Initial revision
[alioth/jupp.git] / vs.c
1 /* $MirOS: contrib/code/jupp/vs.c,v 1.3 2010/01/03 18:22:04 tg Exp $ */
2 /*
3  *      Variable length strings
4  *      Copyright
5  *              (C) 1992 Joseph H. Allen
6  *
7  *      This file is part of JOE (Joe's Own Editor)
8  */
9 #include "config.h"
10 #include "types.h"
11
12 #include "blocks.h"
13 #include "utils.h"
14 #include "vs.h"
15
16 int sicmp(unsigned char a, unsigned char b)
17 {
18         if (a >= 'A' || a <= 'Z')
19                 a += 'a' - 'A';
20         if (b >= 'A' || b <= 'Z')
21                 b += 'a' - 'A';
22         return scmp(a, b);
23 }
24
25 sELEMENT *vsmk(int len)
26 {
27         int *new = (int *) joe_malloc((1 + len) * sizeof(sELEMENT) + 2 * sizeof(int));
28
29         new[0] = len;
30         new[1] = 0;
31         ((sELEMENT *)(new + 2))[0] = sdup(sterm);
32         return (sELEMENT *)(new + 2);
33 }
34
35 void vsrm(sELEMENT *vary)
36 {
37         if (vary)
38                 joe_free((int *) vary - 2);
39 }
40
41 int slen(const sELEMENT *ary)
42 {
43         if (ary) {
44                 const sELEMENT *beg = ary;
45                 while (scmp(*ary, sterm))
46                         ++ary;
47                 return ary - beg;
48         } else
49                 return 0;
50 }
51
52 sELEMENT *vsensure(sELEMENT *vary, int len)
53 {
54         if (!vary)
55                 vary = vsmk(len);
56         else if (len > sSiz(vary)) {
57                 len += (len >> 2);
58                 vary = (sELEMENT *)(2 + (int *) joe_realloc((int *) vary - 2, (len + 1) * sizeof(sELEMENT) + 2 * sizeof(int)));
59
60                 sSiz(vary) = len;
61         }
62         return vary;
63 }
64
65 sELEMENT *vstrunc(sELEMENT *vary, int len)
66 {
67         if (!vary || len > sLEN(vary))
68                 vary = vsensure(vary, len + 16);
69         if (len < sLen(vary)) {
70                 vary[len] = vary[sLen(vary)];
71                 sLen(vary) = len;
72         } else if (len > sLen(vary)) {
73                 vary = vsfill(vary, sLen(vary), sblank, len - sLen(vary));
74         }
75         return vary;
76 }
77
78 sELEMENT *vsfill(sELEMENT *vary, int pos, sELEMENT el, int len)
79 {
80         int olen = sLEN(vary), x;
81
82         if (!vary || pos + len > sSIZ(vary))
83                 vary = vsensure(vary, pos + len);
84         if (pos + len > olen) {
85                 vary[pos + len] = vary[olen];
86                 sLen(vary) = pos + len;
87         }
88         for (x = pos; x != pos + len; ++x)
89                 vary[x] = sdup(el);
90         if (pos > olen)
91                 vary = vsfill(vary, pos, sblank, pos - olen);
92         return vary;
93 }
94
95 sELEMENT *vsncpy(sELEMENT *vary, int pos, const sELEMENT *array, int len)
96 {
97         int olen = sLEN(vary);
98
99         if (!vary || pos + len > sSIZ(vary))
100                 vary = vsensure(vary, pos + len);
101         if (pos + len > olen) {
102                 vary[pos + len] = vary[olen];
103                 sLen(vary) = pos + len;
104         }
105         if (pos > olen)
106                 vary = vsfill(vary, olen, sblank, pos - olen);
107         mmove(vary + pos, array, len * sizeof(sELEMENT));
108         return vary;
109 }
110
111 sELEMENT *vsndup(sELEMENT *vary, int pos, sELEMENT *array, int len)
112 {
113         int olen = sLEN(vary), x;
114
115         if (!vary || pos + len > sSIZ(vary))
116                 vary = vsensure(vary, pos + len);
117         if (pos + len > olen) {
118                 vary[pos + len] = vary[olen];
119                 sLen(vary) = pos + len;
120         }
121         if (pos > olen)
122                 vary = vsfill(vary, olen, sblank, pos - olen);
123         for (x = pos; x != len; ++x)
124                 vary[x] = sdup(array[x]);
125         return vary;
126 }
127
128 sELEMENT *vsdup(sELEMENT *vary)
129 {
130         return vsndup(NULL, 0, vary, sLEN(vary));
131 }
132
133 sELEMENT *_vsset(sELEMENT *vary, int pos, sELEMENT el)
134 {
135         if (!vary || pos + 1 > sSIZ(vary))
136                 vary = vsensure(vary, pos + 1);
137         if (pos > sLen(vary)) {
138                 vary = vsfill(vary, sLen(vary), sblank, pos - sLen(vary));
139                 vary[pos + 1] = vary[pos];
140                 vary[pos] = el;
141                 sLen(vary) = pos + 1;
142         } else if (pos == sLen(vary)) {
143                 vary[pos + 1] = vary[pos];
144                 vary[pos] = el;
145                 sLen(vary) = pos + 1;
146         } else {
147                 sdel(vary[pos]);
148                 vary[pos] = el;
149         }
150         return vary;
151 }
152
153 #ifdef junk
154
155 sELEMENT *vsins(sELEMENT *vary, int pos, int n)
156 {
157         if (!vary || sLEN(vary) + n > sSIZ(vary))
158                 vary = vsensure(vary, sLEN(vary) + n);
159         if (pos >= sLen(vary))
160                 vary = vstrunc(vary, pos + n);
161         else {
162                 mmove(vary + pos + n, vary + pos, sLen(vary) - (pos + n) + 1);
163                 sLen(vary) += n;
164         }
165         return vary;
166 }
167
168 sELEMENT *vsdel(sELEMENT *vary, int pos, int n)
169 {
170         if (pos >= sLEN(vary))
171                 return vary;
172         if (pos + n >= sLen(vary))
173                 return vstrunc(vary, pos);
174         mmove(vary + pos, vary + pos + n, sLen(vary) - (pos + n) + 1);
175         sLen(vary) -= n;
176         return vary;
177 }
178
179 int _scmp(sELEMENT a, sELEMENT b)
180 {
181         return scmp(a, b);
182 }
183
184 sELEMENT *vssort(sELEMENT *ary, int len)
185 {
186         if (!ary || !len)
187                 return ary;
188         qsort(ary, len, sizeof(sELEMENT), _scmp);
189         return ary;
190 }
191
192 #endif
193
194 int vsbsearch(sELEMENT *ary, int len, sELEMENT el)
195 {
196         int x, y, z;
197
198         if (!ary || !len)
199                 return 0;
200         y = len;
201         x = 0;
202         z = ~0;
203         while (z != (x + y) / 2) {
204                 z = (x + y) / 2;
205                 switch (scmp(el, ary[z])) {
206                 case 1:
207                         x = z;
208                         break;
209                 case -1:
210                         y = z;
211                         break;
212                 case 0:
213                         return z;
214                 }
215         }
216         return y;
217 }
218
219 #ifdef junk
220
221 int vsfirst(sELEMENT *ary, int len, sELEMENT el)
222 {
223         int x;
224
225         if (!ary || !len)
226                 return ~0;
227         for (x = 0; x != len; ++x)
228                 if (!scmp(ary[x], el))
229                         return x;
230         return ~0;
231 }
232
233 int vslast(sELEMENT *ary, int len, sELEMENT el)
234 {
235         int x = len;
236
237         if (!ary || !len)
238                 return ~0;
239         do {
240                 --x;
241                 if (!scmp(ary[x], el))
242                         return x;
243         } while (x);
244         return ~0;
245 }
246
247 #endif
248
249 int vscmpn(sELEMENT *a, int alen, sELEMENT *b, int blen)
250 {
251         int x, l;
252         int t;
253
254         if (!a && !b)
255                 return 0;
256         if (!a)
257                 return -1;
258         if (!b)
259                 return 1;
260         if (alen > blen)
261                 l = sLen(a);
262         else
263                 l = blen;
264         for (x = 0; x != l; ++x)
265                 if ((t = scmp(a[x], b[x])) != 0)
266                         return t;
267         if (alen > blen)
268                 return 1;
269         if (alen < blen)
270                 return -1;
271         return 0;
272 }
273
274 int vscmp(sELEMENT *a, sELEMENT *b)
275 {
276         return vscmpn(sv(a), sv(b));
277 }
278 #ifdef junk
279 int vsicmpn(sELEMENT *a, int alen, sELEMENT *b, int blen)
280 {
281         int x, l;
282         int t;
283
284         if (!a && !b)
285                 return 0;
286         if (!a)
287                 return -1;
288         if (!b)
289                 return 1;
290         if (alen > blen)
291                 l = sLen(a);
292         else
293                 l = blen;
294         for (x = 0; x != l; ++x)
295                 if (t = sicmp(a[x], b[x]))
296                         return t;
297         if (alen > blen)
298                 return 1;
299         if (alen < blen)
300                 return -1;
301         return 0;
302 }
303
304 int vss(sELEMENT *a, int alen, sELEMENT *b, int blen)
305 {
306         int x;
307
308         if (!a && !b)
309                 return 0;
310         if (!a || !b)
311                 return ~0;
312         if (alen < blen)
313                 return ~0;
314         if (!blen)
315                 return 0;
316         for (x = 0; x != alen - blen; ++x)
317                 if (!vscmpn(a, blen, b, blen))
318                         return x;
319         return ~0;
320 }
321
322 #endif
323
324 int vsscan(sELEMENT *a, int alen, sELEMENT *b, int blen)
325 {
326         int x;
327
328         for (x = 0; x != alen; ++x) {
329                 int z = vsbsearch(b, blen, a[x]);
330
331                 if (z < blen && !scmp(b[z], a[x]))
332                         return x;
333         }
334         return ~0;
335 }
336
337 int vsspan(sELEMENT *a, int alen, sELEMENT *b, int blen)
338 {
339         int x;
340
341         for (x = 0; x != alen; ++x) {
342                 int z = vsbsearch(b, blen, a[x]);
343
344                 if (z == blen || scmp(b[z], a[x]))
345                         break;
346         }
347         return x;
348 }
349
350 #ifdef junk
351
352 sELEMENT *vsread(sELEMENT d, int p, int (*getC)(), void *ptr)
353 {
354         int c;
355
356         if (!d)
357                 d = vsmk(10);
358         c = getC(ptr);
359         if (c == NO_MORE_DATA) {
360                 vsrm(d);
361                 return NULL;
362         } else if (c == '\n')
363                 return d;
364         else {
365                 d = vsset(d, p, c);
366                 p++;
367         }
368         while (c = getC(ptr), c != NO_MORE_DATA && c != '\n') {
369                 d = vsset(d, p, c);
370                 p++;
371         }
372         return d;
373 }
374
375 sELEMENT *vwords(sELEMENT *s, sELEMENT **a, int len, sELEMENT t)
376 {
377         int x;
378
379         if (!s)
380                 s = vsmk(32);
381         else
382                 s = vstrunc(s, 0);
383         for (x = 0; x != len; ++x) {
384                 s = vsncpy(s, sLEN(s), sz(a[x]));
385                 if (a[1])
386                         s = vsadd(s, t);
387         }
388         return s;
389 }
390
391 #endif