home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / PERL4036.ZIP / os2 / s2p.cmd < prev    next >
OS/2 REXX Batch file  |  1993-02-08  |  12KB  |  677 lines

  1. extproc perl -Sx
  2. #!perl
  3.  
  4. $bin = 'c:/bin';
  5.  
  6. # $Header: s2p.cmd,v 4.0 91/03/20 01:37:09 lwall Locked $
  7. #
  8. # $Log:    s2p.cmd,v $
  9. # Revision 4.0  91/03/20  01:37:09  lwall
  10. # 4.0 baseline.
  11. # Revision 3.0.1.6  90/10/20  02:21:43  lwall
  12. # patch37: changed some ". config.sh" to ". ./config.sh"
  13. #
  14. # Revision 3.0.1.5  90/10/16  11:32:40  lwall
  15. # patch29: s2p modernized
  16. #
  17. # Revision 3.0.1.4  90/08/09  05:50:43  lwall
  18. # patch19: s2p didn't translate \n right
  19. #
  20. # Revision 3.0.1.3  90/03/01  10:31:21  lwall
  21. # patch9: s2p didn't handle \< and \>
  22. #
  23. # Revision 3.0.1.2  89/11/17  15:51:27  lwall
  24. # patch5: in s2p, line labels without a subsequent statement were done wrong
  25. # patch5: s2p left residue in /tmp
  26. #
  27. # Revision 3.0.1.1  89/11/11  05:08:25  lwall
  28. # patch2: in s2p, + within patterns needed backslashing
  29. # patch2: s2p was printing out some debugging info to the output file
  30. #
  31. # Revision 3.0  89/10/18  15:35:02  lwall
  32. # 3.0 baseline
  33. #
  34. # Revision 2.0.1.1  88/07/11  23:26:23  root
  35. # patch2: s2p didn't put a proper prologue on output script
  36. #
  37. # Revision 2.0  88/06/05  00:15:55  root
  38. # Baseline version 2.0.
  39. #
  40. #
  41.  
  42. $indent = 4;
  43. $shiftwidth = 4;
  44. $l = '{'; $r = '}';
  45.  
  46. while ($ARGV[0] =~ /^-/) {
  47.     $_ = shift;
  48.   last if /^--/;
  49.     if (/^-D/) {
  50.     $debug++;
  51.     open(BODY,'>-');
  52.     next;
  53.     }
  54.     if (/^-n/) {
  55.     $assumen++;
  56.     next;
  57.     }
  58.     if (/^-p/) {
  59.     $assumep++;
  60.     next;
  61.     }
  62.     die "I don't recognize this switch: $_\n";
  63. }
  64.  
  65. unless ($debug) {
  66.     open(BODY,">sperl$$") ||
  67.       &Die("Can't open temp file: $!\n");
  68. }
  69.  
  70. if (!$assumen && !$assumep) {
  71.     print BODY <<'EOT';
  72. while ($ARGV[0] =~ /^-/) {
  73.     $_ = shift;
  74.   last if /^--/;
  75.     if (/^-n/) {
  76.     $nflag++;
  77.     next;
  78.     }
  79.     die "I don't recognize this switch: $_\\n";
  80. }
  81.  
  82. EOT
  83. }
  84.  
  85. print BODY <<'EOT';
  86.  
  87. #ifdef PRINTIT
  88. #ifdef ASSUMEP
  89. $printit++;
  90. #else
  91. $printit++ unless $nflag;
  92. #endif
  93. #endif
  94. LINE: while (<>) {
  95. EOT
  96.  
  97. LINE: while (<>) {
  98.  
  99.     # Wipe out surrounding whitespace.
  100.  
  101.     s/[ \t]*(.*)\n$/$1/;
  102.  
  103.     # Perhaps it's a label/comment.
  104.  
  105.     if (/^:/) {
  106.     s/^:[ \t]*//;
  107.     $label = &make_label($_);
  108.     if ($. == 1) {
  109.         $toplabel = $label;
  110.     }
  111.     $_ = "$label:";
  112.     if ($lastlinewaslabel++) {
  113.         $indent += 4;
  114.         print BODY &tab, ";\n";
  115.         $indent -= 4;
  116.     }
  117.     if ($indent >= 2) {
  118.         $indent -= 2;
  119.         $indmod = 2;
  120.     }
  121.     next;
  122.     } else {
  123.     $lastlinewaslabel = '';
  124.     }
  125.  
  126.     # Look for one or two address clauses
  127.  
  128.     $addr1 = '';
  129.     $addr2 = '';
  130.     if (s/^([0-9]+)//) {
  131.     $addr1 = "$1";
  132.     }
  133.     elsif (s/^\$//) {
  134.     $addr1 = 'eof()';
  135.     }
  136.     elsif (s|^/||) {
  137.     $addr1 = &fetchpat('/');
  138.     }
  139.     if (s/^,//) {
  140.     if (s/^([0-9]+)//) {
  141.         $addr2 = "$1";
  142.     } elsif (s/^\$//) {
  143.         $addr2 = "eof()";
  144.     } elsif (s|^/||) {
  145.         $addr2 = &fetchpat('/');
  146.     } else {
  147.         &Die("Invalid second address at line $.\n");
  148.     }
  149.     $addr1 .= " .. $addr2";
  150.     }
  151.  
  152.     # Now we check for metacommands {, }, and ! and worry
  153.     # about indentation.
  154.  
  155.     s/^[ \t]+//;
  156.     # a { to keep vi happy
  157.     if ($_ eq '}') {
  158.     $indent -= 4;
  159.     next;
  160.     }
  161.     if (s/^!//) {
  162.     $if = 'unless';
  163.     $else = "$r else $l\n";
  164.     } else {
  165.     $if = 'if';
  166.     $else = '';
  167.     }
  168.     if (s/^{//) {    # a } to keep vi happy
  169.     $indmod = 4;
  170.     $redo = $_;
  171.     $_ = '';
  172.     $rmaybe = '';
  173.     } else {
  174.     $rmaybe = "\n$r";
  175.     if ($addr2 || $addr1) {
  176.         $space = ' ' x $shiftwidth;
  177.     } else {
  178.         $space = '';
  179.     }
  180.     $_ = &transmogrify();
  181.     }
  182.  
  183.     # See if we can optimize to modifier form.
  184.  
  185.     if ($addr1) {
  186.     if ($_ !~ /[\n{}]/ && $rmaybe && !$change &&
  187.       $_ !~ / if / && $_ !~ / unless /) {
  188.         s/;$/ $if $addr1;/;
  189.         $_ = substr($_,$shiftwidth,1000);
  190.     } else {
  191.         $_ = "$if ($addr1) $l\n$change$_$rmaybe";
  192.     }
  193.     $change = '';
  194.     next LINE;
  195.     }
  196. } continue {
  197.     @lines = split(/\n/,$_);
  198.     for (@lines) {
  199.     unless (s/^ *<<--//) {
  200.         print BODY &tab;
  201.     }
  202.     print BODY $_, "\n";
  203.     }
  204.     $indent += $indmod;
  205.     $indmod = 0;
  206.     if ($redo) {
  207.     $_ = $redo;
  208.     $redo = '';
  209.     redo LINE;
  210.     }
  211. }
  212. if ($lastlinewaslabel++) {
  213.     $indent += 4;
  214.     print BODY &tab, ";\n";
  215.     $indent -= 4;
  216. }
  217.  
  218. print BODY "}\n";
  219. if ($appendseen || $tseen || !$assumen) {
  220.     $printit++ if $dseen || (!$assumen && !$assumep);
  221.     print BODY <<'EOT';
  222.  
  223. continue {
  224. #ifdef PRINTIT
  225. #ifdef DSEEN
  226. #ifdef ASSUMEP
  227.     print if $printit++;
  228. #else
  229.     if ($printit)
  230.     { print; }
  231.     else
  232.     { $printit++ unless $nflag; }
  233. #endif
  234. #else
  235.     print if $printit;
  236. #endif
  237. #else
  238.     print;
  239. #endif
  240. #ifdef TSEEN
  241.     $tflag = '';
  242. #endif
  243. #ifdef APPENDSEEN
  244.     if ($atext) { print $atext; $atext = ''; }
  245. #endif
  246. }
  247. EOT
  248. }
  249.  
  250. close BODY;
  251.  
  252. unless ($debug) {
  253.     open(HEAD,">sperl2$$.c")
  254.       || &Die("Can't open temp file 2: $!\n");
  255.     print HEAD "#define PRINTIT\n" if ($printit);
  256.     print HEAD "#define APPENDSEEN\n" if ($appendseen);
  257.     print HEAD "#define TSEEN\n" if ($tseen);
  258.     print HEAD "#define DSEEN\n" if ($dseen);
  259.     print HEAD "#define ASSUMEN\n" if ($assumen);
  260.     print HEAD "#define ASSUMEP\n" if ($assumep);
  261.     if ($opens) {print HEAD "$opens\n";}
  262.     open(BODY,"sperl$$")
  263.       || &Die("Can't reopen temp file: $!\n");
  264.     while (<BODY>) {
  265.     print HEAD $_;
  266.     }
  267.     close HEAD;
  268.  
  269.     print <<"EOT";
  270. #!$bin/perl
  271. eval 'exec $bin/perl -S \$0 \$*'
  272.     if \$running_under_some_shell;
  273.  
  274. EOT
  275.     open(BODY,"cc -E sperl2$$.c |") ||
  276.     &Die("Can't reopen temp file: $!\n");
  277.     while (<BODY>) {
  278.     /^# [0-9]/ && next;
  279.     /^[ \t]*$/ && next;
  280.     s/^<><>//;
  281.     print;
  282.     }
  283. }
  284.  
  285. &Cleanup;
  286. exit;
  287.  
  288. sub Cleanup {
  289.     unlink "sperl$$", "sperl2$$", "sperl2$$.c";
  290. }
  291. sub Die {
  292.     &Cleanup;
  293.     die $_[0];
  294. }
  295. sub tab {
  296.     "\t" x ($indent / 8) . ' ' x ($indent % 8);
  297. }
  298. sub make_filehandle {
  299.     local($_) = $_[0];
  300.     local($fname) = $_;
  301.     s/[^a-zA-Z]/_/g;
  302.     s/^_*//;
  303.     substr($_,0,1) =~ y/a-z/A-Z/ if /^[a-z]/;
  304.     if (!$seen{$_}) {
  305.     $opens .= <<"EOT";
  306. open($_,'>$fname') || die "Can't create $fname";
  307. EOT
  308.     }
  309.     $seen{$_} = $_;
  310. }
  311.  
  312. sub make_label {
  313.     local($label) = @_;
  314.     $label =~ s/[^a-zA-Z0-9]/_/g;
  315.     if ($label =~ /^[0-9_]/) { $label = 'L' . $label; }
  316.     $label = substr($label,0,8);
  317.  
  318.     # Could be a reserved word, so capitalize it.
  319.     substr($label,0,1) =~ y/a-z/A-Z/
  320.       if $label =~ /^[a-z]/;
  321.  
  322.     $label;
  323. }
  324.  
  325. sub transmogrify {
  326.     {    # case
  327.     if (/^d/) {
  328.         $dseen++;
  329.         chop($_ = <<'EOT');
  330. <<--#ifdef PRINTIT
  331. $printit = '';
  332. <<--#endif
  333. next LINE;
  334. EOT
  335.         next;
  336.     }
  337.  
  338.     if (/^n/) {
  339.         chop($_ = <<'EOT');
  340. <<--#ifdef PRINTIT
  341. <<--#ifdef DSEEN
  342. <<--#ifdef ASSUMEP
  343. print if $printit++;
  344. <<--#else
  345. if ($printit)
  346.     { print; }
  347. else
  348.     { $printit++ unless $nflag; }
  349. <<--#endif
  350. <<--#else
  351. print if $printit;
  352. <<--#endif
  353. <<--#else
  354. print;
  355. <<--#endif
  356. <<--#ifdef APPENDSEEN
  357. if ($atext) {print $atext; $atext = '';}
  358. <<--#endif
  359. $_ = <>;
  360. <<--#ifdef TSEEN
  361. $tflag = '';
  362. <<--#endif
  363. EOT
  364.         next;
  365.     }
  366.  
  367.     if (/^a/) {
  368.         $appendseen++;
  369.         $command = $space . '$atext .=' . "\n<<--'";
  370.         $lastline = 0;
  371.         while (<>) {
  372.         s/^[ \t]*//;
  373.         s/^[\\]//;
  374.         unless (s|\\$||) { $lastline = 1;}
  375.         s/'/\\'/g;
  376.         s/^([ \t]*\n)/<><>$1/;
  377.         $command .= $_;
  378.         $command .= '<<--';
  379.         last if $lastline;
  380.         }
  381.         $_ = $command . "';";
  382.         last;
  383.     }
  384.  
  385.     if (/^[ic]/) {
  386.         if (/^c/) { $change = 1; }
  387.         $addr1 = '$iter = (' . $addr1 . ')';
  388.         $command = $space . 'if ($iter == 1) { print'
  389.           . "\n<<--'";
  390.         $lastline = 0;
  391.         while (<>) {
  392.         s/^[ \t]*//;
  393.         s/^[\\]//;
  394.         unless (s/\\$//) { $lastline = 1;}
  395.         s/'/\\'/g;
  396.         s/^([ \t]*\n)/<><>$1/;
  397.         $command .= $_;
  398.         $command .= '<<--';
  399.         last if $lastline;
  400.         }
  401.         $_ = $command . "';}";
  402.         if ($change) {
  403.         $dseen++;
  404.         $change = "$_\n";
  405.         chop($_ = <<"EOT");
  406. <<--#ifdef PRINTIT
  407. $space\$printit = '';
  408. <<--#endif
  409. ${space}next LINE;
  410. EOT
  411.         }
  412.         last;
  413.     }
  414.  
  415.     if (/^s/) {
  416.         $delim = substr($_,1,1);
  417.         $len = length($_);
  418.         $repl = $end = 0;
  419.         $inbracket = 0;
  420.         for ($i = 2; $i < $len; $i++) {
  421.         $c = substr($_,$i,1);
  422.         if ($c eq $delim) {
  423.             if ($inbracket) {
  424.             substr($_, $i, 0) = '\\';
  425.             $i++;
  426.             $len++;
  427.             }
  428.             else {
  429.             if ($repl) {
  430.                 $end = $i;
  431.                 last;
  432.             } else {
  433.                 $repl = $i;
  434.             }
  435.             }
  436.         }
  437.         elsif ($c eq '\\') {
  438.             $i++;
  439.             if ($i >= $len) {
  440.             $_ .= 'n';
  441.             $_ .= <>;
  442.             $len = length($_);
  443.             $_ = substr($_,0,--$len);
  444.             }
  445.             elsif (substr($_,$i,1) =~ /^[n]$/) {
  446.             ;
  447.             }
  448.             elsif (!$repl &&
  449.               substr($_,$i,1) =~ /^[(){}\w]$/) {
  450.             $i--;
  451.             $len--;
  452.             substr($_, $i, 1) = '';
  453.             }
  454.             elsif (!$repl &&
  455.               substr($_,$i,1) =~ /^[<>]$/) {
  456.             substr($_,$i,1) = 'b';
  457.             }
  458.         }
  459.         elsif ($c eq '[' && !$repl) {
  460.             $i++ if substr($_,$i,1) eq '^';
  461.             $i++ if substr($_,$i,1) eq ']';
  462.             $inbracket = 1;
  463.         }
  464.         elsif ($c eq ']') {
  465.             $inbracket = 0;
  466.         }
  467.         elsif (!$repl && index("()+",$c) >= 0) {
  468.             substr($_, $i, 0) = '\\';
  469.             $i++;
  470.             $len++;
  471.         }
  472.         }
  473.         &Die("Malformed substitution at line $.\n")
  474.           unless $end;
  475.         $pat = substr($_, 0, $repl + 1);
  476.         $repl = substr($_, $repl+1, $end-$repl-1);
  477.         $end = substr($_, $end + 1, 1000);
  478.         $dol = '$';
  479.         $repl =~ s/\$/\\$/;
  480.         $repl =~ s'&'$&'g;
  481.         $repl =~ s/[\\]([0-9])/$dol$1/g;
  482.         $subst = "$pat$repl$delim";
  483.         $cmd = '';
  484.         while ($end) {
  485.         if ($end =~ s/^g//) {
  486.             $subst .= 'g';
  487.             next;
  488.         }
  489.         if ($end =~ s/^p//) {
  490.             $cmd .= ' && (print)';
  491.             next;
  492.         }
  493.         if ($end =~ s/^w[ \t]*//) {
  494.             $fh = &make_filehandle($end);
  495.             $cmd .= " && (print $fh \$_)";
  496.             $end = '';
  497.             next;
  498.         }
  499.         &Die("Unrecognized substitution command".
  500.           "($end) at line $.\n");
  501.         }
  502.         chop ($_ = <<"EOT");
  503. <<--#ifdef TSEEN
  504. $subst && \$tflag++$cmd;
  505. <<--#else
  506. $subst$cmd;
  507. <<--#endif
  508. EOT
  509.         next;
  510.     }
  511.  
  512.     if (/^p/) {
  513.         $_ = 'print;';
  514.         next;
  515.     }
  516.  
  517.     if (/^w/) {
  518.         s/^w[ \t]*//;
  519.         $fh = &make_filehandle($_);
  520.         $_ = "print $fh \$_;";
  521.         next;
  522.     }
  523.  
  524.     if (/^r/) {
  525.         $appendseen++;
  526.         s/^r[ \t]*//;
  527.         $file = $_;
  528.         $_ = "\$atext .= `cat $file 2>/dev/null`;";
  529.         next;
  530.     }
  531.  
  532.     if (/^P/) {
  533.         $_ = 'print $1 if /(^.*\n)/;';
  534.         next;
  535.     }
  536.  
  537.     if (/^D/) {
  538.         chop($_ = <<'EOT');
  539. s/^.*\n//;
  540. redo LINE if $_;
  541. next LINE;
  542. EOT
  543.         next;
  544.     }
  545.  
  546.     if (/^N/) {
  547.         chop($_ = <<'EOT');
  548. $_ .= <>;
  549. <<--#ifdef TSEEN
  550. $tflag = '';
  551. <<--#endif
  552. EOT
  553.         next;
  554.     }
  555.  
  556.     if (/^h/) {
  557.         $_ = '$hold = $_;';
  558.         next;
  559.     }
  560.  
  561.     if (/^H/) {
  562.         $_ = '$hold .= $_ ? $_ : "\n";';
  563.         next;
  564.     }
  565.  
  566.     if (/^g/) {
  567.         $_ = '$_ = $hold;';
  568.         next;
  569.     }
  570.  
  571.     if (/^G/) {
  572.         $_ = '$_ .= $hold ? $hold : "\n";';
  573.         next;
  574.     }
  575.  
  576.     if (/^x/) {
  577.         $_ = '($_, $hold) = ($hold, $_);';
  578.         next;
  579.     }
  580.  
  581.     if (/^b$/) {
  582.         $_ = 'next LINE;';
  583.         next;
  584.     }
  585.  
  586.     if (/^b/) {
  587.         s/^b[ \t]*//;
  588.         $lab = &make_label($_);
  589.         if ($lab eq $toplabel) {
  590.         $_ = 'redo LINE;';
  591.         } else {
  592.         $_ = "goto $lab;";
  593.         }
  594.         next;
  595.     }
  596.  
  597.     if (/^t$/) {
  598.         $_ = 'next LINE if $tflag;';
  599.         $tseen++;
  600.         next;
  601.     }
  602.  
  603.     if (/^t/) {
  604.         s/^t[ \t]*//;
  605.         $lab = &make_label($_);
  606.         $_ = q/if ($tflag) {$tflag = ''; /;
  607.         if ($lab eq $toplabel) {
  608.         $_ .= 'redo LINE;}';
  609.         } else {
  610.         $_ .= "goto $lab;}";
  611.         }
  612.         $tseen++;
  613.         next;
  614.     }
  615.  
  616.     if (/^=/) {
  617.         $_ = 'print "$.\n";';
  618.         next;
  619.     }
  620.  
  621.     if (/^q/) {
  622.         chop($_ = <<'EOT');
  623. close(ARGV);
  624. @ARGV = ();
  625. next LINE;
  626. EOT
  627.         next;
  628.     }
  629.     } continue {
  630.     if ($space) {
  631.         s/^/$space/;
  632.         s/(\n)(.)/$1$space$2/g;
  633.     }
  634.     last;
  635.     }
  636.     $_;
  637. }
  638.  
  639. sub fetchpat {
  640.     local($outer) = @_;
  641.     local($addr) = $outer;
  642.     local($inbracket);
  643.     local($prefix,$delim,$ch);
  644.  
  645.     # Process pattern one potential delimiter at a time.
  646.  
  647.     DELIM: while (s#^([^\]+(|)[\\/]*)([]+(|)[\\/])##) {
  648.     $prefix = $1;
  649.     $delim = $2;
  650.     if ($delim eq '\\') {
  651.         s/(.)//;
  652.         $ch = $1;
  653.         $delim = '' if $ch =~ /^[(){}A-Za-mo-z]$/;
  654.         $ch = 'b' if $ch =~ /^[<>]$/;
  655.         $delim .= $ch;
  656.     }
  657.     elsif ($delim eq '[') {
  658.         $inbracket = 1;
  659.         s/^\^// && ($delim .= '^');
  660.         s/^]// && ($delim .= ']');
  661.     }
  662.     elsif ($delim eq ']') {
  663.         $inbracket = 0;
  664.     }
  665.     elsif ($inbracket || $delim ne $outer) {
  666.         $delim = '\\' . $delim;
  667.     }
  668.     $addr .= $prefix;
  669.     $addr .= $delim;
  670.     if ($delim eq $outer && !$inbracket) {
  671.         last DELIM;
  672.     }
  673.     }
  674.     $addr;
  675. }
  676.