1 /* $Header: doarg.c,v 3.0.1.2 89/12/21 19:52:15 lwall Locked $
3 * Copyright (c) 1989, Larry Wall
5 * You may distribute under the terms of the GNU General Public License
6 * as specified in the README file that comes with the perl 3.0 kit.
9 * Revision 3.0.1.2 89/12/21 19:52:15 lwall
10 * patch7: a pattern wouldn't match a null string before the first character
11 * patch7: certain patterns didn't match correctly at end of string
13 * Revision 3.0.1.1 89/11/11 04:17:20 lwall
14 * patch2: printf %c, %D, %X and %O didn't work right
15 * patch2: printf of unsigned vs signed needed separate casts on some machines
17 * Revision 3.0 89/10/18 15:10:41 lwall
27 extern unsigned char fold[];
40 register char *s = str_get(str);
41 char *strend = s + str->str_cur;
52 rspat = spat = arg[2].arg_ptr.arg_spat;
54 fatal("panic: do_subst");
55 else if (spat->spat_runtime) {
57 (void)eval(spat->spat_runtime,G_SCALAR,sp);
58 m = str_get(dstr = stack->ary_array[sp+1]);
60 if (spat->spat_regexp)
61 regfree(spat->spat_regexp);
62 spat->spat_regexp = regcomp(m,m+dstr->str_cur,
63 spat->spat_flags & SPAT_FOLD,1);
64 if (spat->spat_flags & SPAT_KEEP) {
65 arg_free(spat->spat_runtime); /* it won't change, so */
66 spat->spat_runtime = Nullarg; /* no point compiling again */
71 deb("2.SPAT /%s/\n",spat->spat_regexp->precomp);
74 safebase = ((!spat->spat_regexp || !spat->spat_regexp->nparens) &&
76 if (!*spat->spat_regexp->precomp && lastspat)
80 if (hint < s || hint > strend)
81 fatal("panic: hint in do_match");
84 if (spat->spat_regexp->regback >= 0) {
85 s -= spat->spat_regexp->regback;
92 else if (spat->spat_short) {
93 if (spat->spat_flags & SPAT_SCANFIRST) {
94 if (str->str_pok & SP_STUDIED) {
95 if (screamfirst[spat->spat_short->str_rare] < 0)
97 else if (!(s = screaminstr(str,spat->spat_short)))
101 else if (!(s = fbminstr((unsigned char*)s, (unsigned char*)strend,
105 if (s && spat->spat_regexp->regback >= 0) {
106 ++spat->spat_short->str_u.str_useful;
107 s -= spat->spat_regexp->regback;
114 else if (!multiline && (*spat->spat_short->str_ptr != *s ||
115 bcmp(spat->spat_short->str_ptr, s, spat->spat_slen) ))
117 if (--spat->spat_short->str_u.str_useful < 0) {
118 str_free(spat->spat_short);
119 spat->spat_short = Nullstr; /* opt is being useless */
122 once = ((rspat->spat_flags & SPAT_ONCE) != 0);
123 if (rspat->spat_flags & SPAT_CONST) { /* known replacement string? */
124 if ((rspat->spat_repl[1].arg_type & A_MASK) == A_SINGLE)
125 dstr = rspat->spat_repl[1].arg_ptr.arg_str;
126 else { /* constant over loop, anyway */
127 (void)eval(rspat->spat_repl,G_SCALAR,sp);
128 dstr = stack->ary_array[sp+1];
131 clen = dstr->str_cur;
132 if (clen <= spat->spat_slen + spat->spat_regexp->regback) {
133 /* can do inplace substitution */
134 if (regexec(spat->spat_regexp, s, strend, orig, 0,
135 str->str_pok & SP_STUDIED ? str : Nullstr, safebase)) {
136 if (spat->spat_regexp->subbase) /* oops, no we can't */
140 str->str_pok = SP_VALID; /* disable possible screamer */
142 m = spat->spat_regexp->startp[0];
143 d = spat->spat_regexp->endp[0];
145 if (m - s > strend - d) { /* faster to shorten from end */
147 (void)bcopy(c, m, clen);
152 (void)bcopy(d, m, i);
156 str->str_cur = m - s;
158 str_numset(arg->arg_ptr.arg_str, 1.0);
159 stack->ary_array[++sp] = arg->arg_ptr.arg_str;
162 else if (i = m - s) { /* faster from front */
170 (void)bcopy(c, m, clen);
172 str_numset(arg->arg_ptr.arg_str, 1.0);
173 stack->ary_array[++sp] = arg->arg_ptr.arg_str;
179 (void)bcopy(c,d,clen);
181 str_numset(arg->arg_ptr.arg_str, 1.0);
182 stack->ary_array[++sp] = arg->arg_ptr.arg_str;
188 str_numset(arg->arg_ptr.arg_str, 1.0);
189 stack->ary_array[++sp] = arg->arg_ptr.arg_str;
196 fatal("Substitution loop");
197 m = spat->spat_regexp->startp[0];
204 (void)bcopy(c,d,clen);
207 s = spat->spat_regexp->endp[0];
208 } while (regexec(spat->spat_regexp, s, strend, orig, s == m,
209 Nullstr, TRUE)); /* (don't match same null twice) */
212 str->str_cur = d - str->str_ptr + i;
213 (void)bcopy(s,d,i+1); /* include the Null */
216 str_numset(arg->arg_ptr.arg_str, (double)iters);
217 stack->ary_array[++sp] = arg->arg_ptr.arg_str;
220 str_numset(arg->arg_ptr.arg_str, 0.0);
221 stack->ary_array[++sp] = arg->arg_ptr.arg_str;
227 if (regexec(spat->spat_regexp, s, strend, orig, 0,
228 str->str_pok & SP_STUDIED ? str : Nullstr, safebase)) {
230 dstr = Str_new(25,str_len(str));
231 str_nset(dstr,m,s-m);
232 if (spat->spat_regexp->subbase)
237 fatal("Substitution loop");
238 if (spat->spat_regexp->subbase
239 && spat->spat_regexp->subbase != orig) {
242 orig = spat->spat_regexp->subbase;
244 strend = s + (strend - m);
246 m = spat->spat_regexp->startp[0];
247 str_ncat(dstr,s,m-s);
248 s = spat->spat_regexp->endp[0];
251 str_ncat(dstr,c,clen);
254 (void)eval(rspat->spat_repl,G_SCALAR,sp);
255 str_scat(dstr,stack->ary_array[sp+1]);
259 } while (regexec(spat->spat_regexp, s, strend, orig, s == m, Nullstr,
261 str_ncat(dstr,s,strend - s);
262 str_replace(str,dstr);
264 str_numset(arg->arg_ptr.arg_str, (double)iters);
265 stack->ary_array[++sp] = arg->arg_ptr.arg_str;
268 str_numset(arg->arg_ptr.arg_str, 0.0);
269 stack->ary_array[++sp] = arg->arg_ptr.arg_str;
273 ++spat->spat_short->str_u.str_useful;
274 str_numset(arg->arg_ptr.arg_str, 0.0);
275 stack->ary_array[++sp] = arg->arg_ptr.arg_str;
286 register int matches = 0;
290 tbl = arg[2].arg_ptr.arg_cval;
292 send = s + str->str_cur;
294 fatal("panic: do_trans");
301 if (ch = tbl[*s & 0377]) {
316 register STR **st = stack->ary_array;
317 register int sp = arglast[1];
318 register int items = arglast[2] - sp;
319 register char *delim = str_get(st[sp]);
320 int delimlen = st[sp]->str_cur;
327 for (; items > 0; items--,st++) {
328 str_ncat(str,delim,delimlen);
339 register STR **st = stack->ary_array;
340 register int sp = arglast[1];
342 register char *pat = str_get(st[sp]);
343 register char *patend = pat + st[sp]->str_cur;
347 static char *null10 = "\0\0\0\0\0\0\0\0\0\0";
348 static char *space10 = " ";
350 /* These must not be in registers: */
357 items = arglast[2] - sp;
360 while (pat < patend) {
361 #define NEXTFROM (items-- > 0 ? *st++ : &str_no)
365 while (isdigit(*pat))
375 str_ncat(str,null10,10);
378 str_ncat(str,null10,len);
383 aptr = str_get(fromstr);
384 if (fromstr->str_cur > len)
385 str_ncat(str,aptr,len);
387 str_ncat(str,aptr,fromstr->str_cur);
388 len -= fromstr->str_cur;
389 if (datumtype == 'A') {
391 str_ncat(str,space10,10);
394 str_ncat(str,space10,len);
398 str_ncat(str,null10,10);
401 str_ncat(str,null10,len);
408 aint = (int)str_gnum(fromstr);
410 str_ncat(str,&achar,sizeof(char));
416 ashort = (short)str_gnum(fromstr);
418 ashort = htons(ashort);
420 str_ncat(str,(char*)&ashort,sizeof(short));
427 ashort = (short)str_gnum(fromstr);
428 str_ncat(str,(char*)&ashort,sizeof(short));
435 aint = (int)str_gnum(fromstr);
436 str_ncat(str,(char*)&aint,sizeof(int));
442 along = (long)str_gnum(fromstr);
444 along = htonl(along);
446 str_ncat(str,(char*)&along,sizeof(long));
453 along = (long)str_gnum(fromstr);
454 str_ncat(str,(char*)&along,sizeof(long));
460 aptr = str_get(fromstr);
461 str_ncat(str,(char*)&aptr,sizeof(char*));
471 do_sprintf(str,len,sarg)
480 static STR *sargnull = &str_no;
486 len--; /* don't count pattern string */
488 send = s + (*sarg)->str_cur;
490 for ( ; s < send; len--) {
491 if (len <= 0 || !*sarg) {
496 for (t = s; t < send && *t != '%'; t++) ;
498 break; /* not enough % patterns, oh well */
499 for (t++; *sarg && t < send && t != s; t++) {
504 (void)sprintf(buf,s);
509 case '0': case '1': case '2': case '3': case '4':
510 case '5': case '6': case '7': case '8': case '9':
511 case '.': case '#': case '-': case '+':
519 xlen = (int)str_gnum(*(sarg++));
520 if (strEQ(t-2,"%c")) { /* some printfs fail on null chars */
522 str_ncat(str,s,t - s - 2);
523 str_ncat(str,buf,1); /* so handle simple case */
527 (void)sprintf(buf,s,xlen);
538 (void)sprintf(buf,s,(long)str_gnum(*(sarg++)));
540 (void)sprintf(buf,s,(int)str_gnum(*(sarg++)));
547 case 'x': case 'o': case 'u':
551 (void)sprintf(buf,s,(unsigned long)str_gnum(*(sarg++)));
553 (void)sprintf(buf,s,(unsigned int)str_gnum(*(sarg++)));
557 case 'E': case 'e': case 'f': case 'G': case 'g':
560 (void)sprintf(buf,s,str_gnum(*(sarg++)));
568 xlen = (*sarg)->str_cur;
569 if (*xs == 'S' && xs[1] == 't' && xs[2] == 'a' && xs[3] == 'b'
570 && xlen == sizeof(STBP) && strlen(xs) < xlen) {
571 xs = stab_name(((STAB*)(*sarg))); /* a stab value! */
572 sprintf(tokenbuf,"*%s",xs); /* reformat to non-binary */
574 xlen = strlen(tokenbuf);
576 if (strEQ(t-2,"%s")) { /* some printfs fail on >128 chars */
578 str_ncat(str,s,t - s - 2);
579 str_ncat(str,xs,xlen); /* so handle simple case */
582 (void)sprintf(buf,s,xs);
589 if (s < t && t >= send) {
597 (void)sprintf(buf,s,0,0,0,0);
608 register STR **st = stack->ary_array;
609 register int sp = arglast[1];
610 register int items = arglast[2] - sp;
611 register STR *str = &str_undef;
613 for (st += ++sp; items > 0; items--,st++) {
617 (void)apush(ary,str);
623 do_unshift(ary,arglast)
627 register STR **st = stack->ary_array;
628 register int sp = arglast[1];
629 register int items = arglast[2] - sp;
635 for (st += ++sp; i < items; i++,st++) {
638 (void)astore(ary,i,str);
643 do_subr(arg,gimme,arglast)
648 register STR **st = stack->ary_array;
649 register int sp = arglast[1];
650 register int items = arglast[2] - sp;
654 char *oldfile = filename;
655 int oldsave = savestack->ary_fill;
656 int oldtmps_base = tmps_base;
658 if ((arg[1].arg_type & A_MASK) == A_WORD)
659 stab = arg[1].arg_ptr.arg_stab;
661 STR *tmpstr = stab_val(arg[1].arg_ptr.arg_stab);
664 stab = stabent(str_get(tmpstr),TRUE);
669 fatal("Undefined subroutine called");
670 sub = stab_sub(stab);
672 fatal("Undefined subroutine \"%s\" called", stab_name(stab));
673 if ((arg[2].arg_type & A_MASK) != A_NULL) {
674 savearray = stab_xarray(defstab);
675 stab_xarray(defstab) = afake(defstab, items, &st[sp+1]);
677 savelong(&sub->depth);
681 if (sub->depth >= 2) { /* save temporaries on recursion? */
682 if (sub->depth == 100 && dowarn)
683 warn("Deep recursion on subroutine \"%s\"",stab_name(stab));
684 savelist(sub->tosave->ary_array,sub->tosave->ary_fill);
686 filename = sub->filename;
687 tmps_base = tmps_max;
688 sp = cmd_exec(sub->cmd,gimme,--sp); /* so do it already */
689 st = stack->ary_array;
691 if ((arg[2].arg_type & A_MASK) != A_NULL) {
692 afree(stab_xarray(defstab)); /* put back old $_[] */
693 stab_xarray(defstab) = savearray;
696 tmps_base = oldtmps_base;
697 if (savestack->ary_fill > oldsave) {
698 for (items = arglast[0] + 1; items <= sp; items++)
699 st[items] = str_static(st[items]);
700 /* in case restore wipes old str */
701 restorelist(oldsave);
707 do_dbsubr(arg,gimme,arglast)
712 register STR **st = stack->ary_array;
713 register int sp = arglast[1];
714 register int items = arglast[2] - sp;
719 char *oldfile = filename;
720 int oldsave = savestack->ary_fill;
721 int oldtmps_base = tmps_base;
723 if ((arg[1].arg_type & A_MASK) == A_WORD)
724 stab = arg[1].arg_ptr.arg_stab;
726 STR *tmpstr = stab_val(arg[1].arg_ptr.arg_stab);
729 stab = stabent(str_get(tmpstr),TRUE);
734 fatal("Undefined subroutine called");
735 sub = stab_sub(stab);
737 fatal("Undefined subroutine \"%s\" called", stab_name(stab));
738 /* begin differences */
739 str = stab_val(DBsub);
741 str_set(str,stab_name(stab));
742 sub = stab_sub(DBsub);
744 fatal("No DBsub routine");
745 /* end differences */
746 if ((arg[2].arg_type & A_MASK) != A_NULL) {
747 savearray = stab_xarray(defstab);
748 stab_xarray(defstab) = afake(defstab, items, &st[sp+1]);
750 savelong(&sub->depth);
754 if (sub->depth >= 2) { /* save temporaries on recursion? */
755 if (sub->depth == 100 && dowarn)
756 warn("Deep recursion on subroutine \"%s\"",stab_name(stab));
757 savelist(sub->tosave->ary_array,sub->tosave->ary_fill);
759 filename = sub->filename;
760 tmps_base = tmps_max;
761 sp = cmd_exec(sub->cmd,gimme, --sp); /* so do it already */
762 st = stack->ary_array;
764 if ((arg[2].arg_type & A_MASK) != A_NULL) {
765 afree(stab_xarray(defstab)); /* put back old $_[] */
766 stab_xarray(defstab) = savearray;
769 tmps_base = oldtmps_base;
770 if (savestack->ary_fill > oldsave) {
771 for (items = arglast[0] + 1; items <= sp; items++)
772 st[items] = str_static(st[items]);
773 /* in case restore wipes old str */
774 restorelist(oldsave);
780 do_assign(arg,gimme,arglast)
786 register STR **st = stack->ary_array;
787 STR **firstrelem = st + arglast[1] + 1;
788 STR **firstlelem = st + arglast[0] + 1;
789 STR **lastrelem = st + arglast[2];
790 STR **lastlelem = st + arglast[1];
791 register STR **relem;
792 register STR **lelem;
796 register int makelocal;
800 makelocal = (arg->arg_flags & AF_LOCAL);
801 delaymagic = DM_DELAY; /* catch simultaneous items */
803 /* If there's a common identifier on both sides we have to take
804 * special care that assigning the identifier on the left doesn't
805 * clobber a value on the right that's used later in the list.
807 if (arg->arg_flags & AF_COMMON) {
808 for (relem = firstrelem; relem <= lastrelem; relem++) {
810 *relem = str_static(str);
817 while (lelem <= lastlelem) {
819 if (str->str_state >= SS_HASH) {
820 if (str->str_state == SS_ARY) {
822 ary = saveary(str->str_u.str_stab);
824 ary = stab_array(str->str_u.str_stab);
828 while (relem <= lastrelem) { /* gobble up all the rest */
831 str_sset(str,*(relem++));
834 (void)astore(ary,i++,str);
837 else if (str->str_state == SS_HASH) {
842 hash = savehash(str->str_u.str_stab);
844 hash = stab_hash(str->str_u.str_stab);
847 while (relem < lastrelem) { /* gobble up all the rest */
851 str = &str_no, relem++;
853 tmpstr = Str_new(29,0);
855 str_sset(tmpstr,*(relem++)); /* value */
858 (void)hstore(hash,tmps,str->str_cur,tmpstr,0);
862 fatal("panic: do_assign");
867 if (relem <= lastrelem)
868 str_sset(str, *(relem++));
870 str_nset(str, "", 0);
874 if (delaymagic > 1) {
876 if (delaymagic & DM_REUID)
880 if (delaymagic & DM_REGID)
885 if (gimme == G_ARRAY) {
886 i = lastrelem - firstrelem + 1;
888 Copy(firstrelem, firstlelem, i, STR*);
889 return arglast[0] + i;
892 str_numset(arg->arg_ptr.arg_str,(double)(arglast[2] - arglast[1]));
893 *firstlelem = arg->arg_ptr.arg_str;
894 return arglast[0] + 1;
899 do_study(str,arg,gimme,arglast)
905 register unsigned char *s;
906 register int pos = str->str_cur;
908 register int *sfirst;
910 static int maxscream = -1;
911 static STR *lastscream = Nullstr;
913 int retarg = arglast[0] + 1;
916 s = (unsigned char*)(str_get(str));
918 s = Null(unsigned char*);
921 lastscream->str_pok &= ~SP_STUDIED;
927 if (pos > maxscream) {
929 maxscream = pos + 80;
930 New(301,screamfirst, 256, int);
931 New(302,screamnext, maxscream, int);
934 maxscream = pos + pos / 4;
935 Renew(screamnext, maxscream, int);
939 sfirst = screamfirst;
942 if (!sfirst || !snext)
943 fatal("do_study: out of memory");
945 for (ch = 256; ch; --ch)
952 snext[pos] = sfirst[ch] - pos;
957 /* If there were any case insensitive searches, we must assume they
958 * all are. This speeds up insensitive searches much more than
959 * it slows down sensitive ones.
962 sfirst[fold[ch]] = pos;
965 str->str_pok |= SP_STUDIED;
968 str_numset(arg->arg_ptr.arg_str,(double)retval);
969 stack->ary_array[retarg] = arg->arg_ptr.arg_str;
974 do_defined(str,arg,gimme,arglast)
981 register int retarg = arglast[0] + 1;
984 if ((arg[1].arg_type & A_MASK) != A_LEXPR)
985 fatal("Illegal argument to defined()");
986 arg = arg[1].arg_ptr.arg_arg;
987 type = arg->arg_type;
989 if (type == O_ARRAY || type == O_LARRAY)
990 retval = stab_xarray(arg[1].arg_ptr.arg_stab) != 0;
991 else if (type == O_HASH || type == O_LHASH)
992 retval = stab_xhash(arg[1].arg_ptr.arg_stab) != 0;
993 else if (type == O_SUBR || type == O_DBSUBR)
994 retval = stab_sub(arg[1].arg_ptr.arg_stab) != 0;
995 else if (type == O_ASLICE || type == O_LASLICE)
996 retval = stab_xarray(arg[1].arg_ptr.arg_stab) != 0;
997 else if (type == O_HSLICE || type == O_LHSLICE)
998 retval = stab_xhash(arg[1].arg_ptr.arg_stab) != 0;
1001 str_numset(str,(double)retval);
1002 stack->ary_array[retarg] = str;
1007 do_undef(str,arg,gimme,arglast)
1014 register STAB *stab;
1015 int retarg = arglast[0] + 1;
1017 if ((arg[1].arg_type & A_MASK) != A_LEXPR)
1018 fatal("Illegal argument to undef()");
1019 arg = arg[1].arg_ptr.arg_arg;
1020 type = arg->arg_type;
1022 if (type == O_ARRAY || type == O_LARRAY) {
1023 stab = arg[1].arg_ptr.arg_stab;
1024 afree(stab_xarray(stab));
1025 stab_xarray(stab) = Null(ARRAY*);
1027 else if (type == O_HASH || type == O_LHASH) {
1028 stab = arg[1].arg_ptr.arg_stab;
1029 (void)hfree(stab_xhash(stab));
1030 stab_xhash(stab) = Null(HASH*);
1032 else if (type == O_SUBR || type == O_DBSUBR) {
1033 stab = arg[1].arg_ptr.arg_stab;
1034 cmd_free(stab_sub(stab)->cmd);
1035 afree(stab_sub(stab)->tosave);
1036 Safefree(stab_sub(stab));
1037 stab_sub(stab) = Null(SUBR*);
1040 fatal("Can't undefine that kind of object");
1041 str_numset(str,0.0);
1042 stack->ary_array[retarg] = str;
1047 do_vec(lvalue,astr,arglast)
1052 STR **st = stack->ary_array;
1053 int sp = arglast[0];
1054 register STR *str = st[++sp];
1055 register int offset = (int)str_gnum(st[++sp]);
1056 register int size = (int)str_gnum(st[++sp]);
1057 unsigned char *s = (unsigned char*)str_get(str);
1058 unsigned long retnum;
1062 offset *= size; /* turn into bit offset */
1063 len = (offset + size + 7) / 8;
1064 if (offset < 0 || size < 1)
1066 else if (!lvalue && len > str->str_cur)
1069 if (len > str->str_cur) {
1071 (void)bzero(str->str_ptr + str->str_cur, len - str->str_cur);
1074 s = (unsigned char*)str_get(str);
1076 retnum = (s[offset >> 3] >> (offset & 7)) & ((1 << size) - 1);
1081 else if (size == 16)
1082 retnum = (s[offset] << 8) + s[offset+1];
1083 else if (size == 32)
1084 retnum = (s[offset] << 24) + (s[offset + 1] << 16) +
1085 (s[offset + 2] << 8) + s[offset+3];
1088 if (lvalue) { /* it's an lvalue! */
1089 struct lstring *lstr = (struct lstring*)astr;
1091 astr->str_magic = str;
1092 st[sp]->str_rare = 'v';
1093 lstr->lstr_offset = offset;
1094 lstr->lstr_len = size;
1098 str_numset(astr,(double)retnum);
1108 struct lstring *lstr = (struct lstring*)str;
1109 register int offset;
1111 register unsigned char *s = (unsigned char*)mstr->str_ptr;
1112 register unsigned long lval = (unsigned long)str_gnum(str);
1116 str->str_magic = Nullstr;
1117 offset = lstr->lstr_offset;
1118 size = lstr->lstr_len;
1120 mask = (1 << size) - 1;
1124 s[offset] &= ~(mask << size);
1125 s[offset] |= lval << size;
1129 s[offset] = lval & 255;
1130 else if (size == 16) {
1131 s[offset] = (lval >> 8) & 255;
1132 s[offset+1] = lval & 255;
1134 else if (size == 32) {
1135 s[offset] = (lval >> 24) & 255;
1136 s[offset+1] = (lval >> 16) & 255;
1137 s[offset+2] = (lval >> 8) & 255;
1138 s[offset+3] = lval & 255;
1147 register char *tmps;
1155 if (str->str_state == SS_ARY) {
1156 ary = stab_array(str->str_u.str_stab);
1157 for (i = 0; i <= ary->ary_fill; i++)
1158 do_chop(astr,ary->ary_array[i]);
1161 if (str->str_state == SS_HASH) {
1162 hash = stab_hash(str->str_u.str_stab);
1163 (void)hiterinit(hash);
1164 while (entry = hiternext(hash))
1165 do_chop(astr,hiterval(hash,entry));
1168 tmps = str_get(str);
1171 tmps += str->str_cur - (str->str_cur != 0);
1172 str_nset(astr,tmps,1); /* remember last char */
1173 *tmps = '\0'; /* wipe it out */
1174 str->str_cur = tmps - str->str_ptr;
1178 do_vop(optype,str,left,right)
1183 register char *s = str_get(str);
1184 register char *l = str_get(left);
1185 register char *r = str_get(right);
1188 len = left->str_cur;
1189 if (len > right->str_cur)
1190 len = right->str_cur;
1191 if (str->str_cur > len)
1193 else if (str->str_cur < len) {
1195 (void)bzero(str->str_ptr + str->str_cur, len - str->str_cur);
1213 if (right->str_cur > len)
1214 str_ncat(str,right->str_ptr+len,right->str_cur - len);
1215 else if (left->str_cur > len)
1216 str_ncat(str,left->str_ptr+len,left->str_cur - len);
1225 register STR **st = stack->ary_array;
1226 register int sp = arglast[1];
1227 register int items = arglast[2] - sp;
1234 for (st += ++sp; items--; st++)
1235 tainted |= (*st)->str_tainted;
1236 st = stack->ary_array;
1238 items = arglast[2] - sp;
1241 taintproper("Insecure dependency in syscall");
1243 /* This probably won't work on machines where sizeof(long) != sizeof(int)
1244 * or where sizeof(long) != sizeof(char*). But such machines will
1245 * not likely have syscall implemented either, so who cares?
1248 if (st[++sp]->str_nok || !i)
1249 arg[i++] = (long)str_gnum(st[sp]);
1252 arg[i++] = (long)st[sp]->str_ptr;
1256 items = arglast[2] - sp;
1259 fatal("Too few args to syscall");
1261 retval = syscall(arg[0]);
1264 retval = syscall(arg[0],arg[1]);
1267 retval = syscall(arg[0],arg[1],arg[2]);
1270 retval = syscall(arg[0],arg[1],arg[2],arg[3]);
1273 retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4]);
1276 retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5]);
1279 retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6]);
1282 retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],
1286 st[sp] = str_static(&str_undef);
1287 str_numset(st[sp], (double)retval);
1290 fatal("syscall() unimplemented");