9base

revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log | Files | Refs | README | LICENSE

string.c (2766B)


      1 #include "sam.h"
      2 
      3 #define	MINSIZE	16		/* minimum number of chars allocated */
      4 #define	MAXSIZE	256		/* maximum number of chars for an empty string */
      5 
      6 
      7 void
      8 Strinit(String *p)
      9 {
     10 	p->s = emalloc(MINSIZE*RUNESIZE);
     11 	p->n = 0;
     12 	p->size = MINSIZE;
     13 }
     14 
     15 void
     16 Strinit0(String *p)
     17 {
     18 	p->s = emalloc(MINSIZE*RUNESIZE);
     19 	p->s[0] = 0;
     20 	p->n = 1;
     21 	p->size = MINSIZE;
     22 }
     23 
     24 void
     25 Strclose(String *p)
     26 {
     27 	free(p->s);
     28 }
     29 
     30 void
     31 Strzero(String *p)
     32 {
     33 	if(p->size > MAXSIZE){
     34 		p->s = erealloc(p->s, RUNESIZE*MAXSIZE); /* throw away the garbage */
     35 		p->size = MAXSIZE;
     36 	}
     37 	p->n = 0;
     38 }
     39 
     40 int
     41 Strlen(Rune *r)
     42 {
     43 	Rune *s;
     44 
     45 	for(s=r; *s; s++)
     46 		;
     47 	return s-r;
     48 }
     49 
     50 void
     51 Strdupl(String *p, Rune *s)	/* copies the null */
     52 {
     53 	p->n = Strlen(s)+1;
     54 	Strinsure(p, p->n);
     55 	memmove(p->s, s, p->n*RUNESIZE);
     56 }
     57 
     58 void
     59 Strduplstr(String *p, String *q)	/* will copy the null if there's one there */
     60 {
     61 	Strinsure(p, q->n);
     62 	p->n = q->n;
     63 	memmove(p->s, q->s, q->n*RUNESIZE);
     64 }
     65 
     66 void
     67 Straddc(String *p, int c)
     68 {
     69 	Strinsure(p, p->n+1);
     70 	p->s[p->n++] = c;
     71 }
     72 
     73 void
     74 Strinsure(String *p, ulong n)
     75 {
     76 	if(n > STRSIZE)
     77 		error(Etoolong);
     78 	if(p->size < n){	/* p needs to grow */
     79 		n += 100;
     80 		p->s = erealloc(p->s, n*RUNESIZE);
     81 		p->size = n;
     82 	}
     83 }
     84 
     85 void
     86 Strinsert(String *p, String *q, Posn p0)
     87 {
     88 	Strinsure(p, p->n+q->n);
     89 	memmove(p->s+p0+q->n, p->s+p0, (p->n-p0)*RUNESIZE);
     90 	memmove(p->s+p0, q->s, q->n*RUNESIZE);
     91 	p->n += q->n;
     92 }
     93 
     94 void
     95 Strdelete(String *p, Posn p1, Posn p2)
     96 {
     97 	memmove(p->s+p1, p->s+p2, (p->n-p2)*RUNESIZE);
     98 	p->n -= p2-p1;
     99 }
    100 
    101 int
    102 Strcmp(String *a, String *b)
    103 {
    104 	int i, c;
    105 
    106 	for(i=0; i<a->n && i<b->n; i++)
    107 		if(c = (a->s[i] - b->s[i]))	/* assign = */
    108 			return c;
    109 	/* damn NULs confuse everything */
    110 	i = a->n - b->n;
    111 	if(i == 1){
    112 		if(a->s[a->n-1] == 0)
    113 			return 0;
    114 	}else if(i == -1){
    115 		if(b->s[b->n-1] == 0)
    116 			return 0;
    117 	}
    118 	return i;
    119 }
    120 
    121 int
    122 Strispre(String *a, String *b)
    123 {
    124 	int i;
    125 
    126 	for(i=0; i<a->n && i<b->n; i++){
    127 		if(a->s[i] - b->s[i]){	/* assign = */
    128 			if(a->s[i] == 0)
    129 				return 1;
    130 			return 0;
    131 		}
    132 	}
    133 	return i == a->n;
    134 }
    135 
    136 char*
    137 Strtoc(String *s)
    138 {
    139 	int i;
    140 	char *c, *d;
    141 	Rune *r;
    142 	c = emalloc(s->n*UTFmax + 1);  /* worst case UTFmax bytes per rune, plus NUL */
    143 	d = c;
    144 	r = s->s;
    145 	for(i=0; i<s->n; i++)
    146 		d += runetochar(d, r++);
    147 	if(d==c || d[-1]!=0)
    148 		*d = 0;
    149 	return c;
    150 
    151 }
    152 
    153 /*
    154  * Build very temporary String from Rune*
    155  */
    156 String*
    157 tmprstr(Rune *r, int n)
    158 {
    159 	static String p;
    160 
    161 	p.s = r;
    162 	p.n = n;
    163 	p.size = n;
    164 	return &p;
    165 }
    166 
    167 /*
    168  * Convert null-terminated char* into String
    169  */
    170 String*
    171 tmpcstr(char *s)
    172 {
    173 	String *p;
    174 	Rune *r;
    175 	int i, n;
    176 
    177 	n = utflen(s);	/* don't include NUL */
    178 	p = emalloc(sizeof(String));
    179 	r = emalloc(n*RUNESIZE);
    180 	p->s = r;
    181 	for(i=0; i<n; i++,r++)
    182 		s += chartorune(r, s);
    183 	p->n = n;
    184 	p->size = n;
    185 	return p;
    186 }
    187 
    188 void
    189 freetmpstr(String *s)
    190 {
    191 	free(s->s);
    192 	free(s);
    193 }