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

Discussion in 'Perl Misc' started by guru, Feb 2, 2009.

  1. guru

    guru Guest

    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
    guru, Feb 2, 2009
    #1
    1. Advertising

  2. guru

    smallpond Guest

    Re: Extracting printf(...) from (void) printf(....)

    On Feb 2, 9:04 am, guru <> 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
    smallpond, Feb 2, 2009
    #2
    1. Advertising

  3. guru

    Guest

    On Mon, 2 Feb 2009 06:04:50 -0800 (PST), guru <> 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
    , Feb 2, 2009
    #3
  4. guru

    Guest

    On Mon, 02 Feb 2009 16:54:19 GMT, wrote:

    >On Mon, 2 Feb 2009 06:04:50 -0800 (PST), guru <> 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
    , Feb 2, 2009
    #4
  5. guru

    Guest

    On Mon, 02 Feb 2009 17:12:12 GMT, wrote:

    >On Mon, 02 Feb 2009 16:54:19 GMT, wrote:
    >
    >>On Mon, 2 Feb 2009 06:04:50 -0800 (PST), guru <> 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
    , Feb 2, 2009
    #5
  6. wrote:
    > On Mon, 2 Feb 2009 06:04:50 -0800 (PST), guru <> 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 ___
    \__________________________ http://toerring.de
    Jens Thoms Toerring, Feb 2, 2009
    #6
  7. guru

    Guest

    On 2 Feb 2009 18:54:43 GMT, (Jens Thoms Toerring) wrote:

    > wrote:
    >> On Mon, 2 Feb 2009 06:04:50 -0800 (PST), guru <> 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
    , Feb 2, 2009
    #7
  8. guru

    guru Guest

    Re: Extracting printf(...) from (void) printf(....)

    On Feb 2, 10:12 pm, wrote:
    > On Mon, 02 Feb 2009 16:54:19 GMT, wrote:
    > >On Mon, 2 Feb 2009 06:04:50 -0800 (PST), guru <> 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
    guru, Feb 3, 2009
    #8
  9. guru

    Guest

    Re: Extracting printf(...) from (void) printf(....)

    On Mon, 2 Feb 2009 20:31:45 -0800 (PST), guru <> wrote:

    >On Feb 2, 10:12 pm, wrote:
    >> On Mon, 02 Feb 2009 16:54:19 GMT, wrote:
    >> >On Mon, 2 Feb 2009 06:04:50 -0800 (PST), guru <> 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>
    , Feb 3, 2009
    #9
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ollej Reemt
    Replies:
    7
    Views:
    518
    Jack Klein
    Apr 22, 2005
  2. Stig Brautaset

    `void **' revisited: void *pop(void **root)

    Stig Brautaset, Oct 25, 2003, in forum: C Programming
    Replies:
    15
    Views:
    786
    The Real OS/2 Guy
    Oct 28, 2003
  3. whatluo

    (void) printf vs printf

    whatluo, May 26, 2005, in forum: C Programming
    Replies:
    29
    Views:
    1,238
  4. Replies:
    5
    Views:
    824
    S.Tobias
    Jul 22, 2005
  5. Replies:
    1
    Views:
    403
    Victor Bazarov
    May 23, 2007
Loading...

Share This Page