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