From: megarajan on
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
From: Ed Morton on
On 4/1/2008 7:03 AM, megarajan(a)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.

From: pk on
megarajan(a)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 <stdio.h>
#include <stdlib.h>

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.
From: Ed Morton on
On 4/1/2008 7:26 AM, Ed Morton wrote:
> On 4/1/2008 7:03 AM, megarajan(a)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.

From: Ed Morton on


On 4/1/2008 7:53 AM, pk wrote:
> megarajan(a)gmail.com wrote:
>
>
>>hi,
>>
>>Could anyone tell me the way to extract a C function definition from a
>>C source file ?
<snip>
> 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.