⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dolist.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
		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(&timesbuf);#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 + -