perl 1.0 patch 12: scripts made by a2p doen't handle leading white space right on...
[p5sagit/p5-mst-13.2.git] / arg.c
1 /* $Header: arg.c,v 1.0.1.6 88/02/01 17:32:26 root Exp $
2  *
3  * $Log:        arg.c,v $
4  * Revision 1.0.1.6  88/02/01  17:32:26  root
5  * patch12: made split(' ') behave like awk in ignoring leading white space.
6  * 
7  * Revision 1.0.1.5  88/01/30  08:53:16  root
8  * patch9: fixed some missing right parens introduced (?) by patch 2
9  * 
10  * Revision 1.0.1.4  88/01/28  10:22:06  root
11  * patch8: added eval operator.
12  * 
13  * Revision 1.0.1.2  88/01/24  03:52:34  root
14  * patch 2: added STATBLKS dependencies.
15  * 
16  * Revision 1.0.1.1  88/01/21  21:27:10  root
17  * Now defines signal return values correctly using VOIDSIG.
18  * 
19  * Revision 1.0  87/12/18  13:04:33  root
20  * Initial revision
21  * 
22  */
23
24 #include <signal.h>
25 #include "handy.h"
26 #include "EXTERN.h"
27 #include "search.h"
28 #include "util.h"
29 #include "perl.h"
30
31 ARG *debarg;
32
33 bool
34 do_match(s,arg)
35 register char *s;
36 register ARG *arg;
37 {
38     register SPAT *spat = arg[2].arg_ptr.arg_spat;
39     register char *d;
40     register char *t;
41
42     if (!spat || !s)
43         fatal("panic: do_match\n");
44     if (spat->spat_flags & SPAT_USED) {
45 #ifdef DEBUGGING
46         if (debug & 8)
47             deb("2.SPAT USED\n");
48 #endif
49         return FALSE;
50     }
51     if (spat->spat_runtime) {
52         t = str_get(eval(spat->spat_runtime,Null(STR***)));
53 #ifdef DEBUGGING
54         if (debug & 8)
55             deb("2.SPAT /%s/\n",t);
56 #endif
57         if (d = compile(&spat->spat_compex,t,TRUE,FALSE)) {
58 #ifdef DEBUGGING
59             deb("/%s/: %s\n", t, d);
60 #endif
61             return FALSE;
62         }
63         if (spat->spat_compex.complen <= 1 && curspat)
64             spat = curspat;
65         if (execute(&spat->spat_compex, s, TRUE, 0)) {
66             if (spat->spat_compex.numsubs)
67                 curspat = spat;
68             return TRUE;
69         }
70         else
71             return FALSE;
72     }
73     else {
74 #ifdef DEBUGGING
75         if (debug & 8) {
76             char ch;
77
78             if (spat->spat_flags & SPAT_USE_ONCE)
79                 ch = '?';
80             else
81                 ch = '/';
82             deb("2.SPAT %c%s%c\n",ch,spat->spat_compex.precomp,ch);
83         }
84 #endif
85         if (spat->spat_compex.complen <= 1 && curspat)
86             spat = curspat;
87         if (spat->spat_first) {
88             if (spat->spat_flags & SPAT_SCANFIRST) {
89                 str_free(spat->spat_first);
90                 spat->spat_first = Nullstr;     /* disable optimization */
91             }
92             else if (*spat->spat_first->str_ptr != *s ||
93               strnNE(spat->spat_first->str_ptr, s, spat->spat_flen) )
94                 return FALSE;
95         }
96         if (execute(&spat->spat_compex, s, TRUE, 0)) {
97             if (spat->spat_compex.numsubs)
98                 curspat = spat;
99             if (spat->spat_flags & SPAT_USE_ONCE)
100                 spat->spat_flags |= SPAT_USED;
101             return TRUE;
102         }
103         else
104             return FALSE;
105     }
106     /*NOTREACHED*/
107 }
108
109 int
110 do_subst(str,arg)
111 STR *str;
112 register ARG *arg;
113 {
114     register SPAT *spat;
115     register STR *dstr;
116     register char *s;
117     register char *m;
118
119     spat = arg[2].arg_ptr.arg_spat;
120     s = str_get(str);
121     if (!spat || !s)
122         fatal("panic: do_subst\n");
123     else if (spat->spat_runtime) {
124         char *d;
125
126         m = str_get(eval(spat->spat_runtime,Null(STR***)));
127         if (d = compile(&spat->spat_compex,m,TRUE,FALSE)) {
128 #ifdef DEBUGGING
129             deb("/%s/: %s\n", m, d);
130 #endif
131             return 0;
132         }
133     }
134 #ifdef DEBUGGING
135     if (debug & 8) {
136         deb("2.SPAT /%s/\n",spat->spat_compex.precomp);
137     }
138 #endif
139     if (spat->spat_compex.complen <= 1 && curspat)
140         spat = curspat;
141     if (spat->spat_first) {
142         if (spat->spat_flags & SPAT_SCANFIRST) {
143             str_free(spat->spat_first);
144             spat->spat_first = Nullstr; /* disable optimization */
145         }
146         else if (*spat->spat_first->str_ptr != *s ||
147           strnNE(spat->spat_first->str_ptr, s, spat->spat_flen) )
148             return 0;
149     }
150     if (m = execute(&spat->spat_compex, s, TRUE, 1)) {
151         int iters = 0;
152
153         dstr = str_new(str_len(str));
154         if (spat->spat_compex.numsubs)
155             curspat = spat;
156         do {
157             if (iters++ > 10000)
158                 fatal("Substitution loop?\n");
159             if (spat->spat_compex.numsubs)
160                 s = spat->spat_compex.subbase;
161             str_ncat(dstr,s,m-s);
162             s = spat->spat_compex.subend[0];
163             str_scat(dstr,eval(spat->spat_repl,Null(STR***)));
164             if (spat->spat_flags & SPAT_USE_ONCE)
165                 break;
166         } while (m = execute(&spat->spat_compex, s, FALSE, 1));
167         str_cat(dstr,s);
168         str_replace(str,dstr);
169         STABSET(str);
170         return iters;
171     }
172     return 0;
173 }
174
175 int
176 do_trans(str,arg)
177 STR *str;
178 register ARG *arg;
179 {
180     register char *tbl;
181     register char *s;
182     register int matches = 0;
183     register int ch;
184
185     tbl = arg[2].arg_ptr.arg_cval;
186     s = str_get(str);
187     if (!tbl || !s)
188         fatal("panic: do_trans\n");
189 #ifdef DEBUGGING
190     if (debug & 8) {
191         deb("2.TBL\n");
192     }
193 #endif
194     while (*s) {
195         if (ch = tbl[*s & 0377]) {
196             matches++;
197             *s = ch;
198         }
199         s++;
200     }
201     STABSET(str);
202     return matches;
203 }
204
205 int
206 do_split(s,spat,retary)
207 register char *s;
208 register SPAT *spat;
209 STR ***retary;
210 {
211     register STR *dstr;
212     register char *m;
213     register ARRAY *ary;
214     static ARRAY *myarray = Null(ARRAY*);
215     int iters = 0;
216     STR **sarg;
217     register char *e;
218     int i;
219
220     if (!spat || !s)
221         fatal("panic: do_split\n");
222     else if (spat->spat_runtime) {
223         char *d;
224
225         m = str_get(eval(spat->spat_runtime,Null(STR***)));
226         if (!*m || (*m == ' ' && !m[1])) {
227             m = "[ \\t\\n]+";
228             while (isspace(*s)) s++;
229         }
230         if (spat->spat_runtime->arg_type == O_ITEM &&
231           spat->spat_runtime[1].arg_type == A_SINGLE) {
232             arg_free(spat->spat_runtime);       /* it won't change, so */
233             spat->spat_runtime = Nullarg;       /* no point compiling again */
234         }
235         if (d = compile(&spat->spat_compex,m,TRUE,FALSE)) {
236 #ifdef DEBUGGING
237             deb("/%s/: %s\n", m, d);
238 #endif
239             return FALSE;
240         }
241     }
242 #ifdef DEBUGGING
243     if (debug & 8) {
244         deb("2.SPAT /%s/\n",spat->spat_compex.precomp);
245     }
246 #endif
247     if (retary)
248         ary = myarray;
249     else
250         ary = spat->spat_repl[1].arg_ptr.arg_stab->stab_array;
251     if (!ary)
252         myarray = ary = anew();
253     ary->ary_fill = -1;
254     while (*s && (m = execute(&spat->spat_compex, s, (iters == 0), 1))) {
255         if (spat->spat_compex.numsubs)
256             s = spat->spat_compex.subbase;
257         dstr = str_new(m-s);
258         str_nset(dstr,s,m-s);
259         astore(ary, iters++, dstr);
260         if (iters > 10000)
261             fatal("Substitution loop?\n");
262         s = spat->spat_compex.subend[0];
263     }
264     if (*s) {                   /* ignore field after final "whitespace" */
265         dstr = str_new(0);      /*   if they interpolate, it's null anyway */
266         str_set(dstr,s);
267         astore(ary, iters++, dstr);
268     }
269     else {
270         while (iters > 0 && !*str_get(afetch(ary,iters-1)))
271             iters--;
272     }
273     if (retary) {
274         sarg = (STR**)safemalloc((iters+2)*sizeof(STR*));
275
276         sarg[0] = Nullstr;
277         sarg[iters+1] = Nullstr;
278         for (i = 1; i <= iters; i++)
279             sarg[i] = afetch(ary,i-1);
280         *retary = sarg;
281     }
282     return iters;
283 }
284
285 void
286 do_join(arg,delim,str)
287 register ARG *arg;
288 register char *delim;
289 register STR *str;
290 {
291     STR **tmpary;       /* must not be register */
292     register STR **elem;
293
294     (void)eval(arg[2].arg_ptr.arg_arg,&tmpary);
295     elem = tmpary+1;
296     if (*elem)
297     str_sset(str,*elem++);
298     for (; *elem; elem++) {
299         str_cat(str,delim);
300         str_scat(str,*elem);
301     }
302     STABSET(str);
303     safefree((char*)tmpary);
304 }
305
306 bool
307 do_open(stab,name)
308 STAB *stab;
309 register char *name;
310 {
311     FILE *fp;
312     int len = strlen(name);
313     register STIO *stio = stab->stab_io;
314
315     while (len && isspace(name[len-1]))
316         name[--len] = '\0';
317     if (!stio)
318         stio = stab->stab_io = stio_new();
319     if (stio->fp) {
320         if (stio->type == '|')
321             pclose(stio->fp);
322         else if (stio->type != '-')
323             fclose(stio->fp);
324         stio->fp = Nullfp;
325     }
326     stio->type = *name;
327     if (*name == '|') {
328         for (name++; isspace(*name); name++) ;
329         fp = popen(name,"w");
330     }
331     else if (*name == '>' && name[1] == '>') {
332         for (name += 2; isspace(*name); name++) ;
333         fp = fopen(name,"a");
334     }
335     else if (*name == '>') {
336         for (name++; isspace(*name); name++) ;
337         if (strEQ(name,"-")) {
338             fp = stdout;
339             stio->type = '-';
340         }
341         else
342             fp = fopen(name,"w");
343     }
344     else {
345         if (*name == '<') {
346             for (name++; isspace(*name); name++) ;
347             if (strEQ(name,"-")) {
348                 fp = stdin;
349                 stio->type = '-';
350             }
351             else
352                 fp = fopen(name,"r");
353         }
354         else if (name[len-1] == '|') {
355             name[--len] = '\0';
356             while (len && isspace(name[len-1]))
357                 name[--len] = '\0';
358             for (; isspace(*name); name++) ;
359             fp = popen(name,"r");
360             stio->type = '|';
361         }
362         else {
363             stio->type = '<';
364             for (; isspace(*name); name++) ;
365             if (strEQ(name,"-")) {
366                 fp = stdin;
367                 stio->type = '-';
368             }
369             else
370                 fp = fopen(name,"r");
371         }
372     }
373     if (!fp)
374         return FALSE;
375     if (stio->type != '|' && stio->type != '-') {
376         if (fstat(fileno(fp),&statbuf) < 0) {
377             fclose(fp);
378             return FALSE;
379         }
380         if ((statbuf.st_mode & S_IFMT) != S_IFREG &&
381             (statbuf.st_mode & S_IFMT) != S_IFCHR) {
382             fclose(fp);
383             return FALSE;
384         }
385     }
386     stio->fp = fp;
387     return TRUE;
388 }
389
390 FILE *
391 nextargv(stab)
392 register STAB *stab;
393 {
394     register STR *str;
395     char *oldname;
396
397     while (alen(stab->stab_array) >= 0L) {
398         str = ashift(stab->stab_array);
399         str_sset(stab->stab_val,str);
400         STABSET(stab->stab_val);
401         oldname = str_get(stab->stab_val);
402         if (do_open(stab,oldname)) {
403             if (inplace) {
404                 if (*inplace) {
405                     str_cat(str,inplace);
406 #ifdef RENAME
407                     rename(oldname,str->str_ptr);
408 #else
409                     UNLINK(str->str_ptr);
410                     link(oldname,str->str_ptr);
411                     UNLINK(oldname);
412 #endif
413                 }
414                 sprintf(tokenbuf,">%s",oldname);
415                 do_open(argvoutstab,tokenbuf);
416                 defoutstab = argvoutstab;
417             }
418             str_free(str);
419             return stab->stab_io->fp;
420         }
421         else
422             fprintf(stderr,"Can't open %s\n",str_get(str));
423         str_free(str);
424     }
425     if (inplace) {
426         do_close(argvoutstab,FALSE);
427         defoutstab = stabent("stdout",TRUE);
428     }
429     return Nullfp;
430 }
431
432 bool
433 do_close(stab,explicit)
434 STAB *stab;
435 bool explicit;
436 {
437     bool retval = FALSE;
438     register STIO *stio = stab->stab_io;
439
440     if (!stio)          /* never opened */
441         return FALSE;
442     if (stio->fp) {
443         if (stio->type == '|')
444             retval = (pclose(stio->fp) >= 0);
445         else if (stio->type == '-')
446             retval = TRUE;
447         else
448             retval = (fclose(stio->fp) != EOF);
449         stio->fp = Nullfp;
450     }
451     if (explicit)
452         stio->lines = 0;
453     stio->type = ' ';
454     return retval;
455 }
456
457 bool
458 do_eof(stab)
459 STAB *stab;
460 {
461     register STIO *stio;
462     int ch;
463
464     if (!stab)
465         return TRUE;
466
467     stio = stab->stab_io;
468     if (!stio)
469         return TRUE;
470
471     while (stio->fp) {
472
473 #ifdef STDSTDIO                 /* (the code works without this) */
474         if (stio->fp->_cnt)             /* cheat a little, since */
475             return FALSE;               /* this is the most usual case */
476 #endif
477
478         ch = getc(stio->fp);
479         if (ch != EOF) {
480             ungetc(ch, stio->fp);
481             return FALSE;
482         }
483         if (stio->flags & IOF_ARGV) {   /* not necessarily a real EOF yet? */
484             if (!nextargv(stab))        /* get another fp handy */
485                 return TRUE;
486         }
487         else
488             return TRUE;                /* normal fp, definitely end of file */
489     }
490     return TRUE;
491 }
492
493 long
494 do_tell(stab)
495 STAB *stab;
496 {
497     register STIO *stio;
498     int ch;
499
500     if (!stab)
501         return -1L;
502
503     stio = stab->stab_io;
504     if (!stio || !stio->fp)
505         return -1L;
506
507     return ftell(stio->fp);
508 }
509
510 bool
511 do_seek(stab, pos, whence)
512 STAB *stab;
513 long pos;
514 int whence;
515 {
516     register STIO *stio;
517
518     if (!stab)
519         return FALSE;
520
521     stio = stab->stab_io;
522     if (!stio || !stio->fp)
523         return FALSE;
524
525     return fseek(stio->fp, pos, whence) >= 0;
526 }
527
528 do_stat(arg,sarg,retary)
529 register ARG *arg;
530 register STR **sarg;
531 STR ***retary;
532 {
533     register ARRAY *ary;
534     static ARRAY *myarray = Null(ARRAY*);
535     int max = 13;
536     register int i;
537
538     ary = myarray;
539     if (!ary)
540         myarray = ary = anew();
541     ary->ary_fill = -1;
542     if (arg[1].arg_type == A_LVAL) {
543         tmpstab = arg[1].arg_ptr.arg_stab;
544         if (!tmpstab->stab_io ||
545           fstat(fileno(tmpstab->stab_io->fp),&statbuf) < 0) {
546             max = 0;
547         }
548     }
549     else
550         if (stat(str_get(sarg[1]),&statbuf) < 0)
551             max = 0;
552
553     if (retary) {
554         if (max) {
555             apush(ary,str_nmake((double)statbuf.st_dev));
556             apush(ary,str_nmake((double)statbuf.st_ino));
557             apush(ary,str_nmake((double)statbuf.st_mode));
558             apush(ary,str_nmake((double)statbuf.st_nlink));
559             apush(ary,str_nmake((double)statbuf.st_uid));
560             apush(ary,str_nmake((double)statbuf.st_gid));
561             apush(ary,str_nmake((double)statbuf.st_rdev));
562             apush(ary,str_nmake((double)statbuf.st_size));
563             apush(ary,str_nmake((double)statbuf.st_atime));
564             apush(ary,str_nmake((double)statbuf.st_mtime));
565             apush(ary,str_nmake((double)statbuf.st_ctime));
566 #ifdef STATBLOCKS
567             apush(ary,str_nmake((double)statbuf.st_blksize));
568             apush(ary,str_nmake((double)statbuf.st_blocks));
569 #else
570             apush(ary,str_make(""));
571             apush(ary,str_make(""));
572 #endif
573         }
574         sarg = (STR**)safemalloc((max+2)*sizeof(STR*));
575         sarg[0] = Nullstr;
576         sarg[max+1] = Nullstr;
577         for (i = 1; i <= max; i++)
578             sarg[i] = afetch(ary,i-1);
579         *retary = sarg;
580     }
581     return max;
582 }
583
584 do_tms(retary)
585 STR ***retary;
586 {
587     register ARRAY *ary;
588     static ARRAY *myarray = Null(ARRAY*);
589     register STR **sarg;
590     int max = 4;
591     register int i;
592
593     ary = myarray;
594     if (!ary)
595         myarray = ary = anew();
596     ary->ary_fill = -1;
597     if (times(&timesbuf) < 0)
598         max = 0;
599
600     if (retary) {
601         if (max) {
602             apush(ary,str_nmake(((double)timesbuf.tms_utime)/60.0));
603             apush(ary,str_nmake(((double)timesbuf.tms_stime)/60.0));
604             apush(ary,str_nmake(((double)timesbuf.tms_cutime)/60.0));
605             apush(ary,str_nmake(((double)timesbuf.tms_cstime)/60.0));
606         }
607         sarg = (STR**)safemalloc((max+2)*sizeof(STR*));
608         sarg[0] = Nullstr;
609         sarg[max+1] = Nullstr;
610         for (i = 1; i <= max; i++)
611             sarg[i] = afetch(ary,i-1);
612         *retary = sarg;
613     }
614     return max;
615 }
616
617 do_time(tmbuf,retary)
618 struct tm *tmbuf;
619 STR ***retary;
620 {
621     register ARRAY *ary;
622     static ARRAY *myarray = Null(ARRAY*);
623     register STR **sarg;
624     int max = 9;
625     register int i;
626     STR *str;
627
628     ary = myarray;
629     if (!ary)
630         myarray = ary = anew();
631     ary->ary_fill = -1;
632     if (!tmbuf)
633         max = 0;
634
635     if (retary) {
636         if (max) {
637             apush(ary,str_nmake((double)tmbuf->tm_sec));
638             apush(ary,str_nmake((double)tmbuf->tm_min));
639             apush(ary,str_nmake((double)tmbuf->tm_hour));
640             apush(ary,str_nmake((double)tmbuf->tm_mday));
641             apush(ary,str_nmake((double)tmbuf->tm_mon));
642             apush(ary,str_nmake((double)tmbuf->tm_year));
643             apush(ary,str_nmake((double)tmbuf->tm_wday));
644             apush(ary,str_nmake((double)tmbuf->tm_yday));
645             apush(ary,str_nmake((double)tmbuf->tm_isdst));
646         }
647         sarg = (STR**)safemalloc((max+2)*sizeof(STR*));
648         sarg[0] = Nullstr;
649         sarg[max+1] = Nullstr;
650         for (i = 1; i <= max; i++)
651             sarg[i] = afetch(ary,i-1);
652         *retary = sarg;
653     }
654     return max;
655 }
656
657 void
658 do_sprintf(str,len,sarg)
659 register STR *str;
660 register int len;
661 register STR **sarg;
662 {
663     register char *s;
664     register char *t;
665     bool dolong;
666     char ch;
667     static STR *sargnull = &str_no;
668
669     str_set(str,"");
670     len--;                      /* don't count pattern string */
671     sarg++;
672     for (s = str_get(*(sarg++)); *s; len--) {
673         if (len <= 0 || !*sarg) {
674             sarg = &sargnull;
675             len = 0;
676         }
677         dolong = FALSE;
678         for (t = s; *t && *t != '%'; t++) ;
679         if (!*t)
680             break;              /* not enough % patterns, oh well */
681         for (t++; *sarg && *t && t != s; t++) {
682             switch (*t) {
683             case '\0':
684                 break;
685             case '%':
686                 ch = *(++t);
687                 *t = '\0';
688                 sprintf(buf,s);
689                 s = t;
690                 *(t--) = ch;
691                 break;
692             case 'l':
693                 dolong = TRUE;
694                 break;
695             case 'D': case 'X': case 'O':
696                 dolong = TRUE;
697                 /* FALL THROUGH */
698             case 'd': case 'x': case 'o': case 'c':
699                 ch = *(++t);
700                 *t = '\0';
701                 if (dolong)
702                     sprintf(buf,s,(long)str_gnum(*(sarg++)));
703                 else
704                     sprintf(buf,s,(int)str_gnum(*(sarg++)));
705                 s = t;
706                 *(t--) = ch;
707                 break;
708             case 'E': case 'e': case 'f': case 'G': case 'g':
709                 ch = *(++t);
710                 *t = '\0';
711                 sprintf(buf,s,str_gnum(*(sarg++)));
712                 s = t;
713                 *(t--) = ch;
714                 break;
715             case 's':
716                 ch = *(++t);
717                 *t = '\0';
718                 sprintf(buf,s,str_get(*(sarg++)));
719                 s = t;
720                 *(t--) = ch;
721                 break;
722             }
723         }
724         str_cat(str,buf);
725     }
726     if (*s)
727         str_cat(str,s);
728     STABSET(str);
729 }
730
731 bool
732 do_print(s,fp)
733 char *s;
734 FILE *fp;
735 {
736     if (!fp || !s)
737         return FALSE;
738     fputs(s,fp);
739     return TRUE;
740 }
741
742 bool
743 do_aprint(arg,fp)
744 register ARG *arg;
745 register FILE *fp;
746 {
747     STR **tmpary;       /* must not be register */
748     register STR **elem;
749     register bool retval;
750     double value;
751
752     (void)eval(arg[1].arg_ptr.arg_arg,&tmpary);
753     if (arg->arg_type == O_PRTF) {
754         do_sprintf(arg->arg_ptr.arg_str,32767,tmpary);
755         retval = do_print(str_get(arg->arg_ptr.arg_str),fp);
756     }
757     else {
758         retval = FALSE;
759         for (elem = tmpary+1; *elem; elem++) {
760             if (retval && ofs)
761                 do_print(ofs, fp);
762             if (ofmt && fp) {
763                 if ((*elem)->str_nok || str_gnum(*elem) != 0.0)
764                     fprintf(fp, ofmt, str_gnum(*elem));
765                 retval = TRUE;
766             }
767             else
768                 retval = do_print(str_get(*elem), fp);
769             if (!retval)
770                 break;
771         }
772         if (ors)
773             retval = do_print(ors, fp);
774     }
775     safefree((char*)tmpary);
776     return retval;
777 }
778
779 bool
780 do_aexec(arg)
781 register ARG *arg;
782 {
783     STR **tmpary;       /* must not be register */
784     register STR **elem;
785     register char **a;
786     register int i;
787     char **argv;
788
789     (void)eval(arg[1].arg_ptr.arg_arg,&tmpary);
790     i = 0;
791     for (elem = tmpary+1; *elem; elem++)
792         i++;
793     if (i) {
794         argv = (char**)safemalloc((i+1)*sizeof(char*));
795         a = argv;
796         for (elem = tmpary+1; *elem; elem++) {
797             *a++ = str_get(*elem);
798         }
799         *a = Nullch;
800         execvp(argv[0],argv);
801         safefree((char*)argv);
802     }
803     safefree((char*)tmpary);
804     return FALSE;
805 }
806
807 bool
808 do_exec(cmd)
809 char *cmd;
810 {
811     STR **tmpary;       /* must not be register */
812     register char **a;
813     register char *s;
814     char **argv;
815
816     /* see if there are shell metacharacters in it */
817
818     for (s = cmd; *s; s++) {
819         if (*s != ' ' && !isalpha(*s) && index("$&*(){}[]'\";\\|?<>~`",*s)) {
820             execl("/bin/sh","sh","-c",cmd,0);
821             return FALSE;
822         }
823     }
824     argv = (char**)safemalloc(((s - cmd) / 2 + 2)*sizeof(char*));
825
826     a = argv;
827     for (s = cmd; *s;) {
828         while (isspace(*s)) s++;
829         if (*s)
830             *(a++) = s;
831         while (*s && !isspace(*s)) s++;
832         if (*s)
833             *s++ = '\0';
834     }
835     *a = Nullch;
836     if (argv[0])
837         execvp(argv[0],argv);
838     safefree((char*)argv);
839     return FALSE;
840 }
841
842 STR *
843 do_push(arg,ary)
844 register ARG *arg;
845 register ARRAY *ary;
846 {
847     STR **tmpary;       /* must not be register */
848     register STR **elem;
849     register STR *str = &str_no;
850
851     (void)eval(arg[1].arg_ptr.arg_arg,&tmpary);
852     for (elem = tmpary+1; *elem; elem++) {
853         str = str_new(0);
854         str_sset(str,*elem);
855         apush(ary,str);
856     }
857     safefree((char*)tmpary);
858     return str;
859 }
860
861 do_unshift(arg,ary)
862 register ARG *arg;
863 register ARRAY *ary;
864 {
865     STR **tmpary;       /* must not be register */
866     register STR **elem;
867     register STR *str = &str_no;
868     register int i;
869
870     (void)eval(arg[1].arg_ptr.arg_arg,&tmpary);
871     i = 0;
872     for (elem = tmpary+1; *elem; elem++)
873         i++;
874     aunshift(ary,i);
875     i = 0;
876     for (elem = tmpary+1; *elem; elem++) {
877         str = str_new(0);
878         str_sset(str,*elem);
879         astore(ary,i++,str);
880     }
881     safefree((char*)tmpary);
882 }
883
884 apply(type,arg,sarg)
885 int type;
886 register ARG *arg;
887 STR **sarg;
888 {
889     STR **tmpary;       /* must not be register */
890     register STR **elem;
891     register int i;
892     register int val;
893     register int val2;
894
895     if (sarg)
896         tmpary = sarg;
897     else
898         (void)eval(arg[1].arg_ptr.arg_arg,&tmpary);
899     i = 0;
900     for (elem = tmpary+1; *elem; elem++)
901         i++;
902     switch (type) {
903     case O_CHMOD:
904         if (--i > 0) {
905             val = (int)str_gnum(tmpary[1]);
906             for (elem = tmpary+2; *elem; elem++)
907                 if (chmod(str_get(*elem),val))
908                     i--;
909         }
910         break;
911     case O_CHOWN:
912         if (i > 2) {
913             i -= 2;
914             val = (int)str_gnum(tmpary[1]);
915             val2 = (int)str_gnum(tmpary[2]);
916             for (elem = tmpary+3; *elem; elem++)
917                 if (chown(str_get(*elem),val,val2))
918                     i--;
919         }
920         else
921             i = 0;
922         break;
923     case O_KILL:
924         if (--i > 0) {
925             val = (int)str_gnum(tmpary[1]);
926             if (val < 0)
927                 val = -val;
928             for (elem = tmpary+2; *elem; elem++)
929                 if (kill(atoi(str_get(*elem)),val))
930                     i--;
931         }
932         break;
933     case O_UNLINK:
934         for (elem = tmpary+1; *elem; elem++)
935             if (UNLINK(str_get(*elem)))
936                 i--;
937         break;
938     }
939     if (!sarg)
940         safefree((char*)tmpary);
941     return i;
942 }
943
944 STR *
945 do_subr(arg,sarg)
946 register ARG *arg;
947 register char **sarg;
948 {
949     ARRAY *savearray;
950     STR *str;
951
952     savearray = defstab->stab_array;
953     defstab->stab_array = anew();
954     if (arg[1].arg_flags & AF_SPECIAL)
955         (void)do_push(arg,defstab->stab_array);
956     else if (arg[1].arg_type != A_NULL) {
957         str = str_new(0);
958         str_sset(str,sarg[1]);
959         apush(defstab->stab_array,str);
960     }
961     str = cmd_exec(arg[2].arg_ptr.arg_stab->stab_sub);
962     afree(defstab->stab_array);  /* put back old $_[] */
963     defstab->stab_array = savearray;
964     return str;
965 }
966
967 void
968 do_assign(retstr,arg)
969 STR *retstr;
970 register ARG *arg;
971 {
972     STR **tmpary;       /* must not be register */
973     register ARG *larg = arg[1].arg_ptr.arg_arg;
974     register STR **elem;
975     register STR *str;
976     register ARRAY *ary;
977     register int i;
978     register int lasti;
979     char *s;
980
981     (void)eval(arg[2].arg_ptr.arg_arg,&tmpary);
982
983     if (arg->arg_flags & AF_COMMON) {
984         if (*(tmpary+1)) {
985             for (elem=tmpary+2; *elem; elem++) {
986                 *elem = str_static(*elem);
987             }
988         }
989     }
990     if (larg->arg_type == O_LIST) {
991         lasti = larg->arg_len;
992         for (i=1,elem=tmpary+1; i <= lasti; i++) {
993             if (*elem)
994                 s = str_get(*(elem++));
995             else
996                 s = "";
997             switch (larg[i].arg_type) {
998             case A_STAB:
999             case A_LVAL:
1000                 str = STAB_STR(larg[i].arg_ptr.arg_stab);
1001                 break;
1002             case A_LEXPR:
1003                 str = eval(larg[i].arg_ptr.arg_arg,Null(STR***));
1004                 break;
1005             }
1006             str_set(str,s);
1007             STABSET(str);
1008         }
1009         i = elem - tmpary - 1;
1010     }
1011     else {                      /* should be an array name */
1012         ary = larg[1].arg_ptr.arg_stab->stab_array;
1013         for (i=0,elem=tmpary+1; *elem; i++) {
1014             str = str_new(0);
1015             if (*elem)
1016                 str_sset(str,*(elem++));
1017             astore(ary,i,str);
1018         }
1019         ary->ary_fill = i - 1;  /* they can get the extra ones back by */
1020     }                           /*   setting an element larger than old fill */
1021     str_numset(retstr,(double)i);
1022     STABSET(retstr);
1023     safefree((char*)tmpary);
1024 }
1025
1026 int
1027 do_kv(hash,kv,sarg,retary)
1028 HASH *hash;
1029 int kv;
1030 register STR **sarg;
1031 STR ***retary;
1032 {
1033     register ARRAY *ary;
1034     int max = 0;
1035     int i;
1036     static ARRAY *myarray = Null(ARRAY*);
1037     register HENT *entry;
1038
1039     ary = myarray;
1040     if (!ary)
1041         myarray = ary = anew();
1042     ary->ary_fill = -1;
1043
1044     hiterinit(hash);
1045     while (entry = hiternext(hash)) {
1046         max++;
1047         if (kv == O_KEYS)
1048             apush(ary,str_make(hiterkey(entry)));
1049         else
1050             apush(ary,str_make(str_get(hiterval(entry))));
1051     }
1052     if (retary) { /* array wanted */
1053         sarg = (STR**)saferealloc((char*)sarg,(max+2)*sizeof(STR*));
1054         sarg[0] = Nullstr;
1055         sarg[max+1] = Nullstr;
1056         for (i = 1; i <= max; i++)
1057             sarg[i] = afetch(ary,i-1);
1058         *retary = sarg;
1059     }
1060     return max;
1061 }
1062
1063 STR *
1064 do_each(hash,sarg,retary)
1065 HASH *hash;
1066 register STR **sarg;
1067 STR ***retary;
1068 {
1069     static STR *mystr = Nullstr;
1070     STR *retstr;
1071     HENT *entry = hiternext(hash);
1072
1073     if (mystr) {
1074         str_free(mystr);
1075         mystr = Nullstr;
1076     }
1077
1078     if (retary) { /* array wanted */
1079         if (entry) {
1080             sarg = (STR**)saferealloc((char*)sarg,4*sizeof(STR*));
1081             sarg[0] = Nullstr;
1082             sarg[3] = Nullstr;
1083             sarg[1] = mystr = str_make(hiterkey(entry));
1084             retstr = sarg[2] = hiterval(entry);
1085             *retary = sarg;
1086         }
1087         else {
1088             sarg = (STR**)saferealloc((char*)sarg,2*sizeof(STR*));
1089             sarg[0] = Nullstr;
1090             sarg[1] = retstr = Nullstr;
1091             *retary = sarg;
1092         }
1093     }
1094     else
1095         retstr = hiterval(entry);
1096         
1097     return retstr;
1098 }
1099
1100 init_eval()
1101 {
1102     register int i;
1103
1104 #define A(e1,e2,e3) (e1+(e2<<1)+(e3<<2))
1105     opargs[O_ITEM] =            A(1,0,0);
1106     opargs[O_ITEM2] =           A(0,0,0);
1107     opargs[O_ITEM3] =           A(0,0,0);
1108     opargs[O_CONCAT] =          A(1,1,0);
1109     opargs[O_MATCH] =           A(1,0,0);
1110     opargs[O_NMATCH] =          A(1,0,0);
1111     opargs[O_SUBST] =           A(1,0,0);
1112     opargs[O_NSUBST] =          A(1,0,0);
1113     opargs[O_ASSIGN] =          A(1,1,0);
1114     opargs[O_MULTIPLY] =        A(1,1,0);
1115     opargs[O_DIVIDE] =          A(1,1,0);
1116     opargs[O_MODULO] =          A(1,1,0);
1117     opargs[O_ADD] =             A(1,1,0);
1118     opargs[O_SUBTRACT] =        A(1,1,0);
1119     opargs[O_LEFT_SHIFT] =      A(1,1,0);
1120     opargs[O_RIGHT_SHIFT] =     A(1,1,0);
1121     opargs[O_LT] =              A(1,1,0);
1122     opargs[O_GT] =              A(1,1,0);
1123     opargs[O_LE] =              A(1,1,0);
1124     opargs[O_GE] =              A(1,1,0);
1125     opargs[O_EQ] =              A(1,1,0);
1126     opargs[O_NE] =              A(1,1,0);
1127     opargs[O_BIT_AND] =         A(1,1,0);
1128     opargs[O_XOR] =             A(1,1,0);
1129     opargs[O_BIT_OR] =          A(1,1,0);
1130     opargs[O_AND] =             A(1,0,0);       /* don't eval arg 2 (yet) */
1131     opargs[O_OR] =              A(1,0,0);       /* don't eval arg 2 (yet) */
1132     opargs[O_COND_EXPR] =       A(1,0,0);       /* don't eval args 2 or 3 */
1133     opargs[O_COMMA] =           A(1,1,0);
1134     opargs[O_NEGATE] =          A(1,0,0);
1135     opargs[O_NOT] =             A(1,0,0);
1136     opargs[O_COMPLEMENT] =      A(1,0,0);
1137     opargs[O_WRITE] =           A(1,0,0);
1138     opargs[O_OPEN] =            A(1,1,0);
1139     opargs[O_TRANS] =           A(1,0,0);
1140     opargs[O_NTRANS] =          A(1,0,0);
1141     opargs[O_CLOSE] =           A(0,0,0);
1142     opargs[O_ARRAY] =           A(1,0,0);
1143     opargs[O_HASH] =            A(1,0,0);
1144     opargs[O_LARRAY] =          A(1,0,0);
1145     opargs[O_LHASH] =           A(1,0,0);
1146     opargs[O_PUSH] =            A(1,0,0);
1147     opargs[O_POP] =             A(0,0,0);
1148     opargs[O_SHIFT] =           A(0,0,0);
1149     opargs[O_SPLIT] =           A(1,0,0);
1150     opargs[O_LENGTH] =          A(1,0,0);
1151     opargs[O_SPRINTF] =         A(1,0,0);
1152     opargs[O_SUBSTR] =          A(1,1,1);
1153     opargs[O_JOIN] =            A(1,0,0);
1154     opargs[O_SLT] =             A(1,1,0);
1155     opargs[O_SGT] =             A(1,1,0);
1156     opargs[O_SLE] =             A(1,1,0);
1157     opargs[O_SGE] =             A(1,1,0);
1158     opargs[O_SEQ] =             A(1,1,0);
1159     opargs[O_SNE] =             A(1,1,0);
1160     opargs[O_SUBR] =            A(1,0,0);
1161     opargs[O_PRINT] =           A(1,0,0);
1162     opargs[O_CHDIR] =           A(1,0,0);
1163     opargs[O_DIE] =             A(1,0,0);
1164     opargs[O_EXIT] =            A(1,0,0);
1165     opargs[O_RESET] =           A(1,0,0);
1166     opargs[O_LIST] =            A(0,0,0);
1167     opargs[O_EOF] =             A(0,0,0);
1168     opargs[O_TELL] =            A(0,0,0);
1169     opargs[O_SEEK] =            A(0,1,1);
1170     opargs[O_LAST] =            A(1,0,0);
1171     opargs[O_NEXT] =            A(1,0,0);
1172     opargs[O_REDO] =            A(1,0,0);
1173     opargs[O_GOTO] =            A(1,0,0);
1174     opargs[O_INDEX] =           A(1,1,0);
1175     opargs[O_TIME] =            A(0,0,0);
1176     opargs[O_TMS] =             A(0,0,0);
1177     opargs[O_LOCALTIME] =       A(1,0,0);
1178     opargs[O_GMTIME] =          A(1,0,0);
1179     opargs[O_STAT] =            A(1,0,0);
1180     opargs[O_CRYPT] =           A(1,1,0);
1181     opargs[O_EXP] =             A(1,0,0);
1182     opargs[O_LOG] =             A(1,0,0);
1183     opargs[O_SQRT] =            A(1,0,0);
1184     opargs[O_INT] =             A(1,0,0);
1185     opargs[O_PRTF] =            A(1,0,0);
1186     opargs[O_ORD] =             A(1,0,0);
1187     opargs[O_SLEEP] =           A(1,0,0);
1188     opargs[O_FLIP] =            A(1,0,0);
1189     opargs[O_FLOP] =            A(0,1,0);
1190     opargs[O_KEYS] =            A(0,0,0);
1191     opargs[O_VALUES] =          A(0,0,0);
1192     opargs[O_EACH] =            A(0,0,0);
1193     opargs[O_CHOP] =            A(1,0,0);
1194     opargs[O_FORK] =            A(1,0,0);
1195     opargs[O_EXEC] =            A(1,0,0);
1196     opargs[O_SYSTEM] =          A(1,0,0);
1197     opargs[O_OCT] =             A(1,0,0);
1198     opargs[O_HEX] =             A(1,0,0);
1199     opargs[O_CHMOD] =           A(1,0,0);
1200     opargs[O_CHOWN] =           A(1,0,0);
1201     opargs[O_KILL] =            A(1,0,0);
1202     opargs[O_RENAME] =          A(1,1,0);
1203     opargs[O_UNLINK] =          A(1,0,0);
1204     opargs[O_UMASK] =           A(1,0,0);
1205     opargs[O_UNSHIFT] =         A(1,0,0);
1206     opargs[O_LINK] =            A(1,1,0);
1207     opargs[O_REPEAT] =          A(1,1,0);
1208     opargs[O_EVAL] =            A(1,0,0);
1209 }
1210
1211 #ifdef VOIDSIG
1212 static void (*ihand)();
1213 static void (*qhand)();
1214 #else
1215 static int (*ihand)();
1216 static int (*qhand)();
1217 #endif
1218
1219 STR *
1220 eval(arg,retary)
1221 register ARG *arg;
1222 STR ***retary;          /* where to return an array to, null if nowhere */
1223 {
1224     register STR *str;
1225     register int anum;
1226     register int optype;
1227     register int maxarg;
1228     double value;
1229     STR *quicksarg[5];
1230     register STR **sarg = quicksarg;
1231     register char *tmps;
1232     char *tmps2;
1233     int argflags;
1234     long tmplong;
1235     FILE *fp;
1236     STR *tmpstr;
1237     FCMD *form;
1238     STAB *stab;
1239     ARRAY *ary;
1240     bool assigning = FALSE;
1241     double exp(), log(), sqrt(), modf();
1242     char *crypt(), *getenv();
1243
1244     if (!arg)
1245         return &str_no;
1246     str = arg->arg_ptr.arg_str;
1247     optype = arg->arg_type;
1248     maxarg = arg->arg_len;
1249     if (maxarg > 3 || retary) {
1250         sarg = (STR **)safemalloc((maxarg+2) * sizeof(STR*));
1251     }
1252 #ifdef DEBUGGING
1253     if (debug & 8) {
1254         deb("%s (%lx) %d args:\n",opname[optype],arg,maxarg);
1255     }
1256     debname[dlevel] = opname[optype][0];
1257     debdelim[dlevel++] = ':';
1258 #endif
1259     for (anum = 1; anum <= maxarg; anum++) {
1260         argflags = arg[anum].arg_flags;
1261         if (argflags & AF_SPECIAL)
1262             continue;
1263       re_eval:
1264         switch (arg[anum].arg_type) {
1265         default:
1266             sarg[anum] = &str_no;
1267 #ifdef DEBUGGING
1268             tmps = "NULL";
1269 #endif
1270             break;
1271         case A_EXPR:
1272 #ifdef DEBUGGING
1273             if (debug & 8) {
1274                 tmps = "EXPR";
1275                 deb("%d.EXPR =>\n",anum);
1276             }
1277 #endif
1278             sarg[anum] = eval(arg[anum].arg_ptr.arg_arg, Null(STR***));
1279             break;
1280         case A_CMD:
1281 #ifdef DEBUGGING
1282             if (debug & 8) {
1283                 tmps = "CMD";
1284                 deb("%d.CMD (%lx) =>\n",anum,arg[anum].arg_ptr.arg_cmd);
1285             }
1286 #endif
1287             sarg[anum] = cmd_exec(arg[anum].arg_ptr.arg_cmd);
1288             break;
1289         case A_STAB:
1290             sarg[anum] = STAB_STR(arg[anum].arg_ptr.arg_stab);
1291 #ifdef DEBUGGING
1292             if (debug & 8) {
1293                 sprintf(buf,"STAB $%s ==",arg[anum].arg_ptr.arg_stab->stab_name);
1294                 tmps = buf;
1295             }
1296 #endif
1297             break;
1298         case A_LEXPR:
1299 #ifdef DEBUGGING
1300             if (debug & 8) {
1301                 tmps = "LEXPR";
1302                 deb("%d.LEXPR =>\n",anum);
1303             }
1304 #endif
1305             str = eval(arg[anum].arg_ptr.arg_arg,Null(STR***));
1306             if (!str)
1307                 fatal("panic: A_LEXPR\n");
1308             goto do_crement;
1309         case A_LVAL:
1310 #ifdef DEBUGGING
1311             if (debug & 8) {
1312                 sprintf(buf,"LVAL $%s ==",arg[anum].arg_ptr.arg_stab->stab_name);
1313                 tmps = buf;
1314             }
1315 #endif
1316             str = STAB_STR(arg[anum].arg_ptr.arg_stab);
1317             if (!str)
1318                 fatal("panic: A_LVAL\n");
1319           do_crement:
1320             assigning = TRUE;
1321             if (argflags & AF_PRE) {
1322                 if (argflags & AF_UP)
1323                     str_inc(str);
1324                 else
1325                     str_dec(str);
1326                 STABSET(str);
1327                 sarg[anum] = str;
1328                 str = arg->arg_ptr.arg_str;
1329             }
1330             else if (argflags & AF_POST) {
1331                 sarg[anum] = str_static(str);
1332                 if (argflags & AF_UP)
1333                     str_inc(str);
1334                 else
1335                     str_dec(str);
1336                 STABSET(str);
1337                 str = arg->arg_ptr.arg_str;
1338             }
1339             else {
1340                 sarg[anum] = str;
1341             }
1342             break;
1343         case A_ARYLEN:
1344             sarg[anum] = str_static(&str_no);
1345             str_numset(sarg[anum],
1346                 (double)alen(arg[anum].arg_ptr.arg_stab->stab_array));
1347 #ifdef DEBUGGING
1348             tmps = "ARYLEN";
1349 #endif
1350             break;
1351         case A_SINGLE:
1352             sarg[anum] = arg[anum].arg_ptr.arg_str;
1353 #ifdef DEBUGGING
1354             tmps = "SINGLE";
1355 #endif
1356             break;
1357         case A_DOUBLE:
1358             (void) interp(str,str_get(arg[anum].arg_ptr.arg_str));
1359             sarg[anum] = str;
1360 #ifdef DEBUGGING
1361             tmps = "DOUBLE";
1362 #endif
1363             break;
1364         case A_BACKTICK:
1365             tmps = str_get(arg[anum].arg_ptr.arg_str);
1366             fp = popen(str_get(interp(str,tmps)),"r");
1367             tmpstr = str_new(80);
1368             str_set(str,"");
1369             if (fp) {
1370                 while (str_gets(tmpstr,fp) != Nullch) {
1371                     str_scat(str,tmpstr);
1372                 }
1373                 statusvalue = pclose(fp);
1374             }
1375             else
1376                 statusvalue = -1;
1377             str_free(tmpstr);
1378
1379             sarg[anum] = str;
1380 #ifdef DEBUGGING
1381             tmps = "BACK";
1382 #endif
1383             break;
1384         case A_READ:
1385             fp = Nullfp;
1386             last_in_stab = arg[anum].arg_ptr.arg_stab;
1387             if (last_in_stab->stab_io) {
1388                 fp = last_in_stab->stab_io->fp;
1389                 if (!fp && (last_in_stab->stab_io->flags & IOF_ARGV)) {
1390                     if (last_in_stab->stab_io->flags & IOF_START) {
1391                         last_in_stab->stab_io->flags &= ~IOF_START;
1392                         last_in_stab->stab_io->lines = 0;
1393                         if (alen(last_in_stab->stab_array) < 0L) {
1394                             tmpstr = str_make("-");     /* assume stdin */
1395                             apush(last_in_stab->stab_array, tmpstr);
1396                         }
1397                     }
1398                     fp = nextargv(last_in_stab);
1399                     if (!fp)    /* Note: fp != last_in_stab->stab_io->fp */
1400                         do_close(last_in_stab,FALSE);   /* now it does */
1401                 }
1402             }
1403           keepgoing:
1404             if (!fp)
1405                 sarg[anum] = &str_no;
1406             else if (!str_gets(str,fp)) {
1407                 if (last_in_stab->stab_io->flags & IOF_ARGV) {
1408                     fp = nextargv(last_in_stab);
1409                     if (fp)
1410                         goto keepgoing;
1411                     do_close(last_in_stab,FALSE);
1412                     last_in_stab->stab_io->flags |= IOF_START;
1413                 }
1414                 if (fp == stdin) {
1415                     clearerr(fp);
1416                 }
1417                 sarg[anum] = &str_no;
1418                 break;
1419             }
1420             else {
1421                 last_in_stab->stab_io->lines++;
1422                 sarg[anum] = str;
1423             }
1424 #ifdef DEBUGGING
1425             tmps = "READ";
1426 #endif
1427             break;
1428         }
1429 #ifdef DEBUGGING
1430         if (debug & 8)
1431             deb("%d.%s = '%s'\n",anum,tmps,str_peek(sarg[anum]));
1432 #endif
1433     }
1434     switch (optype) {
1435     case O_ITEM:
1436         if (str != sarg[1])
1437             str_sset(str,sarg[1]);
1438         STABSET(str);
1439         break;
1440     case O_ITEM2:
1441         if (str != sarg[2])
1442             str_sset(str,sarg[2]);
1443         STABSET(str);
1444         break;
1445     case O_ITEM3:
1446         if (str != sarg[3])
1447             str_sset(str,sarg[3]);
1448         STABSET(str);
1449         break;
1450     case O_CONCAT:
1451         if (str != sarg[1])
1452             str_sset(str,sarg[1]);
1453         str_scat(str,sarg[2]);
1454         STABSET(str);
1455         break;
1456     case O_REPEAT:
1457         if (str != sarg[1])
1458             str_sset(str,sarg[1]);
1459         anum = (long)str_gnum(sarg[2]);
1460         if (anum >= 1) {
1461             tmpstr = str_new(0);
1462             str_sset(tmpstr,str);
1463             for (anum--; anum; anum--)
1464                 str_scat(str,tmpstr);
1465         }
1466         else
1467             str_sset(str,&str_no);
1468         STABSET(str);
1469         break;
1470     case O_MATCH:
1471         str_set(str, do_match(str_get(sarg[1]),arg) ? Yes : No);
1472         STABSET(str);
1473         break;
1474     case O_NMATCH:
1475         str_set(str, do_match(str_get(sarg[1]),arg) ? No : Yes);
1476         STABSET(str);
1477         break;
1478     case O_SUBST:
1479         value = (double) do_subst(str, arg);
1480         str = arg->arg_ptr.arg_str;
1481         goto donumset;
1482     case O_NSUBST:
1483         str_set(arg->arg_ptr.arg_str, do_subst(str, arg) ? No : Yes);
1484         str = arg->arg_ptr.arg_str;
1485         break;
1486     case O_ASSIGN:
1487         if (arg[2].arg_flags & AF_SPECIAL)
1488             do_assign(str,arg);
1489         else {
1490             if (str != sarg[2])
1491                 str_sset(str, sarg[2]);
1492             STABSET(str);
1493         }
1494         break;
1495     case O_CHOP:
1496         tmps = str_get(str);
1497         tmps += str->str_cur - (str->str_cur != 0);
1498         str_set(arg->arg_ptr.arg_str,tmps);     /* remember last char */
1499         *tmps = '\0';                           /* wipe it out */
1500         str->str_cur = tmps - str->str_ptr;
1501         str->str_nok = 0;
1502         str = arg->arg_ptr.arg_str;
1503         break;
1504     case O_MULTIPLY:
1505         value = str_gnum(sarg[1]);
1506         value *= str_gnum(sarg[2]);
1507         goto donumset;
1508     case O_DIVIDE:
1509         value = str_gnum(sarg[1]);
1510         value /= str_gnum(sarg[2]);
1511         goto donumset;
1512     case O_MODULO:
1513         value = str_gnum(sarg[1]);
1514         value = (double)(((long)value) % (long)str_gnum(sarg[2]));
1515         goto donumset;
1516     case O_ADD:
1517         value = str_gnum(sarg[1]);
1518         value += str_gnum(sarg[2]);
1519         goto donumset;
1520     case O_SUBTRACT:
1521         value = str_gnum(sarg[1]);
1522         value -= str_gnum(sarg[2]);
1523         goto donumset;
1524     case O_LEFT_SHIFT:
1525         value = str_gnum(sarg[1]);
1526         value = (double)(((long)value) << (long)str_gnum(sarg[2]));
1527         goto donumset;
1528     case O_RIGHT_SHIFT:
1529         value = str_gnum(sarg[1]);
1530         value = (double)(((long)value) >> (long)str_gnum(sarg[2]));
1531         goto donumset;
1532     case O_LT:
1533         value = str_gnum(sarg[1]);
1534         value = (double)(value < str_gnum(sarg[2]));
1535         goto donumset;
1536     case O_GT:
1537         value = str_gnum(sarg[1]);
1538         value = (double)(value > str_gnum(sarg[2]));
1539         goto donumset;
1540     case O_LE:
1541         value = str_gnum(sarg[1]);
1542         value = (double)(value <= str_gnum(sarg[2]));
1543         goto donumset;
1544     case O_GE:
1545         value = str_gnum(sarg[1]);
1546         value = (double)(value >= str_gnum(sarg[2]));
1547         goto donumset;
1548     case O_EQ:
1549         value = str_gnum(sarg[1]);
1550         value = (double)(value == str_gnum(sarg[2]));
1551         goto donumset;
1552     case O_NE:
1553         value = str_gnum(sarg[1]);
1554         value = (double)(value != str_gnum(sarg[2]));
1555         goto donumset;
1556     case O_BIT_AND:
1557         value = str_gnum(sarg[1]);
1558         value = (double)(((long)value) & (long)str_gnum(sarg[2]));
1559         goto donumset;
1560     case O_XOR:
1561         value = str_gnum(sarg[1]);
1562         value = (double)(((long)value) ^ (long)str_gnum(sarg[2]));
1563         goto donumset;
1564     case O_BIT_OR:
1565         value = str_gnum(sarg[1]);
1566         value = (double)(((long)value) | (long)str_gnum(sarg[2]));
1567         goto donumset;
1568     case O_AND:
1569         if (str_true(sarg[1])) {
1570             anum = 2;
1571             optype = O_ITEM2;
1572             maxarg = 0;
1573             argflags = arg[anum].arg_flags;
1574             goto re_eval;
1575         }
1576         else {
1577             if (assigning) {
1578                 str_sset(str, sarg[1]);
1579                 STABSET(str);
1580             }
1581             else
1582                 str = sarg[1];
1583             break;
1584         }
1585     case O_OR:
1586         if (str_true(sarg[1])) {
1587             if (assigning) {
1588                 str_set(str, sarg[1]);
1589                 STABSET(str);
1590             }
1591             else
1592                 str = sarg[1];
1593             break;
1594         }
1595         else {
1596             anum = 2;
1597             optype = O_ITEM2;
1598             maxarg = 0;
1599             argflags = arg[anum].arg_flags;
1600             goto re_eval;
1601         }
1602     case O_COND_EXPR:
1603         anum = (str_true(sarg[1]) ? 2 : 3);
1604         optype = (anum == 2 ? O_ITEM2 : O_ITEM3);
1605         maxarg = 0;
1606         argflags = arg[anum].arg_flags;
1607         goto re_eval;
1608     case O_COMMA:
1609         str = sarg[2];
1610         break;
1611     case O_NEGATE:
1612         value = -str_gnum(sarg[1]);
1613         goto donumset;
1614     case O_NOT:
1615         value = (double) !str_true(sarg[1]);
1616         goto donumset;
1617     case O_COMPLEMENT:
1618         value = (double) ~(long)str_gnum(sarg[1]);
1619         goto donumset;
1620     case O_SELECT:
1621         if (arg[1].arg_type == A_LVAL)
1622             defoutstab = arg[1].arg_ptr.arg_stab;
1623         else
1624             defoutstab = stabent(str_get(sarg[1]),TRUE);
1625         if (!defoutstab->stab_io)
1626             defoutstab->stab_io = stio_new();
1627         curoutstab = defoutstab;
1628         str_set(str,curoutstab->stab_io->fp ? Yes : No);
1629         STABSET(str);
1630         break;
1631     case O_WRITE:
1632         if (maxarg == 0)
1633             stab = defoutstab;
1634         else if (arg[1].arg_type == A_LVAL)
1635             stab = arg[1].arg_ptr.arg_stab;
1636         else
1637             stab = stabent(str_get(sarg[1]),TRUE);
1638         if (!stab->stab_io) {
1639             str_set(str, No);
1640             STABSET(str);
1641             break;
1642         }
1643         curoutstab = stab;
1644         fp = stab->stab_io->fp;
1645         debarg = arg;
1646         if (stab->stab_io->fmt_stab)
1647             form = stab->stab_io->fmt_stab->stab_form;
1648         else
1649             form = stab->stab_form;
1650         if (!form || !fp) {
1651             str_set(str, No);
1652             STABSET(str);
1653             break;
1654         }
1655         format(&outrec,form);
1656         do_write(&outrec,stab->stab_io);
1657         if (stab->stab_io->flags & IOF_FLUSH)
1658             fflush(fp);
1659         str_set(str, Yes);
1660         STABSET(str);
1661         break;
1662     case O_OPEN:
1663         if (do_open(arg[1].arg_ptr.arg_stab,str_get(sarg[2]))) {
1664             str_set(str, Yes);
1665             arg[1].arg_ptr.arg_stab->stab_io->lines = 0;
1666         }
1667         else
1668             str_set(str, No);
1669         STABSET(str);
1670         break;
1671     case O_TRANS:
1672         value = (double) do_trans(str,arg);
1673         str = arg->arg_ptr.arg_str;
1674         goto donumset;
1675     case O_NTRANS:
1676         str_set(arg->arg_ptr.arg_str, do_trans(str,arg) == 0 ? Yes : No);
1677         str = arg->arg_ptr.arg_str;
1678         break;
1679     case O_CLOSE:
1680         str_set(str,
1681             do_close(arg[1].arg_ptr.arg_stab,TRUE) ? Yes : No );
1682         STABSET(str);
1683         break;
1684     case O_EACH:
1685         str_sset(str,do_each(arg[1].arg_ptr.arg_stab->stab_hash,sarg,retary));
1686         retary = Null(STR***);          /* do_each already did retary */
1687         STABSET(str);
1688         break;
1689     case O_VALUES:
1690     case O_KEYS:
1691         value = (double) do_kv(arg[1].arg_ptr.arg_stab->stab_hash,
1692           optype,sarg,retary);
1693         retary = Null(STR***);          /* do_keys already did retary */
1694         goto donumset;
1695     case O_ARRAY:
1696         if (maxarg == 1) {
1697             ary = arg[1].arg_ptr.arg_stab->stab_array;
1698             maxarg = ary->ary_fill;
1699             if (retary) { /* array wanted */
1700                 sarg =
1701                   (STR **)saferealloc((char*)sarg,(maxarg+3)*sizeof(STR*));
1702                 for (anum = 0; anum <= maxarg; anum++) {
1703                     sarg[anum+1] = str = afetch(ary,anum);
1704                 }
1705                 maxarg++;
1706             }
1707             else
1708                 str = afetch(ary,maxarg);
1709         }
1710         else
1711             str = afetch(arg[2].arg_ptr.arg_stab->stab_array,
1712                 ((int)str_gnum(sarg[1])) - arybase);
1713         if (!str)
1714             return &str_no;
1715         break;
1716     case O_HASH:
1717         tmpstab = arg[2].arg_ptr.arg_stab;              /* XXX */
1718         str = hfetch(tmpstab->stab_hash,str_get(sarg[1]));
1719         if (!str)
1720             return &str_no;
1721         break;
1722     case O_LARRAY:
1723         anum = ((int)str_gnum(sarg[1])) - arybase;
1724         str = afetch(arg[2].arg_ptr.arg_stab->stab_array,anum);
1725         if (!str || str == &str_no) {
1726             str = str_new(0);
1727             astore(arg[2].arg_ptr.arg_stab->stab_array,anum,str);
1728         }
1729         break;
1730     case O_LHASH:
1731         tmpstab = arg[2].arg_ptr.arg_stab;
1732         str = hfetch(tmpstab->stab_hash,str_get(sarg[1]));
1733         if (!str) {
1734             str = str_new(0);
1735             hstore(tmpstab->stab_hash,str_get(sarg[1]),str);
1736         }
1737         if (tmpstab == envstab) {       /* heavy wizardry going on here */
1738             str->str_link.str_magic = tmpstab;/* str is now magic */
1739             envname = savestr(str_get(sarg[1]));
1740                                         /* he threw the brick up into the air */
1741         }
1742         else if (tmpstab == sigstab) {  /* same thing, only different */
1743             str->str_link.str_magic = tmpstab;
1744             signame = savestr(str_get(sarg[1]));
1745         }
1746         break;
1747     case O_PUSH:
1748         if (arg[1].arg_flags & AF_SPECIAL)
1749             str = do_push(arg,arg[2].arg_ptr.arg_stab->stab_array);
1750         else {
1751             str = str_new(0);           /* must copy the STR */
1752             str_sset(str,sarg[1]);
1753             apush(arg[2].arg_ptr.arg_stab->stab_array,str);
1754         }
1755         break;
1756     case O_POP:
1757         str = apop(arg[1].arg_ptr.arg_stab->stab_array);
1758         if (!str)
1759             return &str_no;
1760 #ifdef STRUCTCOPY
1761         *(arg->arg_ptr.arg_str) = *str;
1762 #else
1763         bcopy((char*)str, (char*)arg->arg_ptr.arg_str, sizeof *str);
1764 #endif
1765         safefree((char*)str);
1766         str = arg->arg_ptr.arg_str;
1767         break;
1768     case O_SHIFT:
1769         str = ashift(arg[1].arg_ptr.arg_stab->stab_array);
1770         if (!str)
1771             return &str_no;
1772 #ifdef STRUCTCOPY
1773         *(arg->arg_ptr.arg_str) = *str;
1774 #else
1775         bcopy((char*)str, (char*)arg->arg_ptr.arg_str, sizeof *str);
1776 #endif
1777         safefree((char*)str);
1778         str = arg->arg_ptr.arg_str;
1779         break;
1780     case O_SPLIT:
1781         value = (double) do_split(str_get(sarg[1]),arg[2].arg_ptr.arg_spat,retary);
1782         retary = Null(STR***);          /* do_split already did retary */
1783         goto donumset;
1784     case O_LENGTH:
1785         value = (double) str_len(sarg[1]);
1786         goto donumset;
1787     case O_SPRINTF:
1788         sarg[maxarg+1] = Nullstr;
1789         do_sprintf(str,arg->arg_len,sarg);
1790         break;
1791     case O_SUBSTR:
1792         anum = ((int)str_gnum(sarg[2])) - arybase;
1793         for (tmps = str_get(sarg[1]); *tmps && anum > 0; tmps++,anum--) ;
1794         anum = (int)str_gnum(sarg[3]);
1795         if (anum >= 0 && strlen(tmps) > anum)
1796             str_nset(str, tmps, anum);
1797         else
1798             str_set(str, tmps);
1799         break;
1800     case O_JOIN:
1801         if (arg[2].arg_flags & AF_SPECIAL && arg[2].arg_type == A_EXPR)
1802             do_join(arg,str_get(sarg[1]),str);
1803         else
1804             ajoin(arg[2].arg_ptr.arg_stab->stab_array,str_get(sarg[1]),str);
1805         break;
1806     case O_SLT:
1807         tmps = str_get(sarg[1]);
1808         value = (double) strLT(tmps,str_get(sarg[2]));
1809         goto donumset;
1810     case O_SGT:
1811         tmps = str_get(sarg[1]);
1812         value = (double) strGT(tmps,str_get(sarg[2]));
1813         goto donumset;
1814     case O_SLE:
1815         tmps = str_get(sarg[1]);
1816         value = (double) strLE(tmps,str_get(sarg[2]));
1817         goto donumset;
1818     case O_SGE:
1819         tmps = str_get(sarg[1]);
1820         value = (double) strGE(tmps,str_get(sarg[2]));
1821         goto donumset;
1822     case O_SEQ:
1823         tmps = str_get(sarg[1]);
1824         value = (double) strEQ(tmps,str_get(sarg[2]));
1825         goto donumset;
1826     case O_SNE:
1827         tmps = str_get(sarg[1]);
1828         value = (double) strNE(tmps,str_get(sarg[2]));
1829         goto donumset;
1830     case O_SUBR:
1831         str_sset(str,do_subr(arg,sarg));
1832         STABSET(str);
1833         break;
1834     case O_PRTF:
1835     case O_PRINT:
1836         if (maxarg <= 1)
1837             stab = defoutstab;
1838         else {
1839             stab = arg[2].arg_ptr.arg_stab;
1840             if (!stab)
1841                 stab = defoutstab;
1842         }
1843         if (!stab->stab_io)
1844             value = 0.0;
1845         else if (arg[1].arg_flags & AF_SPECIAL)
1846             value = (double)do_aprint(arg,stab->stab_io->fp);
1847         else {
1848             value = (double)do_print(str_get(sarg[1]),stab->stab_io->fp);
1849             if (ors && optype == O_PRINT)
1850                 do_print(ors, stab->stab_io->fp);
1851         }
1852         if (stab->stab_io->flags & IOF_FLUSH)
1853             fflush(stab->stab_io->fp);
1854         goto donumset;
1855     case O_CHDIR:
1856         tmps = str_get(sarg[1]);
1857         if (!tmps || !*tmps)
1858             tmps = getenv("HOME");
1859         if (!tmps || !*tmps)
1860             tmps = getenv("LOGDIR");
1861         value = (double)(chdir(tmps) >= 0);
1862         goto donumset;
1863     case O_DIE:
1864         tmps = str_get(sarg[1]);
1865         if (!tmps || !*tmps)
1866             exit(1);
1867         fatal("%s\n",str_get(sarg[1]));
1868         value = 0.0;
1869         goto donumset;
1870     case O_EXIT:
1871         exit((int)str_gnum(sarg[1]));
1872         value = 0.0;
1873         goto donumset;
1874     case O_RESET:
1875         str_reset(str_get(sarg[1]));
1876         value = 1.0;
1877         goto donumset;
1878     case O_LIST:
1879         if (maxarg > 0)
1880             str = sarg[maxarg]; /* unwanted list, return last item */
1881         else
1882             str = &str_no;
1883         break;
1884     case O_EOF:
1885         str_set(str, do_eof(maxarg > 0 ? arg[1].arg_ptr.arg_stab : last_in_stab) ? Yes : No);
1886         STABSET(str);
1887         break;
1888     case O_TELL:
1889         value = (double)do_tell(maxarg > 0 ? arg[1].arg_ptr.arg_stab : last_in_stab);
1890         goto donumset;
1891         break;
1892     case O_SEEK:
1893         value = str_gnum(sarg[2]);
1894         str_set(str, do_seek(arg[1].arg_ptr.arg_stab,
1895           (long)value, (int)str_gnum(sarg[3]) ) ? Yes : No);
1896         STABSET(str);
1897         break;
1898     case O_REDO:
1899     case O_NEXT:
1900     case O_LAST:
1901         if (maxarg > 0) {
1902             tmps = str_get(sarg[1]);
1903             while (loop_ptr >= 0 && (!loop_stack[loop_ptr].loop_label ||
1904               strNE(tmps,loop_stack[loop_ptr].loop_label) )) {
1905 #ifdef DEBUGGING
1906                 if (debug & 4) {
1907                     deb("(Skipping label #%d %s)\n",loop_ptr,
1908                         loop_stack[loop_ptr].loop_label);
1909                 }
1910 #endif
1911                 loop_ptr--;
1912             }
1913 #ifdef DEBUGGING
1914             if (debug & 4) {
1915                 deb("(Found label #%d %s)\n",loop_ptr,
1916                     loop_stack[loop_ptr].loop_label);
1917             }
1918 #endif
1919         }
1920         if (loop_ptr < 0)
1921             fatal("Bad label: %s\n", maxarg > 0 ? tmps : "<null>");
1922         longjmp(loop_stack[loop_ptr].loop_env, optype);
1923     case O_GOTO:/* shudder */
1924         goto_targ = str_get(sarg[1]);
1925         longjmp(top_env, 1);
1926     case O_INDEX:
1927         tmps = str_get(sarg[1]);
1928         if (!(tmps2 = instr(tmps,str_get(sarg[2]))))
1929             value = (double)(-1 + arybase);
1930         else
1931             value = (double)(tmps2 - tmps + arybase);
1932         goto donumset;
1933     case O_TIME:
1934         value = (double) time(0);
1935         goto donumset;
1936     case O_TMS:
1937         value = (double) do_tms(retary);
1938         retary = Null(STR***);          /* do_tms already did retary */
1939         goto donumset;
1940     case O_LOCALTIME:
1941         tmplong = (long) str_gnum(sarg[1]);
1942         value = (double) do_time(localtime(&tmplong),retary);
1943         retary = Null(STR***);          /* do_localtime already did retary */
1944         goto donumset;
1945     case O_GMTIME:
1946         tmplong = (long) str_gnum(sarg[1]);
1947         value = (double) do_time(gmtime(&tmplong),retary);
1948         retary = Null(STR***);          /* do_gmtime already did retary */
1949         goto donumset;
1950     case O_STAT:
1951         value = (double) do_stat(arg,sarg,retary);
1952         retary = Null(STR***);          /* do_stat already did retary */
1953         goto donumset;
1954     case O_CRYPT:
1955         tmps = str_get(sarg[1]);
1956         str_set(str,crypt(tmps,str_get(sarg[2])));
1957         break;
1958     case O_EXP:
1959         value = exp(str_gnum(sarg[1]));
1960         goto donumset;
1961     case O_LOG:
1962         value = log(str_gnum(sarg[1]));
1963         goto donumset;
1964     case O_SQRT:
1965         value = sqrt(str_gnum(sarg[1]));
1966         goto donumset;
1967     case O_INT:
1968         modf(str_gnum(sarg[1]),&value);
1969         goto donumset;
1970     case O_ORD:
1971         value = (double) *str_get(sarg[1]);
1972         goto donumset;
1973     case O_SLEEP:
1974         tmps = str_get(sarg[1]);
1975         time(&tmplong);
1976         if (!tmps || !*tmps)
1977             sleep((32767<<16)+32767);
1978         else
1979             sleep(atoi(tmps));
1980         value = (double)tmplong;
1981         time(&tmplong);
1982         value = ((double)tmplong) - value;
1983         goto donumset;
1984     case O_FLIP:
1985         if (str_true(sarg[1])) {
1986             str_numset(str,0.0);
1987             anum = 2;
1988             arg->arg_type = optype = O_FLOP;
1989             maxarg = 0;
1990             arg[2].arg_flags &= ~AF_SPECIAL;
1991             arg[1].arg_flags |= AF_SPECIAL;
1992             argflags = arg[anum].arg_flags;
1993             goto re_eval;
1994         }
1995         str_set(str,"");
1996         break;
1997     case O_FLOP:
1998         str_inc(str);
1999         if (str_true(sarg[2])) {
2000             arg->arg_type = O_FLIP;
2001             arg[1].arg_flags &= ~AF_SPECIAL;
2002             arg[2].arg_flags |= AF_SPECIAL;
2003             str_cat(str,"E0");
2004         }
2005         break;
2006     case O_FORK:
2007         value = (double)fork();
2008         goto donumset;
2009     case O_SYSTEM:
2010         if (anum = vfork()) {
2011             ihand = signal(SIGINT, SIG_IGN);
2012             qhand = signal(SIGQUIT, SIG_IGN);
2013             while ((maxarg = wait(&argflags)) != anum && maxarg != -1)
2014                 ;
2015             if (maxarg == -1)
2016                 argflags = -1;
2017             signal(SIGINT, ihand);
2018             signal(SIGQUIT, qhand);
2019             value = (double)argflags;
2020             goto donumset;
2021         }
2022         /* FALL THROUGH */
2023     case O_EXEC:
2024         if (arg[1].arg_flags & AF_SPECIAL)
2025             value = (double)do_aexec(arg);
2026         else {
2027             value = (double)do_exec(str_get(sarg[1]));
2028         }
2029         goto donumset;
2030     case O_HEX:
2031         maxarg = 4;
2032         goto snarfnum;
2033
2034     case O_OCT:
2035         maxarg = 3;
2036
2037       snarfnum:
2038         anum = 0;
2039         tmps = str_get(sarg[1]);
2040         for (;;) {
2041             switch (*tmps) {
2042             default:
2043                 goto out;
2044             case '8': case '9':
2045                 if (maxarg != 4)
2046                     goto out;
2047                 /* FALL THROUGH */
2048             case '0': case '1': case '2': case '3': case '4':
2049             case '5': case '6': case '7':
2050                 anum <<= maxarg;
2051                 anum += *tmps++ & 15;
2052                 break;
2053             case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
2054             case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
2055                 if (maxarg != 4)
2056                     goto out;
2057                 anum <<= 4;
2058                 anum += (*tmps++ & 7) + 9;
2059                 break;
2060             case 'x':
2061                 maxarg = 4;
2062                 tmps++;
2063                 break;
2064             }
2065         }
2066       out:
2067         value = (double)anum;
2068         goto donumset;
2069     case O_CHMOD:
2070     case O_CHOWN:
2071     case O_KILL:
2072     case O_UNLINK:
2073         if (arg[1].arg_flags & AF_SPECIAL)
2074             value = (double)apply(optype,arg,Null(STR**));
2075         else {
2076             sarg[2] = Nullstr;
2077             value = (double)apply(optype,arg,sarg);
2078         }
2079         goto donumset;
2080     case O_UMASK:
2081         value = (double)umask((int)str_gnum(sarg[1]));
2082         goto donumset;
2083     case O_RENAME:
2084         tmps = str_get(sarg[1]);
2085 #ifdef RENAME
2086         value = (double)(rename(tmps,str_get(sarg[2])) >= 0);
2087 #else
2088         tmps2 = str_get(sarg[2]);
2089         UNLINK(tmps2);
2090         if (!(anum = link(tmps,tmps2)))
2091             anum = UNLINK(tmps);
2092         value = (double)(anum >= 0);
2093 #endif
2094         goto donumset;
2095     case O_LINK:
2096         tmps = str_get(sarg[1]);
2097         value = (double)(link(tmps,str_get(sarg[2])) >= 0);
2098         goto donumset;
2099     case O_UNSHIFT:
2100         ary = arg[2].arg_ptr.arg_stab->stab_array;
2101         if (arg[1].arg_flags & AF_SPECIAL)
2102             do_unshift(arg,ary);
2103         else {
2104             str = str_new(0);           /* must copy the STR */
2105             str_sset(str,sarg[1]);
2106             aunshift(ary,1);
2107             astore(ary,0,str);
2108         }
2109         value = (double)(ary->ary_fill + 1);
2110         break;
2111     case O_EVAL:
2112         str_sset(str,
2113             do_eval(arg[1].arg_type != A_NULL ? sarg[1] : defstab->stab_val) );
2114         STABSET(str);
2115         break;
2116     }
2117 #ifdef DEBUGGING
2118     dlevel--;
2119     if (debug & 8)
2120         deb("%s RETURNS \"%s\"\n",opname[optype],str_get(str));
2121 #endif
2122     goto freeargs;
2123
2124 donumset:
2125     str_numset(str,value);
2126     STABSET(str);
2127 #ifdef DEBUGGING
2128     dlevel--;
2129     if (debug & 8)
2130         deb("%s RETURNS \"%f\"\n",opname[optype],value);
2131 #endif
2132
2133 freeargs:
2134     if (sarg != quicksarg) {
2135         if (retary) {
2136             if (optype == O_LIST)
2137                 sarg[0] = &str_no;
2138             else
2139                 sarg[0] = Nullstr;
2140             sarg[maxarg+1] = Nullstr;
2141             *retary = sarg;     /* up to them to free it */
2142         }
2143         else
2144             safefree(sarg);
2145     }
2146     return str;
2147
2148 nullarray:
2149     maxarg = 0;
2150 #ifdef DEBUGGING
2151     dlevel--;
2152     if (debug & 8)
2153         deb("%s RETURNS ()\n",opname[optype],value);
2154 #endif
2155     goto freeargs;
2156 }