📄 str.c
字号:
}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 + -