4 use File::Basename qw(&basename &dirname);
7 # List explicitly here the variables you want Configure to
8 # generate. Metaconfig only looks for shell variables, so you
9 # have to mention them as if they were shell variables, not
10 # %Config entries. Thus you write
12 # to ensure Configure will look for $Config{startperl}.
14 # This forces PL files to create target in same directory as PL file.
15 # This is so that make depend always knows where to find PL derivatives.
18 $file = basename($0, '.PL');
19 $file .= '.com' if $^O eq 'VMS';
21 open OUT,">$file" or die "Can't create $file: $!";
23 print "Extracting $file (with variable substitutions)\n";
25 # In this section, perl variables will be expanded during extraction.
26 # You can use $Config{...} to use Configure variables.
28 print OUT <<"!GROK!THIS!";
30 eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
31 if \$running_under_some_shell;
32 \$startperl = "$Config{startperl}";
33 \$perlpath = "$Config{perlpath}";
36 # In the following, perl variables are not expanded during extraction.
38 print OUT <<'!NO!SUBS!';
40 # $RCSfile: s2p.SH,v $$Revision: 4.1 $$Date: 92/08/07 18:29:23 $
46 s2p - Sed to Perl translator
50 B<s2p [options] filename>
54 I<s2p> takes a sed script specified on the command line (or from
55 standard input) and produces a comparable I<perl> script on the
64 =item B<-DE<lt>numberE<gt>>
70 specifies that this sed script was always invoked with a B<sed -n>.
71 Otherwise a switch parser is prepended to the front of the script.
75 specifies that this sed script was never invoked with a B<sed -n>.
76 Otherwise a switch parser is prepended to the front of the script.
82 The perl script produced looks very sed-ish, and there may very well
83 be better ways to express what you want to do in perl. For instance,
84 s2p does not make any use of the split operator, but you might want
87 The perl script you end up with may be either faster or slower than
88 the original sed script. If you're only interested in speed you'll
89 just have to try it both ways. Of course, if you want to do something
90 sed doesn't do, you have no choice. It's often possible to speed up
91 the perl script by various methods, such as deleting all references to
96 s2p uses no environment variables.
100 Larry Wall E<lt>F<larry@wall.org>E<gt>
106 perl The perl compiler/interpreter
108 a2p awk to perl translator
120 while ($ARGV[0] =~ /^-/) {
136 die "I don't recognize this switch: $_\n";
140 open(BODY,"+>/tmp/sperl$$") ||
141 &Die("Can't open temp file: $!\n");
144 if (!$assumen && !$assumep) {
145 print BODY &q(<<'EOT');
146 : while ($ARGV[0] =~ /^-/) {
153 : die "I don't recognize this switch: $_\\n";
159 print BODY &q(<<'EOT');
164 : $printit++ unless $nflag;
168 : $\ = "\n"; # automatically add newline on print
172 : while (chop($_ = <>)) {
183 # Wipe out surrounding whitespace.
187 # Perhaps it's a label/comment.
191 $label = &make_label($_);
194 if (/^(top|(re)?start|redo|begin(ning)|again|input)$/i) {
196 redo LINE; # Never referenced, so delete it if not a comment.
200 if ($lastlinewaslabel++) {
202 print BODY &tab, ";\n";
211 $lastlinewaslabel = '';
214 # Look for one or two address clauses
220 $addr1 = "\$. == $addr1" unless /^,/;
226 $addr1 = &fetchpat('/');
234 $addr2 = &fetchpat('/');
236 &Die("Invalid second address at line $.\n");
238 if ($addr2 =~ /^\d+$/) {
239 $addr1 .= "..$addr2";
242 $addr1 .= "...$addr2";
246 # Now we check for metacommands {, }, and ! and worry
250 # a { to keep vi happy
257 $else = "$r else $l\n";
262 if (s/^{//) { # a } to keep vi happy
269 if ($addr2 || $addr1) {
270 $space = ' ' x $shiftwidth;
274 $_ = &transmogrify();
277 # See if we can optimize to modifier form.
280 if ($_ !~ /[\n{}]/ && $rmaybe && !$change &&
281 $_ !~ / if / && $_ !~ / unless /) {
283 $_ = substr($_,$shiftwidth,1000);
285 $_ = "$if ($addr1) $l\n$change$_$rmaybe";
291 @lines = split(/\n/,$_);
293 unless (s/^ *<<--//) {
306 if ($lastlinewaslabel++) {
308 print BODY &tab, ";\n";
312 if ($appendseen || $tseen || !$assumen) {
313 $printit++ if $dseen || (!$assumen && !$assumep);
314 print BODY &q(<<'EOT');
322 : print if $printit++;
327 : { $printit++ unless $nflag; }
339 : if ($atext) { chop $atext; print $atext; $atext = ''; }
344 print BODY &q(<<'EOT');
352 : eval 'exec $perlpath -S \$0 \${1+"\$@"}'
353 : if \$running_under_some_shell;
356 print"$opens\n" if $opens;
357 seek(BODY, 0, 0) || die "Can't rewind temp file: $!\n";
360 /^#ifdef (\w+)/ && ((${lc $1} || &skip), next);
361 /^#else/ && (&skip, next);
372 unlink "/tmp/sperl$$";
379 "\t" x ($indent / 8) . ' ' x ($indent % 8);
381 sub make_filehandle {
384 if (!$seen{$fname}) {
385 $_ = "FH_" . $_ if /^\d/;
390 for ($tmp = "a"; $fhseen{"$_$tmp"}; $a++) {}
394 $opens .= &q(<<"EOT");
395 : open($_, '>$fname') || die "Can't create $fname: \$!";
404 $label =~ s/[^a-zA-Z0-9]/_/g;
405 if ($label =~ /^[0-9_]/) { $label = 'L' . $label; }
406 $label = substr($label,0,8);
408 # Could be a reserved word, so capitalize it.
409 substr($label,0,1) =~ y/a-z/A-Z/
410 if $label =~ /^[a-z]/;
419 chop($_ = &q(<<'EOT'));
430 chop($_ = &q(<<'EOT'));
434 : print if $printit++;
439 : { $printit++ unless $nflag; }
447 : <<--#ifdef APPENDSEEN
448 : if ($atext) {chop $atext; print $atext; $atext = '';}
461 $command = $space . "\$atext .= <<'End_Of_Text';\n<<--";
466 unless (s|\\$||) { $lastline = 1;}
467 s/^([ \t]*\n)/<><>$1/;
472 $_ = $command . "End_Of_Text";
477 if (/^c/) { $change = 1; }
478 $addr1 = 1 if $addr1 eq '';
479 $addr1 = '$iter = (' . $addr1 . ')';
481 " if (\$iter == 1) { print <<'End_Of_Text'; }\n<<--";
486 unless (s/\\$//) { $lastline = 1;}
488 s/^([ \t]*\n)/<><>$1/;
493 $_ = $command . "End_Of_Text";
497 chop($_ = &q(<<"EOT"));
499 : $space\$printit = 0;
509 $delim = substr($_,1,1);
513 for ($i = 2; $i < $len; $i++) {
514 $c = substr($_,$i,1);
517 substr($_, $i, 0) = '\\';
536 $_ = substr($_,0,--$len);
538 elsif (substr($_,$i,1) =~ /^[n]$/) {
542 substr($_,$i,1) =~ /^[(){}\w]$/) {
545 substr($_, $i, 1) = '';
548 substr($_,$i,1) =~ /^[<>]$/) {
549 substr($_,$i,1) = 'b';
551 elsif ($repl && substr($_,$i,1) =~ /^\d$/) {
552 substr($_,$i-1,1) = '$';
556 substr($_, $i, 0) = '\\';
560 elsif ($c eq '&' && $repl) {
561 substr($_, $i, 0) = '$';
565 elsif ($c eq '$' && $repl) {
566 substr($_, $i, 0) = '\\';
570 elsif ($c eq '[' && !$repl) {
571 $i++ if substr($_,$i,1) eq '^';
572 $i++ if substr($_,$i,1) eq ']';
579 substr($_, $i, 1) = '\\t';
583 elsif (!$repl && index("()+",$c) >= 0) {
584 substr($_, $i, 0) = '\\';
589 &Die("Malformed substitution at line $.\n")
591 $pat = substr($_, 0, $repl + 1);
592 $repl = substr($_, $repl+1, $end-$repl-1);
593 $end = substr($_, $end + 1, 1000);
595 $subst = "$pat$repl$delim";
598 if ($end =~ s/^g//) {
602 if ($end =~ s/^p//) {
603 $cmd .= ' && (print)';
606 if ($end =~ s/^w[ \t]*//) {
607 $fh = &make_filehandle($end);
608 $cmd .= " && (print $fh \$_)";
612 &Die("Unrecognized substitution command".
613 "($end) at line $.\n");
615 chop ($_ = &q(<<"EOT"));
617 : $subst && \$tflag++$cmd;
632 $fh = &make_filehandle($_);
633 $_ = "print $fh \$_;";
641 $_ = "\$atext .= `cat $file 2>/dev/null`;";
646 $_ = 'print $1 if /^(.*)/;';
651 chop($_ = &q(<<'EOT'));
661 chop($_ = &q(<<'EOT'));
665 : chop if $len1 < length;
679 $_ = '$hold .= "\n", $hold .= $_;';
689 $_ = '$_ .= "\n", $_ .= $hold;';
694 $_ = '($_, $hold) = ($hold, $_);';
706 $lab = &make_label($_);
707 if ($lab eq $toplabel) {
716 $_ = 'next LINE if $tflag;';
724 $lab = &make_label($_);
725 $_ = q/if ($tflag) {$tflag = 0; /;
726 if ($lab eq $toplabel) {
736 s/abcdefghijklmnopqrstuvwxyz/a-z/g;
737 s/ABCDEFGHIJKLMNOPQRSTUVWXYZ/A-Z/g;
751 chop($_ = &q(<<'EOT'));
762 s/(\n)(.)/$1$space$2/g;
771 local($addr) = $outer;
773 local($prefix,$delim,$ch);
775 # Process pattern one potential delimiter at a time.
777 DELIM: while (s#^([^\]+(|)[\\/]*)([]+(|)[\\/])##) {
780 if ($delim eq '\\') {
783 $delim = '' if $ch =~ /^[(){}A-Za-mo-z]$/;
784 $ch = 'b' if $ch =~ /^[<>]$/;
787 elsif ($delim eq '[') {
789 s/^\^// && ($delim .= '^');
790 s/^]// && ($delim .= ']');
792 elsif ($delim eq ']') {
795 elsif ($inbracket || $delim ne $outer) {
796 $delim = '\\' . $delim;
800 if ($delim eq $outer && !$inbracket) {
813 $string =~ s/^:\t?//g;
818 $_[0] =~ s/_a-za-z0-9/\\w/ig;
819 $_[0] =~ s/a-z_a-z0-9/\\w/ig;
820 $_[0] =~ s/a-za-z_0-9/\\w/ig;
821 $_[0] =~ s/a-za-z0-9_/\\w/ig;
822 $_[0] =~ s/_0-9a-za-z/\\w/ig;
823 $_[0] =~ s/0-9_a-za-z/\\w/ig;
824 $_[0] =~ s/0-9a-z_a-z/\\w/ig;
825 $_[0] =~ s/0-9a-za-z_/\\w/ig;
826 $_[0] =~ s/\[\\w\]/\\w/g;
827 $_[0] =~ s/\[^\\w\]/\\W/g;
828 $_[0] =~ s/\[0-9\]/\\d/g;
829 $_[0] =~ s/\[^0-9\]/\\D/g;
830 $_[0] =~ s/\\d\\d\*/\\d+/g;
831 $_[0] =~ s/\\D\\D\*/\\D+/g;
832 $_[0] =~ s/\\w\\w\*/\\w+/g;
833 $_[0] =~ s/\\t\\t\*/\\t+/g;
834 $_[0] =~ s/(\[.[^]]*\])\1\*/$1+/g;
835 $_[0] =~ s/([\w\s!@#%^&-=,:;'"])\1\*/$1+/g;
842 /^#ifdef/ && $level++;
843 /^#else/ && !$level && return;
844 /^#endif/ && !$level-- && return;
847 die "Unterminated `#ifdef' conditional\n";
851 close OUT or die "Can't close $file: $!";
852 chmod 0755, $file or die "Can't reset permissions for $file: $!\n";
853 exec("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':';