123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- /*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
- #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])) != 0)
- 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]){
- 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);
- }
|