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