Blob


1 #include "sam.h"
3 #define MINSIZE 16 /* minimum number of chars allocated */
4 #define MAXSIZE 256 /* maximum number of chars for an empty string */
7 void
8 Strinit(String *p)
9 {
10 p->s = emalloc(MINSIZE*RUNESIZE);
11 p->n = 0;
12 p->size = MINSIZE;
13 }
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 }
24 void
25 Strclose(String *p)
26 {
27 free(p->s);
28 }
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 }
40 int
41 Strlen(Rune *r)
42 {
43 Rune *s;
45 for(s=r; *s; s++)
46 ;
47 return s-r;
48 }
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 }
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 }
66 void
67 Straddc(String *p, int c)
68 {
69 Strinsure(p, p->n+1);
70 p->s[p->n++] = c;
71 }
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 }
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 }
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 }
101 int
102 Strcmp(String *a, String *b)
104 int i, c;
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;
118 return i;
121 int
122 Strispre(String *a, String *b)
124 int i;
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;
133 return i == a->n;
136 char*
137 Strtoc(String *s)
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;
153 /*
154 * Build very temporary String from Rune*
155 */
156 String*
157 tmprstr(Rune *r, int n)
159 static String p;
161 p.s = r;
162 p.n = n;
163 p.size = n;
164 return &p;
167 /*
168 * Convert null-terminated char* into String
169 */
170 String*
171 tmpcstr(char *s)
173 String *p;
174 Rune *r;
175 int i, n;
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;
188 void
189 freetmpstr(String *s)
191 free(s->s);
192 free(s);