📄 dolist.c
字号:
st = stack->ary_array; } Copy(ary->ary_array+offset, st+sp, length, STR*); if (ary->ary_flags & ARF_REAL) { for (i = length, dst = st+sp; i; i--) str_2mortal(*dst++); /* free them eventualy */ } sp += length - 1; } else { st[sp] = ary->ary_array[offset+length-1]; if (ary->ary_flags & ARF_REAL) { str_2mortal(st[sp]); for (i = length - 1, dst = &ary->ary_array[offset]; i > 0; i--) str_free(*dst++); /* free them now */ } } ary->ary_fill += diff; /* pull up or down? */ if (offset < after) { /* easier to pull up */ if (offset) { /* esp. if nothing to pull */ src = &ary->ary_array[offset-1]; dst = src - diff; /* diff is negative */ for (i = offset; i > 0; i--) /* can't trust Copy */ *dst-- = *src--; } Zero(ary->ary_array, -diff, STR*); ary->ary_array -= diff; /* diff is negative */ ary->ary_max += diff; } else { if (after) { /* anything to pull down? */ src = ary->ary_array + offset + length; dst = src + diff; /* diff is negative */ Move(src, dst, after, STR*); } Zero(&ary->ary_array[ary->ary_fill+1], -diff, STR*); /* avoid later double free */ } if (newlen) { for (src = tmparyval, dst = ary->ary_array + offset; newlen; newlen--) { *dst = Str_new(46,0); str_sset(*dst++,*src++); } Safefree(tmparyval); } } else { /* no, expanding (or same) */ if (length) { New(452, tmparyval, length, STR*); /* so remember deletion */ Copy(ary->ary_array+offset, tmparyval, length, STR*); } if (diff > 0) { /* expanding */ /* push up or down? */ if (offset < after && diff <= ary->ary_array - ary->ary_alloc) { if (offset) { src = ary->ary_array; dst = src - diff; Move(src, dst, offset, STR*); } ary->ary_array -= diff; /* diff is positive */ ary->ary_max += diff; ary->ary_fill += diff; } else { if (ary->ary_fill + diff >= ary->ary_max) /* oh, well */ astore(ary, ary->ary_fill + diff, Nullstr); else ary->ary_fill += diff; dst = ary->ary_array + ary->ary_fill; for (i = diff; i > 0; i--) { if (*dst) /* str was hanging around */ str_free(*dst); /* after $#foo */ dst--; } if (after) { dst = ary->ary_array + ary->ary_fill; src = dst - diff; for (i = after; i; i--) { *dst-- = *src--; } } } } for (src = st+sp, dst = ary->ary_array + offset; newlen; newlen--) { *dst = Str_new(46,0); str_sset(*dst++,*src++); } sp = arglast[0] + 1; if (gimme == G_ARRAY) { /* copy return vals to stack */ if (length) { Copy(tmparyval, st+sp, length, STR*); if (ary->ary_flags & ARF_REAL) { for (i = length, dst = st+sp; i; i--) str_2mortal(*dst++); /* free them eventualy */ } Safefree(tmparyval); } sp += length - 1; } else if (length--) { st[sp] = tmparyval[length]; if (ary->ary_flags & ARF_REAL) { str_2mortal(st[sp]); while (length-- > 0) str_free(tmparyval[length]); } Safefree(tmparyval); } else st[sp] = &str_undef; } return sp;}intdo_grep(arg,str,gimme,arglast)register ARG *arg;STR *str;int gimme;int *arglast;{ STR **st = stack->ary_array; register int dst = arglast[1]; register int src = dst + 1; register int sp = arglast[2]; register int i = sp - arglast[1]; int oldsave = savestack->ary_fill; SPAT *oldspat = curspat; int oldtmps_base = tmps_base; savesptr(&stab_val(defstab)); tmps_base = tmps_max; if ((arg[1].arg_type & A_MASK) != A_EXPR) { arg[1].arg_type &= A_MASK; dehoist(arg,1); arg[1].arg_type |= A_DONT; } arg = arg[1].arg_ptr.arg_arg; while (i-- > 0) { if (st[src]) { st[src]->str_pok &= ~SP_TEMP; stab_val(defstab) = st[src]; } else stab_val(defstab) = str_mortal(&str_undef); (void)eval(arg,G_SCALAR,sp); st = stack->ary_array; if (str_true(st[sp+1])) st[dst++] = st[src]; src++; curspat = oldspat; } restorelist(oldsave); tmps_base = oldtmps_base; if (gimme != G_ARRAY) { str_numset(str,(double)(dst - arglast[1])); STABSET(str); st[arglast[0]+1] = str; return arglast[0]+1; } return arglast[0] + (dst - arglast[1]);}intdo_reverse(arglast)int *arglast;{ STR **st = stack->ary_array; register STR **up = &st[arglast[1]]; register STR **down = &st[arglast[2]]; register int i = arglast[2] - arglast[1]; while (i-- > 0) { *up++ = *down; if (i-- > 0) *down-- = *up; } i = arglast[2] - arglast[1]; Move(down+1,up,i/2,STR*); return arglast[2] - 1;}intdo_sreverse(str,arglast)STR *str;int *arglast;{ STR **st = stack->ary_array; register char *up; register char *down; register int tmp; str_sset(str,st[arglast[2]]); up = str_get(str); if (str->str_cur > 1) { down = str->str_ptr + str->str_cur - 1; while (down > up) { tmp = *up; *up++ = *down; *down-- = tmp; } } STABSET(str); st[arglast[0]+1] = str; return arglast[0]+1;}static CMD *sortcmd;static HASH *sortstash = Null(HASH*);static STAB *firststab = Nullstab;static STAB *secondstab = Nullstab;intdo_sort(str,arg,gimme,arglast)STR *str;ARG *arg;int gimme;int *arglast;{ register STR **st = stack->ary_array; int sp = arglast[1]; register STR **up; register int max = arglast[2] - sp; register int i; int sortcmp(); int sortsub(); STR *oldfirst; STR *oldsecond; ARRAY *oldstack; HASH *stash; STR *sortsubvar; static ARRAY *sortstack = Null(ARRAY*); if (gimme != G_ARRAY) { str_sset(str,&str_undef); STABSET(str); st[sp] = str; return sp; } up = &st[sp]; sortsubvar = *up; st += sp; /* temporarily make st point to args */ for (i = 1; i <= max; i++) { /*SUPPRESS 560*/ if (*up = st[i]) { if (!(*up)->str_pok) (void)str_2ptr(*up); else (*up)->str_pok &= ~SP_TEMP; up++; } } st -= sp; max = up - &st[sp]; sp--; if (max > 1) { STAB *stab; if (arg[1].arg_type == (A_CMD|A_DONT)) { sortcmd = arg[1].arg_ptr.arg_cmd; stash = curcmd->c_stash; } else { if ((arg[1].arg_type & A_MASK) == A_WORD) stab = arg[1].arg_ptr.arg_stab; else stab = stabent(str_get(sortsubvar),TRUE); if (stab) { if (!stab_sub(stab) || !(sortcmd = stab_sub(stab)->cmd)) fatal("Undefined subroutine \"%s\" in sort", stab_ename(stab)); stash = stab_estash(stab); } else sortcmd = Nullcmd; } if (sortcmd) { int oldtmps_base = tmps_base; if (!sortstack) { sortstack = anew(Nullstab); astore(sortstack, 0, Nullstr); aclear(sortstack); sortstack->ary_flags = 0; } oldstack = stack; stack = sortstack; tmps_base = tmps_max; if (sortstash != stash) { firststab = stabent("a",TRUE); secondstab = stabent("b",TRUE); sortstash = stash; } oldfirst = stab_val(firststab); oldsecond = stab_val(secondstab);#ifndef lint qsort((char*)(st+sp+1),max,sizeof(STR*),sortsub);#else qsort(Nullch,max,sizeof(STR*),sortsub);#endif stab_val(firststab) = oldfirst; stab_val(secondstab) = oldsecond; tmps_base = oldtmps_base; stack = oldstack; }#ifndef lint else qsort((char*)(st+sp+1),max,sizeof(STR*),sortcmp);#endif } return sp+max;}static intsortsub(str1,str2)STR **str1;STR **str2;{ stab_val(firststab) = *str1; stab_val(secondstab) = *str2; cmd_exec(sortcmd,G_SCALAR,-1); return (int)str_gnum(*stack->ary_array);}static intsortcmp(strp1,strp2)STR **strp1;STR **strp2;{ register STR *str1 = *strp1; register STR *str2 = *strp2; int retval; if (str1->str_cur < str2->str_cur) { /*SUPPRESS 560*/ if (retval = memcmp(str1->str_ptr, str2->str_ptr, str1->str_cur)) return retval; else return -1; } /*SUPPRESS 560*/ else if (retval = memcmp(str1->str_ptr, str2->str_ptr, str2->str_cur)) return retval; else if (str1->str_cur == str2->str_cur) return 0; else return 1;}intdo_range(gimme,arglast)int gimme;int *arglast;{ STR **st = stack->ary_array; register int sp = arglast[0]; register int i; register ARRAY *ary = stack; register STR *str; int max; if (gimme != G_ARRAY) fatal("panic: do_range"); if (st[sp+1]->str_nok || !st[sp+1]->str_pok || (looks_like_number(st[sp+1]) && *st[sp+1]->str_ptr != '0') ) { i = (int)str_gnum(st[sp+1]); max = (int)str_gnum(st[sp+2]); if (max > i) (void)astore(ary, sp + max - i + 1, Nullstr); while (i <= max) { (void)astore(ary, ++sp, str = str_mortal(&str_no)); str_numset(str,(double)i++); } } else { STR *final = str_mortal(st[sp+2]); char *tmps = str_get(final); str = str_mortal(st[sp+1]); while (!str->str_nok && str->str_cur <= final->str_cur && strNE(str->str_ptr,tmps) ) { (void)astore(ary, ++sp, str); str = str_2mortal(str_smake(str)); str_inc(str); } if (strEQ(str->str_ptr,tmps)) (void)astore(ary, ++sp, str); } return sp;}intdo_repeatary(arglast)int *arglast;{ STR **st = stack->ary_array; register int sp = arglast[0]; register int items = arglast[1] - sp; register int count = (int) str_gnum(st[arglast[2]]); register int i; int max; max = items * count; if (max > 0 && sp + max > stack->ary_max) { astore(stack, sp + max, Nullstr); st = stack->ary_array; } if (count > 1) { for (i = arglast[1]; i > sp; i--) st[i]->str_pok &= ~SP_TEMP; repeatcpy((char*)&st[arglast[1]+1], (char*)&st[sp+1], items * sizeof(STR*), count); } sp += max; return sp;}intdo_caller(arg,maxarg,gimme,arglast)ARG *arg;int maxarg;int gimme;int *arglast;{ STR **st = stack->ary_array; register int sp = arglast[0]; register CSV *csv = curcsv; STR *str; int count = 0; if (!csv) fatal("There is no caller"); if (maxarg) count = (int) str_gnum(st[sp+1]); for (;;) { if (!csv) return sp; if (DBsub && csv->curcsv && csv->curcsv->sub == stab_sub(DBsub)) count++; if (!count--) break; csv = csv->curcsv; } if (gimme != G_ARRAY) { STR *str = arg->arg_ptr.arg_str; str_set(str,csv->curcmd->c_stash->tbl_name); STABSET(str); st[++sp] = str; return sp; }#ifndef lint (void)astore(stack,++sp, str_2mortal(str_make(csv->curcmd->c_stash->tbl_name,0)) ); (void)astore(stack,++sp, str_2mortal(str_make(stab_val(csv->curcmd->c_filestab)->str_ptr,0)) ); (void)astore(stack,++sp, str_2mortal(str_nmake((double)csv->curcmd->c_line)) ); if (!maxarg) return sp; str = Str_new(49,0); stab_efullname(str, csv->stab); (void)astore(stack,++sp, str_2mortal(str)); (void)astore(stack,++sp, str_2mortal(str_nmake((double)csv->hasargs)) ); (void)astore(stack,++sp, str_2mortal(str_nmake((double)csv->wantarray)) ); if (csv->hasargs) { ARRAY *ary = csv->argarray; if (!dbargs) dbargs = stab_xarray(aadd(stabent("DB'args", TRUE))); if (dbargs->ary_max < ary->ary_fill) astore(dbargs,ary->ary_fill,Nullstr); Copy(ary->ary_array, dbargs->ary_array, ary->ary_fill+1, STR*); dbargs->ary_fill = ary->ary_fill; }#else (void)astore(stack,++sp, str_2mortal(str_make("",0)));#endif return sp;}intdo_tms(str,gimme,arglast)STR *str;int gimme;int *arglast;{#ifdef MSDOS return -1;#else STR **st = stack->ary_array; register int sp = arglast[0]; if (gimme != G_ARRAY) { str_sset(str,&str_undef); STABSET(str); st[++sp] = str; return sp; } (void)times(×buf);#ifndef HZ#define HZ 60#endif#ifndef lint (void)astore(stack,++sp, str_2mortal(str_nmake(((double)timesbuf.tms_utime)/HZ))); (void)astore(stack,++sp, str_2mortal(str_nmake(((double)timesbuf.tms_stime)/HZ))); (void)astore(stack,++sp, str_2mortal(str_nmake(((double)timesbuf.tms_cutime)/HZ))); (void)astore(stack,++sp, str_2mortal(str_nmake(((double)timesbuf.tms_cstime)/HZ)));#else (void)astore(stack,++sp, str_2mortal(str_nmake(0.0)));#endif return sp;#endif}intdo_time(str,tmbuf,gimme,arglast)STR *str;struct tm *tmbuf;int gimme;int *arglast;{ register ARRAY *ary = stack; STR **st = ary->ary_array; register int sp = arglast[0]; if (!tmbuf || gimme != G_ARRAY) { str_sset(str,&str_undef); STABSET(str); st[++sp] = str; return sp; } (void)astore(ary,++sp,str_2mortal(str_nmake((double)tmbuf->tm_sec))); (void)astore(ary,++sp,str_2mortal(str_nmake((double)tmbuf->tm_min))); (void)astore(ary,++sp,str_2mortal(str_nmake((double)tmbuf->tm_hour))); (void)astore(ary,++sp,str_2mortal(str_nmake((double)tmbuf->tm_mday))); (void)astore(ary,++sp,str_2mortal(str_nmake((double)tmbuf->tm_mon))); (void)astore(ary,++sp,str_2mortal(str_nmake((double)tmbuf->tm_year))); (void)astore(ary,++sp,str_2mortal(str_nmake((double)tmbuf->tm_wday))); (void)astore(ary,++sp,str_2mortal(str_nmake((double)tmbuf->tm_yday))); (void)astore(ary,++sp,str_2mortal(str_nmake((double)tmbuf->tm_isdst))); return sp;}intdo_kv(str,hash,kv,gimme,arglast)STR *str;HASH *hash;int kv;int gimme;int *arglast;{ register ARRAY *ary = stack; STR **st = ary->ary_array; register int sp = arglast[0]; int i; register HENT *entry; char *tmps; STR *tmpstr; int dokeys = (kv == O_KEYS || kv == O_HASH); int dovalues = (kv == O_VALUES || kv == O_HASH); if (gimme != G_ARRAY) { i = 0; (void)hiterinit(hash); /*SUPPRESS 560*/ while (entry = hiternext(hash)) { i++; } str_numset(str,(double)i); STABSET(str); st[++sp] = str; return sp; } (void)hiterinit(hash); /*SUPPRESS 560*/ while (entry = hiternext(hash)) { if (dokeys) { tmps = hiterkey(entry,&i); if (!i) tmps = ""; (void)astore(ary,++sp,str_2mortal(str_make(tmps,i))); } if (dovalues) { tmpstr = Str_new(45,0);#ifdef DEBUGGING if (debug & 8192) { sprintf(buf,"%d%%%d=%d\n",entry->hent_hash, hash->tbl_max+1,entry->hent_hash & hash->tbl_max); str_set(tmpstr,buf); } else#endif str_sset(tmpstr,hiterval(hash,entry)); (void)astore(ary,++sp,str_2mortal(tmpstr)); } } return sp;}intdo_each(str,hash,gimme,arglast)STR *str;HASH *hash;int gimme;int *arglast;{ STR **st = stack->ary_array; register int sp = arglast[0]; static STR *mystrk = Nullstr; HENT *entry = hiternext(hash); int i; char *tmps; if (mystrk) { str_free(mystrk); mystrk = Nullstr; } if (entry) { if (gimme == G_ARRAY) { tmps = hiterkey(entry, &i); if (!i) tmps = ""; st[++sp] = mystrk = str_make(tmps,i); } st[++sp] = str; str_sset(str,hiterval(hash,entry)); STABSET(str); return sp; } else return sp;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -