diff options
| author | Peter Mikkelsen <petermikkelsen10@gmail.com> | 2025-10-15 19:46:13 +0200 |
|---|---|---|
| committer | Peter Mikkelsen <petermikkelsen10@gmail.com> | 2025-10-15 19:46:13 +0200 |
| commit | 184526f3bf90e2948b1d09b9da58d66814181f4d (patch) | |
| tree | d39614e3e29fb89594d1dc52ef07805bc754c4c7 /sam/string.c | |
| parent | fd41e6cc88f98121db5c64a0693e4169962f6c2c (diff) | |
Import sam and samterm sources
Diffstat (limited to 'sam/string.c')
| -rw-r--r-- | sam/string.c | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/sam/string.c b/sam/string.c new file mode 100644 index 0000000..9a4b9a7 --- /dev/null +++ b/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); +} |