Path: utzoo!attcan!uunet!lll-winken!lll-lcc!ames!elroy!devvax!lroot From: lroot@devvax.JPL.NASA.GOV (The Superuser) Newsgroups: comp.sources.bugs Subject: perl 2.0 patch #5 Summary: This is an official patch for perl 2.0. Please apply it. Message-ID: <2440@devvax.JPL.NASA.GOV> Date: 13 Jul 88 00:54:23 GMT Organization: Jet Propulsion Laboratory, Pasadena, CA Lines: 1190 System: perl version 2.0 Patch #: 5 Priority: MEDIUM Subject: patch2 continued Description: See patch 2. 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 5 Index: x2p/s2p Prereq: 2.0 *** x2p/s2p.old Mon Jul 11 23:40:01 1988 --- x2p/s2p Mon Jul 11 23:40:02 1988 *************** *** 1,8 **** #!/usr/bin/perl ! # $Header: s2p,v 2.0 88/06/05 00:15:55 root Exp $ # # $Log: s2p,v $ # Revision 2.0 88/06/05 00:15:55 root # Baseline version 2.0. # --- 1,11 ---- #!/usr/bin/perl ! # $Header: s2p,v 2.0.1.1 88/07/11 23:26:23 root Exp $ # # $Log: s2p,v $ + # Revision 2.0.1.1 88/07/11 23:26:23 root + # patch2: s2p didn't put a proper prologue on output script + # # Revision 2.0 88/06/05 00:15:55 root # Baseline version 2.0. # *************** *** 243,249 **** } close head; ! print "#!/bin/perl\n\n"; open(body,"cc -E /tmp/sperl2$$.c |") || do Die("Can't reopen temp file"); while () { --- 246,256 ---- } close head; ! print '#!/usr/bin/perl ! eval "exec /usr/bin/perl -S $0 $*" ! if $running_under_some_shell; ! ! '; open(body,"cc -E /tmp/sperl2$$.c |") || do Die("Can't reopen temp file"); while () { Index: x2p/walk.c Prereq: 2.0 *** x2p/walk.c.old Mon Jul 11 23:40:08 1988 --- x2p/walk.c Mon Jul 11 23:40:11 1988 *************** *** 1,6 **** ! /* $Header: walk.c,v 2.0 88/06/05 00:16:12 root Exp $ * * $Log: walk.c,v $ * Revision 2.0 88/06/05 00:16:12 root * Baseline version 2.0. * --- 1,13 ---- ! /* $Header: walk.c,v 2.0.1.1 88/07/11 23:35:57 root Exp $ * * $Log: walk.c,v $ + * Revision 2.0.1.1 88/07/11 23:35:57 root + * patch2: changes to support translation of 1985 awk + * patch2: handles multiple opens to same file better + * patch2: now handles absence of line actions + * patch2: now takes advantage of perl's filehandle indirection + * patch2: now uses keys() instead of each() to protect against deletes in loop + * * Revision 2.0 88/06/05 00:16:12 root * Baseline version 2.0. * *************** *** 14,22 **** --- 21,34 ---- bool exitval = FALSE; bool realexit = FALSE; bool saw_getline = FALSE; + bool subretnum = FALSE; + bool saw_FNR = FALSE; + bool saw_argv0 = FALSE; int maxtmp = 0; char *lparen; char *rparen; + STR *subs; + STR *curargs = Nullstr; STR * walk(useval,level,node,numericptr) *************** *** 31,36 **** --- 43,49 ---- register int i; register STR *tmpstr; STR *tmp2str; + STR *tmp3str; char *t; char *d, *s; int numarg; *************** *** 47,54 **** type &= 255; switch (type) { case OPROG: - str = walk(0,level,ops[node+1].ival,&numarg); opens = str_new(0); if (do_split && need_entire && !absmaxfld) split_to_array = TRUE; if (do_split && split_to_array) --- 60,68 ---- type &= 255; switch (type) { case OPROG: opens = str_new(0); + subs = str_new(0); + str = walk(0,level,ops[node+1].ival,&numarg); if (do_split && need_entire && !absmaxfld) split_to_array = TRUE; if (do_split && split_to_array) *************** *** 79,84 **** --- 93,101 ---- if (saw_ORS) { str_cat(str,"$\\ = \"\\n\";\t\t# set output record separator\n"); } + if (saw_argv0) { + str_cat(str,"$ARGV0 = $0;\t\t# remember what we ran as\n"); + } if (str->str_cur > 20) str_cat(str,"\n"); if (ops[node+2].ival) { *************** *** 86,121 **** str_free(fstr); str_cat(str,"\n\n"); } ! if (saw_line_op) ! str_cat(str,"line: "); ! str_cat(str,"while (<>) {\n"); ! tab(str,++level); ! if (saw_FS && !const_FS) ! do_chop = TRUE; ! if (do_chop) { ! str_cat(str,"chop;\t# strip record separator\n"); ! tab(str,level); ! } ! arymax = 0; ! if (namelist) { ! while (isalpha(*namelist)) { ! for (d = tokenbuf,s=namelist; ! isalpha(*s) || isdigit(*s) || *s == '_'; ! *d++ = *s++) ; ! *d = '\0'; ! while (*s && !isalpha(*s)) s++; ! namelist = s; ! nameary[++arymax] = savestr(tokenbuf); } } ! if (maxfld < arymax) ! maxfld = arymax; ! if (do_split) ! emit_split(str,level); ! str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg)); ! str_free(fstr); ! fixtab(str,--level); ! str_cat(str,"}\n"); if (ops[node+4].ival) { realexit = TRUE; str_cat(str,"\n"); --- 103,145 ---- str_free(fstr); str_cat(str,"\n\n"); } ! fstr = walk(0,level+1,ops[node+3].ival,&numarg); ! if (*fstr->str_ptr) { ! if (saw_line_op) ! str_cat(str,"line: "); ! str_cat(str,"while (<>) {\n"); ! tab(str,++level); ! if (saw_FS && !const_FS) ! do_chop = TRUE; ! if (do_chop) { ! str_cat(str,"chop;\t# strip record separator\n"); ! tab(str,level); } + arymax = 0; + if (namelist) { + while (isalpha(*namelist)) { + for (d = tokenbuf,s=namelist; + isalpha(*s) || isdigit(*s) || *s == '_'; + *d++ = *s++) ; + *d = '\0'; + while (*s && !isalpha(*s)) s++; + namelist = s; + nameary[++arymax] = savestr(tokenbuf); + } + } + if (maxfld < arymax) + maxfld = arymax; + if (do_split) + emit_split(str,level); + str_scat(str,fstr); + str_free(fstr); + fixtab(str,--level); + str_cat(str,"}\n"); + if (saw_FNR) + str_cat(str,"continue {\n $FNRbase = $. if eof;\n}\n"); } ! else ! str_cat(str,"# (no line actions)\n"); if (ops[node+4].ival) { realexit = TRUE; str_cat(str,"\n"); *************** *** 126,162 **** } if (exitval) str_cat(str,"exit ExitValue;\n"); if (saw_getline) { ! str_cat(str,"\nsub Getline {\n $_ = <>;\n"); ! tab(str,++level); ! if (do_chop) { ! str_cat(str,"chop;\t# strip record separator\n"); ! tab(str,level); } - if (do_split) - emit_split(str,level); - fixtab(str,--level); - str_cat(str,"}\n"); } if (do_fancy_opens) { str_cat(str,"\n\ sub Pick {\n\ ! ($name) = @_;\n\ $fh = $opened{$name};\n\ if (!$fh) {\n\ ! $nextfh == 0 && open(fh_0,$name);\n\ ! $nextfh == 1 && open(fh_1,$name);\n\ ! $nextfh == 2 && open(fh_2,$name);\n\ ! $nextfh == 3 && open(fh_3,$name);\n\ ! $nextfh == 4 && open(fh_4,$name);\n\ ! $nextfh == 5 && open(fh_5,$name);\n\ ! $nextfh == 6 && open(fh_6,$name);\n\ ! $nextfh == 7 && open(fh_7,$name);\n\ ! $nextfh == 8 && open(fh_8,$name);\n\ ! $nextfh == 9 && open(fh_9,$name);\n\ ! $fh = $opened{$name} = 'fh_' . $nextfh++;\n\ }\n\ - select($fh);\n\ }\n\ "); } --- 150,212 ---- } if (exitval) str_cat(str,"exit ExitValue;\n"); + if (subs->str_ptr) { + str_cat(str,"\n"); + str_scat(str,subs); + } if (saw_getline) { ! for (len = 0; len < 4; len++) { ! if (saw_getline & (1 << len)) { ! sprintf(tokenbuf,"\nsub Getline%d {\n",len); ! str_cat(str, tokenbuf); ! if (len & 2) { ! if (do_fancy_opens) ! str_cat(str," do Pick('',@_);\n"); ! else ! str_cat(str," ($fh) = @_;\n"); ! } ! else { ! if (saw_FNR) ! str_cat(str," $FNRbase = $. if eof;\n"); ! } ! if (len & 1) ! str_cat(str," local($_)\n"); ! if (len & 2) ! str_cat(str, ! " if ($getline_ok = (($_ = <$fh>) ne ''))"); ! else ! str_cat(str, ! " if ($getline_ok = (($_ = <>) ne ''))"); ! str_cat(str, " {\n"); ! level += 2; ! tab(str,level); ! i = 0; ! if (do_chop) { ! i++; ! str_cat(str,"chop;\t# strip record separator\n"); ! tab(str,level); ! } ! if (do_split && !(len & 1)) { ! i++; ! emit_split(str,level); ! } ! if (!i) ! str_cat(str,";\n"); ! fixtab(str,--level); ! str_cat(str,"}\n $_;\n}\n"); ! --level; ! } } } if (do_fancy_opens) { str_cat(str,"\n\ sub Pick {\n\ ! local($mode,$name,$pipe) = @_;\n\ $fh = $opened{$name};\n\ if (!$fh) {\n\ ! $fh = $opened{$name} = 'fh_' . ($nextfh++ + 0);\n\ ! open($fh,$mode.$name.$pipe);\n\ }\n\ }\n\ "); } *************** *** 345,352 **** --- 395,407 ---- str_free(tmpstr); } str_cat(str," "); + type = ops[ops[node+3].ival].ival & 255; + if (type != OREGEX && type != OVAR) + str_cat(str,"("); str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg)); str_free(fstr); + if (type != OREGEX && type != OVAR) + str_cat(str,")"); numeric = 1; break; case OMPAREN: *************** *** 383,389 **** str_free(fstr); numeric = 1; break; ! case OSUB: str = walk(1,level,ops[node+1].ival,&numarg); str_cat(str," - "); str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg)); --- 438,444 ---- str_free(fstr); numeric = 1; break; ! case OSUBTRACT: str = walk(1,level,ops[node+1].ival,&numarg); str_cat(str," - "); str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg)); *************** *** 404,409 **** --- 459,471 ---- str_free(fstr); numeric = 1; break; + case OPOW: + str = walk(1,level,ops[node+1].ival,&numarg); + str_cat(str," ** "); + str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg)); + str_free(fstr); + numeric = 1; + break; case OMOD: str = walk(1,level,ops[node+1].ival,&numarg); str_cat(str," % "); *************** *** 455,462 **** break; case OGETLINE: str = str_new(0); ! str_set(str,"do Getline()"); ! saw_getline = TRUE; break; case OSPRINTF: str = str_new(0); --- 517,596 ---- break; case OGETLINE: str = str_new(0); ! if (useval) ! str_cat(str,"("); ! if (len > 0) { ! str_cat(str,"$"); ! str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg)); ! if (!*fstr->str_ptr) { ! str_cat(str,"_"); ! len = 2; /* a legal fiction */ ! } ! str_free(fstr); ! } ! else ! str_cat(str,"$_"); ! if (len > 1) { ! tmpstr=walk(1,level,ops[node+3].ival,&numarg); ! fstr=walk(1,level,ops[node+2].ival,&numarg); ! if (!do_fancy_opens) { ! t = tmpstr->str_ptr; ! if (*t == '"' || *t == '\'') ! t = cpytill(tokenbuf,t+1,*t); ! else ! fatal("Internal error: OGETLINE %s", t); ! d = savestr(t); ! s = savestr(tokenbuf); ! for (t = tokenbuf; *t; t++) { ! *t &= 127; ! if (!isalpha(*t) && !isdigit(*t)) ! *t = '_'; ! } ! if (!index(tokenbuf,'_')) ! strcpy(t,"_fh"); ! tmp3str = hfetch(symtab,tokenbuf); ! if (!tmp3str) { ! do_opens = TRUE; ! str_cat(opens,"open("); ! str_cat(opens,tokenbuf); ! str_cat(opens,", "); ! d[1] = '\0'; ! str_cat(opens,d); ! str_cat(opens,tmpstr->str_ptr+1); ! opens->str_cur--; ! if (*fstr->str_ptr == '|') ! str_cat(opens,"|"); ! str_cat(opens,d); ! if (*fstr->str_ptr == '|') ! str_cat(opens,") || die 'Cannot pipe from \""); ! else ! str_cat(opens,") || die 'Cannot open file \""); ! if (*d == '"') ! str_cat(opens,"'.\""); ! str_cat(opens,s); ! if (*d == '"') ! str_cat(opens,"\".'"); ! str_cat(opens,"\".';\n"); ! hstore(symtab,tokenbuf,str_make("x")); ! } ! safefree(s); ! safefree(d); ! str_set(tmpstr,"'"); ! str_cat(tmpstr,tokenbuf); ! str_cat(tmpstr,"'"); ! } ! if (*fstr->str_ptr == '|') ! str_cat(tmpstr,", '|'"); ! str_free(fstr); ! } ! else ! tmpstr = str_make(""); ! sprintf(tokenbuf," = do Getline%d(%s)",len,tmpstr->str_ptr); ! str_cat(str,tokenbuf); ! str_free(tmpstr); ! if (useval) ! str_cat(str,",getline_ok)"); ! saw_getline |= 1 << len; break; case OSPRINTF: str = str_new(0); *************** *** 538,543 **** --- 672,862 ---- str_cat(str,")"); numeric = 1; break; + case OMATCH: + str = str_new(0); + str_set(str,"("); + str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg)); + str_free(fstr); + str_cat(str," =~ "); + str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg)); + str_free(fstr); + str_cat(str," && ($RLENGTH = length($&), $RSTART = length($`)+1))"); + numeric = 1; + break; + case OUSERDEF: + str = str_new(0); + subretnum = FALSE; + fstr=walk(1,level-1,ops[node+2].ival,&numarg); + curargs = str_new(0); + str_sset(curargs,fstr); + str_cat(curargs,","); + tmp2str=walk(1,level,ops[node+5].ival,&numarg); + str_free(curargs); + curargs = Nullstr; + level--; + subretnum |= numarg; + s = Nullch; + t = tmp2str->str_ptr; + while (t = instr(t,"return ")) + s = t++; + if (s) { + i = 0; + for (t = s+7; *t; t++) { + if (*t == ';' || *t == '}') + i++; + } + if (i == 1) { + strcpy(s,s+7); + tmp2str->str_cur -= 7; + } + } + str_set(str,"sub "); + str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg)); + str_cat(str," {\n"); + tab(str,++level); + str_cat(str,"local("); + str_scat(str,fstr); + str_free(fstr); + str_cat(str,") = @_;"); + str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg)); + str_free(fstr); + fixtab(str,level); + str_scat(str,fstr=walk(1,level,ops[node+4].ival,&numarg)); + str_free(fstr); + fixtab(str,level); + str_scat(str,tmp2str); + str_free(tmp2str); + fixtab(str,--level); + str_cat(str,"}\n"); + tab(str,level); + str_scat(subs,str); + str_set(str,""); + str_cat(tmpstr,"("); + tmp2str = str_new(0); + if (subretnum) + str_set(tmp2str,"1"); + hstore(symtab,tmpstr->str_ptr,tmp2str); + str_free(tmpstr); + level++; + break; + case ORETURN: + str = str_new(0); + if (len > 0) { + str_cat(str,"return "); + str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg)); + str_free(fstr); + if (numarg) + subretnum = TRUE; + } + else + str_cat(str,"return"); + break; + case OUSERFUN: + str = str_new(0); + str_set(str,"do "); + str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg)); + str_free(fstr); + str_cat(str,"("); + tmpstr = hfetch(symtab,str->str_ptr+3); + if (tmpstr) + numeric |= atoi(tmpstr->str_ptr); + str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg)); + str_free(fstr); + str_cat(str,")"); + break; + case OGSUB: + case OSUB: + if (type == OGSUB) + s = "g"; + else + s = ""; + str = str_new(0); + tmpstr = str_new(0); + i = 0; + if (len == 3) { + tmpstr = walk(1,level,ops[node+3].ival,&numarg); + if (strNE(tmpstr->str_ptr,"$_")) { + str_cat(tmpstr, " =~ s"); + i++; + } + else + str_set(tmpstr, "s"); + } + else + str_set(tmpstr, "s"); + type = ops[ops[node+2].ival].ival; + len = type >> 8; + type &= 255; + tmp3str = str_new(0); + if (type == OSTR) { + tmp2str=walk(1,level,ops[ops[node+2].ival+1].ival,&numarg); + for (t = tmp2str->str_ptr, d=tokenbuf; *t; d++,t++) { + if (*t == '&') + *d++ = '$' + 128; + else if (*t == '$') + *d++ = '\\' + 128; + *d = *t + 128; + } + *d = '\0'; + str_set(tmp2str,tokenbuf); + } + else { + tmp2str=walk(1,level,ops[node+2].ival,&numarg); + str_set(tmp3str,"($s_ = '\"'.("); + str_scat(tmp3str,tmp2str); + str_cat(tmp3str,").'\"') =~ s/&/\$&/g, "); + str_set(tmp2str,"eval $s_"); + s = (*s == 'g' ? "ge" : "e"); + i++; + } + type = ops[ops[node+1].ival].ival; + len = type >> 8; + type &= 255; + fstr=walk(1,level,ops[node+1].ival,&numarg); + if (type == OREGEX) { + if (useval && i) + str_cat(str,"("); + str_scat(str,tmp3str); + str_scat(str,tmpstr); + str_scat(str,fstr); + str_scat(str,tmp2str); + str_cat(str,"/"); + str_cat(str,s); + } + else if ((type == OFLD && !split_to_array) || (type == OVAR && len == 1)) { + if (useval && i) + str_cat(str,"("); + str_scat(str,tmp3str); + str_scat(str,tmpstr); + str_cat(str,"/"); + str_scat(str,fstr); + str_cat(str,"/"); + str_scat(str,tmp2str); + str_cat(str,"/"); + str_cat(str,s); + } + else { + i++; + if (useval) + str_cat(str,"("); + str_cat(str,"$s = "); + str_scat(str,fstr); + str_cat(str,", "); + str_scat(str,tmp3str); + str_scat(str,tmpstr); + str_cat(str,"/$s/"); + str_scat(str,tmp2str); + str_cat(str,"/"); + str_cat(str,s); + } + if (useval && i) + str_cat(str,")"); + str_free(fstr); + str_free(tmpstr); + str_free(tmp2str); + str_free(tmp3str); + numeric = 1; + break; case ONUM: str = walk(1,level,ops[node+1].ival,&numarg); numeric = 1; *************** *** 567,582 **** str_free(tmpstr); str_cat(str,s); break; case OVAR: str = str_new(0); str_set(str,"$"); str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg)); if (len == 1) { tmp2str = hfetch(symtab,tmpstr->str_ptr); if (tmp2str && atoi(tmp2str->str_ptr)) numeric = 2; ! if (strEQ(str->str_ptr,"$NR")) { numeric = 1; str_set(str,"$."); } else if (strEQ(str->str_ptr,"$NF")) { --- 886,911 ---- str_free(tmpstr); str_cat(str,s); break; + case ODELETE: + str = str_new(0); + str_set(str,"delete $"); + goto addvar; case OVAR: str = str_new(0); str_set(str,"$"); + addvar: str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg)); if (len == 1) { tmp2str = hfetch(symtab,tmpstr->str_ptr); if (tmp2str && atoi(tmp2str->str_ptr)) numeric = 2; ! if (strEQ(str->str_ptr,"$FNR")) { numeric = 1; + saw_FNR++; + str_set(str,"($.-$FNRbase)"); + } + else if (strEQ(str->str_ptr,"$NR")) { + numeric = 1; str_set(str,"$."); } else if (strEQ(str->str_ptr,"$NF")) { *************** *** 585,592 **** --- 914,928 ---- } else if (strEQ(str->str_ptr,"$0")) str_set(str,"$_"); + else if (strEQ(str->str_ptr,"$ARGC")) + str_set(str,"($#ARGV+1)"); } else { + if (curargs) { + sprintf(tokenbuf,"$%s,",tmpstr->str_ptr); + if (instr(curargs->str_ptr,tokenbuf)) + str_cat(str,"\377"); /* can't translate yet */ + } str_cat(tmpstr,"[]"); tmp2str = hfetch(symtab,tmpstr->str_ptr); if (tmp2str && atoi(tmp2str->str_ptr)) *************** *** 595,606 **** str_cat(str,"{"); str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg)); str_free(fstr); ! if (tmp2str && atoi(tmp2str->str_ptr)) ! strcpy(tokenbuf,"]"); ! else ! strcpy(tokenbuf,"}"); ! *tokenbuf += 128; ! str_cat(str,tokenbuf); } str_free(tmpstr); break; --- 931,948 ---- str_cat(str,"{"); str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg)); str_free(fstr); ! if (strEQ(str->str_ptr,"$ARGV[0")) { ! str_set(str,"$ARGV0"); ! saw_argv0++; ! } ! else { ! if (tmp2str && atoi(tmp2str->str_ptr)) ! strcpy(tokenbuf,"]"); ! else ! strcpy(tokenbuf,"}"); ! *tokenbuf += 128; ! str_cat(str,tokenbuf); ! } } str_free(tmpstr); break; *************** *** 694,699 **** --- 1036,1070 ---- } } break; + case OCLOSE: + str = str_make("close("); + tmpstr = walk(1,level,ops[node+1].ival,&numarg); + if (!do_fancy_opens) { + t = tmpstr->str_ptr; + if (*t == '"' || *t == '\'') + t = cpytill(tokenbuf,t+1,*t); + else + fatal("Internal error: OCLOSE %s",t); + s = savestr(tokenbuf); + for (t = tokenbuf; *t; t++) { + *t &= 127; + if (!isalpha(*t) && !isdigit(*t)) + *t = '_'; + } + if (!index(tokenbuf,'_')) + strcpy(t,"_fh"); + str_free(tmpstr); + safefree(s); + str_set(str,"close "); + str_cat(str,tokenbuf); + } + else { + sprintf(tokenbuf,"$fh = delete $opened{%s} && close $fh", + tmpstr->str_ptr); + str_free(tmpstr); + str_set(str,tokenbuf); + } + break; case OPRINTF: case OPRINT: lparen = ""; /* set to parens if necessary */ *************** *** 717,739 **** } if (!index(tokenbuf,'_')) strcpy(t,"_fh"); ! str_cat(opens,"open("); ! str_cat(opens,tokenbuf); ! str_cat(opens,", "); ! d[1] = '\0'; ! str_cat(opens,d); ! str_scat(opens,tmp2str); ! str_cat(opens,tmpstr->str_ptr+1); ! if (*tmp2str->str_ptr == '|') ! str_cat(opens,") || die 'Cannot pipe to \""); ! else ! str_cat(opens,") || die 'Cannot create file \""); ! if (*d == '"') ! str_cat(opens,"'.\""); ! str_cat(opens,s); ! if (*d == '"') ! str_cat(opens,"\".'"); ! str_cat(opens,"\".';\n"); str_free(tmpstr); str_free(tmp2str); safefree(s); --- 1088,1114 ---- } if (!index(tokenbuf,'_')) strcpy(t,"_fh"); ! tmp3str = hfetch(symtab,tokenbuf); ! if (!tmp3str) { ! str_cat(opens,"open("); ! str_cat(opens,tokenbuf); ! str_cat(opens,", "); ! d[1] = '\0'; ! str_cat(opens,d); ! str_scat(opens,tmp2str); ! str_cat(opens,tmpstr->str_ptr+1); ! if (*tmp2str->str_ptr == '|') ! str_cat(opens,") || die 'Cannot pipe to \""); ! else ! str_cat(opens,") || die 'Cannot create file \""); ! if (*d == '"') ! str_cat(opens,"'.\""); ! str_cat(opens,s); ! if (*d == '"') ! str_cat(opens,"\".'"); ! str_cat(opens,"\".';\n"); ! hstore(symtab,tokenbuf,str_make("x")); ! } str_free(tmpstr); str_free(tmp2str); safefree(s); *************** *** 740,750 **** safefree(d); } else { ! sprintf(tokenbuf,"do Pick('%s' . (%s)) &&\n", tmp2str->str_ptr, tmpstr->str_ptr); str_cat(str,tokenbuf); tab(str,level+1); ! *tokenbuf = '\0'; str_free(tmpstr); str_free(tmp2str); lparen = "("; --- 1115,1125 ---- safefree(d); } else { ! sprintf(tokenbuf,"do Pick('%s', %s) &&\n", tmp2str->str_ptr, tmpstr->str_ptr); str_cat(str,tokenbuf); tab(str,level+1); ! strcpy(tokenbuf,"$fh"); str_free(tmpstr); str_free(tmp2str); lparen = "("; *************** *** 795,800 **** --- 1170,1193 ---- str_cat(str,rparen); /* may be null */ str_free(tmpstr); break; + case ORAND: + str = str_make("rand(1)"); + break; + case OSRAND: + str = str_make("srand("); + goto maybe0; + case OATAN2: + str = str_make("atan2("); + goto maybe0; + case OSIN: + str = str_make("sin("); + goto maybe0; + case OCOS: + str = str_make("cos("); + goto maybe0; + case OSYSTEM: + str = str_make("system("); + goto maybe0; case OLENGTH: str = str_make("length("); goto maybe0; *************** *** 960,991 **** str_free(fstr); break; case OFORIN: ! tmpstr=walk(0,level,ops[node+2].ival,&numarg); str = str_new(0); ! str_sset(str,tmpstr); str_cat(str,"[]"); tmp2str = hfetch(symtab,str->str_ptr); if (tmp2str && atoi(tmp2str->str_ptr)) { - fstr=walk(1,level,ops[node+1].ival,&numarg); sprintf(tokenbuf, ! "foreach $%s (@%s) ", ! fstr->str_ptr, ! tmpstr->str_ptr); ! str_set(str,tokenbuf); ! str_free(fstr); ! str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg)); ! str_free(fstr); } else { ! str_set(str,"while (($"); ! str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg)); ! str_free(fstr); ! str_cat(str,",$junkval) = each("); ! str_scat(str,tmpstr); ! str_cat(str,")) "); ! str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg)); ! str_free(fstr); } str_free(tmpstr); break; case OBLOCK: --- 1353,1389 ---- str_free(fstr); break; case OFORIN: ! tmpstr = walk(0,level,ops[node+1].ival,&numarg); ! s = index(tmpstr->str_ptr,'{'); ! if (!s) ! s = index(tmpstr->str_ptr,'['); ! if (!s) ! fatal("Illegal for loop: %s",tmpstr->str_ptr); ! *s++ = '\0'; ! t = index(s,'}' + 128); ! if (!t) ! t = index(s,']' + 128); ! if (t) ! *t = '\0'; str = str_new(0); ! str_set(str,tmpstr->str_ptr+1); str_cat(str,"[]"); tmp2str = hfetch(symtab,str->str_ptr); if (tmp2str && atoi(tmp2str->str_ptr)) { sprintf(tokenbuf, ! "foreach %s (@%s) ", ! s, ! tmpstr->str_ptr+1); } else { ! sprintf(tokenbuf, ! "foreach %s (keys(%s)) ", ! s, ! tmpstr->str_ptr+1); } + str_set(str,tokenbuf); + str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg)); + str_free(fstr); str_free(tmpstr); break; case OBLOCK: *************** *** 1132,1137 **** --- 1530,1537 ---- char *d, *s; int numarg; int numeric = FALSE; + STR *tmpstr; + STR *tmp2str; if (!node) { *numericptr = 0; *************** *** 1259,1265 **** prewalk(1,level,ops[node+2].ival,&numarg); numeric = 1; break; ! case OSUB: prewalk(1,level,ops[node+1].ival,&numarg); prewalk(1,level,ops[node+2].ival,&numarg); numeric = 1; --- 1659,1665 ---- prewalk(1,level,ops[node+2].ival,&numarg); numeric = 1; break; ! case OSUBTRACT: prewalk(1,level,ops[node+1].ival,&numarg); prewalk(1,level,ops[node+2].ival,&numarg); numeric = 1; *************** *** 1274,1279 **** --- 1674,1684 ---- prewalk(1,level,ops[node+2].ival,&numarg); numeric = 1; break; + case OPOW: + prewalk(1,level,ops[node+1].ival,&numarg); + prewalk(1,level,ops[node+2].ival,&numarg); + numeric = 1; + break; case OMOD: prewalk(1,level,ops[node+1].ival,&numarg); prewalk(1,level,ops[node+2].ival,&numarg); *************** *** 1333,1338 **** --- 1738,1791 ---- prewalk(0,level,ops[node+2].ival,&numarg); numeric = 1; break; + case OMATCH: + prewalk(0,level,ops[node+1].ival,&numarg); + prewalk(0,level,ops[node+2].ival,&numarg); + numeric = 1; + break; + case OUSERDEF: + subretnum = FALSE; + --level; + tmpstr = walk(0,level,ops[node+1].ival,&numarg); + ++level; + prewalk(0,level,ops[node+2].ival,&numarg); + prewalk(0,level,ops[node+4].ival,&numarg); + prewalk(0,level,ops[node+5].ival,&numarg); + --level; + str_cat(tmpstr,"("); + tmp2str = str_new(0); + if (subretnum || numarg) + str_set(tmp2str,"1"); + hstore(symtab,tmpstr->str_ptr,tmp2str); + str_free(tmpstr); + level++; + break; + case ORETURN: + if (len > 0) { + prewalk(0,level,ops[node+1].ival,&numarg); + if (numarg) + subretnum = TRUE; + } + break; + case OUSERFUN: + tmp2str = str_new(0); + str_scat(tmp2str,tmpstr=walk(1,level,ops[node+1].ival,&numarg)); + str_free(tmpstr); + str_cat(tmp2str,"("); + tmpstr = hfetch(symtab,tmp2str->str_ptr); + if (tmpstr) + numeric |= atoi(tmpstr->str_ptr); + prewalk(0,level,ops[node+2].ival,&numarg); + str_free(tmp2str); + break; + case OGSUB: + case OSUB: + if (len >= 3) + prewalk(0,level,ops[node+3].ival,&numarg); + prewalk(0,level,ops[ops[node+2].ival+1].ival,&numarg); + prewalk(0,level,ops[node+1].ival,&numarg); + numeric = 1; + break; case ONUM: prewalk(0,level,ops[node+1].ival,&numarg); numeric = 1; *************** *** 1340,1345 **** --- 1793,1799 ---- case OSTR: prewalk(0,level,ops[node+1].ival,&numarg); break; + case ODELETE: case OVAR: prewalk(0,level,ops[node+1].ival,&numarg); if (len == 1) { *************** *** 1385,1390 **** --- 1839,1847 ---- } } break; + case OCLOSE: + prewalk(0,level,ops[node+1].ival,&numarg); + break; case OPRINTF: case OPRINT: if (len == 3) { /* output redirection */ *************** *** 1393,1398 **** --- 1850,1867 ---- } prewalk(0+(type==OPRINT),level,ops[node+1].ival,&numarg); break; + case ORAND: + break; + case OSRAND: + goto maybe0; + case OATAN2: + goto maybe0; + case OSIN: + goto maybe0; + case OCOS: + goto maybe0; + case OSYSTEM: + goto maybe0; case OLENGTH: goto maybe0; case OLOG: *************** *** 1405,1411 **** maybe0: numeric = 1; if (len > 0) ! prewalk(type != OLENGTH,level,ops[node+1].ival,&numarg); break; case OBREAK: break; --- 1874,1881 ---- maybe0: numeric = 1; if (len > 0) ! prewalk(type != OLENGTH && type != OSYSTEM, ! level,ops[node+1].ival,&numarg); break; case OBREAK: break; *************** *** 1440,1446 **** case OFORIN: prewalk(0,level,ops[node+2].ival,&numarg); prewalk(0,level,ops[node+1].ival,&numarg); - prewalk(0,level,ops[node+3].ival,&numarg); break; case OBLOCK: if (len == 2) { --- 1910,1915 ----