use split CVS repo address, like in dietlibc
[alioth/jupp.git] / va.c
1 /*
2  *      Variable length array of strings
3  *      Copyright
4  *              (C) 1992 Joseph H. Allen
5  *
6  *      This file is part of JOE (Joe's Own Editor)
7  */
8 #include "config.h"
9 #include "types.h"
10
11 __RCSID("$MirOS: contrib/code/jupp/va.c,v 1.10 2018/01/07 20:39:33 tg Exp $");
12
13 #include <stdlib.h>
14
15 #include "utils.h"
16 #include "va.h"
17
18 aELEMENT *
19 vamk(int len)
20 {
21         aELEMENT *rv;
22
23         rv = jalloc(NULL, len, sizeof(aELEMENT));
24         rv[0] = aterm;
25         return (rv);
26 }
27
28 void
29 varm(aELEMENT *vary)
30 {
31         if (vary) {
32                 vazap(vary, 0, aLen(vary));
33                 jfree(vary);
34         }
35 }
36
37 int alen(aELEMENT *ary)
38 {
39         aELEMENT *beg = ary;
40
41         if (!ary)
42                 return (0);
43
44         while (acmp(*ary, aterm))
45                 ++ary;
46         return (ary - beg);
47 }
48
49 aELEMENT *
50 vaensure(aELEMENT *vary, int len)
51 {
52         aELEMENT *rv;
53
54         if (vary && len > aSiz(vary))
55                 len += (len >> 2);
56         rv = jalloc(vary, len, sizeof(aELEMENT));
57         if (!vary)
58                 rv[0] = aterm;
59         return (rv);
60 }
61
62 aELEMENT *vazap(aELEMENT *vary, int pos, int n)
63 {
64         if (vary) {
65                 int x;
66
67                 if (pos < aLen(vary)) {
68                         if (pos + n <= aLen(vary)) {
69                                 for (x = pos; x != pos + n; ++x)
70                                         adel(vary[x]);
71                         } else {
72                                 for (x = pos; x != aLen(vary); ++x)
73                                         adel(vary[x]);
74                         }
75                 }
76         }
77         return vary;
78 }
79
80 aELEMENT *vatrunc(aELEMENT *vary, int len)
81 {
82         if (!vary || len > aLEN(vary))
83                 vary = vaensure(vary, len);
84         if (len < aLen(vary)) {
85                 vary = vazap(vary, len, aLen(vary) - len);
86                 vary[len] = vary[aLen(vary)];
87                 aLen(vary) = len;
88         } else if (len > aLen(vary)) {
89                 vary = vafill(vary, aLen(vary), ablank, len - aLen(vary));
90         }
91         return vary;
92 }
93
94 aELEMENT *vafill(aELEMENT *vary, int pos, aELEMENT el, int len)
95 {
96         int olen = aLEN(vary), x;
97
98         if (!vary || pos + len > aSIZ(vary))
99                 vary = vaensure(vary, pos + len);
100         if (pos + len > olen) {
101                 vary[pos + len] = vary[olen];
102                 aLen(vary) = pos + len;
103         }
104         for (x = pos; x != pos + len; ++x)
105                 vary[x] = adup(el);
106         if (pos > olen)
107                 vary = vafill(vary, pos, ablank, pos - olen);
108         return vary;
109 }
110
111 aELEMENT *vandup(aELEMENT *vary, int pos, aELEMENT *array, int len)
112 {
113         int olen = aLEN(vary), x;
114
115         if (!vary || pos + len > aSIZ(vary))
116                 vary = vaensure(vary, pos + len);
117         if (pos + len > olen) {
118                 vary[pos + len] = vary[olen];
119                 aLen(vary) = pos + len;
120         }
121         if (pos > olen)
122                 vary = vafill(vary, olen, ablank, pos - olen);
123         for (x = 0; x != len; ++x)
124                 vary[x + pos] = adup(array[x]);
125         return vary;
126 }
127
128 aELEMENT *vadup(aELEMENT *vary)
129 {
130         return vandup(NULL, 0, vary, aLEN(vary));
131 }
132
133 aELEMENT *_vaset(aELEMENT *vary, int pos, aELEMENT el)
134 {
135         if (!vary || pos + 1 > aSIZ(vary))
136                 vary = vaensure(vary, pos + 1);
137         if (pos > aLen(vary)) {
138                 vary = vafill(vary, aLen(vary), ablank, pos - aLen(vary));
139                 vary[pos + 1] = vary[pos];
140                 vary[pos] = el;
141                 aLen(vary) = pos + 1;
142         } else if (pos == aLen(vary)) {
143                 vary[pos + 1] = vary[pos];
144                 vary[pos] = el;
145                 aLen(vary) = pos + 1;
146         } else {
147                 adel(vary[pos]);
148                 vary[pos] = el;
149         }
150         return vary;
151 }
152
153 static int _acmp(aELEMENT *a, aELEMENT *b)
154 {
155         return acmp(*a, *b);
156 }
157
158 aELEMENT *vasort(aELEMENT *ary, int len)
159 {
160         if (ary && len)
161                 qsort(ary, len, sizeof(aELEMENT),
162                     (int (*)(const void *, const void *))_acmp);
163         return ary;
164 }
165
166 aELEMENT *
167 vawords(aELEMENT *a, unsigned char *s, int len,
168     const unsigned char *sep, int seplen)
169 {
170         int x;
171
172         if (!a)
173                 a = vamk(10);
174         else
175                 a = vatrunc(a, 0);
176  loop:
177         x = vsspan(s, len, sep, seplen);
178         s += x;
179         len -= x;
180         if (len) {
181                 x = vsscan(s, len, sep, seplen);
182                 if (x != ~0) {
183                         a = vaadd(a, vsncpy(vsmk(x), 0, s, x));
184                         s += x;
185                         len -= x;
186                         if (len)
187                                 goto loop;
188                 } else
189                         a = vaadd(a, vsncpy(vsmk(len), 0, s, len));
190         }
191         return a;
192 }