home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume13 / perl / patches6-10 / patch8 < prev    next >
Encoding:
Text File  |  1988-01-30  |  35.0 KB  |  1,448 lines

  1. Path: bbn.com!bbn!uwmcsd1!ig!agate!pasteur!ames!elroy!devvax!lroot
  2. From: lroot@devvax.JPL.NASA.GOV (The Superuser)
  3. Newsgroups: comp.sources.bugs
  4. Subject: perl 1.0 patch #8
  5. Summary: This is an official patch for perl 1.0.  Please apply it.
  6. Message-ID: <1174@devvax.JPL.NASA.GOV>
  7. Date: 28 Jan 88 19:44:05 GMT
  8. Organization: Jet Propulsion Laboratory, Pasadena, CA
  9. Lines: 1437
  10.  
  11. System: perl version 1.0
  12. Patch #: 8
  13. Priority: ENHANCEMENT
  14. Subject: perl needed an eval operator and a symbolic debugger
  15. From: lwall@jpl-devvax.jpl.nasa.gov (Larry Wall)
  16.  
  17. Description:
  18.     I didn't add an eval operator to the original perl because
  19.     I hadn't thought of any good uses for it.  Recently I thought
  20.     of some.  Along with creating the eval operator, this patch
  21.     introduces a symbolic debugger for perl scripts, which makes
  22.     use of eval to interpret some debugging commands.  Having eval
  23.     also lets me emulate awk's FOO=bar command line behavior with
  24.     a line such as the one a2p now inserts at the beginning of
  25.     translated scripts.
  26.  
  27. Fix:    From rn, say "| patch -p0 -d DIR", where DIR is your perl source
  28.                   ^^^
  29.     directory.  Outside of rn, say "cd DIR; patch -p0 <thisarticle".
  30.     If you don't have the patch program, apply the following by hand,
  31.     or get patch.
  32.  
  33. >>>>    YOU MUST USE THE -p0 SWITCH ABOVE OR PATCH WON'T WORK RIGHT.   <<<<
  34.  
  35.     If patch indicates that patchlevel is the wrong version, you may need
  36.     to apply one or more previous patches, or the patch may already
  37.     have been applied.  See the patchlevel.h file to find out what has or
  38.     has not been applied.  In any event, don't continue with the patch.
  39.  
  40.     If you are missing previous patches they can be obtained from me:
  41.  
  42.     Larry Wall
  43.     lwall@jpl-devvax.jpl.nasa.gov
  44.  
  45.     If you send a mail message of the following form it will greatly speed
  46.     processing:
  47.  
  48.     Subject: Command
  49.     @SH mailpatch PATH perl 1.0 LIST
  50.            ^ note the c
  51.  
  52.     where PATH is a return path FROM ME TO YOU in Internet notation, and
  53.     LIST is the number of one or more patches you need, separated by spaces,
  54.     commas, and/or hyphens.  Saying 35- says everything from 35 to the end.
  55.  
  56.     You can also get the patches via anonymous FTP from
  57.     jpl-devvax.jpl.nasa.gov (128.149.8.43).
  58.  
  59. Index: patchlevel.h
  60. Prereq: 7
  61. 1c1
  62. < #define PATCHLEVEL 7
  63. ---
  64. > #define PATCHLEVEL 8
  65.  
  66. Index: Makefile.SH
  67. Prereq: 1.0.1.3
  68. *** Makefile.SH.old    Thu Jan 28 11:08:32 1988
  69. --- Makefile.SH    Thu Jan 28 11:08:33 1988
  70. ***************
  71. *** 14,22 ****
  72.   esac
  73.   echo "Extracting Makefile (with variable substitutions)"
  74.   cat >Makefile <<!GROK!THIS!
  75. ! # $Header: Makefile.SH,v 1.0.1.3 88/01/26 14:14:52 root Exp $
  76.   #
  77.   # $Log:    Makefile.SH,v $
  78.   # Revision 1.0.1.3  88/01/26  14:14:52  root
  79.   # Added mallocsrc stuff.
  80.   # 
  81. --- 14,25 ----
  82.   esac
  83.   echo "Extracting Makefile (with variable substitutions)"
  84.   cat >Makefile <<!GROK!THIS!
  85. ! # $Header: Makefile.SH,v 1.0.1.4 88/01/28 10:17:59 root Exp $
  86.   #
  87.   # $Log:    Makefile.SH,v $
  88. + # Revision 1.0.1.4  88/01/28  10:17:59  root
  89. + # patch8: added perldb.man
  90. + # 
  91.   # Revision 1.0.1.3  88/01/26  14:14:52  root
  92.   # Added mallocsrc stuff.
  93.   # 
  94. ***************
  95. *** 47,57 ****
  96.   
  97.   cat >>Makefile <<'!NO!SUBS!'
  98.   
  99. ! public = perl
  100.   
  101.   private = 
  102.   
  103. ! manpages = perl.man
  104.   
  105.   util =
  106.   
  107. --- 50,60 ----
  108.   
  109.   cat >>Makefile <<'!NO!SUBS!'
  110.   
  111. ! public = perl perldb
  112.   
  113.   private = 
  114.   
  115. ! manpages = perl.man perldb.man
  116.   
  117.   util =
  118.   
  119. If you are sitting there wondering why patch didn't find x2p/a2py.c, perhaps
  120. it is because you didn't say -p0 to patch.  If so, abort patch now and run
  121. it again as you did, but add the following switches: -p0 -N
  122.  
  123. Index: x2p/a2py.c
  124. Prereq: 1.0
  125. *** x2p/a2py.c.old    Thu Jan 28 11:18:17 1988
  126. --- x2p/a2py.c    Thu Jan 28 11:18:18 1988
  127. ***************
  128. *** 1,6 ****
  129. ! /* $Header: a2py.c,v 1.0 87/12/18 17:50:33 root Exp $
  130.    *
  131.    * $Log:    a2py.c,v $
  132.    * Revision 1.0  87/12/18  17:50:33  root
  133.    * Initial revision
  134.    * 
  135. --- 1,9 ----
  136. ! /* $Header: a2py.c,v 1.0.1.1 88/01/28 11:07:08 root Exp $
  137.    *
  138.    * $Log:    a2py.c,v $
  139. +  * Revision 1.0.1.1  88/01/28  11:07:08  root
  140. +  * patch8: added support for FOO=bar switches using eval.
  141. +  * 
  142.    * Revision 1.0  87/12/18  17:50:33  root
  143.    * Initial revision
  144.    * 
  145. ***************
  146. *** 114,119 ****
  147. --- 117,126 ----
  148.   
  149.       tmpstr = walk(0,0,root,&i);
  150.       str = str_make("#!/bin/perl\n\n");
  151. +     str_cat(str,
  152. +       "eval '$'.$1.'$2;' while $ARGV[0] =~ /^([A-Za-z_]+=)(.*)/ && shift;\n");
  153. +     str_cat(str,
  154. +       "            # process any FOO=bar switches\n\n");
  155.       if (do_opens && opens) {
  156.       str_scat(str,opens);
  157.       str_free(opens);
  158.  
  159. Index: arg.c
  160. Prereq: 1.0.1.3
  161. *** arg.c.old    Thu Jan 28 11:08:43 1988
  162. --- arg.c    Thu Jan 28 11:08:46 1988
  163. ***************
  164. *** 1,8 ****
  165. ! /* $Header: arg.c,v 1.0.1.3 88/01/26 12:30:33 root Exp $
  166.    *
  167.    * $Log:    arg.c,v $
  168. !  * Revision 1.0.1.3  88/01/26  12:30:33  root
  169. !  * patch 6: sprintf didn't finish processing format string when out of args.
  170.    * 
  171.    * Revision 1.0.1.2  88/01/24  03:52:34  root
  172.    * patch 2: added STATBLKS dependencies.
  173. --- 1,8 ----
  174. ! /* $Header: arg.c,v 1.0.1.4 88/01/28 10:22:06 root Exp $
  175.    *
  176.    * $Log:    arg.c,v $
  177. !  * Revision 1.0.1.4  88/01/28  10:22:06  root
  178. !  * patch8: added eval operator.
  179.    * 
  180.    * Revision 1.0.1.2  88/01/24  03:52:34  root
  181.    * patch 2: added STATBLKS dependencies.
  182. ***************
  183. *** 1190,1195 ****
  184. --- 1190,1196 ----
  185.       opargs[O_UNSHIFT] =        A(1,0,0);
  186.       opargs[O_LINK] =        A(1,1,0);
  187.       opargs[O_REPEAT] =        A(1,1,0);
  188. +     opargs[O_EVAL] =        A(1,0,0);
  189.   }
  190.   
  191.   #ifdef VOIDSIG
  192. ***************
  193. *** 2091,2096 ****
  194. --- 2092,2102 ----
  195.           astore(ary,0,str);
  196.       }
  197.       value = (double)(ary->ary_fill + 1);
  198. +     break;
  199. +     case O_EVAL:
  200. +     str_sset(str,
  201. +         do_eval(arg[1].arg_type != A_NULL ? sarg[1] : defstab->stab_val) );
  202. +     STABSET(str);
  203.       break;
  204.       }
  205.   #ifdef DEBUGGING
  206.  
  207. Index: arg.h
  208. Prereq: 1.0
  209. *** arg.h.old    Thu Jan 28 11:08:59 1988
  210. --- arg.h    Thu Jan 28 11:09:00 1988
  211. ***************
  212. *** 1,6 ****
  213. ! /* $Header: arg.h,v 1.0 87/12/18 13:04:39 root Exp $
  214.    *
  215.    * $Log:    arg.h,v $
  216.    * Revision 1.0  87/12/18  13:04:39  root
  217.    * Initial revision
  218.    * 
  219. --- 1,9 ----
  220. ! /* $Header: arg.h,v 1.0.1.1 88/01/28 10:22:40 root Exp $
  221.    *
  222.    * $Log:    arg.h,v $
  223. +  * Revision 1.0.1.1  88/01/28  10:22:40  root
  224. +  * patch8: added eval operator.
  225. +  * 
  226.    * Revision 1.0  87/12/18  13:04:39  root
  227.    * Initial revision
  228.    * 
  229. ***************
  230. *** 111,117 ****
  231.   #define O_UNSHIFT 102
  232.   #define O_LINK 103
  233.   #define O_REPEAT 104
  234. ! #define MAXO 105
  235.   
  236.   #ifndef DOINIT
  237.   extern char *opname[];
  238. --- 114,121 ----
  239.   #define O_UNSHIFT 102
  240.   #define O_LINK 103
  241.   #define O_REPEAT 104
  242. ! #define O_EVAL 105
  243. ! #define MAXO 106
  244.   
  245.   #ifndef DOINIT
  246.   extern char *opname[];
  247. ***************
  248. *** 222,228 ****
  249.       "UNSHIFT",
  250.       "LINK",
  251.       "REPEAT",
  252. !     "105"
  253.   };
  254.   #endif
  255.   
  256. --- 226,233 ----
  257.       "UNSHIFT",
  258.       "LINK",
  259.       "REPEAT",
  260. !     "EVAL",
  261. !     "106"
  262.   };
  263.   #endif
  264.   
  265.  
  266. Index: t/base.lex
  267. Prereq: 1.0
  268. *** t/base.lex.old    Thu Jan 28 11:17:55 1988
  269. --- t/base.lex    Thu Jan 28 11:17:56 1988
  270. ***************
  271. *** 1,8 ****
  272.   #!./perl
  273.   
  274. ! # $Header: base.lex,v 1.0 87/12/18 13:11:51 root Exp $
  275.   
  276. ! print "1..4\n";
  277.   
  278.   $ # this is the register <space>
  279.   = 'x';
  280. --- 1,8 ----
  281.   #!./perl
  282.   
  283. ! # $Header: base.lex,v 1.0.1.1 88/01/28 10:37:00 root Exp $
  284.   
  285. ! print "1..6\n";
  286.   
  287.   $ # this is the register <space>
  288.   = 'x';
  289. ***************
  290. *** 21,23 ****
  291. --- 21,32 ----
  292.   $x = '\\'; # ';
  293.   
  294.   if (length($x) == 1) {print "ok 4\n";} else {print "not ok 4\n";}
  295. + eval 'while (0) {
  296. +     print "foo\n";
  297. + }
  298. + /^/ && (print "ok 5\n");
  299. + ';
  300. + eval '$foo{1} / 1;';
  301. + if (!$@) {print "ok 6\n";} else {print "not ok 6\n";}
  302.  
  303. Index: cmd.h
  304. Prereq: 1.0
  305. *** cmd.h.old    Thu Jan 28 11:09:05 1988
  306. --- cmd.h    Thu Jan 28 11:09:06 1988
  307. ***************
  308. *** 1,6 ****
  309. ! /* $Header: cmd.h,v 1.0 87/12/18 13:04:59 root Exp $
  310.    *
  311.    * $Log:    cmd.h,v $
  312.    * Revision 1.0  87/12/18  13:04:59  root
  313.    * Initial revision
  314.    * 
  315. --- 1,9 ----
  316. ! /* $Header: cmd.h,v 1.0.1.1 88/01/28 10:23:07 root Exp $
  317.    *
  318.    * $Log:    cmd.h,v $
  319. +  * Revision 1.0.1.1  88/01/28  10:23:07  root
  320. +  * patch8: added eval_root for eval operator.
  321. +  * 
  322.    * Revision 1.0  87/12/18  13:04:59  root
  323.    * Initial revision
  324.    * 
  325. ***************
  326. *** 106,111 ****
  327. --- 109,115 ----
  328.   #define Nullcmd Null(CMD*)
  329.   
  330.   EXT CMD *main_root INIT(Nullcmd);
  331. + EXT CMD *eval_root INIT(Nullcmd);
  332.   
  333.   EXT struct compcmd {
  334.       CMD *comp_true;
  335.  
  336. Index: t/op.eval
  337. *** t/op.eval.old    Thu Jan 28 11:18:04 1988
  338. --- t/op.eval    Thu Jan 28 11:18:04 1988
  339. ***************
  340. *** 0 ****
  341. --- 1,20 ----
  342. + #!./perl
  343. + print "1..6\n";
  344. + eval 'print "ok 1\n";';
  345. + if ($@ eq '') {print "ok 2\n";} else {print "not ok 2\n";}
  346. + eval "\$foo\n    = # this is a comment\n'ok 3';";
  347. + print $foo,"\n";
  348. + eval "\$foo\n    = # this is a comment\n'ok 4\n';";
  349. + print $foo;
  350. + eval '
  351. + $foo =';        # this tests for a call through yyerror()
  352. + if ($@ =~ /line 2/) {print "ok 5\n";} else {print "not ok 5\n";}
  353. + eval '$foo = /';    # this tests for a call through fatal()
  354. + if ($@ =~ /Search/) {print "ok 6\n";} else {print "not ok 6\n";}
  355.  
  356. Index: perl.h
  357. Prereq: 1.0.1.2
  358. *** perl.h.old    Thu Jan 28 11:09:13 1988
  359. --- perl.h    Thu Jan 28 11:09:14 1988
  360. ***************
  361. *** 1,6 ****
  362. ! /* $Header: perl.h,v 1.0.1.2 88/01/24 03:53:47 root Exp $
  363.    *
  364.    * $Log:    perl.h,v $
  365.    * Revision 1.0.1.2  88/01/24  03:53:47  root
  366.    * patch 2: hid str_peek() in #ifdef DEBUGGING.
  367.    * 
  368. --- 1,9 ----
  369. ! /* $Header: perl.h,v 1.0.1.3 88/01/28 10:24:17 root Exp $
  370.    *
  371.    * $Log:    perl.h,v $
  372. +  * Revision 1.0.1.3  88/01/28  10:24:17  root
  373. +  * patch8: added eval operator.
  374. +  * 
  375.    * Revision 1.0.1.2  88/01/24  03:53:47  root
  376.    * patch 2: hid str_peek() in #ifdef DEBUGGING.
  377.    * 
  378. ***************
  379. *** 103,109 ****
  380.   STR *arg_to_str();
  381.   STR *str_new();
  382.   STR *stab_str();
  383. ! STR *eval();
  384.   
  385.   FCMD *load_format();
  386.   
  387. --- 106,113 ----
  388.   STR *arg_to_str();
  389.   STR *str_new();
  390.   STR *stab_str();
  391. ! STR *eval();        /* this evaluates expressions */
  392. ! STR *do_eval();        /* this evaluates eval operator */
  393.   
  394.   FCMD *load_format();
  395.   
  396. ***************
  397. *** 164,169 ****
  398. --- 168,174 ----
  399.   EXT char tokenbuf[256];
  400.   EXT int expectterm INIT(TRUE);
  401.   EXT int lex_newlines INIT(FALSE);
  402. + EXT int in_eval INIT(FALSE);
  403.   
  404.   FILE *popen();
  405.   /* char *str_get(); */
  406. ***************
  407. *** 196,201 ****
  408. --- 201,207 ----
  409.   EXT int loop_ptr INIT(-1);
  410.   
  411.   EXT jmp_buf top_env;
  412. + EXT jmp_buf eval_env;
  413.   
  414.   EXT char *goto_targ INIT(Nullch);    /* cmd_exec gets strange when set */
  415.   
  416.  
  417. Index: perl.y
  418. Prereq: 1.0
  419. *** perl.y.old    Thu Jan 28 11:09:22 1988
  420. --- perl.y    Thu Jan 28 11:09:24 1988
  421. ***************
  422. *** 1,6 ****
  423. ! /* $Header: perl.y,v 1.0 87/12/18 15:48:59 root Exp $
  424.    *
  425.    * $Log:    perl.y,v $
  426.    * Revision 1.0  87/12/18  15:48:59  root
  427.    * Initial revision
  428.    * 
  429. --- 1,9 ----
  430. ! /* $Header: perl.y,v 1.0.1.1 88/01/28 10:25:31 root Exp $
  431.    *
  432.    * $Log:    perl.y,v $
  433. +  * Revision 1.0.1.1  88/01/28  10:25:31  root
  434. +  * patch8: added eval operator.
  435. +  * 
  436.    * Revision 1.0  87/12/18  15:48:59  root
  437.    * Initial revision
  438.    * 
  439. ***************
  440. *** 97,103 ****
  441.   %% /* RULES */
  442.   
  443.   prog    :    lineseq
  444. !             { main_root = block_head($1); }
  445.       ;
  446.   
  447.   compblock:    block CONTINUE block
  448. --- 100,109 ----
  449.   %% /* RULES */
  450.   
  451.   prog    :    lineseq
  452. !             { if (in_eval)
  453. !                 eval_root = block_head($1);
  454. !                 else
  455. !                 main_root = block_head($1); }
  456.       ;
  457.   
  458.   compblock:    block CONTINUE block
  459.  
  460. Index: perldb
  461. *** perldb.old    Thu Jan 28 11:17:03 1988
  462. --- perldb    Thu Jan 28 11:17:04 1988
  463. ***************
  464. *** 0 ****
  465. --- 1,296 ----
  466. + #!/bin/perl
  467. + # $Header: perldb,v 1.0.1.1 88/01/28 10:27:16 root Exp $
  468. + #
  469. + # $Log:    perldb,v $
  470. + # Revision 1.0.1.1  88/01/28  10:27:16  root
  471. + # patch8: created this file.
  472. + # 
  473. + #
  474. + $tmp = "/tmp/pdb$$";        # default temporary file, -o overrides.
  475. + # parse any switches
  476. + while ($ARGV[0] =~ /^-/) {
  477. +     $_ = shift;
  478. +     /^-o$/ && ($tmp = shift,next);
  479. +     die "Unrecognized switch: $_";
  480. + }
  481. + $filename = shift;
  482. + die "Usage: perldb [-o output] scriptname arguments" unless $filename;
  483. + open(script,$filename) || die "Can't find $filename";
  484. + open(tmp, ">$tmp") || die "Can't make temp script";
  485. + $perl = '/bin/perl';
  486. + $init = 1;
  487. + $state = 'statement';
  488. + # now translate script to contain DB calls at the appropriate places
  489. + while (<script>) {
  490. +     chop;
  491. +     if ($. == 1) {
  492. +     if (/^#! *([^ \t]*) (-[^ \t]*)/) {
  493. +         $perl = $1;
  494. +         $switch = $2;
  495. +     }
  496. +     elsif (/^#! *([^ \t]*)/) {
  497. +         $perl = $1;
  498. +     }
  499. +     }
  500. +     s/ *$//;
  501. +     push(@script,$_);        # remember line for DBinit
  502. +     $line = $_;
  503. +     next if /^$/;        # blank lines are uninteresting
  504. +     next if /^[ \t]*#/;        # likewise comment lines
  505. +     if ($init) {
  506. +     print tmp "do DBinit($.);"; $init = '';
  507. +     }
  508. +     if ($inform) {        # skip formats
  509. +     if (/^\.$/) {
  510. +         $inform = '';
  511. +         $state = 'statement';
  512. +     }
  513. +     next;
  514. +     }
  515. +     if (/^[ \t]*format /) {
  516. +     $inform++;
  517. +     next;
  518. +     }
  519. +     if ($state eq 'statement' && !/^[ \t]*}/) {
  520. +     if (s/^([ \t]*[A-Za-z_0-9]+:)//) {
  521. +         $label = $1;
  522. +     }
  523. +     else {
  524. +         $label = '';
  525. +     }
  526. +     $line = $label . "do DB($.); " . $_;    # all that work for this line
  527. +     }
  528. +     else {
  529. +     $script[$#script - 1] .= ' ';    # mark line as having continuation
  530. +     }
  531. +     do parse();                # set $state to correct eol value
  532. + }
  533. + continue {
  534. +     print tmp $line,"\n";
  535. + }
  536. + # now put out our debugging subroutines.  First the one that's called all over.
  537. + print tmp '
  538. + sub DB {
  539. +     push(@DB,$. ,$@, $!, $[, $,, $/, $\ );
  540. +     $[ = 0; $, = ""; $/ = "\n"; $\ = "";
  541. +     $DBline=pop(@_);
  542. +     if ($DBsingle || $DBstop[$DBline] || $DBtrace) {
  543. +     print "$DBline:\t",$DBline[$DBline],"\n";
  544. +     for ($DBi = $DBline; $DBline[$DBi++] =~ / $/; ) {
  545. +         print "$DBi:\t",$DBline[$DBi],"\n";
  546. +     }
  547. +     }
  548. +     if ($DBaction[$DBline]) {
  549. +     eval $DBaction[$DBline];  print $@;
  550. +     }
  551. +     if ($DBstop[$DBline] || $DBsingle) {
  552. +     for (;;) {
  553. +         print "perldb> ";
  554. +         $DBcmd = <stdin>;
  555. +         last if $DBcmd =~ /^$/;
  556. +         if ($DBcmd =~ /^q$/) {
  557. +         exit 0;
  558. +         }
  559. +         if ($DBcmd =~ /^h$/) {
  560. +         print "
  561. + s        Single step.
  562. + c        Continue.
  563. + <CR>        Repeat last s or c.
  564. + l min-max    List lines.
  565. + l line        List line.
  566. + l        List the whole program.
  567. + L        List breakpoints.
  568. + t        Toggle trace mode.
  569. + b line        Set breakpoint.
  570. + d line        Delete breakpoint.
  571. + d        Delete breakpoint at this line.
  572. + a line command    Set an action for this line.
  573. + q        Quit.
  574. + command        Execute as a perl statement.
  575. + ";
  576. +         next;
  577. +         }
  578. +         if ($DBcmd =~ /^t$/) {
  579. +         $DBtrace = !$DBtrace;
  580. +         print "Trace = $DBtrace\n";
  581. +         next;
  582. +         }
  583. +         if ($DBcmd =~ /^l (.*)[-,](.*)/) {
  584. +         for ($DBi = $1; $DBi <= $2; $DBi++) {
  585. +             print "$DBi:\t", $DBline[$DBi], "\n";
  586. +         }
  587. +         next;
  588. +         }
  589. +         if ($DBcmd =~ /^l (.*)/) {
  590. +         print "$1:\t", $DBline[$1], "\n";
  591. +         next;
  592. +         }
  593. +         if ($DBcmd =~ /^l$/) {
  594. +         for ($DBi = 1; $DBi <= $DBmax ; $DBi++) {
  595. +             print "$DBi:\t", $DBline[$DBi], "\n";
  596. +         }
  597. +         next;
  598. +         }
  599. +         if ($DBcmd =~ /^L$/) {
  600. +         for ($DBi = 1; $DBi <= $DBmax ; $DBi++) {
  601. +             print "$DBi:\t", $DBline[$DBi], "\n" if $DBstop[$DBi];
  602. +         }
  603. +         next;
  604. +         }
  605. +         if ($DBcmd =~ /^b (.*)/) {
  606. +         $DBi = $1;
  607. +         if ($DBline[$DBi-1] =~ / $/) {
  608. +             print "Line $DBi not breakable.\n";
  609. +         }
  610. +         else {
  611. +             $DBstop[$DBi] = 1;
  612. +         }
  613. +         next;
  614. +         }
  615. +         if ($DBcmd =~ /^d (.*)/) {
  616. +         $DBstop[$1] = 0;
  617. +         next;
  618. +         }
  619. +         if ($DBcmd =~ /^d$/) {
  620. +         $DBstop[$DBline] = 0;
  621. +         next;
  622. +         }
  623. +         if ($DBcmd =~ /^a ([0-9]+)[ \t]+(.*)/) {
  624. +         $DBi = $1;
  625. +         $DBaction = $2;
  626. +         $DBaction .= ";" unless $DBaction =~ /[;}]$/;
  627. +         $DBaction[$DBi] = $DBaction;
  628. +         next;
  629. +         }
  630. +         if ($DBcmd =~ /^s$/) {
  631. +         $DBsingle = 1;
  632. +         last;
  633. +         }
  634. +         if ($DBcmd =~ /^c$/) {
  635. +         $DBsingle = 0;
  636. +         last;
  637. +         }
  638. +         chop($DBcmd);
  639. +         $DBcmd .= ";" unless $DBcmd =~ /[;}]$/;
  640. +         eval $DBcmd;
  641. +         print $@,"\n";
  642. +     }
  643. +     }
  644. +     $\ = pop(@DB);
  645. +     $/ = pop(@DB);
  646. +     $, = pop(@DB);
  647. +     $[ = pop(@DB);
  648. +     $! = pop(@DB);
  649. +     $@ = pop(@DB);
  650. +     $. = pop(@DB);
  651. + }
  652. + sub DBinit {
  653. +     $DBstop[$_[0]] = 1;
  654. + ';
  655. + print tmp "    \$0 = '$script';\n";
  656. + print tmp "    \$DBmax = $.;\n";
  657. + print tmp "    unlink '/tmp/pdb$$';\n";        # expected to fail on -o.
  658. + for ($i = 1; $#script >= 0; $i++) {
  659. +     $_ = shift(@script);
  660. +     s/'/\\'/g;
  661. +     print tmp "    \$DBline[$i] = '$_';\n";
  662. + }
  663. + print tmp '}
  664. + ';
  665. + close tmp;
  666. + # prepare to run the new script
  667. + unshift(@ARGV,$tmp);
  668. + unshift(@ARGV,$switch) if $switch;
  669. + unshift(@ARGV,$perl);
  670. + exec @ARGV;
  671. + # This routine tokenizes one perl line good enough to tell what state we are
  672. + # in by the end of the line, so we can tell if the next line should contain
  673. + # a call to DB or not.
  674. + sub parse {
  675. +     until ($_ eq '') {
  676. +     $ord = ord($_);
  677. +     if ($quoting) {
  678. +         if ($quote == $ord) {
  679. +         $quoting--;
  680. +         }
  681. +         s/^.//            if /^[\\]/;
  682. +         s/^.//;
  683. +         last if $_ eq "\n";
  684. +         $state = 'term'        unless $quoting;
  685. +         next;
  686. +     }
  687. +     if ($ord > 64) {
  688. +         do quote(ord($1),1), next    if s/^m\b(.)//;
  689. +         do quote(ord($1),2), next    if s/^s\b(.)//;
  690. +         do quote(ord($1),2), next    if s/^y\b(.)//;
  691. +         do quote(ord($1),2), next    if s/^tr\b(.)//;
  692. +         next            if s/^[A-Za-z_][A-Za-z_0-9]*://;
  693. +         $state = 'term', next    if s/^eof\b//;
  694. +         $state = 'term', next    if s/^shift\b//;
  695. +         $state = 'term', next    if s/^split\b//;
  696. +         $state = 'term', next    if s/^tell\b//;
  697. +         $state = 'term', next    if s/^write\b//;
  698. +         $state = 'operator', next    if s/^[A-Za-z_][A-Za-z_0-9]*//;
  699. +         $state = 'operator', next    if s/^[~^|]+//;
  700. +         $state = 'statement', next    if s/^{//;
  701. +         $state = 'statement', next    if s/^}[ \t]*$//;
  702. +         $state = 'statement', next    if s/^}[ \t]*#/#/;
  703. +         $state = 'term', next    if s/^}//;
  704. +         $state = 'operator', next    if s/^\[//;
  705. +         $state = 'term', next    if s/^]//;
  706. +         die "Illegal character $_";
  707. +     }
  708. +     elsif ($ord < 33) {
  709. +         next if s/[ \t\n]+//;
  710. +         die "Illegal character $_";
  711. +     }
  712. +     else {
  713. +         $state = 'statement', next    if s/^;//;
  714. +         $state = 'term', next    if s/^\.[0-9eE]+//;
  715. +         $state = 'term', next    if s/^[0-9][0-9xaAbBcCddeEfF.]*//;
  716. +         $state = 'term', next    if s/^\$[A-Za-z_][A-Za-z_0-9]*//;
  717. +         $state = 'term', next    if s/^\$.//;
  718. +         $state = 'term', next    if s/^@[A-Za-z_][A-Za-z_0-9]*//;
  719. +         $state = 'term', next    if s/^@.//;
  720. +         $state = 'term', next    if s/^<[A-Za-z_0-9]*>//;
  721. +         next            if s/^\+\+//;
  722. +         next            if s/^--//;
  723. +         $state = 'operator', next    if s/^[(!%&*-=+:,.<>]//;
  724. +         $state = 'term', next    if s/^\)+//;
  725. +         do quote($ord,1), next    if s/^'//;
  726. +         do quote($ord,1), next    if s/^"//;
  727. +         if (s|^[/?]||) {
  728. +         if ($state =~ /stat|oper/) {
  729. +             $state = 'term';
  730. +             do quote($ord,1), next;
  731. +         }
  732. +         $state = 'operator', next;
  733. +         }
  734. +         next            if s/^#.*//;
  735. +     }
  736. +     }
  737. + }
  738. + sub quote {
  739. +     ($quote,$quoting) = @_;
  740. +     $state = 'quote';
  741. + }
  742.  
  743. Index: perldb.man
  744. *** perldb.man.old    Thu Jan 28 11:17:11 1988
  745. --- perldb.man    Thu Jan 28 11:17:12 1988
  746. ***************
  747. *** 0 ****
  748. --- 1,119 ----
  749. + .rn '' }`
  750. + ''' $Header: perldb.man,v 1.0.1.1 88/01/28 10:28:19 root Exp $
  751. + ''' 
  752. + ''' $Log:    perldb.man,v $
  753. + ''' Revision 1.0.1.1  88/01/28  10:28:19  root
  754. + ''' patch8: created this file.
  755. + ''' 
  756. + ''' 
  757. + .de Sh
  758. + .br
  759. + .ne 5
  760. + .PP
  761. + \fB\\$1\fR
  762. + .PP
  763. + ..
  764. + .de Sp
  765. + .if t .sp .5v
  766. + .if n .sp
  767. + ..
  768. + .de Ip
  769. + .br
  770. + .ie \\n.$>=3 .ne \\$3
  771. + .el .ne 3
  772. + .IP "\\$1" \\$2
  773. + ..
  774. + '''
  775. + '''     Set up \*(-- to give an unbreakable dash;
  776. + '''     string Tr holds user defined translation string.
  777. + '''     Bell System Logo is used as a dummy character.
  778. + '''
  779. + .tr \(bs-|\(bv\*(Tr
  780. + .ie n \{\
  781. + .ds -- \(bs-
  782. + .if (\n(.H=4u)&(1m=24u) .ds -- \(bs\h'-12u'\(bs\h'-12u'-\" diablo 10 pitch
  783. + .if (\n(.H=4u)&(1m=20u) .ds -- \(bs\h'-12u'\(bs\h'-8u'-\" diablo 12 pitch
  784. + .ds L" ""
  785. + .ds R" ""
  786. + .ds L' '
  787. + .ds R' '
  788. + 'br\}
  789. + .el\{\
  790. + .ds -- \(em\|
  791. + .tr \*(Tr
  792. + .ds L" ``
  793. + .ds R" ''
  794. + .ds L' `
  795. + .ds R' '
  796. + 'br\}
  797. + .TH PERLDB 1 LOCAL
  798. + .SH NAME
  799. + perldb - Perl Debugger
  800. + .SH SYNOPSIS
  801. + .B perldb [-o output] perlscript arguments
  802. + .SH DESCRIPTION
  803. + .I Perldb
  804. + is a symbolic debugger for
  805. + .I perl
  806. + scripts.
  807. + Run your script just as you normally would, only prepend \*(L"perldb\*(R" to
  808. + the command.
  809. + (On systems where #! doesn't work, put any perl switches into the #! line
  810. + anyway\*(--perldb will pass them off to perl when it runs the script.)
  811. + Perldb copies your script to a temporary file, instrumenting it in the process
  812. + and adding a debugging monitor.
  813. + It then executes the instrumented script for
  814. + you and stops at the first statement so you can set any breakpoints or actions
  815. + you desire.
  816. + .PP
  817. + There is only one switch: \-o, which tells perldb to put its temporary file
  818. + in the filename you specify, and to refrain from deleting the file.
  819. + Use this switch if you intend to rerun the instrumented script, or want to
  820. + look at it for some reason.
  821. + .PP
  822. + These are the debugging commands:
  823. + .Ip s 8
  824. + Single step.
  825. + Subsequent carriage returns will single step.
  826. + .Ip c 8
  827. + Continue.
  828. + Turns off single step mode and runs till the next break point.
  829. + Subsequent carriage returns will continue.
  830. + .Ip <CR> 8
  831. + Repeat last s or c.
  832. + .Ip "l min-max" 8
  833. + List lines in the indicated range.
  834. + .Ip "l line" 8
  835. + List indicated line.
  836. + .Ip l 8
  837. + List the whole program.
  838. + .Ip L 8
  839. + List breakpoints.
  840. + .Ip t 8
  841. + Toggle trace mode.
  842. + .Ip "b line" 8
  843. + Set breakpoint at indicated line.
  844. + .Ip "d line" 8
  845. + Delete breakpoint at indicated line.
  846. + .Ip d 8
  847. + Delete breakpoint at this line.
  848. + .Ip "a line command" 8
  849. + Set an action for indicated line.
  850. + The command must be a valid perl command, except that a missing trailing ;
  851. + will be supplied.
  852. + .Ip q 8
  853. + Quit.
  854. + .Ip command 8
  855. + Execute command as a perl statement.
  856. + A missing trailing ; will be supplied if necessary.
  857. + .SH ENVIRONMENT
  858. + No environment variables are used by perldb.
  859. + .SH AUTHOR
  860. + Larry Wall <lwall@jpl-devvax.Jpl.Nasa.Gov>
  861. + .SH FILES
  862. + /tmp/pdb$$    temporary file for instrumented script
  863. + .SH SEE ALSO
  864. + perl    
  865. + .SH DIAGNOSTICS
  866. + .SH BUGS
  867. + .rn }` ''
  868.  
  869. Index: perly.c
  870. Prereq: 1.0.1.2
  871. *** perly.c.old    Thu Jan 28 11:17:22 1988
  872. --- perly.c    Thu Jan 28 11:17:25 1988
  873. ***************
  874. *** 1,6 ****
  875. ! char rcsid[] = "$Header: perly.c,v 1.0.1.2 88/01/24 00:06:03 root Exp $";
  876.   /*
  877.    * $Log:    perly.c,v $
  878.    * Revision 1.0.1.2  88/01/24  00:06:03  root
  879.    * patch 2: s/(abc)/\1/ grandfathering didn't work right.
  880.    * 
  881. --- 1,9 ----
  882. ! char rcsid[] = "$Header: perly.c,v 1.0.1.3 88/01/28 10:28:31 root Exp $";
  883.   /*
  884.    * $Log:    perly.c,v $
  885. +  * Revision 1.0.1.3  88/01/28  10:28:31  root
  886. +  * patch8: added eval operator.  Also fixed expectterm following right curly.
  887. +  * 
  888.    * Revision 1.0.1.2  88/01/24  00:06:03  root
  889.    * patch 2: s/(abc)/\1/ grandfathering didn't work right.
  890.    * 
  891. ***************
  892. *** 16,21 ****
  893. --- 19,25 ----
  894.   bool assume_n = FALSE;
  895.   bool assume_p = FALSE;
  896.   bool doswitches = FALSE;
  897. + bool allstabs = FALSE;        /* init all customary symbols in symbol table?*/
  898.   char *filename;
  899.   char *e_tmpname = "/tmp/perl-eXXXXXX";
  900.   FILE *e_fp = Nullfp;
  901. ***************
  902. *** 161,172 ****
  903.           str_numset(stabent(argv[0]+1,TRUE)->stab_val,(double)1.0);
  904.       }
  905.       }
  906. !     if (argvstab = stabent("ARGV",FALSE)) {
  907.       for (; argc > 0; argc--,argv++) {
  908.           apush(argvstab->stab_array,str_make(argv[0]));
  909.       }
  910.       }
  911. !     if (envstab = stabent("ENV",FALSE)) {
  912.       for (; *env; env++) {
  913.           if (!(s = index(*env,'=')))
  914.           continue;
  915. --- 165,176 ----
  916.           str_numset(stabent(argv[0]+1,TRUE)->stab_val,(double)1.0);
  917.       }
  918.       }
  919. !     if (argvstab = stabent("ARGV",allstabs)) {
  920.       for (; argc > 0; argc--,argv++) {
  921.           apush(argvstab->stab_array,str_make(argv[0]));
  922.       }
  923.       }
  924. !     if (envstab = stabent("ENV",allstabs)) {
  925.       for (; *env; env++) {
  926.           if (!(s = index(*env,'=')))
  927.           continue;
  928. ***************
  929. *** 177,188 ****
  930.           *--s = '=';
  931.       }
  932.       }
  933. !     sigstab = stabent("SIG",FALSE);
  934.   
  935.       magicalize("!#?^~=-%0123456789.+&*(),\\/[|");
  936.   
  937. !     (tmpstab = stabent("0",FALSE)) && str_set(STAB_STR(tmpstab),filename);
  938. !     (tmpstab = stabent("$",FALSE)) &&
  939.       str_numset(STAB_STR(tmpstab),(double)getpid());
  940.   
  941.       tmpstab = stabent("stdin",TRUE);
  942. --- 181,192 ----
  943.           *--s = '=';
  944.       }
  945.       }
  946. !     sigstab = stabent("SIG",allstabs);
  947.   
  948.       magicalize("!#?^~=-%0123456789.+&*(),\\/[|");
  949.   
  950. !     (tmpstab = stabent("0",allstabs)) && str_set(STAB_STR(tmpstab),filename);
  951. !     (tmpstab = stabent("$",allstabs)) &&
  952.       str_numset(STAB_STR(tmpstab),(double)getpid());
  953.   
  954.       tmpstab = stabent("stdin",TRUE);
  955. ***************
  956. *** 198,203 ****
  957. --- 202,209 ----
  958.       tmpstab = stabent("stderr",TRUE);
  959.       tmpstab->stab_io = stio_new();
  960.       tmpstab->stab_io->fp = stderr;
  961. +     safefree(filename);
  962. +     filename = "(eval)";
  963.   
  964.       setjmp(top_env);    /* sets goto_targ on longjump */
  965.   
  966. ***************
  967. *** 225,231 ****
  968.   
  969.       sym[1] = '\0';
  970.       while (*sym = *list++) {
  971. !     if (stab = stabent(sym,FALSE)) {
  972.           stab->stab_flags = SF_VMAGIC;
  973.           stab->stab_val->str_link.str_magic = stab;
  974.       }
  975. --- 231,237 ----
  976.   
  977.       sym[1] = '\0';
  978.       while (*sym = *list++) {
  979. !     if (stab = stabent(sym,allstabs)) {
  980.           stab->stab_flags = SF_VMAGIC;
  981.           stab->stab_val->str_link.str_magic = stab;
  982.       }
  983. ***************
  984. *** 322,328 ****
  985.           filename = savestr(s);
  986.           s = str_get(linestr);
  987.       }
  988. !     *s = '\0';
  989.       if (lex_newlines)
  990.           RETURN('\n');
  991.       goto retry;
  992. --- 328,342 ----
  993.           filename = savestr(s);
  994.           s = str_get(linestr);
  995.       }
  996. !     if (in_eval) {
  997. !         while (*s && *s != '\n')
  998. !         s++;
  999. !         if (*s)
  1000. !         s++;
  1001. !         line++;
  1002. !     }
  1003. !     else
  1004. !         *s = '\0';
  1005.       if (lex_newlines)
  1006.           RETURN('\n');
  1007.       goto retry;
  1008. ***************
  1009. *** 350,358 ****
  1010.       OPERATOR(tmp);
  1011.       case ')':
  1012.       case ']':
  1013. -     case '}':
  1014.       tmp = *s++;
  1015.       TERM(tmp);
  1016.       case '&':
  1017.       s++;
  1018.       tmp = *s++;
  1019. --- 364,378 ----
  1020.       OPERATOR(tmp);
  1021.       case ')':
  1022.       case ']':
  1023.       tmp = *s++;
  1024.       TERM(tmp);
  1025. +     case '}':
  1026. +     tmp = *s++;
  1027. +     for (d = s; *d == ' ' || *d == '\t'; d++) ;
  1028. +     if (*d == '\n' || *d == '#')
  1029. +         OPERATOR(tmp);        /* block end */
  1030. +     else
  1031. +         TERM(tmp);            /* associative array end */
  1032.       case '&':
  1033.       s++;
  1034.       tmp = *s++;
  1035. ***************
  1036. *** 508,513 ****
  1037. --- 528,537 ----
  1038.           OPERATOR(SEQ);
  1039.       if (strEQ(d,"exit"))
  1040.           UNI(O_EXIT);
  1041. +     if (strEQ(d,"eval")) {
  1042. +         allstabs = TRUE;        /* must initialize everything since */
  1043. +         UNI(O_EVAL);        /* we don't know what will be used */
  1044. +     }
  1045.       if (strEQ(d,"eof"))
  1046.           TERM(FEOF);
  1047.       if (strEQ(d,"exp"))
  1048. ***************
  1049. *** 1480,1487 ****
  1050.       strcpy(tname,"^?");
  1051.       else
  1052.       sprintf(tname,"%c",yychar);
  1053. !     printf("%s in file %s at line %d, next token \"%s\"\n",
  1054.         s,filename,line,tname);
  1055.   }
  1056.   
  1057.   char *
  1058. --- 1504,1515 ----
  1059.       strcpy(tname,"^?");
  1060.       else
  1061.       sprintf(tname,"%c",yychar);
  1062. !     sprintf(tokenbuf, "%s in file %s at line %d, next token \"%s\"\n",
  1063.         s,filename,line,tname);
  1064. +     if (in_eval)
  1065. +     str_set(stabent("@",TRUE)->stab_val,tokenbuf);
  1066. +     else
  1067. +     fputs(tokenbuf,stderr);
  1068.   }
  1069.   
  1070.   char *
  1071. ***************
  1072. *** 1964,1970 ****
  1073.           str_numset(str, (double)str_len(s1));
  1074.           break;
  1075.       case O_SUBSTR:
  1076. !         if (arg[3].arg_type != A_SINGLE || stabent("[",FALSE)) {
  1077.           str_free(str);        /* making the fallacious assumption */
  1078.           str = Nullstr;        /* that any $[ occurs before substr()*/
  1079.           }
  1080. --- 1992,1998 ----
  1081.           str_numset(str, (double)str_len(s1));
  1082.           break;
  1083.       case O_SUBSTR:
  1084. !         if (arg[3].arg_type != A_SINGLE || stabent("[",allstabs)) {
  1085.           str_free(str);        /* making the fallacious assumption */
  1086.           str = Nullstr;        /* that any $[ occurs before substr()*/
  1087.           }
  1088. ***************
  1089. *** 2463,2466 ****
  1090. --- 2491,2619 ----
  1091.       bufptr = str_get(linestr);
  1092.       yyerror("Format not terminated");
  1093.       return froot.f_next;
  1094. + }
  1095. + STR *
  1096. + do_eval(str)
  1097. + STR *str;
  1098. + {
  1099. +     int retval;
  1100. +     CMD *myroot;
  1101. +     in_eval++;
  1102. +     str_set(stabent("@",TRUE)->stab_val,"");
  1103. +     line = 1;
  1104. +     str_sset(linestr,str);
  1105. +     bufptr = str_get(linestr);
  1106. +     if (setjmp(eval_env))
  1107. +     retval = 1;
  1108. +     else
  1109. +     retval = yyparse();
  1110. +     myroot = eval_root;        /* in case cmd_exec does another eval! */
  1111. +     if (retval)
  1112. +     str = &str_no;
  1113. +     else {
  1114. +     str = cmd_exec(eval_root);
  1115. +     cmd_free(myroot);    /* can't free on error, for some reason */
  1116. +     }
  1117. +     in_eval--;
  1118. +     return str;
  1119. + }
  1120. + cmd_free(cmd)
  1121. + register CMD *cmd;
  1122. + {
  1123. +     register CMD *tofree;
  1124. +     register CMD *head = cmd;
  1125. +     while (cmd) {
  1126. +     if (cmd->c_label)
  1127. +         safefree(cmd->c_label);
  1128. +     if (cmd->c_first)
  1129. +         str_free(cmd->c_first);
  1130. +     if (cmd->c_spat)
  1131. +         spat_free(cmd->c_spat);
  1132. +     if (cmd->c_expr)
  1133. +         arg_free(cmd->c_expr);
  1134. +     switch (cmd->c_type) {
  1135. +     case C_WHILE:
  1136. +     case C_BLOCK:
  1137. +     case C_IF:
  1138. +         if (cmd->ucmd.ccmd.cc_true)
  1139. +         cmd_free(cmd->ucmd.ccmd.cc_true);
  1140. +         if (cmd->c_type == C_IF && cmd->ucmd.ccmd.cc_alt)
  1141. +         cmd_free(cmd->ucmd.ccmd.cc_alt,Nullcmd);
  1142. +         break;
  1143. +     case C_EXPR:
  1144. +         if (cmd->ucmd.acmd.ac_stab)
  1145. +         arg_free(cmd->ucmd.acmd.ac_stab);
  1146. +         if (cmd->ucmd.acmd.ac_expr)
  1147. +         arg_free(cmd->ucmd.acmd.ac_expr);
  1148. +         break;
  1149. +     }
  1150. +     tofree = cmd;
  1151. +     cmd = cmd->c_next;
  1152. +     safefree((char*)tofree);
  1153. +     if (cmd && cmd == head)        /* reached end of while loop */
  1154. +         break;
  1155. +     }
  1156. + }
  1157. + arg_free(arg)
  1158. + register ARG *arg;
  1159. + {
  1160. +     register int i;
  1161. +     for (i = 1; i <= arg->arg_len; i++) {
  1162. +     switch (arg[i].arg_type) {
  1163. +     case A_NULL:
  1164. +         break;
  1165. +     case A_LEXPR:
  1166. +     case A_EXPR:
  1167. +         arg_free(arg[i].arg_ptr.arg_arg);
  1168. +         break;
  1169. +     case A_CMD:
  1170. +         cmd_free(arg[i].arg_ptr.arg_cmd);
  1171. +         break;
  1172. +     case A_STAB:
  1173. +     case A_LVAL:
  1174. +     case A_READ:
  1175. +     case A_ARYLEN:
  1176. +         break;
  1177. +     case A_SINGLE:
  1178. +     case A_DOUBLE:
  1179. +     case A_BACKTICK:
  1180. +         str_free(arg[i].arg_ptr.arg_str);
  1181. +         break;
  1182. +     case A_SPAT:
  1183. +         spat_free(arg[i].arg_ptr.arg_spat);
  1184. +         break;
  1185. +     case A_NUMBER:
  1186. +         break;
  1187. +     }
  1188. +     }
  1189. +     free_arg(arg);
  1190. + }
  1191. + spat_free(spat)
  1192. + register SPAT *spat;
  1193. + {
  1194. +     register SPAT *sp;
  1195. +     if (spat->spat_runtime)
  1196. +     arg_free(spat->spat_runtime);
  1197. +     if (spat->spat_repl) {
  1198. +     arg_free(spat->spat_repl);
  1199. +     }
  1200. +     free_compex(&spat->spat_compex);
  1201. +     /* now unlink from spat list */
  1202. +     if (spat_root == spat)
  1203. +     spat_root = spat->spat_next;
  1204. +     else {
  1205. +     for (sp = spat_root; sp->spat_next != spat; sp = sp->spat_next) ;
  1206. +     sp->spat_next = spat->spat_next;
  1207. +     }
  1208. +     safefree((char*)spat);
  1209.   }
  1210.  
  1211. Index: search.c
  1212. Prereq: 1.0.1.1
  1213. *** search.c.old    Thu Jan 28 11:17:36 1988
  1214. --- search.c    Thu Jan 28 11:17:37 1988
  1215. ***************
  1216. *** 1,6 ****
  1217. ! /* $Header: search.c,v 1.0.1.1 88/01/24 03:55:05 root Exp $
  1218.    *
  1219.    * $Log:    search.c,v $
  1220.    * Revision 1.0.1.1  88/01/24  03:55:05  root
  1221.    * patch 2: made depend on perl.h.
  1222.    * 
  1223. --- 1,9 ----
  1224. ! /* $Header: search.c,v 1.0.1.2 88/01/28 10:30:46 root Exp $
  1225.    *
  1226.    * $Log:    search.c,v $
  1227. +  * Revision 1.0.1.2  88/01/28  10:30:46  root
  1228. +  * patch8: uncommented free_compex for use with eval operator.
  1229. +  * 
  1230.    * Revision 1.0.1.1  88/01/24  03:55:05  root
  1231.    * patch 2: made depend on perl.h.
  1232.    * 
  1233. ***************
  1234. *** 107,113 ****
  1235.       compex->subbase = Nullch;
  1236.   }
  1237.   
  1238. - #ifdef NOTUSED
  1239.   void
  1240.   free_compex(compex)
  1241.   register COMPEX *compex;
  1242. --- 110,115 ----
  1243. ***************
  1244. *** 121,127 ****
  1245.       compex->subbase = Nullch;
  1246.       }
  1247.   }
  1248. - #endif
  1249.   
  1250.   static char *gbr_str = Nullch;
  1251.   static int gbr_siz = 0;
  1252. --- 123,128 ----
  1253.  
  1254. Index: stab.c
  1255. Prereq: 1.0
  1256. *** stab.c.old    Thu Jan 28 11:17:44 1988
  1257. --- stab.c    Thu Jan 28 11:17:45 1988
  1258. ***************
  1259. *** 1,6 ****
  1260. ! /* $Header: stab.c,v 1.0 87/12/18 13:06:14 root Exp $
  1261.    *
  1262.    * $Log:    stab.c,v $
  1263.    * Revision 1.0  87/12/18  13:06:14  root
  1264.    * Initial revision
  1265.    * 
  1266. --- 1,9 ----
  1267. ! /* $Header: stab.c,v 1.0.1.1 88/01/28 10:35:17 root Exp $
  1268.    *
  1269.    * $Log:    stab.c,v $
  1270. +  * Revision 1.0.1.1  88/01/28  10:35:17  root
  1271. +  * patch8: changed some stabents to support eval operator.
  1272. +  * 
  1273.    * Revision 1.0  87/12/18  13:06:14  root
  1274.    * Initial revision
  1275.    * 
  1276. ***************
  1277. *** 169,180 ****
  1278.       case '^':
  1279.           safefree(curoutstab->stab_io->top_name);
  1280.           curoutstab->stab_io->top_name = str_get(str);
  1281. !         curoutstab->stab_io->top_stab = stabent(str_get(str),FALSE);
  1282.           break;
  1283.       case '~':
  1284.           safefree(curoutstab->stab_io->fmt_name);
  1285.           curoutstab->stab_io->fmt_name = str_get(str);
  1286. !         curoutstab->stab_io->fmt_stab = stabent(str_get(str),FALSE);
  1287.           break;
  1288.       case '=':
  1289.           curoutstab->stab_io->page_len = (long)str_gnum(str);
  1290. --- 172,183 ----
  1291.       case '^':
  1292.           safefree(curoutstab->stab_io->top_name);
  1293.           curoutstab->stab_io->top_name = str_get(str);
  1294. !         curoutstab->stab_io->top_stab = stabent(str_get(str),TRUE);
  1295.           break;
  1296.       case '~':
  1297.           safefree(curoutstab->stab_io->fmt_name);
  1298.           curoutstab->stab_io->fmt_name = str_get(str);
  1299. !         curoutstab->stab_io->fmt_stab = stabent(str_get(str),TRUE);
  1300.           break;
  1301.       case '=':
  1302.           curoutstab->stab_io->page_len = (long)str_gnum(str);
  1303. ***************
  1304. *** 274,280 ****
  1305.       ARRAY *savearray;
  1306.       STR *str;
  1307.   
  1308. !     stab = stabent(str_get(hfetch(sigstab->stab_hash,sig_name[sig])),FALSE);
  1309.       savearray = defstab->stab_array;
  1310.       defstab->stab_array = anew();
  1311.       str = str_new(0);
  1312. --- 277,283 ----
  1313.       ARRAY *savearray;
  1314.       STR *str;
  1315.   
  1316. !     stab = stabent(str_get(hfetch(sigstab->stab_hash,sig_name[sig])),TRUE);
  1317.       savearray = defstab->stab_array;
  1318.       defstab->stab_array = anew();
  1319.       str = str_new(0);
  1320.  
  1321. Index: util.c
  1322. Prereq: 1.0
  1323. *** util.c.old    Thu Jan 28 11:18:10 1988
  1324. --- util.c    Thu Jan 28 11:18:10 1988
  1325. ***************
  1326. *** 1,6 ****
  1327. ! /* $Header: util.c,v 1.0 87/12/18 13:06:30 root Exp $
  1328.    *
  1329.    * $Log:    util.c,v $
  1330.    * Revision 1.0  87/12/18  13:06:30  root
  1331.    * Initial revision
  1332.    * 
  1333. --- 1,9 ----
  1334. ! /* $Header: util.c,v 1.0.1.1 88/01/28 11:06:35 root Exp $
  1335.    *
  1336.    * $Log:    util.c,v $
  1337. +  * Revision 1.0.1.1  88/01/28  11:06:35  root
  1338. +  * patch8: changed fatal() to support eval operator with exiting.
  1339. +  * 
  1340.    * Revision 1.0  87/12/18  13:06:30  root
  1341.    * Initial revision
  1342.    * 
  1343. ***************
  1344. *** 205,210 ****
  1345. --- 208,218 ----
  1346.       extern FILE *e_fp;
  1347.       extern char *e_tmpname;
  1348.   
  1349. +     if (in_eval) {
  1350. +     sprintf(tokenbuf,pat,a1,a2,a3,a4);
  1351. +     str_set(stabent("@",TRUE)->stab_val,tokenbuf);
  1352. +     longjmp(eval_env,1);
  1353. +     }
  1354.       fprintf(stderr,pat,a1,a2,a3,a4);
  1355.       if (e_fp)
  1356.       UNLINK(e_tmpname);
  1357.  
  1358. Index: x2p/walk.c
  1359. Prereq: 1.0
  1360. *** x2p/walk.c.old    Thu Jan 28 11:18:25 1988
  1361. --- x2p/walk.c    Thu Jan 28 11:18:26 1988
  1362. ***************
  1363. *** 1,6 ****
  1364. ! /* $Header: walk.c,v 1.0 87/12/18 13:07:40 root Exp $
  1365.    *
  1366.    * $Log:    walk.c,v $
  1367.    * Revision 1.0  87/12/18  13:07:40  root
  1368.    * Initial revision
  1369.    * 
  1370. --- 1,9 ----
  1371. ! /* $Header: walk.c,v 1.0.1.1 88/01/28 11:07:56 root Exp $
  1372.    *
  1373.    * $Log:    walk.c,v $
  1374. +  * Revision 1.0.1.1  88/01/28  11:07:56  root
  1375. +  * patch8: changed some misleading comments.
  1376. +  * 
  1377.    * Revision 1.0  87/12/18  13:07:40  root
  1378.    * Initial revision
  1379.    * 
  1380. ***************
  1381. *** 68,80 ****
  1382.           str_cat(str,"';\t\t# field separator from -F switch\n");
  1383.       }
  1384.       else if (saw_FS && !const_FS) {
  1385. !         str_cat(str,"$FS = '[ \\t\\n]+';\t\t# default field separator\n");
  1386.       }
  1387.       if (saw_OFS) {
  1388. !         str_cat(str,"$, = ' ';\t\t# default output field separator\n");
  1389.       }
  1390.       if (saw_ORS) {
  1391. !         str_cat(str,"$\\ = \"\\n\";\t\t# default output record separator\n");
  1392.       }
  1393.       if (str->str_cur > 20)
  1394.           str_cat(str,"\n");
  1395. --- 71,83 ----
  1396.           str_cat(str,"';\t\t# field separator from -F switch\n");
  1397.       }
  1398.       else if (saw_FS && !const_FS) {
  1399. !         str_cat(str,"$FS = '[ \\t\\n]+';\t\t# set field separator\n");
  1400.       }
  1401.       if (saw_OFS) {
  1402. !         str_cat(str,"$, = ' ';\t\t# set output field separator\n");
  1403.       }
  1404.       if (saw_ORS) {
  1405. !         str_cat(str,"$\\ = \"\\n\";\t\t# set output record separator\n");
  1406.       }
  1407.       if (str->str_cur > 20)
  1408.           str_cat(str,"\n");
  1409.