📄 string.c
字号:
head 2.1;access;symbols;locks; strict;comment @ * @;2.1date 95.10.24.15.46.14; author tsurace; state Release;branches;next 1.1;1.1date 95.10.12.20.55.09; author tsurace; state Beta;branches;next ;desc@String management functions.@2.1log@Roll.@text@/* string.c: string manipulation routines */
/* $Id: string.c 1.1 1995/10/12 20:55:09 tsurace Beta tsurace $ */
#include "vt.h"
String wbufs[NUM_WBUFS];
Cstr empty_cstr = { "", 0 };
String empty_string = { { "", 0 }, 0 };
#ifndef ANSI_CTYPES
char 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 strcspn
int vtstrcspn(s1, s2)
char *s1, *s2;
{
char *p;
for (p = s1; *p && !strchr(s2, *p); p++);
return p - s1;
}
#endif
#ifdef strcasecmp
int vtstricmp(s, t)
char *s, *t;
{
for (; *s && *t && lcase(*s) == lcase(*t); s++, t++);
return lcase(*s) - lcase(*t);
}
#endif
#ifdef strncasecmp
int 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 strstr
char *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;
}
#endif
char *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;
g = hashval & 0xf0000000;
if (g) {
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_fwd
void bcopy_fwd(src, dest, l)
char *src, *dest;
int l;
{
char *send = src + l, *dend = dest + l;
while (l--)
*--dend = *--send;
}
#endif
void 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);
}
}
@1.1log@Initial revision@text@d2 1a2 1/* $Id$ */@
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -