diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/sam/string.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/sam/string.c')
-rwxr-xr-x | sys/src/cmd/sam/string.c | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/sys/src/cmd/sam/string.c b/sys/src/cmd/sam/string.c new file mode 100755 index 000000000..9a4b9a71b --- /dev/null +++ b/sys/src/cmd/sam/string.c @@ -0,0 +1,193 @@ +#include "sam.h" + +#define MINSIZE 16 /* minimum number of chars allocated */ +#define MAXSIZE 256 /* maximum number of chars for an empty string */ + + +void +Strinit(String *p) +{ + p->s = emalloc(MINSIZE*RUNESIZE); + p->n = 0; + p->size = MINSIZE; +} + +void +Strinit0(String *p) +{ + p->s = emalloc(MINSIZE*RUNESIZE); + p->s[0] = 0; + p->n = 1; + p->size = MINSIZE; +} + +void +Strclose(String *p) +{ + free(p->s); +} + +void +Strzero(String *p) +{ + if(p->size > MAXSIZE){ + p->s = erealloc(p->s, RUNESIZE*MAXSIZE); /* throw away the garbage */ + p->size = MAXSIZE; + } + p->n = 0; +} + +int +Strlen(Rune *r) +{ + Rune *s; + + for(s=r; *s; s++) + ; + return s-r; +} + +void +Strdupl(String *p, Rune *s) /* copies the null */ +{ + p->n = Strlen(s)+1; + Strinsure(p, p->n); + memmove(p->s, s, p->n*RUNESIZE); +} + +void +Strduplstr(String *p, String *q) /* will copy the null if there's one there */ +{ + Strinsure(p, q->n); + p->n = q->n; + memmove(p->s, q->s, q->n*RUNESIZE); +} + +void +Straddc(String *p, int c) +{ + Strinsure(p, p->n+1); + p->s[p->n++] = c; +} + +void +Strinsure(String *p, ulong n) +{ + if(n > STRSIZE) + error(Etoolong); + if(p->size < n){ /* p needs to grow */ + n += 100; + p->s = erealloc(p->s, n*RUNESIZE); + p->size = n; + } +} + +void +Strinsert(String *p, String *q, Posn p0) +{ + Strinsure(p, p->n+q->n); + memmove(p->s+p0+q->n, p->s+p0, (p->n-p0)*RUNESIZE); + memmove(p->s+p0, q->s, q->n*RUNESIZE); + p->n += q->n; +} + +void +Strdelete(String *p, Posn p1, Posn p2) +{ + memmove(p->s+p1, p->s+p2, (p->n-p2)*RUNESIZE); + p->n -= p2-p1; +} + +int +Strcmp(String *a, String *b) +{ + int i, c; + + for(i=0; i<a->n && i<b->n; i++) + if(c = (a->s[i] - b->s[i])) /* assign = */ + return c; + /* damn NULs confuse everything */ + i = a->n - b->n; + if(i == 1){ + if(a->s[a->n-1] == 0) + return 0; + }else if(i == -1){ + if(b->s[b->n-1] == 0) + return 0; + } + return i; +} + +int +Strispre(String *a, String *b) +{ + int i; + + for(i=0; i<a->n && i<b->n; i++){ + if(a->s[i] - b->s[i]){ /* assign = */ + if(a->s[i] == 0) + return 1; + return 0; + } + } + return i == a->n; +} + +char* +Strtoc(String *s) +{ + int i; + char *c, *d; + Rune *r; + c = emalloc(s->n*UTFmax + 1); /* worst case UTFmax bytes per rune, plus NUL */ + d = c; + r = s->s; + for(i=0; i<s->n; i++) + d += runetochar(d, r++); + if(d==c || d[-1]!=0) + *d = 0; + return c; + +} + +/* + * Build very temporary String from Rune* + */ +String* +tmprstr(Rune *r, int n) +{ + static String p; + + p.s = r; + p.n = n; + p.size = n; + return &p; +} + +/* + * Convert null-terminated char* into String + */ +String* +tmpcstr(char *s) +{ + String *p; + Rune *r; + int i, n; + + n = utflen(s); /* don't include NUL */ + p = emalloc(sizeof(String)); + r = emalloc(n*RUNESIZE); + p->s = r; + for(i=0; i<n; i++,r++) + s += chartorune(r, s); + p->n = n; + p->size = n; + return p; +} + +void +freetmpstr(String *s) +{ + free(s->s); + free(s); +} |