home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume30 / perl / patch31 < prev    next >
Encoding:
Text File  |  1992-06-11  |  49.1 KB  |  1,991 lines

  1. Newsgroups: comp.sources.misc
  2. From: lwall@netlabs.com (Larry Wall)
  3. Subject:  v30i042:  perl - The perl programming language, Patch31
  4. Message-ID: <1992Jun11.180837.1513@sparky.imd.sterling.com>
  5. X-Md4-Signature: caccc3bc2532ecd416516dc628dc3e6e
  6. Date: Thu, 11 Jun 1992 18:08:37 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: lwall@netlabs.com (Larry Wall)
  10. Posting-number: Volume 30, Issue 42
  11. Archive-name: perl/patch31
  12. Environment: UNIX, MS-DOS, OS2
  13. Patch-To: perl: Volume 18, Issue 19-54
  14.  
  15. System: perl version 4.0
  16. Patch #: 31
  17. Priority: highish
  18. Subject: patch #20, continued
  19.  
  20. Description:
  21.     See patch #20.
  22.  
  23. Fix:    From rn, say "| patch -p -N -d DIR", where DIR is your perl source
  24.     directory.  Outside of rn, say "cd DIR; patch -p -N <thisarticle".
  25.     If you don't have the patch program, apply the following by hand,
  26.     or get patch (version 2.0, latest patchlevel).
  27.  
  28.     After patching:
  29.         *** DO NOTHING--INSTALL ALL PATCHES UP THROUGH #33 FIRST ***
  30.  
  31.     If patch indicates that patchlevel is the wrong version, you may need
  32.     to apply one or more previous patches, or the patch may already
  33.     have been applied.  See the patchlevel.h file to find out what has or
  34.     has not been applied.  In any event, don't continue with the patch.
  35.  
  36.     If you are missing previous patches they can be obtained from me:
  37.  
  38.     Larry Wall
  39.     lwall@netlabs.com
  40.  
  41.     If you send a mail message of the following form it will greatly speed
  42.     processing:
  43.  
  44.     Subject: Command
  45.     @SH mailpatch PATH perl 4.0 LIST
  46.            ^ note the c
  47.  
  48.     where PATH is a return path FROM ME TO YOU either in Internet notation,
  49.     or in bang notation from some well-known host, and LIST is the number
  50.     of one or more patches you need, separated by spaces, commas, and/or
  51.     hyphens.  Saying 35- says everything from 35 to the end.
  52.  
  53.  
  54. Index: patchlevel.h
  55. Prereq: 30
  56. 1c1
  57. < #define PATCHLEVEL 30
  58. ---
  59. > #define PATCHLEVEL 31
  60.  
  61. Index: regcomp.c
  62. *** regcomp.c.old    Mon Jun  8 17:51:34 1992
  63. --- regcomp.c    Mon Jun  8 17:51:35 1992
  64. ***************
  65. *** 7,15 ****
  66.    * blame Henry for some of the lack of readability.
  67.    */
  68.   
  69. ! /* $RCSfile: regcomp.c,v $$Revision: 4.0.1.4 $$Date: 91/11/05 22:55:14 $
  70.    *
  71.    * $Log:    regcomp.c,v $
  72.    * Revision 4.0.1.4  91/11/05  22:55:14  lwall
  73.    * patch11: Erratum
  74.    * 
  75. --- 7,21 ----
  76.    * blame Henry for some of the lack of readability.
  77.    */
  78.   
  79. ! /* $RCSfile: regcomp.c,v $$Revision: 4.0.1.5 $$Date: 92/06/08 15:23:36 $
  80.    *
  81.    * $Log:    regcomp.c,v $
  82. +  * Revision 4.0.1.5  92/06/08  15:23:36  lwall
  83. +  * patch20: Perl now distinguishes overlapped copies from non-overlapped
  84. +  * patch20: /^stuff/ wrongly assumed an implicit $* == 1
  85. +  * patch20: /x{0}/ was wrongly interpreted as /x{0,}/
  86. +  * patch20: added \W, \S and \D inside /[...]/
  87. +  * 
  88.    * Revision 4.0.1.4  91/11/05  22:55:14  lwall
  89.    * patch11: Erratum
  90.    * 
  91. ***************
  92. *** 86,92 ****
  93. --- 92,102 ----
  94.   #define    ISMULT1(c)    ((c) == '*' || (c) == '+' || (c) == '?')
  95.   #define    ISMULT2(s)    ((*s) == '*' || (*s) == '+' || (*s) == '?' || \
  96.       ((*s) == '{' && regcurly(s)))
  97. + #ifdef atarist
  98. + #define    PERL_META    "^$.[()|?+*\\"
  99. + #else
  100.   #define    META    "^$.[()|?+*\\"
  101. + #endif
  102.   
  103.   #ifdef SPSTART
  104.   #undef SPSTART        /* dratted cpp namespace... */
  105. ***************
  106. *** 160,169 ****
  107.       int backest;
  108.       int curback;
  109.       int minlen;
  110. - #ifndef safemalloc
  111. -     extern char *safemalloc();
  112. - #endif
  113. -     extern char *savestr();
  114.       int sawplus = 0;
  115.       int sawopen = 0;
  116.   
  117. --- 170,175 ----
  118. ***************
  119. *** 198,204 ****
  120.   
  121.       /* Second pass: emit code. */
  122.       if (regsawbracket)
  123. !         bcopy(regprecomp,exp,xend-exp);
  124.       r->prelen = xend-exp;
  125.       r->precomp = regprecomp;
  126.       r->subbeg = r->subbase = NULL;
  127. --- 204,210 ----
  128.   
  129.       /* Second pass: emit code. */
  130.       if (regsawbracket)
  131. !         Copy(regprecomp,exp,xend-exp,char);
  132.       r->prelen = xend-exp;
  133.       r->precomp = regprecomp;
  134.       r->subbeg = r->subbase = NULL;
  135. ***************
  136. *** 243,251 ****
  137.               r->regstclass = first;
  138.           else if (OP(first) == BOUND || OP(first) == NBOUND)
  139.               r->regstclass = first;
  140. !         else if (OP(first) == BOL ||
  141. !             (OP(first) == STAR && OP(NEXTOPER(first)) == ANY) ) {
  142. !             /* kinda turn .* into ^.* */
  143.               r->reganch = ROPT_ANCH | ROPT_IMPLICIT;
  144.               first = NEXTOPER(first);
  145.                   goto again;
  146. --- 249,262 ----
  147.               r->regstclass = first;
  148.           else if (OP(first) == BOUND || OP(first) == NBOUND)
  149.               r->regstclass = first;
  150. !         else if (OP(first) == BOL) {
  151. !             r->reganch = ROPT_ANCH;
  152. !             first = NEXTOPER(first);
  153. !                 goto again;
  154. !         }
  155. !         else if ((OP(first) == STAR && OP(NEXTOPER(first)) == ANY) &&
  156. !              !(r->reganch & ROPT_ANCH) ) {
  157. !             /* turn .* into ^.* with an implied $*=1 */
  158.               r->reganch = ROPT_ANCH | ROPT_IMPLICIT;
  159.               first = NEXTOPER(first);
  160.                   goto again;
  161. ***************
  162. *** 564,569 ****
  163. --- 575,582 ----
  164.               else
  165.               max = regparse;
  166.               tmp = atoi(max);
  167. +             if (!tmp && *max != '0')
  168. +             tmp = 32767;        /* meaning "infinity" */
  169.               if (tmp && tmp < iter)
  170.               fatal("Can't do {n,m} with n > m");
  171.               if (regcode != ®dummy) {
  172. ***************
  173. *** 967,994 ****
  174.               class = UCHARAT(regparse++);
  175.               switch (class) {
  176.               case 'w':
  177. !                 for (class = 'a'; class <= 'z'; class++)
  178.                       regset(bits,def,class);
  179. !                 for (class = 'A'; class <= 'Z'; class++)
  180.                       regset(bits,def,class);
  181. -                 for (class = '0'; class <= '9'; class++)
  182. -                     regset(bits,def,class);
  183. -                 regset(bits,def,'_');
  184.                   lastclass = 1234;
  185.                   continue;
  186.               case 's':
  187. !                 regset(bits,def,' ');
  188. !                 regset(bits,def,'\t');
  189. !                 regset(bits,def,'\r');
  190. !                 regset(bits,def,'\f');
  191. !                 regset(bits,def,'\n');
  192.                   lastclass = 1234;
  193.                   continue;
  194.               case 'd':
  195.                   for (class = '0'; class <= '9'; class++)
  196.                       regset(bits,def,class);
  197.                   lastclass = 1234;
  198.                   continue;
  199.               case 'n':
  200.                   class = '\n';
  201.                   break;
  202. --- 980,1020 ----
  203.               class = UCHARAT(regparse++);
  204.               switch (class) {
  205.               case 'w':
  206. !                 for (class = 0; class < 256; class++)
  207. !                     if (isALNUM(class))
  208.                       regset(bits,def,class);
  209. !                 lastclass = 1234;
  210. !                 continue;
  211. !             case 'W':
  212. !                 for (class = 0; class < 256; class++)
  213. !                     if (!isALNUM(class))
  214.                       regset(bits,def,class);
  215.                   lastclass = 1234;
  216.                   continue;
  217.               case 's':
  218. !                 for (class = 0; class < 256; class++)
  219. !                     if (isSPACE(class))
  220. !                     regset(bits,def,class);
  221.                   lastclass = 1234;
  222.                   continue;
  223. +             case 'S':
  224. +                 for (class = 0; class < 256; class++)
  225. +                     if (!isSPACE(class))
  226. +                     regset(bits,def,class);
  227. +                 lastclass = 1234;
  228. +                 continue;
  229.               case 'd':
  230.                   for (class = '0'; class <= '9'; class++)
  231.                       regset(bits,def,class);
  232.                   lastclass = 1234;
  233.                   continue;
  234. +             case 'D':
  235. +                 for (class = 0; class < '0'; class++)
  236. +                     regset(bits,def,class);
  237. +                 for (class = '9' + 1; class < 256; class++)
  238. +                     regset(bits,def,class);
  239. +                 lastclass = 1234;
  240. +                 continue;
  241.               case 'n':
  242.                   class = '\n';
  243.                   break;
  244. ***************
  245. *** 1184,1189 ****
  246. --- 1210,1218 ----
  247.       *place++ = '\0';
  248.       while (offset-- > 0)
  249.           *place++ = '\0';
  250. + #ifdef REGALIGN
  251. +     *place++ = '\177';
  252. + #endif
  253.   }
  254.   
  255.   /*
  256. ***************
  257. *** 1420,1425 ****
  258. --- 1449,1455 ----
  259.   }
  260.   #endif /* DEBUGGING */
  261.   
  262. + void
  263.   regfree(r)
  264.   struct regexp *r;
  265.   {
  266.  
  267. Index: regexec.c
  268. *** regexec.c.old    Mon Jun  8 17:51:40 1992
  269. --- regexec.c    Mon Jun  8 17:51:40 1992
  270. ***************
  271. *** 7,15 ****
  272.    * blame Henry for some of the lack of readability.
  273.    */
  274.   
  275. ! /* $RCSfile: regexec.c,v $$Revision: 4.0.1.3 $$Date: 91/11/05 18:23:55 $
  276.    *
  277.    * $Log:    regexec.c,v $
  278.    * Revision 4.0.1.3  91/11/05  18:23:55  lwall
  279.    * patch11: prepared for ctype implementations that don't define isascii()
  280.    * patch11: initial .* in pattern had dependency on value of $*
  281. --- 7,20 ----
  282.    * blame Henry for some of the lack of readability.
  283.    */
  284.   
  285. ! /* $RCSfile: regexec.c,v $$Revision: 4.0.1.4 $$Date: 92/06/08 15:25:50 $
  286.    *
  287.    * $Log:    regexec.c,v $
  288. +  * Revision 4.0.1.4  92/06/08  15:25:50  lwall
  289. +  * patch20: pattern modifiers i and g didn't interact right
  290. +  * patch20: in some cases $` and $' didn't get set by match
  291. +  * patch20: /x{0}/ was wrongly interpreted as /x{0,}/
  292. +  * 
  293.    * Revision 4.0.1.3  91/11/05  18:23:55  lwall
  294.    * patch11: prepared for ctype implementations that don't define isascii()
  295.    * patch11: initial .* in pattern had dependency on value of $*
  296. ***************
  297. *** 140,149 ****
  298.       }
  299.   
  300.       if (prog->do_folding) {
  301. -         safebase = FALSE;
  302.           i = strend - string;
  303.           New(1101,c,i+1,char);
  304. !         (void)bcopy(string, c, i+1);
  305.           string = c;
  306.           strend = string + i;
  307.           for (s = string; s < strend; s++)
  308. --- 145,153 ----
  309.       }
  310.   
  311.       if (prog->do_folding) {
  312.           i = strend - string;
  313.           New(1101,c,i+1,char);
  314. !         Copy(string, c, i+1, char);
  315.           string = c;
  316.           strend = string + i;
  317.           for (s = string; s < strend; s++)
  318. ***************
  319. *** 441,446 ****
  320. --- 445,452 ----
  321.       goto phooey;
  322.   
  323.       got_it:
  324. +     prog->subbeg = strbeg;
  325. +     prog->subend = strend;
  326.       if ((!safebase && (prog->nparens || sawampersand)) || prog->do_folding){
  327.           strend += dontbother;    /* uncheat */
  328.           if (safebase)            /* no need for $digit later */
  329. ***************
  330. *** 453,460 ****
  331.               prog->subbeg = prog->subbase = s;
  332.               prog->subend = s+i;
  333.           }
  334. !         else
  335. !             s = prog->subbase;
  336.           s += (stringarg - strbeg);
  337.           for (i = 0; i <= prog->nparens; i++) {
  338.               if (prog->endp[i]) {
  339. --- 459,469 ----
  340.               prog->subbeg = prog->subbase = s;
  341.               prog->subend = s+i;
  342.           }
  343. !         else {
  344. !             i = strend - string + (stringarg - strbeg);
  345. !             prog->subbeg = s = prog->subbase;
  346. !             prog->subend = s+i;
  347. !         }
  348.           s += (stringarg - strbeg);
  349.           for (i = 0; i <= prog->nparens; i++) {
  350.               if (prog->endp[i]) {
  351. ***************
  352. *** 742,748 ****
  353.               goto repeat;
  354.           case STAR:
  355.               ln = 0;
  356. !             n = 0;
  357.               scan = NEXTOPER(scan);
  358.               goto repeat;
  359.           case PLUS:
  360. --- 751,757 ----
  361.               goto repeat;
  362.           case STAR:
  363.               ln = 0;
  364. !             n = 32767;
  365.               scan = NEXTOPER(scan);
  366.               goto repeat;
  367.           case PLUS:
  368. ***************
  369. *** 751,757 ****
  370.                * when we know what character comes next.
  371.                */
  372.               ln = 1;
  373. !             n = 0;
  374.               scan = NEXTOPER(scan);
  375.               repeat:
  376.               if (OP(next) == EXACTLY)
  377. --- 760,766 ----
  378.                * when we know what character comes next.
  379.                */
  380.               ln = 1;
  381. !             n = 32767;
  382.               scan = NEXTOPER(scan);
  383.               repeat:
  384.               if (OP(next) == EXACTLY)
  385. ***************
  386. *** 813,819 ****
  387.       register char *loceol = regeol;
  388.   
  389.       scan = reginput;
  390. !     if (max && max < loceol - scan)
  391.           loceol = scan + max;
  392.       opnd = OPERAND(p);
  393.       switch (OP(p)) {
  394. --- 822,828 ----
  395.       register char *loceol = regeol;
  396.   
  397.       scan = reginput;
  398. !     if (max != 32767 && max < loceol - scan)
  399.           loceol = scan + max;
  400.       opnd = OPERAND(p);
  401.       switch (OP(p)) {
  402.  
  403. Index: x2p/s2p.SH
  404. *** x2p/s2p.SH.old    Mon Jun  8 17:52:59 1992
  405. --- x2p/s2p.SH    Mon Jun  8 17:52:59 1992
  406. ***************
  407. *** 20,28 ****
  408. --- 20,32 ----
  409.   : Move anything that needs config subs from !NO!SUBS! section to !GROK!THIS!.
  410.   : Protect any dollar signs and backticks that you do not want interpreted
  411.   : by putting a backslash in front.  You may delete these comments.
  412. + rm -f s2p
  413.   $spitshell >s2p <<!GROK!THIS!
  414.   #!$bin/perl
  415.   
  416. + eval 'exec $bin/perl -S \$0 \${1+"\$@"}'
  417. +     if \$running_under_some_shell;
  418.   \$bin = '$bin';
  419.   !GROK!THIS!
  420.   
  421. ***************
  422. *** 29,37 ****
  423.   : In the following dollars and backticks do not need the extra backslash.
  424.   $spitshell >>s2p <<'!NO!SUBS!'
  425.   
  426. ! # $RCSfile: s2p.SH,v $$Revision: 4.0.1.1 $$Date: 91/06/07 12:19:18 $
  427.   #
  428.   # $Log:    s2p.SH,v $
  429.   # Revision 4.0.1.1  91/06/07  12:19:18  lwall
  430.   # patch4: s2p now handles embedded newlines better and optimizes common idioms
  431.   # 
  432. --- 33,46 ----
  433.   : In the following dollars and backticks do not need the extra backslash.
  434.   $spitshell >>s2p <<'!NO!SUBS!'
  435.   
  436. ! # $RCSfile: s2p.SH,v $$Revision: 4.0.1.2 $$Date: 92/06/08 17:26:31 $
  437.   #
  438.   # $Log:    s2p.SH,v $
  439. + # Revision 4.0.1.2  92/06/08  17:26:31  lwall
  440. + # patch20: s2p didn't output portable startup code
  441. + # patch20: added ... as variant on ..
  442. + # patch20: s2p didn't translate s/pat/\&/ or s/pat/\$/ or s/pat/\\1/ right
  443. + # 
  444.   # Revision 4.0.1.1  91/06/07  12:19:18  lwall
  445.   # patch4: s2p now handles embedded newlines better and optimizes common idioms
  446.   # 
  447. ***************
  448. *** 162,168 ****
  449.       } else {
  450.           &Die("Invalid second address at line $.\n");
  451.       }
  452. !     $addr1 .= " .. $addr2";
  453.       }
  454.   
  455.       # Now we check for metacommands {, }, and ! and worry
  456. --- 171,182 ----
  457.       } else {
  458.           &Die("Invalid second address at line $.\n");
  459.       }
  460. !     if ($addr2 =~ /^\d+$/) {
  461. !         $addr1 .= "..$addr2";
  462. !     }
  463. !     else {
  464. !         $addr1 .= "...$addr2";
  465. !     }
  466.       }
  467.   
  468.       # Now we check for metacommands {, }, and ! and worry
  469. ***************
  470. *** 488,494 ****
  471. --- 502,521 ----
  472.                 substr($_,$i,1) =~ /^[<>]$/) {
  473.               substr($_,$i,1) = 'b';
  474.               }
  475. +             elsif ($repl && substr($_,$i,1) =~ /^\d$/) {
  476. +             substr($_,$i-1,1) = '$';
  477. +             }
  478.           }
  479. +         elsif ($c eq '&' && $repl) {
  480. +             substr($_, $i, 0) = '$';
  481. +             $i++;
  482. +             $len++;
  483. +         }
  484. +         elsif ($c eq '$' && $repl) {
  485. +             substr($_, $i, 0) = '\\';
  486. +             $i++;
  487. +             $len++;
  488. +         }
  489.           elsif ($c eq '[' && !$repl) {
  490.               $i++ if substr($_,$i,1) eq '^';
  491.               $i++ if substr($_,$i,1) eq ']';
  492. ***************
  493. *** 515,523 ****
  494.           $end = substr($_, $end + 1, 1000);
  495.           &simplify($pat);
  496.           $dol = '$';
  497. -         $repl =~ s/\$/\\$/;
  498. -         $repl =~ s'&'$&'g;
  499. -         $repl =~ s/[\\]([0-9])/$dol$1/g;
  500.           $subst = "$pat$repl$delim";
  501.           $cmd = '';
  502.           while ($end) {
  503. --- 542,547 ----
  504.  
  505. Index: hints/sco_2_3_3.sh
  506. *** hints/sco_2_3_3.sh.old    Mon Jun  8 17:48:13 1992
  507. --- hints/sco_2_3_3.sh    Mon Jun  8 17:48:13 1992
  508. ***************
  509. *** 1,4 ****
  510.   yacc='/usr/bin/yacc -Sm25000'
  511. - libswanted=`echo $libswanted | sed 's/ x / /'`
  512.   echo "NOTE: you may have problems due to a spurious semicolon on the strerror()"
  513.   echo "macro definition in /usr/include/string.h.  If so, delete the semicolon."
  514. --- 1,3 ----
  515.  
  516. Index: hints/sco_2_3_4.sh
  517. *** hints/sco_2_3_4.sh.old    Mon Jun  8 17:48:15 1992
  518. --- hints/sco_2_3_4.sh    Mon Jun  8 17:48:15 1992
  519. ***************
  520. *** 0 ****
  521. --- 1,5 ----
  522. + yacc='/usr/bin/yacc -Sm25000'
  523. + ccflags="$ccflags -UM_I86"
  524. + d_mymalloc=define
  525. + echo "NOTE: you may have problems due to a spurious semicolon on the strerror()"
  526. + echo "macro definition in /usr/include/string.h.  If so, delete the semicolon."
  527.  
  528. Index: hints/sgi.sh
  529. *** hints/sgi.sh.old    Mon Jun  8 17:48:17 1992
  530. --- hints/sgi.sh    Mon Jun  8 17:48:18 1992
  531. ***************
  532. *** 1,6 ****
  533.   optimize='-O1'
  534. ! usemymalloc='y'
  535.   mallocsrc='malloc.c'
  536.   mallocobj='malloc.o'
  537.   d_voidsig=define
  538.   d_vfork=undef
  539. --- 1,12 ----
  540.   optimize='-O1'
  541. ! d_mymalloc=define
  542.   mallocsrc='malloc.c'
  543.   mallocobj='malloc.o'
  544.   d_voidsig=define
  545.   d_vfork=undef
  546. + d_charsprf=undef
  547. + case `(uname -r) 2>/dev/null` in
  548. + 4*)libswanted=`echo $libswanted | sed 's/c_s \(.*\)/\1 c_s/'`
  549. +     ccflags="$ccflags -DLANGUAGE_C -DBSD_SIGNALS -cckr -signed"
  550. +     ;;
  551. + esac
  552.  
  553. Index: lib/shellwords.pl
  554. *** lib/shellwords.pl.old    Mon Jun  8 17:49:11 1992
  555. --- lib/shellwords.pl    Mon Jun  8 17:49:12 1992
  556. ***************
  557. *** 1,12 ****
  558. ! #; shellwords.pl
  559. ! #;
  560. ! #; Usage:
  561. ! #;    require 'shellwords.pl';
  562. ! #;    @words = &shellwords($line);
  563. ! #;    or
  564. ! #;    @words = &shellwords(@lines);
  565. ! #;    or
  566. ! #;    @words = &shellwords;        # defaults to $_ (and clobbers it)
  567.   
  568.   sub shellwords {
  569.       package shellwords;
  570. --- 1,12 ----
  571. ! ;# shellwords.pl
  572. ! ;#
  573. ! ;# Usage:
  574. ! ;#    require 'shellwords.pl';
  575. ! ;#    @words = &shellwords($line);
  576. ! ;#    or
  577. ! ;#    @words = &shellwords(@lines);
  578. ! ;#    or
  579. ! ;#    @words = &shellwords;        # defaults to $_ (and clobbers it)
  580.   
  581.   sub shellwords {
  582.       package shellwords;
  583. ***************
  584. *** 17,27 ****
  585.       while ($_ ne '') {
  586.       $field = '';
  587.       for (;;) {
  588. !         if (s/^"(([^"\\]+|\\[\\"])*)"//) {
  589.           ($snippet = $1) =~ s#\\(.)#$1#g;
  590.           }
  591. !         elsif (s/^'(([^'\\]+|\\[\\'])*)'//) {
  592.           ($snippet = $1) =~ s#\\(.)#$1#g;
  593.           }
  594.           elsif (s/^\\(.)//) {
  595.           $snippet = $1;
  596. --- 17,33 ----
  597.       while ($_ ne '') {
  598.       $field = '';
  599.       for (;;) {
  600. !         if (s/^"(([^"\\]|\\[\\"])*)"//) {
  601.           ($snippet = $1) =~ s#\\(.)#$1#g;
  602.           }
  603. !         elsif (/^"/) {
  604. !         die "Unmatched double quote: $_\n";
  605. !         }
  606. !         elsif (s/^'(([^'\\]|\\[\\'])*)'//) {
  607.           ($snippet = $1) =~ s#\\(.)#$1#g;
  608. +         }
  609. +         elsif (/^'/) {
  610. +         die "Unmatched single quote: $_\n";
  611.           }
  612.           elsif (s/^\\(.)//) {
  613.           $snippet = $1;
  614.  
  615. Index: atarist/test/sig
  616. *** atarist/test/sig.old    Mon Jun  8 17:45:21 1992
  617. --- atarist/test/sig    Mon Jun  8 17:45:21 1992
  618. ***************
  619. *** 0 ****
  620. --- 1,12 ----
  621. + sub handler {
  622. +     local($sig) = @_;
  623. +     print "Caught SIG$sig\n";
  624. +     exit(0);
  625. + }
  626. + $SIG{'INT'} = 'handler';
  627. + print "Hit CRTL-C to see if it is trapped\n";
  628. + while($_ = <ARGV>) {
  629. +     print $_;
  630. + }
  631.  
  632. Index: stab.c
  633. *** stab.c.old    Mon Jun  8 17:51:45 1992
  634. --- stab.c    Mon Jun  8 17:51:45 1992
  635. ***************
  636. *** 1,4 ****
  637. ! /* $RCSfile: stab.c,v $$Revision: 4.0.1.3 $$Date: 91/11/05 18:35:33 $
  638.    *
  639.    *    Copyright (c) 1991, Larry Wall
  640.    *
  641. --- 1,4 ----
  642. ! /* $RCSfile: stab.c,v $$Revision: 4.0.1.4 $$Date: 92/06/08 15:32:19 $
  643.    *
  644.    *    Copyright (c) 1991, Larry Wall
  645.    *
  646. ***************
  647. *** 6,11 ****
  648. --- 6,18 ----
  649.    *    License or the Artistic License, as specified in the README file.
  650.    *
  651.    * $Log:    stab.c,v $
  652. +  * Revision 4.0.1.4  92/06/08  15:32:19  lwall
  653. +  * patch20: fixed confusion between a *var's real name and its effective name
  654. +  * patch20: the debugger now warns you on lines that can't set a breakpoint
  655. +  * patch20: the debugger made perl forget the last pattern used by //
  656. +  * patch20: paragraph mode now skips extra newlines automatically
  657. +  * patch20: ($<,$>) = ... didn't work on some architectures
  658. +  * 
  659.    * Revision 4.0.1.3  91/11/05  18:35:33  lwall
  660.    * patch11: length($x) was sometimes wrong for numeric $x
  661.    * patch11: perl now issues warning if $SIG{'ALARM'} is referenced
  662. ***************
  663. *** 91,97 ****
  664.       case '1': case '2': case '3': case '4':
  665.       case '5': case '6': case '7': case '8': case '9': case '&':
  666.       if (curspat) {
  667. !         paren = atoi(stab_name(stab));
  668.         getparen:
  669.           if (curspat->spat_regexp &&
  670.             paren <= curspat->spat_regexp->nparens &&
  671. --- 98,104 ----
  672.       case '1': case '2': case '3': case '4':
  673.       case '5': case '6': case '7': case '8': case '9': case '&':
  674.       if (curspat) {
  675. !         paren = atoi(stab_ename(stab));
  676.         getparen:
  677.           if (curspat->spat_regexp &&
  678.             paren <= curspat->spat_regexp->nparens &&
  679. ***************
  680. *** 138,144 ****
  681.       break;
  682.       case '.':
  683.   #ifndef lint
  684. !     if (last_in_stab) {
  685.           str_numset(stab_val(stab),(double)stab_io(last_in_stab)->lines);
  686.       }
  687.   #endif
  688. --- 145,151 ----
  689.       break;
  690.       case '.':
  691.   #ifndef lint
  692. !     if (last_in_stab && stab_io(last_in_stab)) {
  693.           str_numset(stab_val(stab),(double)stab_io(last_in_stab)->lines);
  694.       }
  695.   #endif
  696. ***************
  697. *** 151,157 ****
  698.       if (s)
  699.           str_set(stab_val(stab),s);
  700.       else {
  701. !         str_set(stab_val(stab),stab_name(curoutstab));
  702.           str_cat(stab_val(stab),"_TOP");
  703.       }
  704.       break;
  705. --- 158,164 ----
  706.       if (s)
  707.           str_set(stab_val(stab),s);
  708.       else {
  709. !         str_set(stab_val(stab),stab_ename(curoutstab));
  710.           str_cat(stab_val(stab),"_TOP");
  711.       }
  712.       break;
  713. ***************
  714. *** 158,164 ****
  715.       case '~':
  716.       s = stab_io(curoutstab)->fmt_name;
  717.       if (!s)
  718. !         s = stab_name(curoutstab);
  719.       str_set(stab_val(stab),s);
  720.       break;
  721.   #ifndef lint
  722. --- 165,171 ----
  723.       case '~':
  724.       s = stab_io(curoutstab)->fmt_name;
  725.       if (!s)
  726. !         s = stab_ename(curoutstab);
  727.       str_set(stab_val(stab),s);
  728.       break;
  729.   #ifndef lint
  730. ***************
  731. *** 172,177 ****
  732. --- 179,186 ----
  733.       str_numset(stab_val(stab),(double)stab_io(curoutstab)->page);
  734.       break;
  735.   #endif
  736. +     case ':':
  737. +     break;
  738.       case '/':
  739.       break;
  740.       case '[':
  741. ***************
  742. *** 260,266 ****
  743.       case '1': case '2': case '3': case '4':
  744.       case '5': case '6': case '7': case '8': case '9': case '&':
  745.       if (curspat) {
  746. !         paren = atoi(stab_name(stab));
  747.         getparen:
  748.           if (curspat->spat_regexp &&
  749.             paren <= curspat->spat_regexp->nparens &&
  750. --- 269,275 ----
  751.       case '1': case '2': case '3': case '4':
  752.       case '5': case '6': case '7': case '8': case '9': case '&':
  753.       if (curspat) {
  754. !         paren = atoi(stab_ename(stab));
  755.         getparen:
  756.           if (curspat->spat_regexp &&
  757.             paren <= curspat->spat_regexp->nparens &&
  758. ***************
  759. *** 314,319 ****
  760. --- 323,329 ----
  761.       }
  762.   }
  763.   
  764. + void
  765.   stabset(mstr,str)
  766.   register STR *mstr;
  767.   STR *str;
  768. ***************
  769. *** 324,330 ****
  770.   
  771.       switch (mstr->str_rare) {
  772.       case 'E':
  773. !     setenv(mstr->str_ptr,str_get(str));
  774.                   /* And you'll never guess what the dog had */
  775.                   /*   in its mouth... */
  776.   #ifdef TAINT
  777. --- 334,340 ----
  778.   
  779.       switch (mstr->str_rare) {
  780.       case 'E':
  781. !     my_setenv(mstr->str_ptr,str_get(str));
  782.                   /* And you'll never guess what the dog had */
  783.                   /*   in its mouth... */
  784.   #ifdef TAINT
  785. ***************
  786. *** 376,384 ****
  787.           stab = mstr->str_u.str_stab;
  788.           i = str_true(str);
  789.           str = afetch(stab_xarray(stab),atoi(mstr->str_ptr), FALSE);
  790. !         cmd = str->str_magic->str_u.str_cmd;
  791. !         cmd->c_flags &= ~CF_OPTIMIZE;
  792. !         cmd->c_flags |= i? CFT_D1 : CFT_D0;
  793.       }
  794.       break;
  795.       case '#':
  796. --- 386,397 ----
  797.           stab = mstr->str_u.str_stab;
  798.           i = str_true(str);
  799.           str = afetch(stab_xarray(stab),atoi(mstr->str_ptr), FALSE);
  800. !         if (str->str_magic && (cmd = str->str_magic->str_u.str_cmd)) {
  801. !         cmd->c_flags &= ~CF_OPTIMIZE;
  802. !         cmd->c_flags |= i? CFT_D1 : CFT_D0;
  803. !         }
  804. !         else
  805. !         warn("Can't break at that line\n");
  806.       }
  807.       break;
  808.       case '#':
  809. ***************
  810. *** 405,411 ****
  811.           strcpy(stab_magic(stab),"StB");
  812.           stab_val(stab) = Str_new(70,0);
  813.           stab_line(stab) = curcmd->c_line;
  814. !         stab_stash(stab) = curcmd->c_stash;
  815.           }
  816.           else {
  817.           stab = stabent(s,TRUE);
  818. --- 418,424 ----
  819.           strcpy(stab_magic(stab),"StB");
  820.           stab_val(stab) = Str_new(70,0);
  821.           stab_line(stab) = curcmd->c_line;
  822. !         stab_estab(stab) = stab;
  823.           }
  824.           else {
  825.           stab = stabent(s,TRUE);
  826. ***************
  827. *** 459,468 ****
  828.           inplace = Nullch;
  829.           break;
  830.       case '\020':    /* ^P */
  831. !         perldb = (int)str_gnum(str);
  832.           break;
  833.       case '\024':    /* ^T */
  834. !         basetime = (long)str_gnum(str);
  835.           break;
  836.       case '\027':    /* ^W */
  837.           dowarn = (bool)str_gnum(str);
  838. --- 472,490 ----
  839.           inplace = Nullch;
  840.           break;
  841.       case '\020':    /* ^P */
  842. !         i = (int)str_gnum(str);
  843. !         if (i != perldb) {
  844. !         static SPAT *oldlastspat;
  845. !         if (perldb)
  846. !             oldlastspat = lastspat;
  847. !         else
  848. !             lastspat = oldlastspat;
  849. !         }
  850. !         perldb = i;
  851.           break;
  852.       case '\024':    /* ^T */
  853. !         basetime = (time_t)str_gnum(str);
  854.           break;
  855.       case '\027':    /* ^W */
  856.           dowarn = (bool)str_gnum(str);
  857. ***************
  858. *** 508,514 ****
  859.           if (str->str_pok) {
  860.           rs = str_get(str);
  861.           rslen = str->str_cur;
  862. !         if (!rslen) {
  863.               rs = "\n\n";
  864.               rslen = 2;
  865.           }
  866. --- 530,536 ----
  867.           if (str->str_pok) {
  868.           rs = str_get(str);
  869.           rslen = str->str_cur;
  870. !         if (rspara = !rslen) {
  871.               rs = "\n\n";
  872.               rslen = 2;
  873.           }
  874. ***************
  875. *** 547,588 ****
  876.           break;
  877.       case '<':
  878.           uid = (int)str_gnum(str);
  879. - #if defined(HAS_SETREUID) || !defined(HAS_SETRUID)
  880.           if (delaymagic) {
  881. !         delaymagic |= DM_REUID;
  882.           break;                /* don't do magic till later */
  883.           }
  884. - #endif /* HAS_SETREUID or not HASSETRUID */
  885.   #ifdef HAS_SETRUID
  886. !         if (setruid((UIDTYPE)uid) < 0)
  887. !         uid = (int)getuid();
  888.   #else
  889.   #ifdef HAS_SETREUID
  890. !         if (setreuid((UIDTYPE)uid, (UIDTYPE)-1) < 0)
  891. !         uid = (int)getuid();
  892.   #else
  893.           if (uid == euid)        /* special case $< = $> */
  894. !         setuid(uid);
  895.           else
  896.           fatal("setruid() not implemented");
  897.   #endif
  898.   #endif
  899.           break;
  900.       case '>':
  901.           euid = (int)str_gnum(str);
  902. - #if defined(HAS_SETREUID) || !defined(HAS_SETEUID)
  903.           if (delaymagic) {
  904. !         delaymagic |= DM_REUID;
  905.           break;                /* don't do magic till later */
  906.           }
  907. - #endif /* HAS_SETREUID or not HAS_SETEUID */
  908.   #ifdef HAS_SETEUID
  909. !         if (seteuid((UIDTYPE)euid) < 0)
  910. !         euid = (int)geteuid();
  911.   #else
  912.   #ifdef HAS_SETREUID
  913. !         if (setreuid((UIDTYPE)-1, (UIDTYPE)euid) < 0)
  914. !         euid = (int)geteuid();
  915.   #else
  916.           if (euid == uid)        /* special case $> = $< */
  917.           setuid(euid);
  918. --- 569,603 ----
  919.           break;
  920.       case '<':
  921.           uid = (int)str_gnum(str);
  922.           if (delaymagic) {
  923. !         delaymagic |= DM_RUID;
  924.           break;                /* don't do magic till later */
  925.           }
  926.   #ifdef HAS_SETRUID
  927. !         (void)setruid((UIDTYPE)uid);
  928.   #else
  929.   #ifdef HAS_SETREUID
  930. !         (void)setreuid((UIDTYPE)uid, (UIDTYPE)-1);
  931.   #else
  932.           if (uid == euid)        /* special case $< = $> */
  933. !         (void)setuid(uid);
  934.           else
  935.           fatal("setruid() not implemented");
  936.   #endif
  937.   #endif
  938. +         uid = (int)getuid();
  939.           break;
  940.       case '>':
  941.           euid = (int)str_gnum(str);
  942.           if (delaymagic) {
  943. !         delaymagic |= DM_EUID;
  944.           break;                /* don't do magic till later */
  945.           }
  946.   #ifdef HAS_SETEUID
  947. !         (void)seteuid((UIDTYPE)euid);
  948.   #else
  949.   #ifdef HAS_SETREUID
  950. !         (void)setreuid((UIDTYPE)-1, (UIDTYPE)euid);
  951.   #else
  952.           if (euid == uid)        /* special case $> = $< */
  953.           setuid(euid);
  954. ***************
  955. *** 590,604 ****
  956.           fatal("seteuid() not implemented");
  957.   #endif
  958.   #endif
  959.           break;
  960.       case '(':
  961.           gid = (int)str_gnum(str);
  962. - #if defined(HAS_SETREGID) || !defined(HAS_SETRGID)
  963.           if (delaymagic) {
  964. !         delaymagic |= DM_REGID;
  965.           break;                /* don't do magic till later */
  966.           }
  967. - #endif /* HAS_SETREGID or not HAS_SETRGID */
  968.   #ifdef HAS_SETRGID
  969.           (void)setrgid((GIDTYPE)gid);
  970.   #else
  971. --- 605,618 ----
  972.           fatal("seteuid() not implemented");
  973.   #endif
  974.   #endif
  975. +         euid = (int)geteuid();
  976.           break;
  977.       case '(':
  978.           gid = (int)str_gnum(str);
  979.           if (delaymagic) {
  980. !         delaymagic |= DM_RGID;
  981.           break;                /* don't do magic till later */
  982.           }
  983.   #ifdef HAS_SETRGID
  984.           (void)setrgid((GIDTYPE)gid);
  985.   #else
  986. ***************
  987. *** 605,622 ****
  988.   #ifdef HAS_SETREGID
  989.           (void)setregid((GIDTYPE)gid, (GIDTYPE)-1);
  990.   #else
  991. !         fatal("setrgid() not implemented");
  992.   #endif
  993.   #endif
  994.           break;
  995.       case ')':
  996.           egid = (int)str_gnum(str);
  997. - #if defined(HAS_SETREGID) || !defined(HAS_SETEGID)
  998.           if (delaymagic) {
  999. !         delaymagic |= DM_REGID;
  1000.           break;                /* don't do magic till later */
  1001.           }
  1002. - #endif /* HAS_SETREGID or not HAS_SETEGID */
  1003.   #ifdef HAS_SETEGID
  1004.           (void)setegid((GIDTYPE)egid);
  1005.   #else
  1006. --- 619,638 ----
  1007.   #ifdef HAS_SETREGID
  1008.           (void)setregid((GIDTYPE)gid, (GIDTYPE)-1);
  1009.   #else
  1010. !         if (gid == egid)            /* special case $( = $) */
  1011. !         (void)setgid(gid);
  1012. !         else
  1013. !         fatal("setrgid() not implemented");
  1014.   #endif
  1015.   #endif
  1016. +         gid = (int)getgid();
  1017.           break;
  1018.       case ')':
  1019.           egid = (int)str_gnum(str);
  1020.           if (delaymagic) {
  1021. !         delaymagic |= DM_EGID;
  1022.           break;                /* don't do magic till later */
  1023.           }
  1024.   #ifdef HAS_SETEGID
  1025.           (void)setegid((GIDTYPE)egid);
  1026.   #else
  1027. ***************
  1028. *** 623,631 ****
  1029.   #ifdef HAS_SETREGID
  1030.           (void)setregid((GIDTYPE)-1, (GIDTYPE)egid);
  1031.   #else
  1032. !         fatal("setegid() not implemented");
  1033.   #endif
  1034.   #endif
  1035.           break;
  1036.       case ':':
  1037.           chopset = str_get(str);
  1038. --- 639,651 ----
  1039.   #ifdef HAS_SETREGID
  1040.           (void)setregid((GIDTYPE)-1, (GIDTYPE)egid);
  1041.   #else
  1042. !         if (egid == gid)            /* special case $) = $( */
  1043. !         (void)setgid(egid);
  1044. !         else
  1045. !         fatal("setegid() not implemented");
  1046.   #endif
  1047.   #endif
  1048. +         egid = (int)getegid();
  1049.           break;
  1050.       case ':':
  1051.           chopset = str_get(str);
  1052. ***************
  1053. *** 640,646 ****
  1054.               s += strlen(++s);    /* this one is ok too */
  1055.           }
  1056.           if (origenviron[0] == s + 1) {    /* can grab env area too? */
  1057. !             setenv("NoNeSuCh", Nullch);    /* force copy of environment */
  1058.               for (i = 0; origenviron[i]; i++)
  1059.               if (origenviron[i] == s + 1)
  1060.                   s += strlen(++s);
  1061. --- 660,667 ----
  1062.               s += strlen(++s);    /* this one is ok too */
  1063.           }
  1064.           if (origenviron[0] == s + 1) {    /* can grab env area too? */
  1065. !             my_setenv("NoNeSuCh", Nullch);
  1066. !                         /* force copy of environment */
  1067.               for (i = 0; origenviron[i]; i++)
  1068.               if (origenviron[i] == s + 1)
  1069.                   s += strlen(++s);
  1070. ***************
  1071. *** 653,662 ****
  1072.           i = origalen;
  1073.           str->str_cur = i;
  1074.           str->str_ptr[i] = '\0';
  1075. !         bcopy(s, origargv[0], i);
  1076.           }
  1077.           else {
  1078. !         bcopy(s, origargv[0], i);
  1079.           s = origargv[0]+i;
  1080.           *s++ = '\0';
  1081.           while (++i < origalen)
  1082. --- 674,683 ----
  1083.           i = origalen;
  1084.           str->str_cur = i;
  1085.           str->str_ptr[i] = '\0';
  1086. !         Copy(s, origargv[0], i, char);
  1087.           }
  1088.           else {
  1089. !         Copy(s, origargv[0], i, char);
  1090.           s = origargv[0]+i;
  1091.           *s++ = '\0';
  1092.           while (++i < origalen)
  1093. ***************
  1094. *** 676,681 ****
  1095. --- 697,703 ----
  1096.       }
  1097.   }
  1098.   
  1099. + int
  1100.   whichsig(sig)
  1101.   char *sig;
  1102.   {
  1103. ***************
  1104. *** 725,731 ****
  1105.       if (!sub) {
  1106.       if (dowarn)
  1107.           warn("SIG%s handler \"%s\" not defined.\n",
  1108. !         sig_name[sig], stab_name(stab) );
  1109.       return;
  1110.       }
  1111.       /*SUPPRESS 701*/
  1112. --- 747,753 ----
  1113.       if (!sub) {
  1114.       if (dowarn)
  1115.           warn("SIG%s handler \"%s\" not defined.\n",
  1116. !         sig_name[sig], stab_ename(stab) );
  1117.       return;
  1118.       }
  1119.       /*SUPPRESS 701*/
  1120. ***************
  1121. *** 751,757 ****
  1122.       sub->depth++;
  1123.       if (sub->depth >= 2) {    /* save temporaries on recursion? */
  1124.       if (sub->depth == 100 && dowarn)
  1125. !         warn("Deep recursion on subroutine \"%s\"",stab_name(stab));
  1126.       savelist(sub->tosave->ary_array,sub->tosave->ary_fill);
  1127.       }
  1128.   
  1129. --- 773,779 ----
  1130.       sub->depth++;
  1131.       if (sub->depth >= 2) {    /* save temporaries on recursion? */
  1132.       if (sub->depth == 100 && dowarn)
  1133. !         warn("Deep recursion on subroutine \"%s\"",stab_ename(stab));
  1134.       savelist(sub->tosave->ary_array,sub->tosave->ary_fill);
  1135.       }
  1136.   
  1137. ***************
  1138. *** 888,893 ****
  1139. --- 910,916 ----
  1140.       strcpy(stab_magic(stab),"StB");
  1141.       stab_val(stab) = Str_new(72,0);
  1142.       stab_line(stab) = curcmd->c_line;
  1143. +     stab_estab(stab) = stab;
  1144.       str_magic((STR*)stab, stab, '*', name, len);
  1145.       stab_stash(stab) = stash;
  1146.       if (isDIGIT(*name) && *name != '0') {
  1147. ***************
  1148. *** 900,905 ****
  1149. --- 923,929 ----
  1150.       }
  1151.   }
  1152.   
  1153. + void
  1154.   stab_fullname(str,stab)
  1155.   STR *str;
  1156.   STAB *stab;
  1157. ***************
  1158. *** 913,918 ****
  1159. --- 937,956 ----
  1160.       str_scat(str,stab->str_magic);
  1161.   }
  1162.   
  1163. + void
  1164. + stab_efullname(str,stab)
  1165. + STR *str;
  1166. + STAB *stab;
  1167. + {
  1168. +     HASH *tb = stab_estash(stab);
  1169. +     if (!tb)
  1170. +     return;
  1171. +     str_set(str,tb->tbl_name);
  1172. +     str_ncat(str,"'", 1);
  1173. +     str_scat(str,stab_estab(stab)->str_magic);
  1174. + }
  1175.   STIO *
  1176.   stio_new()
  1177.   {
  1178. ***************
  1179. *** 923,928 ****
  1180. --- 961,967 ----
  1181.       return stio;
  1182.   }
  1183.   
  1184. + void
  1185.   stab_check(min,max)
  1186.   int min;
  1187.   register int max;
  1188. ***************
  1189. *** 960,965 ****
  1190. --- 999,1006 ----
  1191.       STIO *stio;
  1192.       SUBR *sub;
  1193.   
  1194. +     if (!stab || !stab->str_ptr)
  1195. +     return;
  1196.       afree(stab_xarray(stab));
  1197.       stab_xarray(stab) = Null(ARRAY*);
  1198.       (void)hfree(stab_xhash(stab), FALSE);
  1199.  
  1200. Index: stab.h
  1201. *** stab.h.old    Mon Jun  8 17:51:49 1992
  1202. --- stab.h    Mon Jun  8 17:51:50 1992
  1203. ***************
  1204. *** 1,4 ****
  1205. ! /* $RCSfile: stab.h,v $$Revision: 4.0.1.2 $$Date: 91/11/05 18:36:15 $
  1206.    *
  1207.    *    Copyright (c) 1991, Larry Wall
  1208.    *
  1209. --- 1,4 ----
  1210. ! /* $RCSfile: stab.h,v $$Revision: 4.0.1.3 $$Date: 92/06/08 15:33:44 $
  1211.    *
  1212.    *    Copyright (c) 1991, Larry Wall
  1213.    *
  1214. ***************
  1215. *** 6,11 ****
  1216. --- 6,15 ----
  1217.    *    License or the Artistic License, as specified in the README file.
  1218.    *
  1219.    * $Log:    stab.h,v $
  1220. +  * Revision 4.0.1.3  92/06/08  15:33:44  lwall
  1221. +  * patch20: fixed confusion between a *var's real name and its effective name
  1222. +  * patch20: ($<,$>) = ... didn't work on some architectures
  1223. +  * 
  1224.    * Revision 4.0.1.2  91/11/05  18:36:15  lwall
  1225.    * patch11: length($x) was sometimes wrong for numeric $x
  1226.    * 
  1227. ***************
  1228. *** 25,31 ****
  1229.       FCMD    *stbp_form;    /* format value */
  1230.       ARRAY    *stbp_array;    /* array value */
  1231.       HASH    *stbp_hash;    /* associative array value */
  1232. !     HASH    *stbp_stash;    /* symbol table for this stab */
  1233.       SUBR    *stbp_sub;    /* subroutine value */
  1234.       int        stbp_lastexpr;    /* used by nothing_in_common() */
  1235.       line_t    stbp_line;    /* line first declared at (for -w) */
  1236. --- 29,35 ----
  1237.       FCMD    *stbp_form;    /* format value */
  1238.       ARRAY    *stbp_array;    /* array value */
  1239.       HASH    *stbp_hash;    /* associative array value */
  1240. !     STAB    *stbp_stab;    /* effective stab, if *glob */
  1241.       SUBR    *stbp_sub;    /* subroutine value */
  1242.       int        stbp_lastexpr;    /* used by nothing_in_common() */
  1243.       line_t    stbp_line;    /* line first declared at (for -w) */
  1244. ***************
  1245. *** 56,68 ****
  1246.                    ((STBP*)(stab->str_ptr))->stbp_hash : \
  1247.                    ((STBP*)(hadd(stab)->str_ptr))->stbp_hash)
  1248.   #endif            /* Microport 2.4 hack */
  1249. - #define stab_stash(stab)    (((STBP*)(stab->str_ptr))->stbp_stash)
  1250.   #define stab_sub(stab)        (((STBP*)(stab->str_ptr))->stbp_sub)
  1251.   #define stab_lastexpr(stab)    (((STBP*)(stab->str_ptr))->stbp_lastexpr)
  1252.   #define stab_line(stab)        (((STBP*)(stab->str_ptr))->stbp_line)
  1253.   #define stab_flags(stab)    (((STBP*)(stab->str_ptr))->stbp_flags)
  1254.   #define stab_name(stab)        (stab->str_magic->str_ptr)
  1255.   
  1256.   #define SF_VMAGIC 1        /* call routine to dereference STR val */
  1257.   #define SF_MULTI 2        /* seen more than once */
  1258.   
  1259. --- 60,79 ----
  1260.                    ((STBP*)(stab->str_ptr))->stbp_hash : \
  1261.                    ((STBP*)(hadd(stab)->str_ptr))->stbp_hash)
  1262.   #endif            /* Microport 2.4 hack */
  1263.   #define stab_sub(stab)        (((STBP*)(stab->str_ptr))->stbp_sub)
  1264.   #define stab_lastexpr(stab)    (((STBP*)(stab->str_ptr))->stbp_lastexpr)
  1265.   #define stab_line(stab)        (((STBP*)(stab->str_ptr))->stbp_line)
  1266.   #define stab_flags(stab)    (((STBP*)(stab->str_ptr))->stbp_flags)
  1267. + #define stab_stab(stab)        (stab->str_magic->str_u.str_stab)
  1268. + #define stab_estab(stab)    (((STBP*)(stab->str_ptr))->stbp_stab)
  1269.   #define stab_name(stab)        (stab->str_magic->str_ptr)
  1270. + #define stab_ename(stab)    stab_name(stab_estab(stab))
  1271.   
  1272. + #define stab_stash(stab)    (stab->str_magic->str_u.str_stash)
  1273. + #define stab_estash(stab)    stab_stash(stab_estab(stab))
  1274.   #define SF_VMAGIC 1        /* call routine to dereference STR val */
  1275.   #define SF_MULTI 2        /* seen more than once */
  1276.   
  1277. ***************
  1278. *** 114,123 ****
  1279.   EXT unsigned short statusvalue;
  1280.   
  1281.   EXT int delaymagic INIT(0);
  1282. ! #define DM_DELAY 1
  1283. ! #define DM_REUID 2
  1284. ! #define DM_REGID 4
  1285.   
  1286.   STAB *aadd();
  1287.   STAB *hadd();
  1288.   STAB *fstab();
  1289. --- 125,142 ----
  1290.   EXT unsigned short statusvalue;
  1291.   
  1292.   EXT int delaymagic INIT(0);
  1293. ! #define DM_UID   0x003
  1294. ! #define DM_RUID   0x001
  1295. ! #define DM_EUID   0x002
  1296. ! #define DM_GID   0x030
  1297. ! #define DM_RGID   0x010
  1298. ! #define DM_EGID   0x020
  1299. ! #define DM_DELAY 0x100
  1300.   
  1301.   STAB *aadd();
  1302.   STAB *hadd();
  1303.   STAB *fstab();
  1304. + void stabset();
  1305. + void stab_fullname();
  1306. + void stab_efullname();
  1307. + void stab_check();
  1308.  
  1309. Index: str.c
  1310. *** str.c.old    Mon Jun  8 17:51:53 1992
  1311. --- str.c    Mon Jun  8 17:51:54 1992
  1312. ***************
  1313. *** 1,4 ****
  1314. ! /* $RCSfile: str.c,v $$Revision: 4.0.1.4 $$Date: 91/11/05 18:40:51 $
  1315.    *
  1316.    *    Copyright (c) 1991, Larry Wall
  1317.    *
  1318. --- 1,4 ----
  1319. ! /* $RCSfile: str.c,v $$Revision: 4.0.1.5 $$Date: 92/06/08 15:40:43 $
  1320.    *
  1321.    *    Copyright (c) 1991, Larry Wall
  1322.    *
  1323. ***************
  1324. *** 6,11 ****
  1325. --- 6,21 ----
  1326.    *    License or the Artistic License, as specified in the README file.
  1327.    *
  1328.    * $Log:    str.c,v $
  1329. +  * Revision 4.0.1.5  92/06/08  15:40:43  lwall
  1330. +  * patch20: removed implicit int declarations on functions
  1331. +  * patch20: Perl now distinguishes overlapped copies from non-overlapped
  1332. +  * patch20: paragraph mode now skips extra newlines automatically
  1333. +  * patch20: fixed memory leak in doube-quote interpretation
  1334. +  * patch20: made /\$$foo/ look for literal '$foo'
  1335. +  * patch20: "$var{$foo'bar}" didn't scan subscript correctly
  1336. +  * patch20: a splice on non-existent array elements could dump core
  1337. +  * patch20: running taintperl explicitly now does checks even if $< == $>
  1338. +  * 
  1339.    * Revision 4.0.1.4  91/11/05  18:40:51  lwall
  1340.    * patch11: $foo .= <BAR> could overrun malloced memory
  1341.    * patch11: \$ didn't always make it through double-quoter to regexp routines
  1342. ***************
  1343. *** 32,37 ****
  1344. --- 42,50 ----
  1345.   #include "perl.h"
  1346.   #include "perly.h"
  1347.   
  1348. + static void ucase();
  1349. + static void lcase();
  1350.   #ifndef str_get
  1351.   char *
  1352.   str_get(str)
  1353. ***************
  1354. *** 48,53 ****
  1355. --- 61,67 ----
  1356.    * dlb the following functions are usually macros.
  1357.    */
  1358.   #ifndef str_true
  1359. + int
  1360.   str_true(Str)
  1361.   STR *Str;
  1362.   {
  1363. ***************
  1364. *** 81,87 ****
  1365.   char *
  1366.   str_grow(str,newlen)
  1367.   register STR *str;
  1368. ! #ifndef MSDOS
  1369.   register int newlen;
  1370.   #else
  1371.   unsigned long newlen;
  1372. --- 95,101 ----
  1373.   char *
  1374.   str_grow(str,newlen)
  1375.   register STR *str;
  1376. ! #ifndef DOSISH
  1377.   register int newlen;
  1378.   #else
  1379.   unsigned long newlen;
  1380. ***************
  1381. *** 99,105 ****
  1382.       str->str_len += str->str_u.str_useful;
  1383.       str->str_ptr -= str->str_u.str_useful;
  1384.       str->str_u.str_useful = 0L;
  1385. !     bcopy(s, str->str_ptr, str->str_cur+1);
  1386.       s = str->str_ptr;
  1387.       str->str_state = SS_NORM;            /* normal again */
  1388.       if (newlen > str->str_len)
  1389. --- 113,119 ----
  1390.       str->str_len += str->str_u.str_useful;
  1391.       str->str_ptr -= str->str_u.str_useful;
  1392.       str->str_u.str_useful = 0L;
  1393. !     Move(s, str->str_ptr, str->str_cur+1, char);
  1394.       s = str->str_ptr;
  1395.       str->str_state = SS_NORM;            /* normal again */
  1396.       if (newlen > str->str_len)
  1397. ***************
  1398. *** 116,121 ****
  1399. --- 130,136 ----
  1400.       return s;
  1401.   }
  1402.   
  1403. + void
  1404.   str_numset(str,num)
  1405.   register STR *str;
  1406.   double num;
  1407. ***************
  1408. *** 212,217 ****
  1409. --- 227,233 ----
  1410.    * as temporary.
  1411.    */
  1412.   
  1413. + void
  1414.   str_sset(dstr,sstr)
  1415.   STR *dstr;
  1416.   register STR *sstr;
  1417. ***************
  1418. *** 273,278 ****
  1419. --- 289,298 ----
  1420.           char *tmps = dstr->str_ptr;
  1421.   
  1422.           if (*tmps == 'S' && bcmp(tmps,"StB",4) == 0) {
  1423. +             if (dstr->str_magic && dstr->str_magic->str_rare == 'X') {
  1424. +             str_free(dstr->str_magic);
  1425. +             dstr->str_magic = Nullstr;
  1426. +             }
  1427.               if (!dstr->str_magic) {
  1428.               dstr->str_magic = str_smake(sstr->str_magic);
  1429.               dstr->str_magic->str_rare = 'X';
  1430. ***************
  1431. *** 296,301 ****
  1432. --- 316,322 ----
  1433.       }
  1434.   }
  1435.   
  1436. + void
  1437.   str_nset(str,ptr,len)
  1438.   register STR *str;
  1439.   register char *ptr;
  1440. ***************
  1441. *** 305,311 ****
  1442.       return;
  1443.       STR_GROW(str, len + 1);
  1444.       if (ptr)
  1445. !     (void)bcopy(ptr,str->str_ptr,len);
  1446.       str->str_cur = len;
  1447.       *(str->str_ptr+str->str_cur) = '\0';
  1448.       str->str_nok = 0;        /* invalidate number */
  1449. --- 326,332 ----
  1450.       return;
  1451.       STR_GROW(str, len + 1);
  1452.       if (ptr)
  1453. !     Move(ptr,str->str_ptr,len,char);
  1454.       str->str_cur = len;
  1455.       *(str->str_ptr+str->str_cur) = '\0';
  1456.       str->str_nok = 0;        /* invalidate number */
  1457. ***************
  1458. *** 315,320 ****
  1459. --- 336,342 ----
  1460.   #endif
  1461.   }
  1462.   
  1463. + void
  1464.   str_set(str,ptr)
  1465.   register STR *str;
  1466.   register char *ptr;
  1467. ***************
  1468. *** 327,333 ****
  1469.       ptr = "";
  1470.       len = strlen(ptr);
  1471.       STR_GROW(str, len + 1);
  1472. !     (void)bcopy(ptr,str->str_ptr,len+1);
  1473.       str->str_cur = len;
  1474.       str->str_nok = 0;        /* invalidate number */
  1475.       str->str_pok = 1;        /* validate pointer */
  1476. --- 349,355 ----
  1477.       ptr = "";
  1478.       len = strlen(ptr);
  1479.       STR_GROW(str, len + 1);
  1480. !     Move(ptr,str->str_ptr,len+1,char);
  1481.       str->str_cur = len;
  1482.       str->str_nok = 0;        /* invalidate number */
  1483.       str->str_pok = 1;        /* validate pointer */
  1484. ***************
  1485. *** 336,341 ****
  1486. --- 358,364 ----
  1487.   #endif
  1488.   }
  1489.   
  1490. + void
  1491.   str_chop(str,ptr)    /* like set but assuming ptr is in str */
  1492.   register STR *str;
  1493.   register char *ptr;
  1494. ***************
  1495. *** 358,363 ****
  1496. --- 381,387 ----
  1497.       str->str_pok = 1;        /* validate pointer (and unstudy str) */
  1498.   }
  1499.   
  1500. + void
  1501.   str_ncat(str,ptr,len)
  1502.   register STR *str;
  1503.   register char *ptr;
  1504. ***************
  1505. *** 368,374 ****
  1506.       if (!(str->str_pok))
  1507.       (void)str_2ptr(str);
  1508.       STR_GROW(str, str->str_cur + len + 1);
  1509. !     (void)bcopy(ptr,str->str_ptr+str->str_cur,len);
  1510.       str->str_cur += len;
  1511.       *(str->str_ptr+str->str_cur) = '\0';
  1512.       str->str_nok = 0;        /* invalidate number */
  1513. --- 392,398 ----
  1514.       if (!(str->str_pok))
  1515.       (void)str_2ptr(str);
  1516.       STR_GROW(str, str->str_cur + len + 1);
  1517. !     Move(ptr,str->str_ptr+str->str_cur,len,char);
  1518.       str->str_cur += len;
  1519.       *(str->str_ptr+str->str_cur) = '\0';
  1520.       str->str_nok = 0;        /* invalidate number */
  1521. ***************
  1522. *** 378,383 ****
  1523. --- 402,408 ----
  1524.   #endif
  1525.   }
  1526.   
  1527. + void
  1528.   str_scat(dstr,sstr)
  1529.   STR *dstr;
  1530.   register STR *sstr;
  1531. ***************
  1532. *** 393,398 ****
  1533. --- 418,424 ----
  1534.       str_ncat(dstr,sstr->str_ptr,sstr->str_cur);
  1535.   }
  1536.   
  1537. + void
  1538.   str_cat(str,ptr)
  1539.   register STR *str;
  1540.   register char *ptr;
  1541. ***************
  1542. *** 407,413 ****
  1543.       (void)str_2ptr(str);
  1544.       len = strlen(ptr);
  1545.       STR_GROW(str, str->str_cur + len + 1);
  1546. !     (void)bcopy(ptr,str->str_ptr+str->str_cur,len+1);
  1547.       str->str_cur += len;
  1548.       str->str_nok = 0;        /* invalidate number */
  1549.       str->str_pok = 1;        /* validate pointer */
  1550. --- 433,439 ----
  1551.       (void)str_2ptr(str);
  1552.       len = strlen(ptr);
  1553.       STR_GROW(str, str->str_cur + len + 1);
  1554. !     Move(ptr,str->str_ptr+str->str_cur,len+1,char);
  1555.       str->str_cur += len;
  1556.       str->str_nok = 0;        /* invalidate number */
  1557.       str->str_pok = 1;        /* validate pointer */
  1558. ***************
  1559. *** 530,542 ****
  1560.       *bigend = '\0';
  1561.       while (midend > mid)        /* shove everything down */
  1562.           *--bigend = *--midend;
  1563. !     (void)bcopy(little,big+offset,littlelen);
  1564.       bigstr->str_cur += i;
  1565.       STABSET(bigstr);
  1566.       return;
  1567.       }
  1568.       else if (i == 0) {
  1569. !     (void)bcopy(little,bigstr->str_ptr+offset,len);
  1570.       STABSET(bigstr);
  1571.       return;
  1572.       }
  1573. --- 556,568 ----
  1574.       *bigend = '\0';
  1575.       while (midend > mid)        /* shove everything down */
  1576.           *--bigend = *--midend;
  1577. !     Move(little,big+offset,littlelen,char);
  1578.       bigstr->str_cur += i;
  1579.       STABSET(bigstr);
  1580.       return;
  1581.       }
  1582.       else if (i == 0) {
  1583. !     Move(little,bigstr->str_ptr+offset,len,char);
  1584.       STABSET(bigstr);
  1585.       return;
  1586.       }
  1587. ***************
  1588. *** 551,562 ****
  1589.   
  1590.       if (mid - big > bigend - midend) {    /* faster to shorten from end */
  1591.       if (littlelen) {
  1592. !         (void)bcopy(little, mid, littlelen);
  1593.           mid += littlelen;
  1594.       }
  1595.       i = bigend - midend;
  1596.       if (i > 0) {
  1597. !         (void)bcopy(midend, mid, i);
  1598.           mid += i;
  1599.       }
  1600.       *mid = '\0';
  1601. --- 577,588 ----
  1602.   
  1603.       if (mid - big > bigend - midend) {    /* faster to shorten from end */
  1604.       if (littlelen) {
  1605. !         Move(little, mid, littlelen,char);
  1606.           mid += littlelen;
  1607.       }
  1608.       i = bigend - midend;
  1609.       if (i > 0) {
  1610. !         Move(midend, mid, i,char);
  1611.           mid += i;
  1612.       }
  1613.       *mid = '\0';
  1614. ***************
  1615. *** 571,582 ****
  1616.       while (i--)
  1617.           *--midend = *--big;
  1618.       if (littlelen)
  1619. !         (void)bcopy(little, mid, littlelen);
  1620.       }
  1621.       else if (littlelen) {
  1622.       midend -= littlelen;
  1623.       str_chop(bigstr,midend);
  1624. !     (void)bcopy(little,midend,littlelen);
  1625.       }
  1626.       else {
  1627.       str_chop(bigstr,midend);
  1628. --- 597,608 ----
  1629.       while (i--)
  1630.           *--midend = *--big;
  1631.       if (littlelen)
  1632. !         Move(little, mid, littlelen,char);
  1633.       }
  1634.       else if (littlelen) {
  1635.       midend -= littlelen;
  1636.       str_chop(bigstr,midend);
  1637. !     Move(little,midend,littlelen,char);
  1638.       }
  1639.       else {
  1640.       str_chop(bigstr,midend);
  1641. ***************
  1642. *** 679,684 ****
  1643. --- 705,711 ----
  1644.       return 0;
  1645.   }
  1646.   
  1647. + int
  1648.   str_eq(str1,str2)
  1649.   register STR *str1;
  1650.   register STR *str2;
  1651. ***************
  1652. *** 699,704 ****
  1653. --- 726,732 ----
  1654.       return !bcmp(str1->str_ptr, str2->str_ptr, str1->str_cur);
  1655.   }
  1656.   
  1657. + int
  1658.   str_cmp(str1,str2)
  1659.   register STR *str1;
  1660.   register STR *str2;
  1661. ***************
  1662. *** 747,752 ****
  1663. --- 775,789 ----
  1664.   
  1665.       if (str == &str_undef)
  1666.       return Nullch;
  1667. +     if (rspara) {        /* have to do this both before and after */
  1668. +     do {            /* to make sure file boundaries work right */
  1669. +         i = getc(fp);
  1670. +         if (i != '\n') {
  1671. +         ungetc(i,fp);
  1672. +         break;
  1673. +         }
  1674. +     } while (i != EOF);
  1675. +     }
  1676.   #ifdef STDSTDIO        /* Here is some breathtakingly efficient cheating */
  1677.       cnt = fp->_cnt;            /* get count into register */
  1678.       str->str_nok = 0;            /* invalidate number */
  1679. ***************
  1680. *** 849,854 ****
  1681. --- 886,900 ----
  1682.   
  1683.   #endif /* STDSTDIO */
  1684.   
  1685. +     if (rspara) {
  1686. +         while (i != EOF) {
  1687. +         i = getc(fp);
  1688. +         if (i != '\n') {
  1689. +         ungetc(i,fp);
  1690. +         break;
  1691. +         }
  1692. +     }
  1693. +     }
  1694.       return str->str_cur - append ? str->str_ptr : Nullch;
  1695.   }
  1696.   
  1697. ***************
  1698. *** 906,912 ****
  1699.       if (cmd->c_type != C_EXPR || cmd->c_next || arg->arg_type != O_LIST)
  1700.       fatal("panic: error in parselist %d %x %d", cmd->c_type,
  1701.         cmd->c_next, arg ? arg->arg_type : -1);
  1702. !     Safefree(cmd);
  1703.       eval_root = Nullcmd;
  1704.       return arg;
  1705.   }
  1706. --- 952,959 ----
  1707.       if (cmd->c_type != C_EXPR || cmd->c_next || arg->arg_type != O_LIST)
  1708.       fatal("panic: error in parselist %d %x %d", cmd->c_type,
  1709.         cmd->c_next, arg ? arg->arg_type : -1);
  1710. !     cmd->c_expr = Nullarg;
  1711. !     cmd_free(cmd);
  1712.       eval_root = Nullcmd;
  1713.       return arg;
  1714.   }
  1715. ***************
  1716. *** 945,954 ****
  1717.           if (*nointrp) {        /* in a regular expression */
  1718.               if (*s == '@')    /* always strip \@ */ /*SUPPRESS 530*/
  1719.               ;
  1720. -             else if (*s == '$') {
  1721. -             if (s+1 >= send || index(nointrp, s[1]))
  1722. -                 str_ncat(str,s-1,1); /* only strip \$ for vars */
  1723. -             }
  1724.               else        /* don't strip \\, \[, \{ etc. */
  1725.               str_ncat(str,s-1,1);
  1726.           }
  1727. --- 992,997 ----
  1728. ***************
  1729. *** 988,1014 ****
  1730.           do {
  1731.               switch (*s) {
  1732.               case '[':
  1733. !             if (s[-1] != '$')
  1734. !                 brackets++;
  1735.               break;
  1736.               case '{':
  1737.               brackets++;
  1738.               break;
  1739.               case ']':
  1740. !             if (s[-1] != '$')
  1741. !                 brackets--;
  1742.               break;
  1743.               case '}':
  1744.               brackets--;
  1745.               break;
  1746.               case '\'':
  1747.               case '"':
  1748. !             if (s[-1] != '$') {
  1749. !                 /*SUPPRESS 68*/
  1750. !                 s = cpytill(tokenbuf,s+1,send,*s,&len);
  1751. !                 if (s >= send)
  1752. !                 fatal("Unterminated string");
  1753. !             }
  1754.               break;
  1755.               }
  1756.               s++;
  1757. --- 1031,1060 ----
  1758.           do {
  1759.               switch (*s) {
  1760.               case '[':
  1761. !             brackets++;
  1762.               break;
  1763.               case '{':
  1764.               brackets++;
  1765.               break;
  1766.               case ']':
  1767. !             brackets--;
  1768.               break;
  1769.               case '}':
  1770.               brackets--;
  1771.               break;
  1772. +             case '$':
  1773. +             case '%':
  1774. +             case '@':
  1775. +             case '&':
  1776. +             case '*':
  1777. +             s = scanident(s,send,tokenbuf);
  1778. +             break;
  1779.               case '\'':
  1780.               case '"':
  1781. !             /*SUPPRESS 68*/
  1782. !             s = cpytill(tokenbuf,s+1,send,*s,&len);
  1783. !             if (s >= send)
  1784. !                 fatal("Unterminated string");
  1785.               break;
  1786.               }
  1787.               s++;
  1788. ***************
  1789. *** 1254,1259 ****
  1790. --- 1300,1306 ----
  1791.       return str;
  1792.   }
  1793.   
  1794. + static void
  1795.   ucase(s,send)
  1796.   register char *s;
  1797.   register char *send;
  1798. ***************
  1799. *** 1265,1270 ****
  1800. --- 1312,1318 ----
  1801.       }
  1802.   }
  1803.   
  1804. + static void
  1805.   lcase(s,send)
  1806.   register char *s;
  1807.   register char *send;
  1808. ***************
  1809. *** 1381,1387 ****
  1810.   str_2mortal(str)
  1811.   register STR *str;
  1812.   {
  1813. !     if (str == &str_undef)
  1814.       return str;
  1815.       if (++tmps_max > tmps_size) {
  1816.       tmps_size = tmps_max;
  1817. --- 1429,1435 ----
  1818.   str_2mortal(str)
  1819.   register STR *str;
  1820.   {
  1821. !     if (!str || str == &str_undef)
  1822.       return str;
  1823.       if (++tmps_max > tmps_size) {
  1824.       tmps_size = tmps_max;
  1825. ***************
  1826. *** 1439,1445 ****
  1827.       Str_Grow(old,0);
  1828.       if (new->str_ptr)
  1829.       Safefree(new->str_ptr);
  1830. !     Copy(old,new,1,STR);
  1831.       if (old->str_ptr) {
  1832.       new->str_ptr = nsavestr(old->str_ptr,old->str_len);
  1833.       new->str_pok &= ~SP_TEMP;
  1834. --- 1487,1493 ----
  1835.       Str_Grow(old,0);
  1836.       if (new->str_ptr)
  1837.       Safefree(new->str_ptr);
  1838. !     StructCopy(old,new,STR);
  1839.       if (old->str_ptr) {
  1840.       new->str_ptr = nsavestr(old->str_ptr,old->str_len);
  1841.       new->str_pok &= ~SP_TEMP;
  1842. ***************
  1843. *** 1447,1452 ****
  1844. --- 1495,1501 ----
  1845.       return new;
  1846.   }
  1847.   
  1848. + void
  1849.   str_reset(s,stash)
  1850.   register char *s;
  1851.   HASH *stash;
  1852. ***************
  1853. *** 1504,1509 ****
  1854. --- 1553,1559 ----
  1855.   }
  1856.   
  1857.   #ifdef TAINT
  1858. + void
  1859.   taintproper(s)
  1860.   char *s;
  1861.   {
  1862. ***************
  1863. *** 1511,1517 ****
  1864.       if (debug & 2048)
  1865.       fprintf(stderr,"%s %d %d %d\n",s,tainted,uid, euid);
  1866.   #endif
  1867. !     if (tainted && (!euid || euid != uid || egid != gid)) {
  1868.       if (!unsafe)
  1869.           fatal("%s", s);
  1870.       else if (dowarn)
  1871. --- 1561,1567 ----
  1872.       if (debug & 2048)
  1873.       fprintf(stderr,"%s %d %d %d\n",s,tainted,uid, euid);
  1874.   #endif
  1875. !     if (tainted && (!euid || euid != uid || egid != gid || taintanyway)) {
  1876.       if (!unsafe)
  1877.           fatal("%s", s);
  1878.       else if (dowarn)
  1879. ***************
  1880. *** 1519,1524 ****
  1881. --- 1569,1575 ----
  1882.       }
  1883.   }
  1884.   
  1885. + void
  1886.   taintenv()
  1887.   {
  1888.       register STR *envstr;
  1889.  
  1890. Index: lib/syslog.pl
  1891. *** lib/syslog.pl.old    Mon Jun  8 17:49:14 1992
  1892. --- lib/syslog.pl    Mon Jun  8 17:49:14 1992
  1893. ***************
  1894. *** 2,7 ****
  1895. --- 2,10 ----
  1896.   # syslog.pl
  1897.   #
  1898.   # $Log:    syslog.pl,v $
  1899. + # Revision 4.0.1.1  92/06/08  13:48:05  lwall
  1900. + # patch20: new warning for ambiguous use of unary operators
  1901. + # 
  1902.   # Revision 4.0  91/03/20  01:26:24  lwall
  1903.   # 4.0 baseline.
  1904.   # 
  1905. ***************
  1906. *** 164,170 ****
  1907.       $name =~ y/a-z/A-Z/;
  1908.       $name = "LOG_$name" unless $name =~ /^LOG_/;
  1909.       $name = "syslog'$name";
  1910. !     eval &$name || -1;
  1911.   }
  1912.   
  1913.   sub connect {
  1914. --- 167,173 ----
  1915.       $name =~ y/a-z/A-Z/;
  1916.       $name = "LOG_$name" unless $name =~ /^LOG_/;
  1917.       $name = "syslog'$name";
  1918. !     eval(&$name) || -1;
  1919.   }
  1920.   
  1921.   sub connect {
  1922.  
  1923. Index: atarist/test/tbinmode
  1924. *** atarist/test/tbinmode.old    Mon Jun  8 17:45:23 1992
  1925. --- atarist/test/tbinmode    Mon Jun  8 17:45:25 1992
  1926. ***************
  1927. *** 0 ****
  1928. --- 1,12 ----
  1929. + open(FP, ">bintest") || die "Can't open bintest for write\n";
  1930. + binmode FP;
  1931. + print FP pack("C*", 0xaa, 0x55, 0xaa, 0x55,
  1932. +                     0xff, 0x0d, 0x0a);
  1933. + close FP;
  1934. + open(FP, "<bintest") || die "Can't open bintest for read\n";
  1935. + binmode FP;
  1936. + @got = unpack("C*", <FP>);
  1937. + close FP;
  1938. + printf "expect:\t7 elements: aa 55 aa 55 ff 0d 0a\n";
  1939. + printf "got:\t%d elements: %x %x %x %x %x %02x %02x\n", $#got+1-$[, @got;
  1940.  
  1941. Index: hints/ultrix_4.sh
  1942. *** hints/ultrix_4.sh.old    Mon Jun  8 17:48:29 1992
  1943. --- hints/ultrix_4.sh    Mon Jun  8 17:48:29 1992
  1944. ***************
  1945. *** 18,22 ****
  1946. --- 18,23 ----
  1947.       toke_cflags='optimize="-g"'
  1948.       ttoke_cflags='optimize="-g"'
  1949.       ;;
  1950. + *4.2*) libswanted=`echo $libswanted | sed 's/ malloc / /'` ;;
  1951.   esac
  1952.   
  1953.  
  1954. Index: hints/unisysdynix.sh
  1955. *** hints/unisysdynix.sh.old    Mon Jun  8 17:47:43 1992
  1956. --- hints/unisysdynix.sh    Mon Jun  8 17:47:43 1992
  1957. ***************
  1958. *** 0 ****
  1959. --- 1 ----
  1960. + d_waitpid=undef
  1961.  
  1962. Index: atarist/usersub.c
  1963. *** atarist/usersub.c.old    Mon Jun  8 17:45:26 1992
  1964. --- atarist/usersub.c    Mon Jun  8 17:45:27 1992
  1965. ***************
  1966. *** 0 ****
  1967. --- 1,9 ----
  1968. + #include "EXTERN.h"
  1969. + #include "perl.h"
  1970. + #include <stdio.h>
  1971. + int userinit()
  1972. + {
  1973. +     install_null();    /* install device /dev/null or NUL: */
  1974. +     return 0;
  1975. + }
  1976.  
  1977. *** End of Patch 31 ***
  1978. exit 0 # Just in case...
  1979.