📄 string.c
字号:
/* string.c: string manipulation routines */#include "vt.h"String wbufs[NUM_WBUFS];Cstr empty_cstr = { "", 0 };String empty_string = { { "", 0 }, 0 };#ifndef ANSI_CTYPESchar lowercase_values[128];char uppercase_values[128];#endif#define INIT_SIZE 32#define BLOCKSIZE (4 * INIT_SIZE)/* Operations on character strings, some of which may be redefined */char *vtstrnchr(s, c, n) char *s; int c, n;{ while (n-- && *s != c) s++; return n >= 0 ? s : NULL;}char *vtstrnrchr(s, c, n) char *s; int c, n;{ for (s += n; n-- && *--s != c;); return n >= 0 ? s : NULL;}#ifdef strcspnint vtstrcspn(s1, s2) char *s1, *s2;{ char *p; for (p = s1; *p && !strchr(s2, *p); p++); return p - s1;}#endif#ifdef strcasecmpint vtstricmp(s, t) char *s, *t;{ for (; *s && *t && lcase(*s) == lcase(*t); s++, t++); return lcase(*s) - lcase(*t);}#endif#ifdef strncasecmpint vtstrnicmp(s, t, n) char *s, *t; int n;{ for (; n-- && *s && *t && lcase(*s) == lcase(*t); s++, t++); return (n < 0) ? 0 : lcase(*s) - lcase(*t);}#endif#ifdef strstrchar *vtstrstr(str, find) char *str, *find;{ int l; l = strlen(find); while (str = strchr(str, *find)) { if (!strncmp(str, find, l)) return str; str++; } return NULL;}#endifchar *vtstristr(s, f) char *s; Cstr f;{ for (; *s; s++) { if (lcase(*s) == lcase(*f.s) && !strncasecmp(s, f.s, f.l)) return s; } return NULL;}char *vtstrdup(s) char *s;{ char *new; int len; len = strlen(s); new = Newarray(char, len + 1); bcopy(s, new, len + 1); return new;}/* Since a few non-ANSI compilers kludge and define tolower(c) and** toupper(c) in such a way that they're invalid if c is not uppercase** or lowercase, respectively, to begin with (e.g. #define tolower(c)** (c - 'A' + 'a')), we recreate the tables and use those. */void init_tables(){#ifndef ANSI_CTYPES int c; for (c = 0; c < 128; c++) { lowercase_values[c] = isupper(c) ? tolower(c) : c; uppercase_values[c] = islower(c) ? toupper(c) : c; }#endif}/* Algorithm by Peter J. Weinberger */int hash(s, size) char *s; int size;{ unsigned hashval, g; for (hashval = 0; *s; s++) { hashval = (hashval << 4) + *s; if (g = hashval & 0xf0000000) { hashval ^= g >> 24; hashval ^= g; } } return (int)(hashval % size);}/* Counted string constructors */Cstr cstr_sl(s, l) char *s; int l;{ Cstr cstr; cstr.s = s; cstr.l = l; return cstr;}Cstr cstr_s(s) char *s;{ Cstr cstr; cstr.s = s; cstr.l = strlen(s); return cstr;}Cstr cstr_c(cstr) Cstr cstr;{ Cstr new; new.s = Newarray(char, cstr.l + 1); bcopy(cstr.s, new.s, cstr.l); new.s[new.l = cstr.l] = '\0'; return new;}/* Stretchybuffer operations */void init_wbufs(){ int i; for (i = 0; i < NUM_WBUFS; i++) { wbufs[i].c = empty_cstr; wbufs[i].sz = 0; }}void s_free(str) String *str;{ if (str->sz) Discardarray(str->c.s, char, str->sz);}void lcheck(str, len) String *str; int len;{ int sz; if (len >= str->sz) { for (sz = INIT_SIZE; sz <= len; sz <<= 1); if (str->sz) { str->c.s = Rearray(str->c.s, char, str->sz, sz); } else { str->c.s = Newarray(char, sz); *str->c.s = '\0'; } str->sz = sz; }}void s_add(str, c) String *str; int c;{ lcheck(str, str->c.l + 1); str->c.s[str->c.l++] = c; str->c.s[str->c.l] = '\0';}void s_fadd(str, c) String *str; int c;{ lcheck(str, str->c.l + 1); str->c.s[str->c.l++] = c;}void s_nt(str) String *str;{ if (str->sz) str->c.s[str->c.l] = '\0';}void s_term(str, l) String *str; int l;{ if (str->c.l > l) str->c.s[str->c.l = l] = '\0';}void s_cpy(dest, cstr) String *dest; Cstr cstr;{ lcheck(dest, dest->c.l = cstr.l); bcopy(cstr.s, dest->c.s, cstr.l); dest->c.s[cstr.l] = '\0';}void s_cat(dest, cstr) String *dest; Cstr cstr;{ lcheck(dest, dest->c.l + cstr.l); bcopy(cstr.s, dest->c.s + dest->c.l, cstr.l); dest->c.l += cstr.l; dest->c.s[dest->c.l] = '\0';}#ifndef bcopy_fwdvoid bcopy_fwd(src, dest, l) char *src, *dest; int l;{ char *send = src + l, *dend = dest + l; while (l--) *--dend = *--send;}#endifvoid s_insert(dest, cstr, loc) String *dest; Cstr cstr; int loc;{ if (!cstr.l) return; lcheck(dest, dest->c.l + cstr.l); bcopy_fwd(dest->c.s + loc, dest->c.s + loc + cstr.l, dest->c.l - loc + 1); bcopy(cstr.s, dest->c.s + loc, cstr.l); dest->c.l += cstr.l;}void s_delete(str, loc, l) String *str; int loc, l;{ str->c.l -= l; bcopy(str->c.s + loc + l, str->c.s + loc, str->c.l - loc + 1);}char *s_fget(str, stream) String *str; FILE *stream;{ static char buf[BLOCKSIZE + 1]; int len; if (!fgets(buf, BLOCKSIZE, stream)) return NULL; s_cpy(str, cstr_s(buf)); len = strlen(buf); while (buf[len - 1] != '\n') { if (!fgets(buf, BLOCKSIZE + 1, stream)) break; len = strlen(buf); s_cat(str, cstr_sl(buf, len)); } return str->c.s;}/* Referenced string constructors */Rstr *rstr_c(c) Cstr c;{ Rstr *new; new = New(Rstr); new->str.c = cstr_c(c); new->str.sz = c.l + 1; new->refs = 0; return new;}Rstr *rstr_rs(rs) Rstr *rs;{ Rstr *new; new = New(Rstr); if (rs->str.sz) { new->str.c.s = Newarray(char, rs->str.sz); bcopy(rs->str.c.s, new->str.c.s, rs->str.c.l + 1); new->str.c.l = rs->str.c.l; } else new->str = empty_string; new->str.sz = rs->str.sz; new->refs = 1; return new;}void dec_ref_rstr(rs) Rstr *rs;{ if (!--rs->refs) { s_free(&rs->str); Discard(rs, Rstr); }}/* Interpreter string operations */Istr *istr_rs(rs) Rstr *rs;{ Istr *new; new = New(Istr); new->rs = rs; new->rs->refs++; new->refs = 0; return new;}/* Copy rstr contents of istr in preparation for modification */void isolate(is) Istr *is;{ if (is->rs->refs > 1) { is->rs->refs--; is->rs = rstr_rs(is->rs); }}void dec_ref_istr(is) Istr *is;{ if (!--is->refs) { dec_ref_rstr(is->rs); Discard(is, Istr); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -