home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / p / perl4036.zip / x2p / s2p.SH < prev    next >
Text File  |  1993-02-08  |  15KB  |  790 lines

  1. : This forces SH files to create target in same directory as SH file.
  2. : This is so that make depend always knows where to find SH derivatives.
  3. case "$0" in
  4. */*) cd `expr X$0 : 'X\(.*\)/'` ;;
  5. esac
  6. case $CONFIG in
  7. '')
  8.     if test ! -f config.sh; then
  9.     ln ../config.sh . || \
  10.     ln -s ../config.sh . || \
  11.     ln ../../config.sh . || \
  12.     ln ../../../config.sh . || \
  13.     (echo "Can't find config.sh."; exit 1)
  14.     fi 2>/dev/null
  15.     . ./config.sh
  16.     ;;
  17. esac
  18. echo "Extracting s2p (with variable substitutions)"
  19. : This section of the file will have variable substitutions done on it.
  20. : Move anything that needs config subs from !NO!SUBS! section to !GROK!THIS!.
  21. : Protect any dollar signs and backticks that you do not want interpreted
  22. : by putting a backslash in front.  You may delete these comments.
  23. rm -f s2p
  24. $spitshell >s2p <<!GROK!THIS!
  25. #!$bin/perl
  26.  
  27. eval 'exec $bin/perl -S \$0 \${1+"\$@"}'
  28.     if \$running_under_some_shell;
  29.  
  30. \$bin = '$bin';
  31. !GROK!THIS!
  32.  
  33. : In the following dollars and backticks do not need the extra backslash.
  34. $spitshell >>s2p <<'!NO!SUBS!'
  35.  
  36. # $RCSfile: s2p.SH,v $$Revision: 4.0.1.2 $$Date: 92/06/08 17:26:31 $
  37. #
  38. # $Log:    s2p.SH,v $
  39. # Revision 4.0.1.2  92/06/08  17:26:31  lwall
  40. # patch20: s2p didn't output portable startup code
  41. # patch20: added ... as variant on ..
  42. # patch20: s2p didn't translate s/pat/\&/ or s/pat/\$/ or s/pat/\\1/ right
  43. # Revision 4.0.1.1  91/06/07  12:19:18  lwall
  44. # patch4: s2p now handles embedded newlines better and optimizes common idioms
  45. # Revision 4.0  91/03/20  01:57:59  lwall
  46. # 4.0 baseline.
  47. #
  48.  
  49. $indent = 4;
  50. $shiftwidth = 4;
  51. $l = '{'; $r = '}';
  52.  
  53. while ($ARGV[0] =~ /^-/) {
  54.     $_ = shift;
  55.   last if /^--/;
  56.     if (/^-D/) {
  57.     $debug++;
  58.     open(BODY,'>-');
  59.     next;
  60.     }
  61.     if (/^-n/) {
  62.     $assumen++;
  63.     next;
  64.     }
  65.     if (/^-p/) {
  66.     $assumep++;
  67.     next;
  68.     }
  69.     die "I don't recognize this switch: $_\n";
  70. }
  71.  
  72. unless ($debug) {
  73.     open(BODY,">/tmp/sperl$$") ||
  74.       &Die("Can't open temp file: $!\n");
  75. }
  76.  
  77. if (!$assumen && !$assumep) {
  78.     print BODY &q(<<'EOT');
  79. :    while ($ARGV[0] =~ /^-/) {
  80. :        $_ = shift;
  81. :      last if /^--/;
  82. :        if (/^-n/) {
  83. :        $nflag++;
  84. :        next;
  85. :        }
  86. :        die "I don't recognize this switch: $_\\n";
  87. :    }
  88. :    
  89. EOT
  90. }
  91.  
  92. print BODY &q(<<'EOT');
  93. :    #ifdef PRINTIT
  94. :    #ifdef ASSUMEP
  95. :    $printit++;
  96. :    #else
  97. :    $printit++ unless $nflag;
  98. :    #endif
  99. :    #endif
  100. :    <><>
  101. :    $\ = "\n";        # automatically add newline on print
  102. :    <><>
  103. :    #ifdef TOPLABEL
  104. :    LINE:
  105. :    while (chop($_ = <>)) {
  106. :    #else
  107. :    LINE:
  108. :    while (<>) {
  109. :        chop;
  110. :    #endif
  111. EOT
  112.  
  113. LINE:
  114. while (<>) {
  115.  
  116.     # Wipe out surrounding whitespace.
  117.  
  118.     s/[ \t]*(.*)\n$/$1/;
  119.  
  120.     # Perhaps it's a label/comment.
  121.  
  122.     if (/^:/) {
  123.     s/^:[ \t]*//;
  124.     $label = &make_label($_);
  125.     if ($. == 1) {
  126.         $toplabel = $label;
  127.         if (/^(top|(re)?start|redo|begin(ning)|again|input)$/i) {
  128.         $_ = <>;
  129.         redo LINE; # Never referenced, so delete it if not a comment.
  130.         }
  131.     }
  132.     $_ = "$label:";
  133.     if ($lastlinewaslabel++) {
  134.         $indent += 4;
  135.         print BODY &tab, ";\n";
  136.         $indent -= 4;
  137.     }
  138.     if ($indent >= 2) {
  139.         $indent -= 2;
  140.         $indmod = 2;
  141.     }
  142.     next;
  143.     } else {
  144.     $lastlinewaslabel = '';
  145.     }
  146.  
  147.     # Look for one or two address clauses
  148.  
  149.     $addr1 = '';
  150.     $addr2 = '';
  151.     if (s/^([0-9]+)//) {
  152.     $addr1 = "$1";
  153.     $addr1 = "\$. == $addr1" unless /^,/;
  154.     }
  155.     elsif (s/^\$//) {
  156.     $addr1 = 'eof()';
  157.     }
  158.     elsif (s|^/||) {
  159.     $addr1 = &fetchpat('/');
  160.     }
  161.     if (s/^,//) {
  162.     if (s/^([0-9]+)//) {
  163.         $addr2 = "$1";
  164.     } elsif (s/^\$//) {
  165.         $addr2 = "eof()";
  166.     } elsif (s|^/||) {
  167.         $addr2 = &fetchpat('/');
  168.     } else {
  169.         &Die("Invalid second address at line $.\n");
  170.     }
  171.     if ($addr2 =~ /^\d+$/) {
  172.         $addr1 .= "..$addr2";
  173.     }
  174.     else {
  175.         $addr1 .= "...$addr2";
  176.     }
  177.     }
  178.  
  179.     # Now we check for metacommands {, }, and ! and worry
  180.     # about indentation.
  181.  
  182.     s/^[ \t]+//;
  183.     # a { to keep vi happy
  184.     if ($_ eq '}') {
  185.     $indent -= 4;
  186.     next;
  187.     }
  188.     if (s/^!//) {
  189.     $if = 'unless';
  190.     $else = "$r else $l\n";
  191.     } else {
  192.     $if = 'if';
  193.     $else = '';
  194.     }
  195.     if (s/^{//) {    # a } to keep vi happy
  196.     $indmod = 4;
  197.     $redo = $_;
  198.     $_ = '';
  199.     $rmaybe = '';
  200.     } else {
  201.     $rmaybe = "\n$r";
  202.     if ($addr2 || $addr1) {
  203.         $space = ' ' x $shiftwidth;
  204.     } else {
  205.         $space = '';
  206.     }
  207.     $_ = &transmogrify();
  208.     }
  209.  
  210.     # See if we can optimize to modifier form.
  211.  
  212.     if ($addr1) {
  213.     if ($_ !~ /[\n{}]/ && $rmaybe && !$change &&
  214.       $_ !~ / if / && $_ !~ / unless /) {
  215.         s/;$/ $if $addr1;/;
  216.         $_ = substr($_,$shiftwidth,1000);
  217.     } else {
  218.         $_ = "$if ($addr1) $l\n$change$_$rmaybe";
  219.     }
  220.     $change = '';
  221.     next LINE;
  222.     }
  223. } continue {
  224.     @lines = split(/\n/,$_);
  225.     for (@lines) {
  226.     unless (s/^ *<<--//) {
  227.         print BODY &tab;
  228.     }
  229.     print BODY $_, "\n";
  230.     }
  231.     $indent += $indmod;
  232.     $indmod = 0;
  233.     if ($redo) {
  234.     $_ = $redo;
  235.     $redo = '';
  236.     redo LINE;
  237.     }
  238. }
  239. if ($lastlinewaslabel++) {
  240.     $indent += 4;
  241.     print BODY &tab, ";\n";
  242.     $indent -= 4;
  243. }
  244.  
  245. if ($appendseen || $tseen || !$assumen) {
  246.     $printit++ if $dseen || (!$assumen && !$assumep);
  247.     print BODY &q(<<'EOT');
  248. :    #ifdef SAWNEXT
  249. :    }
  250. :    continue {
  251. :    #endif
  252. :    #ifdef PRINTIT
  253. :    #ifdef DSEEN
  254. :    #ifdef ASSUMEP
  255. :        print if $printit++;
  256. :    #else
  257. :        if ($printit)
  258. :        { print; }
  259. :        else
  260. :        { $printit++ unless $nflag; }
  261. :    #endif
  262. :    #else
  263. :        print if $printit;
  264. :    #endif
  265. :    #else
  266. :        print;
  267. :    #endif
  268. :    #ifdef TSEEN
  269. :        $tflag = 0;
  270. :    #endif
  271. :    #ifdef APPENDSEEN
  272. :        if ($atext) { chop $atext; print $atext; $atext = ''; }
  273. :    #endif
  274. EOT
  275.  
  276. print BODY &q(<<'EOT');
  277. :    }
  278. EOT
  279. }
  280.  
  281. close BODY;
  282.  
  283. unless ($debug) {
  284.     open(HEAD,">/tmp/sperl2$$.c")
  285.       || &Die("Can't open temp file 2: $!\n");
  286.     print HEAD "#define PRINTIT\n"    if $printit;
  287.     print HEAD "#define APPENDSEEN\n"    if $appendseen;
  288.     print HEAD "#define TSEEN\n"    if $tseen;
  289.     print HEAD "#define DSEEN\n"    if $dseen;
  290.     print HEAD "#define ASSUMEN\n"    if $assumen;
  291.     print HEAD "#define ASSUMEP\n"    if $assumep;
  292.     print HEAD "#define TOPLABEL\n"    if $toplabel;
  293.     print HEAD "#define SAWNEXT\n"    if $sawnext;
  294.     if ($opens) {print HEAD "$opens\n";}
  295.     open(BODY,"/tmp/sperl$$")
  296.       || &Die("Can't reopen temp file: $!\n");
  297.     while (<BODY>) {
  298.     print HEAD $_;
  299.     }
  300.     close HEAD;
  301.  
  302.     print &q(<<"EOT");
  303. :    #!$bin/perl
  304. :    eval 'exec $bin/perl -S \$0 \${1+"\$@"}'
  305. :        if \$running_under_some_shell;
  306. :    
  307. EOT
  308.     open(BODY,"cc -E /tmp/sperl2$$.c |") ||
  309.     &Die("Can't reopen temp file: $!\n");
  310.     while (<BODY>) {
  311.     /^# [0-9]/ && next;
  312.     /^[ \t]*$/ && next;
  313.     s/^<><>//;
  314.     print;
  315.     }
  316. }
  317.  
  318. &Cleanup;
  319. exit;
  320.  
  321. sub Cleanup {
  322.     chdir "/tmp";
  323.     unlink "sperl$$", "sperl2$$", "sperl2$$.c";
  324. }
  325. sub Die {
  326.     &Cleanup;
  327.     die $_[0];
  328. }
  329. sub tab {
  330.     "\t" x ($indent / 8) . ' ' x ($indent % 8);
  331. }
  332. sub make_filehandle {
  333.     local($_) = $_[0];
  334.     local($fname) = $_;
  335.     if (!$seen{$fname}) {
  336.     $_ = "FH_" . $_ if /^\d/;
  337.     s/[^a-zA-Z0-9]/_/g;
  338.     s/^_*//;
  339.     $_ = "\U$_";
  340.     if ($fhseen{$_}) {
  341.         for ($tmp = "a"; $fhseen{"$_$tmp"}; $a++) {}
  342.         $_ .= $tmp;
  343.     }
  344.     $fhseen{$_} = 1;
  345.     $opens .= &q(<<"EOT");
  346. :    open($_, '>$fname') || die "Can't create $fname: \$!";
  347. EOT
  348.     $seen{$fname} = $_;
  349.     }
  350.     $seen{$fname};
  351. }
  352.  
  353. sub make_label {
  354.     local($label) = @_;
  355.     $label =~ s/[^a-zA-Z0-9]/_/g;
  356.     if ($label =~ /^[0-9_]/) { $label = 'L' . $label; }
  357.     $label = substr($label,0,8);
  358.  
  359.     # Could be a reserved word, so capitalize it.
  360.     substr($label,0,1) =~ y/a-z/A-Z/
  361.       if $label =~ /^[a-z]/;
  362.  
  363.     $label;
  364. }
  365.  
  366. sub transmogrify {
  367.     {    # case
  368.     if (/^d/) {
  369.         $dseen++;
  370.         chop($_ = &q(<<'EOT'));
  371. :    <<--#ifdef PRINTIT
  372. :    $printit = 0;
  373. :    <<--#endif
  374. :    next LINE;
  375. EOT
  376.         $sawnext++;
  377.         next;
  378.     }
  379.  
  380.     if (/^n/) {
  381.         chop($_ = &q(<<'EOT'));
  382. :    <<--#ifdef PRINTIT
  383. :    <<--#ifdef DSEEN
  384. :    <<--#ifdef ASSUMEP
  385. :    print if $printit++;
  386. :    <<--#else
  387. :    if ($printit)
  388. :        { print; }
  389. :    else
  390. :        { $printit++ unless $nflag; }
  391. :    <<--#endif
  392. :    <<--#else
  393. :    print if $printit;
  394. :    <<--#endif
  395. :    <<--#else
  396. :    print;
  397. :    <<--#endif
  398. :    <<--#ifdef APPENDSEEN
  399. :    if ($atext) {chop $atext; print $atext; $atext = '';}
  400. :    <<--#endif
  401. :    $_ = <>;
  402. :    chop;
  403. :    <<--#ifdef TSEEN
  404. :    $tflag = 0;
  405. :    <<--#endif
  406. EOT
  407.         next;
  408.     }
  409.  
  410.     if (/^a/) {
  411.         $appendseen++;
  412.         $command = $space . "\$atext .= <<'End_Of_Text';\n<<--";
  413.         $lastline = 0;
  414.         while (<>) {
  415.         s/^[ \t]*//;
  416.         s/^[\\]//;
  417.         unless (s|\\$||) { $lastline = 1;}
  418.         s/^([ \t]*\n)/<><>$1/;
  419.         $command .= $_;
  420.         $command .= '<<--';
  421.         last if $lastline;
  422.         }
  423.         $_ = $command . "End_Of_Text";
  424.         last;
  425.     }
  426.  
  427.     if (/^[ic]/) {
  428.         if (/^c/) { $change = 1; }
  429.         $addr1 = 1 if $addr1 eq '';
  430.         $addr1 = '$iter = (' . $addr1 . ')';
  431.         $command = $space .
  432.           "    if (\$iter == 1) { print <<'End_Of_Text'; }\n<<--";
  433.         $lastline = 0;
  434.         while (<>) {
  435.         s/^[ \t]*//;
  436.         s/^[\\]//;
  437.         unless (s/\\$//) { $lastline = 1;}
  438.         s/'/\\'/g;
  439.         s/^([ \t]*\n)/<><>$1/;
  440.         $command .= $_;
  441.         $command .= '<<--';
  442.         last if $lastline;
  443.         }
  444.         $_ = $command . "End_Of_Text";
  445.         if ($change) {
  446.         $dseen++;
  447.         $change = "$_\n";
  448.         chop($_ = &q(<<"EOT"));
  449. :    <<--#ifdef PRINTIT
  450. :    $space\$printit = 0;
  451. :    <<--#endif
  452. :    ${space}next LINE;
  453. EOT
  454.         $sawnext++;
  455.         }
  456.         last;
  457.     }
  458.  
  459.     if (/^s/) {
  460.         $delim = substr($_,1,1);
  461.         $len = length($_);
  462.         $repl = $end = 0;
  463.         $inbracket = 0;
  464.         for ($i = 2; $i < $len; $i++) {
  465.         $c = substr($_,$i,1);
  466.         if ($c eq $delim) {
  467.             if ($inbracket) {
  468.             substr($_, $i, 0) = '\\';
  469.             $i++;
  470.             $len++;
  471.             }
  472.             else {
  473.             if ($repl) {
  474.                 $end = $i;
  475.                 last;
  476.             } else {
  477.                 $repl = $i;
  478.             }
  479.             }
  480.         }
  481.         elsif ($c eq '\\') {
  482.             $i++;
  483.             if ($i >= $len) {
  484.             $_ .= 'n';
  485.             $_ .= <>;
  486.             $len = length($_);
  487.             $_ = substr($_,0,--$len);
  488.             }
  489.             elsif (substr($_,$i,1) =~ /^[n]$/) {
  490.             ;
  491.             }
  492.             elsif (!$repl &&
  493.               substr($_,$i,1) =~ /^[(){}\w]$/) {
  494.             $i--;
  495.             $len--;
  496.             substr($_, $i, 1) = '';
  497.             }
  498.             elsif (!$repl &&
  499.               substr($_,$i,1) =~ /^[<>]$/) {
  500.             substr($_,$i,1) = 'b';
  501.             }
  502.             elsif ($repl && substr($_,$i,1) =~ /^\d$/) {
  503.             substr($_,$i-1,1) = '$';
  504.             }
  505.         }
  506.         elsif ($c eq '&' && $repl) {
  507.             substr($_, $i, 0) = '$';
  508.             $i++;
  509.             $len++;
  510.         }
  511.         elsif ($c eq '$' && $repl) {
  512.             substr($_, $i, 0) = '\\';
  513.             $i++;
  514.             $len++;
  515.         }
  516.         elsif ($c eq '[' && !$repl) {
  517.             $i++ if substr($_,$i,1) eq '^';
  518.             $i++ if substr($_,$i,1) eq ']';
  519.             $inbracket = 1;
  520.         }
  521.         elsif ($c eq ']') {
  522.             $inbracket = 0;
  523.         }
  524.         elsif ($c eq "\t") {
  525.             substr($_, $i, 1) = '\\t';
  526.             $i++;
  527.             $len++;
  528.         }
  529.         elsif (!$repl && index("()+",$c) >= 0) {
  530.             substr($_, $i, 0) = '\\';
  531.             $i++;
  532.             $len++;
  533.         }
  534.         }
  535.         &Die("Malformed substitution at line $.\n")
  536.           unless $end;
  537.         $pat = substr($_, 0, $repl + 1);
  538.         $repl = substr($_, $repl+1, $end-$repl-1);
  539.         $end = substr($_, $end + 1, 1000);
  540.         &simplify($pat);
  541.         $dol = '$';
  542.         $subst = "$pat$repl$delim";
  543.         $cmd = '';
  544.         while ($end) {
  545.         if ($end =~ s/^g//) {
  546.             $subst .= 'g';
  547.             next;
  548.         }
  549.         if ($end =~ s/^p//) {
  550.             $cmd .= ' && (print)';
  551.             next;
  552.         }
  553.         if ($end =~ s/^w[ \t]*//) {
  554.             $fh = &make_filehandle($end);
  555.             $cmd .= " && (print $fh \$_)";
  556.             $end = '';
  557.             next;
  558.         }
  559.         &Die("Unrecognized substitution command".
  560.           "($end) at line $.\n");
  561.         }
  562.         chop ($_ = &q(<<"EOT"));
  563. :    <<--#ifdef TSEEN
  564. :    $subst && \$tflag++$cmd;
  565. :    <<--#else
  566. :    $subst$cmd;
  567. :    <<--#endif
  568. EOT
  569.         next;
  570.     }
  571.  
  572.     if (/^p/) {
  573.         $_ = 'print;';
  574.         next;
  575.     }
  576.  
  577.     if (/^w/) {
  578.         s/^w[ \t]*//;
  579.         $fh = &make_filehandle($_);
  580.         $_ = "print $fh \$_;";
  581.         next;
  582.     }
  583.  
  584.     if (/^r/) {
  585.         $appendseen++;
  586.         s/^r[ \t]*//;
  587.         $file = $_;
  588.         $_ = "\$atext .= `cat $file 2>/dev/null`;";
  589.         next;
  590.     }
  591.  
  592.     if (/^P/) {
  593.         $_ = 'print $1 if /^(.*)/;';
  594.         next;
  595.     }
  596.  
  597.     if (/^D/) {
  598.         chop($_ = &q(<<'EOT'));
  599. :    s/^.*\n?//;
  600. :    redo LINE if $_;
  601. :    next LINE;
  602. EOT
  603.         $sawnext++;
  604.         next;
  605.     }
  606.  
  607.     if (/^N/) {
  608.         chop($_ = &q(<<'EOT'));
  609. :    $_ .= "\n";
  610. :    $len1 = length;
  611. :    $_ .= <>;
  612. :    chop if $len1 < length;
  613. :    <<--#ifdef TSEEN
  614. :    $tflag = 0;
  615. :    <<--#endif
  616. EOT
  617.         next;
  618.     }
  619.  
  620.     if (/^h/) {
  621.         $_ = '$hold = $_;';
  622.         next;
  623.     }
  624.  
  625.     if (/^H/) {
  626.         $_ = '$hold .= "\n"; $hold .= $_;';
  627.         next;
  628.     }
  629.  
  630.     if (/^g/) {
  631.         $_ = '$_ = $hold;';
  632.         next;
  633.     }
  634.  
  635.     if (/^G/) {
  636.         $_ = '$_ .= "\n"; $_ .= $hold;';
  637.         next;
  638.     }
  639.  
  640.     if (/^x/) {
  641.         $_ = '($_, $hold) = ($hold, $_);';
  642.         next;
  643.     }
  644.  
  645.     if (/^b$/) {
  646.         $_ = 'next LINE;';
  647.         $sawnext++;
  648.         next;
  649.     }
  650.  
  651.     if (/^b/) {
  652.         s/^b[ \t]*//;
  653.         $lab = &make_label($_);
  654.         if ($lab eq $toplabel) {
  655.         $_ = 'redo LINE;';
  656.         } else {
  657.         $_ = "goto $lab;";
  658.         }
  659.         next;
  660.     }
  661.  
  662.     if (/^t$/) {
  663.         $_ = 'next LINE if $tflag;';
  664.         $sawnext++;
  665.         $tseen++;
  666.         next;
  667.     }
  668.  
  669.     if (/^t/) {
  670.         s/^t[ \t]*//;
  671.         $lab = &make_label($_);
  672.         $_ = q/if ($tflag) {$tflag = 0; /;
  673.         if ($lab eq $toplabel) {
  674.         $_ .= 'redo LINE;}';
  675.         } else {
  676.         $_ .= "goto $lab;}";
  677.         }
  678.         $tseen++;
  679.         next;
  680.     }
  681.  
  682.     if (/^y/) {
  683.         s/abcdefghijklmnopqrstuvwxyz/a-z/g;
  684.         s/ABCDEFGHIJKLMNOPQRSTUVWXYZ/A-Z/g;
  685.         s/abcdef/a-f/g;
  686.         s/ABCDEF/A-F/g;
  687.         s/0123456789/0-9/g;
  688.         s/01234567/0-7/g;
  689.         $_ .= ';';
  690.     }
  691.  
  692.     if (/^=/) {
  693.         $_ = 'print $.;';
  694.         next;
  695.     }
  696.  
  697.     if (/^q/) {
  698.         chop($_ = &q(<<'EOT'));
  699. :    close(ARGV);
  700. :    @ARGV = ();
  701. :    next LINE;
  702. EOT
  703.         $sawnext++;
  704.         next;
  705.     }
  706.     } continue {
  707.     if ($space) {
  708.         s/^/$space/;
  709.         s/(\n)(.)/$1$space$2/g;
  710.     }
  711.     last;
  712.     }
  713.     $_;
  714. }
  715.  
  716. sub fetchpat {
  717.     local($outer) = @_;
  718.     local($addr) = $outer;
  719.     local($inbracket);
  720.     local($prefix,$delim,$ch);
  721.  
  722.     # Process pattern one potential delimiter at a time.
  723.  
  724.     DELIM: while (s#^([^\]+(|)[\\/]*)([]+(|)[\\/])##) {
  725.     $prefix = $1;
  726.     $delim = $2;
  727.     if ($delim eq '\\') {
  728.         s/(.)//;
  729.         $ch = $1;
  730.         $delim = '' if $ch =~ /^[(){}A-Za-mo-z]$/;
  731.         $ch = 'b' if $ch =~ /^[<>]$/;
  732.         $delim .= $ch;
  733.     }
  734.     elsif ($delim eq '[') {
  735.         $inbracket = 1;
  736.         s/^\^// && ($delim .= '^');
  737.         s/^]// && ($delim .= ']');
  738.     }
  739.     elsif ($delim eq ']') {
  740.         $inbracket = 0;
  741.     }
  742.     elsif ($inbracket || $delim ne $outer) {
  743.         $delim = '\\' . $delim;
  744.     }
  745.     $addr .= $prefix;
  746.     $addr .= $delim;
  747.     if ($delim eq $outer && !$inbracket) {
  748.         last DELIM;
  749.     }
  750.     }
  751.     $addr =~ s/\t/\\t/g;
  752.     &simplify($addr);
  753.     $addr;
  754. }
  755.  
  756. sub q {
  757.     local($string) = @_;
  758.     local($*) = 1;
  759.     $string =~ s/^:\t?//g;
  760.     $string;
  761. }
  762.  
  763. sub simplify {
  764.     $_[0] =~ s/_a-za-z0-9/\\w/ig;
  765.     $_[0] =~ s/a-z_a-z0-9/\\w/ig;
  766.     $_[0] =~ s/a-za-z_0-9/\\w/ig;
  767.     $_[0] =~ s/a-za-z0-9_/\\w/ig;
  768.     $_[0] =~ s/_0-9a-za-z/\\w/ig;
  769.     $_[0] =~ s/0-9_a-za-z/\\w/ig;
  770.     $_[0] =~ s/0-9a-z_a-z/\\w/ig;
  771.     $_[0] =~ s/0-9a-za-z_/\\w/ig;
  772.     $_[0] =~ s/\[\\w\]/\\w/g;
  773.     $_[0] =~ s/\[^\\w\]/\\W/g;
  774.     $_[0] =~ s/\[0-9\]/\\d/g;
  775.     $_[0] =~ s/\[^0-9\]/\\D/g;
  776.     $_[0] =~ s/\\d\\d\*/\\d+/g;
  777.     $_[0] =~ s/\\D\\D\*/\\D+/g;
  778.     $_[0] =~ s/\\w\\w\*/\\w+/g;
  779.     $_[0] =~ s/\\t\\t\*/\\t+/g;
  780.     $_[0] =~ s/(\[.[^]]*\])\1\*/$1+/g;
  781.     $_[0] =~ s/([\w\s!@#%^&-=,:;'"])\1\*/$1+/g;
  782. }
  783.  
  784. !NO!SUBS!
  785. chmod 755 s2p
  786. $eunicefix s2p
  787.