Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Extracting printf(...) from (void) printf(....)

Reply
Thread Tools

Extracting printf(...) from (void) printf(....)

 
 
guru
Guest
Posts: n/a
 
      02-02-2009
HI all

How to search for (void) from the line.

ex: (void) printf(....)

I want to search if (void) is there at the beggining of the line.. if
exist then extract printf(....) function.

Please let me know how it can be done or tell me the reference so that
I can try.

Thanks & Regards
Gururaja
 
Reply With Quote
 
 
 
 
smallpond
Guest
Posts: n/a
 
      02-02-2009
On Feb 2, 9:04 am, guru <(E-Mail Removed)> wrote:
> HI all
>
> How to search for (void) from the line.
>
> ex: (void) printf(....)
>
> I want to search if (void) is there at the beggining of the line.. if
> exist then extract printf(....) function.
>
> Please let me know how it can be done or tell me the reference so that
> I can try.
>
> Thanks & Regards
> Gururaja



Run the command:
perldoc perlretut

 
Reply With Quote
 
 
 
 
sln@netherlands.com
Guest
Posts: n/a
 
      02-02-2009
On Mon, 2 Feb 2009 06:04:50 -0800 (PST), guru <(E-Mail Removed)> wrote:

>HI all
>
>How to search for (void) from the line.
>
>ex: (void) printf(....)
>
>I want to search if (void) is there at the beggining of the line.. if
>exist then extract printf(....) function.
>
>Please let me know how it can be done or tell me the reference so that
>I can try.
>
>Thanks & Regards
>Gururaja


I assume this is just an example, the key phrase is 'void' and printf has
nothing to do with it.

printf() from CRT returns type 'int', the number of characters written.
To cast the return value to type (void) serves no purpose since only pointers
can be of type 'void', ie: not variables.

So these produce errors ->
int ivar; // ok
void var; // invalid type
var = (void) printf(....); // invalid rvalue cast
ivar = (void) printf(....); // invalid rvalue cast
(void) printf(....); // ok, does nothing
void *ptr; // ok, its a pointer


As far as parsing a source file, functions can span lines and have
nested functions, requiring balanced text parsing:

printf("*The floor of 0.3/0.1-2 is %f\n",
floor(0.3/0.1-2) );

and be mixed with comments. A better solution is to get a C++ parser somewhere.

But, if this isn't real source code text and all you want to do is parse anything
in (void) "function(anything)" on a line by line basis, I guess you could adopt a quick and
dirty approach, something like this:


while (<DATA>) # no caching of lines, raw per-line basis
{
chomp;
if (/(\s*void\s*)\s*([a-z][\w-]*?\s*\(.*\)\s*)/ { # greedy () in liue of balanced parenthesis
print $1,"\n";
}
# Or, just grab everything past (void)
# if (/(\s*void\s*)\s*(.+)/ {
# print $1,"\n";
# }
}

sln



 
Reply With Quote
 
sln@netherlands.com
Guest
Posts: n/a
 
      02-02-2009
On Mon, 02 Feb 2009 16:54:19 GMT, http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:

>On Mon, 2 Feb 2009 06:04:50 -0800 (PST), guru <(E-Mail Removed)> wrote:
>
>>HI all
>>
>>How to search for (void) from the line.
>>

[snip]
>and be mixed with comments. A better solution is to get a C++ parser somewhere.
>
>But, if this isn't real source code text and all you want to do is parse anything
>in (void) "function(anything)" on a line by line basis, I guess you could adopt a quick and
>dirty approach, something like this:
>
>
>while (<DATA>) # no caching of lines, raw per-line basis
>{
> chomp;
> if (/(\s*void\s*)\s*([a-z][\w-]*?\s*\(.*\)\s*)/ { # greedy () in liue of balanced parenthesis

^^^
I forgot to mention this is untested. After looking at it a bit, this may be better:

/\(\s*void\s*\)\s*([a-zA-Z][\w-]*\s*\(.*\))/

Gee, there are alot of paren's in this one..

sln

 
Reply With Quote
 
sln@netherlands.com
Guest
Posts: n/a
 
      02-02-2009
On Mon, 02 Feb 2009 17:12:12 GMT, (E-Mail Removed) wrote:

>On Mon, 02 Feb 2009 16:54:19 GMT, (E-Mail Removed) wrote:
>
>>On Mon, 2 Feb 2009 06:04:50 -0800 (PST), guru <(E-Mail Removed)> wrote:
>>
>>>HI all
>>>
>>>How to search for (void) from the line.
>>>

>[snip]
>>and be mixed with comments. A better solution is to get a C++ parser somewhere.
>>
>>But, if this isn't real source code text and all you want to do is parse anything
>>in (void) "function(anything)" on a line by line basis, I guess you could adopt a quick and
>>dirty approach, something like this:
>>
>>
>>while (<DATA>) # no caching of lines, raw per-line basis
>>{
>> chomp;
>> if (/(\s*void\s*)\s*([a-z][\w-]*?\s*\(.*\)\s*)/ { # greedy () in liue of balanced parenthesis

> ^^^
>I forgot to mention this is untested. After looking at it a bit, this may be better:
>
> /\(\s*void\s*\)\s*([a-zA-Z][\w-]*\s*\(.*\))/
>
>Gee, there are alot of paren's in this one..
>

Why not add some more ..
/\(\s*void\s*\)\s*((?:_[a-zA-Z]|[a-zA-Z])[\w-]*\s*\(.*\))/

sln

 
Reply With Quote
 
Jens Thoms Toerring
Guest
Posts: n/a
 
      02-02-2009
(E-Mail Removed) wrote:
> On Mon, 2 Feb 2009 06:04:50 -0800 (PST), guru <(E-Mail Removed)> wrote:


> >How to search for (void) from the line.
> >
> >ex: (void) printf(....)
> >
> >I want to search if (void) is there at the beggining of the line.. if
> >exist then extract printf(....) function.
> >
> >Please let me know how it can be done or tell me the reference so that
> >I can try.


> I assume this is just an example, the key phrase is 'void' and printf has
> nothing to do with it.


> printf() from CRT returns type 'int', the number of characters written.
> To cast the return value to type (void) serves no purpose since only pointers
> can be of type 'void', ie: not variables.


It may not serve any purpose to the C compiler, but there are code
testing tools like lint that complain when the return value of a
function isn't used. And to keep lint etc. from doing so in cases
where disregarding the return value is exactly what you want it is
not uncommon practise to cast the such return values to '(void)'
since lint only then understands that you don't want to do anything
with it and shuts up.

To the OP: Of course you can search for such lines with something
like

/^\s*\(\s*void\*\)\s*printf\(.*?\)\s*;/

or, if it's not just about printf() but all functions,

/^\s*\(\s*void\*\)\s*[A-Za-z0-9_]+\s*\(.*?\)\s*;/

but there are more possible cases like

if (some_condition) (void) printf(...);

or

do_something(); (void) printf(...);

just to name a few - so just looking for the first piece of code
on a line won't catch all instances. You would have to use at least
(I probably forgot a few possibilities) something like the fol-
lowing (assuming the function call isn't split up into more than
one line):

/(^|;|\)|,|}|(*/))\s*\(\s*void\*\)\s*[A-Za-z0-9_]+\s*\(.*?\)\s*;/

But even that it still might get a few cases wrong (e.g. if you
have printf()s with weird format strings like "xyz);" etc.) or
produce false positives. To get it 100% right I guess you would
have to write a parser for C, regexps probably aren't good enough
for this since they just look at the input stream but without
"understanding" what it means. To see how hairy C code can look
like check out the winning entries of the obfuscated C contest

Regards, Jens
--
\ Jens Thoms Toerring ___ (E-Mail Removed)
\__________________________ http://toerring.de
 
Reply With Quote
 
sln@netherlands.com
Guest
Posts: n/a
 
      02-02-2009
On 2 Feb 2009 18:54:43 GMT, (E-Mail Removed) (Jens Thoms Toerring) wrote:

>(E-Mail Removed) wrote:
>> On Mon, 2 Feb 2009 06:04:50 -0800 (PST), guru <(E-Mail Removed)> wrote:

>
>> >How to search for (void) from the line.
>> >
>> >ex: (void) printf(....)
>> >
>> >I want to search if (void) is there at the beggining of the line.. if
>> >exist then extract printf(....) function.
>> >
>> >Please let me know how it can be done or tell me the reference so that
>> >I can try.

>
>> I assume this is just an example, the key phrase is 'void' and printf has
>> nothing to do with it.

>
>> printf() from CRT returns type 'int', the number of characters written.
>> To cast the return value to type (void) serves no purpose since only pointers
>> can be of type 'void', ie: not variables.

>
>It may not serve any purpose to the C compiler, but there are code
>testing tools like lint that complain when the return value of a
>function isn't used. And to keep lint etc. from doing so in cases
>where disregarding the return value is exactly what you want it is
>not uncommon practise to cast the such return values to '(void)'
>since lint only then understands that you don't want to do anything
>with it and shuts up.


Years ago, I read the description of Lint, even tried a code checker once.
Later on (a couple of years ago), I tried the Bounds Checker suite of stuff.
Total hogwash!! Bogged down bloated, slow, erroneous piece of crap.

Casting a function return value to void does not cast anything unless its assigned
to an lvalue, and then only as (void *). Other than that, nothing can be cast as void
except in function prototypes. I'm not suprised a Lint type tool can't tell the difference.
Possibly because the compiler will let any non-assignment type void cast take place.
Don't think Lint doesent use compiler compliant constructs, it does.
Lint is just a stoopid usless tool.

Imagine seeing (void) function(....) all over the code, possibly surrounded by define's.
What a dream job that would be to have to maintane such crap. Same with unit test bull crap.
Imagine having to code review that.

>
>To the OP: Of course you can search for such lines with something
>like
>
>/^\s*\(\s*void\*\)\s*printf\(.*?\)\s*;/
>
>or, if it's not just about printf() but all functions,
>
>/^\s*\(\s*void\*\)\s*[A-Za-z0-9_]+\s*\(.*?\)\s*;/

^
The beginning of the line doesen't matter.
There is no capture in this regex.

>
>but there are more possible cases like
>
> if (some_condition) (void) printf(...);


Or var = (void) printf(...);
Oh, that won't compile.

>
>or
>
> do_something(); (void) printf(...);
>
>just to name a few - so just looking for the first piece of code
>on a line won't catch all instances. You would have to use at least
>(I probably forgot a few possibilities) something like the fol-
>lowing (assuming the function call isn't split up into more than
>one line):
>
>/(^|;|\)|,|}|(*/))\s*\(\s*void\*\)\s*[A-Za-z0-9_]+\s*\(.*?\)\s*;/

^ metachar, needs to be escaped
>/(^|;|\)|,|}|(*/))\s*\(\s*void\*\)\s*[A-Za-z0-9_]+\s*\(.*?\)\s*;/

^^^^ capturing a quantifier and a foward slash, the regex delimeter
>/(^|;|\)|,|}|(*/))\s*\(\s*void\*\)\s*[A-Za-z0-9_]+\s*\(.*?\)\s*;/

^^^^^^^^^^^^^^^^^ capturing, why? ^ ^ no capturing of function, why?
>/(^|;|\)|,|}|(*/))\s*\(\s*void\*\)\s*[A-Za-z0-9_]+\s*\(.*?\)\s*;/

^^^^^^^^^^^^^
functions can't begin with numeric digits, only underscore pluls alpha or alpha alone.
Better this (?:_[a-zA-Z]|[a-zA-Z])[\w-]

>/(^|;|\)|,|}|(*/))\s*\(\s*void\*\)\s*[A-Za-z0-9_]+\s*\(.*?\)\s*;/

^^^^^^^^^^ this is \w

>/(^|;|\)|,|}|(*/))\s*\(\s*void\*\)\s*[A-Za-z0-9_]+\s*\(.*?\)\s*;/

^^^^^^^^^^^^^^^^^
This is the right approach, but this is only needed if the line were being parsed
on a line-based, multiple occurances of (void) fn(..); within a looping while in
global context. As we know this is still inadequate.
In its simplest form, something like this might be enough but its not even close.
/\(\s*void\s*\)\s*((?:_[a-zA-Z]|[a-zA-Z])[\w-]*\s*\(.*\))\s*;/

>
>But even that it still might get a few cases wrong (e.g. if you
>have printf()s with weird format strings like "xyz);" etc.) or
>produce false positives. To get it 100% right I guess you would
>have to write a parser for C, regexps probably aren't good enough
>for this since they just look at the input stream but without
>"understanding" what it means. To see how hairy C code can look
>like check out the winning entries of the obfuscated C contest
>
> Regards, Jens


Still though, to parse this with other than a full on C/C++ parser would involve much
more complexities. Thats not saying it can't be done with regular expressions.
If you can do while(/./sg) {} , then you can parse anything on the planet. And it is
a regular expression.

sln



 
Reply With Quote
 
guru
Guest
Posts: n/a
 
      02-03-2009
On Feb 2, 10:12*pm, (E-Mail Removed) wrote:
> On Mon, 02 Feb 2009 16:54:19 GMT, (E-Mail Removed) wrote:
> >On Mon, 2 Feb 2009 06:04:50 -0800 (PST), guru <(E-Mail Removed)> wrote:

>
> >>HI all

>
> >>How to search for (void) from the line.

>
> [snip]
> >and be mixed with comments. A better solution is to get a C++ parser somewhere.

>
> >But, if this isn't real source code text and all you want to do is parseanything
> >in (void) "function(anything)" on a line by line basis, I guess you could adopt a quick and
> >dirty approach, something like this:

>
> >while (<DATA>) *# no caching of lines, raw per-line basis
> >{
> > * *chomp;
> > * *if (/(\s*void\s*)\s*([a-z][\w-]*?\s*\(.*\)\s*)/ { # greedy () inliue of balanced parenthesis

>
> * * * * * * ^^^
> I forgot to mention this is untested. After looking at it a bit, this maybe better:
>
> * * * * /\(\s*void\s*\)\s*([a-zA-Z][\w-]*\s*\(.*\))/
>
> Gee, there are alot of paren's in this one..
>
> sln- Hide quoted text -
>
> - Show quoted text -


HI

yes this is not a real example.

the acually the pattern will be of type

1. (void) function(....)
2. function(....)
3. return (function(....)........)

I want to extract the function(....) from the above type of lines.

Thanks & Regards
Gururaja
 
Reply With Quote
 
sln@netherlands.com
Guest
Posts: n/a
 
      02-03-2009
On Mon, 2 Feb 2009 20:31:45 -0800 (PST), guru <(E-Mail Removed)> wrote:

>On Feb 2, 10:12*pm, (E-Mail Removed) wrote:
>> On Mon, 02 Feb 2009 16:54:19 GMT, (E-Mail Removed) wrote:
>> >On Mon, 2 Feb 2009 06:04:50 -0800 (PST), guru <(E-Mail Removed)> wrote:

>>
>> >>HI all

>>
>> >>How to search for (void) from the line.

>>
>> [snip]
>> >and be mixed with comments. A better solution is to get a C++ parser somewhere.

>>
>> >But, if this isn't real source code text and all you want to do is parse anything
>> >in (void) "function(anything)" on a line by line basis, I guess you could adopt a quick and
>> >dirty approach, something like this:

>>
>> >while (<DATA>) *# no caching of lines, raw per-line basis
>> >{
>> > * *chomp;
>> > * *if (/(\s*void\s*)\s*([a-z][\w-]*?\s*\(.*\)\s*)/ { # greedy () in liue of balanced parenthesis

>>
>> * * * * * * ^^^
>> I forgot to mention this is untested. After looking at it a bit, this may be better:
>>
>> * * * * /\(\s*void\s*\)\s*([a-zA-Z][\w-]*\s*\(.*\))/
>>
>> Gee, there are alot of paren's in this one..
>>
>> sln- Hide quoted text -
>>
>> - Show quoted text -

>
>HI
>
>yes this is not a real example.
>
>the acually the pattern will be of type
>
>1. (void) function(....)
>2. function(....)
>3. return (function(....)........)
>
>I want to extract the function(....) from the above type of lines.
>
>Thanks & Regards
>Gururaja


Oh, I needed something to do for a few hours.
I guess the below should parse C/C++ functions any way desired.

sln

---------------------------------------------------------

## Idea - To parse out C/C++ style functions
## that have parenthetical closures (some don't)
## ===============================================
use strict;
use warnings;

my $Source = join '', <DATA>;

my @Funct = (); # Holds sequential functions info;
# ie: substr indexes to 'name', '(', and ')' segment positions
my @Ndx = (); # Index stack of current @Funct elements in find recursion

my $Preamble = "\\s*\\("; # constant
my $Compliance = "_*[a-zA-Z][\\w]*"; # constant

my $FName = $Compliance; # Gets all functions, uses the compliant pattern
#my $FName = "\\(\\s*void\\s*\\)\\s*function"; # Extended, non-compliant function pattern

# ***************************************
# Or, uncomment these to search for a specific function name that is compliant.
# (Warning! FName should resolve to a compliant function name)
# If you wish to use a custom regex for FName (non-compliant), skip this block and enter FName above.
# -------------------------
# my $FName = "atoi";
# die "Function name pattern: '$FName' is non-compliant!\n" if ($FName !~ /$Compliance/);
# ***************************************

# The main pre-compiled parser regular expression
my $FxParse = qr/(\/{2}.*?\n)|(\/\*.*?\*\/)|($FName$Preamble)|(\()|(\))/s;
# 1 1|2 2|3 3|4 4|5 5

# Parse out some functions
Find_Function(\$Source);

# Print functions found
if (!@Funct) { print "Function name pattern: '$FName' not found!\n" }
else { print "\nFound ".@Funct." matches.\nFunction pattern: '$FName' \n" }
for my $ref (@Funct)
{
# print "@{$ref}\n";
print "\n\@: ";
print substr($Source,$ref->[0],$ref->[2]-$ref->[0]),"\n";
# Here, each function name and/or parameter can be printed
# and/or examined separately.
}

# Finished!
#

# ---------------------------------------------------------
# Recursive procedure that finds C/C++ style functions
# (the engine)
#
sub Find_Function
{
my ($src,$spos,$closure) = @_;
$spos = 0 if (!defined $spos);
$closure = 0 if (!defined $closure);
pos($$src) = $spos;

while ($$src =~ /$FxParse/g)
{
# $1/$2 - comments

if (defined $3) # 'function name'
{
push @Ndx, scalar(@Funct);
# positions: function ( )
push @Funct , [$-[0], pos($$src), 0];
# recurse this procedure
pos($$src) = Find_Function ( $src, pos($$src), 1 );
}
elsif (defined $4) # '('
{
++$closure;
}
elsif (defined $5) # ')'
{
--$closure;
if ($closure <= 0)
{
if (@Ndx)
{
$Funct[pop @Ndx]->[2] = pos($$src);
return pos($$src);
}
$closure = 0;
}
}
}
}

__DATA__

1. (void) function(....)
2. function(....)
3. return ( // some comments
function(..(atoi("398"), (5 * x)..)..,
/* ) <-forget this parenth */......)
)

---------------------------------------------
Do not copy from here down...
---------------------------------------------

Some various input/output:

c:\temp>perl c_functionparser.pl

Found 5 matches.
Function pattern: '_*[a-zA-Z][\w]*'

@: function(....)

@: function(....)

@: return ( // some comments
function(..(atoi("398"), (5 * x)..)..,
/* ) <-forget this parenth */......)
)

@: function(..(atoi("398"), (5 * x)..)..,
/* ) <-forget this parenth */......)

@: atoi("398")

c:\temp>

----------------------------

c:\temp>perl c_functionparser.pl

Found 3 matches.
Function pattern: 'function'

@: function(....)

@: function(....)

@: function(..(atoi("398"), (5 * x)..)..,
/* ) <-forget this parenth */......)

c:\temp>

---------------------------

c:\temp>perl c_functionparser.pl

Found 1 matches.
Function pattern: 'atoi'

@: atoi("398")

c:\temp>

---------------------------

c:\temp>perl c_functionparser.pl

Found 1 matches.
Function pattern: '\(\s*void\s*\)\s*function'

@: (void) function(....)

c:\temp>


 
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
Extracting files from an EXE Zagor ASP .Net 2 04-15-2006 11:39 PM
extracting text from files using IFilters kunal ASP .Net 0 10-15-2005 11:09 AM
extracting event logs to a file Gnaneshwar Babu Perl 0 12-31-2003 08:24 AM
Extracting records Dj Frenzy Perl 1 12-02-2003 11:01 PM
Extracting matches from Regex.Split Stephan Bour ASP .Net 3 10-30-2003 04:59 PM



Advertisments