Commit | Line | Data |
fe14fcc3 |
1 | extproc 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 | |
49 | while ($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 | |
68 | unless ($debug) { |
69 | open(BODY,">sperl$$") || |
70 | &Die("Can't open temp file: $!\n"); |
71 | } |
72 | |
73 | if (!$assumen && !$assumep) { |
74 | print BODY <<'EOT'; |
75 | while ($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 | |
85 | EOT |
86 | } |
87 | |
88 | print BODY <<'EOT'; |
89 | |
90 | #ifdef PRINTIT |
91 | #ifdef ASSUMEP |
92 | $printit++; |
93 | #else |
94 | $printit++ unless $nflag; |
95 | #endif |
96 | #endif |
97 | LINE: while (<>) { |
98 | EOT |
99 | |
100 | LINE: 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 | } |
215 | if ($lastlinewaslabel++) { |
216 | $indent += 4; |
217 | print BODY &tab, ";\n"; |
218 | $indent -= 4; |
219 | } |
220 | |
221 | print BODY "}\n"; |
222 | if ($appendseen || $tseen || !$assumen) { |
223 | $printit++ if $dseen || (!$assumen && !$assumep); |
224 | print BODY <<'EOT'; |
225 | |
226 | continue { |
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 | } |
250 | EOT |
251 | } |
252 | |
253 | close BODY; |
254 | |
255 | unless ($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 |
274 | eval 'exec $bin/perl -S \$0 \$*' |
275 | if \$running_under_some_shell; |
276 | |
277 | EOT |
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; |
289 | exit; |
290 | |
291 | sub Cleanup { |
292 | unlink "sperl$$", "sperl2$$", "sperl2$$.c"; |
293 | } |
294 | sub Die { |
295 | &Cleanup; |
296 | die $_[0]; |
297 | } |
298 | sub tab { |
299 | "\t" x ($indent / 8) . ' ' x ($indent % 8); |
300 | } |
301 | sub 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"; |
309 | open($_,'>$fname') || die "Can't create $fname"; |
310 | EOT |
311 | } |
312 | $seen{$_} = $_; |
313 | } |
314 | |
315 | sub 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 | |
328 | sub transmogrify { |
329 | { # case |
330 | if (/^d/) { |
331 | $dseen++; |
332 | chop($_ = <<'EOT'); |
333 | <<--#ifdef PRINTIT |
334 | $printit = ''; |
335 | <<--#endif |
336 | next LINE; |
337 | EOT |
338 | next; |
339 | } |
340 | |
341 | if (/^n/) { |
342 | chop($_ = <<'EOT'); |
343 | <<--#ifdef PRINTIT |
344 | <<--#ifdef DSEEN |
345 | <<--#ifdef ASSUMEP |
346 | print if $printit++; |
347 | <<--#else |
348 | if ($printit) |
349 | { print; } |
350 | else |
351 | { $printit++ unless $nflag; } |
352 | <<--#endif |
353 | <<--#else |
354 | print if $printit; |
355 | <<--#endif |
356 | <<--#else |
357 | print; |
358 | <<--#endif |
359 | <<--#ifdef APPENDSEEN |
360 | if ($atext) {print $atext; $atext = '';} |
361 | <<--#endif |
362 | $_ = <>; |
363 | <<--#ifdef TSEEN |
364 | $tflag = ''; |
365 | <<--#endif |
366 | EOT |
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; |
413 | EOT |
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 |
511 | EOT |
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'); |
542 | s/^.*\n//; |
543 | redo LINE if $_; |
544 | next LINE; |
545 | EOT |
546 | next; |
547 | } |
548 | |
549 | if (/^N/) { |
550 | chop($_ = <<'EOT'); |
551 | $_ .= <>; |
552 | <<--#ifdef TSEEN |
553 | $tflag = ''; |
554 | <<--#endif |
555 | EOT |
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'); |
626 | close(ARGV); |
627 | @ARGV = (); |
628 | next LINE; |
629 | EOT |
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 | |
642 | sub 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 | } |