How to extract a C function definition from a C source file

How to extract a C function definition from a C source file

am 01.04.2008 14:03:11 von megarajan

hi,

Could anyone tell me the way to extract a C function definition from a
C source file ?

i.e search print1 should give me the output

void print1()
{

}

when the file is

void print1()
{

}

void print2()
{


}

.....

Thanks
Thanks
Megarajan

Re: How to extract a C function definition from a C source file

am 01.04.2008 14:26:26 von Ed Morton

On 4/1/2008 7:03 AM, megarajan@gmail.com wrote:
> hi,
>
> Could anyone tell me the way to extract a C function definition from a
> C source file ?
>
> i.e search print1 should give me the output
>
> void print1()
> {
>
> }
>
> when the file is
>
> void print1()
> {
>
> }
>
> void print2()
> {
>
>
> }
>
> ....
>
> Thanks
> Thanks
> Megarajan

With exactly that format of input file you could use:

awk -v fn="print1" '$2==fn"()",/^}/' file

Regards,


Ed.

Re: How to extract a C function definition from a C source file

am 01.04.2008 14:47:08 von Ed Morton

On 4/1/2008 7:26 AM, Ed Morton wrote:
> On 4/1/2008 7:03 AM, megarajan@gmail.com wrote:
>
>>hi,
>>
>>Could anyone tell me the way to extract a C function definition from a
>>C source file ?
>>
>>i.e search print1 should give me the output
>>
>>void print1()
>>{
>>
>>}
>>
>>when the file is
>>
>>void print1()
>>{
>>
>>}
>>
>>void print2()
>>{
>>
>>
>>}
>>
>>....
>>
>>Thanks
>>Thanks
>>Megarajan
>
>
> With exactly that format of input file you could use:
>
> awk -v fn="print1" '$2==fn"()",/^}/' file
>

In reality, of course, your code won't alaways have exactly that format, so
you'll probably need to run a C beautifier to get your code into a standard
format (e.g. "indent", "cb", "bcpp", "prettyprint" or "uncrustify" - google "C
beautifier" or see the man pages and http://uncrustify.sourceforge.net/) and use
a C parser like "cscope" (see http://cscope.sourceforge.net/) to find the
function definition. Do NOT trust any shell/sed/perl/awk/whatever script that
claims to understand C code without actually implementing a full C parser.

Ed.

Re: How to extract a C function definition from a C source file

am 01.04.2008 14:53:19 von PK

megarajan@gmail.com wrote:

> hi,
>
> Could anyone tell me the way to extract a C function definition from a
> C source file ?
>
> i.e search print1 should give me the output
>
> void print1()
> {
>
> }
>
> when the file is
>
> void print1()
> {
>
> }
>
> void print2()
> {
>
>
> }
>
> ....
>
> Thanks
> Thanks
> Megarajan

The following assumes balanced braces, and that the closing } for a function
is the last character in its line.

$ cat extract.awk
function match_braces() {
s=$0
# how to abuse gsub
op=gsub(/{/,"",s);
cl=gsub(/}/,"",s);
if (op || cl) f=1;
return (op-cl);
}

/void print1/ {ok=1}
ok {n+=match_braces(); print; if ((n==0)&&(f==1)) exit}

$ cat file.c
#include
#include

void print1()
{
int foo=1;
int i,j,k,bar=2;
if (foo==bar) {
printf("hello, world\n");
} else {
printf("Bye\n");
}

for (i=0;i<10;i++) {
for (j=0;j<10;j++) {
for (k=0;k<10;k++) {
printf("a");
}
}
}
foo=110;
}

void print2()
{


}

$ awk -f extract.awk file.c
void print1()
{
int foo=1;
int i,j,k,bar=2;
if (foo==bar) {
printf("hello, world\n");
} else {
printf("Bye\n");
}

for (i=0;i<10;i++) {
for (j=0;j<10;j++) {
for (k=0;k<10;k++) {
printf("a");
}
}
}
foo=110;
}

--
All the commands are tested with bash and GNU tools, so they may use
nonstandard features. I try to mention when something is nonstandard (if
I'm aware of that), but I may miss something. Corrections are welcome.

Re: How to extract a C function definition from a C source file

am 01.04.2008 16:08:26 von Ed Morton

On 4/1/2008 7:53 AM, pk wrote:
> megarajan@gmail.com wrote:
>
>
>>hi,
>>
>>Could anyone tell me the way to extract a C function definition from a
>>C source file ?

> The following assumes balanced braces, and that the closing } for a function
> is the last character in its line.

Abandon hope all ye who enter here ;-). I know, the code you posted will work
for exactly the sample input but there's just WAY too many variations for how a
function could be defined to try to handle them in general without a C parser.
For example:

void print1() {
}

void /* comment */ print1()
{
}

int print1() { /* commented brace { */
}

#if SOMETHING
int
#else
void
#endif
print1() { }

void
print1(char arg) /* ANSI C arg */
{ }

void
print1(arg) /* K&R C arg */
char arg;
{ }

void print1(char); /* function template */

etc....

If the OP doesn't mind losing the comments you can strip those and the
preprocessor stuff out using a preprocessor like "gcc -E" but there's still a
ton of variations and it's not clear that'd be acceptable in this case anyway.

It's much easier and more reliable to use a tool like cscope that's designed for
parsing C, though that still needs some post-processing help to pull out the
whole function rather than just the start of the definition.

Ed.

Re: How to extract a C function definition from a C source file

am 01.04.2008 19:30:34 von PK

Ed Morton wrote:

> Abandon hope all ye who enter here ;-). I know, the code you posted will
> work for exactly the sample input but there's just WAY too many variations
> for how a function could be defined to try to handle them in general
> without a C parser. For example:
>
> void print1() {
> }
>
> void /* comment */ print1()
> {
> }
>
> int print1() { /* commented brace { */
> }
>
> #if SOMETHING
> int
> #else
> void
> #endif
> print1() { }
>
> void
> print1(char arg) /* ANSI C arg */
> { }
>
> void
> print1(arg) /* K&R C arg */
> char arg;
> { }
>
> void print1(char); /* function template */
>
> etc....

My code will only work with your first example.

> If the OP doesn't mind losing the comments you can strip those and the
> preprocessor stuff out using a preprocessor like "gcc -E" but there's
> still a ton of variations and it's not clear that'd be acceptable in this
> case anyway.
>
> It's much easier and more reliable to use a tool like cscope that's
> designed for parsing C, though that still needs some post-processing help
> to pull out the whole function rather than just the start of the
> definition.

Yes, I see your point. I tried to write something that could work for the
most common cases (ie, "void print1" on the same line, with no braces in
comments, any number of blanks or empty lines between the print1() and the
opening brace, closing brace last char on a line, and completely free-form
body). Of course, this is not and does not claim to be a complete parser,
and I recognize it won't work in many cases (I should have specified that).
However, as you pointed out in your previous post, the code could be
reformatted by running it through a dedicated tool and forced to look the
way the script expects. This, however, is probably not always what the OP
wants.

Thanks!

--
All the commands are tested with bash and GNU tools, so they may use
nonstandard features. I try to mention when something is nonstandard (if
I'm aware of that), but I may miss something. Corrections are welcome.