File: va.h

package info (click to toggle)
jupp 3.1.38-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 2,420 kB
  • sloc: ansic: 31,382; sh: 4,199; makefile: 431
file content (237 lines) | stat: -rw-r--r-- 8,258 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
/*
 *	Variable length arrays of strings
 *	Copyright
 *		(C) 1992 Joseph H. Allen
 *
 *	This file is part of JOE (Joe's Own Editor)
 */
#ifndef _JOE_VA_H
#define _JOE_VA_H 1

#ifdef EXTERN_B_C
__IDSTRING(rcsid_va_h, "$MirOS: contrib/code/jupp/va.h,v 1.8 2018/01/07 20:32:47 tg Exp $");
#endif

#include "vs.h"

/* Functions and global variable you have to define.  Replace these with
 * macros or defines here if they are not to be actual functions
 */

typedef unsigned char *aELEMENT;

/* aELEMENT adup(); */
#define adup(s) vsdup(s)
/* aELEMENT adel(); */
#define adel(s) vsrm(s)
/* int acmp(); */
#define acmp(a,b) vscmp((a),(b))
/* extern aELEMENT ablank; */
#define ablank NULL
/* extern aELEMENT aterm; */
#define aterm NULL

/************************/
/* Creation/Destruction */
/************************/

/* aELEMENT *vamk(int len);
 * Create a variable length array.  Space for 'len' elements is preallocated.
 */
aELEMENT *vamk(int len);

/* void varm(aELEMENT *vary);
 * Free an array and everything which is in it.  Does nothing if 'vary' is
 * 0.
 */
void varm(aELEMENT *vary);

/********************/
/* Space management */
/********************/

/* int aSIZ(aELEMENT *vary);
 * int aSiz(aELEMENT *vary);
 * Access size part of array.  This int indicates the number of elements which
 * can fit in the array before realloc needs to be called.  It does not include
 * the extra space needed for the terminator and the header.
 *
 * aSIZ returns 0 if you pass it 0.  aSiz does not do this checking,
 * but can be used as an lvalue.
 */
#define aSiz(a) jalloc_siz(a)
#define aSIZ(a) ((a) ? aSiz(a) : 0)

/* int aLEN(aELEMENT *vary);
 * int aLen(aELEMENT *vary);
 * Access length part of array.  This int indicates the number of elements
 * currently in the array (not including the terminator).  This should be
 * used primarily for reading the size of the array.  It can be used for
 * setting the size of the array, but it must be used with care since it
 * does not eliminate elements (if the size decreases) or make sure there's
 * enough room (if the size increases).  See vensure and vtrunc.
 *
 * aLEN return a length of zero if 'vary' is 0.
 * aLen doesn't do this checking, but can be used as an lvalue
 */
#define aLen(a) jalloc_len(a)
#define aLEN(a) ((a) ? aLen(a) : 0)

/* int alen(aELEMENT *ary);
 * Compute length of char or variable length array by searching for termination
 * element.  Returns 0 if 'vary' is 0.
 */
int alen(aELEMENT *ary);

/* aELEMENT *vaensure(aELEMENT *vary, int len);
 * Make sure there's enough space in the array for 'len' elements.  Whenever
 * vaensure reallocs the array, it allocates 25% more than the necessary
 * minimum space in anticipation of future expansion.  If 'vary' is 0,
 * it creates a new array.
 */
aELEMENT *vaensure(aELEMENT *vary, int len);

/* aELEMENT *vazap(aELEMENT *vary, int pos, int n);
 * Destroy n elements from an array beginning at pos.  Is ok if pos/n go
 * past end of array.  This does not change the aLEN() value of the array.
 * This does nothing and returns 0 if 'vary' is 0.  Note that this
 * function does not actually write to the array.  This does not stop if
 * a aterm is encountered.
 */
aELEMENT *vazap(aELEMENT *vary, int pos, int n);

/* aELEMENT *vatrunc(aELEMENT *vary, int len);
 * Truncate array to indicated size.  This zaps or expands with blank elements
 * and sets the LEN() of the array.  A new array is created if 'vary' is 0.
 */
aELEMENT *vatrunc(aELEMENT *vary, int len);

/************************************/
/* Function which write to an array */
/************************************/

/* aELEMENT *vafill(aELEMENT *vary, int pos, aELEMENT el, int len);
 * Set 'len' element of 'vary' beginning at 'pos' to duplications of 'el'.
 * Ok, if pos/len are past end of array.  If 'vary' is 0, a new array is
 * created.
 *
 * This does not zap previous values.  If you need that to happen, call
 * vazap first.  It does move the terminator around properly though.
 */
aELEMENT *vafill(aELEMENT *vary, int pos, aELEMENT el, int len);

/* aELEMENT *vandup(aELEMENT *vary, int pos, aELEMENT *array, int len);
 * Duplicate 'len' elements from 'array' onto 'vary' beginning at position
 * 'pos'.  'array' can be a char array since its length is passed seperately.  A
 * new array is created if 'vary' is 0.
 */
aELEMENT *vandup(aELEMENT *vary, int pos, aELEMENT *array, int len);

/* aELEMENT *vadup(aELEMENT *vary);
 * Duplicate array.  This is just a functionalized version of:
 *
 *   vandup(NULL,0,vary,aLEN(vary));
 *
 * but since you need to be able to refer to this particular function by
 * address often it's given here.
 *
 * (actually, there's bazillions of these simple combinations of the above
 * functions and the macros of the next section.  You'll probably want to make
 * functionalized instances of the ones you use most often - especially since
 * the macros aren't safe).
 */
aELEMENT *vadup(aELEMENT *vary);

/* aELEMENT *vaset(aELEMENT *vary, int pos, aELEMENT element);
 * Set an element in an array.  Any value of 'pos' is valid.  A new array
 * is created if 'vary' is 0.  The previous contents of the position is
 * deleted.    This does not duplicate 'element'.  If you need 'element'
 * duplicated, call: vaset(vary,pos,adup(element));
 */
aELEMENT *_vaset(aELEMENT *vary, int pos, aELEMENT el);

#define vaset(v,p,el)  \
 (!(v) || (p) > aLen(v) || ((p) == aLen(v) && (p) == aSiz(v)) ?  \
  _vaset((v),(p),(el)) \
 : \
  ((p) == aLen(v) ? \
   ((v)[(p)+1] = (v)[p], (v)[p] = (el), aLen(v) = (p)+1, (v)) \
  : \
   (adel((v)[p]), (v)[p] = (el), (v)) \
  ) \
 )

/* aELEMENT *vaadd(aELEMENT *vary, aELEMENT element);
 * Concatenate a single element to the end of 'vary'.  A new array is created
 * if 'vary' is 0.  This does not duplicate element: call
 * vaadd(vary,adup(element));  If you need it duplicated.
 */
#define vaadd(v,el) \
 (!(v) || aLen(v) == aSiz(v) ? \
  _vaset((v), aLEN(v), (el)) \
 : \
  ((v)[aLen(v) + 1] = (v)[aLen(v)], (v)[aLen(v)] = (el), \
   aLen(v) = aLen(v) + 1, (v)) \
 )

/**************************************/
/* Functions which read from an array */
/**************************************/

/* These macros are used to generate the address/size pairs which get
 * passed to the functions of the previous section.
 */

/* { aELEMENT *, int } av(aELEMENT *array);
 * Return array,size pair.  Uses aLEN to get size.
 */
#define av(a) (a), aLEN(a)

/* { aELEMENT *, int } az(aELEMENT *array);
 * Return array,size pair.  Uses alen to get size.
 */
#define az(a) (a), alen(a)

/* { aELEMENT *, int } ac(aELEMENT *array);
 * Return array,size pair.  Uses 'sizeof' to get size.
 */
#define ac(a) (a), (sizeof(a) / sizeof(aELEMENT))

/* { aELEMENT *, int } arest(aELEMENT *vary, int pos);
 * Return array,size pair of rest of array beginning at pos.  If
 * pos is past end of array, gives size of 0.
 */
#define arest(a, p) ((a) + (p)), (((p) > aLEN(a)) ? 0 : aLen(a) - (p))

/* { aELEMENT *, int } apart(aELEMENT *vary, int pos, int len);
 * Return array,size pair of 'len' elements of array beginning with pos.  If
 * pos is past end of array, gives size of 0.  If pos+len is past end of array,
 * returns number of elements to end of array.
 */
#define apart(a, p, l) \
 ((a) + (p)), ((p) >= aLEN(a) ? 0 : ((p) + (l) > aLen(a) ? aLen(a) - (p) : (l)))

/* aELEMENT vaget(aELEMENT *vary, int pos);
 * Get an element from an array.  Any value of pos is valid; if it's past the
 * end of the array or if 'vary' is 0, the terminator is returned.  This
 * does not make a duplicate of the returned element.  If you want that, pass
 * the return value of this to adup.
 */
#define vaget(a, p) ((p) >= aLEN(a) ? aterm : (a)[p])

/*************************/
/* Searching and Sorting */
/*************************/

/* aELEMENT *vasort(aELEMENT *ary, int len)
 * Sort the elements of an array (char or variable length) using qsort().
 */
aELEMENT *vasort(aELEMENT *ary, int len);

/* aELEMENT *vawords(aELEMENT *a, char *s, int len, char *sep, int seplen);
 * Generate list of strings out of words in 's' seperated with the characters
 * in 'sep'.  The characters in 'sep' must be sorted.
 */
aELEMENT *vawords(aELEMENT *a, unsigned char *s, int len, const unsigned char *sep, int seplen);

#endif