📄 doarg.c
字号:
{ char *savepat = pat; int saveitems; fromstr = NEXTFROM; saveitems = items; aptr = str_get(fromstr); if (pat[-1] == '*') len = fromstr->str_cur; pat = aptr; aint = str->str_cur; str->str_cur += (len+1)/2; STR_GROW(str, str->str_cur + 1); aptr = str->str_ptr + aint; if (len > fromstr->str_cur) len = fromstr->str_cur; aint = len; items = 0; if (datumtype == 'H') { for (len = 0; len++ < aint;) { if (isALPHA(*pat)) items |= ((*pat++ & 15) + 9) & 15; else items |= *pat++ & 15; if (len & 1) items <<= 4; else { *aptr++ = items & 0xff; items = 0; } } } else { for (len = 0; len++ < aint;) { if (isALPHA(*pat)) items |= (((*pat++ & 15) + 9) & 15) << 4; else items |= (*pat++ & 15) << 4; if (len & 1) items >>= 4; else { *aptr++ = items & 0xff; items = 0; } } } if (aint & 1) *aptr++ = items & 0xff; pat = str->str_ptr + str->str_cur; while (aptr <= pat) *aptr++ = '\0'; pat = savepat; items = saveitems; } break; case 'C': case 'c': while (len-- > 0) { fromstr = NEXTFROM; aint = (int)str_gnum(fromstr); achar = aint; str_ncat(str,&achar,sizeof(char)); } break; /* Float and double added by gnb@melba.bby.oz.au 22/11/89 */ case 'f': case 'F': while (len-- > 0) { fromstr = NEXTFROM; afloat = (float)str_gnum(fromstr); str_ncat(str, (char *)&afloat, sizeof (float)); } break; case 'd': case 'D': while (len-- > 0) { fromstr = NEXTFROM; adouble = (double)str_gnum(fromstr); str_ncat(str, (char *)&adouble, sizeof (double)); } break; case 'n': while (len-- > 0) { fromstr = NEXTFROM; ashort = (short)str_gnum(fromstr);#ifdef HAS_HTONS ashort = htons(ashort);#endif str_ncat(str,(char*)&ashort,sizeof(short)); } break; case 'v': while (len-- > 0) { fromstr = NEXTFROM; ashort = (short)str_gnum(fromstr);#ifdef HAS_HTOVS ashort = htovs(ashort);#endif str_ncat(str,(char*)&ashort,sizeof(short)); } break; case 'S': case 's': while (len-- > 0) { fromstr = NEXTFROM; ashort = (short)str_gnum(fromstr); str_ncat(str,(char*)&ashort,sizeof(short)); } break; case 'I': while (len-- > 0) { fromstr = NEXTFROM; auint = U_I(str_gnum(fromstr)); str_ncat(str,(char*)&auint,sizeof(unsigned int)); } break; case 'i': while (len-- > 0) { fromstr = NEXTFROM; aint = (int)str_gnum(fromstr); str_ncat(str,(char*)&aint,sizeof(int)); } break; case 'N': while (len-- > 0) { fromstr = NEXTFROM; aulong = U_L(str_gnum(fromstr));#ifdef HAS_HTONL aulong = htonl(aulong);#endif str_ncat(str,(char*)&aulong,sizeof(unsigned long)); } break; case 'V': while (len-- > 0) { fromstr = NEXTFROM; aulong = U_L(str_gnum(fromstr));#ifdef HAS_HTOVL aulong = htovl(aulong);#endif str_ncat(str,(char*)&aulong,sizeof(unsigned long)); } break; case 'L': while (len-- > 0) { fromstr = NEXTFROM; aulong = U_L(str_gnum(fromstr)); str_ncat(str,(char*)&aulong,sizeof(unsigned long)); } break; case 'l': while (len-- > 0) { fromstr = NEXTFROM; along = (long)str_gnum(fromstr); str_ncat(str,(char*)&along,sizeof(long)); } break;#ifdef QUAD case 'Q': while (len-- > 0) { fromstr = NEXTFROM; auquad = (unsigned quad)str_gnum(fromstr); str_ncat(str,(char*)&auquad,sizeof(unsigned quad)); } break; case 'q': while (len-- > 0) { fromstr = NEXTFROM; aquad = (quad)str_gnum(fromstr); str_ncat(str,(char*)&aquad,sizeof(quad)); } break;#endif /* QUAD */ case 'p': while (len-- > 0) { fromstr = NEXTFROM; aptr = str_get(fromstr); str_ncat(str,(char*)&aptr,sizeof(char*)); } break; case 'u': fromstr = NEXTFROM; aptr = str_get(fromstr); aint = fromstr->str_cur; STR_GROW(str,aint * 4 / 3); if (len <= 1) len = 45; else len = len / 3 * 3; while (aint > 0) { int todo; if (aint > len) todo = len; else todo = aint; doencodes(str, aptr, todo); aint -= todo; aptr += todo; } break; } } STABSET(str);}#undef NEXTFROMstatic voiddoencodes(str, s, len)register STR *str;register char *s;register int len;{ char hunk[5]; *hunk = len + ' '; str_ncat(str, hunk, 1); hunk[4] = '\0'; while (len > 0) { hunk[0] = ' ' + (077 & (*s >> 2)); hunk[1] = ' ' + (077 & ((*s << 4) & 060 | (s[1] >> 4) & 017)); hunk[2] = ' ' + (077 & ((s[1] << 2) & 074 | (s[2] >> 6) & 03)); hunk[3] = ' ' + (077 & (s[2] & 077)); str_ncat(str, hunk, 4); s += 3; len -= 3; } for (s = str->str_ptr; *s; s++) { if (*s == ' ') *s = '`'; } str_ncat(str, "\n", 1);}voiddo_sprintf(str,len,sarg)register STR *str;register int len;register STR **sarg;{ register char *s; register char *t; register char *f; bool dolong;#ifdef QUAD bool doquad;#endif /* QUAD */ char ch; static STR *sargnull = &str_no; register char *send; register STR *arg; char *xs; int xlen; int pre; int post; double value; str_set(str,""); len--; /* don't count pattern string */ t = s = str_get(*sarg); send = s + (*sarg)->str_cur; sarg++; for ( ; ; len--) { /*SUPPRESS 560*/ if (len <= 0 || !(arg = *sarg++)) arg = sargnull; /*SUPPRESS 530*/ for ( ; t < send && *t != '%'; t++) ; if (t >= send) break; /* end of format string, ignore extra args */ f = t; *buf = '\0'; xs = buf;#ifdef QUAD doquad =#endif /* QUAD */ dolong = FALSE; pre = post = 0; for (t++; t < send; t++) { switch (*t) { default: ch = *(++t); *t = '\0'; (void)sprintf(xs,f); len++, sarg--; xlen = strlen(xs); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.': case '#': case '-': case '+': case ' ': continue; case 'l':#ifdef QUAD if (dolong) { dolong = FALSE; doquad = TRUE; } else#endif dolong = TRUE; continue; case 'c': ch = *(++t); *t = '\0'; xlen = (int)str_gnum(arg); if (strEQ(f,"%c")) { /* some printfs fail on null chars */ *xs = xlen; xs[1] = '\0'; xlen = 1; } else { (void)sprintf(xs,f,xlen); xlen = strlen(xs); } break; case 'D': dolong = TRUE; /* FALL THROUGH */ case 'd': ch = *(++t); *t = '\0';#ifdef QUAD if (doquad) (void)sprintf(buf,s,(quad)str_gnum(arg)); else#endif if (dolong) (void)sprintf(xs,f,(long)str_gnum(arg)); else (void)sprintf(xs,f,(int)str_gnum(arg)); xlen = strlen(xs); break; case 'X': case 'O': dolong = TRUE; /* FALL THROUGH */ case 'x': case 'o': case 'u': ch = *(++t); *t = '\0'; value = str_gnum(arg);#ifdef QUAD if (doquad) (void)sprintf(buf,s,(unsigned quad)value); else#endif if (dolong) (void)sprintf(xs,f,U_L(value)); else (void)sprintf(xs,f,U_I(value)); xlen = strlen(xs); break; case 'E': case 'e': case 'f': case 'G': case 'g': ch = *(++t); *t = '\0'; (void)sprintf(xs,f,str_gnum(arg)); xlen = strlen(xs); break; case 's': ch = *(++t); *t = '\0'; xs = str_get(arg); xlen = arg->str_cur; if (*xs == 'S' && xs[1] == 't' && xs[2] == 'B' && xs[3] == '\0' && xlen == sizeof(STBP)) { STR *tmpstr = Str_new(24,0); stab_efullname(tmpstr, ((STAB*)arg)); /* a stab value! */ sprintf(tokenbuf,"*%s",tmpstr->str_ptr); /* reformat to non-binary */ xs = tokenbuf; xlen = strlen(tokenbuf); str_free(tmpstr); } if (strEQ(f,"%s")) { /* some printfs fail on >128 chars */ break; /* so handle simple cases */ } else if (f[1] == '-') { char *mp = index(f, '.'); int min = atoi(f+2); if (mp) { int max = atoi(mp+1); if (xlen > max) xlen = max; } if (xlen < min) post = min - xlen; break; } else if (isDIGIT(f[1])) { char *mp = index(f, '.'); int min = atoi(f+1); if (mp) { int max = atoi(mp+1); if (xlen > max) xlen = max; } if (xlen < min) pre = min - xlen; break; } strcpy(tokenbuf+64,f); /* sprintf($s,...$s...) */ *t = ch; (void)sprintf(buf,tokenbuf+64,xs); xs = buf; xlen = strlen(xs); break; } /* end of switch, copy results */ *t = ch; STR_GROW(str, str->str_cur + (f - s) + xlen + 1 + pre + post); str_ncat(str, s, f - s); if (pre) { repeatcpy(str->str_ptr + str->str_cur, " ", 1, pre); str->str_cur += pre; } str_ncat(str, xs, xlen); if (post) { repeatcpy(str->str_ptr + str->str_cur, " ", 1, post); str->str_cur += post; } s = t; break; /* break from for loop */ } } str_ncat(str, s, t - s); STABSET(str);}STR *do_push(ary,arglast)register ARRAY *ary;int *arglast;{ register STR **st = stack->ary_array; register int sp = arglast[1]; register int items = arglast[2] - sp; register STR *str = &str_undef; for (st += ++sp; items > 0; items--,st++) { str = Str_new(26,0); if (*st) str_sset(str,*st); (void)apush(ary,str); } return str;}voiddo_unshift(ary,arglast)register ARRAY *ary;int *arglast;{ register STR **st = stack->ary_array; register int sp = arglast[1]; register int items = arglast[2] - sp; register STR *str; register int i; aunshift(ary,items); i = 0; for (st += ++sp; i < items; i++,st++) { str = Str_new(27,0); str_sset(str,*st); (void)astore(ary,i,str); }}intdo_subr(arg,gimme,arglast)register ARG *arg;int gimme;int *arglast;{ register STR **st = stack->ary_array; register int sp = arglast[1]; register int items = arglast[2] - sp; register SUBR *sub; SPAT * VOLATILE oldspat = curspat; STR *str; STAB *stab; int oldsave = savestack->ary_fill; int oldtmps_base = tmps_base; int hasargs = ((arg[2].arg_type & A_MASK) != A_NULL); register CSV *csv; if ((arg[1].arg_type & A_MASK) == A_WORD) stab = arg[1].arg_ptr.arg_stab; else { STR *tmpstr = STAB_STR(arg[1].arg_ptr.arg_stab); if (tmpstr) stab = stabent(str_get(tmpstr),TRUE); else stab = Nullstab; } if (!stab) fatal("Undefined subroutine called"); if (!(sub = stab_sub(stab))) { STR *tmpstr = arg[0].arg_ptr.arg_str; stab_efullname(tmpstr, stab); fatal("Undefined subroutine \"%s\" called",tmpstr->str_ptr); } if (arg->arg_type == O_DBSUBR && !sub->usersub) { str = stab_val(DBsub); saveitem(str); stab_efullname(str,stab); sub = stab_sub(DBsub); if (!sub) fatal("No DBsub routine"); } str = Str_new(15, sizeof(CSV)); str->str_state = SS_SCSV; (void)apush(savestack,str); csv = (CSV*)str->str_ptr; csv->sub = sub; csv->stab = stab; csv->curcsv = curcsv; csv->curcmd = curcmd; csv->depth = sub->depth; csv->wantarray = gimme; csv->hasargs = hasargs; curcsv = csv; tmps_base = tmps_max; if (sub->usersub) { csv->hasargs = 0; csv->savearray = Null(ARRAY*);; csv->argarray = Null(ARRAY*); st[sp] = arg->arg_ptr.arg_str; if (!hasargs) items = 0; sp = (*sub->usersub)(sub->userindex,sp,items); } else { if (hasargs) { csv->savearray = stab_xarray(defstab); csv->argarray = afake(defstab, items, &st[sp+1]); stab_xarray(defstab) = csv->argarray; } sub->depth++; if (sub->depth >= 2) { /* save temporaries on recursion? */ if (sub->depth == 100 && dowarn) warn("Deep recursion on subroutine \"%s\"",stab_ename(stab)); savelist(sub->tosave->ary_array,sub->tosave->ary_fill); } sp = cmd_exec(sub->cmd,gimme, --sp); /* so do it already */ } st = stack->ary_array; tmps_base = oldtmps_base; for (items = arglast[0] + 1; items <= sp; items++) st[items] = str_mortal(st[items]); /* in case restore wipes old str */ restorelist(oldsave); curspat = oldspat; return sp;}intdo_assign(arg,gimme,arglast)register ARG *arg;int gimme;int *arglast;{ register STR **st = stack->ary_array; STR **firstrelem = st + arglast[1] + 1; STR **firstlelem = st + arglast[0] + 1; STR **lastrelem = st + arglast[2]; STR **lastlelem = st + arglast[1]; register STR **relem; register STR **lelem; register STR *str; register ARRAY *ary; register int makelocal; HASH *hash; int i; makelocal = (arg->arg_flags & AF_LOCAL) != 0; localizing = makelocal; delaymagic = DM_DELAY; /* catch simultaneous items */ /* If there's a common identifier on both sides we have to take * special care that assigning the identifier on the left doesn't * clobber a value on the right that's used later in the list. */ if (arg->arg_flags & AF_COMMON) { for (relem = firstrelem; relem <= lastrelem; relem++) { /*SUPPRESS 560*/ if (str = *relem) *relem = str_mortal(str); } } relem = firstrelem; lelem = firstlelem; ary = Null(ARRAY*); hash = Null(HASH*); while (lelem <= lastlelem) { str = *lelem++; if (str->str_state >= SS_HASH) { if (str->str_state == SS_ARY) { if (makelocal) ary = saveary(str->str_u.str_stab); else { ary = stab_array(str->str_u.str_stab); ary->ary_fill = -1; } i = 0; while (relem <= lastrelem) { /* gobble up all the rest */ str = Str_new(28,0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -