/MirOS/dist/jupp/joe-3.1jupp23.tgz
[alioth/jupp.git] / vs.c
1 /* $MirOS: contrib/code/jupp/vs.c,v 1.5 2012/12/22 00:06:16 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         mkssert(vary != NULL);
102         if (pos + len > olen) {
103                 vary[pos + len] = vary[olen];
104                 sLen(vary) = pos + len;
105         }
106         if (pos > olen)
107                 vary = vsfill(vary, olen, sblank, pos - olen);
108         mmove(vary + pos, array, len * sizeof(sELEMENT));
109         return vary;
110 }
111
112 sELEMENT *vsndup(sELEMENT *vary, int pos, sELEMENT *array, int len)
113 {
114         int olen = sLEN(vary), x;
115
116         if (!vary || pos + len > sSIZ(vary))
117                 vary = vsensure(vary, pos + len);
118         if (pos + len > olen) {
119                 vary[pos + len] = vary[olen];
120                 sLen(vary) = pos + len;
121         }
122         if (pos > olen)
123                 vary = vsfill(vary, olen, sblank, pos - olen);
124         for (x = pos; x != len; ++x)
125                 vary[x] = sdup(array[x]);
126         return vary;
127 }
128
129 sELEMENT *vsdup(sELEMENT *vary)
130 {
131         return vsndup(NULL, 0, vary, sLEN(vary));
132 }
133
134 sELEMENT *_vsset(sELEMENT *vary, int pos, sELEMENT el)
135 {
136         if (!vary || pos + 1 > sSIZ(vary))
137                 vary = vsensure(vary, pos + 1);
138         if (pos > sLen(vary)) {
139                 vary = vsfill(vary, sLen(vary), sblank, pos - sLen(vary));
140                 vary[pos + 1] = vary[pos];
141                 vary[pos] = el;
142                 sLen(vary) = pos + 1;
143         } else if (pos == sLen(vary)) {
144                 vary[pos + 1] = vary[pos];
145                 vary[pos] = el;
146                 sLen(vary) = pos + 1;
147         } else {
148                 sdel(vary[pos]);
149                 vary[pos] = el;
150         }
151         return vary;
152 }
153
154 int vsbsearch(sELEMENT *ary, int len, sELEMENT el)
155 {
156         int x, y, z;
157
158         if (!ary || !len)
159                 return 0;
160         y = len;
161         x = 0;
162         z = ~0;
163         while (z != (x + y) / 2) {
164                 z = (x + y) / 2;
165                 switch (scmp(el, ary[z])) {
166                 case 1:
167                         x = z;
168                         break;
169                 case -1:
170                         y = z;
171                         break;
172                 case 0:
173                         return z;
174                 }
175         }
176         return y;
177 }
178
179 int vscmpn(sELEMENT *a, int alen, sELEMENT *b, int blen)
180 {
181         int x, l;
182         int t;
183
184         if (!a && !b)
185                 return 0;
186         if (!a)
187                 return -1;
188         if (!b)
189                 return 1;
190         if (alen > blen)
191                 l = sLen(a);
192         else
193                 l = blen;
194         for (x = 0; x != l; ++x)
195                 if ((t = scmp(a[x], b[x])) != 0)
196                         return t;
197         if (alen > blen)
198                 return 1;
199         if (alen < blen)
200                 return -1;
201         return 0;
202 }
203
204 int vscmp(sELEMENT *a, sELEMENT *b)
205 {
206         return vscmpn(sv(a), sv(b));
207 }
208
209 int vsscan(sELEMENT *a, int alen, sELEMENT *b, int blen)
210 {
211         int x;
212
213         for (x = 0; x != alen; ++x) {
214                 int z = vsbsearch(b, blen, a[x]);
215
216                 if (z < blen && !scmp(b[z], a[x]))
217                         return x;
218         }
219         return ~0;
220 }
221
222 int vsspan(sELEMENT *a, int alen, sELEMENT *b, int blen)
223 {
224         int x;
225
226         /* should not happen */
227         if (!b)
228                 return (0);
229
230         for (x = 0; x != alen; ++x) {
231                 int z = vsbsearch(b, blen, a[x]);
232
233                 if (z == blen || scmp(b[z], a[x]))
234                         break;
235         }
236         return x;
237 }