glewis@fws204.pcocd2.intel.com (Glenn M. Lewis ~) (01/24/91)
[]
I have decided that it would be a good idea for me to Perl. So
I figured, "What better way than by writing a Perl program?" Now I have
a few questions that maybe you could help me with.
I want this program to read an input file, strip off all C-style
comments and TeX-style comments ('%...'), process any directives like
'#include "file"' and "#define a b", do any necessary search and replace
from previous "#define"s, and then check if the current line's first
word is the name of an executable file in my environment's $path. If it
is, execute it and pipe its output recursively through this Perl filter.
If the word is not an executable in my $path, then simply echo the line
to the STDOUT.
Simple, right? Well, I seem to have things working pretty well
except for the piping mechanism (and the restriction that C-style
comments can not be nested and must appear on a single line... *and*
the search of the executable only takes place in the current directory).
Since this is my very first program, I would appreciate it if
you critique my Perl programming techniques. Is this terribly
inefficient? Is it ugly? Is there a much easier way to do this? It
would also be nice if you could help me make it work as described above.
Thank you very much for your help! I doubt this is of general
interest, so e-mail responses would be fantastic.
-- Glenn Lewis
glewis%pcocd2.intel.com@Relay.CS.Net | These are my own opinions... not Intel's
#!/usr/local/mcfg/bin/perl
# $Id: pipe,v 1.3 1991/01/24 06:36:27 glewis Exp glewis $
# $Log: pipe,v $
# Revision 1.3 1991/01/24 06:36:27 glewis
# Right before messing around with cterm...
#
# Revision 1.2 1991/01/24 01:00:57 glewis
# Made main block into a subroutine
#
# Revision 1.1 1991/01/24 00:55:56 glewis
# Initial revision
#
$| = 1; # Flush output automatically
if ($#ARGV<0 && -t) { die "No files to be processed"; }
# print(STDERR "Processing $ARGV...\n");
#
sub process_line {
s/[ \t\n]*$//; # Remove trailing white space
s/^[ \t]*//; # Remove leading white space
s@[ \t]*/\*.*\*/@@; # Remove C-style comments
s/[ \t]*%.*$//; # Remove '%'-style comments
s/\t/ /g; # Change all '\t' to ' '
# Process directives...
if (/#/) {
if (/#include/) {
s/^.*#include *//; # Remove directive
s/;$//; # Strip trailing semicolon
s/"//g; # Remove quotes
if (! -T) {
print(STDERR " Can't open $_ for input\n");
} else {
print(STDERR " Processing: $_\n");
open(FILE, $_);
while (<FILE>) {
&process_line;
}
close(FILE);
}
next;
}
if (/#define/) { # Save definitions
s/^.*#define *//; # Remove directive
split; # Separate components
$name = $_[0]; # Definition name
s/$name *//; # Remove name
$definition{$name} = $_;
print(STDERR " Equating '$name' = '$definition{$name}'\n");
next;
}
}
# Process through list of "#define"s...
while (($key,$value) = each %definition) { s/$key/$value/g; }
# Finally, take a look at the resulting string...
$num = split;
next if (!$num); # Skip blank line
# print(STDERR "$num items: '$_'\n");
if (-x $_[0]) {
print(STDERR " Processing: $_\n");
pipe(PROGIN,PERLOUT) || die "pipe can\'t create pipe PROGIN/PERLOUT" ;
pipe(PERLIN,PROGOUT) || die "pipe can\'t create pipe PERLIN/PROGOUT" ;
$pipePid = fork ;
$command = $_;
$fileno_in = fileno(PROGIN);
$fileno_out = fileno(PROGOUT);
if ( $pipePid == 0 )
{ close(PERLIN) || die "pipe can\'t close PERLIN" ;
close(PERLOUT) || die "pipe can\'t close PERLOUT" ;
exec("$command <&$fileno_in >&$fileno_out") ;
die "pipe can\'t exec $command" ;
}
else
{ close(PROGIN) || die "pipe can\'t close PROGIN" ;
close(PROGOUT) || die "pipe can\'t close PROGOUT" ;
open(SAVESTDIN, "<&STDIN") || die 'pipe can\'t save STDIN' ;
open(SAVESTDOUT,">&STDOUT") || die 'pipe can\'t save STDOUT' ;
open(STDIN, "<&PERLIN") || die 'pipe can\'t redirect STDIN' ;
open(STDOUT,">&PERLOUT") || die 'pipe can\'t redirect STDOUT' ;
$prePipeSelect = select(STDOUT);
$| = 0;
}
while (<PERLIN>) {
&process_line;
}
close(PERLOUT) ;
sleep 1 ;
close(PERLIN) ;
open(STDIN, "<&SAVESTDIN") || die 'pipe can\'t reredirect STDIN' ;
open(STDOUT,">&SAVESTDOUT") || die 'pipe can\'t reredirect STDOUT' ;
close(SAVESTDIN) ;
close(SAVESTDOUT) ;
select($prePipeSelect);
$| = 1;
} else {
print("$_\n");
}
}
#
# End of process_line subroutine
#
while (<>) {
&process_line;
}
exit(0);
--
glewis%pcocd2.intel.com@Relay.CS.Net | These are my own opinions... not Intel'sglewis@fws204.intel.com (Glenn M. Lewis ~) (01/25/91)
[] I am very sorry for the wasted bandwidth, by the "From:" line in my previous posting was wrong, hence any replies would bounce. You can send mail to me at "glewis@pcocd2.intel.com" or "glewis%pcocd2.intel.com@uunet.uu.net". Also, the first line said "...a good idea for me to Perl". I meant to say "...a good idea for me to LEARN Perl." Ooops. Thanks again for any help you can provide. -- Glenn Lewis -- glewis%pcocd2.intel.com@Relay.CS.Net | These are my own opinions... not Intel's