Blame


1 7cf289ca 2004-04-06 devnull #include <u.h>
2 650deb79 2004-04-08 devnull #include <limits.h>
3 7cf289ca 2004-04-06 devnull #include <libc.h>
4 7cf289ca 2004-04-06 devnull #include <draw.h>
5 7cf289ca 2004-04-06 devnull #include <html.h>
6 7cf289ca 2004-04-06 devnull #include "impl.h"
7 7cf289ca 2004-04-06 devnull
8 7cf289ca 2004-04-06 devnull Rune whitespace[] = { ' ', '\t', '\n', '\r', '\0' };
9 7cf289ca 2004-04-06 devnull Rune notwhitespace[] = { '^', ' ', '\t', '\n', '\r' , '\0'};
10 7cf289ca 2004-04-06 devnull
11 cbeb0b26 2006-04-01 devnull /* All lists start out like List structure. */
12 cbeb0b26 2006-04-01 devnull /* List itself can be used as list of int. */
13 7cf289ca 2004-04-06 devnull int
14 7cf289ca 2004-04-06 devnull _listlen(List* l)
15 7cf289ca 2004-04-06 devnull {
16 7cf289ca 2004-04-06 devnull int n = 0;
17 7cf289ca 2004-04-06 devnull
18 7cf289ca 2004-04-06 devnull while(l != nil) {
19 7cf289ca 2004-04-06 devnull l = l->next;
20 7cf289ca 2004-04-06 devnull n++;
21 7cf289ca 2004-04-06 devnull }
22 7cf289ca 2004-04-06 devnull return n;
23 7cf289ca 2004-04-06 devnull }
24 7cf289ca 2004-04-06 devnull
25 cbeb0b26 2006-04-01 devnull /* Cons */
26 7cf289ca 2004-04-06 devnull List*
27 7cf289ca 2004-04-06 devnull _newlist(int val, List* rest)
28 7cf289ca 2004-04-06 devnull {
29 7cf289ca 2004-04-06 devnull List* ans;
30 7cf289ca 2004-04-06 devnull
31 7cf289ca 2004-04-06 devnull ans = (List*)emalloc(sizeof(List));
32 7cf289ca 2004-04-06 devnull ans->val = val;
33 7cf289ca 2004-04-06 devnull ans->next = rest;
34 7cf289ca 2004-04-06 devnull return ans;
35 7cf289ca 2004-04-06 devnull }
36 7cf289ca 2004-04-06 devnull
37 cbeb0b26 2006-04-01 devnull /* Reverse a list in place */
38 7cf289ca 2004-04-06 devnull List*
39 7cf289ca 2004-04-06 devnull _revlist(List* l)
40 7cf289ca 2004-04-06 devnull {
41 7cf289ca 2004-04-06 devnull List* newl;
42 7cf289ca 2004-04-06 devnull List* nextl;
43 7cf289ca 2004-04-06 devnull
44 7cf289ca 2004-04-06 devnull newl = nil;
45 7cf289ca 2004-04-06 devnull while(l != nil) {
46 7cf289ca 2004-04-06 devnull nextl = l->next;
47 7cf289ca 2004-04-06 devnull l->next = newl;
48 7cf289ca 2004-04-06 devnull newl = l;
49 7cf289ca 2004-04-06 devnull l = nextl;
50 7cf289ca 2004-04-06 devnull }
51 7cf289ca 2004-04-06 devnull return newl;
52 7cf289ca 2004-04-06 devnull }
53 7cf289ca 2004-04-06 devnull
54 cbeb0b26 2006-04-01 devnull /* The next few routines take a "character class" as argument. */
55 cbeb0b26 2006-04-01 devnull /* e.g., "a-zA-Z", or "^ \t\n" */
56 cbeb0b26 2006-04-01 devnull /* (ranges indicated by - except in first position; */
57 cbeb0b26 2006-04-01 devnull /* ^ is first position means "not in" the following class) */
58 7cf289ca 2004-04-06 devnull
59 cbeb0b26 2006-04-01 devnull /* Splitl splits s[0:n] just before first character of class cl. */
60 cbeb0b26 2006-04-01 devnull /* Answers go in (p1, n1) and (p2, n2). */
61 cbeb0b26 2006-04-01 devnull /* If no split, the whole thing goes in the first component. */
62 cbeb0b26 2006-04-01 devnull /* Note: answers contain pointers into original string. */
63 7cf289ca 2004-04-06 devnull void
64 7cf289ca 2004-04-06 devnull _splitl(Rune* s, int n, Rune* cl, Rune** p1, int* n1, Rune** p2, int* n2)
65 7cf289ca 2004-04-06 devnull {
66 7cf289ca 2004-04-06 devnull Rune* p;
67 7cf289ca 2004-04-06 devnull
68 7cf289ca 2004-04-06 devnull p = _Strnclass(s, cl, n);
69 7cf289ca 2004-04-06 devnull *p1 = s;
70 7cf289ca 2004-04-06 devnull if(p == nil) {
71 7cf289ca 2004-04-06 devnull *n1 = n;
72 7cf289ca 2004-04-06 devnull *p2 = nil;
73 7cf289ca 2004-04-06 devnull *n2 = 0;
74 7cf289ca 2004-04-06 devnull }
75 7cf289ca 2004-04-06 devnull else {
76 7cf289ca 2004-04-06 devnull *p2 = p;
77 7cf289ca 2004-04-06 devnull *n1 = p-s;
78 7cf289ca 2004-04-06 devnull *n2 = n-*n1;
79 7cf289ca 2004-04-06 devnull }
80 7cf289ca 2004-04-06 devnull }
81 7cf289ca 2004-04-06 devnull
82 cbeb0b26 2006-04-01 devnull /* Splitr splits s[0:n] just after last character of class cl. */
83 cbeb0b26 2006-04-01 devnull /* Answers go in (p1, n1) and (p2, n2). */
84 cbeb0b26 2006-04-01 devnull /* If no split, the whole thing goes in the last component. */
85 cbeb0b26 2006-04-01 devnull /* Note: answers contain pointers into original string. */
86 7cf289ca 2004-04-06 devnull void
87 7cf289ca 2004-04-06 devnull _splitr(Rune* s, int n, Rune* cl, Rune** p1, int* n1, Rune** p2, int* n2)
88 7cf289ca 2004-04-06 devnull {
89 7cf289ca 2004-04-06 devnull Rune* p;
90 7cf289ca 2004-04-06 devnull
91 7cf289ca 2004-04-06 devnull p = _Strnrclass(s, cl, n);
92 7cf289ca 2004-04-06 devnull if(p == nil) {
93 7cf289ca 2004-04-06 devnull *p1 = nil;
94 7cf289ca 2004-04-06 devnull *n1 = 0;
95 7cf289ca 2004-04-06 devnull *p2 = s;
96 7cf289ca 2004-04-06 devnull *n2 = n;
97 7cf289ca 2004-04-06 devnull }
98 7cf289ca 2004-04-06 devnull else {
99 7cf289ca 2004-04-06 devnull *p1 = s;
100 7cf289ca 2004-04-06 devnull *p2 = p+1;
101 7cf289ca 2004-04-06 devnull *n1 = *p2-s;
102 7cf289ca 2004-04-06 devnull *n2 = n-*n1;
103 7cf289ca 2004-04-06 devnull }
104 7cf289ca 2004-04-06 devnull }
105 7cf289ca 2004-04-06 devnull
106 cbeb0b26 2006-04-01 devnull /* Splitall splits s[0:n] into parts that are separated by characters from class cl. */
107 cbeb0b26 2006-04-01 devnull /* Each part will have nonzero length. */
108 cbeb0b26 2006-04-01 devnull /* At most alen parts are found, and pointers to their starts go into */
109 cbeb0b26 2006-04-01 devnull /* the strarr array, while their lengths go into the lenarr array. */
110 cbeb0b26 2006-04-01 devnull /* The return value is the number of parts found. */
111 7cf289ca 2004-04-06 devnull int
112 7cf289ca 2004-04-06 devnull _splitall(Rune* s, int n, Rune* cl, Rune** strarr, int* lenarr, int alen)
113 7cf289ca 2004-04-06 devnull {
114 7cf289ca 2004-04-06 devnull int i;
115 7cf289ca 2004-04-06 devnull Rune* p;
116 7cf289ca 2004-04-06 devnull Rune* q;
117 7cf289ca 2004-04-06 devnull Rune* slast;
118 7cf289ca 2004-04-06 devnull
119 7cf289ca 2004-04-06 devnull if(s == nil || n == 0)
120 7cf289ca 2004-04-06 devnull return 0;
121 7cf289ca 2004-04-06 devnull i = 0;
122 7cf289ca 2004-04-06 devnull p = s;
123 7cf289ca 2004-04-06 devnull slast = s+n;
124 7cf289ca 2004-04-06 devnull while(p < slast && i < alen) {
125 7cf289ca 2004-04-06 devnull while(p < slast && _inclass(*p, cl))
126 7cf289ca 2004-04-06 devnull p++;
127 7cf289ca 2004-04-06 devnull if(p == slast)
128 7cf289ca 2004-04-06 devnull break;
129 7cf289ca 2004-04-06 devnull q = _Strnclass(p, cl, slast-p);
130 7cf289ca 2004-04-06 devnull if(q == nil)
131 7cf289ca 2004-04-06 devnull q = slast;
132 7cf289ca 2004-04-06 devnull assert(q > p && q <= slast);
133 7cf289ca 2004-04-06 devnull strarr[i] = p;
134 7cf289ca 2004-04-06 devnull lenarr[i] = q-p;
135 7cf289ca 2004-04-06 devnull i++;
136 7cf289ca 2004-04-06 devnull p = q;
137 7cf289ca 2004-04-06 devnull }
138 7cf289ca 2004-04-06 devnull return i;
139 7cf289ca 2004-04-06 devnull }
140 7cf289ca 2004-04-06 devnull
141 cbeb0b26 2006-04-01 devnull /* Find part of s that excludes leading and trailing whitespace, */
142 cbeb0b26 2006-04-01 devnull /* and return that part in *pans (and its length in *panslen). */
143 7cf289ca 2004-04-06 devnull void
144 7cf289ca 2004-04-06 devnull _trimwhite(Rune* s, int n, Rune** pans, int* panslen)
145 7cf289ca 2004-04-06 devnull {
146 7cf289ca 2004-04-06 devnull Rune* p;
147 7cf289ca 2004-04-06 devnull Rune* q;
148 7cf289ca 2004-04-06 devnull
149 7cf289ca 2004-04-06 devnull p = nil;
150 7cf289ca 2004-04-06 devnull if(n > 0) {
151 7cf289ca 2004-04-06 devnull p = _Strnclass(s, notwhitespace, n);
152 7cf289ca 2004-04-06 devnull if(p != nil) {
153 7cf289ca 2004-04-06 devnull q = _Strnrclass(s, notwhitespace, n);
154 7cf289ca 2004-04-06 devnull assert(q != nil);
155 7cf289ca 2004-04-06 devnull n = q+1-p;
156 7cf289ca 2004-04-06 devnull }
157 7cf289ca 2004-04-06 devnull }
158 7cf289ca 2004-04-06 devnull *pans = p;
159 7cf289ca 2004-04-06 devnull *panslen = n;
160 7cf289ca 2004-04-06 devnull }
161 7cf289ca 2004-04-06 devnull
162 cbeb0b26 2006-04-01 devnull /* _Strclass returns a pointer to the first element of s that is */
163 cbeb0b26 2006-04-01 devnull /* a member of class cl, nil if none. */
164 7cf289ca 2004-04-06 devnull Rune*
165 7cf289ca 2004-04-06 devnull _Strclass(Rune* s, Rune* cl)
166 7cf289ca 2004-04-06 devnull {
167 7cf289ca 2004-04-06 devnull Rune* p;
168 7cf289ca 2004-04-06 devnull
169 7cf289ca 2004-04-06 devnull for(p = s; *p != 0; p++)
170 7cf289ca 2004-04-06 devnull if(_inclass(*p, cl))
171 7cf289ca 2004-04-06 devnull return p;
172 7cf289ca 2004-04-06 devnull return nil;
173 7cf289ca 2004-04-06 devnull }
174 7cf289ca 2004-04-06 devnull
175 cbeb0b26 2006-04-01 devnull /* _Strnclass returns a pointer to the first element of s[0:n] that is */
176 cbeb0b26 2006-04-01 devnull /* a member of class cl, nil if none. */
177 7cf289ca 2004-04-06 devnull Rune*
178 7cf289ca 2004-04-06 devnull _Strnclass(Rune* s, Rune* cl, int n)
179 7cf289ca 2004-04-06 devnull {
180 7cf289ca 2004-04-06 devnull Rune* p;
181 7cf289ca 2004-04-06 devnull
182 7cf289ca 2004-04-06 devnull for(p = s; n-- && *p != 0; p++)
183 7cf289ca 2004-04-06 devnull if(_inclass(*p, cl))
184 7cf289ca 2004-04-06 devnull return p;
185 7cf289ca 2004-04-06 devnull return nil;
186 7cf289ca 2004-04-06 devnull }
187 7cf289ca 2004-04-06 devnull
188 cbeb0b26 2006-04-01 devnull /* _Strrclass returns a pointer to the last element of s that is */
189 cbeb0b26 2006-04-01 devnull /* a member of class cl, nil if none */
190 7cf289ca 2004-04-06 devnull Rune*
191 7cf289ca 2004-04-06 devnull _Strrclass(Rune* s, Rune* cl)
192 7cf289ca 2004-04-06 devnull {
193 7cf289ca 2004-04-06 devnull Rune* p;
194 7cf289ca 2004-04-06 devnull
195 7cf289ca 2004-04-06 devnull if(s == nil || *s == 0)
196 7cf289ca 2004-04-06 devnull return nil;
197 7cf289ca 2004-04-06 devnull p = s + runestrlen(s) - 1;
198 7cf289ca 2004-04-06 devnull while(p >= s) {
199 7cf289ca 2004-04-06 devnull if(_inclass(*p, cl))
200 7cf289ca 2004-04-06 devnull return p;
201 7cf289ca 2004-04-06 devnull p--;
202 7cf289ca 2004-04-06 devnull };
203 7cf289ca 2004-04-06 devnull return nil;
204 7cf289ca 2004-04-06 devnull }
205 7cf289ca 2004-04-06 devnull
206 cbeb0b26 2006-04-01 devnull /* _Strnrclass returns a pointer to the last element of s[0:n] that is */
207 cbeb0b26 2006-04-01 devnull /* a member of class cl, nil if none */
208 7cf289ca 2004-04-06 devnull Rune*
209 7cf289ca 2004-04-06 devnull _Strnrclass(Rune* s, Rune* cl, int n)
210 7cf289ca 2004-04-06 devnull {
211 7cf289ca 2004-04-06 devnull Rune* p;
212 7cf289ca 2004-04-06 devnull
213 7cf289ca 2004-04-06 devnull if(s == nil || *s == 0 || n == 0)
214 7cf289ca 2004-04-06 devnull return nil;
215 7cf289ca 2004-04-06 devnull p = s + n - 1;
216 7cf289ca 2004-04-06 devnull while(p >= s) {
217 7cf289ca 2004-04-06 devnull if(_inclass(*p, cl))
218 7cf289ca 2004-04-06 devnull return p;
219 7cf289ca 2004-04-06 devnull p--;
220 7cf289ca 2004-04-06 devnull };
221 7cf289ca 2004-04-06 devnull return nil;
222 7cf289ca 2004-04-06 devnull }
223 7cf289ca 2004-04-06 devnull
224 cbeb0b26 2006-04-01 devnull /* Is c in the class cl? */
225 7cf289ca 2004-04-06 devnull int
226 7cf289ca 2004-04-06 devnull _inclass(Rune c, Rune* cl)
227 7cf289ca 2004-04-06 devnull {
228 7cf289ca 2004-04-06 devnull int n;
229 7cf289ca 2004-04-06 devnull int ans;
230 7cf289ca 2004-04-06 devnull int negate;
231 7cf289ca 2004-04-06 devnull int i;
232 7cf289ca 2004-04-06 devnull
233 7cf289ca 2004-04-06 devnull n = _Strlen(cl);
234 7cf289ca 2004-04-06 devnull if(n == 0)
235 7cf289ca 2004-04-06 devnull return 0;
236 7cf289ca 2004-04-06 devnull ans = 0;
237 7cf289ca 2004-04-06 devnull negate = 0;
238 7cf289ca 2004-04-06 devnull if(cl[0] == '^') {
239 7cf289ca 2004-04-06 devnull negate = 1;
240 7cf289ca 2004-04-06 devnull cl++;
241 7cf289ca 2004-04-06 devnull n--;
242 7cf289ca 2004-04-06 devnull }
243 7cf289ca 2004-04-06 devnull for(i = 0; i < n; i++) {
244 7cf289ca 2004-04-06 devnull if(cl[i] == '-' && i > 0 && i < n - 1) {
245 7cf289ca 2004-04-06 devnull if(c >= cl[i - 1] && c <= cl[i + 1]) {
246 7cf289ca 2004-04-06 devnull ans = 1;
247 7cf289ca 2004-04-06 devnull break;
248 7cf289ca 2004-04-06 devnull }
249 7cf289ca 2004-04-06 devnull i++;
250 7cf289ca 2004-04-06 devnull }
251 7cf289ca 2004-04-06 devnull else if(c == cl[i]) {
252 7cf289ca 2004-04-06 devnull ans = 1;
253 7cf289ca 2004-04-06 devnull break;
254 7cf289ca 2004-04-06 devnull }
255 7cf289ca 2004-04-06 devnull }
256 7cf289ca 2004-04-06 devnull if(negate)
257 7cf289ca 2004-04-06 devnull ans = !ans;
258 7cf289ca 2004-04-06 devnull return ans;
259 7cf289ca 2004-04-06 devnull }
260 7cf289ca 2004-04-06 devnull
261 cbeb0b26 2006-04-01 devnull /* Is pre a prefix of s? */
262 7cf289ca 2004-04-06 devnull int
263 7cf289ca 2004-04-06 devnull _prefix(Rune* pre, Rune* s)
264 7cf289ca 2004-04-06 devnull {
265 7cf289ca 2004-04-06 devnull int ns;
266 7cf289ca 2004-04-06 devnull int n;
267 7cf289ca 2004-04-06 devnull int k;
268 7cf289ca 2004-04-06 devnull
269 7cf289ca 2004-04-06 devnull ns = _Strlen(s);
270 7cf289ca 2004-04-06 devnull n = _Strlen(pre);
271 7cf289ca 2004-04-06 devnull if(ns < n)
272 7cf289ca 2004-04-06 devnull return 0;
273 7cf289ca 2004-04-06 devnull for(k = 0; k < n; k++) {
274 7cf289ca 2004-04-06 devnull if(pre[k] != s[k])
275 7cf289ca 2004-04-06 devnull return 0;
276 7cf289ca 2004-04-06 devnull }
277 7cf289ca 2004-04-06 devnull return 1;
278 7cf289ca 2004-04-06 devnull }
279 7cf289ca 2004-04-06 devnull
280 cbeb0b26 2006-04-01 devnull /* Number of runes in (null-terminated) s */
281 7cf289ca 2004-04-06 devnull int
282 7cf289ca 2004-04-06 devnull _Strlen(Rune* s)
283 7cf289ca 2004-04-06 devnull {
284 7cf289ca 2004-04-06 devnull if(s == nil)
285 7cf289ca 2004-04-06 devnull return 0;
286 7cf289ca 2004-04-06 devnull return runestrlen(s);
287 7cf289ca 2004-04-06 devnull }
288 7cf289ca 2004-04-06 devnull
289 cbeb0b26 2006-04-01 devnull /* -1, 0, 1 as s1 is lexicographically less, equal greater than s2 */
290 7cf289ca 2004-04-06 devnull int
291 7cf289ca 2004-04-06 devnull _Strcmp(Rune *s1, Rune *s2)
292 7cf289ca 2004-04-06 devnull {
293 7cf289ca 2004-04-06 devnull if(s1 == nil)
294 7cf289ca 2004-04-06 devnull return (s2 == nil || *s2 == 0) ? 0 : -1;
295 7cf289ca 2004-04-06 devnull if(s2 == nil)
296 7cf289ca 2004-04-06 devnull return (*s1 == 0) ? 0 : 1;
297 7cf289ca 2004-04-06 devnull return runestrcmp(s1, s2);
298 7cf289ca 2004-04-06 devnull }
299 7cf289ca 2004-04-06 devnull
300 cbeb0b26 2006-04-01 devnull /* Like Strcmp, but use exactly n chars of s1 (assume s1 has at least n chars). */
301 cbeb0b26 2006-04-01 devnull /* Also, do a case-insensitive match, assuming s2 */
302 cbeb0b26 2006-04-01 devnull /* has no chars in [A-Z], only their lowercase versions. */
303 cbeb0b26 2006-04-01 devnull /* (This routine is used for in-place keyword lookup, where s2 is in a keyword */
304 cbeb0b26 2006-04-01 devnull /* list and s1 is some substring, possibly mixed-case, in a buffer.) */
305 7cf289ca 2004-04-06 devnull int
306 7cf289ca 2004-04-06 devnull _Strncmpci(Rune *s1, int n1, Rune *s2)
307 7cf289ca 2004-04-06 devnull {
308 7cf289ca 2004-04-06 devnull Rune c1, c2;
309 7cf289ca 2004-04-06 devnull
310 7cf289ca 2004-04-06 devnull for(;;) {
311 7cf289ca 2004-04-06 devnull if(n1-- == 0) {
312 7cf289ca 2004-04-06 devnull if(*s2 == 0)
313 7cf289ca 2004-04-06 devnull return 0;
314 7cf289ca 2004-04-06 devnull return -1;
315 7cf289ca 2004-04-06 devnull }
316 7cf289ca 2004-04-06 devnull c1 = *s1++;
317 7cf289ca 2004-04-06 devnull c2 = *s2++;
318 7cf289ca 2004-04-06 devnull if(c1 >= 'A' && c1 <= 'Z')
319 7cf289ca 2004-04-06 devnull c1 = c1 - 'A' + 'a';
320 7cf289ca 2004-04-06 devnull if(c1 != c2) {
321 7cf289ca 2004-04-06 devnull if(c1 > c2)
322 7cf289ca 2004-04-06 devnull return 1;
323 7cf289ca 2004-04-06 devnull return -1;
324 7cf289ca 2004-04-06 devnull }
325 7cf289ca 2004-04-06 devnull }
326 7cf289ca 2004-04-06 devnull }
327 7cf289ca 2004-04-06 devnull
328 cbeb0b26 2006-04-01 devnull /* emalloc and copy */
329 7cf289ca 2004-04-06 devnull Rune*
330 7cf289ca 2004-04-06 devnull _Strdup(Rune* s)
331 7cf289ca 2004-04-06 devnull {
332 7cf289ca 2004-04-06 devnull if(s == nil)
333 7cf289ca 2004-04-06 devnull return nil;
334 7cf289ca 2004-04-06 devnull return _Strndup(s, runestrlen(s));
335 7cf289ca 2004-04-06 devnull }
336 7cf289ca 2004-04-06 devnull
337 cbeb0b26 2006-04-01 devnull /* emalloc and copy n chars of s (assume s is at least that long), */
338 cbeb0b26 2006-04-01 devnull /* and add 0 terminator. */
339 cbeb0b26 2006-04-01 devnull /* Return nil if n==0. */
340 7cf289ca 2004-04-06 devnull Rune*
341 7cf289ca 2004-04-06 devnull _Strndup(Rune* s, int n)
342 7cf289ca 2004-04-06 devnull {
343 7cf289ca 2004-04-06 devnull Rune* ans;
344 7cf289ca 2004-04-06 devnull
345 7cf289ca 2004-04-06 devnull if(n <= 0)
346 7cf289ca 2004-04-06 devnull return nil;
347 7cf289ca 2004-04-06 devnull ans = _newstr(n);
348 7cf289ca 2004-04-06 devnull memmove(ans, s, n*sizeof(Rune));
349 7cf289ca 2004-04-06 devnull ans[n] = 0;
350 7cf289ca 2004-04-06 devnull return ans;
351 7cf289ca 2004-04-06 devnull }
352 cbeb0b26 2006-04-01 devnull /* emalloc enough room for n Runes, plus 1 null terminator. */
353 cbeb0b26 2006-04-01 devnull /* (Not initialized to anything.) */
354 7cf289ca 2004-04-06 devnull Rune*
355 7cf289ca 2004-04-06 devnull _newstr(int n)
356 7cf289ca 2004-04-06 devnull {
357 7cf289ca 2004-04-06 devnull return (Rune*)emalloc((n+1)*sizeof(Rune));
358 7cf289ca 2004-04-06 devnull }
359 7cf289ca 2004-04-06 devnull
360 cbeb0b26 2006-04-01 devnull /* emalloc and copy s+t */
361 7cf289ca 2004-04-06 devnull Rune*
362 7cf289ca 2004-04-06 devnull _Strdup2(Rune* s, Rune* t)
363 7cf289ca 2004-04-06 devnull {
364 7cf289ca 2004-04-06 devnull int ns, nt;
365 7cf289ca 2004-04-06 devnull Rune* ans;
366 7cf289ca 2004-04-06 devnull Rune* p;
367 7cf289ca 2004-04-06 devnull
368 7cf289ca 2004-04-06 devnull ns = _Strlen(s);
369 7cf289ca 2004-04-06 devnull nt = _Strlen(t);
370 7cf289ca 2004-04-06 devnull if(ns+nt == 0)
371 7cf289ca 2004-04-06 devnull return nil;
372 7cf289ca 2004-04-06 devnull ans = _newstr(ns+nt);
373 7cf289ca 2004-04-06 devnull p = _Stradd(ans, s, ns);
374 7cf289ca 2004-04-06 devnull p = _Stradd(p, t, nt);
375 7cf289ca 2004-04-06 devnull *p = 0;
376 7cf289ca 2004-04-06 devnull return ans;
377 7cf289ca 2004-04-06 devnull }
378 7cf289ca 2004-04-06 devnull
379 cbeb0b26 2006-04-01 devnull /* Return emalloc'd substring s[start:stop], */
380 7cf289ca 2004-04-06 devnull Rune*
381 7cf289ca 2004-04-06 devnull _Strsubstr(Rune* s, int start, int stop)
382 7cf289ca 2004-04-06 devnull {
383 7cf289ca 2004-04-06 devnull Rune* t;
384 7cf289ca 2004-04-06 devnull
385 7cf289ca 2004-04-06 devnull if(start == stop)
386 7cf289ca 2004-04-06 devnull return nil;
387 7cf289ca 2004-04-06 devnull t = _Strndup(s+start, stop-start);
388 7cf289ca 2004-04-06 devnull return t;
389 7cf289ca 2004-04-06 devnull }
390 7cf289ca 2004-04-06 devnull
391 cbeb0b26 2006-04-01 devnull /* Copy n chars to s1 from s2, and return s1+n */
392 7cf289ca 2004-04-06 devnull Rune*
393 7cf289ca 2004-04-06 devnull _Stradd(Rune* s1, Rune* s2, int n)
394 7cf289ca 2004-04-06 devnull {
395 7cf289ca 2004-04-06 devnull if(n == 0)
396 7cf289ca 2004-04-06 devnull return s1;
397 7cf289ca 2004-04-06 devnull memmove(s1, s2, n*sizeof(Rune));
398 7cf289ca 2004-04-06 devnull return s1+n;
399 7cf289ca 2004-04-06 devnull }
400 7cf289ca 2004-04-06 devnull
401 cbeb0b26 2006-04-01 devnull /* Like strtol, but converting from Rune* string */
402 7cf289ca 2004-04-06 devnull
403 cbeb0b26 2006-04-01 devnull /*#define LONG_MAX 2147483647L */
404 cbeb0b26 2006-04-01 devnull /*#define LONG_MIN -2147483648L */
405 7cf289ca 2004-04-06 devnull
406 7cf289ca 2004-04-06 devnull long
407 7cf289ca 2004-04-06 devnull _Strtol(Rune* nptr, Rune** endptr, int base)
408 7cf289ca 2004-04-06 devnull {
409 7cf289ca 2004-04-06 devnull Rune* p;
410 7cf289ca 2004-04-06 devnull long n, nn;
411 7cf289ca 2004-04-06 devnull int c, ovfl, v, neg, ndig;
412 7cf289ca 2004-04-06 devnull
413 7cf289ca 2004-04-06 devnull p = nptr;
414 7cf289ca 2004-04-06 devnull neg = 0;
415 7cf289ca 2004-04-06 devnull n = 0;
416 7cf289ca 2004-04-06 devnull ndig = 0;
417 7cf289ca 2004-04-06 devnull ovfl = 0;
418 7cf289ca 2004-04-06 devnull
419 7cf289ca 2004-04-06 devnull /*
420 7cf289ca 2004-04-06 devnull * White space
421 7cf289ca 2004-04-06 devnull */
422 7cf289ca 2004-04-06 devnull for(;;p++){
423 7cf289ca 2004-04-06 devnull switch(*p){
424 7cf289ca 2004-04-06 devnull case ' ':
425 7cf289ca 2004-04-06 devnull case '\t':
426 7cf289ca 2004-04-06 devnull case '\n':
427 7cf289ca 2004-04-06 devnull case '\f':
428 7cf289ca 2004-04-06 devnull case '\r':
429 7cf289ca 2004-04-06 devnull case '\v':
430 7cf289ca 2004-04-06 devnull continue;
431 7cf289ca 2004-04-06 devnull }
432 7cf289ca 2004-04-06 devnull break;
433 7cf289ca 2004-04-06 devnull }
434 7cf289ca 2004-04-06 devnull
435 7cf289ca 2004-04-06 devnull /*
436 7cf289ca 2004-04-06 devnull * Sign
437 7cf289ca 2004-04-06 devnull */
438 7cf289ca 2004-04-06 devnull if(*p=='-' || *p=='+')
439 7cf289ca 2004-04-06 devnull if(*p++ == '-')
440 7cf289ca 2004-04-06 devnull neg = 1;
441 7cf289ca 2004-04-06 devnull
442 7cf289ca 2004-04-06 devnull /*
443 7cf289ca 2004-04-06 devnull * Base
444 7cf289ca 2004-04-06 devnull */
445 7cf289ca 2004-04-06 devnull if(base==0){
446 7cf289ca 2004-04-06 devnull if(*p != '0')
447 7cf289ca 2004-04-06 devnull base = 10;
448 7cf289ca 2004-04-06 devnull else{
449 7cf289ca 2004-04-06 devnull base = 8;
450 7cf289ca 2004-04-06 devnull if(p[1]=='x' || p[1]=='X'){
451 7cf289ca 2004-04-06 devnull p += 2;
452 7cf289ca 2004-04-06 devnull base = 16;
453 7cf289ca 2004-04-06 devnull }
454 7cf289ca 2004-04-06 devnull }
455 7cf289ca 2004-04-06 devnull }else if(base==16 && *p=='0'){
456 7cf289ca 2004-04-06 devnull if(p[1]=='x' || p[1]=='X')
457 7cf289ca 2004-04-06 devnull p += 2;
458 7cf289ca 2004-04-06 devnull }else if(base<0 || 36<base)
459 7cf289ca 2004-04-06 devnull goto Return;
460 7cf289ca 2004-04-06 devnull
461 7cf289ca 2004-04-06 devnull /*
462 7cf289ca 2004-04-06 devnull * Non-empty sequence of digits
463 7cf289ca 2004-04-06 devnull */
464 7cf289ca 2004-04-06 devnull for(;; p++,ndig++){
465 7cf289ca 2004-04-06 devnull c = *p;
466 7cf289ca 2004-04-06 devnull v = base;
467 7cf289ca 2004-04-06 devnull if('0'<=c && c<='9')
468 7cf289ca 2004-04-06 devnull v = c - '0';
469 7cf289ca 2004-04-06 devnull else if('a'<=c && c<='z')
470 7cf289ca 2004-04-06 devnull v = c - 'a' + 10;
471 7cf289ca 2004-04-06 devnull else if('A'<=c && c<='Z')
472 7cf289ca 2004-04-06 devnull v = c - 'A' + 10;
473 7cf289ca 2004-04-06 devnull if(v >= base)
474 7cf289ca 2004-04-06 devnull break;
475 7cf289ca 2004-04-06 devnull nn = n*base + v;
476 7cf289ca 2004-04-06 devnull if(nn < n)
477 7cf289ca 2004-04-06 devnull ovfl = 1;
478 7cf289ca 2004-04-06 devnull n = nn;
479 7cf289ca 2004-04-06 devnull }
480 7cf289ca 2004-04-06 devnull
481 7cf289ca 2004-04-06 devnull Return:
482 7cf289ca 2004-04-06 devnull if(ndig == 0)
483 7cf289ca 2004-04-06 devnull p = nptr;
484 7cf289ca 2004-04-06 devnull if(endptr)
485 7cf289ca 2004-04-06 devnull *endptr = p;
486 7cf289ca 2004-04-06 devnull if(ovfl){
487 7cf289ca 2004-04-06 devnull if(neg)
488 7cf289ca 2004-04-06 devnull return LONG_MIN;
489 7cf289ca 2004-04-06 devnull return LONG_MAX;
490 7cf289ca 2004-04-06 devnull }
491 7cf289ca 2004-04-06 devnull if(neg)
492 7cf289ca 2004-04-06 devnull return -n;
493 7cf289ca 2004-04-06 devnull return n;
494 7cf289ca 2004-04-06 devnull }
495 7cf289ca 2004-04-06 devnull
496 cbeb0b26 2006-04-01 devnull /* Convert buf[0:n], bytes whose character set is chset, */
497 cbeb0b26 2006-04-01 devnull /* into a emalloc'd null-terminated Unicode string. */
498 7cf289ca 2004-04-06 devnull Rune*
499 7cf289ca 2004-04-06 devnull toStr(uchar* buf, int n, int chset)
500 7cf289ca 2004-04-06 devnull {
501 7cf289ca 2004-04-06 devnull int i;
502 7cf289ca 2004-04-06 devnull int m;
503 7cf289ca 2004-04-06 devnull Rune ch;
504 7cf289ca 2004-04-06 devnull Rune* ans;
505 7cf289ca 2004-04-06 devnull
506 7cf289ca 2004-04-06 devnull switch(chset) {
507 7cf289ca 2004-04-06 devnull case US_Ascii:
508 7cf289ca 2004-04-06 devnull case ISO_8859_1:
509 7cf289ca 2004-04-06 devnull ans = (Rune*)emalloc((n+1)*sizeof(Rune));
510 7cf289ca 2004-04-06 devnull for(i = 0; i < n; i++)
511 7cf289ca 2004-04-06 devnull ans[i] = buf[i];
512 7cf289ca 2004-04-06 devnull ans[n] = 0;
513 7cf289ca 2004-04-06 devnull break;
514 7cf289ca 2004-04-06 devnull
515 7cf289ca 2004-04-06 devnull case UTF_8:
516 7cf289ca 2004-04-06 devnull m = 0;
517 7cf289ca 2004-04-06 devnull for(i = 0; i < n; ) {
518 7cf289ca 2004-04-06 devnull i += chartorune(&ch, (char*)(buf+i));
519 7cf289ca 2004-04-06 devnull m++;
520 7cf289ca 2004-04-06 devnull }
521 7cf289ca 2004-04-06 devnull ans = (Rune*)emalloc((m+1)*sizeof(Rune));
522 7cf289ca 2004-04-06 devnull m = 0;
523 7cf289ca 2004-04-06 devnull for(i = 0; i < n; ) {
524 7cf289ca 2004-04-06 devnull i += chartorune(&ch, (char*)(buf+i));
525 7cf289ca 2004-04-06 devnull ans[m++] = ch;
526 7cf289ca 2004-04-06 devnull }
527 7cf289ca 2004-04-06 devnull ans[m] = 0;
528 7cf289ca 2004-04-06 devnull break;
529 7cf289ca 2004-04-06 devnull
530 7cf289ca 2004-04-06 devnull default:
531 7cf289ca 2004-04-06 devnull ans = nil;
532 7cf289ca 2004-04-06 devnull assert(0);
533 7cf289ca 2004-04-06 devnull }
534 7cf289ca 2004-04-06 devnull return ans;
535 7cf289ca 2004-04-06 devnull }
536 7cf289ca 2004-04-06 devnull
537 cbeb0b26 2006-04-01 devnull /* Convert buf[0:n], Unicode characters, */
538 cbeb0b26 2006-04-01 devnull /* into an emalloc'd null-terminated string in character set chset. */
539 cbeb0b26 2006-04-01 devnull /* Use 0x80 for unconvertable characters. */
540 7cf289ca 2004-04-06 devnull uchar*
541 7cf289ca 2004-04-06 devnull fromStr(Rune* buf, int n, int chset)
542 7cf289ca 2004-04-06 devnull {
543 7cf289ca 2004-04-06 devnull uchar* ans;
544 7cf289ca 2004-04-06 devnull int i, lim, m;
545 7cf289ca 2004-04-06 devnull Rune ch;
546 7cf289ca 2004-04-06 devnull uchar* p;
547 7cf289ca 2004-04-06 devnull uchar s[UTFmax];
548 7cf289ca 2004-04-06 devnull
549 7cf289ca 2004-04-06 devnull ans = nil;
550 7cf289ca 2004-04-06 devnull switch(chset) {
551 7cf289ca 2004-04-06 devnull case US_Ascii:
552 7cf289ca 2004-04-06 devnull case ISO_8859_1:
553 7cf289ca 2004-04-06 devnull ans = (uchar*)emalloc(n+1);
554 7cf289ca 2004-04-06 devnull lim = (chset==US_Ascii)? 127 : 255;
555 7cf289ca 2004-04-06 devnull for(i = 0; i < n; i++) {
556 7cf289ca 2004-04-06 devnull ch = buf[i];
557 7cf289ca 2004-04-06 devnull if(ch > lim)
558 7cf289ca 2004-04-06 devnull ch = 0x80;
559 7cf289ca 2004-04-06 devnull ans[i] = ch;
560 7cf289ca 2004-04-06 devnull }
561 7cf289ca 2004-04-06 devnull ans[n] = 0;
562 7cf289ca 2004-04-06 devnull break;
563 7cf289ca 2004-04-06 devnull
564 7cf289ca 2004-04-06 devnull case UTF_8:
565 7cf289ca 2004-04-06 devnull m = 0;
566 7cf289ca 2004-04-06 devnull for(i = 0; i < n; i++) {
567 7cf289ca 2004-04-06 devnull m += runetochar((char*)s, &buf[i]);
568 7cf289ca 2004-04-06 devnull }
569 7cf289ca 2004-04-06 devnull ans = (uchar*)emalloc(m+1);
570 7cf289ca 2004-04-06 devnull p = ans;
571 7cf289ca 2004-04-06 devnull for(i = 0; i < n; i++)
572 7cf289ca 2004-04-06 devnull p += runetochar((char*)p, &buf[i]);
573 7cf289ca 2004-04-06 devnull *p = 0;
574 7cf289ca 2004-04-06 devnull break;
575 7cf289ca 2004-04-06 devnull
576 7cf289ca 2004-04-06 devnull default:
577 7cf289ca 2004-04-06 devnull assert(0);
578 7cf289ca 2004-04-06 devnull }
579 7cf289ca 2004-04-06 devnull return ans;
580 7cf289ca 2004-04-06 devnull
581 7cf289ca 2004-04-06 devnull }
582 7cf289ca 2004-04-06 devnull
583 cbeb0b26 2006-04-01 devnull /* Convert n to emalloc'd String. */
584 7cf289ca 2004-04-06 devnull Rune*
585 7cf289ca 2004-04-06 devnull _ltoStr(int n)
586 7cf289ca 2004-04-06 devnull {
587 7cf289ca 2004-04-06 devnull int m;
588 7cf289ca 2004-04-06 devnull uchar buf[20];
589 7cf289ca 2004-04-06 devnull
590 7cf289ca 2004-04-06 devnull m = snprint((char*)buf, sizeof(buf), "%d", n);
591 7cf289ca 2004-04-06 devnull return toStr(buf, m, US_Ascii);
592 7cf289ca 2004-04-06 devnull }