Help needed to write a regular expression.

V

Vittal

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 = $';
}
 
A

A. Sinan Unur

(e-mail address removed) (Vittal) wrote in
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.
 
J

John W. Krahn

Vittal said:
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
 
V

Vittal

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 said:
Vittal said:
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
 

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,995
Messages
2,570,230
Members
46,818
Latest member
Brigette36

Latest Threads

Top