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