~mirabilos/jupp/trunk

1 by tg
Initial revision
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"
591 by tg
redo dynamic string memory foo to get rid of those ugly casts
9
#include "types.h"
1 by tg
Initial revision
10
592 by tg
tiny optimisations
11
__RCSID("$MirOS: contrib/code/jupp/va.c,v 1.10 2018/01/07 20:39:33 tg Exp $");
473 by tg
overhaul the way includes work; give jupp proper RCS IDs
12
1 by tg
Initial revision
13
#include <stdlib.h>
14
15
#include "utils.h"
16
#include "va.h"
17
591 by tg
redo dynamic string memory foo to get rid of those ugly casts
18
aELEMENT *
19
vamk(int len)
1 by tg
Initial revision
20
{
591 by tg
redo dynamic string memory foo to get rid of those ugly casts
21
	aELEMENT *rv;
1 by tg
Initial revision
22
591 by tg
redo dynamic string memory foo to get rid of those ugly casts
23
	rv = jalloc(NULL, len, sizeof(aELEMENT));
24
	rv[0] = aterm;
25
	return (rv);
1 by tg
Initial revision
26
}
27
591 by tg
redo dynamic string memory foo to get rid of those ugly casts
28
void
29
varm(aELEMENT *vary)
1 by tg
Initial revision
30
{
31
	if (vary) {
32
		vazap(vary, 0, aLen(vary));
591 by tg
redo dynamic string memory foo to get rid of those ugly casts
33
		jfree(vary);
1 by tg
Initial revision
34
	}
35
}
36
37
int alen(aELEMENT *ary)
38
{
592 by tg
tiny optimisations
39
	aELEMENT *beg = ary;
40
41
	if (!ary)
42
		return (0);
43
44
	while (acmp(*ary, aterm))
45
		++ary;
46
	return (ary - beg);
1 by tg
Initial revision
47
}
48
591 by tg
redo dynamic string memory foo to get rid of those ugly casts
49
aELEMENT *
50
vaensure(aELEMENT *vary, int len)
1 by tg
Initial revision
51
{
591 by tg
redo dynamic string memory foo to get rid of those ugly casts
52
	aELEMENT *rv;
53
54
	if (vary && len > aSiz(vary))
55
		len += (len >> 2);
56
	rv = jalloc(vary, len, sizeof(aELEMENT));
1 by tg
Initial revision
57
	if (!vary)
591 by tg
redo dynamic string memory foo to get rid of those ugly casts
58
		rv[0] = aterm;
59
	return (rv);
1 by tg
Initial revision
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
{
592 by tg
tiny optimisations
160
	if (ary && len)
161
		qsort(ary, len, sizeof(aELEMENT),
162
		    (int (*)(const void *, const void *))_acmp);
1 by tg
Initial revision
163
	return ary;
164
}
165
576 by tg
merge fixes from gitlab branch; highlights:
166
aELEMENT *
167
vawords(aELEMENT *a, unsigned char *s, int len,
168
    const unsigned char *sep, int seplen)
1 by tg
Initial revision
169
{
170
	int x;
171
172
	if (!a)
173
		a = vamk(10);
174
	else
175
		a = vatrunc(a, 0);
542 by tg
label indent; small tweaks while here
176
 loop:
1 by tg
Initial revision
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
}