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

📄 str.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
}voidstr_insert(bigstr,offset,len,little,littlelen)STR *bigstr;STRLEN offset;STRLEN len;char *little;STRLEN littlelen;{    register char *big;    register char *mid;    register char *midend;    register char *bigend;    register int i;    if (bigstr == &str_undef)	return;    bigstr->str_nok = 0;    bigstr->str_pok = SP_VALID;	/* disable possible screamer */    i = littlelen - len;    if (i > 0) {			/* string might grow */	STR_GROW(bigstr, bigstr->str_cur + i + 1);	big = bigstr->str_ptr;	mid = big + offset + len;	midend = bigend = big + bigstr->str_cur;	bigend += i;	*bigend = '\0';	while (midend > mid)		/* shove everything down */	    *--bigend = *--midend;	Move(little,big+offset,littlelen,char);	bigstr->str_cur += i;	STABSET(bigstr);	return;    }    else if (i == 0) {	Move(little,bigstr->str_ptr+offset,len,char);	STABSET(bigstr);	return;    }    big = bigstr->str_ptr;    mid = big + offset;    midend = mid + len;    bigend = big + bigstr->str_cur;    if (midend > bigend)	fatal("panic: str_insert");    if (mid - big > bigend - midend) {	/* faster to shorten from end */	if (littlelen) {	    Move(little, mid, littlelen,char);	    mid += littlelen;	}	i = bigend - midend;	if (i > 0) {	    Move(midend, mid, i,char);	    mid += i;	}	*mid = '\0';	bigstr->str_cur = mid - big;    }    /*SUPPRESS 560*/    else if (i = mid - big) {	/* faster from front */	midend -= littlelen;	mid = midend;	str_chop(bigstr,midend-i);	big += i;	while (i--)	    *--midend = *--big;	if (littlelen)	    Move(little, mid, littlelen,char);    }    else if (littlelen) {	midend -= littlelen;	str_chop(bigstr,midend);	Move(little,midend,littlelen,char);    }    else {	str_chop(bigstr,midend);    }    STABSET(bigstr);}/* make str point to what nstr did */voidstr_replace(str,nstr)register STR *str;register STR *nstr;{    if (str == &str_undef)	return;    if (str->str_state == SS_INCR)	Str_Grow(str,0);	/* just force copy down */    if (nstr->str_state == SS_INCR)	Str_Grow(nstr,0);    if (str->str_ptr)	Safefree(str->str_ptr);    str->str_ptr = nstr->str_ptr;    str->str_len = nstr->str_len;    str->str_cur = nstr->str_cur;    str->str_pok = nstr->str_pok;    str->str_nok = nstr->str_nok;#ifdef STRUCTCOPY    str->str_u = nstr->str_u;#else    str->str_u.str_nval = nstr->str_u.str_nval;#endif#ifdef TAINT    str->str_tainted = nstr->str_tainted;#endif    if (nstr->str_magic)	str_free(nstr->str_magic);    Safefree(nstr);}voidstr_free(str)register STR *str;{    if (!str || str == &str_undef)	return;    if (str->str_state) {	if (str->str_state == SS_FREE)	/* already freed */	    return;	if (str->str_state == SS_INCR && !(str->str_pok & 2)) {	    str->str_ptr -= str->str_u.str_useful;	    str->str_len += str->str_u.str_useful;	}    }    if (str->str_magic)	str_free(str->str_magic);    str->str_magic = freestrroot;#ifdef LEAKTEST    if (str->str_len) {	Safefree(str->str_ptr);	str->str_ptr = Nullch;    }    if ((str->str_pok & SP_INTRP) && str->str_u.str_args)	arg_free(str->str_u.str_args);    Safefree(str);#else /* LEAKTEST */    if (str->str_len) {	if (str->str_len > 127) {	/* next user not likely to want more */	    Safefree(str->str_ptr);	/* so give it back to malloc */	    str->str_ptr = Nullch;	    str->str_len = 0;	}	else	    str->str_ptr[0] = '\0';    }    if ((str->str_pok & SP_INTRP) && str->str_u.str_args)	arg_free(str->str_u.str_args);    str->str_cur = 0;    str->str_nok = 0;    str->str_pok = 0;    str->str_state = SS_FREE;#ifdef TAINT    str->str_tainted = 0;#endif    freestrroot = str;#endif /* LEAKTEST */}STRLENstr_len(str)register STR *str;{    if (!str)	return 0;    if (!(str->str_pok))	(void)str_2ptr(str);    if (str->str_ptr)	return str->str_cur;    else	return 0;}intstr_eq(str1,str2)register STR *str1;register STR *str2;{    if (!str1 || str1 == &str_undef)	return (str2 == Nullstr || str2 == &str_undef || !str2->str_cur);    if (!str2 || str2 == &str_undef)	return !str1->str_cur;    if (!str1->str_pok)	(void)str_2ptr(str1);    if (!str2->str_pok)	(void)str_2ptr(str2);    if (str1->str_cur != str2->str_cur)	return 0;    return !bcmp(str1->str_ptr, str2->str_ptr, str1->str_cur);}intstr_cmp(str1,str2)register STR *str1;register STR *str2;{    int retval;    if (!str1 || str1 == &str_undef)	return (str2 == Nullstr || str2 == &str_undef || !str2->str_cur)?0:-1;    if (!str2 || str2 == &str_undef)	return str1->str_cur != 0;    if (!str1->str_pok)	(void)str_2ptr(str1);    if (!str2->str_pok)	(void)str_2ptr(str2);    if (str1->str_cur < str2->str_cur) {	/*SUPPRESS 560*/	if (retval = memcmp(str1->str_ptr, str2->str_ptr, str1->str_cur))	    return retval < 0 ? -1 : 1;	else	    return -1;    }    /*SUPPRESS 560*/    else if (retval = memcmp(str1->str_ptr, str2->str_ptr, str2->str_cur))	return retval < 0 ? -1 : 1;    else if (str1->str_cur == str2->str_cur)	return 0;    else	return 1;}char *str_gets(str,fp,append)register STR *str;register FILE *fp;int append;{    register char *bp;		/* we're going to steal some values */    register int cnt;		/*  from the stdio struct and put EVERYTHING */    register STDCHAR *ptr;	/*   in the innermost loop into registers */    register int newline = rschar;/* (assuming >= 6 registers) */    int i;    STRLEN bpx;    int shortbuffered;    if (str == &str_undef)	return Nullch;    if (rspara) {		/* have to do this both before and after */	do {			/* to make sure file boundaries work right */	    i = getc(fp);	    if (i != '\n') {		ungetc(i,fp);		break;	    }	} while (i != EOF);    }#ifdef STDSTDIO		/* Here is some breathtakingly efficient cheating */    cnt = fp->_cnt;			/* get count into register */    str->str_nok = 0;			/* invalidate number */    str->str_pok = 1;			/* validate pointer */    if (str->str_len - append <= cnt + 1) { /* make sure we have the room */	if (cnt > 80 && str->str_len > append) {	    shortbuffered = cnt - str->str_len + append + 1;	    cnt -= shortbuffered;	}	else {	    shortbuffered = 0;	    STR_GROW(str, append+cnt+2);/* (remembering cnt can be -1) */	}    }    else	shortbuffered = 0;    bp = str->str_ptr + append;		/* move these two too to registers */    ptr = fp->_ptr;    for (;;) {      screamer:	while (--cnt >= 0) {			/* this */	/* eat */	    if ((*bp++ = *ptr++) == newline)	/* really */	/* dust */		goto thats_all_folks;		/* screams */	/* sed :-) */ 	}		if (shortbuffered) {			/* oh well, must extend */	    cnt = shortbuffered;	    shortbuffered = 0;	    bpx = bp - str->str_ptr;	/* prepare for possible relocation */	    str->str_cur = bpx;	    STR_GROW(str, str->str_len + append + cnt + 2);	    bp = str->str_ptr + bpx;	/* reconstitute our pointer */	    continue;	}	fp->_cnt = cnt;			/* deregisterize cnt and ptr */	fp->_ptr = ptr;	i = _filbuf(fp);		/* get more characters */	cnt = fp->_cnt;	ptr = fp->_ptr;			/* reregisterize cnt and ptr */	bpx = bp - str->str_ptr;	/* prepare for possible relocation */	str->str_cur = bpx;	STR_GROW(str, bpx + cnt + 2);	bp = str->str_ptr + bpx;	/* reconstitute our pointer */	if (i == newline) {		/* all done for now? */	    *bp++ = i;	    goto thats_all_folks;	}	else if (i == EOF)		/* all done for ever? */	    goto thats_really_all_folks;	*bp++ = i;			/* now go back to screaming loop */    }thats_all_folks:    if (rslen > 1 && (bp - str->str_ptr < rslen || bcmp(bp - rslen, rs, rslen)))	goto screamer;	/* go back to the fray */thats_really_all_folks:    if (shortbuffered)	cnt += shortbuffered;    fp->_cnt = cnt;			/* put these back or we're in trouble */    fp->_ptr = ptr;    *bp = '\0';    str->str_cur = bp - str->str_ptr;	/* set length */#else /* !STDSTDIO */	/* The big, slow, and stupid way */    {	static char buf[8192];	char * bpe = buf + sizeof(buf) - 3;screamer:	bp = buf;	while ((i = getc(fp)) != EOF && (*bp++ = i) != newline && bp < bpe) ;	if (append)	    str_ncat(str, buf, bp - buf);	else	    str_nset(str, buf, bp - buf);	if (i != EOF			/* joy */	    &&	    (i != newline	     ||	     (rslen > 1	      &&	      (str->str_cur < rslen	       ||	       bcmp(str->str_ptr + str->str_cur - rslen, rs, rslen)	      )	     )	    )	   )	{	    append = -1;	    goto screamer;	}    }#endif /* STDSTDIO */    if (rspara) {        while (i != EOF) {	    i = getc(fp);	    if (i != '\n') {		ungetc(i,fp);		break;	    }	}    }    return str->str_cur - append ? str->str_ptr : Nullch;}ARG *parselist(str)STR *str;{    register CMD *cmd;    register ARG *arg;    CMD *oldcurcmd = curcmd;    int oldperldb = perldb;    int retval;    perldb = 0;    str_sset(linestr,str);    in_eval++;    oldoldbufptr = oldbufptr = bufptr = str_get(linestr);    bufend = bufptr + linestr->str_cur;    if (++loop_ptr >= loop_max) {        loop_max += 128;        Renew(loop_stack, loop_max, struct loop);    }    loop_stack[loop_ptr].loop_label = "_EVAL_";    loop_stack[loop_ptr].loop_sp = 0;#ifdef DEBUGGING    if (debug & 4) {        deb("(Pushing label #%d _EVAL_)\n", loop_ptr);    }#endif    if (setjmp(loop_stack[loop_ptr].loop_env)) {	in_eval--;	loop_ptr--;	perldb = oldperldb;	fatal("%s\n",stab_val(stabent("@",TRUE))->str_ptr);    }#ifdef DEBUGGING    if (debug & 4) {	char *tmps = loop_stack[loop_ptr].loop_label;	deb("(Popping label #%d %s)\n",loop_ptr,	    tmps ? tmps : "" );    }#endif    loop_ptr--;    error_count = 0;    curcmd = &compiling;    curcmd->c_line = oldcurcmd->c_line;    retval = yyparse();    curcmd = oldcurcmd;    perldb = oldperldb;    in_eval--;    if (retval || error_count)	fatal("Invalid component in string or format");    cmd = eval_root;    arg = cmd->c_expr;    if (cmd->c_type != C_EXPR || cmd->c_next || arg->arg_type != O_LIST)	fatal("panic: error in parselist %d %x %d", cmd->c_type,	  cmd->c_next, arg ? arg->arg_type : -1);    cmd->c_expr = Nullarg;    cmd_free(cmd);    eval_root = Nullcmd;    return arg;}voidintrpcompile(src)STR *src;{    register char *s = str_get(src);    register char *send = s + src->str_cur;    register STR *str;    register char *t;    STR *toparse;    STRLEN len;    register int brackets;    register char *d;    STAB *stab;    char *checkpoint;    int sawcase = 0;    toparse = Str_new(76,0);    str = Str_new(77,0);    str_nset(str,"",0);    str_nset(toparse,"",0);    t = s;    while (s < send) {	if (*s == '\\' && s[1] && index("$@[{\\]}lLuUE",s[1])) {	    str_ncat(str, t, s - t);	    ++s;	    if (isALPHA(*s)) {		str_ncat(str, "$c", 2);		sawcase = (*s != 'E');	    }	    else {		if (*nointrp) {		/* in a regular expression */		    if (*s == '@')	/* always strip \@ */ /*SUPPRESS 530*/			;		    else		/* don't strip \\, \[, \{ etc. */			str_ncat(str,s-1,1);		}		str_ncat(str, "$b", 2);	    }	    str_ncat(str, s, 1);	    ++s;	    t = s;	}	else if (*s == '$' && s+1 < send && *nointrp && index(nointrp,s[1])) {	    str_ncat(str, t, s - t);	    str_ncat(str, "$b", 2);	    str_ncat(str, s, 2);	    s += 2;	    t = s;	}	else if ((*s == '@' || *s == '$') && s+1 < send) {	    str_ncat(str,t,s-t);	    t = s;	    if (*s == '$' && s[1] == '#' && (isALPHA(s[2]) || s[2] == '_'))		s++;	    s = scanident(s,send,tokenbuf);	    if (*t == '@' &&	      (!(stab = stabent(tokenbuf,FALSE)) || 		 (*s == '{' ? !stab_xhash(stab) : !stab_xarray(stab)) )) {		str_ncat(str,"@",1);		s = ++t;		continue;	/* grandfather @ from old scripts */	    }	    str_ncat(str,"$a",2);	    str_ncat(toparse,",",1);	    if (t[1] != '{' && (*s == '['  || *s == '{' /* }} */ ) &&	      (stab = stabent(tokenbuf,FALSE)) &&	      ((*s == '[') ? (stab_xarray(stab) != 0) : (stab_xhash(stab) != 0)) ) {		brackets = 0;		checkpoint = s;		do {		    switch (*s) {		    case '[':			brackets++;			break;		    case '{':			brackets++;			break;		    case ']':			brackets--;			break;		    case '}':			brackets--;			break;		    case '$':		    case '%':		    case '@':		    case '&':		    case '*':			s = scanident(s,send,tokenbuf);			continue;		    case '\'':		    case '"':			/*SUPPRESS 68*/			s = cpytill(tokenbuf,s+1,send,*s,&len);			if (s >= send)			    fatal("Unterminated string");			break;		    }		    s++;		} while (brackets > 0 && s < send);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -