1 /* $Header: arg.c,v 1.0 87/12/18 13:04:33 root Exp $
4 * Revision 1.0 87/12/18 13:04:33 root
23 register SPAT *spat = arg[2].arg_ptr.arg_spat;
28 fatal("panic: do_match\n");
29 if (spat->spat_flags & SPAT_USED) {
36 if (spat->spat_runtime) {
37 t = str_get(eval(spat->spat_runtime,Null(STR***)));
40 deb("2.SPAT /%s/\n",t);
42 if (d = compile(&spat->spat_compex,t,TRUE,FALSE)) {
44 deb("/%s/: %s\n", t, d);
48 if (spat->spat_compex.complen <= 1 && curspat)
50 if (execute(&spat->spat_compex, s, TRUE, 0)) {
51 if (spat->spat_compex.numsubs)
63 if (spat->spat_flags & SPAT_USE_ONCE)
67 deb("2.SPAT %c%s%c\n",ch,spat->spat_compex.precomp,ch);
70 if (spat->spat_compex.complen <= 1 && curspat)
72 if (spat->spat_first) {
73 if (spat->spat_flags & SPAT_SCANFIRST) {
74 str_free(spat->spat_first);
75 spat->spat_first = Nullstr; /* disable optimization */
77 else if (*spat->spat_first->str_ptr != *s ||
78 strnNE(spat->spat_first->str_ptr, s, spat->spat_flen) )
81 if (execute(&spat->spat_compex, s, TRUE, 0)) {
82 if (spat->spat_compex.numsubs)
84 if (spat->spat_flags & SPAT_USE_ONCE)
85 spat->spat_flags |= SPAT_USED;
104 spat = arg[2].arg_ptr.arg_spat;
107 fatal("panic: do_subst\n");
108 else if (spat->spat_runtime) {
111 m = str_get(eval(spat->spat_runtime,Null(STR***)));
112 if (d = compile(&spat->spat_compex,m,TRUE,FALSE)) {
114 deb("/%s/: %s\n", m, d);
121 deb("2.SPAT /%s/\n",spat->spat_compex.precomp);
124 if (spat->spat_compex.complen <= 1 && curspat)
126 if (spat->spat_first) {
127 if (spat->spat_flags & SPAT_SCANFIRST) {
128 str_free(spat->spat_first);
129 spat->spat_first = Nullstr; /* disable optimization */
131 else if (*spat->spat_first->str_ptr != *s ||
132 strnNE(spat->spat_first->str_ptr, s, spat->spat_flen) )
135 if (m = execute(&spat->spat_compex, s, TRUE, 1)) {
138 dstr = str_new(str_len(str));
139 if (spat->spat_compex.numsubs)
143 fatal("Substitution loop?\n");
144 if (spat->spat_compex.numsubs)
145 s = spat->spat_compex.subbase;
146 str_ncat(dstr,s,m-s);
147 s = spat->spat_compex.subend[0];
148 str_scat(dstr,eval(spat->spat_repl,Null(STR***)));
149 if (spat->spat_flags & SPAT_USE_ONCE)
151 } while (m = execute(&spat->spat_compex, s, FALSE, 1));
153 str_replace(str,dstr);
167 register int matches = 0;
170 tbl = arg[2].arg_ptr.arg_cval;
173 fatal("panic: do_trans\n");
180 if (ch = tbl[*s & 0377]) {
191 do_split(s,spat,retary)
199 static ARRAY *myarray = Null(ARRAY*);
206 fatal("panic: do_split\n");
207 else if (spat->spat_runtime) {
210 m = str_get(eval(spat->spat_runtime,Null(STR***)));
211 if (d = compile(&spat->spat_compex,m,TRUE,FALSE)) {
213 deb("/%s/: %s\n", m, d);
220 deb("2.SPAT /%s/\n",spat->spat_compex.precomp);
226 ary = spat->spat_repl[1].arg_ptr.arg_stab->stab_array;
228 myarray = ary = anew();
230 while (*s && (m = execute(&spat->spat_compex, s, (iters == 0), 1))) {
231 if (spat->spat_compex.numsubs)
232 s = spat->spat_compex.subbase;
234 str_nset(dstr,s,m-s);
235 astore(ary, iters++, dstr);
237 fatal("Substitution loop?\n");
238 s = spat->spat_compex.subend[0];
240 if (*s) { /* ignore field after final "whitespace" */
241 dstr = str_new(0); /* if they interpolate, it's null anyway */
243 astore(ary, iters++, dstr);
246 while (iters > 0 && !*str_get(afetch(ary,iters-1)))
250 sarg = (STR**)safemalloc((iters+2)*sizeof(STR*));
253 sarg[iters+1] = Nullstr;
254 for (i = 1; i <= iters; i++)
255 sarg[i] = afetch(ary,i-1);
262 do_join(arg,delim,str)
264 register char *delim;
267 STR **tmpary; /* must not be register */
270 (void)eval(arg[2].arg_ptr.arg_arg,&tmpary);
273 str_sset(str,*elem++);
274 for (; *elem; elem++) {
279 safefree((char*)tmpary);
288 int len = strlen(name);
289 register STIO *stio = stab->stab_io;
291 while (len && isspace(name[len-1]))
294 stio = stab->stab_io = stio_new();
296 if (stio->type == '|')
298 else if (stio->type != '-')
304 for (name++; isspace(*name); name++) ;
305 fp = popen(name,"w");
307 else if (*name == '>' && name[1] == '>') {
308 for (name += 2; isspace(*name); name++) ;
309 fp = fopen(name,"a");
311 else if (*name == '>') {
312 for (name++; isspace(*name); name++) ;
313 if (strEQ(name,"-")) {
318 fp = fopen(name,"w");
322 for (name++; isspace(*name); name++) ;
323 if (strEQ(name,"-")) {
328 fp = fopen(name,"r");
330 else if (name[len-1] == '|') {
332 while (len && isspace(name[len-1]))
334 for (; isspace(*name); name++) ;
335 fp = popen(name,"r");
340 for (; isspace(*name); name++) ;
341 if (strEQ(name,"-")) {
346 fp = fopen(name,"r");
351 if (stio->type != '|' && stio->type != '-') {
352 if (fstat(fileno(fp),&statbuf) < 0) {
356 if ((statbuf.st_mode & S_IFMT) != S_IFREG &&
357 (statbuf.st_mode & S_IFMT) != S_IFCHR) {
373 while (alen(stab->stab_array) >= 0L) {
374 str = ashift(stab->stab_array);
375 str_sset(stab->stab_val,str);
376 STABSET(stab->stab_val);
377 oldname = str_get(stab->stab_val);
378 if (do_open(stab,oldname)) {
381 str_cat(str,inplace);
383 rename(oldname,str->str_ptr);
385 UNLINK(str->str_ptr);
386 link(oldname,str->str_ptr);
390 sprintf(tokenbuf,">%s",oldname);
391 do_open(argvoutstab,tokenbuf);
392 defoutstab = argvoutstab;
395 return stab->stab_io->fp;
398 fprintf(stderr,"Can't open %s\n",str_get(str));
402 do_close(argvoutstab,FALSE);
403 defoutstab = stabent("stdout",TRUE);
409 do_close(stab,explicit)
414 register STIO *stio = stab->stab_io;
416 if (!stio) /* never opened */
419 if (stio->type == '|')
420 retval = (pclose(stio->fp) >= 0);
421 else if (stio->type == '-')
424 retval = (fclose(stio->fp) != EOF);
443 stio = stab->stab_io;
449 #ifdef STDSTDIO /* (the code works without this) */
450 if (stio->fp->_cnt) /* cheat a little, since */
451 return FALSE; /* this is the most usual case */
456 ungetc(ch, stio->fp);
459 if (stio->flags & IOF_ARGV) { /* not necessarily a real EOF yet? */
460 if (!nextargv(stab)) /* get another fp handy */
464 return TRUE; /* normal fp, definitely end of file */
479 stio = stab->stab_io;
480 if (!stio || !stio->fp)
483 return ftell(stio->fp);
487 do_seek(stab, pos, whence)
497 stio = stab->stab_io;
498 if (!stio || !stio->fp)
501 return fseek(stio->fp, pos, whence) >= 0;
504 do_stat(arg,sarg,retary)
510 static ARRAY *myarray = Null(ARRAY*);
516 myarray = ary = anew();
518 if (arg[1].arg_type == A_LVAL) {
519 tmpstab = arg[1].arg_ptr.arg_stab;
520 if (!tmpstab->stab_io ||
521 fstat(fileno(tmpstab->stab_io->fp),&statbuf) < 0) {
526 if (stat(str_get(sarg[1]),&statbuf) < 0)
531 apush(ary,str_nmake((double)statbuf.st_dev));
532 apush(ary,str_nmake((double)statbuf.st_ino));
533 apush(ary,str_nmake((double)statbuf.st_mode));
534 apush(ary,str_nmake((double)statbuf.st_nlink));
535 apush(ary,str_nmake((double)statbuf.st_uid));
536 apush(ary,str_nmake((double)statbuf.st_gid));
537 apush(ary,str_nmake((double)statbuf.st_rdev));
538 apush(ary,str_nmake((double)statbuf.st_size));
539 apush(ary,str_nmake((double)statbuf.st_atime));
540 apush(ary,str_nmake((double)statbuf.st_mtime));
541 apush(ary,str_nmake((double)statbuf.st_ctime));
542 apush(ary,str_nmake((double)statbuf.st_blksize));
543 apush(ary,str_nmake((double)statbuf.st_blocks));
545 sarg = (STR**)safemalloc((max+2)*sizeof(STR*));
547 sarg[max+1] = Nullstr;
548 for (i = 1; i <= max; i++)
549 sarg[i] = afetch(ary,i-1);
559 static ARRAY *myarray = Null(ARRAY*);
566 myarray = ary = anew();
568 if (times(×buf) < 0)
573 apush(ary,str_nmake(((double)timesbuf.tms_utime)/60.0));
574 apush(ary,str_nmake(((double)timesbuf.tms_stime)/60.0));
575 apush(ary,str_nmake(((double)timesbuf.tms_cutime)/60.0));
576 apush(ary,str_nmake(((double)timesbuf.tms_cstime)/60.0));
578 sarg = (STR**)safemalloc((max+2)*sizeof(STR*));
580 sarg[max+1] = Nullstr;
581 for (i = 1; i <= max; i++)
582 sarg[i] = afetch(ary,i-1);
588 do_time(tmbuf,retary)
593 static ARRAY *myarray = Null(ARRAY*);
601 myarray = ary = anew();
608 apush(ary,str_nmake((double)tmbuf->tm_sec));
609 apush(ary,str_nmake((double)tmbuf->tm_min));
610 apush(ary,str_nmake((double)tmbuf->tm_hour));
611 apush(ary,str_nmake((double)tmbuf->tm_mday));
612 apush(ary,str_nmake((double)tmbuf->tm_mon));
613 apush(ary,str_nmake((double)tmbuf->tm_year));
614 apush(ary,str_nmake((double)tmbuf->tm_wday));
615 apush(ary,str_nmake((double)tmbuf->tm_yday));
616 apush(ary,str_nmake((double)tmbuf->tm_isdst));
618 sarg = (STR**)safemalloc((max+2)*sizeof(STR*));
620 sarg[max+1] = Nullstr;
621 for (i = 1; i <= max; i++)
622 sarg[i] = afetch(ary,i-1);
629 do_sprintf(str,len,sarg)
640 len--; /* don't count pattern string */
642 for (s = str_get(*(sarg++)); *sarg && *s && len; len--) {
644 for (t = s; *t && *t != '%'; t++) ;
646 break; /* not enough % patterns, oh well */
647 for (t++; *sarg && *t && t != s; t++) {
661 case 'D': case 'X': case 'O':
664 case 'd': case 'x': case 'o': case 'c':
668 sprintf(buf,s,(long)str_gnum(*(sarg++)));
670 sprintf(buf,s,(int)str_gnum(*(sarg++)));
674 case 'E': case 'e': case 'f': case 'G': case 'g':
677 sprintf(buf,s,str_gnum(*(sarg++)));
684 sprintf(buf,s,str_get(*(sarg++)));
713 STR **tmpary; /* must not be register */
715 register bool retval;
718 (void)eval(arg[1].arg_ptr.arg_arg,&tmpary);
719 if (arg->arg_type == O_PRTF) {
720 do_sprintf(arg->arg_ptr.arg_str,32767,tmpary);
721 retval = do_print(str_get(arg->arg_ptr.arg_str),fp);
725 for (elem = tmpary+1; *elem; elem++) {
729 if ((*elem)->str_nok || str_gnum(*elem) != 0.0)
730 fprintf(fp, ofmt, str_gnum(*elem));
734 retval = do_print(str_get(*elem), fp);
739 retval = do_print(ors, fp);
741 safefree((char*)tmpary);
749 STR **tmpary; /* must not be register */
755 (void)eval(arg[1].arg_ptr.arg_arg,&tmpary);
757 for (elem = tmpary+1; *elem; elem++)
760 argv = (char**)safemalloc((i+1)*sizeof(char*));
762 for (elem = tmpary+1; *elem; elem++) {
763 *a++ = str_get(*elem);
766 execvp(argv[0],argv);
767 safefree((char*)argv);
769 safefree((char*)tmpary);
777 STR **tmpary; /* must not be register */
782 /* see if there are shell metacharacters in it */
784 for (s = cmd; *s; s++) {
785 if (*s != ' ' && !isalpha(*s) && index("$&*(){}[]'\";\\|?<>~`",*s)) {
786 execl("/bin/sh","sh","-c",cmd,0);
790 argv = (char**)safemalloc(((s - cmd) / 2 + 2)*sizeof(char*));
794 while (isspace(*s)) s++;
797 while (*s && !isspace(*s)) s++;
803 execvp(argv[0],argv);
804 safefree((char*)argv);
813 STR **tmpary; /* must not be register */
815 register STR *str = &str_no;
817 (void)eval(arg[1].arg_ptr.arg_arg,&tmpary);
818 for (elem = tmpary+1; *elem; elem++) {
823 safefree((char*)tmpary);
831 STR **tmpary; /* must not be register */
833 register STR *str = &str_no;
836 (void)eval(arg[1].arg_ptr.arg_arg,&tmpary);
838 for (elem = tmpary+1; *elem; elem++)
842 for (elem = tmpary+1; *elem; elem++) {
847 safefree((char*)tmpary);
855 STR **tmpary; /* must not be register */
864 (void)eval(arg[1].arg_ptr.arg_arg,&tmpary);
866 for (elem = tmpary+1; *elem; elem++)
871 val = (int)str_gnum(tmpary[1]);
872 for (elem = tmpary+2; *elem; elem++)
873 if (chmod(str_get(*elem),val))
880 val = (int)str_gnum(tmpary[1]);
881 val2 = (int)str_gnum(tmpary[2]);
882 for (elem = tmpary+3; *elem; elem++)
883 if (chown(str_get(*elem),val,val2))
891 val = (int)str_gnum(tmpary[1]);
894 for (elem = tmpary+2; *elem; elem++)
895 if (kill(atoi(str_get(*elem)),val))
900 for (elem = tmpary+1; *elem; elem++)
901 if (UNLINK(str_get(*elem)))
906 safefree((char*)tmpary);
913 register char **sarg;
918 savearray = defstab->stab_array;
919 defstab->stab_array = anew();
920 if (arg[1].arg_flags & AF_SPECIAL)
921 (void)do_push(arg,defstab->stab_array);
922 else if (arg[1].arg_type != A_NULL) {
924 str_sset(str,sarg[1]);
925 apush(defstab->stab_array,str);
927 str = cmd_exec(arg[2].arg_ptr.arg_stab->stab_sub);
928 afree(defstab->stab_array); /* put back old $_[] */
929 defstab->stab_array = savearray;
934 do_assign(retstr,arg)
938 STR **tmpary; /* must not be register */
939 register ARG *larg = arg[1].arg_ptr.arg_arg;
947 (void)eval(arg[2].arg_ptr.arg_arg,&tmpary);
949 if (arg->arg_flags & AF_COMMON) {
951 for (elem=tmpary+2; *elem; elem++) {
952 *elem = str_static(*elem);
956 if (larg->arg_type == O_LIST) {
957 lasti = larg->arg_len;
958 for (i=1,elem=tmpary+1; i <= lasti; i++) {
960 s = str_get(*(elem++));
963 switch (larg[i].arg_type) {
966 str = STAB_STR(larg[i].arg_ptr.arg_stab);
969 str = eval(larg[i].arg_ptr.arg_arg,Null(STR***));
975 i = elem - tmpary - 1;
977 else { /* should be an array name */
978 ary = larg[1].arg_ptr.arg_stab->stab_array;
979 for (i=0,elem=tmpary+1; *elem; i++) {
982 str_sset(str,*(elem++));
985 ary->ary_fill = i - 1; /* they can get the extra ones back by */
986 } /* setting an element larger than old fill */
987 str_numset(retstr,(double)i);
989 safefree((char*)tmpary);
993 do_kv(hash,kv,sarg,retary)
1002 static ARRAY *myarray = Null(ARRAY*);
1003 register HENT *entry;
1007 myarray = ary = anew();
1011 while (entry = hiternext(hash)) {
1014 apush(ary,str_make(hiterkey(entry)));
1016 apush(ary,str_make(str_get(hiterval(entry))));
1018 if (retary) { /* array wanted */
1019 sarg = (STR**)saferealloc((char*)sarg,(max+2)*sizeof(STR*));
1021 sarg[max+1] = Nullstr;
1022 for (i = 1; i <= max; i++)
1023 sarg[i] = afetch(ary,i-1);
1030 do_each(hash,sarg,retary)
1032 register STR **sarg;
1035 static STR *mystr = Nullstr;
1037 HENT *entry = hiternext(hash);
1044 if (retary) { /* array wanted */
1046 sarg = (STR**)saferealloc((char*)sarg,4*sizeof(STR*));
1049 sarg[1] = mystr = str_make(hiterkey(entry));
1050 retstr = sarg[2] = hiterval(entry);
1054 sarg = (STR**)saferealloc((char*)sarg,2*sizeof(STR*));
1056 sarg[1] = retstr = Nullstr;
1061 retstr = hiterval(entry);
1070 #define A(e1,e2,e3) (e1+(e2<<1)+(e3<<2))
1071 opargs[O_ITEM] = A(1,0,0);
1072 opargs[O_ITEM2] = A(0,0,0);
1073 opargs[O_ITEM3] = A(0,0,0);
1074 opargs[O_CONCAT] = A(1,1,0);
1075 opargs[O_MATCH] = A(1,0,0);
1076 opargs[O_NMATCH] = A(1,0,0);
1077 opargs[O_SUBST] = A(1,0,0);
1078 opargs[O_NSUBST] = A(1,0,0);
1079 opargs[O_ASSIGN] = A(1,1,0);
1080 opargs[O_MULTIPLY] = A(1,1,0);
1081 opargs[O_DIVIDE] = A(1,1,0);
1082 opargs[O_MODULO] = A(1,1,0);
1083 opargs[O_ADD] = A(1,1,0);
1084 opargs[O_SUBTRACT] = A(1,1,0);
1085 opargs[O_LEFT_SHIFT] = A(1,1,0);
1086 opargs[O_RIGHT_SHIFT] = A(1,1,0);
1087 opargs[O_LT] = A(1,1,0);
1088 opargs[O_GT] = A(1,1,0);
1089 opargs[O_LE] = A(1,1,0);
1090 opargs[O_GE] = A(1,1,0);
1091 opargs[O_EQ] = A(1,1,0);
1092 opargs[O_NE] = A(1,1,0);
1093 opargs[O_BIT_AND] = A(1,1,0);
1094 opargs[O_XOR] = A(1,1,0);
1095 opargs[O_BIT_OR] = A(1,1,0);
1096 opargs[O_AND] = A(1,0,0); /* don't eval arg 2 (yet) */
1097 opargs[O_OR] = A(1,0,0); /* don't eval arg 2 (yet) */
1098 opargs[O_COND_EXPR] = A(1,0,0); /* don't eval args 2 or 3 */
1099 opargs[O_COMMA] = A(1,1,0);
1100 opargs[O_NEGATE] = A(1,0,0);
1101 opargs[O_NOT] = A(1,0,0);
1102 opargs[O_COMPLEMENT] = A(1,0,0);
1103 opargs[O_WRITE] = A(1,0,0);
1104 opargs[O_OPEN] = A(1,1,0);
1105 opargs[O_TRANS] = A(1,0,0);
1106 opargs[O_NTRANS] = A(1,0,0);
1107 opargs[O_CLOSE] = A(0,0,0);
1108 opargs[O_ARRAY] = A(1,0,0);
1109 opargs[O_HASH] = A(1,0,0);
1110 opargs[O_LARRAY] = A(1,0,0);
1111 opargs[O_LHASH] = A(1,0,0);
1112 opargs[O_PUSH] = A(1,0,0);
1113 opargs[O_POP] = A(0,0,0);
1114 opargs[O_SHIFT] = A(0,0,0);
1115 opargs[O_SPLIT] = A(1,0,0);
1116 opargs[O_LENGTH] = A(1,0,0);
1117 opargs[O_SPRINTF] = A(1,0,0);
1118 opargs[O_SUBSTR] = A(1,1,1);
1119 opargs[O_JOIN] = A(1,0,0);
1120 opargs[O_SLT] = A(1,1,0);
1121 opargs[O_SGT] = A(1,1,0);
1122 opargs[O_SLE] = A(1,1,0);
1123 opargs[O_SGE] = A(1,1,0);
1124 opargs[O_SEQ] = A(1,1,0);
1125 opargs[O_SNE] = A(1,1,0);
1126 opargs[O_SUBR] = A(1,0,0);
1127 opargs[O_PRINT] = A(1,0,0);
1128 opargs[O_CHDIR] = A(1,0,0);
1129 opargs[O_DIE] = A(1,0,0);
1130 opargs[O_EXIT] = A(1,0,0);
1131 opargs[O_RESET] = A(1,0,0);
1132 opargs[O_LIST] = A(0,0,0);
1133 opargs[O_EOF] = A(0,0,0);
1134 opargs[O_TELL] = A(0,0,0);
1135 opargs[O_SEEK] = A(0,1,1);
1136 opargs[O_LAST] = A(1,0,0);
1137 opargs[O_NEXT] = A(1,0,0);
1138 opargs[O_REDO] = A(1,0,0);
1139 opargs[O_GOTO] = A(1,0,0);
1140 opargs[O_INDEX] = A(1,1,0);
1141 opargs[O_TIME] = A(0,0,0);
1142 opargs[O_TMS] = A(0,0,0);
1143 opargs[O_LOCALTIME] = A(1,0,0);
1144 opargs[O_GMTIME] = A(1,0,0);
1145 opargs[O_STAT] = A(1,0,0);
1146 opargs[O_CRYPT] = A(1,1,0);
1147 opargs[O_EXP] = A(1,0,0);
1148 opargs[O_LOG] = A(1,0,0);
1149 opargs[O_SQRT] = A(1,0,0);
1150 opargs[O_INT] = A(1,0,0);
1151 opargs[O_PRTF] = A(1,0,0);
1152 opargs[O_ORD] = A(1,0,0);
1153 opargs[O_SLEEP] = A(1,0,0);
1154 opargs[O_FLIP] = A(1,0,0);
1155 opargs[O_FLOP] = A(0,1,0);
1156 opargs[O_KEYS] = A(0,0,0);
1157 opargs[O_VALUES] = A(0,0,0);
1158 opargs[O_EACH] = A(0,0,0);
1159 opargs[O_CHOP] = A(1,0,0);
1160 opargs[O_FORK] = A(1,0,0);
1161 opargs[O_EXEC] = A(1,0,0);
1162 opargs[O_SYSTEM] = A(1,0,0);
1163 opargs[O_OCT] = A(1,0,0);
1164 opargs[O_HEX] = A(1,0,0);
1165 opargs[O_CHMOD] = A(1,0,0);
1166 opargs[O_CHOWN] = A(1,0,0);
1167 opargs[O_KILL] = A(1,0,0);
1168 opargs[O_RENAME] = A(1,1,0);
1169 opargs[O_UNLINK] = A(1,0,0);
1170 opargs[O_UMASK] = A(1,0,0);
1171 opargs[O_UNSHIFT] = A(1,0,0);
1172 opargs[O_LINK] = A(1,1,0);
1173 opargs[O_REPEAT] = A(1,1,0);
1176 static int (*ihand)();
1177 static int (*qhand)();
1182 STR ***retary; /* where to return an array to, null if nowhere */
1186 register int optype;
1187 register int maxarg;
1190 register STR **sarg = quicksarg;
1191 register char *tmps;
1200 bool assigning = FALSE;
1201 double exp(), log(), sqrt(), modf();
1202 char *crypt(), *getenv();
1206 str = arg->arg_ptr.arg_str;
1207 optype = arg->arg_type;
1208 maxarg = arg->arg_len;
1209 if (maxarg > 3 || retary) {
1210 sarg = (STR **)safemalloc((maxarg+2) * sizeof(STR*));
1214 deb("%s (%lx) %d args:\n",opname[optype],arg,maxarg);
1216 debname[dlevel] = opname[optype][0];
1217 debdelim[dlevel++] = ':';
1219 for (anum = 1; anum <= maxarg; anum++) {
1220 argflags = arg[anum].arg_flags;
1221 if (argflags & AF_SPECIAL)
1224 switch (arg[anum].arg_type) {
1226 sarg[anum] = &str_no;
1235 deb("%d.EXPR =>\n",anum);
1238 sarg[anum] = eval(arg[anum].arg_ptr.arg_arg, Null(STR***));
1244 deb("%d.CMD (%lx) =>\n",anum,arg[anum].arg_ptr.arg_cmd);
1247 sarg[anum] = cmd_exec(arg[anum].arg_ptr.arg_cmd);
1250 sarg[anum] = STAB_STR(arg[anum].arg_ptr.arg_stab);
1253 sprintf(buf,"STAB $%s ==",arg[anum].arg_ptr.arg_stab->stab_name);
1262 deb("%d.LEXPR =>\n",anum);
1265 str = eval(arg[anum].arg_ptr.arg_arg,Null(STR***));
1267 fatal("panic: A_LEXPR\n");
1272 sprintf(buf,"LVAL $%s ==",arg[anum].arg_ptr.arg_stab->stab_name);
1276 str = STAB_STR(arg[anum].arg_ptr.arg_stab);
1278 fatal("panic: A_LVAL\n");
1281 if (argflags & AF_PRE) {
1282 if (argflags & AF_UP)
1288 str = arg->arg_ptr.arg_str;
1290 else if (argflags & AF_POST) {
1291 sarg[anum] = str_static(str);
1292 if (argflags & AF_UP)
1297 str = arg->arg_ptr.arg_str;
1304 sarg[anum] = str_static(&str_no);
1305 str_numset(sarg[anum],
1306 (double)alen(arg[anum].arg_ptr.arg_stab->stab_array));
1312 sarg[anum] = arg[anum].arg_ptr.arg_str;
1318 (void) interp(str,str_get(arg[anum].arg_ptr.arg_str));
1325 tmps = str_get(arg[anum].arg_ptr.arg_str);
1326 fp = popen(str_get(interp(str,tmps)),"r");
1327 tmpstr = str_new(80);
1330 while (str_gets(tmpstr,fp) != Nullch) {
1331 str_scat(str,tmpstr);
1333 statusvalue = pclose(fp);
1346 last_in_stab = arg[anum].arg_ptr.arg_stab;
1347 if (last_in_stab->stab_io) {
1348 fp = last_in_stab->stab_io->fp;
1349 if (!fp && (last_in_stab->stab_io->flags & IOF_ARGV)) {
1350 if (last_in_stab->stab_io->flags & IOF_START) {
1351 last_in_stab->stab_io->flags &= ~IOF_START;
1352 last_in_stab->stab_io->lines = 0;
1353 if (alen(last_in_stab->stab_array) < 0L) {
1354 tmpstr = str_make("-"); /* assume stdin */
1355 apush(last_in_stab->stab_array, tmpstr);
1358 fp = nextargv(last_in_stab);
1359 if (!fp) /* Note: fp != last_in_stab->stab_io->fp */
1360 do_close(last_in_stab,FALSE); /* now it does */
1365 sarg[anum] = &str_no;
1366 else if (!str_gets(str,fp)) {
1367 if (last_in_stab->stab_io->flags & IOF_ARGV) {
1368 fp = nextargv(last_in_stab);
1371 do_close(last_in_stab,FALSE);
1372 last_in_stab->stab_io->flags |= IOF_START;
1377 sarg[anum] = &str_no;
1381 last_in_stab->stab_io->lines++;
1391 deb("%d.%s = '%s'\n",anum,tmps,str_peek(sarg[anum]));
1397 str_sset(str,sarg[1]);
1402 str_sset(str,sarg[2]);
1407 str_sset(str,sarg[3]);
1412 str_sset(str,sarg[1]);
1413 str_scat(str,sarg[2]);
1418 str_sset(str,sarg[1]);
1419 anum = (long)str_gnum(sarg[2]);
1421 tmpstr = str_new(0);
1422 str_sset(tmpstr,str);
1423 for (anum--; anum; anum--)
1424 str_scat(str,tmpstr);
1427 str_sset(str,&str_no);
1431 str_set(str, do_match(str_get(sarg[1]),arg) ? Yes : No);
1435 str_set(str, do_match(str_get(sarg[1]),arg) ? No : Yes);
1439 value = (double) do_subst(str, arg);
1440 str = arg->arg_ptr.arg_str;
1443 str_set(arg->arg_ptr.arg_str, do_subst(str, arg) ? No : Yes);
1444 str = arg->arg_ptr.arg_str;
1447 if (arg[2].arg_flags & AF_SPECIAL)
1451 str_sset(str, sarg[2]);
1456 tmps = str_get(str);
1457 tmps += str->str_cur - (str->str_cur != 0);
1458 str_set(arg->arg_ptr.arg_str,tmps); /* remember last char */
1459 *tmps = '\0'; /* wipe it out */
1460 str->str_cur = tmps - str->str_ptr;
1462 str = arg->arg_ptr.arg_str;
1465 value = str_gnum(sarg[1]);
1466 value *= str_gnum(sarg[2]);
1469 value = str_gnum(sarg[1]);
1470 value /= str_gnum(sarg[2]);
1473 value = str_gnum(sarg[1]);
1474 value = (double)(((long)value) % (long)str_gnum(sarg[2]));
1477 value = str_gnum(sarg[1]);
1478 value += str_gnum(sarg[2]);
1481 value = str_gnum(sarg[1]);
1482 value -= str_gnum(sarg[2]);
1485 value = str_gnum(sarg[1]);
1486 value = (double)(((long)value) << (long)str_gnum(sarg[2]));
1489 value = str_gnum(sarg[1]);
1490 value = (double)(((long)value) >> (long)str_gnum(sarg[2]));
1493 value = str_gnum(sarg[1]);
1494 value = (double)(value < str_gnum(sarg[2]));
1497 value = str_gnum(sarg[1]);
1498 value = (double)(value > str_gnum(sarg[2]));
1501 value = str_gnum(sarg[1]);
1502 value = (double)(value <= str_gnum(sarg[2]));
1505 value = str_gnum(sarg[1]);
1506 value = (double)(value >= str_gnum(sarg[2]));
1509 value = str_gnum(sarg[1]);
1510 value = (double)(value == str_gnum(sarg[2]));
1513 value = str_gnum(sarg[1]);
1514 value = (double)(value != str_gnum(sarg[2]));
1517 value = str_gnum(sarg[1]);
1518 value = (double)(((long)value) & (long)str_gnum(sarg[2]));
1521 value = str_gnum(sarg[1]);
1522 value = (double)(((long)value) ^ (long)str_gnum(sarg[2]));
1525 value = str_gnum(sarg[1]);
1526 value = (double)(((long)value) | (long)str_gnum(sarg[2]));
1529 if (str_true(sarg[1])) {
1533 argflags = arg[anum].arg_flags;
1538 str_sset(str, sarg[1]);
1546 if (str_true(sarg[1])) {
1548 str_set(str, sarg[1]);
1559 argflags = arg[anum].arg_flags;
1563 anum = (str_true(sarg[1]) ? 2 : 3);
1564 optype = (anum == 2 ? O_ITEM2 : O_ITEM3);
1566 argflags = arg[anum].arg_flags;
1572 value = -str_gnum(sarg[1]);
1575 value = (double) !str_true(sarg[1]);
1578 value = (double) ~(long)str_gnum(sarg[1]);
1581 if (arg[1].arg_type == A_LVAL)
1582 defoutstab = arg[1].arg_ptr.arg_stab;
1584 defoutstab = stabent(str_get(sarg[1]),TRUE);
1585 if (!defoutstab->stab_io)
1586 defoutstab->stab_io = stio_new();
1587 curoutstab = defoutstab;
1588 str_set(str,curoutstab->stab_io->fp ? Yes : No);
1594 else if (arg[1].arg_type == A_LVAL)
1595 stab = arg[1].arg_ptr.arg_stab;
1597 stab = stabent(str_get(sarg[1]),TRUE);
1598 if (!stab->stab_io) {
1604 fp = stab->stab_io->fp;
1606 if (stab->stab_io->fmt_stab)
1607 form = stab->stab_io->fmt_stab->stab_form;
1609 form = stab->stab_form;
1615 format(&outrec,form);
1616 do_write(&outrec,stab->stab_io);
1617 if (stab->stab_io->flags & IOF_FLUSH)
1623 if (do_open(arg[1].arg_ptr.arg_stab,str_get(sarg[2]))) {
1625 arg[1].arg_ptr.arg_stab->stab_io->lines = 0;
1632 value = (double) do_trans(str,arg);
1633 str = arg->arg_ptr.arg_str;
1636 str_set(arg->arg_ptr.arg_str, do_trans(str,arg) == 0 ? Yes : No);
1637 str = arg->arg_ptr.arg_str;
1641 do_close(arg[1].arg_ptr.arg_stab,TRUE) ? Yes : No );
1645 str_sset(str,do_each(arg[1].arg_ptr.arg_stab->stab_hash,sarg,retary));
1646 retary = Null(STR***); /* do_each already did retary */
1651 value = (double) do_kv(arg[1].arg_ptr.arg_stab->stab_hash,
1652 optype,sarg,retary);
1653 retary = Null(STR***); /* do_keys already did retary */
1657 ary = arg[1].arg_ptr.arg_stab->stab_array;
1658 maxarg = ary->ary_fill;
1659 if (retary) { /* array wanted */
1661 (STR **)saferealloc((char*)sarg,(maxarg+3)*sizeof(STR*));
1662 for (anum = 0; anum <= maxarg; anum++) {
1663 sarg[anum+1] = str = afetch(ary,anum);
1668 str = afetch(ary,maxarg);
1671 str = afetch(arg[2].arg_ptr.arg_stab->stab_array,
1672 ((int)str_gnum(sarg[1])) - arybase);
1677 tmpstab = arg[2].arg_ptr.arg_stab; /* XXX */
1678 str = hfetch(tmpstab->stab_hash,str_get(sarg[1]));
1683 anum = ((int)str_gnum(sarg[1])) - arybase;
1684 str = afetch(arg[2].arg_ptr.arg_stab->stab_array,anum);
1685 if (!str || str == &str_no) {
1687 astore(arg[2].arg_ptr.arg_stab->stab_array,anum,str);
1691 tmpstab = arg[2].arg_ptr.arg_stab;
1692 str = hfetch(tmpstab->stab_hash,str_get(sarg[1]));
1695 hstore(tmpstab->stab_hash,str_get(sarg[1]),str);
1697 if (tmpstab == envstab) { /* heavy wizardry going on here */
1698 str->str_link.str_magic = tmpstab;/* str is now magic */
1699 envname = savestr(str_get(sarg[1]));
1700 /* he threw the brick up into the air */
1702 else if (tmpstab == sigstab) { /* same thing, only different */
1703 str->str_link.str_magic = tmpstab;
1704 signame = savestr(str_get(sarg[1]));
1708 if (arg[1].arg_flags & AF_SPECIAL)
1709 str = do_push(arg,arg[2].arg_ptr.arg_stab->stab_array);
1711 str = str_new(0); /* must copy the STR */
1712 str_sset(str,sarg[1]);
1713 apush(arg[2].arg_ptr.arg_stab->stab_array,str);
1717 str = apop(arg[1].arg_ptr.arg_stab->stab_array);
1721 *(arg->arg_ptr.arg_str) = *str;
1723 bcopy((char*)str, (char*)arg->arg_ptr.arg_str, sizeof *str);
1725 safefree((char*)str);
1726 str = arg->arg_ptr.arg_str;
1729 str = ashift(arg[1].arg_ptr.arg_stab->stab_array);
1733 *(arg->arg_ptr.arg_str) = *str;
1735 bcopy((char*)str, (char*)arg->arg_ptr.arg_str, sizeof *str);
1737 safefree((char*)str);
1738 str = arg->arg_ptr.arg_str;
1741 value = (double) do_split(str_get(sarg[1]),arg[2].arg_ptr.arg_spat,retary);
1742 retary = Null(STR***); /* do_split already did retary */
1745 value = (double) str_len(sarg[1]);
1748 sarg[maxarg+1] = Nullstr;
1749 do_sprintf(str,arg->arg_len,sarg);
1752 anum = ((int)str_gnum(sarg[2])) - arybase;
1753 for (tmps = str_get(sarg[1]); *tmps && anum > 0; tmps++,anum--) ;
1754 anum = (int)str_gnum(sarg[3]);
1755 if (anum >= 0 && strlen(tmps) > anum)
1756 str_nset(str, tmps, anum);
1761 if (arg[2].arg_flags & AF_SPECIAL && arg[2].arg_type == A_EXPR)
1762 do_join(arg,str_get(sarg[1]),str);
1764 ajoin(arg[2].arg_ptr.arg_stab->stab_array,str_get(sarg[1]),str);
1767 tmps = str_get(sarg[1]);
1768 value = (double) strLT(tmps,str_get(sarg[2]));
1771 tmps = str_get(sarg[1]);
1772 value = (double) strGT(tmps,str_get(sarg[2]));
1775 tmps = str_get(sarg[1]);
1776 value = (double) strLE(tmps,str_get(sarg[2]));
1779 tmps = str_get(sarg[1]);
1780 value = (double) strGE(tmps,str_get(sarg[2]));
1783 tmps = str_get(sarg[1]);
1784 value = (double) strEQ(tmps,str_get(sarg[2]));
1787 tmps = str_get(sarg[1]);
1788 value = (double) strNE(tmps,str_get(sarg[2]));
1791 str_sset(str,do_subr(arg,sarg));
1799 stab = arg[2].arg_ptr.arg_stab;
1805 else if (arg[1].arg_flags & AF_SPECIAL)
1806 value = (double)do_aprint(arg,stab->stab_io->fp);
1808 value = (double)do_print(str_get(sarg[1]),stab->stab_io->fp);
1809 if (ors && optype == O_PRINT)
1810 do_print(ors, stab->stab_io->fp);
1812 if (stab->stab_io->flags & IOF_FLUSH)
1813 fflush(stab->stab_io->fp);
1816 tmps = str_get(sarg[1]);
1817 if (!tmps || !*tmps)
1818 tmps = getenv("HOME");
1819 if (!tmps || !*tmps)
1820 tmps = getenv("LOGDIR");
1821 value = (double)(chdir(tmps) >= 0);
1824 tmps = str_get(sarg[1]);
1825 if (!tmps || !*tmps)
1827 fatal("%s\n",str_get(sarg[1]));
1831 exit((int)str_gnum(sarg[1]));
1835 str_reset(str_get(sarg[1]));
1840 str = sarg[maxarg]; /* unwanted list, return last item */
1845 str_set(str, do_eof(maxarg > 0 ? arg[1].arg_ptr.arg_stab : last_in_stab) ? Yes : No);
1849 value = (double)do_tell(maxarg > 0 ? arg[1].arg_ptr.arg_stab : last_in_stab);
1853 value = str_gnum(sarg[2]);
1854 str_set(str, do_seek(arg[1].arg_ptr.arg_stab,
1855 (long)value, (int)str_gnum(sarg[3]) ) ? Yes : No);
1862 tmps = str_get(sarg[1]);
1863 while (loop_ptr >= 0 && (!loop_stack[loop_ptr].loop_label ||
1864 strNE(tmps,loop_stack[loop_ptr].loop_label) )) {
1867 deb("(Skipping label #%d %s)\n",loop_ptr,
1868 loop_stack[loop_ptr].loop_label);
1875 deb("(Found label #%d %s)\n",loop_ptr,
1876 loop_stack[loop_ptr].loop_label);
1881 fatal("Bad label: %s\n", maxarg > 0 ? tmps : "<null>");
1882 longjmp(loop_stack[loop_ptr].loop_env, optype);
1883 case O_GOTO:/* shudder */
1884 goto_targ = str_get(sarg[1]);
1885 longjmp(top_env, 1);
1887 tmps = str_get(sarg[1]);
1888 if (!(tmps2 = instr(tmps,str_get(sarg[2]))))
1889 value = (double)(-1 + arybase);
1891 value = (double)(tmps2 - tmps + arybase);
1894 value = (double) time(0);
1897 value = (double) do_tms(retary);
1898 retary = Null(STR***); /* do_tms already did retary */
1901 tmplong = (long) str_gnum(sarg[1]);
1902 value = (double) do_time(localtime(&tmplong),retary);
1903 retary = Null(STR***); /* do_localtime already did retary */
1906 tmplong = (long) str_gnum(sarg[1]);
1907 value = (double) do_time(gmtime(&tmplong),retary);
1908 retary = Null(STR***); /* do_gmtime already did retary */
1911 value = (double) do_stat(arg,sarg,retary);
1912 retary = Null(STR***); /* do_stat already did retary */
1915 tmps = str_get(sarg[1]);
1916 str_set(str,crypt(tmps,str_get(sarg[2])));
1919 value = exp(str_gnum(sarg[1]));
1922 value = log(str_gnum(sarg[1]));
1925 value = sqrt(str_gnum(sarg[1]));
1928 modf(str_gnum(sarg[1]),&value);
1931 value = (double) *str_get(sarg[1]);
1934 tmps = str_get(sarg[1]);
1936 if (!tmps || !*tmps)
1937 sleep((32767<<16)+32767);
1940 value = (double)tmplong;
1942 value = ((double)tmplong) - value;
1945 if (str_true(sarg[1])) {
1946 str_numset(str,0.0);
1948 arg->arg_type = optype = O_FLOP;
1950 arg[2].arg_flags &= ~AF_SPECIAL;
1951 arg[1].arg_flags |= AF_SPECIAL;
1952 argflags = arg[anum].arg_flags;
1959 if (str_true(sarg[2])) {
1960 arg->arg_type = O_FLIP;
1961 arg[1].arg_flags &= ~AF_SPECIAL;
1962 arg[2].arg_flags |= AF_SPECIAL;
1967 value = (double)fork();
1970 if (anum = vfork()) {
1971 ihand = signal(SIGINT, SIG_IGN);
1972 qhand = signal(SIGQUIT, SIG_IGN);
1973 while ((maxarg = wait(&argflags)) != anum && maxarg != -1)
1977 signal(SIGINT, ihand);
1978 signal(SIGQUIT, qhand);
1979 value = (double)argflags;
1984 if (arg[1].arg_flags & AF_SPECIAL)
1985 value = (double)do_aexec(arg);
1987 value = (double)do_exec(str_get(sarg[1]));
1999 tmps = str_get(sarg[1]);
2008 case '0': case '1': case '2': case '3': case '4':
2009 case '5': case '6': case '7':
2011 anum += *tmps++ & 15;
2013 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
2014 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
2018 anum += (*tmps++ & 7) + 9;
2027 value = (double)anum;
2033 if (arg[1].arg_flags & AF_SPECIAL)
2034 value = (double)apply(optype,arg,Null(STR**));
2037 value = (double)apply(optype,arg,sarg);
2041 value = (double)umask((int)str_gnum(sarg[1]));
2044 tmps = str_get(sarg[1]);
2046 value = (double)(rename(tmps,str_get(sarg[2])) >= 0);
2048 tmps2 = str_get(sarg[2]);
2050 if (!(anum = link(tmps,tmps2)))
2051 anum = UNLINK(tmps);
2052 value = (double)(anum >= 0);
2056 tmps = str_get(sarg[1]);
2057 value = (double)(link(tmps,str_get(sarg[2])) >= 0);
2060 ary = arg[2].arg_ptr.arg_stab->stab_array;
2061 if (arg[1].arg_flags & AF_SPECIAL)
2062 do_unshift(arg,ary);
2064 str = str_new(0); /* must copy the STR */
2065 str_sset(str,sarg[1]);
2069 value = (double)(ary->ary_fill + 1);
2075 deb("%s RETURNS \"%s\"\n",opname[optype],str_get(str));
2080 str_numset(str,value);
2085 deb("%s RETURNS \"%f\"\n",opname[optype],value);
2089 if (sarg != quicksarg) {
2091 if (optype == O_LIST)
2095 sarg[maxarg+1] = Nullstr;
2096 *retary = sarg; /* up to them to free it */
2108 deb("%s RETURNS ()\n",opname[optype],value);