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