Add debug print code in every function using vim - c

I have a huge code file and want to insert print code in every function.
I know debugging is one option but I am new to Kernel and kgdb is not an easy and immediate option hence I want to use printf temporarily.
I used vim's multiple buffers to do this task faster, but want to know if there is any way to automate it in .vimrc
Here is what the final code must look like
void foo(int a, int b) {
printf("Some print");
// ...
}
int bar() {
printf("Some print");
// ...
}
void bleh(int b) {
printf("Some print");
// ...
}

one quick way to do it is in the shell:
find -name '*.c' | xargs vim
In vim, you start recording with qq a macro, make use of the global command
:g/\v\s*(void|int) \w+\([^)]*\)/normal A^Mprint("some print");
And then you use the wonderful argdo command:
:argdo normal #q
To save the changes you use:
:argdo normal :w^M
That will add print("someprint") to every function on the located c source code files. If you want to use the function name or the file name in the print statement, you can use the global command with a little complex substitution like (not tested):
:global /\v\s*(void|int) \w+([^)]*)/s/\v(\w+)\([^]]*\)\s* {/\=submatch(0) . '\r\t\tprint(in file.function:'. expand('%') .'.'. submatch(1) . ');'
Remember that ^M and ^[ are not literal strings, they are inserted with <C-v><CR> and <C-v><Esc>
Hope this help

Related

Finding "main" functions' names in a C file via Bash script

I'm having a large number of C files, that are structured with the following principle:
All functions are declared in the C file and are with return type int, double or void.
All functions start with "ksz_". Only functions use this - nothing else uses "ksz_" in their names.
The file contains "main" functions. All supporting functions use their "main" function's name to form themselves.
Because they were made by different people they are quite messly made and have spaces placed at random places:
A rought visualization would be(note the spaces):
int ksz_Print(...)
{
...
}
void ksz_Print_Helper1 (... ){
...
}
void ksz_Print_Helper2(...) {
...
}
int ksz_Input(...){
...
}
double ksz_Input_Helper1 ( ...){
...
}
I need to find the "main" function names of each individual C file in order to use them for another seach algorithm.
Since these files are huge(sme of them have over a dozen thousand lines) and there are hundreds of them - I need a Bash scrip for this.
Ideally this script would extract only the "main" functions:
ksz_Print
ksz_Input
What stops me is that i can't think the Regex of my grep in order to extract the function lines. I think its logic should look like this:
(spaces)(int/float/double)(spaces)(ksz_)(other characers without space)(spaces)(open bracket)
After that I guess I'll extract the word containing "ksz_" from each line with cut(after trimming and removing duplicate spaces).
And last I'll need to find a way to filter out the supporting functions.
But what would be my initial grep in this script?
If I understand your specifications correctly this should do it:
root#local [~]# awk '/^[ \t]*(int|float|double)[ \t]+ksz_/ {print $2}' sample.txt
One thing I did not understand was whether there should only be one "_" after ksz so for example if "double ksz_Input_Helper1" is not something you want to match. In the regex above it does match.
I also chose to go with awk rather than grep as you said you want only the name the above awk prints only the second field using whitespace as a delimiter. If you still want to use grep this one does the same task:
root#local [~]# egrep '^\s*(int|float|double)\s+ksz_' sample.txt
Here is a breakdown(note in awk I use [ \t] in place of \s as I could not get it to recognize \s]:
^ - match start of line
\s* - match if there are 0 or more white spaces
(int|float|double) - match int, float, OR double
\s+ - match at least one whitespace
ksz_ - match literal string "ksz_"
Try using a regex that only matches the portion you want and only print that:
grep -oRE "(ksz_[a-zA-Z_]*\b)" *
-o - output only match
-R - recursive
-E - regex
[a-zA-Z_] - upper and lower case letters, underscore
\b - ending at word boundry

Print shell command lines in C with printf()

I am trying to build a shell program with a c program. Basically I need a text file with the same shell commands repeated over and over but with one part changed. I tried to build a C program to count from 1 to 750 and print out the paragraph with that one digit changed but it is trying to read the shell commands and giving me errors. How do I have it ignore the shell commands and just print what's in the printf?
Here is the program:
#include <stdio.h>
int main ()
{
int x;
for(x=1;x<751;x++){
printf("#!/bin/sh");
printf("NRNHOME="/Applications/NEURON-7.3/nrn"");
printf("\NEURONHOME="${NRNHOME}/share/nrn"");
printf("CPU=i386");
printf("NRNBIN="${NRNHOME}/i386/bin/"");
printf("PATH="${NRNHOME}/i386/bin:${PATH}"");
printf("export NRNHOME");
printf("export NEURONHOME");
printf("export NRNBIN");
printf("export PATH");
printf("export CPU");
printf("nrncarbon=yes");
printf("export nrncarbon");
printf("cd "\${NRNHOME}/i386/bin"");
printf("./nrngui.sh "/Applications/NSD2013/s%d.hoc"\n\n",x);
}
}
It's telling me all the directories are undeclared and it expects a ) before $? All I want is to have it print out the commands changing the .hoc file in the very last line beginning with s1.hoc and ending with s750.hoc.
Thanks in advance for your advice.
Aside from the fact that your program will generate a relatively useless long output list of 750 times almost the same script that you will probably have to chop up in 750 separate scriptfiles, there are a number of concrete problems that cause it to malfunction:
printf("#!/bin/sh");
because this statement is inside the loop, it will be
printf doesn't add newlines by itself, add \n if you want the next printf to start on a new line
printf("\NEURONHOME="${NRNHOME}/share/nrn"");
Pretty sure that \N at the start is unintentional
double quotes inside the string should be escaped, eg \"
printf("cd "\${NRNHOME}/i386/bin"");
Not sure why you seem to escape the $ here...
printf("./nrngui.sh "/Applications/NSD2013/s%d.hoc"\n\n",x);
}
Anyways, it's pretty easy to do this in pure shellscript, and send the output to 750 different script files in 1 blow:
for i in {1..750} ; do
cat << EOT > the_output_script$i.sh
#!/bin/sh
NRNHOME="/Applications/NEURON-7.3/nrn"
...
# If you want bash to ignore variables that should be evaluated later on
# you just need to escape the dollarsign
NRNBIN="\${NRNHOME}/i386/bin/"
./nrngui.sh "/Applications/NSD2013/s$i.hoc
EOT
# we're after the end of the heredoc, so here we can add other stuff that
# needs to be done in the loop, like changing the file's access:
chown ug+x the_output_script$i.sh
done
which will produce 750 files named the_output_script1.sh to the_output_script750.sh which is what I think you're really looking for. Btw, the core trick used in this script is called a heredoc or here document
Ok, to maintain your original intent (for educational purposes only):
#include <stdio.h>
int main ()
{
int x;
for(x=1;x<751;x++) {
printf("#!/bin/sh\n");
printf("NRNHOME=\"/Applications/NEURON-7.3/nrn\"\n");
printf("NEURONHOME=\"${NRNHOME}/share/nrn\"\n");
printf("CPU=i386");
printf("NRNBIN=\"${NRNHOME}/i386/bin/\"\n");
printf("PATH=\"${NRNHOME}/i386/bin:${PATH}\"\n");
printf("export NRNHOME");
printf("export NEURONHOME");
printf("export NRNBIN");
printf("export PATH");
printf("export CPU");
printf("nrncarbon=yes");
printf("export nrncarbon");
printf("cd \"${NRNHOME}/i386/bin\"\n");
printf("./nrngui.sh \"/Applications/NSD2013/s%d.hoc\"\n\n",x);
}
}
Now, another way to do it would be (my_script.sh):
#!/bin/sh
NRNHOME=/Applications/NEURON-7.3/nrn
NEURONHOME=${NRNHOME}/share/nrn
CPU=i386
NRNBIN=${NRNHOME}/i386/bin/
PATH=${NRNHOME}/i386/bin:${PATH}
export NRNHOME
export NEURONHOME
export NRNBIN
export PATH
export CPU
nrncarbon=yes
export nrncarbon
cd ${NRNHOME}/i386/bin
./nrnqui.sh /Applications/NSD2013/s*.hoc // the lazy way
OR: my_script.sh: // with a for loop
#!/bin/sh
NRNHOME=/Applications/NEURON-7.3/nrn
NEURONHOME=${NRNHOME}/share/nrn
CPU=i386
NRNBIN=${NRNHOME}/i386/bin/
PATH=${NRNHOME}/i386/bin:${PATH}
export NRNHOME
export NEURONHOME
export NRNBIN
export PATH
export CPU
nrncarbon=yes
export nrncarbon
cd ${NRNHOME}/i386/bin
for i in {1..750}
do
./nrnqui.sh /Applications/NSD2013/s{$i}.hoc
done
This could do it,
#include <stdio.h>
int main ()
{
int x;
for(x=1;x<751;x++){
printf("#!/bin/sh\n");
printf("NRNHOME=\"/Applications/NEURON-7.3/nrn\"\n");
printf("NEURONHOME=\"${NRNHOME}/share/nrn\"\n");
printf("CPU=i386\n");
printf("NRNBIN=\"${NRNHOME}/i386/bin/\"\n");
printf("PATH=\"${NRNHOME}/i386/bin:${PATH}\"\n");
printf("export NRNHOME\n");
printf("export NEURONHOME\n");
printf("export NRNBIN\n");
printf("export PATH\n");
printf("export CPU\n");
printf("nrncarbon=yes\n");
printf("export nrncarbon\n");
printf("cd \"${NRNHOME}/i386/bin\"\n");
printf("./nrngui.sh \"/Applications/NSD2013/s%d.hoc\"\n\n",x);
}
}
I strongly recommend you to learn printf here. Refer sources given here to know about c language

Search and replace a string as shown below

I am reading a file say x.c and I have to find for the string "shared". Once the string like that has been found, the following has to be done.
Example:
shared(x,n)
Output has to be
*var = &x;
*var1 = &n;
Pointers can be of any name. Output has to be written to a different file. How to do this?
I'm developing a source to source compiler for concurrent platforms using lex and yacc. This can be a routine written in C or if u can using lex and yacc. Can anyone please help?
Thanks.
If, as you state, the arguments can only be variables and not any kind of other expressions, then there are a couple of simple solutions.
One is to use regular expressions, and do a simple search/replace on the whole file using a pretty simple regular expression.
Another is to simply load the entire source file into memory, search using strstr for "shared(", and use e.g. strtok to get the arguments. Copy everything else verbatim to the destination.
Take advantage of the C preprocessor.
Put this at the top of the file
#define shared(x,n) { *var = &(x); *var1 = &(n); }
and run in through cpp. This will include external resources also and replace all macros, but you can simply remove all #something lines from the code, convert using injected preprocessor rules and then re-add them.
By the way, why not a simple macro set in a header file for the developer to include?
A doubt: where do var and var1 come from?
EDIT: corrected as shown by johnchen902
When it comes to preprocessor, I'll do this:
#define shared(x,n) (*var=&(x),*var1=&(n))
Why I think it's better than esseks's answer?
Suppose this situation:
if( someBool )
shared(x,n);
else { /* something else */ }
In esseks's answer it will becomes to:
if( someBool )
{ *var = &x; *var1 = &n; }; // compile error
else { /* something else */ }
And in my answer it will becomes to:
if( someBool )
(*var=&(x),*var1=&(n)); // good!
else { /* something else */ }

Profiling for runtime in C

i am trying to find out a way in which i can write out run-time of selected number of functions when my tool runs. let say out of large list of functions which my tool have i need to write out the what is the time taken by individual calls y(), z() , a1() ....
X(){
y();
..
..
z();
..
..
a1();
..
..
b1();
..
..
}
I don't want to use gprof because it need to be separately run , and there is no way customer can run gprof at there end. In many cases i don't have access to the test which is producing long runtime. A way to log run time of high level function will be helpful. i dont't want to wrap around each and every function call around time() system call and then print it. Can macro help in this.? any ideas?
You said you don't want to wrap each call, but let me just show you how I handle timer calls so they can be removed at compile time, and maybe that can be wrapped up in another macro later:
#ifndef NOTIME
# include <ctime>
# define CLOCK_TICK(acc, ctr) ctr = std::clock()
# define CLOCK_TOCK(acc, ctr) acc += (std::clock() - ctr)
# define CLOCK_RESET(acc) acc = 0
# define CLOCK_REPORT(acc) 1000. * double(acc) / double(CLOCKS_PER_SEC)
static clock_t t1a, t1c, t2a, t2c; // as many pairs as you need
#else
# define CLOCK_TICK(acc, ctr)
# define CLOCK_TOCK(acc, ctr)
# define CLOCK_RESET(acc)
# define CLOCK_REPORT(acc) 0
#endif
Now you can use it like this:
CLOCK_RESET(t1a);
for (int i = 0; i != 250000; ++i)
{
CLOCK_TICK(t1a, t1c);
some_expensive_function();
CLOCK_TOCK(t1a, t1c);
}
std::cout << "Time spent in some_expensive_function(): " << CLOCK_REPORT(t1a) << "ms.\n";
With variadic macros you might even be able to wrap up the function call:
#define timed_call(ACC, CTR, func, ...) do { CLOCK_TICK(ACC, CTR); \
func(__VA_ARGS__); \
CLOCK_TOCK(ACC,CTR); \
} while (false)
Your customer does not need to run gprof. If you compile your executable with profiling he just needs to run the app normally, then collect the gmon.out data file and deliver it to you. You will then run gprof to generate profiling data.
If you want to have more control over what parts of your code are profiled then you could try the open source Shiny profiler. To use this you have link with a small C++ library and insert a macro at the beginning of each function you want to profile. There are also options to profile blocks of code. The profiler output is generated via a function call from your application, so you can decide how and when the output is generated.
Why not wrap each call, with a macro like this:
#define WRAP(fcall) do {\
.. before stuff .. \
fcall; \
.. after call .. \
} while(0)
then in place of each
foo(x, y, z);
you write
WRAP(foo(x, y, z));
Then if you want to disable it, just comment out the before/after stuff.
It may not be pretty, but it works.

I have a function with a lot of return points. Is there any way that I can make gdb show me which one is returning?

I have a function with an absurd number of return points, and I don't want to caveman each one, and I don't want to next through the function. Is there any way I can do something like finish, except have it stop on the return statement?
You can try reverse debugging to find out where function actually returns. Finish executing current frame, do reverse-step and then you should stop at just returned statement.
(gdb) fin
(gdb) reverse-step
There is already similar question
I think you're stuck setting breakpoints. I'd write a script to generate the list of breakpoint commands to run and paste them into gdb.
Sample script (in Python):
lines = open(filename, 'r').readlines()
break_lines = [line_num for line_num, line in enumerate(lines) if 'return' in line and
line_num > first and line_num <= last]
break_cmds = ['b %s:%d' % (filename, line_num) for line_num in break_lines]
print '\n'.join(break_cmds)
Set filename to the name of the file with the absurd function, first to the first line of the function (this is a quick script, not a C parser) and last to the number of the last line of the function. The output ought to be suitable for pasting into gdb.
Kind of a stretch, but the catch command can stop on many kinds of things (like forking, exiting, receiving a signal). You may be able to use catch catch (which breaks for exceptions) to do what you want in C++ if you wrap the function in try/finally. For that matter, if you break on a line inside the finally you can probably single-step through the return after that (although how much that will tell you about where it came from is highly dependent on optimization: common return cases are often folded by gcc).
How about taking this opportunity to break up what seems to be clearly a too-large function?
This question's come up before on SO. My answer from there:
Obviously you ought to refactor this function, but in C++ you can use this simple expedient to deal with this in five minutes:
class ReturnMarker
{
public:
ReturnMarker() {};
~ReturnMarker()
{
dummy += 1; //<-- put your breakpoint here
}
static int dummy;
}
int ReturnMarker::dummy = 0;
and then instance a single ReturnMarker at the top of your function. When it returns, that instance will go out of scope, and you'll hit the destructor.
void LongFunction()
{
ReturnMarker foo;
// ...
}

Resources