Help needed to write a regular expression.

Discussion in 'Perl Misc' started by Vittal, Mar 9, 2005.

  1. Vittal

    Vittal Guest

    Hello All,

    I am writing a simple perl script to scan C/C++ Makefiles and list all
    the macros used in those Makefiles. For this I am using the below
    mentioned regular expression. The problem with this RE is that it does
    not show the complete macro definition. It cuts it short at new line
    character. As per makefile rules, if a line ends with "/" means it
    continues on to next line also. I want to add this portion into my RE
    so that I can catch the whole macro definition.

    Can someone help in this?

    Thanks
    -Vittal

    open INFILE, $FILE || die "Failed to open $FILE file \n";
    while (<INFILE>)
    {
    # Exclude all the lines starting with # in the
    makefile
    $temp .=$_ if (!/^#/);
    }

    $str_macro .= "\n$FILE\n\n";
    while ($temp && $temp =~ /(\w+)\s*=(\t| )*([^\n]+)/ )
    {
    print "\t$&\n";
    $temp = $';
    }
     
    Vittal, Mar 9, 2005
    #1
    1. Advertising

  2. (Vittal) wrote in
    news::

    > I am writing a simple perl script to scan C/C++ Makefiles and list all
    > the macros used in those Makefiles.


    Do you mean macros used or defined? If you really do mean 'used' then
    the task is pretty complicated.

    There must be a specification somewhere of the exact grammar of a macro
    definition in makefiles. Of course, this depends on whose make you are
    using. You did not specify this either.

    So, there is precious little information to go on. You would get better
    help if you helped others help you.

    > mentioned regular expression. The problem with this RE is that it does
    > not show the complete macro definition. It cuts it short at new line
    > character. As per makefile rules, if a line ends with "/" means it
    > continues on to next line also.


    Why don't you check for that then?

    ....

    > open INFILE, $FILE || die "Failed to open $FILE file \n";


    1. If you want to drop the parantheses in the call to open, you should
    use 'or' rather than '||'.

    D:\Home> cat f.pl
    use strict;
    use warnings;

    open my $f, '<', $ARGV[0] || die $!;
    print <$f>;

    D:\Home> f non-existent-file
    readline() on closed filehandle $f at D:\Home\f.pl line 5.

    2. You might want to figure out why open failed if open failed.

    D:\Home> cat f.pl
    use strict;
    use warnings;

    open my $f, '<', $ARGV[0] or die "Cannot open $ARGV[0]: $!";
    print <$f>;

    D:\Home> f non-existent-file
    Cannot open non-existent-file: No such file or directory at D:\Home\f.pl
    line 4.

    Of course, the script you posted is useless as there is no way for us to
    run it without jumping through a whole bunch of loops.

    > while (<INFILE>)
    > {
    > # Exclude all the lines starting with # in the
    > makefile
    > $temp .=$_ if (!/^#/);
    > }


    Why partially slurp the file?

    >
    > $str_macro .= "\n$FILE\n\n";
    > while ($temp && $temp =~ /(\w+)\s*=(\t| )*([^\n]+)/ )
    > {
    > print "\t$&\n";
    > $temp = $';
    > }


    You lost me.

    Sinan.
     
    A. Sinan Unur, Mar 9, 2005
    #2
    1. Advertising

  3. Vittal wrote:
    >
    > I am writing a simple perl script to scan C/C++ Makefiles and list all
    > the macros used in those Makefiles. For this I am using the below
    > mentioned regular expression. The problem with this RE is that it does
    > not show the complete macro definition. It cuts it short at new line
    > character. As per makefile rules, if a line ends with "/" means it


    Don't you mean if a line ends with '\'? That is what the Makefiles on my
    system use.


    > continues on to next line also. I want to add this portion into my RE
    > so that I can catch the whole macro definition.
    >
    > Can someone help in this?
    >
    > Thanks
    > -Vittal
    >
    > open INFILE, $FILE || die "Failed to open $FILE file \n";


    You have a precedence error. As long as $FILE does not contain '' or '0' then
    the error message will never be printed. You need to either use parentheses
    for the open() function or use the lower precedence 'or' operator. You should
    also include the $! variable in the error message so you will know why it failed.

    open INFILE, $FILE or die "Failed to open $FILE file: $!";


    > while (<INFILE>)
    > {
    > # Exclude all the lines starting with # in the
    > makefile
    > $temp .=$_ if (!/^#/);
    > }
    >
    > $str_macro .= "\n$FILE\n\n";
    > while ($temp && $temp =~ /(\w+)\s*=(\t| )*([^\n]+)/ )
    > {
    > print "\t$&\n";
    > $temp = $';
    > }


    my %macros;
    while ( <INFILE> ) {

    if ( s/\\\n// ) {
    $_ .= <INFILE>;
    redo;
    }

    if ( /(\w+)\s*=[\t ]*(.+)/ ) {
    $macros{ $1 } = $2;
    }
    }

    for my $key ( keys %macros ) {
    print "$key = $macros{$key}\n";
    }




    John
    --
    use Perl;
    program
    fulfillment
     
    John W. Krahn, Mar 9, 2005
    #3
  4. Vittal

    Vittal Guest

    Thank you very much John for your help. This is what I exactly wanted
    and had been struggling to write the regular expression.

    Thanks again
    -Vittal
    "John W. Krahn" <> wrote in message news:<BDAXd.23079$fc4.20716@edtnps89>...
    > Vittal wrote:
    > >
    > > I am writing a simple perl script to scan C/C++ Makefiles and list all
    > > the macros used in those Makefiles. For this I am using the below
    > > mentioned regular expression. The problem with this RE is that it does
    > > not show the complete macro definition. It cuts it short at new line
    > > character. As per makefile rules, if a line ends with "/" means it

    >
    > Don't you mean if a line ends with '\'? That is what the Makefiles on my
    > system use.
    >
    >
    > > continues on to next line also. I want to add this portion into my RE
    > > so that I can catch the whole macro definition.
    > >
    > > Can someone help in this?
    > >
    > > Thanks
    > > -Vittal
    > >
    > > open INFILE, $FILE || die "Failed to open $FILE file \n";

    >
    > You have a precedence error. As long as $FILE does not contain '' or '0' then
    > the error message will never be printed. You need to either use parentheses
    > for the open() function or use the lower precedence 'or' operator. You should
    > also include the $! variable in the error message so you will know why it failed.
    >
    > open INFILE, $FILE or die "Failed to open $FILE file: $!";
    >
    >
    > > while (<INFILE>)
    > > {
    > > # Exclude all the lines starting with # in the
    > > makefile
    > > $temp .=$_ if (!/^#/);
    > > }
    > >
    > > $str_macro .= "\n$FILE\n\n";
    > > while ($temp && $temp =~ /(\w+)\s*=(\t| )*([^\n]+)/ )
    > > {
    > > print "\t$&\n";
    > > $temp = $';
    > > }

    >
    > my %macros;
    > while ( <INFILE> ) {
    >
    > if ( s/\\\n// ) {
    > $_ .= <INFILE>;
    > redo;
    > }
    >
    > if ( /(\w+)\s*=[\t ]*(.+)/ ) {
    > $macros{ $1 } = $2;
    > }
    > }
    >
    > for my $key ( keys %macros ) {
    > print "$key = $macros{$key}\n";
    > }
    >
    >
    >
    >
    > John
     
    Vittal, Mar 10, 2005
    #4
    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. VSK
    Replies:
    2
    Views:
    2,381
  2. David Cho
    Replies:
    4
    Views:
    423
    David Cho
    Feb 15, 2005
  3. Chanchal
    Replies:
    1
    Views:
    502
    NullBock
    Dec 13, 2005
  4. pekka niiranen
    Replies:
    5
    Views:
    561
    Paul McGuire
    Oct 20, 2004
  5. ragz_82
    Replies:
    1
    Views:
    314
    ragz_82
    Aug 4, 2009
Loading...

Share This Page