ref: bf645afaac246967b9590ae7463f243c11d97480
dir: /sys/src/cmd/sam/string.c/
#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); }