Find function definition in a C file for a function with its name and starting line no. as input

J

jeniffer

I am writing a perl code to find out the location (line number) of
ending bracket of a function given its name and start line number .Do i
just scan character by character (from start line number ) and
increment a counter when I encounter { decrement the counter by 1 on
getting } ,and when the counter = 0 ,I take the line number .This would
free me from parsing the code .Is this method correct? or can i do it
in a better way by regular expression ? I need to have a fast approach
since the code has finally to work on thousands of C files.
 
S

Sisyphus

jeniffer said:
I am writing a perl code to find out the location (line number) of
ending bracket of a function given its name and start line number .Do i
just scan character by character (from start line number ) and
increment a counter when I encounter { decrement the counter by 1 on
getting } ,and when the counter = 0 ,I take the line number .This would
free me from parsing the code .Is this method correct? or can i do it
in a better way by regular expression ? I need to have a fast approach
since the code has finally to work on thousands of C files.

Yeah - I've done stuff like that successfully - but it's in an environment
that's not going to cause me any embarrassment if it breaks (and where I
have control over what the C file looks like).

I scanned line by line (rather than character by character) and kept count
via a regex - something like:

while(<READ>) {
$open_count += $_ =~ tr/\{//;
$close_count += $_ =~ tr/\}//;
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was sent to
jeniffer
I am writing a perl code to find out the location (line number) of
ending bracket of a function given its name and start line number .Do i
just scan character by character (from start line number ) and
increment a counter when I encounter { decrement the counter by 1 on
getting } ,and when the counter = 0 ,I take the line number .This would
free me from parsing the code .Is this method correct?

Will not work. Too hard to distinguish what is a comment, what is a
literal, etc.

Either use C::Scan (directly - or it might be that you need to hook
into lower level subroutines), or program in Emacs lisp, where this is
trivial.

Hope this helps,
Ilya
 
L

Lukas Mai

jeniffer said:
I am writing a perl code to find out the location (line number) of
ending bracket of a function given its name and start line number .Do i
just scan character by character (from start line number ) and
increment a counter when I encounter { decrement the counter by 1 on
getting } ,and when the counter = 0 ,I take the line number .This would
free me from parsing the code .Is this method correct? or can i do it
in a better way by regular expression ? I need to have a fast approach
since the code has finally to work on thousands of C files.

This is non-trivial as you have to deal with nesting, string literals,
comments, etc. I think it's possible with irregular expressions:

$bs = qr{\\|\Q??/\E}; # backslash
$lbr = qr{\{|\Q??<\E}; # left brace
$rbr = qr{\}|\Q??>\E}; # right brace
$block = qr!
$lbr
(?>
" (?> $bs . | [^"] )* "
|
' (?> $bs . | [^'] )* '
|
/ (?: $bs \n )* \*
[^*]*
\*+ (?: $bs \n )*
(?:
[^/*] [^*]*
\*+ (?: $bs \n )*
)*
/
|
/ (?: $bs \n )* /
(?:
$bs \n
|
[^\n]
)*
|
(??{ $block })
|
[^{}"']
)*
$rbr
!sx;

Note that this uses several experimental features of the regex engine,
some of which don't work (and I didn't test this code).

To do it right, you have to somehow tokenize the input. Simply counting
characters doesn't work.

HTH, Lukas
 
J

jeniffer

Ilya said:
[A complimentary Cc of this posting was sent to
jeniffer
I am writing a perl code to find out the location (line number) of
ending bracket of a function given its name and start line number .Do i
just scan character by character (from start line number ) and
increment a counter when I encounter { decrement the counter by 1 on
getting } ,and when the counter = 0 ,I take the line number .This would
free me from parsing the code .Is this method correct?

Will not work. Too hard to distinguish what is a comment, what is a
literal, etc.

Either use C::Scan (directly - or it might be that you need to hook
into lower level subroutines), or program in Emacs lisp, where this is
trivial.

Hope this helps,
Ilya


I read abt C::Scan and tried using C::Scan ...Here's the code and the
error :::Can you plz help me find out the reason??

#!/usr/bin/perl

use strict;
use warnings;
use C::Scan;

my $c = new C::Scan 'filename' => $name;
my $fdef = $c->get('inlines');
print "\nfdefinition =$fdef";

[u103@linux part2]$ perl cs.pl
Can't locate C/Scan.pm in @INC (@INC contains:
/usr/lib/perl5/5.8.0/i386-linux-t
hread-multi /usr/lib/perl5/5.8.0
/usr/lib/perl5/site_perl/5.8.0/i386-linux-threa
d-multi /usr/lib/perl5/site_perl/5.8.0 /usr/lib/perl5/site_perl
/usr/lib/perl5/v
endor_perl/5.8.0/i386-linux-thread-multi
/usr/lib/perl5/vendor_perl/5.8.0 /usr/l
ib/perl5/vendor_perl /usr/lib/perl5/5.8.0/i386-linux-thread-multi
/usr/lib/perl5
/5.8.0 .) at cs.pl line 5.
BEGIN failed--compilation aborted at cs.pl line 5.
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was sent to
jeniffer
use strict;
use warnings;
use C::Scan;

my $c = new C::Scan 'filename' => $name;

Do not see where $name is defined. This should not even compile.
[u103@linux part2]$ perl cs.pl
Can't locate C/Scan.pm in @INC (@INC contains:

As the message says, you did not install it yet.

perl -MCPAN -e 'install C::Scan'

Hope this helps,
Ilya
 
J

Juha Laiho

jeniffer said:
I read abt C::Scan and tried using C::Scan ...Here's the code and the
error :::Can you plz help me find out the reason??

#!/usr/bin/perl

use strict;
use warnings;
use C::Scan; [...]
[u103@linux part2]$ perl cs.pl
Can't locate C/Scan.pm in @INC (@INC contains: [...]
at cs.pl line 5.
BEGIN failed--compilation aborted at cs.pl line 5.

This very much looks like you don't have C::Scan installed at all,
or alternatively, you don't have your perl library search path
defined, if you made a private (as opposed to systemwide) installation
of the module.
 
B

Bart Lateur

jeniffer said:
I am writing a perl code to find out the location (line number) of
ending bracket of a function given its name and start line number .Do i
just scan character by character (from start line number ) and
increment a counter when I encounter { decrement the counter by 1 on
getting } ,and when the counter = 0 ,I take the line number .This would
free me from parsing the code .Is this method correct?

It's close, but not quite. You'll have to be able to recognize comments,
and strings. You have to skip braces inside those. For the rest, it's
just a matter of balancing the braces.
or can i do it
in a better way by regular expression ?

Yeah, doing it character by character is how one would do it in C, but
it most definitely isn't the fastest way in Perl. Scanning for the next
brace with a regex would be lots faster. But likely not better,
resultwise.

At first I'm thinking of using Text::Balanced, it's more or less
designed for things like that. But I remember reading an article on
perl.com, on lexing your data (thus recognizing comments and strings).
That might be of use to you:

Lexing Your Data
<http://www.perl.com/pub/a/2006/01/05/parsing.html>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,756
Messages
2,569,533
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top