xref: /plan9/sys/src/cmd/sam/string.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
13e12c5d1SDavid du Colombier #include "sam.h"
23e12c5d1SDavid du Colombier 
33e12c5d1SDavid du Colombier #define	MINSIZE	16		/* minimum number of chars allocated */
43e12c5d1SDavid du Colombier #define	MAXSIZE	256		/* maximum number of chars for an empty string */
53e12c5d1SDavid du Colombier 
63e12c5d1SDavid du Colombier 
73e12c5d1SDavid du Colombier void
Strinit(String * p)83e12c5d1SDavid du Colombier Strinit(String *p)
93e12c5d1SDavid du Colombier {
103e12c5d1SDavid du Colombier 	p->s = emalloc(MINSIZE*RUNESIZE);
113e12c5d1SDavid du Colombier 	p->n = 0;
123e12c5d1SDavid du Colombier 	p->size = MINSIZE;
133e12c5d1SDavid du Colombier }
143e12c5d1SDavid du Colombier 
153e12c5d1SDavid du Colombier void
Strinit0(String * p)163e12c5d1SDavid du Colombier Strinit0(String *p)
173e12c5d1SDavid du Colombier {
183e12c5d1SDavid du Colombier 	p->s = emalloc(MINSIZE*RUNESIZE);
193e12c5d1SDavid du Colombier 	p->s[0] = 0;
203e12c5d1SDavid du Colombier 	p->n = 1;
213e12c5d1SDavid du Colombier 	p->size = MINSIZE;
223e12c5d1SDavid du Colombier }
233e12c5d1SDavid du Colombier 
243e12c5d1SDavid du Colombier void
Strclose(String * p)253e12c5d1SDavid du Colombier Strclose(String *p)
263e12c5d1SDavid du Colombier {
273e12c5d1SDavid du Colombier 	free(p->s);
283e12c5d1SDavid du Colombier }
293e12c5d1SDavid du Colombier 
303e12c5d1SDavid du Colombier void
Strzero(String * p)313e12c5d1SDavid du Colombier Strzero(String *p)
323e12c5d1SDavid du Colombier {
333e12c5d1SDavid du Colombier 	if(p->size > MAXSIZE){
343e12c5d1SDavid du Colombier 		p->s = erealloc(p->s, RUNESIZE*MAXSIZE); /* throw away the garbage */
353e12c5d1SDavid du Colombier 		p->size = MAXSIZE;
363e12c5d1SDavid du Colombier 	}
373e12c5d1SDavid du Colombier 	p->n = 0;
383e12c5d1SDavid du Colombier }
393e12c5d1SDavid du Colombier 
403e12c5d1SDavid du Colombier int
Strlen(Rune * r)413e12c5d1SDavid du Colombier Strlen(Rune *r)
423e12c5d1SDavid du Colombier {
433e12c5d1SDavid du Colombier 	Rune *s;
443e12c5d1SDavid du Colombier 
453e12c5d1SDavid du Colombier 	for(s=r; *s; s++)
463e12c5d1SDavid du Colombier 		;
473e12c5d1SDavid du Colombier 	return s-r;
483e12c5d1SDavid du Colombier }
493e12c5d1SDavid du Colombier 
503e12c5d1SDavid du Colombier void
Strdupl(String * p,Rune * s)513e12c5d1SDavid du Colombier Strdupl(String *p, Rune *s)	/* copies the null */
523e12c5d1SDavid du Colombier {
533e12c5d1SDavid du Colombier 	p->n = Strlen(s)+1;
543e12c5d1SDavid du Colombier 	Strinsure(p, p->n);
553e12c5d1SDavid du Colombier 	memmove(p->s, s, p->n*RUNESIZE);
563e12c5d1SDavid du Colombier }
573e12c5d1SDavid du Colombier 
583e12c5d1SDavid du Colombier void
Strduplstr(String * p,String * q)593e12c5d1SDavid du Colombier Strduplstr(String *p, String *q)	/* will copy the null if there's one there */
603e12c5d1SDavid du Colombier {
613e12c5d1SDavid du Colombier 	Strinsure(p, q->n);
623e12c5d1SDavid du Colombier 	p->n = q->n;
633e12c5d1SDavid du Colombier 	memmove(p->s, q->s, q->n*RUNESIZE);
643e12c5d1SDavid du Colombier }
653e12c5d1SDavid du Colombier 
663e12c5d1SDavid du Colombier void
Straddc(String * p,int c)673e12c5d1SDavid du Colombier Straddc(String *p, int c)
683e12c5d1SDavid du Colombier {
693e12c5d1SDavid du Colombier 	Strinsure(p, p->n+1);
703e12c5d1SDavid du Colombier 	p->s[p->n++] = c;
713e12c5d1SDavid du Colombier }
723e12c5d1SDavid du Colombier 
733e12c5d1SDavid du Colombier void
Strinsure(String * p,ulong n)743e12c5d1SDavid du Colombier Strinsure(String *p, ulong n)
753e12c5d1SDavid du Colombier {
763e12c5d1SDavid du Colombier 	if(n > STRSIZE)
773e12c5d1SDavid du Colombier 		error(Etoolong);
783e12c5d1SDavid du Colombier 	if(p->size < n){	/* p needs to grow */
793e12c5d1SDavid du Colombier 		n += 100;
803e12c5d1SDavid du Colombier 		p->s = erealloc(p->s, n*RUNESIZE);
813e12c5d1SDavid du Colombier 		p->size = n;
823e12c5d1SDavid du Colombier 	}
833e12c5d1SDavid du Colombier }
843e12c5d1SDavid du Colombier 
853e12c5d1SDavid du Colombier void
Strinsert(String * p,String * q,Posn p0)863e12c5d1SDavid du Colombier Strinsert(String *p, String *q, Posn p0)
873e12c5d1SDavid du Colombier {
883e12c5d1SDavid du Colombier 	Strinsure(p, p->n+q->n);
893e12c5d1SDavid du Colombier 	memmove(p->s+p0+q->n, p->s+p0, (p->n-p0)*RUNESIZE);
903e12c5d1SDavid du Colombier 	memmove(p->s+p0, q->s, q->n*RUNESIZE);
913e12c5d1SDavid du Colombier 	p->n += q->n;
923e12c5d1SDavid du Colombier }
933e12c5d1SDavid du Colombier 
943e12c5d1SDavid du Colombier void
Strdelete(String * p,Posn p1,Posn p2)953e12c5d1SDavid du Colombier Strdelete(String *p, Posn p1, Posn p2)
963e12c5d1SDavid du Colombier {
973e12c5d1SDavid du Colombier 	memmove(p->s+p1, p->s+p2, (p->n-p2)*RUNESIZE);
983e12c5d1SDavid du Colombier 	p->n -= p2-p1;
993e12c5d1SDavid du Colombier }
1003e12c5d1SDavid du Colombier 
1013e12c5d1SDavid du Colombier int
Strcmp(String * a,String * b)1023e12c5d1SDavid du Colombier Strcmp(String *a, String *b)
1033e12c5d1SDavid du Colombier {
1043e12c5d1SDavid du Colombier 	int i, c;
1053e12c5d1SDavid du Colombier 
1063e12c5d1SDavid du Colombier 	for(i=0; i<a->n && i<b->n; i++)
1073e12c5d1SDavid du Colombier 		if(c = (a->s[i] - b->s[i]))	/* assign = */
1083e12c5d1SDavid du Colombier 			return c;
1093e12c5d1SDavid du Colombier 	/* damn NULs confuse everything */
1103e12c5d1SDavid du Colombier 	i = a->n - b->n;
1113e12c5d1SDavid du Colombier 	if(i == 1){
1123e12c5d1SDavid du Colombier 		if(a->s[a->n-1] == 0)
1133e12c5d1SDavid du Colombier 			return 0;
1143e12c5d1SDavid du Colombier 	}else if(i == -1){
1153e12c5d1SDavid du Colombier 		if(b->s[b->n-1] == 0)
1163e12c5d1SDavid du Colombier 			return 0;
1173e12c5d1SDavid du Colombier 	}
1183e12c5d1SDavid du Colombier 	return i;
1193e12c5d1SDavid du Colombier }
1203e12c5d1SDavid du Colombier 
121*7dd7cddfSDavid du Colombier int
Strispre(String * a,String * b)122*7dd7cddfSDavid du Colombier Strispre(String *a, String *b)
123*7dd7cddfSDavid du Colombier {
124*7dd7cddfSDavid du Colombier 	int i;
125*7dd7cddfSDavid du Colombier 
126*7dd7cddfSDavid du Colombier 	for(i=0; i<a->n && i<b->n; i++){
127*7dd7cddfSDavid du Colombier 		if(a->s[i] - b->s[i]){	/* assign = */
128*7dd7cddfSDavid du Colombier 			if(a->s[i] == 0)
129*7dd7cddfSDavid du Colombier 				return 1;
130*7dd7cddfSDavid du Colombier 			return 0;
131*7dd7cddfSDavid du Colombier 		}
132*7dd7cddfSDavid du Colombier 	}
133*7dd7cddfSDavid du Colombier 	return i == a->n;
134*7dd7cddfSDavid du Colombier }
135*7dd7cddfSDavid du Colombier 
1363e12c5d1SDavid du Colombier char*
Strtoc(String * s)1373e12c5d1SDavid du Colombier Strtoc(String *s)
1383e12c5d1SDavid du Colombier {
1393e12c5d1SDavid du Colombier 	int i;
1403e12c5d1SDavid du Colombier 	char *c, *d;
1413e12c5d1SDavid du Colombier 	Rune *r;
1423e12c5d1SDavid du Colombier 	c = emalloc(s->n*UTFmax + 1);  /* worst case UTFmax bytes per rune, plus NUL */
1433e12c5d1SDavid du Colombier 	d = c;
1443e12c5d1SDavid du Colombier 	r = s->s;
1453e12c5d1SDavid du Colombier 	for(i=0; i<s->n; i++)
1463e12c5d1SDavid du Colombier 		d += runetochar(d, r++);
1473e12c5d1SDavid du Colombier 	if(d==c || d[-1]!=0)
1483e12c5d1SDavid du Colombier 		*d = 0;
1493e12c5d1SDavid du Colombier 	return c;
1503e12c5d1SDavid du Colombier 
1513e12c5d1SDavid du Colombier }
1523e12c5d1SDavid du Colombier 
1533e12c5d1SDavid du Colombier /*
1543e12c5d1SDavid du Colombier  * Build very temporary String from Rune*
1553e12c5d1SDavid du Colombier  */
1563e12c5d1SDavid du Colombier String*
tmprstr(Rune * r,int n)1573e12c5d1SDavid du Colombier tmprstr(Rune *r, int n)
1583e12c5d1SDavid du Colombier {
1593e12c5d1SDavid du Colombier 	static String p;
1603e12c5d1SDavid du Colombier 
1613e12c5d1SDavid du Colombier 	p.s = r;
1623e12c5d1SDavid du Colombier 	p.n = n;
1633e12c5d1SDavid du Colombier 	p.size = n;
1643e12c5d1SDavid du Colombier 	return &p;
1653e12c5d1SDavid du Colombier }
1663e12c5d1SDavid du Colombier 
1673e12c5d1SDavid du Colombier /*
1683e12c5d1SDavid du Colombier  * Convert null-terminated char* into String
1693e12c5d1SDavid du Colombier  */
1703e12c5d1SDavid du Colombier String*
tmpcstr(char * s)1713e12c5d1SDavid du Colombier tmpcstr(char *s)
1723e12c5d1SDavid du Colombier {
1733e12c5d1SDavid du Colombier 	String *p;
1743e12c5d1SDavid du Colombier 	Rune *r;
1753e12c5d1SDavid du Colombier 	int i, n;
1763e12c5d1SDavid du Colombier 
1773e12c5d1SDavid du Colombier 	n = utflen(s);	/* don't include NUL */
1783e12c5d1SDavid du Colombier 	p = emalloc(sizeof(String));
1793e12c5d1SDavid du Colombier 	r = emalloc(n*RUNESIZE);
1803e12c5d1SDavid du Colombier 	p->s = r;
1813e12c5d1SDavid du Colombier 	for(i=0; i<n; i++,r++)
1823e12c5d1SDavid du Colombier 		s += chartorune(r, s);
1833e12c5d1SDavid du Colombier 	p->n = n;
1843e12c5d1SDavid du Colombier 	p->size = n;
1853e12c5d1SDavid du Colombier 	return p;
1863e12c5d1SDavid du Colombier }
1873e12c5d1SDavid du Colombier 
1883e12c5d1SDavid du Colombier void
freetmpstr(String * s)1893e12c5d1SDavid du Colombier freetmpstr(String *s)
1903e12c5d1SDavid du Colombier {
1913e12c5d1SDavid du Colombier 	free(s->s);
1923e12c5d1SDavid du Colombier 	free(s);
1933e12c5d1SDavid du Colombier }
194