home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume20 / perl / patch08 < prev    next >
Encoding:
Text File  |  1991-06-19  |  49.1 KB  |  2,019 lines

  1. Newsgroups: comp.sources.misc
  2. From: Larry Wall <lwall@netlabs.com>
  3. Subject:  v20i060:  perl - The perl programming language, Patch08
  4. Message-ID: <1991Jun20.030715.8793@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: ae57846772c5492202517c7c68da4503
  6. Date: Thu, 20 Jun 1991 03:07:15 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: Larry Wall <lwall@netlabs.com>
  10. Posting-number: Volume 20, Issue 60
  11. Archive-name: perl/patch08
  12. Patch-To: perl: Volume 18, Issue 19-54
  13.  
  14. System: perl version 4.0
  15. Patch #: 8
  16. Priority: High
  17. Subject: patch #4, continued
  18.  
  19. Description:
  20.     See patch #4.
  21.  
  22. Fix:    From rn, say "| patch -p -N -d DIR", where DIR is your perl source
  23.     directory.  Outside of rn, say "cd DIR; patch -p -N <thisarticle".
  24.     If you don't have the patch program, apply the following by hand,
  25.     or get patch (version 2.0, latest patchlevel).
  26.  
  27.     After patching:
  28.         *** DO NOTHING--INSTALL ALL PATCHES UP THROUGH #09 FIRST ***
  29.  
  30.     If patch indicates that patchlevel is the wrong version, you may need
  31.     to apply one or more previous patches, or the patch may already
  32.     have been applied.  See the patchlevel.h file to find out what has or
  33.     has not been applied.  In any event, don't continue with the patch.
  34.  
  35.     If you are missing previous patches they can be obtained from me:
  36.  
  37.     Larry Wall
  38.     lwall@netlabs.com
  39.  
  40.     If you send a mail message of the following form it will greatly speed
  41.     processing:
  42.  
  43.     Subject: Command
  44.     @SH mailpatch PATH perl 4.0 LIST
  45.            ^ note the c
  46.  
  47.     where PATH is a return path FROM ME TO YOU either in Internet notation,
  48.     or in bang notation from some well-known host, and LIST is the number
  49.     of one or more patches you need, separated by spaces, commas, and/or
  50.     hyphens.  Saying 35- says everything from 35 to the end.
  51.  
  52.  
  53. Index: patchlevel.h
  54. Prereq: 7
  55. 1c1
  56. < #define PATCHLEVEL 7
  57. ---
  58. > #define PATCHLEVEL 8
  59.  
  60. Index: lib/perldb.pl
  61. Prereq: 4.0
  62. *** lib/perldb.pl.old    Fri Jun  7 12:25:19 1991
  63. --- lib/perldb.pl    Fri Jun  7 12:25:20 1991
  64. ***************
  65. *** 1,6 ****
  66.   package DB;
  67.   
  68. ! $header = '$Header: perldb.pl,v 4.0 91/03/20 01:25:50 lwall Locked $';
  69.   #
  70.   # This file is automatically included if you do perl -d.
  71.   # It's probably not useful to include this yourself.
  72. --- 1,6 ----
  73.   package DB;
  74.   
  75. ! $header = '$RCSfile: perldb.pl,v $$Revision: 4.0.1.1 $$Date: 91/06/07 11:17:44 $';
  76.   #
  77.   # This file is automatically included if you do perl -d.
  78.   # It's probably not useful to include this yourself.
  79. ***************
  80. *** 10,15 ****
  81. --- 10,19 ----
  82.   # have a breakpoint.  It also inserts a do 'perldb.pl' before the first line.
  83.   #
  84.   # $Log:    perldb.pl,v $
  85. + # Revision 4.0.1.1  91/06/07  11:17:44  lwall
  86. + # patch4: added $^P variable to control calling of perldb routines
  87. + # patch4: debugger sometimes listed wrong number of lines for a statement
  88. + # 
  89.   # Revision 4.0  91/03/20  01:25:50  lwall
  90.   # 4.0 baseline.
  91.   # 
  92. ***************
  93. *** 61,66 ****
  94. --- 65,71 ----
  95.       ($package, $filename, $line) = caller;
  96.       $usercontext = '($@, $!, $[, $,, $/, $\) = @saved;' .
  97.       "package $package;";        # this won't let them modify, alas
  98. +     local($^P) = 0;            # don't debug our own evals
  99.       local(*dbline) = "_<$filename";
  100.       $max = $#dbline;
  101.       if (($stop,$action) = split(/\0/,$dbline{$line})) {
  102. ***************
  103. *** 76,82 ****
  104.       print OUT "$package'" unless $sub =~ /'/;
  105.       print OUT "$sub($filename:$line):\t",$dbline[$line];
  106.       for ($i = $line + 1; $i <= $max && $dbline[$i] == 0; ++$i) {
  107. !         last if $dbline[$i] =~ /^\s*(}|#|\n)/;
  108.           print OUT "$sub($filename:$i):\t",$dbline[$i];
  109.       }
  110.       }
  111. --- 81,87 ----
  112.       print OUT "$package'" unless $sub =~ /'/;
  113.       print OUT "$sub($filename:$line):\t",$dbline[$line];
  114.       for ($i = $line + 1; $i <= $max && $dbline[$i] == 0; ++$i) {
  115. !         last if $dbline[$i] =~ /^\s*(;|}|#|\n)/;
  116.           print OUT "$sub($filename:$i):\t",$dbline[$i];
  117.       }
  118.       }
  119.  
  120. Index: perly.fixer
  121. *** perly.fixer.old    Fri Jun  7 12:26:21 1991
  122. --- perly.fixer    Fri Jun  7 12:26:21 1991
  123. ***************
  124. *** 2,7 ****
  125. --- 2,10 ----
  126.   
  127.   #  Hacks to make it work with Interactive's SysVr3 Version 2.2
  128.   #   doughera@lafvax.lafayette.edu (Andy Dougherty)   3/23/91
  129. + #
  130. + # Additional information to make the BSD section work with SunOS 4.0.2
  131. + #   tdinger@East.Sun.COM (Tom Dinger)    4/15/1991
  132.   
  133.   input=$1
  134.   output=$2
  135. ***************
  136. *** 10,20 ****
  137.   plan="unknown"
  138.   
  139.   #  Test for BSD 4.3 version.
  140.   egrep 'YYSTYPE[     ]*yyv\[ *YYMAXDEPTH *\];
  141.   short[  ]*yys\[ *YYMAXDEPTH *\] *;
  142.   yyps *= *&yys\[ *-1 *\];
  143.   yypv *= *&yyv\[ *-1 *\];
  144. ! if *\( *\+\+yyps *> *&yys\[ *YYMAXDEPTH *\] *\)' $input >$tmp
  145.   
  146.   set `wc -l $tmp`
  147.   if test "$1" = "5"; then
  148. --- 13,24 ----
  149.   plan="unknown"
  150.   
  151.   #  Test for BSD 4.3 version.
  152. + #  Also tests for the SunOS 4.0.2 version
  153.   egrep 'YYSTYPE[     ]*yyv\[ *YYMAXDEPTH *\];
  154.   short[  ]*yys\[ *YYMAXDEPTH *\] *;
  155.   yyps *= *&yys\[ *-1 *\];
  156.   yypv *= *&yyv\[ *-1 *\];
  157. ! if *\( *\+\+yyps *>=* *&yys\[ *YYMAXDEPTH *\] *\)' $input >$tmp
  158.   
  159.   set `wc -l $tmp`
  160.   if test "$1" = "5"; then
  161. ***************
  162. *** 36,42 ****
  163.   fi
  164.   
  165.   case "$plan" in
  166. !     #######################################################
  167.       "bsd43")
  168.       echo "Patching perly.c to allow dynamic yacc stack allocation"
  169.       echo "Assuming bsd4.3 yaccpar"
  170. --- 40,49 ----
  171.   fi
  172.   
  173.   case "$plan" in
  174. !     ##################################################################
  175. !     # The SunOS 4.0.2 version has the comparison fixed already.
  176. !     # Also added are out of memory checks (makes porting the generated
  177. !     # code easier) For most systems, it can't hurt. -- TD
  178.       "bsd43")
  179.       echo "Patching perly.c to allow dynamic yacc stack allocation"
  180.       echo "Assuming bsd4.3 yaccpar"
  181. ***************
  182. *** 55,60 ****
  183. --- 62,71 ----
  184.   \    if (!yyv) {\
  185.   \        yyv = (YYSTYPE*) malloc(yymaxdepth * sizeof(YYSTYPE));\
  186.   \        yys = (short*) malloc(yymaxdepth * sizeof(short));\
  187. + \        if ( !yyv || !yys ) {\
  188. + \        yyerror( "out of memory" );\
  189. + \        return(1);\
  190. + \        }\
  191.   \        maxyyps = &yys[yymaxdepth];\
  192.   \    }\
  193.   \    yyps = &yys[-1];\
  194. ***************
  195. *** 61,67 ****
  196.   \    yypv = &yyv[-1];
  197.   
  198.   
  199. ! /if *( *\+\+yyps *> *&yys\[ *YYMAXDEPTH *\] *)/c\
  200.   \        if( ++yyps >= maxyyps ) {\
  201.   \            int tv = yypv - yyv;\
  202.   \            int ts = yyps - yys;\
  203. --- 72,78 ----
  204.   \    yypv = &yyv[-1];
  205.   
  206.   
  207. ! /if *( *\+\+yyps *>=* *&yys\[ *YYMAXDEPTH *\] *)/c\
  208.   \        if( ++yyps >= maxyyps ) {\
  209.   \            int tv = yypv - yyv;\
  210.   \            int ts = yyps - yys;\
  211. ***************
  212. *** 71,76 ****
  213. --- 82,91 ----
  214.   \              yymaxdepth*sizeof(YYSTYPE));\
  215.   \            yys = (short*)realloc((char*)yys,\
  216.   \              yymaxdepth*sizeof(short));\
  217. + \            if ( !yyv || !yys ) {\
  218. + \            yyerror( "yacc stack overflow" );\
  219. + \            return(1);\
  220. + \            }\
  221.   \            yyps = yys + ts;\
  222.   \            yypv = yyv + tv;\
  223.   \            maxyyps = &yys[yymaxdepth];\
  224.  
  225. Index: perly.y
  226. Prereq: 4.0
  227. *** perly.y.old    Fri Jun  7 12:26:24 1991
  228. --- perly.y    Fri Jun  7 12:26:25 1991
  229. ***************
  230. *** 1,11 ****
  231. ! /* $Header: perly.y,v 4.0 91/03/20 01:38:40 lwall Locked $
  232.    *
  233. !  *    Copyright (c) 1989, Larry Wall
  234.    *
  235. !  *    You may distribute under the terms of the GNU General Public License
  236. !  *    as specified in the README file that comes with the perl 3.0 kit.
  237.    *
  238.    * $Log:    perly.y,v $
  239.    * Revision 4.0  91/03/20  01:38:40  lwall
  240.    * 4.0 baseline.
  241.    * 
  242. --- 1,14 ----
  243. ! /* $RCSfile: perly.y,v $$Revision: 4.0.1.1 $$Date: 91/06/07 11:42:34 $
  244.    *
  245. !  *    Copyright (c) 1991, Larry Wall
  246.    *
  247. !  *    You may distribute under the terms of either the GNU General Public
  248. !  *    License or the Artistic License, as specified in the README file.
  249.    *
  250.    * $Log:    perly.y,v $
  251. +  * Revision 4.0.1.1  91/06/07  11:42:34  lwall
  252. +  * patch4: new copyright notice
  253. +  * 
  254.    * Revision 4.0  91/03/20  01:38:40  lwall
  255.    * 4.0 baseline.
  256.    * 
  257. ***************
  258. *** 788,792 ****
  259.                     "\"%s\" may clash with future reserved word",
  260.                     $1 );
  261.               }
  262.   %% /* PROGRAM */
  263. --- 791,795 ----
  264.                     "\"%s\" may clash with future reserved word",
  265.                     $1 );
  266.               }
  267. !         ;
  268.   %% /* PROGRAM */
  269.  
  270. Index: msdos/popen.c
  271. Prereq: 4.0
  272. *** msdos/popen.c.old    Fri Jun  7 12:25:48 1991
  273. --- msdos/popen.c    Fri Jun  7 12:25:49 1991
  274. ***************
  275. *** 1,11 ****
  276. ! /* $Header: popen.c,v 4.0 91/03/20 01:34:50 lwall Locked $
  277.    *
  278.    *    (C) Copyright 1988, 1990 Diomidis Spinellis.
  279.    *
  280. !  *    You may distribute under the terms of the GNU General Public License
  281. !  *    as specified in the README file that comes with the perl 3.0 kit.
  282.    *
  283.    * $Log:    popen.c,v $
  284.    * Revision 4.0  91/03/20  01:34:50  lwall
  285.    * 4.0 baseline.
  286.    * 
  287. --- 1,14 ----
  288. ! /* $RCSfile: popen.c,v $$Revision: 4.0.1.1 $$Date: 91/06/07 11:22:52 $
  289.    *
  290.    *    (C) Copyright 1988, 1990 Diomidis Spinellis.
  291.    *
  292. !  *    You may distribute under the terms of either the GNU General Public
  293. !  *    License or the Artistic License, as specified in the README file.
  294.    *
  295.    * $Log:    popen.c,v $
  296. +  * Revision 4.0.1.1  91/06/07  11:22:52  lwall
  297. +  * patch4: new copyright notice
  298. +  * 
  299.    * Revision 4.0  91/03/20  01:34:50  lwall
  300.    * 4.0 baseline.
  301.    * 
  302.  
  303. Index: regcomp.c
  304. *** regcomp.c.old    Fri Jun  7 12:26:29 1991
  305. --- regcomp.c    Fri Jun  7 12:26:30 1991
  306. ***************
  307. *** 7,15 ****
  308.    * blame Henry for some of the lack of readability.
  309.    */
  310.   
  311. ! /* $RCSfile: regcomp.c,v $$Revision: 4.0.1.1 $$Date: 91/04/12 09:04:45 $
  312.    *
  313.    * $Log:    regcomp.c,v $
  314.    * Revision 4.0.1.1  91/04/12  09:04:45  lwall
  315.    * patch1: random cleanup in cpp namespace
  316.    * 
  317. --- 7,20 ----
  318.    * blame Henry for some of the lack of readability.
  319.    */
  320.   
  321. ! /* $RCSfile: regcomp.c,v $$Revision: 4.0.1.2 $$Date: 91/06/07 11:48:24 $
  322.    *
  323.    * $Log:    regcomp.c,v $
  324. +  * Revision 4.0.1.2  91/06/07  11:48:24  lwall
  325. +  * patch4: new copyright notice
  326. +  * patch4: /(x+) \1/ incorrectly optimized to not match "xxx xx"
  327. +  * patch4: // wouldn't use previous pattern if it started with a null character
  328. +  * 
  329.    * Revision 4.0.1.1  91/04/12  09:04:45  lwall
  330.    * patch1: random cleanup in cpp namespace
  331.    * 
  332. ***************
  333. *** 41,50 ****
  334.    *
  335.    ****    Alterations to Henry's code are...
  336.    ****
  337. !  ****    Copyright (c) 1989, Larry Wall
  338.    ****
  339. !  ****    You may distribute under the terms of the GNU General Public License
  340. !  ****    as specified in the README file that comes with the perl 3.0 kit.
  341.    *
  342.    * Beware that some of this code is subtly aware of the way operator
  343.    * precedence is structured in regular expressions.  Serious changes in
  344. --- 46,56 ----
  345.    *
  346.    ****    Alterations to Henry's code are...
  347.    ****
  348. !  ****    Copyright (c) 1991, Larry Wall
  349.    ****
  350. !  ****    You may distribute under the terms of either the GNU General Public
  351. !  ****    License or the Artistic License, as specified in the README file.
  352.    *
  353.    * Beware that some of this code is subtly aware of the way operator
  354.    * precedence is structured in regular expressions.  Serious changes in
  355. ***************
  356. *** 95,100 ****
  357. --- 101,107 ----
  358.   static long regsize;        /* Code size. */
  359.   static int regfold;
  360.   static int regsawbracket;    /* Did we do {d,d} trick? */
  361. + static int regsawback;        /* Did we see \1, ...? */
  362.   
  363.   /*
  364.    * Forward declarations for regcomp()'s friends.
  365. ***************
  366. *** 146,151 ****
  367. --- 153,159 ----
  368.       extern char *safemalloc();
  369.       extern char *savestr();
  370.       int sawplus = 0;
  371. +     int sawopen = 0;
  372.   
  373.       if (exp == NULL)
  374.           fatal("NULL regexp argument");
  375. ***************
  376. *** 156,161 ****
  377. --- 164,170 ----
  378.       regxend = xend;
  379.       regprecomp = nsavestr(exp,xend-exp);
  380.       regsawbracket = 0;
  381. +     regsawback = 0;
  382.       regnpar = 1;
  383.       regsize = 0L;
  384.       regcode = ®dummy;
  385. ***************
  386. *** 178,185 ****
  387.       /* Second pass: emit code. */
  388.       if (regsawbracket)
  389.           bcopy(regprecomp,exp,xend-exp);
  390.       r->precomp = regprecomp;
  391. !     r->subbase = NULL;
  392.       regparse = exp;
  393.       regnpar = 1;
  394.       regcode = r->program;
  395. --- 187,195 ----
  396.       /* Second pass: emit code. */
  397.       if (regsawbracket)
  398.           bcopy(regprecomp,exp,xend-exp);
  399. +     r->prelen = xend-exp;
  400.       r->precomp = regprecomp;
  401. !     r->subbeg = r->subbase = NULL;
  402.       regparse = exp;
  403.       regnpar = 1;
  404.       regcode = r->program;
  405. ***************
  406. *** 198,209 ****
  407.           scan = NEXTOPER(scan);
  408.   
  409.           first = scan;
  410. !         while (OP(first) == OPEN ||
  411.               (OP(first) == BRANCH && OP(regnext(first)) != BRANCH) ||
  412.               (OP(first) == PLUS) ||
  413.               (OP(first) == CURLY && ARG1(first) > 0) ) {
  414.               if (OP(first) == PLUS)
  415. !                 sawplus = 2;
  416.               else
  417.                   first += regarglen[OP(first)];
  418.               first = NEXTOPER(first);
  419. --- 208,219 ----
  420.           scan = NEXTOPER(scan);
  421.   
  422.           first = scan;
  423. !         while ((OP(first) == OPEN && (sawopen = 1)) ||
  424.               (OP(first) == BRANCH && OP(regnext(first)) != BRANCH) ||
  425.               (OP(first) == PLUS) ||
  426.               (OP(first) == CURLY && ARG1(first) > 0) ) {
  427.               if (OP(first) == PLUS)
  428. !                 sawplus = 1;
  429.               else
  430.                   first += regarglen[OP(first)];
  431.               first = NEXTOPER(first);
  432. ***************
  433. *** 210,215 ****
  434. --- 220,226 ----
  435.           }
  436.   
  437.           /* Starting-point info. */
  438. +         again:
  439.           if (OP(first) == EXACTLY) {
  440.               r->regstart =
  441.                   str_make(OPERAND(first)+1,*OPERAND(first));
  442. ***************
  443. *** 221,229 ****
  444.           else if (OP(first) == BOUND || OP(first) == NBOUND)
  445.               r->regstclass = first;
  446.           else if (OP(first) == BOL ||
  447. !             (OP(first) == STAR && OP(NEXTOPER(first)) == ANY) )
  448. !             r->reganch = 1;        /* kinda turn .* into ^.* */
  449. !         r->reganch |= sawplus;
  450.   
  451.   #ifdef DEBUGGING
  452.           if (debug & 512)
  453. --- 232,244 ----
  454.           else if (OP(first) == BOUND || OP(first) == NBOUND)
  455.               r->regstclass = first;
  456.           else if (OP(first) == BOL ||
  457. !             (OP(first) == STAR && OP(NEXTOPER(first)) == ANY) ) {
  458. !             r->reganch = ROPT_ANCH;    /* kinda turn .* into ^.* */
  459. !             first = NEXTOPER(first);
  460. !                 goto again;
  461. !         }
  462. !         if (sawplus && (!sawopen || !regsawback))
  463. !             r->reganch |= ROPT_SKIP;    /* x+ must match 1st of run */
  464.   
  465.   #ifdef DEBUGGING
  466.           if (debug & 512)
  467. ***************
  468. *** 741,746 ****
  469. --- 756,762 ----
  470.                   if (num > 9 && num >= regnpar)
  471.                   goto defchar;
  472.                   else {
  473. +                 regsawback = 1;
  474.                   ret = reganode(REF, num);
  475.                   while (isascii(*regparse) && isdigit(*regparse))
  476.                       regparse++;
  477. ***************
  478. *** 1272,1280 ****
  479.           fprintf(stderr,"start `%s' ", r->regstart->str_ptr);
  480.       if (r->regstclass)
  481.           fprintf(stderr,"stclass `%s' ", regprop(r->regstclass));
  482. !     if (r->reganch & 1)
  483.           fprintf(stderr,"anchored ");
  484. !     if (r->reganch & 2)
  485.           fprintf(stderr,"plus ");
  486.       if (r->regmust != NULL)
  487.           fprintf(stderr,"must have \"%s\" back %d ", r->regmust->str_ptr,
  488. --- 1288,1296 ----
  489.           fprintf(stderr,"start `%s' ", r->regstart->str_ptr);
  490.       if (r->regstclass)
  491.           fprintf(stderr,"stclass `%s' ", regprop(r->regstclass));
  492. !     if (r->reganch & ROPT_ANCH)
  493.           fprintf(stderr,"anchored ");
  494. !     if (r->reganch & ROPT_SKIP)
  495.           fprintf(stderr,"plus ");
  496.       if (r->regmust != NULL)
  497.           fprintf(stderr,"must have \"%s\" back %d ", r->regmust->str_ptr,
  498.  
  499. Index: regcomp.h
  500. Prereq: 4.0
  501. *** regcomp.h.old    Fri Jun  7 12:26:33 1991
  502. --- regcomp.h    Fri Jun  7 12:26:34 1991
  503. ***************
  504. *** 1,6 ****
  505. ! /* $Header: regcomp.h,v 4.0 91/03/20 01:39:09 lwall Locked $
  506.    *
  507.    * $Log:    regcomp.h,v $
  508.    * Revision 4.0  91/03/20  01:39:09  lwall
  509.    * 4.0 baseline.
  510.    * 
  511. --- 1,9 ----
  512. ! /* $RCSfile: regcomp.h,v $$Revision: 4.0.1.1 $$Date: 91/06/07 11:49:40 $
  513.    *
  514.    * $Log:    regcomp.h,v $
  515. +  * Revision 4.0.1.1  91/06/07  11:49:40  lwall
  516. +  * patch4: no change
  517. +  * 
  518.    * Revision 4.0  91/03/20  01:39:09  lwall
  519.    * 4.0 baseline.
  520.    * 
  521.  
  522. Index: regexec.c
  523. *** regexec.c.old    Fri Jun  7 12:26:37 1991
  524. --- regexec.c    Fri Jun  7 12:26:38 1991
  525. ***************
  526. *** 7,15 ****
  527.    * blame Henry for some of the lack of readability.
  528.    */
  529.   
  530. ! /* $RCSfile: regexec.c,v $$Revision: 4.0.1.1 $$Date: 91/04/12 09:07:39 $
  531.    *
  532.    * $Log:    regexec.c,v $
  533.    * Revision 4.0.1.1  91/04/12  09:07:39  lwall
  534.    * patch1: regexec only allocated space for 9 subexpresssions
  535.    * 
  536. --- 7,19 ----
  537.    * blame Henry for some of the lack of readability.
  538.    */
  539.   
  540. ! /* $RCSfile: regexec.c,v $$Revision: 4.0.1.2 $$Date: 91/06/07 11:50:33 $
  541.    *
  542.    * $Log:    regexec.c,v $
  543. +  * Revision 4.0.1.2  91/06/07  11:50:33  lwall
  544. +  * patch4: new copyright notice
  545. +  * patch4: // wouldn't use previous pattern if it started with a null character
  546. +  * 
  547.    * Revision 4.0.1.1  91/04/12  09:07:39  lwall
  548.    * patch1: regexec only allocated space for 9 subexpresssions
  549.    * 
  550. ***************
  551. *** 40,49 ****
  552.    *
  553.    ****    Alterations to Henry's code are...
  554.    ****
  555. !  ****    Copyright (c) 1989, Larry Wall
  556.    ****
  557. !  ****    You may distribute under the terms of the GNU General Public License
  558. !  ****    as specified in the README file that comes with the perl 3.0 kit.
  559.    *
  560.    * Beware that some of this code is subtly aware of the way operator
  561.    * precedence is structured in regular expressions.  Serious changes in
  562. --- 44,53 ----
  563.    *
  564.    ****    Alterations to Henry's code are...
  565.    ****
  566. !  ****    Copyright (c) 1991, Larry Wall
  567.    ****
  568. !  ****    You may distribute under the terms of either the GNU General Public
  569. !  ****    License or the Artistic License, as specified in the README file.
  570.    *
  571.    * Beware that some of this code is subtly aware of the way operator
  572.    * precedence is structured in regular expressions.  Serious changes in
  573. ***************
  574. *** 151,157 ****
  575.       /* If there is a "must appear" string, look for it. */
  576.       s = string;
  577.       if (prog->regmust != Nullstr &&
  578. !         (!(prog->reganch & 1) || (multiline && prog->regback >= 0)) ) {
  579.           if (stringarg == strbeg && screamer) {
  580.               if (screamfirst[prog->regmust->str_rare] >= 0)
  581.                   s = screaminstr(screamer,prog->regmust);
  582. --- 155,162 ----
  583.       /* If there is a "must appear" string, look for it. */
  584.       s = string;
  585.       if (prog->regmust != Nullstr &&
  586. !         (!(prog->reganch & ROPT_ANCH)
  587. !          || (multiline && prog->regback >= 0)) ) {
  588.           if (stringarg == strbeg && screamer) {
  589.               if (screamfirst[prog->regmust->str_rare] >= 0)
  590.                   s = screaminstr(screamer,prog->regmust);
  591. ***************
  592. *** 213,219 ****
  593.   
  594.       /* Simplest case:  anchored match need be tried only once. */
  595.       /*  [unless multiline is set] */
  596. !     if (prog->reganch & 1) {
  597.           if (regtry(prog, string))
  598.               goto got_it;
  599.           else if (multiline) {
  600. --- 218,224 ----
  601.   
  602.       /* Simplest case:  anchored match need be tried only once. */
  603.       /*  [unless multiline is set] */
  604. !     if (prog->reganch & ROPT_ANCH) {
  605.           if (regtry(prog, string))
  606.               goto got_it;
  607.           else if (multiline) {
  608. ***************
  609. *** 235,241 ****
  610.   
  611.       /* Messy cases:  unanchored match. */
  612.       if (prog->regstart) {
  613. !         if (prog->reganch & 2) {    /* we have /x+whatever/ */
  614.               /* it must be a one character string */
  615.               i = prog->regstart->str_ptr[0];
  616.               while (s < strend) {
  617. --- 240,246 ----
  618.   
  619.       /* Messy cases:  unanchored match. */
  620.       if (prog->regstart) {
  621. !         if (prog->reganch & ROPT_SKIP) {  /* we have /x+whatever/ */
  622.               /* it must be a one character string */
  623.               i = prog->regstart->str_ptr[0];
  624.               while (s < strend) {
  625. ***************
  626. *** 275,281 ****
  627.           goto phooey;
  628.       }
  629.       if (c = prog->regstclass) {
  630. !         int doevery = (prog->reganch & 2) == 0;
  631.   
  632.           if (minlen)
  633.               dontbother = minlen - 1;
  634. --- 280,286 ----
  635.           goto phooey;
  636.       }
  637.       if (c = prog->regstclass) {
  638. !         int doevery = (prog->reganch & ROPT_SKIP) == 0;
  639.   
  640.           if (minlen)
  641.               dontbother = minlen - 1;
  642. ***************
  643. *** 445,451 ****
  644.               s = nsavestr(strbeg,i);    /* so $digit will work later */
  645.               if (prog->subbase)
  646.                   Safefree(prog->subbase);
  647. !             prog->subbase = s;
  648.               prog->subend = s+i;
  649.           }
  650.           else
  651. --- 450,456 ----
  652.               s = nsavestr(strbeg,i);    /* so $digit will work later */
  653.               if (prog->subbase)
  654.                   Safefree(prog->subbase);
  655. !             prog->subbeg = prog->subbase = s;
  656.               prog->subend = s+i;
  657.           }
  658.           else
  659.  
  660. Index: regexp.h
  661. Prereq: 4.0
  662. *** regexp.h.old    Fri Jun  7 12:26:40 1991
  663. --- regexp.h    Fri Jun  7 12:26:41 1991
  664. ***************
  665. *** 5,13 ****
  666.    * not the System V one.
  667.    */
  668.   
  669. ! /* $Header: regexp.h,v 4.0 91/03/20 01:39:23 lwall Locked $
  670.    *
  671.    * $Log:    regexp.h,v $
  672.    * Revision 4.0  91/03/20  01:39:23  lwall
  673.    * 4.0 baseline.
  674.    * 
  675. --- 5,18 ----
  676.    * not the System V one.
  677.    */
  678.   
  679. ! /* $RCSfile: regexp.h,v $$Revision: 4.0.1.1 $$Date: 91/06/07 11:51:18 $
  680.    *
  681.    * $Log:    regexp.h,v $
  682. +  * Revision 4.0.1.1  91/06/07  11:51:18  lwall
  683. +  * patch4: new copyright notice
  684. +  * patch4: // wouldn't use previous pattern if it started with a null character
  685. +  * patch4: $` was busted inside s///
  686. +  * 
  687.    * Revision 4.0  91/03/20  01:39:23  lwall
  688.    * 4.0 baseline.
  689.    * 
  690. ***************
  691. *** 20,27 ****
  692. --- 25,34 ----
  693.       char *regstclass;
  694.       STR *regmust;        /* Internal use only. */
  695.       int regback;        /* Can regmust locate first try? */
  696. +     int prelen;        /* length of precomp */
  697.       char *precomp;        /* pre-compilation regular expression */
  698.       char *subbase;        /* saved string so \digit works forever */
  699. +     char *subbeg;        /* same, but not responsible for allocation */
  700.       char *subend;        /* end of subbase */
  701.       char reganch;        /* Internal use only. */
  702.       char do_folding;    /* do case-insensitive match? */
  703. ***************
  704. *** 29,34 ****
  705. --- 36,44 ----
  706.       char nparens;        /* number of parentheses */
  707.       char program[1];    /* Unwarranted chumminess with compiler. */
  708.   } regexp;
  709. + #define ROPT_ANCH 1
  710. + #define ROPT_SKIP 2
  711.   
  712.   regexp *regcomp();
  713.   int regexec();
  714.  
  715. Index: x2p/s2p.SH
  716. Prereq: 4.0
  717. *** x2p/s2p.SH.old    Fri Jun  7 12:28:10 1991
  718. --- x2p/s2p.SH    Fri Jun  7 12:28:11 1991
  719. ***************
  720. *** 29,37 ****
  721.   : In the following dollars and backticks do not need the extra backslash.
  722.   $spitshell >>s2p <<'!NO!SUBS!'
  723.   
  724. ! # $Header: s2p.SH,v 4.0 91/03/20 01:57:59 lwall Locked $
  725.   #
  726.   # $Log:    s2p.SH,v $
  727.   # Revision 4.0  91/03/20  01:57:59  lwall
  728.   # 4.0 baseline.
  729.   # 
  730. --- 29,40 ----
  731.   : In the following dollars and backticks do not need the extra backslash.
  732.   $spitshell >>s2p <<'!NO!SUBS!'
  733.   
  734. ! # $RCSfile: s2p.SH,v $$Revision: 4.0.1.1 $$Date: 91/06/07 12:19:18 $
  735.   #
  736.   # $Log:    s2p.SH,v $
  737. + # Revision 4.0.1.1  91/06/07  12:19:18  lwall
  738. + # patch4: s2p now handles embedded newlines better and optimizes common idioms
  739. + # 
  740.   # Revision 4.0  91/03/20  01:57:59  lwall
  741.   # 4.0 baseline.
  742.   # 
  743. ***************
  744. *** 66,98 ****
  745.   }
  746.   
  747.   if (!$assumen && !$assumep) {
  748. !     print BODY <<'EOT';
  749. ! while ($ARGV[0] =~ /^-/) {
  750. !     $_ = shift;
  751. !   last if /^--/;
  752. !     if (/^-n/) {
  753. !     $nflag++;
  754. !     next;
  755. !     }
  756. !     die "I don't recognize this switch: $_\\n";
  757. ! }
  758.   EOT
  759.   }
  760.   
  761. ! print BODY <<'EOT';
  762. ! #ifdef PRINTIT
  763. ! #ifdef ASSUMEP
  764. ! $printit++;
  765. ! #else
  766. ! $printit++ unless $nflag;
  767. ! #endif
  768. ! #endif
  769. ! LINE: while (<>) {
  770.   EOT
  771.   
  772. ! LINE: while (<>) {
  773.   
  774.       # Wipe out surrounding whitespace.
  775.   
  776. --- 69,111 ----
  777.   }
  778.   
  779.   if (!$assumen && !$assumep) {
  780. !     print BODY &q(<<'EOT');
  781. ! :    while ($ARGV[0] =~ /^-/) {
  782. ! :        $_ = shift;
  783. ! :      last if /^--/;
  784. ! :        if (/^-n/) {
  785. ! :        $nflag++;
  786. ! :        next;
  787. ! :        }
  788. ! :        die "I don't recognize this switch: $_\\n";
  789. ! :    }
  790. ! :    
  791.   EOT
  792.   }
  793.   
  794. ! print BODY &q(<<'EOT');
  795. ! :    #ifdef PRINTIT
  796. ! :    #ifdef ASSUMEP
  797. ! :    $printit++;
  798. ! :    #else
  799. ! :    $printit++ unless $nflag;
  800. ! :    #endif
  801. ! :    #endif
  802. ! :    <><>
  803. ! :    $\ = "\n";        # automatically add newline on print
  804. ! :    <><>
  805. ! :    #ifdef TOPLABEL
  806. ! :    LINE:
  807. ! :    while (chop($_ = <>)) {
  808. ! :    #else
  809. ! :    LINE:
  810. ! :    while (<>) {
  811. ! :        chop;
  812. ! :    #endif
  813.   EOT
  814.   
  815. ! LINE:
  816. ! while (<>) {
  817.   
  818.       # Wipe out surrounding whitespace.
  819.   
  820. ***************
  821. *** 105,110 ****
  822. --- 118,127 ----
  823.       $label = &make_label($_);
  824.       if ($. == 1) {
  825.           $toplabel = $label;
  826. +         if (/^(top|(re)?start|redo|begin(ning)|again|input)$/i) {
  827. +         $_ = <>;
  828. +         redo LINE; # Never referenced, so delete it if not a comment.
  829. +         }
  830.       }
  831.       $_ = "$label:";
  832.       if ($lastlinewaslabel++) {
  833. ***************
  834. *** 127,132 ****
  835. --- 144,150 ----
  836.       $addr2 = '';
  837.       if (s/^([0-9]+)//) {
  838.       $addr1 = "$1";
  839. +     $addr1 = "\$. == $addr1" unless /^,/;
  840.       }
  841.       elsif (s/^\$//) {
  842.       $addr1 = 'eof()';
  843. ***************
  844. *** 213,247 ****
  845.       $indent -= 4;
  846.   }
  847.   
  848. - print BODY "}\n";
  849.   if ($appendseen || $tseen || !$assumen) {
  850.       $printit++ if $dseen || (!$assumen && !$assumep);
  851. !     print BODY <<'EOT';
  852.   
  853. ! continue {
  854. ! #ifdef PRINTIT
  855. ! #ifdef DSEEN
  856. ! #ifdef ASSUMEP
  857. !     print if $printit++;
  858. ! #else
  859. !     if ($printit)
  860. !     { print; }
  861. !     else
  862. !     { $printit++ unless $nflag; }
  863. ! #endif
  864. ! #else
  865. !     print if $printit;
  866. ! #endif
  867. ! #else
  868. !     print;
  869. ! #endif
  870. ! #ifdef TSEEN
  871. !     $tflag = '';
  872. ! #endif
  873. ! #ifdef APPENDSEEN
  874. !     if ($atext) { print $atext; $atext = ''; }
  875. ! #endif
  876. ! }
  877.   EOT
  878.   }
  879.   
  880. --- 231,269 ----
  881.       $indent -= 4;
  882.   }
  883.   
  884.   if ($appendseen || $tseen || !$assumen) {
  885.       $printit++ if $dseen || (!$assumen && !$assumep);
  886. !     print BODY &q(<<'EOT');
  887. ! :    #ifdef SAWNEXT
  888. ! :    }
  889. ! :    continue {
  890. ! :    #endif
  891. ! :    #ifdef PRINTIT
  892. ! :    #ifdef DSEEN
  893. ! :    #ifdef ASSUMEP
  894. ! :        print if $printit++;
  895. ! :    #else
  896. ! :        if ($printit)
  897. ! :        { print; }
  898. ! :        else
  899. ! :        { $printit++ unless $nflag; }
  900. ! :    #endif
  901. ! :    #else
  902. ! :        print if $printit;
  903. ! :    #endif
  904. ! :    #else
  905. ! :        print;
  906. ! :    #endif
  907. ! :    #ifdef TSEEN
  908. ! :        $tflag = 0;
  909. ! :    #endif
  910. ! :    #ifdef APPENDSEEN
  911. ! :        if ($atext) { chop $atext; print $atext; $atext = ''; }
  912. ! :    #endif
  913. ! EOT
  914.   
  915. ! print BODY &q(<<'EOT');
  916. ! :    }
  917.   EOT
  918.   }
  919.   
  920. ***************
  921. *** 250,261 ****
  922.   unless ($debug) {
  923.       open(HEAD,">/tmp/sperl2$$.c")
  924.         || &Die("Can't open temp file 2: $!\n");
  925. !     print HEAD "#define PRINTIT\n" if ($printit);
  926. !     print HEAD "#define APPENDSEEN\n" if ($appendseen);
  927. !     print HEAD "#define TSEEN\n" if ($tseen);
  928. !     print HEAD "#define DSEEN\n" if ($dseen);
  929. !     print HEAD "#define ASSUMEN\n" if ($assumen);
  930. !     print HEAD "#define ASSUMEP\n" if ($assumep);
  931.       if ($opens) {print HEAD "$opens\n";}
  932.       open(BODY,"/tmp/sperl$$")
  933.         || &Die("Can't reopen temp file: $!\n");
  934. --- 272,285 ----
  935.   unless ($debug) {
  936.       open(HEAD,">/tmp/sperl2$$.c")
  937.         || &Die("Can't open temp file 2: $!\n");
  938. !     print HEAD "#define PRINTIT\n"    if $printit;
  939. !     print HEAD "#define APPENDSEEN\n"    if $appendseen;
  940. !     print HEAD "#define TSEEN\n"    if $tseen;
  941. !     print HEAD "#define DSEEN\n"    if $dseen;
  942. !     print HEAD "#define ASSUMEN\n"    if $assumen;
  943. !     print HEAD "#define ASSUMEP\n"    if $assumep;
  944. !     print HEAD "#define TOPLABEL\n"    if $toplabel;
  945. !     print HEAD "#define SAWNEXT\n"    if $sawnext;
  946.       if ($opens) {print HEAD "$opens\n";}
  947.       open(BODY,"/tmp/sperl$$")
  948.         || &Die("Can't reopen temp file: $!\n");
  949. ***************
  950. *** 264,274 ****
  951.       }
  952.       close HEAD;
  953.   
  954. !     print <<"EOT";
  955. ! #!$bin/perl
  956. ! eval 'exec $bin/perl -S \$0 \$*'
  957. !     if \$running_under_some_shell;
  958.   EOT
  959.       open(BODY,"cc -E /tmp/sperl2$$.c |") ||
  960.       &Die("Can't reopen temp file: $!\n");
  961. --- 288,298 ----
  962.       }
  963.       close HEAD;
  964.   
  965. !     print &q(<<"EOT");
  966. ! :    #!$bin/perl
  967. ! :    eval 'exec $bin/perl -S \$0 \${1+"\$@"}'
  968. ! :        if \$running_under_some_shell;
  969. ! :    
  970.   EOT
  971.       open(BODY,"cc -E /tmp/sperl2$$.c |") ||
  972.       &Die("Can't reopen temp file: $!\n");
  973. ***************
  974. *** 297,311 ****
  975.   sub make_filehandle {
  976.       local($_) = $_[0];
  977.       local($fname) = $_;
  978. !     s/[^a-zA-Z]/_/g;
  979. !     s/^_*//;
  980. !     substr($_,0,1) =~ y/a-z/A-Z/ if /^[a-z]/;
  981. !     if (!$seen{$_}) {
  982. !     $opens .= <<"EOT";
  983. ! open($_,'>$fname') || die "Can't create $fname";
  984.   EOT
  985.       }
  986. !     $seen{$_} = $_;
  987.   }
  988.   
  989.   sub make_label {
  990. --- 321,342 ----
  991.   sub make_filehandle {
  992.       local($_) = $_[0];
  993.       local($fname) = $_;
  994. !     if (!$seen{$fname}) {
  995. !     $_ = "FH_" . $_ if /^\d/;
  996. !     s/[^a-zA-Z0-9]/_/g;
  997. !     s/^_*//;
  998. !     $_ = "\U$_";
  999. !     if ($fhseen{$_}) {
  1000. !         for ($tmp = "a"; $fhseen{"$_$tmp"}; $a++) {}
  1001. !         $_ .= $tmp;
  1002. !     }
  1003. !     $fhseen{$_} = 1;
  1004. !     $opens .= &q(<<"EOT");
  1005. ! :    open($_, '>$fname') || die "Can't create $fname: \$!";
  1006.   EOT
  1007. +     $seen{$fname} = $_;
  1008.       }
  1009. !     $seen{$fname};
  1010.   }
  1011.   
  1012.   sub make_label {
  1013. ***************
  1014. *** 325,364 ****
  1015.       {    # case
  1016.       if (/^d/) {
  1017.           $dseen++;
  1018. !         chop($_ = <<'EOT');
  1019. ! <<--#ifdef PRINTIT
  1020. ! $printit = '';
  1021. ! <<--#endif
  1022. ! next LINE;
  1023.   EOT
  1024.           next;
  1025.       }
  1026.   
  1027.       if (/^n/) {
  1028. !         chop($_ = <<'EOT');
  1029. ! <<--#ifdef PRINTIT
  1030. ! <<--#ifdef DSEEN
  1031. ! <<--#ifdef ASSUMEP
  1032. ! print if $printit++;
  1033. ! <<--#else
  1034. ! if ($printit)
  1035. !     { print; }
  1036. ! else
  1037. !     { $printit++ unless $nflag; }
  1038. ! <<--#endif
  1039. ! <<--#else
  1040. ! print if $printit;
  1041. ! <<--#endif
  1042. ! <<--#else
  1043. ! print;
  1044. ! <<--#endif
  1045. ! <<--#ifdef APPENDSEEN
  1046. ! if ($atext) {print $atext; $atext = '';}
  1047. ! <<--#endif
  1048. ! $_ = <>;
  1049. ! <<--#ifdef TSEEN
  1050. ! $tflag = '';
  1051. ! <<--#endif
  1052.   EOT
  1053.           next;
  1054.       }
  1055. --- 356,397 ----
  1056.       {    # case
  1057.       if (/^d/) {
  1058.           $dseen++;
  1059. !         chop($_ = &q(<<'EOT'));
  1060. ! :    <<--#ifdef PRINTIT
  1061. ! :    $printit = 0;
  1062. ! :    <<--#endif
  1063. ! :    next LINE;
  1064.   EOT
  1065. +         $sawnext++;
  1066.           next;
  1067.       }
  1068.   
  1069.       if (/^n/) {
  1070. !         chop($_ = &q(<<'EOT'));
  1071. ! :    <<--#ifdef PRINTIT
  1072. ! :    <<--#ifdef DSEEN
  1073. ! :    <<--#ifdef ASSUMEP
  1074. ! :    print if $printit++;
  1075. ! :    <<--#else
  1076. ! :    if ($printit)
  1077. ! :        { print; }
  1078. ! :    else
  1079. ! :        { $printit++ unless $nflag; }
  1080. ! :    <<--#endif
  1081. ! :    <<--#else
  1082. ! :    print if $printit;
  1083. ! :    <<--#endif
  1084. ! :    <<--#else
  1085. ! :    print;
  1086. ! :    <<--#endif
  1087. ! :    <<--#ifdef APPENDSEEN
  1088. ! :    if ($atext) {chop $atext; print $atext; $atext = '';}
  1089. ! :    <<--#endif
  1090. ! :    $_ = <>;
  1091. ! :    chop;
  1092. ! :    <<--#ifdef TSEEN
  1093. ! :    $tflag = 0;
  1094. ! :    <<--#endif
  1095.   EOT
  1096.           next;
  1097.       }
  1098. ***************
  1099. *** 365,391 ****
  1100.   
  1101.       if (/^a/) {
  1102.           $appendseen++;
  1103. !         $command = $space . '$atext .=' . "\n<<--'";
  1104.           $lastline = 0;
  1105.           while (<>) {
  1106.           s/^[ \t]*//;
  1107.           s/^[\\]//;
  1108.           unless (s|\\$||) { $lastline = 1;}
  1109. -         s/'/\\'/g;
  1110.           s/^([ \t]*\n)/<><>$1/;
  1111.           $command .= $_;
  1112.           $command .= '<<--';
  1113.           last if $lastline;
  1114.           }
  1115. !         $_ = $command . "';";
  1116.           last;
  1117.       }
  1118.   
  1119.       if (/^[ic]/) {
  1120.           if (/^c/) { $change = 1; }
  1121.           $addr1 = '$iter = (' . $addr1 . ')';
  1122. !         $command = $space . 'if ($iter == 1) { print'
  1123. !           . "\n<<--'";
  1124.           $lastline = 0;
  1125.           while (<>) {
  1126.           s/^[ \t]*//;
  1127. --- 398,424 ----
  1128.   
  1129.       if (/^a/) {
  1130.           $appendseen++;
  1131. !         $command = $space . "\$atext .= <<'End_Of_Text';\n<<--";
  1132.           $lastline = 0;
  1133.           while (<>) {
  1134.           s/^[ \t]*//;
  1135.           s/^[\\]//;
  1136.           unless (s|\\$||) { $lastline = 1;}
  1137.           s/^([ \t]*\n)/<><>$1/;
  1138.           $command .= $_;
  1139.           $command .= '<<--';
  1140.           last if $lastline;
  1141.           }
  1142. !         $_ = $command . "End_Of_Text";
  1143.           last;
  1144.       }
  1145.   
  1146.       if (/^[ic]/) {
  1147.           if (/^c/) { $change = 1; }
  1148. +         $addr1 = 1 if $addr1 eq '';
  1149.           $addr1 = '$iter = (' . $addr1 . ')';
  1150. !         $command = $space .
  1151. !           "    if (\$iter == 1) { print <<'End_Of_Text'; }\n<<--";
  1152.           $lastline = 0;
  1153.           while (<>) {
  1154.           s/^[ \t]*//;
  1155. ***************
  1156. *** 397,412 ****
  1157.           $command .= '<<--';
  1158.           last if $lastline;
  1159.           }
  1160. !         $_ = $command . "';}";
  1161.           if ($change) {
  1162.           $dseen++;
  1163.           $change = "$_\n";
  1164. !         chop($_ = <<"EOT");
  1165. ! <<--#ifdef PRINTIT
  1166. ! $space\$printit = '';
  1167. ! <<--#endif
  1168. ! ${space}next LINE;
  1169.   EOT
  1170.           }
  1171.           last;
  1172.       }
  1173. --- 430,446 ----
  1174.           $command .= '<<--';
  1175.           last if $lastline;
  1176.           }
  1177. !         $_ = $command . "End_Of_Text";
  1178.           if ($change) {
  1179.           $dseen++;
  1180.           $change = "$_\n";
  1181. !         chop($_ = &q(<<"EOT"));
  1182. ! :    <<--#ifdef PRINTIT
  1183. ! :    $space\$printit = 0;
  1184. ! :    <<--#endif
  1185. ! :    ${space}next LINE;
  1186.   EOT
  1187. +         $sawnext++;
  1188.           }
  1189.           last;
  1190.       }
  1191. ***************
  1192. *** 463,468 ****
  1193. --- 497,507 ----
  1194.           elsif ($c eq ']') {
  1195.               $inbracket = 0;
  1196.           }
  1197. +         elsif ($c eq "\t") {
  1198. +             substr($_, $i, 1) = '\\t';
  1199. +             $i++;
  1200. +             $len++;
  1201. +         }
  1202.           elsif (!$repl && index("()+",$c) >= 0) {
  1203.               substr($_, $i, 0) = '\\';
  1204.               $i++;
  1205. ***************
  1206. *** 474,479 ****
  1207. --- 513,519 ----
  1208.           $pat = substr($_, 0, $repl + 1);
  1209.           $repl = substr($_, $repl+1, $end-$repl-1);
  1210.           $end = substr($_, $end + 1, 1000);
  1211. +         &simplify($pat);
  1212.           $dol = '$';
  1213.           $repl =~ s/\$/\\$/;
  1214.           $repl =~ s'&'$&'g;
  1215. ***************
  1216. *** 498,509 ****
  1217.           &Die("Unrecognized substitution command".
  1218.             "($end) at line $.\n");
  1219.           }
  1220. !         chop ($_ = <<"EOT");
  1221. ! <<--#ifdef TSEEN
  1222. ! $subst && \$tflag++$cmd;
  1223. ! <<--#else
  1224. ! $subst$cmd;
  1225. ! <<--#endif
  1226.   EOT
  1227.           next;
  1228.       }
  1229. --- 538,549 ----
  1230.           &Die("Unrecognized substitution command".
  1231.             "($end) at line $.\n");
  1232.           }
  1233. !         chop ($_ = &q(<<"EOT"));
  1234. ! :    <<--#ifdef TSEEN
  1235. ! :    $subst && \$tflag++$cmd;
  1236. ! :    <<--#else
  1237. ! :    $subst$cmd;
  1238. ! :    <<--#endif
  1239.   EOT
  1240.           next;
  1241.       }
  1242. ***************
  1243. *** 529,553 ****
  1244.       }
  1245.   
  1246.       if (/^P/) {
  1247. !         $_ = 'print $1 if /(^.*\n)/;';
  1248.           next;
  1249.       }
  1250.   
  1251.       if (/^D/) {
  1252. !         chop($_ = <<'EOT');
  1253. ! s/^.*\n//;
  1254. ! redo LINE if $_;
  1255. ! next LINE;
  1256.   EOT
  1257.           next;
  1258.       }
  1259.   
  1260.       if (/^N/) {
  1261. !         chop($_ = <<'EOT');
  1262. ! $_ .= <>;
  1263. ! <<--#ifdef TSEEN
  1264. ! $tflag = '';
  1265. ! <<--#endif
  1266.   EOT
  1267.           next;
  1268.       }
  1269. --- 569,597 ----
  1270.       }
  1271.   
  1272.       if (/^P/) {
  1273. !         $_ = 'print $1 if /^(.*)/;';
  1274.           next;
  1275.       }
  1276.   
  1277.       if (/^D/) {
  1278. !         chop($_ = &q(<<'EOT'));
  1279. ! :    s/^.*\n?//;
  1280. ! :    redo LINE if $_;
  1281. ! :    next LINE;
  1282.   EOT
  1283. +         $sawnext++;
  1284.           next;
  1285.       }
  1286.   
  1287.       if (/^N/) {
  1288. !         chop($_ = &q(<<'EOT'));
  1289. ! :    $_ .= "\n";
  1290. ! :    $len1 = length;
  1291. ! :    $_ .= <>;
  1292. ! :    chop if $len1 < length;
  1293. ! :    <<--#ifdef TSEEN
  1294. ! :    $tflag = 0;
  1295. ! :    <<--#endif
  1296.   EOT
  1297.           next;
  1298.       }
  1299. ***************
  1300. *** 558,564 ****
  1301.       }
  1302.   
  1303.       if (/^H/) {
  1304. !         $_ = '$hold .= $_ ? $_ : "\n";';
  1305.           next;
  1306.       }
  1307.   
  1308. --- 602,608 ----
  1309.       }
  1310.   
  1311.       if (/^H/) {
  1312. !         $_ = '$hold .= "\n"; $hold .= $_;';
  1313.           next;
  1314.       }
  1315.   
  1316. ***************
  1317. *** 568,574 ****
  1318.       }
  1319.   
  1320.       if (/^G/) {
  1321. !         $_ = '$_ .= $hold ? $hold : "\n";';
  1322.           next;
  1323.       }
  1324.   
  1325. --- 612,618 ----
  1326.       }
  1327.   
  1328.       if (/^G/) {
  1329. !         $_ = '$_ .= "\n"; $_ .= $hold;';
  1330.           next;
  1331.       }
  1332.   
  1333. ***************
  1334. *** 579,584 ****
  1335. --- 623,629 ----
  1336.   
  1337.       if (/^b$/) {
  1338.           $_ = 'next LINE;';
  1339. +         $sawnext++;
  1340.           next;
  1341.       }
  1342.   
  1343. ***************
  1344. *** 595,600 ****
  1345. --- 640,646 ----
  1346.   
  1347.       if (/^t$/) {
  1348.           $_ = 'next LINE if $tflag;';
  1349. +         $sawnext++;
  1350.           $tseen++;
  1351.           next;
  1352.       }
  1353. ***************
  1354. *** 602,608 ****
  1355.       if (/^t/) {
  1356.           s/^t[ \t]*//;
  1357.           $lab = &make_label($_);
  1358. !         $_ = q/if ($tflag) {$tflag = ''; /;
  1359.           if ($lab eq $toplabel) {
  1360.           $_ .= 'redo LINE;}';
  1361.           } else {
  1362. --- 648,654 ----
  1363.       if (/^t/) {
  1364.           s/^t[ \t]*//;
  1365.           $lab = &make_label($_);
  1366. !         $_ = q/if ($tflag) {$tflag = 0; /;
  1367.           if ($lab eq $toplabel) {
  1368.           $_ .= 'redo LINE;}';
  1369.           } else {
  1370. ***************
  1371. *** 612,628 ****
  1372.           next;
  1373.       }
  1374.   
  1375.       if (/^=/) {
  1376. !         $_ = 'print "$.\n";';
  1377.           next;
  1378.       }
  1379.   
  1380.       if (/^q/) {
  1381. !         chop($_ = <<'EOT');
  1382. ! close(ARGV);
  1383. ! @ARGV = ();
  1384. ! next LINE;
  1385.   EOT
  1386.           next;
  1387.       }
  1388.       } continue {
  1389. --- 658,685 ----
  1390.           next;
  1391.       }
  1392.   
  1393. +     if (/^y/) {
  1394. +         s/abcdefghijklmnopqrstuvwxyz/a-z/g;
  1395. +         s/ABCDEFGHIJKLMNOPQRSTUVWXYZ/A-Z/g;
  1396. +         s/abcdef/a-f/g;
  1397. +         s/ABCDEF/A-F/g;
  1398. +         s/0123456789/0-9/g;
  1399. +         s/01234567/0-7/g;
  1400. +         $_ .= ';';
  1401. +     }
  1402.       if (/^=/) {
  1403. !         $_ = 'print $.;';
  1404.           next;
  1405.       }
  1406.   
  1407.       if (/^q/) {
  1408. !         chop($_ = &q(<<'EOT'));
  1409. ! :    close(ARGV);
  1410. ! :    @ARGV = ();
  1411. ! :    next LINE;
  1412.   EOT
  1413. +         $sawnext++;
  1414.           next;
  1415.       }
  1416.       } continue {
  1417. ***************
  1418. *** 670,676 ****
  1419. --- 727,763 ----
  1420.           last DELIM;
  1421.       }
  1422.       }
  1423. +     $addr =~ s/\t/\\t/g;
  1424. +     &simplify($addr);
  1425.       $addr;
  1426. + }
  1427. + sub q {
  1428. +     local($string) = @_;
  1429. +     local($*) = 1;
  1430. +     $string =~ s/^:\t?//g;
  1431. +     $string;
  1432. + }
  1433. + sub simplify {
  1434. +     $_[0] =~ s/_a-za-z0-9/\\w/ig;
  1435. +     $_[0] =~ s/a-z_a-z0-9/\\w/ig;
  1436. +     $_[0] =~ s/a-za-z_0-9/\\w/ig;
  1437. +     $_[0] =~ s/a-za-z0-9_/\\w/ig;
  1438. +     $_[0] =~ s/_0-9a-za-z/\\w/ig;
  1439. +     $_[0] =~ s/0-9_a-za-z/\\w/ig;
  1440. +     $_[0] =~ s/0-9a-z_a-z/\\w/ig;
  1441. +     $_[0] =~ s/0-9a-za-z_/\\w/ig;
  1442. +     $_[0] =~ s/\[\\w\]/\\w/g;
  1443. +     $_[0] =~ s/\[^\\w\]/\\W/g;
  1444. +     $_[0] =~ s/\[0-9\]/\\d/g;
  1445. +     $_[0] =~ s/\[^0-9\]/\\D/g;
  1446. +     $_[0] =~ s/\\d\\d\*/\\d+/g;
  1447. +     $_[0] =~ s/\\D\\D\*/\\D+/g;
  1448. +     $_[0] =~ s/\\w\\w\*/\\w+/g;
  1449. +     $_[0] =~ s/\\t\\t\*/\\t+/g;
  1450. +     $_[0] =~ s/(\[.[^]]*\])\1\*/$1+/g;
  1451. +     $_[0] =~ s/([\w\s!@#%^&-=,:;'"])\1\*/$1+/g;
  1452.   }
  1453.   
  1454.   !NO!SUBS!
  1455.  
  1456. Index: x2p/s2p.man
  1457. Prereq: 4.0
  1458. *** x2p/s2p.man.old    Fri Jun  7 12:28:14 1991
  1459. --- x2p/s2p.man    Fri Jun  7 12:28:14 1991
  1460. ***************
  1461. *** 1,7 ****
  1462.   .rn '' }`
  1463. ! ''' $Header: s2p.man,v 4.0 91/03/20 01:58:07 lwall Locked $
  1464.   ''' 
  1465.   ''' $Log:    s2p.man,v $
  1466.   ''' Revision 4.0  91/03/20  01:58:07  lwall
  1467.   ''' 4.0 baseline.
  1468.   ''' 
  1469. --- 1,10 ----
  1470.   .rn '' }`
  1471. ! ''' $RCSfile: s2p.man,v $$Revision: 4.0.1.1 $$Date: 91/06/07 12:19:57 $
  1472.   ''' 
  1473.   ''' $Log:    s2p.man,v $
  1474. + ''' Revision 4.0.1.1  91/06/07  12:19:57  lwall
  1475. + ''' patch4: s2p now handles embedded newlines better and optimizes common idioms
  1476. + ''' 
  1477.   ''' Revision 4.0  91/03/20  01:58:07  lwall
  1478.   ''' 4.0 baseline.
  1479.   ''' 
  1480. ***************
  1481. *** 86,91 ****
  1482. --- 89,96 ----
  1483.   sed script.
  1484.   If you're only interested in speed you'll just have to try it both ways.
  1485.   Of course, if you want to do something sed doesn't do, you have no choice.
  1486. + It's often possible to speed up the perl script by various methods, such
  1487. + as deleting all references to $\e and chop.
  1488.   .SH ENVIRONMENT
  1489.   S2p uses no environment variables.
  1490.   .SH AUTHOR
  1491.  
  1492. Index: hints/sco_2_3_0.sh
  1493. *** hints/sco_2_3_0.sh.old    Fri Jun  7 12:24:35 1991
  1494. --- hints/sco_2_3_0.sh    Fri Jun  7 12:24:36 1991
  1495. ***************
  1496. *** 1,2 ****
  1497. ! yacc='/usr/bin/yacc -m25000'
  1498.   i_dirent=undef
  1499. --- 1,2 ----
  1500. ! yacc='/usr/bin/yacc -Sm25000'
  1501.   i_dirent=undef
  1502.  
  1503. Index: hints/sco_2_3_1.sh
  1504. *** hints/sco_2_3_1.sh.old    Fri Jun  7 12:24:38 1991
  1505. --- hints/sco_2_3_1.sh    Fri Jun  7 12:24:38 1991
  1506. ***************
  1507. *** 1,2 ****
  1508. ! yacc='/usr/bin/yacc -m25000'
  1509.   i_dirent=undef
  1510. --- 1,2 ----
  1511. ! yacc='/usr/bin/yacc -Sm25000'
  1512.   i_dirent=undef
  1513.  
  1514. Index: hints/sco_2_3_2.sh
  1515. *** hints/sco_2_3_2.sh.old    Fri Jun  7 12:24:40 1991
  1516. --- hints/sco_2_3_2.sh    Fri Jun  7 12:24:41 1991
  1517. ***************
  1518. *** 1,2 ****
  1519. ! yacc='/usr/bin/yacc -m25000'
  1520.   libswanted=`echo $libswanted | sed 's/ x / /'`
  1521. --- 1,2 ----
  1522. ! yacc='/usr/bin/yacc -Sm25000'
  1523.   libswanted=`echo $libswanted | sed 's/ x / /'`
  1524.  
  1525. Index: hints/sco_2_3_3.sh
  1526. *** hints/sco_2_3_3.sh.old    Fri Jun  7 12:24:43 1991
  1527. --- hints/sco_2_3_3.sh    Fri Jun  7 12:24:43 1991
  1528. ***************
  1529. *** 1,2 ****
  1530. ! yacc='/usr/bin/yacc -m25000'
  1531.   libswanted=`echo $libswanted | sed 's/ x / /'`
  1532. --- 1,4 ----
  1533. ! yacc='/usr/bin/yacc -Sm25000'
  1534.   libswanted=`echo $libswanted | sed 's/ x / /'`
  1535. + echo "NOTE: you may have problems due to a spurious semicolon on the strerror()"
  1536. + echo "macro definition in /usr/include/string.h.  If so, delete the semicolon."
  1537.  
  1538. Index: hints/sco_3.sh
  1539. *** hints/sco_3.sh.old    Fri Jun  7 12:24:46 1991
  1540. --- hints/sco_3.sh    Fri Jun  7 12:24:46 1991
  1541. ***************
  1542. *** 1,3 ****
  1543. --- 1,4 ----
  1544.   yacc='/usr/bin/yacc -Sm11000'
  1545.   libswanted=`echo $libswanted | sed 's/ x / /'`
  1546.   i_varargs=undef
  1547. + ccflags="$ccflags -U M_XENIX"
  1548.  
  1549. Index: hints/sgi.sh
  1550. *** hints/sgi.sh.old    Fri Jun  7 12:24:48 1991
  1551. --- hints/sgi.sh    Fri Jun  7 12:24:49 1991
  1552. ***************
  1553. *** 1,7 ****
  1554. ! optimize='-O0'
  1555.   usemymalloc='y'
  1556.   mallocsrc='malloc.c'
  1557.   mallocobj='malloc.o'
  1558. - ccflags="$ccflags -Uf_next"
  1559.   d_voidsig=define
  1560.   d_vfork=undef
  1561. --- 1,6 ----
  1562. ! optimize='-O1'
  1563.   usemymalloc='y'
  1564.   mallocsrc='malloc.c'
  1565.   mallocobj='malloc.o'
  1566.   d_voidsig=define
  1567.   d_vfork=undef
  1568.  
  1569. Index: lib/shellwords.pl
  1570. *** lib/shellwords.pl.old    Fri Jun  7 12:25:22 1991
  1571. --- lib/shellwords.pl    Fri Jun  7 12:25:23 1991
  1572. ***************
  1573. *** 0 ****
  1574. --- 1,42 ----
  1575. + #; shellwords.pl
  1576. + #;
  1577. + #; Usage:
  1578. + #;    require 'shellwords.pl';
  1579. + #;    @words = &shellwords($line);
  1580. + #;    or
  1581. + #;    @words = &shellwords(@lines);
  1582. + #;    or
  1583. + #;    @words = &shellwords;        # defaults to $_ (and clobbers it)
  1584. + sub shellwords {
  1585. +     package shellwords;
  1586. +     local($_) = join('', @_) if @_;
  1587. +     local(@words,$snippet,$field);
  1588. +     s/^\s+//;
  1589. +     while ($_ ne '') {
  1590. +     $field = '';
  1591. +     for (;;) {
  1592. +         if (s/^"(([^"\\]+|\\[\\"])*)"//) {
  1593. +         ($snippet = $1) =~ s#\\(.)#$1#g;
  1594. +         }
  1595. +         elsif (s/^'(([^'\\]+|\\[\\'])*)'//) {
  1596. +         ($snippet = $1) =~ s#\\(.)#$1#g;
  1597. +         }
  1598. +         elsif (s/^\\(.)//) {
  1599. +         $snippet = $1;
  1600. +         }
  1601. +         elsif (s/^([^\s\\'"]+)//) {
  1602. +         $snippet = $1;
  1603. +         }
  1604. +         else {
  1605. +         s/^\s+//;
  1606. +         last;
  1607. +         }
  1608. +         $field .= $snippet;
  1609. +     }
  1610. +     push(@words, $field);
  1611. +     }
  1612. +     @words;
  1613. + }
  1614. + 1;
  1615.  
  1616. Index: spat.h
  1617. Prereq: 4.0
  1618. *** spat.h.old    Fri Jun  7 12:26:43 1991
  1619. --- spat.h    Fri Jun  7 12:26:44 1991
  1620. ***************
  1621. *** 1,11 ****
  1622. ! /* $Header: spat.h,v 4.0 91/03/20 01:39:36 lwall Locked $
  1623.    *
  1624. !  *    Copyright (c) 1989, Larry Wall
  1625.    *
  1626. !  *    You may distribute under the terms of the GNU General Public License
  1627. !  *    as specified in the README file that comes with the perl 3.0 kit.
  1628.    *
  1629.    * $Log:    spat.h,v $
  1630.    * Revision 4.0  91/03/20  01:39:36  lwall
  1631.    * 4.0 baseline.
  1632.    * 
  1633. --- 1,15 ----
  1634. ! /* $RCSfile: spat.h,v $$Revision: 4.0.1.1 $$Date: 91/06/07 11:51:59 $
  1635.    *
  1636. !  *    Copyright (c) 1991, Larry Wall
  1637.    *
  1638. !  *    You may distribute under the terms of either the GNU General Public
  1639. !  *    License or the Artistic License, as specified in the README file.
  1640.    *
  1641.    * $Log:    spat.h,v $
  1642. +  * Revision 4.0.1.1  91/06/07  11:51:59  lwall
  1643. +  * patch4: new copyright notice
  1644. +  * patch4: added global modifier for pattern matches
  1645. +  * 
  1646.    * Revision 4.0  91/03/20  01:39:36  lwall
  1647.    * 4.0 baseline.
  1648.    * 
  1649. ***************
  1650. *** 17,23 ****
  1651.       ARG        *spat_repl;        /* replacement string for subst */
  1652.       ARG        *spat_runtime;        /* compile pattern at runtime */
  1653.       STR        *spat_short;        /* for a fast bypass of execute() */
  1654. !     bool    spat_flags;
  1655.       char    spat_slen;
  1656.   };
  1657.   
  1658. --- 21,27 ----
  1659.       ARG        *spat_repl;        /* replacement string for subst */
  1660.       ARG        *spat_runtime;        /* compile pattern at runtime */
  1661.       STR        *spat_short;        /* for a fast bypass of execute() */
  1662. !     short    spat_flags;
  1663.       char    spat_slen;
  1664.   };
  1665.   
  1666. ***************
  1667. *** 29,34 ****
  1668. --- 33,39 ----
  1669.   #define SPAT_FOLD 32            /* case insensitivity */
  1670.   #define SPAT_CONST 64            /* subst replacement is constant */
  1671.   #define SPAT_KEEP 128            /* keep 1st runtime pattern forever */
  1672. + #define SPAT_GLOBAL 256            /* pattern had a g modifier */
  1673.   
  1674.   EXT SPAT *curspat;        /* what to do \ interps from */
  1675.   EXT SPAT *lastspat;        /* what to use in place of null pattern */
  1676.  
  1677. Index: stab.c
  1678. *** stab.c.old    Fri Jun  7 12:26:47 1991
  1679. --- stab.c    Fri Jun  7 12:26:47 1991
  1680. ***************
  1681. *** 1,11 ****
  1682. ! /* $RCSfile: stab.c,v $$Revision: 4.0.1.1 $$Date: 91/04/12 09:10:24 $
  1683.    *
  1684. !  *    Copyright (c) 1989, Larry Wall
  1685.    *
  1686. !  *    You may distribute under the terms of the GNU General Public License
  1687. !  *    as specified in the README file that comes with the perl 3.0 kit.
  1688.    *
  1689.    * $Log:    stab.c,v $
  1690.    * Revision 4.0.1.1  91/04/12  09:10:24  lwall
  1691.    * patch1: Configure now differentiates getgroups() type from getgid() type
  1692.    * patch1: you may now use "die" and "caller" in a signal handler
  1693. --- 1,20 ----
  1694. ! /* $RCSfile: stab.c,v $$Revision: 4.0.1.2 $$Date: 91/06/07 11:55:53 $
  1695.    *
  1696. !  *    Copyright (c) 1991, Larry Wall
  1697.    *
  1698. !  *    You may distribute under the terms of either the GNU General Public
  1699. !  *    License or the Artistic License, as specified in the README file.
  1700.    *
  1701.    * $Log:    stab.c,v $
  1702. +  * Revision 4.0.1.2  91/06/07  11:55:53  lwall
  1703. +  * patch4: new copyright notice
  1704. +  * patch4: added $^P variable to control calling of perldb routines
  1705. +  * patch4: added $^F variable to specify maximum system fd, default 2
  1706. +  * patch4: $` was busted inside s///
  1707. +  * patch4: default top-of-form format is now FILEHANDLE_TOP
  1708. +  * patch4: length($`), length($&), length($') now optimized to avoid string copy
  1709. +  * patch4: $^D |= 1024 now does syntax tree dump at run-time
  1710. +  * 
  1711.    * Revision 4.0.1.1  91/04/12  09:10:24  lwall
  1712.    * patch1: Configure now differentiates getgroups() type from getgid() type
  1713.    * patch1: you may now use "die" and "caller" in a signal handler
  1714. ***************
  1715. *** 54,59 ****
  1716. --- 63,71 ----
  1717.       str_numset(stab_val(stab),(double)(debug & 32767));
  1718.   #endif
  1719.       break;
  1720. +     case '\006':        /* ^F */
  1721. +     str_numset(stab_val(stab),(double)maxsysfd);
  1722. +     break;
  1723.       case '\t':            /* ^I */
  1724.       if (inplace)
  1725.           str_set(stab_val(stab), inplace);
  1726. ***************
  1727. *** 60,65 ****
  1728. --- 72,80 ----
  1729.       else
  1730.           str_sset(stab_val(stab),&str_undef);
  1731.       break;
  1732. +     case '\020':        /* ^P */
  1733. +     str_numset(stab_val(stab),(double)perldb);
  1734. +     break;
  1735.       case '\024':        /* ^T */
  1736.       str_numset(stab_val(stab),(double)basetime);
  1737.       break;
  1738. ***************
  1739. *** 93,99 ****
  1740.       case '`':
  1741.       if (curspat) {
  1742.           if (curspat->spat_regexp &&
  1743. !           (s = curspat->spat_regexp->subbase) ) {
  1744.           i = curspat->spat_regexp->startp[0] - s;
  1745.           if (i >= 0)
  1746.               str_nset(stab_val(stab),s,i);
  1747. --- 108,114 ----
  1748.       case '`':
  1749.       if (curspat) {
  1750.           if (curspat->spat_regexp &&
  1751. !           (s = curspat->spat_regexp->subbeg) ) {
  1752.           i = curspat->spat_regexp->startp[0] - s;
  1753.           if (i >= 0)
  1754.               str_nset(stab_val(stab),s,i);
  1755. ***************
  1756. *** 126,135 ****
  1757.       break;
  1758.       case '^':
  1759.       s = stab_io(curoutstab)->top_name;
  1760. !     str_set(stab_val(stab),s);
  1761.       break;
  1762.       case '~':
  1763.       s = stab_io(curoutstab)->fmt_name;
  1764.       str_set(stab_val(stab),s);
  1765.       break;
  1766.   #ifndef lint
  1767. --- 141,157 ----
  1768.       break;
  1769.       case '^':
  1770.       s = stab_io(curoutstab)->top_name;
  1771. !     if (s)
  1772. !         str_set(stab_val(stab),s);
  1773. !     else {
  1774. !         str_set(stab_val(stab),stab_name(curoutstab));
  1775. !         str_cat(stab_val(stab),"_TOP");
  1776. !     }
  1777.       break;
  1778.       case '~':
  1779.       s = stab_io(curoutstab)->fmt_name;
  1780. +     if (!s)
  1781. +         s = stab_name(curoutstab);
  1782.       str_set(stab_val(stab),s);
  1783.       break;
  1784.   #ifndef lint
  1785. ***************
  1786. *** 215,220 ****
  1787. --- 237,312 ----
  1788.       return stab_val(stab);
  1789.   }
  1790.   
  1791. + STRLEN
  1792. + stab_len(str)
  1793. + STR *str;
  1794. + {
  1795. +     STAB *stab = str->str_u.str_stab;
  1796. +     int paren;
  1797. +     int i;
  1798. +     char *s;
  1799. +     if (str->str_rare)
  1800. +     return stab_val(stab)->str_cur;
  1801. +     switch (*stab->str_magic->str_ptr) {
  1802. +     case '1': case '2': case '3': case '4':
  1803. +     case '5': case '6': case '7': case '8': case '9': case '&':
  1804. +     if (curspat) {
  1805. +         paren = atoi(stab_name(stab));
  1806. +       getparen:
  1807. +         if (curspat->spat_regexp &&
  1808. +           paren <= curspat->spat_regexp->nparens &&
  1809. +           (s = curspat->spat_regexp->startp[paren]) ) {
  1810. +         i = curspat->spat_regexp->endp[paren] - s;
  1811. +         if (i >= 0)
  1812. +             return i;
  1813. +         else
  1814. +             return 0;
  1815. +         }
  1816. +         else
  1817. +         return 0;
  1818. +     }
  1819. +     break;
  1820. +     case '+':
  1821. +     if (curspat) {
  1822. +         paren = curspat->spat_regexp->lastparen;
  1823. +         goto getparen;
  1824. +     }
  1825. +     break;
  1826. +     case '`':
  1827. +     if (curspat) {
  1828. +         if (curspat->spat_regexp &&
  1829. +           (s = curspat->spat_regexp->subbeg) ) {
  1830. +         i = curspat->spat_regexp->startp[0] - s;
  1831. +         if (i >= 0)
  1832. +             return i;
  1833. +         else
  1834. +             return 0;
  1835. +         }
  1836. +         else
  1837. +         return 0;
  1838. +     }
  1839. +     break;
  1840. +     case '\'':
  1841. +     if (curspat) {
  1842. +         if (curspat->spat_regexp &&
  1843. +           (s = curspat->spat_regexp->endp[0]) ) {
  1844. +         return (STRLEN) (curspat->spat_regexp->subend - s);
  1845. +         }
  1846. +         else
  1847. +         return 0;
  1848. +     }
  1849. +     break;
  1850. +     case ',':
  1851. +     return (STRLEN)ofslen;
  1852. +     case '\\':
  1853. +     return (STRLEN)orslen;
  1854. +     default:
  1855. +     return stab_str(str)->str_cur;
  1856. +     }
  1857. + }
  1858.   stabset(mstr,str)
  1859.   register STR *mstr;
  1860.   STR *str;
  1861. ***************
  1862. *** 334,341 ****
  1863. --- 426,438 ----
  1864.       case '\004':    /* ^D */
  1865.   #ifdef DEBUGGING
  1866.           debug = (int)(str_gnum(str)) | 32768;
  1867. +         if (debug & 1024)
  1868. +         dump_all();
  1869.   #endif
  1870.           break;
  1871. +     case '\006':    /* ^F */
  1872. +         maxsysfd = (int)str_gnum(str);
  1873. +         break;
  1874.       case '\t':    /* ^I */
  1875.           if (inplace)
  1876.           Safefree(inplace);
  1877. ***************
  1878. *** 344,349 ****
  1879. --- 441,449 ----
  1880.           else
  1881.           inplace = Nullch;
  1882.           break;
  1883. +     case '\020':    /* ^P */
  1884. +         perldb = (int)str_gnum(str);
  1885. +         break;
  1886.       case '\024':    /* ^T */
  1887.           basetime = (long)str_gnum(str);
  1888.           break;
  1889. ***************
  1890. *** 430,441 ****
  1891.           break;
  1892.       case '<':
  1893.           uid = (int)str_gnum(str);
  1894. ! #ifdef HAS_SETREUID
  1895.           if (delaymagic) {
  1896.           delaymagic |= DM_REUID;
  1897.           break;                /* don't do magic till later */
  1898.           }
  1899. ! #endif /* HAS_SETREUID */
  1900.   #ifdef HAS_SETRUID
  1901.           if (setruid((UIDTYPE)uid) < 0)
  1902.           uid = (int)getuid();
  1903. --- 530,541 ----
  1904.           break;
  1905.       case '<':
  1906.           uid = (int)str_gnum(str);
  1907. ! #if defined(HAS_SETREUID) || !defined(HAS_SETRUID)
  1908.           if (delaymagic) {
  1909.           delaymagic |= DM_REUID;
  1910.           break;                /* don't do magic till later */
  1911.           }
  1912. ! #endif /* HAS_SETREUID or not HASSETRUID */
  1913.   #ifdef HAS_SETRUID
  1914.           if (setruid((UIDTYPE)uid) < 0)
  1915.           uid = (int)getuid();
  1916. ***************
  1917. *** 453,464 ****
  1918.           break;
  1919.       case '>':
  1920.           euid = (int)str_gnum(str);
  1921. ! #ifdef HAS_SETREUID
  1922.           if (delaymagic) {
  1923.           delaymagic |= DM_REUID;
  1924.           break;                /* don't do magic till later */
  1925.           }
  1926. ! #endif /* HAS_SETREUID */
  1927.   #ifdef HAS_SETEUID
  1928.           if (seteuid((UIDTYPE)euid) < 0)
  1929.           euid = (int)geteuid();
  1930. --- 553,564 ----
  1931.           break;
  1932.       case '>':
  1933.           euid = (int)str_gnum(str);
  1934. ! #if defined(HAS_SETREUID) || !defined(HAS_SETEUID)
  1935.           if (delaymagic) {
  1936.           delaymagic |= DM_REUID;
  1937.           break;                /* don't do magic till later */
  1938.           }
  1939. ! #endif /* HAS_SETREUID or not HAS_SETEUID */
  1940.   #ifdef HAS_SETEUID
  1941.           if (seteuid((UIDTYPE)euid) < 0)
  1942.           euid = (int)geteuid();
  1943. ***************
  1944. *** 476,487 ****
  1945.           break;
  1946.       case '(':
  1947.           gid = (int)str_gnum(str);
  1948. ! #ifdef HAS_SETREGID
  1949.           if (delaymagic) {
  1950.           delaymagic |= DM_REGID;
  1951.           break;                /* don't do magic till later */
  1952.           }
  1953. ! #endif /* HAS_SETREGID */
  1954.   #ifdef HAS_SETRGID
  1955.           (void)setrgid((GIDTYPE)gid);
  1956.   #else
  1957. --- 576,587 ----
  1958.           break;
  1959.       case '(':
  1960.           gid = (int)str_gnum(str);
  1961. ! #if defined(HAS_SETREGID) || !defined(HAS_SETRGID)
  1962.           if (delaymagic) {
  1963.           delaymagic |= DM_REGID;
  1964.           break;                /* don't do magic till later */
  1965.           }
  1966. ! #endif /* HAS_SETREGID or not HAS_SETRGID */
  1967.   #ifdef HAS_SETRGID
  1968.           (void)setrgid((GIDTYPE)gid);
  1969.   #else
  1970. ***************
  1971. *** 494,505 ****
  1972.           break;
  1973.       case ')':
  1974.           egid = (int)str_gnum(str);
  1975. ! #ifdef HAS_SETREGID
  1976.           if (delaymagic) {
  1977.           delaymagic |= DM_REGID;
  1978.           break;                /* don't do magic till later */
  1979.           }
  1980. ! #endif /* HAS_SETREGID */
  1981.   #ifdef HAS_SETEGID
  1982.           (void)setegid((GIDTYPE)egid);
  1983.   #else
  1984. --- 594,605 ----
  1985.           break;
  1986.       case ')':
  1987.           egid = (int)str_gnum(str);
  1988. ! #if defined(HAS_SETREGID) || !defined(HAS_SETEGID)
  1989.           if (delaymagic) {
  1990.           delaymagic |= DM_REGID;
  1991.           break;                /* don't do magic till later */
  1992.           }
  1993. ! #endif /* HAS_SETREGID or not HAS_SETEGID */
  1994.   #ifdef HAS_SETEGID
  1995.           (void)setegid((GIDTYPE)egid);
  1996.   #else
  1997.  
  1998. *** End of Patch 8 ***
  1999. exit 0 # Just in case...
  2000. -- 
  2001. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  2002. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  2003. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  2004. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  2005.