System: perl version 3.0 Patch #: 10 Priority: HIGH Subject: patch #9, continued Description: See patch #9. Fix: From rn, say "| patch -p -N -d DIR", where DIR is your perl source directory. Outside of rn, say "cd DIR; patch -p -N #define PATCHLEVEL 10 Index: t/base.term Prereq: 3.0 *** t/base.term.old Thu Mar 1 10:54:44 1990 --- t/base.term Thu Mar 1 10:54:46 1990 *************** *** 1,6 **** #!./perl ! # $Header: base.term,v 3.0 89/10/18 15:24:34 lwall Locked $ print "1..6\n"; --- 1,6 ---- #!./perl ! # $Header: base.term,v 3.0.1.1 90/02/28 18:31:56 lwall Locked $ print "1..6\n"; *************** *** 30,36 **** # check <> pseudoliteral open(try, "/dev/null") || (die "Can't open /dev/null."); ! if ( eq '') {print "ok 5\n";} else {print "not ok 5\n";} open(try, "../Makefile") || (die "Can't open ../Makefile."); if ( ne '') {print "ok 6\n";} else {print "not ok 6\n";} --- 30,42 ---- # check <> pseudoliteral open(try, "/dev/null") || (die "Can't open /dev/null."); ! if ( eq '') { ! print "ok 5\n"; ! } ! else { ! print "not ok 5\n"; ! die "/dev/null IS NOT A CHARACTER SPECIAL FILE!!!!\n" unless -c '/dev/null'; ! } open(try, "../Makefile") || (die "Can't open ../Makefile."); if ( ne '') {print "ok 6\n";} else {print "not ok 6\n";} Index: cmd.c Prereq: 3.0.1.4 *** cmd.c.old Thu Mar 1 10:48:45 1990 --- cmd.c Thu Mar 1 10:48:48 1990 *************** *** 1,4 **** ! /* $Header: cmd.c,v 3.0.1.4 89/12/21 19:17:41 lwall Locked $ * * Copyright (c) 1989, Larry Wall * --- 1,4 ---- ! /* $Header: cmd.c,v 3.0.1.5 90/02/28 16:38:31 lwall Locked $ * * Copyright (c) 1989, Larry Wall * *************** *** 6,11 **** --- 6,19 ---- * as specified in the README file that comes with the perl 3.0 kit. * * $Log: cmd.c,v $ + * Revision 3.0.1.5 90/02/28 16:38:31 lwall + * patch9: volatilized some more variables for super-optimizing compilers + * patch9: nested foreach loops didn't reset inner loop on next to outer loop + * patch9: returned values were read from obsolete stack + * patch9: added sanity check on longjmp() return value + * patch9: substitutions that almost always succeed can corrupt label stack + * patch9: subs which return by both mechanisms can clobber local return data + * * Revision 3.0.1.4 89/12/21 19:17:41 lwall * patch7: arranged for certain registers to be restored after longjmp() * patch7: made nested or recursive foreach work right *************** *** 50,60 **** int cmd_exec(cmdparm,gimme,sp) CMD *VOLATILE cmdparm; ! int gimme; ! int sp; { register CMD *cmd = cmdparm; SPAT *VOLATILE oldspat; VOLATILE int oldsave; VOLATILE int aryoptsave; #ifdef DEBUGGING --- 58,69 ---- int cmd_exec(cmdparm,gimme,sp) CMD *VOLATILE cmdparm; ! VOLATILE int gimme; ! VOLATILE int sp; { register CMD *cmd = cmdparm; SPAT *VOLATILE oldspat; + VOLATILE int firstsave = savestack->ary_fill; VOLATILE int oldsave; VOLATILE int aryoptsave; #ifdef DEBUGGING *************** *** 178,189 **** cmdparm = cmd; #endif if (match = setjmp(loop_stack[loop_ptr].loop_env)) { - #ifdef JMPCLOBBER st = stack->ary_array; /* possibly reallocated */ cmd = cmdparm; cmdflags = cmd->c_flags|CF_ONCE; #endif switch (match) { case O_LAST: /* not done unless go_to found */ go_to = Nullch; if (lastretstr) { --- 187,202 ---- cmdparm = cmd; #endif if (match = setjmp(loop_stack[loop_ptr].loop_env)) { st = stack->ary_array; /* possibly reallocated */ + #ifdef JMPCLOBBER cmd = cmdparm; cmdflags = cmd->c_flags|CF_ONCE; #endif + if (savestack->ary_fill > oldsave) + restorelist(oldsave); switch (match) { + default: + fatal("longjmp returned bad value (%d)",match); case O_LAST: /* not done unless go_to found */ go_to = Nullch; if (lastretstr) { *************** *** 198,205 **** olddlevel = dlevel; #endif curspat = oldspat; - if (savestack->ary_fill > oldsave) - restorelist(oldsave); goto next_cmd; case O_NEXT: /* not done unless go_to found */ go_to = Nullch; --- 211,216 ---- *************** *** 450,456 **** } } if (--cmd->c_short->str_u.str_useful < 0) { ! cmdflags &= ~CF_OPTIMIZE; cmdflags |= CFT_EVAL; /* never try this optimization again */ cmd->c_flags = cmdflags; } --- 461,467 ---- } } if (--cmd->c_short->str_u.str_useful < 0) { ! cmdflags &= ~(CF_OPTIMIZE|CF_ONCE); cmdflags |= CFT_EVAL; /* never try this optimization again */ cmd->c_flags = cmdflags; } *************** *** 563,570 **** savesptr(&stab_val(cmd->c_stab)); savelong(&cmd->c_short->str_u.str_useful); } ! else ar = stab_xarray(cmd->c_expr[1].arg_ptr.arg_stab); if (match >= ar->ary_fill) { /* we're in LAST, probably */ retstr = &str_undef; --- 574,584 ---- savesptr(&stab_val(cmd->c_stab)); savelong(&cmd->c_short->str_u.str_useful); } ! else { ar = stab_xarray(cmd->c_expr[1].arg_ptr.arg_stab); + if (cmd->c_type != C_WHILE && savestack->ary_fill > firstsave) + restorelist(firstsave); + } if (match >= ar->ary_fill) { /* we're in LAST, probably */ retstr = &str_undef; *************** *** 753,765 **** cmdparm = cmd; #endif if (match = setjmp(loop_stack[loop_ptr].loop_env)) { - #ifdef JMPCLOBBER st = stack->ary_array; /* possibly reallocated */ cmd = cmdparm; cmdflags = cmd->c_flags|CF_ONCE; go_to = goto_targ; #endif switch (match) { case O_LAST: if (lastretstr) { retstr = lastretstr; --- 767,783 ---- cmdparm = cmd; #endif if (match = setjmp(loop_stack[loop_ptr].loop_env)) { st = stack->ary_array; /* possibly reallocated */ + #ifdef JMPCLOBBER cmd = cmdparm; cmdflags = cmd->c_flags|CF_ONCE; go_to = goto_targ; #endif + if (savestack->ary_fill > oldsave) + restorelist(oldsave); switch (match) { + default: + fatal("longjmp returned bad value (%d)",match); case O_LAST: if (lastretstr) { retstr = lastretstr; *************** *** 770,777 **** retstr = st[newsp]; } curspat = oldspat; - if (savestack->ary_fill > oldsave) - restorelist(oldsave); goto next_cmd; case O_NEXT: #ifdef JMPCLOBBER --- 788,793 ---- *************** *** 831,838 **** } finish_while: curspat = oldspat; ! if (savestack->ary_fill > oldsave) restorelist(oldsave); #ifdef DEBUGGING dlevel = olddlevel - 1; #endif --- 847,860 ---- } finish_while: curspat = oldspat; ! if (savestack->ary_fill > oldsave) { ! if (cmdflags & CF_TERM) { ! for (match = sp + 1; match <= newsp; match++) ! st[match] = str_static(st[match]); ! retstr = st[newsp]; ! } restorelist(oldsave); + } #ifdef DEBUGGING dlevel = olddlevel - 1; #endif *************** *** 855,861 **** } #endif loop_ptr--; ! if ((cmdflags & CF_OPTIMIZE) == CFT_ARRAY) restorelist(aryoptsave); } cmd = cmd->c_next; --- 877,884 ---- } #endif loop_ptr--; ! if ((cmdflags & CF_OPTIMIZE) == CFT_ARRAY && ! savestack->ary_fill > aryoptsave) restorelist(aryoptsave); } cmd = cmd->c_next; Index: cmd.h Prereq: 3.0.1.1 *** cmd.h.old Thu Mar 1 10:48:53 1990 --- cmd.h Thu Mar 1 10:48:55 1990 *************** *** 1,4 **** ! /* $Header: cmd.h,v 3.0.1.1 89/10/26 23:05:43 lwall Locked $ * * Copyright (c) 1989, Larry Wall * --- 1,4 ---- ! /* $Header: cmd.h,v 3.0.1.2 90/02/28 16:39:36 lwall Locked $ * * Copyright (c) 1989, Larry Wall * *************** *** 6,11 **** --- 6,14 ---- * as specified in the README file that comes with the perl 3.0 kit. * * $Log: cmd.h,v $ + * Revision 3.0.1.2 90/02/28 16:39:36 lwall + * patch9: volatilized some more variables for super-optimizing compilers + * * Revision 3.0.1.1 89/10/26 23:05:43 lwall * patch1: unless was broken when run under the debugger * *************** *** 127,133 **** struct scmd scmd; /* switch command */ } ucmd; short c_slen; /* len of c_short, if not null */ ! short c_flags; /* optimization flags--see above */ char *c_file; /* file the following line # is from */ line_t c_line; /* line # of this command */ char c_type; /* what this command does */ --- 130,136 ---- struct scmd scmd; /* switch command */ } ucmd; short c_slen; /* len of c_short, if not null */ ! VOLATILE short c_flags; /* optimization flags--see above */ char *c_file; /* file the following line # is from */ line_t c_line; /* line # of this command */ char c_type; /* what this command does */ *************** *** 135,142 **** #define Nullcmd Null(CMD*) ! EXT CMD *main_root INIT(Nullcmd); ! EXT CMD *eval_root INIT(Nullcmd); struct compcmd { CMD *comp_true; --- 138,145 ---- #define Nullcmd Null(CMD*) ! EXT CMD * VOLATILE main_root INIT(Nullcmd); ! EXT CMD * VOLATILE eval_root INIT(Nullcmd); struct compcmd { CMD *comp_true; Index: lib/complete.pl *** lib/complete.pl.old Thu Mar 1 10:51:47 1990 --- lib/complete.pl Thu Mar 1 10:51:49 1990 *************** *** 25,30 **** --- 25,31 ---- local ($prompt) = shift (@_); local ($c, $cmp, $l, $r, $ret, $return, $test); @_cmp_lst = sort @_; + local($[) = 0; system 'stty raw -echo'; loop: { print $prompt, $return; Index: config.h.SH *** config.h.SH.old Thu Mar 1 10:49:02 1990 --- config.h.SH Thu Mar 1 10:49:05 1990 *************** *** 422,427 **** --- 422,433 ---- */ #$d_voidsig VOIDSIG /**/ + /* HASVOLATILE: + * This symbol, if defined, indicates that this C compiler knows about + * the volatile declaration. + */ + #$d_volatile HASVOLATILE /**/ + /* VPRINTF: * This symbol, if defined, indicates that the vprintf routine is available * to printf with a pointer to an argument list. If unavailable, you *************** *** 542,548 **** /* I_UTIME: * This symbol, if defined, indicates to the C program that it should ! * include utime.h (a DG/UX thingie). */ #$i_utime I_UTIME /**/ --- 548,554 ---- /* I_UTIME: * This symbol, if defined, indicates to the C program that it should ! * include utime.h. */ #$i_utime I_UTIME /**/ Index: cons.c Prereq: 3.0.1.3 *** cons.c.old Thu Mar 1 10:49:15 1990 --- cons.c Thu Mar 1 10:49:17 1990 *************** *** 1,4 **** ! /* $Header: cons.c,v 3.0.1.3 89/12/21 19:20:25 lwall Locked $ * * Copyright (c) 1989, Larry Wall * --- 1,4 ---- ! /* $Header: cons.c,v 3.0.1.4 90/02/28 16:44:00 lwall Locked $ * * Copyright (c) 1989, Larry Wall * *************** *** 6,11 **** --- 6,16 ---- * as specified in the README file that comes with the perl 3.0 kit. * * $Log: cons.c,v $ + * Revision 3.0.1.4 90/02/28 16:44:00 lwall + * patch9: subs which return by both mechanisms can clobber local return data + * patch9: changed internal SUB label to _SUB_ + * patch9: line numbers were bogus during certain portions of foreach evaluation + * * Revision 3.0.1.3 89/12/21 19:20:25 lwall * patch7: made nested or recursive foreach work right * *************** *** 67,74 **** mycompblock.comp_true = cmd; mycompblock.comp_alt = Nullcmd; ! cmd = add_label(savestr("SUB"),make_ccmd(C_BLOCK,Nullarg,mycompblock)); saw_return = FALSE; } sub->cmd = cmd; stab_sub(stab) = sub; --- 72,83 ---- mycompblock.comp_true = cmd; mycompblock.comp_alt = Nullcmd; ! cmd = add_label(savestr("_SUB_"),make_ccmd(C_BLOCK,Nullarg,mycompblock)); saw_return = FALSE; + if (perldb) + cmd->c_next->c_flags |= CF_TERM; + else + cmd->c_flags |= CF_TERM; } sub->cmd = cmd; stab_sub(stab) = sub; *************** *** 412,418 **** cmd->c_expr = cond; if (cond) cmd->c_flags |= CF_COND; ! if (cmdline != NOLINE) { cmd->c_line = cmdline; cmdline = NOLINE; } --- 421,429 ---- cmd->c_expr = cond; if (cond) cmd->c_flags |= CF_COND; ! if (cmdline == NOLINE) ! cmd->c_line = line; ! else { cmd->c_line = cmdline; cmdline = NOLINE; } *************** *** 437,443 **** cmd->ucmd.ccmd.cc_alt = cblock.comp_alt; if (arg) cmd->c_flags |= CF_COND; ! if (cmdline != NOLINE) { cmd->c_line = cmdline; cmdline = NOLINE; } --- 448,456 ---- cmd->ucmd.ccmd.cc_alt = cblock.comp_alt; if (arg) cmd->c_flags |= CF_COND; ! if (cmdline == NOLINE) ! cmd->c_line = line; ! else { cmd->c_line = cmdline; cmdline = NOLINE; } *************** *** 466,472 **** cmd->ucmd.ccmd.cc_alt = cblock.comp_alt; if (arg) cmd->c_flags |= CF_COND; ! if (cmdline != NOLINE) { cmd->c_line = cmdline; cmdline = NOLINE; } --- 479,487 ---- cmd->ucmd.ccmd.cc_alt = cblock.comp_alt; if (arg) cmd->c_flags |= CF_COND; ! if (cmdline == NOLINE) ! cmd->c_line = line; ! else { cmd->c_line = cmdline; cmdline = NOLINE; } Index: consarg.c Prereq: 3.0.1.2 *** consarg.c.old Thu Mar 1 10:49:25 1990 --- consarg.c Thu Mar 1 10:49:27 1990 *************** *** 1,4 **** ! /* $Header: consarg.c,v 3.0.1.2 89/11/17 15:11:34 lwall Locked $ * * Copyright (c) 1989, Larry Wall * --- 1,4 ---- ! /* $Header: consarg.c,v 3.0.1.3 90/02/28 16:47:54 lwall Locked $ * * Copyright (c) 1989, Larry Wall * *************** *** 6,11 **** --- 6,15 ---- * as specified in the README file that comes with the perl 3.0 kit. * * $Log: consarg.c,v $ + * Revision 3.0.1.3 90/02/28 16:47:54 lwall + * patch9: the x operator is now up to 10 times faster + * patch9: @_ clobbered by ($foo,$bar) = split + * * Revision 3.0.1.2 89/11/17 15:11:34 lwall * patch5: defined $foo{'bar'} should not create element * *************** *** 312,320 **** break; case O_REPEAT: i = (int)str_gnum(s2); str_nset(str,"",0); ! while (i-- > 0) ! str_scat(str,s1); break; case O_MULTIPLY: value = str_gnum(s1); --- 316,327 ---- break; case O_REPEAT: i = (int)str_gnum(s2); + tmps = str_get(s1); str_nset(str,"",0); ! STR_GROW(str, i * s1->str_cur + 1); ! repeatcpy(str->str_ptr, tmps, s1->str_cur, i); ! str->str_cur = i * s1->str_cur; ! str->str_ptr[str->str_cur] = '\0'; break; case O_MULTIPLY: value = str_gnum(s1); *************** *** 648,657 **** arg2 = arg[2].arg_ptr.arg_arg; if (arg2->arg_type == O_SPLIT) { /* use split's builtin =?*/ spat = arg2[2].arg_ptr.arg_spat; ! if (spat->spat_repl[1].arg_ptr.arg_stab == defstab && nothing_in_common(arg1,spat->spat_repl)) { spat->spat_repl[1].arg_ptr.arg_stab = arg1[1].arg_ptr.arg_stab; arg_free(arg1); /* recursive */ free_arg(arg); /* non-recursive */ return arg2; /* split has builtin assign */ --- 655,665 ---- arg2 = arg[2].arg_ptr.arg_arg; if (arg2->arg_type == O_SPLIT) { /* use split's builtin =?*/ spat = arg2[2].arg_ptr.arg_spat; ! if (!(spat->spat_flags & SPAT_ONCE) && nothing_in_common(arg1,spat->spat_repl)) { spat->spat_repl[1].arg_ptr.arg_stab = arg1[1].arg_ptr.arg_stab; + spat->spat_flags |= SPAT_ONCE; arg_free(arg1); /* recursive */ free_arg(arg); /* non-recursive */ return arg2; /* split has builtin assign */ Index: doarg.c Prereq: 3.0.1.2 *** doarg.c.old Thu Mar 1 10:49:38 1990 --- doarg.c Thu Mar 1 10:49:42 1990 *************** *** 1,4 **** ! /* $Header: doarg.c,v 3.0.1.2 89/12/21 19:52:15 lwall Locked $ * * Copyright (c) 1989, Larry Wall * --- 1,4 ---- ! /* $Header: doarg.c,v 3.0.1.3 90/02/28 16:56:58 lwall Locked $ * * Copyright (c) 1989, Larry Wall * *************** *** 6,11 **** --- 6,20 ---- * as specified in the README file that comes with the perl 3.0 kit. * * $Log: doarg.c,v $ + * Revision 3.0.1.3 90/02/28 16:56:58 lwall + * patch9: split now can split into more than 10000 elements + * patch9: sped up pack and unpack + * patch9: pack of unsigned ints and longs blew up some places + * patch9: sun3 can't cast negative float to unsigned int or long + * patch9: local($.) didn't work + * patch9: grep(s/foo/bar/, @abc = @xyz) modified @xyz rather than @abc + * patch9: syscall returned stack size rather than value of system call + * * Revision 3.0.1.2 89/12/21 19:52:15 lwall * patch7: a pattern wouldn't match a null string before the first character * patch7: certain patterns didn't match correctly at end of string *************** *** 44,49 **** --- 53,59 ---- register char *d; int clen; int iters = 0; + int maxiters = (strend - s) + 10; register int i; bool once; char *orig; *************** *** 192,198 **** /* NOTREACHED */ } do { ! if (iters++ > 10000) fatal("Substitution loop"); m = spat->spat_regexp->startp[0]; if (i = m - s) { --- 202,208 ---- /* NOTREACHED */ } do { ! if (iters++ > maxiters) fatal("Substitution loop"); m = spat->spat_regexp->startp[0]; if (i = m - s) { *************** *** 233,239 **** curspat = spat; lastspat = spat; do { ! if (iters++ > 10000) fatal("Substitution loop"); if (spat->spat_regexp->subbase && spat->spat_regexp->subbase != orig) { --- 243,249 ---- curspat = spat; lastspat = spat; do { ! if (iters++ > maxiters) fatal("Substitution loop"); if (spat->spat_regexp->subbase && spat->spat_regexp->subbase != orig) { *************** *** 351,357 **** --- 361,369 ---- char achar; short ashort; int aint; + unsigned int auint; long along; + unsigned long aulong; char *aptr; items = arglast[2] - sp; *************** *** 361,369 **** #define NEXTFROM (items-- > 0 ? *st++ : &str_no) datumtype = *pat++; if (isdigit(*pat)) { ! len = atoi(pat); while (isdigit(*pat)) ! pat++; } else len = 1; --- 373,381 ---- #define NEXTFROM (items-- > 0 ? *st++ : &str_no) datumtype = *pat++; if (isdigit(*pat)) { ! len = *pat++ - '0'; while (isdigit(*pat)) ! len = (len * 10) + (*pat++ - '0'); } else len = 1; *************** *** 429,434 **** --- 441,452 ---- } break; case 'I': + while (len-- > 0) { + fromstr = NEXTFROM; + auint = (unsigned int)str_gnum(fromstr); + str_ncat(str,(char*)&auint,sizeof(unsigned int)); + } + break; case 'i': while (len-- > 0) { fromstr = NEXTFROM; *************** *** 447,452 **** --- 465,476 ---- } break; case 'L': + while (len-- > 0) { + fromstr = NEXTFROM; + aulong = (unsigned long)str_gnum(fromstr); + str_ncat(str,(char*)&aulong,sizeof(unsigned long)); + } + break; case 'l': while (len-- > 0) { fromstr = NEXTFROM; *************** *** 481,486 **** --- 505,511 ---- register char *send; char *xs; int xlen; + double value; str_set(str,""); len--; /* don't count pattern string */ *************** *** 547,556 **** case 'x': case 'o': case 'u': ch = *(++t); *t = '\0'; if (dolong) ! (void)sprintf(buf,s,(unsigned long)str_gnum(*(sarg++))); else ! (void)sprintf(buf,s,(unsigned int)str_gnum(*(sarg++))); s = t; *(t--) = ch; break; --- 572,591 ---- case 'x': case 'o': case 'u': ch = *(++t); *t = '\0'; + value = str_gnum(*(sarg++)); + #if defined(sun) && !defined(sparc) + if (value < 0.0) { /* sigh */ + if (dolong) + (void)sprintf(buf,s,(long)value); + else + (void)sprintf(buf,s,(int)value); + } + else + #endif if (dolong) ! (void)sprintf(buf,s,(unsigned long)value); else ! (void)sprintf(buf,s,(unsigned int)value); s = t; *(t--) = ch; break; *************** *** 798,803 **** --- 833,839 ---- int i; makelocal = (arg->arg_flags & AF_LOCAL); + localizing = makelocal; delaymagic = DM_DELAY; /* catch simultaneous items */ /* If there's a common identifier on both sides we have to take *************** *** 828,836 **** while (relem <= lastrelem) { /* gobble up all the rest */ str = Str_new(28,0); if (*relem) ! str_sset(str,*(relem++)); ! else ! relem++; (void)astore(ary,i++,str); } } --- 864,871 ---- while (relem <= lastrelem) { /* gobble up all the rest */ str = Str_new(28,0); if (*relem) ! str_sset(str,*relem); ! *(relem++) = str; (void)astore(ary,i++,str); } } *************** *** 852,860 **** tmps = str_get(str); tmpstr = Str_new(29,0); if (*relem) ! str_sset(tmpstr,*(relem++)); /* value */ ! else ! relem++; (void)hstore(hash,tmps,str->str_cur,tmpstr,0); } } --- 887,894 ---- tmps = str_get(str); tmpstr = Str_new(29,0); if (*relem) ! str_sset(tmpstr,*relem); /* value */ ! *(relem++) = tmpstr; (void)hstore(hash,tmps,str->str_cur,tmpstr,0); } } *************** *** 864,873 **** else { if (makelocal) saveitem(str); ! if (relem <= lastrelem) ! str_sset(str, *(relem++)); ! else str_nset(str, "", 0); STABSET(str); } } --- 898,923 ---- else { if (makelocal) saveitem(str); ! if (relem <= lastrelem) { ! str_sset(str, *relem); ! *(relem++) = str; ! } ! else { str_nset(str, "", 0); + if (gimme == G_ARRAY) { + i = ++lastrelem - firstrelem; + relem++; /* tacky, I suppose */ + astore(stack,i,str); + if (st != stack->ary_array) { + st = stack->ary_array; + firstrelem = st + arglast[1] + 1; + firstlelem = st + arglast[0] + 1; + lastlelem = st + arglast[1]; + lastrelem = st + i; + relem = lastrelem + 1; + } + } + } STABSET(str); } } *************** *** 882,887 **** --- 932,938 ---- #endif } delaymagic = 0; + localizing = FALSE; if (gimme == G_ARRAY) { i = lastrelem - firstrelem + 1; if (ary || hash) *************** *** 1283,1291 **** arg[7]); break; } ! st[sp] = str_static(&str_undef); ! str_numset(st[sp], (double)retval); ! return sp; #else fatal("syscall() unimplemented"); #endif --- 1334,1340 ---- arg[7]); break; } ! return retval; #else fatal("syscall() unimplemented"); #endif Index: doio.c Prereq: 3.0.1.4 *** doio.c.old Thu Mar 1 10:49:56 1990 --- doio.c Thu Mar 1 10:50:03 1990 *************** *** 1,4 **** ! /* $Header: doio.c,v 3.0.1.4 89/12/21 19:55:10 lwall Locked $ * * Copyright (c) 1989, Larry Wall * --- 1,4 ---- ! /* $Header: doio.c,v 3.0.1.5 90/02/28 17:01:36 lwall Locked $ * * Copyright (c) 1989, Larry Wall * *************** *** 6,11 **** --- 6,17 ---- * as specified in the README file that comes with the perl 3.0 kit. * * $Log: doio.c,v $ + * Revision 3.0.1.5 90/02/28 17:01:36 lwall + * patch9: open(FOO,"$filename\0") will now protect trailing spaces in filename + * patch9: removed obsolete checks to avoid opening block devices + * patch9: removed references to acusec and modusec that some utime.h's have + * patch9: added pipe function + * * Revision 3.0.1.4 89/12/21 19:55:10 lwall * patch7: select now works on big-endian machines * patch7: errno may now be a macro with an lvalue *************** *** 53,64 **** #endif bool ! do_open(stab,name) STAB *stab; register char *name; { FILE *fp; - int len = strlen(name); register STIO *stio = stab_io(stab); char *myname = savestr(name); int result; --- 59,70 ---- #endif bool ! do_open(stab,name,len) STAB *stab; register char *name; + int len; { FILE *fp; register STIO *stio = stab_io(stab); char *myname = savestr(name); int result; *************** *** 202,223 **** return FALSE; } result = (statbuf.st_mode & S_IFMT); - if (result != S_IFREG && #ifdef S_IFSOCK - result != S_IFSOCK && - #endif - #ifdef S_IFFIFO - result != S_IFFIFO && - #endif - #ifdef S_IFIFO - result != S_IFIFO && - #endif - result != 0 && /* socket? */ - result != S_IFCHR) { - (void)fclose(fp); - return FALSE; - } - #ifdef S_IFSOCK if (result == S_IFSOCK || result == 0) stio->type = 's'; /* in case a socket was passed in to us */ #endif --- 208,214 ---- *************** *** 250,256 **** str_sset(stab_val(stab),str); STABSET(stab_val(stab)); oldname = str_get(stab_val(stab)); ! if (do_open(stab,oldname)) { if (inplace) { #ifdef TAINT taintproper("Insecure dependency in inplace open"); --- 241,247 ---- str_sset(stab_val(stab),str); STABSET(stab_val(stab)); oldname = str_get(stab_val(stab)); ! if (do_open(stab,oldname,stab_val(stab)->str_cur)) { if (inplace) { #ifdef TAINT taintproper("Insecure dependency in inplace open"); *************** *** 275,281 **** str_nset(str,">",1); str_cat(str,oldname); errno = 0; /* in case sprintf set errno */ ! if (!do_open(argvoutstab,str->str_ptr)) fatal("Can't do inplace edit"); defoutstab = argvoutstab; #ifdef FCHMOD --- 266,272 ---- str_nset(str,">",1); str_cat(str,oldname); errno = 0; /* in case sprintf set errno */ ! if (!do_open(argvoutstab,str->str_ptr,str->str_cur)) fatal("Can't do inplace edit"); defoutstab = argvoutstab; #ifdef FCHMOD *************** *** 303,308 **** --- 294,342 ---- return Nullfp; } + void + do_pipe(str, rstab, wstab) + STR *str; + STAB *rstab; + STAB *wstab; + { + register STIO *rstio; + register STIO *wstio; + int fd[2]; + + if (!rstab) + goto badexit; + if (!wstab) + goto badexit; + + rstio = stab_io(rstab); + wstio = stab_io(wstab); + + if (!rstio) + rstio = stab_io(rstab) = stio_new(); + else if (rstio->ifp) + do_close(rstab,FALSE); + if (!wstio) + wstio = stab_io(wstab) = stio_new(); + else if (wstio->ifp) + do_close(wstab,FALSE); + + if (pipe(fd) < 0) + goto badexit; + rstio->ifp = fdopen(fd[0], "r"); + wstio->ofp = fdopen(fd[1], "w"); + wstio->ifp = wstio->ofp; + rstio->type = '<'; + wstio->type = '>'; + + str_sset(str,&str_yes); + return; + + badexit: + str_sset(str,&str_undef); + return; + } + bool do_close(stab,explicit) STAB *stab; *************** *** 1991,2002 **** } utbuf; #endif utbuf.actime = (long)str_gnum(st[++sp]); /* time accessed */ utbuf.modtime = (long)str_gnum(st[++sp]); /* time modified */ - #ifdef I_UTIME - utbuf.acusec = 0; /* hopefully I_UTIME implies these */ - utbuf.modusec = 0; - #endif items -= 2; #ifndef lint tot = items; --- 2025,2033 ---- } utbuf; #endif + Zero(&utbuf, sizeof utbuf, char); utbuf.actime = (long)str_gnum(st[++sp]); /* time accessed */ utbuf.modtime = (long)str_gnum(st[++sp]); /* time modified */ items -= 2; #ifndef lint tot = items; Index: dolist.c Prereq: 3.0.1.4 *** dolist.c.old Thu Mar 1 10:50:18 1990 --- dolist.c Thu Mar 1 10:50:21 1990 *************** *** 1,4 **** ! /* $Header: dolist.c,v 3.0.1.4 89/12/21 19:58:46 lwall Locked $ * * Copyright (c) 1989, Larry Wall * --- 1,4 ---- ! /* $Header: dolist.c,v 3.0.1.5 90/02/28 17:09:44 lwall Locked $ * * Copyright (c) 1989, Larry Wall * *************** *** 6,11 **** --- 6,20 ---- * as specified in the README file that comes with the perl 3.0 kit. * * $Log: dolist.c,v $ + * Revision 3.0.1.5 90/02/28 17:09:44 lwall + * patch9: split now can split into more than 10000 elements + * patch9: @_ clobbered by ($foo,$bar) = split + * patch9: sped up pack and unpack + * patch9: unpack of single item now works in a scalar context + * patch9: slices ignored value of $[ + * patch9: grep now returns number of items matched in scalar context + * patch9: grep iterations no longer in the regexp context of previous iteration + * * Revision 3.0.1.4 89/12/21 19:58:46 lwall * patch7: grep(1,@array) didn't work * patch7: /$pat/; //; wrongly freed runtime pattern twice *************** *** 264,269 **** --- 273,279 ---- register STR *dstr; register char *m; int iters = 0; + int maxiters = (strend - s) + 10; int i; char *orig; int origlimit = limit; *************** *** 299,305 **** } #endif ary = stab_xarray(spat->spat_repl[1].arg_ptr.arg_stab); ! if (ary && ((ary->ary_flags & ARF_REAL) || gimme != G_ARRAY)) { realarray = 1; if (!(ary->ary_flags & ARF_REAL)) { ary->ary_flags |= ARF_REAL; --- 309,315 ---- } #endif ary = stab_xarray(spat->spat_repl[1].arg_ptr.arg_stab); ! if (ary && (gimme != G_ARRAY || (spat->spat_flags & SPAT_ONCE))) { realarray = 1; if (!(ary->ary_flags & ARF_REAL)) { ary->ary_flags |= ARF_REAL; *************** *** 317,323 **** s++; } if (!limit) ! limit = 10001; if (spat->spat_short) { i = spat->spat_short->str_cur; if (i == 1) { --- 327,333 ---- s++; } if (!limit) ! limit = maxiters + 2; if (spat->spat_short) { i = spat->spat_short->str_cur; if (i == 1) { *************** *** 353,358 **** --- 363,369 ---- } } else { + maxiters += (strend - s) * spat->spat_regexp->nparens; while (s < strend && --limit && regexec(spat->spat_regexp, s, strend, orig, 1, Nullstr, TRUE) ) { if (spat->spat_regexp->subbase *************** *** 389,395 **** iters = sp + 1; else iters = sp - arglast[0]; ! if (iters > 9999) fatal("Split loop"); if (s < strend || origlimit) { /* keep field after final delim? */ if (realarray) --- 400,406 ---- iters = sp + 1; else iters = sp - arglast[0]; ! if (iters > maxiters) fatal("Split loop"); if (s < strend || origlimit) { /* keep field after final delim? */ if (realarray) *************** *** 468,486 **** unsigned long aulong; char *aptr; ! if (gimme != G_ARRAY) { ! str_sset(str,&str_undef); ! STABSET(str); ! st[sp] = str; ! return sp; } sp--; while (pat < patend) { datumtype = *pat++; if (isdigit(*pat)) { ! len = atoi(pat); while (isdigit(*pat)) ! pat++; } else len = 1; --- 479,498 ---- unsigned long aulong; char *aptr; ! if (gimme != G_ARRAY) { /* arrange to do first one only */ ! patend = pat+1; ! if (*pat == 'a' || *pat == 'A') { ! while (isdigit(*patend)) ! patend++; ! } } sp--; while (pat < patend) { datumtype = *pat++; if (isdigit(*pat)) { ! len = *pat++ - '0'; while (isdigit(*pat)) ! len = (len * 10) + (*pat++ - '0'); } else len = 1; *************** *** 675,682 **** if (numarray) { while (sp < max) { if (st[++sp]) { ! st[sp-1] = afetch(stab_array(stab),(int)str_gnum(st[sp]), ! lval); } else st[sp-1] = &str_undef; --- 687,694 ---- if (numarray) { while (sp < max) { if (st[++sp]) { ! st[sp-1] = afetch(stab_array(stab), ! ((int)str_gnum(st[sp])) - arybase, lval); } else st[sp-1] = &str_undef; *************** *** 700,706 **** else { if (numarray) { if (st[max]) ! st[sp] = afetch(stab_array(stab),(int)str_gnum(st[max]), lval); else st[sp] = &str_undef; } --- 712,719 ---- else { if (numarray) { if (st[max]) ! st[sp] = afetch(stab_array(stab), ! ((int)str_gnum(st[max])) - arybase, lval); else st[sp] = &str_undef; } *************** *** 732,737 **** --- 745,751 ---- register int sp = arglast[2]; register int i = sp - arglast[1]; int oldsave = savestack->ary_fill; + SPAT *oldspat = curspat; savesptr(&stab_val(defstab)); if ((arg[1].arg_type & A_MASK) != A_EXPR) { *************** *** 747,756 **** if (str_true(st[sp+1])) st[dst++] = st[src]; src++; } restorelist(oldsave); if (gimme != G_ARRAY) { ! str_sset(str,&str_undef); STABSET(str); st[arglast[0]+1] = str; return arglast[0]+1; --- 761,771 ---- if (str_true(st[sp+1])) st[dst++] = st[src]; src++; + curspat = oldspat; } restorelist(oldsave); if (gimme != G_ARRAY) { ! str_numset(str,(double)(dst - arglast[1])); STABSET(str); st[arglast[0]+1] = str; return arglast[0]+1; Index: eval.c Prereq: 3.0.1.3 *** eval.c.old Thu Mar 1 10:51:08 1990 --- eval.c Thu Mar 1 10:51:15 1990 *************** *** 1,4 **** ! /* $Header: eval.c,v 3.0.1.3 89/12/21 20:03:05 lwall Locked $ * * Copyright (c) 1989, Larry Wall * --- 1,4 ---- ! /* $Header: eval.c,v 3.0.1.4 90/02/28 17:36:59 lwall Locked $ * * Copyright (c) 1989, Larry Wall * *************** *** 6,11 **** --- 6,23 ---- * as specified in the README file that comes with the perl 3.0 kit. * * $Log: eval.c,v $ + * Revision 3.0.1.4 90/02/28 17:36:59 lwall + * patch9: added pipe function + * patch9: a return in scalar context wouldn't return array + * patch9: !~ now always returns scalar even in array context + * patch9: some machines can't cast float to long with high bit set + * patch9: piped opens returned undef in child + * patch9: @array in scalar context now returns length of array + * patch9: chdir; coredumped + * patch9: wait no longer ignores signals + * patch9: mkdir now handles odd versions of /bin/mkdir + * patch9: -l FILEHANDLE now disallowed + * * Revision 3.0.1.3 89/12/21 20:03:05 lwall * patch7: errno may now be a macro with an lvalue * patch7: ANSI strerror() is now supported *************** *** 48,53 **** --- 60,66 ---- static STIO *stio; static struct lstring *lstr; static char old_record_separator; + extern int wantarray; double sin(), cos(), atan2(), pow(); *************** *** 141,150 **** STR_SSET(str,st[1]); anum = (int)str_gnum(st[2]); if (anum >= 1) { ! tmpstr = Str_new(50,0); str_sset(tmpstr,str); ! while (--anum > 0) ! str_scat(str,tmpstr); } else str_sset(str,&str_no); --- 154,165 ---- STR_SSET(str,st[1]); anum = (int)str_gnum(st[2]); if (anum >= 1) { ! tmpstr = Str_new(50, 0); str_sset(tmpstr,str); ! tmps = str_get(tmpstr); /* force to be string */ ! STR_GROW(str, (anum * str->str_cur) + 1); ! repeatcpy(str->str_ptr, tmps, tmpstr->str_cur, anum); ! str->str_cur *= anum; str->str_ptr[str->str_cur] = '\0'; } else str_sset(str,&str_no); *************** *** 159,167 **** break; case O_NMATCH: sp = do_match(str,arg, ! gimme,arglast); ! if (gimme == G_ARRAY) ! goto array_return; str_sset(str, str_true(str) ? &str_no : &str_yes); STABSET(str); break; --- 174,180 ---- break; case O_NMATCH: sp = do_match(str,arg, ! G_SCALAR,arglast); str_sset(str, str_true(str) ? &str_no : &str_yes); STABSET(str); break; *************** *** 270,276 **** value = str_gnum(st[1]); anum = (int)str_gnum(st[2]); #ifndef lint ! value = (double)(((long)value) << anum); #endif goto donumset; case O_RIGHT_SHIFT: --- 283,289 ---- value = str_gnum(st[1]); anum = (int)str_gnum(st[2]); #ifndef lint ! value = (double)(((unsigned long)value) << anum); #endif goto donumset; case O_RIGHT_SHIFT: *************** *** 277,283 **** value = str_gnum(st[1]); anum = (int)str_gnum(st[2]); #ifndef lint ! value = (double)(((long)value) >> anum); #endif goto donumset; case O_LT: --- 290,296 ---- value = str_gnum(st[1]); anum = (int)str_gnum(st[2]); #ifndef lint ! value = (double)(((unsigned long)value) >> anum); #endif goto donumset; case O_LT: *************** *** 313,319 **** if (!sawvec || st[1]->str_nok || st[2]->str_nok) { value = str_gnum(st[1]); #ifndef lint ! value = (double)(((long)value) & (long)str_gnum(st[2])); #endif goto donumset; } --- 326,333 ---- if (!sawvec || st[1]->str_nok || st[2]->str_nok) { value = str_gnum(st[1]); #ifndef lint ! value = (double)(((unsigned long)value) & ! (unsigned long)str_gnum(st[2])); #endif goto donumset; } *************** *** 324,330 **** if (!sawvec || st[1]->str_nok || st[2]->str_nok) { value = str_gnum(st[1]); #ifndef lint ! value = (double)(((long)value) ^ (long)str_gnum(st[2])); #endif goto donumset; } --- 338,345 ---- if (!sawvec || st[1]->str_nok || st[2]->str_nok) { value = str_gnum(st[1]); #ifndef lint ! value = (double)(((unsigned long)value) ^ ! (unsigned long)str_gnum(st[2])); #endif goto donumset; } *************** *** 335,341 **** if (!sawvec || st[1]->str_nok || st[2]->str_nok) { value = str_gnum(st[1]); #ifndef lint ! value = (double)(((long)value) | (long)str_gnum(st[2])); #endif goto donumset; } --- 350,357 ---- if (!sawvec || st[1]->str_nok || st[2]->str_nok) { value = str_gnum(st[1]); #ifndef lint ! value = (double)(((unsigned long)value) | ! (unsigned long)str_gnum(st[2])); #endif goto donumset; } *************** *** 414,420 **** goto donumset; case O_COMPLEMENT: #ifndef lint ! value = (double) ~(long)str_gnum(st[1]); #endif goto donumset; case O_SELECT: --- 430,436 ---- goto donumset; case O_COMPLEMENT: #ifndef lint ! value = (double) ~(unsigned long)str_gnum(st[1]); #endif goto donumset; case O_SELECT: *************** *** 502,512 **** stab = arg[1].arg_ptr.arg_stab; else stab = stabent(str_get(st[1]),TRUE); ! if (do_open(stab,str_get(st[2]))) { value = (double)forkprocess; stab_io(stab)->lines = 0; goto donumset; } else goto say_undef; break; --- 518,531 ---- stab = arg[1].arg_ptr.arg_stab; else stab = stabent(str_get(st[1]),TRUE); ! tmps = str_get(st[2]); ! if (do_open(stab,tmps,st[2]->str_cur)) { value = (double)forkprocess; stab_io(stab)->lines = 0; goto donumset; } + else if (forkprocess == 0) /* we are a new child */ + goto say_zero; else goto say_undef; break; *************** *** 556,564 **** sp += maxarg; goto array_return; } ! else ! str = afetch(ary,maxarg - 1,FALSE); ! break; case O_AELEM: anum = ((int)str_gnum(st[2])) - arybase; str = afetch(stab_array(arg[1].arg_ptr.arg_stab),anum,FALSE); --- 575,584 ---- sp += maxarg; goto array_return; } ! else { ! value = (double)maxarg; ! goto donumset; ! } case O_AELEM: anum = ((int)str_gnum(st[2])) - arybase; str = afetch(stab_array(arg[1].arg_ptr.arg_stab),anum,FALSE); *************** *** 824,830 **** goto donumset; case O_CHDIR: if (maxarg < 1) ! tmps = str_get(stab_val(defstab)); else tmps = str_get(st[1]); if (!tmps || !*tmps) { --- 844,850 ---- goto donumset; case O_CHDIR: if (maxarg < 1) ! tmps = Nullch; else tmps = str_get(st[1]); if (!tmps || !*tmps) { *************** *** 993,1001 **** STABSET(str); break; case O_RETURN: ! tmps = "SUB"; /* just fake up a "last SUB" */ optype = O_LAST; ! if (gimme == G_ARRAY) { lastretstr = Nullstr; lastspbase = arglast[1]; lastsize = arglast[2] - arglast[1]; --- 1013,1021 ---- STABSET(str); break; case O_RETURN: ! tmps = "_SUB_"; /* just fake up a "last _SUB_" */ optype = O_LAST; ! if (wantarray == G_ARRAY) { lastretstr = Nullstr; lastspbase = arglast[1]; lastsize = arglast[2] - arglast[1]; *************** *** 1304,1320 **** goto donumset; case O_WAIT: #ifndef lint ! ihand = signal(SIGINT, SIG_IGN); ! qhand = signal(SIGQUIT, SIG_IGN); anum = wait(&argflags); if (anum > 0) pidgone(anum,argflags); value = (double)anum; #else ! ihand = qhand = 0; #endif ! (void)signal(SIGINT, ihand); ! (void)signal(SIGQUIT, qhand); statusvalue = (unsigned short)argflags; goto donumset; case O_SYSTEM: --- 1324,1340 ---- goto donumset; case O_WAIT: #ifndef lint ! /* ihand = signal(SIGINT, SIG_IGN); */ ! /* qhand = signal(SIGQUIT, SIG_IGN); */ anum = wait(&argflags); if (anum > 0) pidgone(anum,argflags); value = (double)anum; #else ! /* ihand = qhand = 0; */ #endif ! /* (void)signal(SIGINT, ihand); */ ! /* (void)signal(SIGQUIT, qhand); */ statusvalue = (unsigned short)argflags; goto donumset; case O_SYSTEM: *************** *** 1491,1496 **** --- 1511,1518 ---- errno = EEXIST; else if (instr(buf,"non-exist")) errno = ENOENT; + else if (instr(buf,"does not exist")) + errno = ENOENT; else if (instr(buf,"not empty")) errno = EBUSY; else if (instr(buf,"cannot access")) *************** *** 1600,1606 **** stab = arg[1].arg_ptr.arg_stab; else stab = stabent(str_get(st[1]),TRUE); ! argtype = (int)str_gnum(st[2]); #ifdef TAINT taintproper("Insecure dependency in ioctl"); #endif --- 1622,1628 ---- stab = arg[1].arg_ptr.arg_stab; else stab = stabent(str_get(st[1]),TRUE); ! argtype = (unsigned int)str_gnum(st[2]); #ifdef TAINT taintproper("Insecure dependency in ioctl"); #endif *************** *** 1748,1753 **** --- 1770,1777 ---- goto say_no; #endif case O_FTLINK: + if (arg[1].arg_type & A_DONT) + fatal("You must supply explicit filename with -l"); #ifdef LSTAT if (lstat(str_get(st[1]),&statcache) < 0) goto say_undef; *************** *** 2070,2075 **** --- 2094,2111 ---- case O_SYSCALL: value = (double)do_syscall(arglast); goto donumset; + case O_PIPE: + if ((arg[1].arg_type & A_MASK) == A_WORD) + stab = arg[1].arg_ptr.arg_stab; + else + stab = stabent(str_get(st[1]),TRUE); + if ((arg[2].arg_type & A_MASK) == A_WORD) + stab2 = arg[2].arg_ptr.arg_stab; + else + stab2 = stabent(str_get(st[2]),TRUE); + do_pipe(str,stab,stab2); + STABSET(str); + break; } normal_return: *************** *** 2087,2094 **** #ifdef DEBUGGING if (debug) { dlevel--; ! if (debug & 8) ! deb("%s RETURNS ARRAY OF %d ARGS\n",opname[optype],sp - arglast[0]); } #endif return sp; --- 2123,2143 ---- #ifdef DEBUGGING if (debug) { dlevel--; ! if (debug & 8) { ! anum = sp - arglast[0]; ! switch (anum) { ! case 0: ! deb("%s RETURNS ()\n",opname[optype]); ! break; ! case 1: ! deb("%s RETURNS (\"%s\")\n",opname[optype],str_get(st[1])); ! break; ! default: ! deb("%s RETURNS %d ARGS (\"%s\",%s\"%s\"\n",opname[optype],anum, ! str_get(st[1]),anum==2?"":"...,",str_get(st[anum])); ! break; ! } ! } } #endif return sp; *** End of Patch 10 ***