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

📄 str.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/* $RCSfile: str.c,v $$Revision: 4.0.1.7 $$Date: 1993/02/05 19:43:47 $ * *    Copyright (c) 1991, Larry Wall * *    You may distribute under the terms of either the GNU General Public *    License or the Artistic License, as specified in the README file. * * $Log: str.c,v $ * Revision 4.0.1.7  1993/02/05  19:43:47  lwall * patch36: the non-std stdio input code wasn't null-proof * * Revision 4.0.1.6  92/06/11  21:14:21  lwall * patch34: quotes containing subscripts containing variables didn't parse right *  * Revision 4.0.1.5  92/06/08  15:40:43  lwall * patch20: removed implicit int declarations on functions * patch20: Perl now distinguishes overlapped copies from non-overlapped * patch20: paragraph mode now skips extra newlines automatically * patch20: fixed memory leak in doube-quote interpretation * patch20: made /\$$foo/ look for literal '$foo' * patch20: "$var{$foo'bar}" didn't scan subscript correctly * patch20: a splice on non-existent array elements could dump core * patch20: running taintperl explicitly now does checks even if $< == $> *  * Revision 4.0.1.4  91/11/05  18:40:51  lwall * patch11: $foo .= <BAR> could overrun malloced memory * patch11: \$ didn't always make it through double-quoter to regexp routines * patch11: prepared for ctype implementations that don't define isascii() *  * Revision 4.0.1.3  91/06/10  01:27:54  lwall * patch10: $) and $| incorrectly handled in run-time patterns *  * Revision 4.0.1.2  91/06/07  11:58:13  lwall * patch4: new copyright notice * patch4: taint check on undefined string could cause core dump *  * Revision 4.0.1.1  91/04/12  09:15:30  lwall * patch1: fixed undefined environ problem * patch1: substr($ENV{"PATH"},0,0) = "/foo:" didn't modify environment * patch1: $foo .= <BAR> could cause core dump for certain lengths of $foo *  * Revision 4.0  91/03/20  01:39:55  lwall * 4.0 baseline. *  */#include "EXTERN.h"#include "perl.h"#include "perly.h"static void ucase();static void lcase();#ifndef str_getchar *str_get(str)STR *str;{#ifdef TAINT    tainted |= str->str_tainted;#endif    return str->str_pok ? str->str_ptr : str_2ptr(str);}#endif/* dlb ... guess we have a "crippled cc". * dlb the following functions are usually macros. */#ifndef str_trueintstr_true(Str)STR *Str;{	if (Str->str_pok) {	    if (*Str->str_ptr > '0' ||	      Str->str_cur > 1 ||	      (Str->str_cur && *Str->str_ptr != '0'))		return 1;	    return 0;	}	if (Str->str_nok)		return (Str->str_u.str_nval != 0.0);	return 0;}#endif /* str_true */#ifndef str_gnumdouble str_gnum(Str)STR *Str;{#ifdef TAINT	tainted |= Str->str_tainted;#endif /* TAINT*/	if (Str->str_nok)		return Str->str_u.str_nval;	return str_2num(Str);}#endif /* str_gnum *//* dlb ... end of crutch */char *str_grow(str,newlen)register STR *str;#ifndef DOSISHregister int newlen;#elseunsigned long newlen;#endif{    register char *s = str->str_ptr;#ifdef MSDOS    if (newlen >= 0x10000) {	fprintf(stderr, "Allocation too large: %lx\n", newlen);	exit(1);    }#endif /* MSDOS */    if (str->str_state == SS_INCR) {		/* data before str_ptr? */	str->str_len += str->str_u.str_useful;	str->str_ptr -= str->str_u.str_useful;	str->str_u.str_useful = 0L;	Move(s, str->str_ptr, str->str_cur+1, char);	s = str->str_ptr;	str->str_state = SS_NORM;			/* normal again */	if (newlen > str->str_len)	    newlen += 10 * (newlen - str->str_cur); /* avoid copy each time */    }    if (newlen > str->str_len) {		/* need more room? */        if (str->str_len)	    Renew(s,newlen,char);        else	    New(703,s,newlen,char);	str->str_ptr = s;        str->str_len = newlen;    }    return s;}voidstr_numset(str,num)register STR *str;double num;{    if (str->str_pok) {	str->str_pok = 0;	/* invalidate pointer */	if (str->str_state == SS_INCR)	    Str_Grow(str,0);    }    str->str_u.str_nval = num;    str->str_state = SS_NORM;    str->str_nok = 1;			/* validate number */#ifdef TAINT    str->str_tainted = tainted;#endif}char *str_2ptr(str)register STR *str;{    register char *s;    int olderrno;    if (!str)	return "";    if (str->str_nok) {	STR_GROW(str, 30);	s = str->str_ptr;	olderrno = errno;	/* some Xenix systems wipe out errno here */#if defined(scs) && defined(ns32000)	gcvt(str->str_u.str_nval,20,s);#else#ifdef apollo	if (str->str_u.str_nval == 0.0)	    (void)strcpy(s,"0");	else#endif /*apollo*/	(void)sprintf(s,"%.20g",str->str_u.str_nval);#endif /*scs*/	errno = olderrno;	while (*s) s++;#ifdef hcx	if (s[-1] == '.')	    s--;#endif    }    else {	if (str == &str_undef)	    return No;	if (dowarn)	    warn("Use of uninitialized variable");	STR_GROW(str, 30);	s = str->str_ptr;    }    *s = '\0';    str->str_cur = s - str->str_ptr;    str->str_pok = 1;#ifdef DEBUGGING    if (debug & 32)	fprintf(stderr,"0x%lx ptr(%s)\n",str,str->str_ptr);#endif    return str->str_ptr;}doublestr_2num(str)register STR *str;{    if (!str)	return 0.0;    if (str->str_state == SS_INCR)	Str_Grow(str,0);       /* just force copy down */    str->str_state = SS_NORM;    if (str->str_len && str->str_pok)	str->str_u.str_nval = atof(str->str_ptr);    else  {	if (str == &str_undef)	    return 0.0;	if (dowarn)	    warn("Use of uninitialized variable");	str->str_u.str_nval = 0.0;    }    str->str_nok = 1;#ifdef DEBUGGING    if (debug & 32)	fprintf(stderr,"0x%lx num(%g)\n",str,str->str_u.str_nval);#endif    return str->str_u.str_nval;}/* Note: str_sset() should not be called with a source string that needs * be reused, since it may destroy the source string if it is marked * as temporary. */voidstr_sset(dstr,sstr)STR *dstr;register STR *sstr;{#ifdef TAINT    if (sstr)	tainted |= sstr->str_tainted;#endif    if (sstr == dstr || dstr == &str_undef)	return;    if (!sstr)	dstr->str_pok = dstr->str_nok = 0;    else if (sstr->str_pok) {	/*	 * Check to see if we can just swipe the string.  If so, it's a	 * possible small lose on short strings, but a big win on long ones.	 * It might even be a win on short strings if dstr->str_ptr	 * has to be allocated and sstr->str_ptr has to be freed.	 */	if (sstr->str_pok & SP_TEMP) {		/* slated for free anyway? */	    if (dstr->str_ptr) {		if (dstr->str_state == SS_INCR)		    dstr->str_ptr -= dstr->str_u.str_useful;		Safefree(dstr->str_ptr);	    }	    dstr->str_ptr = sstr->str_ptr;	    dstr->str_len = sstr->str_len;	    dstr->str_cur = sstr->str_cur;	    dstr->str_state = sstr->str_state;	    dstr->str_pok = sstr->str_pok & ~SP_TEMP;#ifdef TAINT	    dstr->str_tainted = sstr->str_tainted;#endif	    sstr->str_ptr = Nullch;	    sstr->str_len = 0;	    sstr->str_pok = 0;			/* wipe out any weird flags */	    sstr->str_state = 0;		/* so sstr frees uneventfully */	}	else {					/* have to copy actual string */	    if (dstr->str_ptr) {		if (dstr->str_state == SS_INCR) {			Str_Grow(dstr,0);		}	    }	    str_nset(dstr,sstr->str_ptr,sstr->str_cur);	}	/*SUPPRESS 560*/	if (dstr->str_nok = sstr->str_nok)	    dstr->str_u.str_nval = sstr->str_u.str_nval;	else {#ifdef STRUCTCOPY	    dstr->str_u = sstr->str_u;#else	    dstr->str_u.str_nval = sstr->str_u.str_nval;#endif	    if (dstr->str_cur == sizeof(STBP)) {		char *tmps = dstr->str_ptr;		if (*tmps == 'S' && bcmp(tmps,"StB",4) == 0) {		    if (dstr->str_magic && dstr->str_magic->str_rare == 'X') {			str_free(dstr->str_magic);			dstr->str_magic = Nullstr;		    }		    if (!dstr->str_magic) {			dstr->str_magic = str_smake(sstr->str_magic);			dstr->str_magic->str_rare = 'X';		    }		}	    }	}    }    else if (sstr->str_nok)	str_numset(dstr,sstr->str_u.str_nval);    else {	if (dstr->str_state == SS_INCR)	    Str_Grow(dstr,0);       /* just force copy down */#ifdef STRUCTCOPY	dstr->str_u = sstr->str_u;#else	dstr->str_u.str_nval = sstr->str_u.str_nval;#endif	dstr->str_pok = dstr->str_nok = 0;    }}voidstr_nset(str,ptr,len)register STR *str;register char *ptr;register STRLEN len;{    if (str == &str_undef)	return;    STR_GROW(str, len + 1);    if (ptr)	Move(ptr,str->str_ptr,len,char);    str->str_cur = len;    *(str->str_ptr+str->str_cur) = '\0';    str->str_nok = 0;		/* invalidate number */    str->str_pok = 1;		/* validate pointer */#ifdef TAINT    str->str_tainted = tainted;#endif}voidstr_set(str,ptr)register STR *str;register char *ptr;{    register STRLEN len;    if (str == &str_undef)	return;    if (!ptr)	ptr = "";    len = strlen(ptr);    STR_GROW(str, len + 1);    Move(ptr,str->str_ptr,len+1,char);    str->str_cur = len;    str->str_nok = 0;		/* invalidate number */    str->str_pok = 1;		/* validate pointer */#ifdef TAINT    str->str_tainted = tainted;#endif}voidstr_chop(str,ptr)	/* like set but assuming ptr is in str */register STR *str;register char *ptr;{    register STRLEN delta;    if (!ptr || !(str->str_pok))	return;    delta = ptr - str->str_ptr;    str->str_len -= delta;    str->str_cur -= delta;    str->str_ptr += delta;    if (str->str_state == SS_INCR)	str->str_u.str_useful += delta;    else {	str->str_u.str_useful = delta;	str->str_state = SS_INCR;    }    str->str_nok = 0;		/* invalidate number */    str->str_pok = 1;		/* validate pointer (and unstudy str) */}voidstr_ncat(str,ptr,len)register STR *str;register char *ptr;register STRLEN len;{    if (str == &str_undef)	return;    if (!(str->str_pok))	(void)str_2ptr(str);    STR_GROW(str, str->str_cur + len + 1);    Move(ptr,str->str_ptr+str->str_cur,len,char);    str->str_cur += len;    *(str->str_ptr+str->str_cur) = '\0';    str->str_nok = 0;		/* invalidate number */    str->str_pok = 1;		/* validate pointer */#ifdef TAINT    str->str_tainted |= tainted;#endif}voidstr_scat(dstr,sstr)STR *dstr;register STR *sstr;{    if (!sstr)	return;#ifdef TAINT    tainted |= sstr->str_tainted;#endif    if (!(sstr->str_pok))	(void)str_2ptr(sstr);    if (sstr)	str_ncat(dstr,sstr->str_ptr,sstr->str_cur);}voidstr_cat(str,ptr)register STR *str;register char *ptr;{    register STRLEN len;    if (str == &str_undef)	return;    if (!ptr)	return;    if (!(str->str_pok))	(void)str_2ptr(str);    len = strlen(ptr);    STR_GROW(str, str->str_cur + len + 1);    Move(ptr,str->str_ptr+str->str_cur,len+1,char);    str->str_cur += len;    str->str_nok = 0;		/* invalidate number */    str->str_pok = 1;		/* validate pointer */#ifdef TAINT    str->str_tainted |= tainted;#endif}char *str_append_till(str,from,fromend,delim,keeplist)register STR *str;register char *from;register char *fromend;register int delim;char *keeplist;{    register char *to;    register STRLEN len;    if (str == &str_undef)	return Nullch;    if (!from)	return Nullch;    len = fromend - from;    STR_GROW(str, str->str_cur + len + 1);    str->str_nok = 0;		/* invalidate number */    str->str_pok = 1;		/* validate pointer */    to = str->str_ptr+str->str_cur;    for (; from < fromend; from++,to++) {	if (*from == '\\' && from+1 < fromend && delim != '\\') {	    if (!keeplist) {		if (from[1] == delim || from[1] == '\\')		    from++;		else		    *to++ = *from++;	    }	    else if (from[1] && index(keeplist,from[1]))		*to++ = *from++;	    else		from++;	}	else if (*from == delim)	    break;	*to = *from;    }    *to = '\0';    str->str_cur = to - str->str_ptr;    return from;}STR *#ifdef LEAKTESTstr_new(x,len)int x;#elsestr_new(len)#endifSTRLEN len;{    register STR *str;        if (freestrroot) {	str = freestrroot;	freestrroot = str->str_magic;	str->str_magic = Nullstr;	str->str_state = SS_NORM;    }    else {	Newz(700+x,str,1,STR);    }    if (len)	STR_GROW(str, len + 1);    return str;}voidstr_magic(str, stab, how, name, namlen)register STR *str;STAB *stab;int how;char *name;STRLEN namlen;{    if (str == &str_undef || str->str_magic)	return;    str->str_magic = Str_new(75,namlen);    str = str->str_magic;    str->str_u.str_stab = stab;    str->str_rare = how;    if (name)	str_nset(str,name,namlen);

⌨️ 快捷键说明

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