Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Find function definition in a C file for a function with its name and starting line no. as input

Reply
Thread Tools

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

 
 
jeniffer
Guest
Posts: n/a
 
      03-24-2006
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.

 
Reply With Quote
 
 
 
 
Sisyphus
Guest
Posts: n/a
 
      03-24-2006

"jeniffer" <> wrote in message
news: ps.com...
> 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/\}//;
 
Reply With Quote
 
 
 
 
Ilya Zakharevich
Guest
Posts: n/a
 
      03-24-2006
[A complimentary Cc of this posting was sent to
jeniffer
<>], who wrote in article < om>:
> 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
 
Reply With Quote
 
Lukas Mai
Guest
Posts: n/a
 
      03-24-2006
jeniffer <> schrob:
> 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
 
Reply With Quote
 
jeniffer
Guest
Posts: n/a
 
      03-26-2006

Ilya Zakharevich wrote:

> [A complimentary Cc of this posting was sent to
> jeniffer
> <>], who wrote in article < om>:
> > 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.

 
Reply With Quote
 
Ilya Zakharevich
Guest
Posts: n/a
 
      03-26-2006
[A complimentary Cc of this posting was sent to
jeniffer
<>], who wrote in article < .com>:
> 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
 
Reply With Quote
 
Juha Laiho
Guest
Posts: n/a
 
      03-26-2006
"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.
--
Wolf a.k.a. Juha Laiho Espoo, Finland
(GC 3.0) GIT d- s+: a C++ ULSH++++$ P++@ L+++ E- W+$@ N++ !K w !O !M V
PS(+) PE Y+ PGP(+) t- 5 !X R !tv b+ !DI D G e+ h---- r+++ y++++
"...cancel my subscription to the resurrection!" (Jim Morrison)
 
Reply With Quote
 
Bart Lateur
Guest
Posts: n/a
 
      03-26-2006
jeniffer wrote:

>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>


--
Bart.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Its a bird, its a plane, its.. um, an Attribute based System? thunk Ruby 0 04-01-2010 10:25 PM
Its a bird, its a plane, no ummm, its a Ruide thunk Ruby 1 03-30-2010 11:10 AM
3 ESSENTIAL TOOLS FOR STARTING AND MAINTAINING...3 ESSENTIAL TOOLSFOR STARTING AND MAINTAINING...3 ESSENTIAL TOOLS FOR STARTING ANDMAINTAINING... Oanh Bui C++ 0 04-27-2009 12:51 PM
3 ESSENTIAL TOOLS FOR STARTING AND MAINTAINING...3 ESSENTIAL TOOLSFOR STARTING AND MAINTAINING...3 ESSENTIAL TOOLS FOR STARTING ANDMAINTAINING... Oanh Bui C Programming 0 04-27-2009 12:51 PM
3 ESSENTIAL TOOLS FOR STARTING AND MAINTAINING...3 ESSENTIAL TOOLSFOR STARTING AND MAINTAINING...3 ESSENTIAL TOOLS FOR STARTING ANDMAINTAINING... Oanh Bui Python 0 04-27-2009 12:46 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57