joe-3.1jupp31.tgz (die zweite Klappeā€¦)
[alioth/jupp.git] / va.h
1 /* $MirOS: contrib/code/jupp/va.h,v 1.3 2012/06/08 16:55:29 tg Exp $ */
2 /*
3  *      Variable length arrays of strings
4  *      Copyright
5  *              (C) 1992 Joseph H. Allen
6  *
7  *      This file is part of JOE (Joe's Own Editor)
8  */
9 #ifndef _JOE_VA_H
10 #define _JOE_VA_H 1
11
12 #include "config.h"
13
14 #include "vs.h"
15
16 /* Functions and global variable you have to define.  Replace these with
17  * macros or defines here if they are not to be actual functions
18  */
19
20 typedef unsigned char *aELEMENT;
21
22 /* aELEMENT adup(); */
23 #define adup(s) vsdup(s)
24 /* aELEMENT adel(); */
25 #define adel(s) vsrm(s)
26 /* int acmp(); */
27 #define acmp(a,b) vscmp((a),(b))
28 /* extern aELEMENT ablank; */
29 #define ablank NULL
30 /* extern aELEMENT aterm; */
31 #define aterm NULL
32
33 /************************/
34 /* Creation/Destruction */
35 /************************/
36
37 /* aELEMENT *vamk(int len);
38  * Create a variable length array.  Space for 'len' elements is preallocated.
39  */
40 aELEMENT *vamk PARAMS((int len));
41
42 /* void varm(aELEMENT *vary);
43  * Free an array and everything which is in it.  Does nothing if 'vary' is
44  * 0.
45  */
46 void varm PARAMS((aELEMENT *vary));
47
48 /********************/
49 /* Space management */
50 /********************/
51
52 /* int aSIZ(aELEMENT *vary);
53  * int aSiz(aELEMENT *vary);
54  * Access size part of array.  This int indicates the number of elements which
55  * can fit in the array before realloc needs to be called.  It does not include
56  * the extra space needed for the terminator and the header.
57  *
58  * aSIZ returns 0 if you pass it 0.  aSiz does not do this checking,
59  * but can be used as an lvalue.
60  */
61 #define aSIZ(a) ((a) ? *((int *)(a) - 2) : 0)
62 #define aSiz(a) (*((int *)(a) - 2))
63
64 /* int aLEN(aELEMENT *vary);
65  * int aLen(aELEMENT *vary);
66  * Access length part of array.  This int indicates the number of elements
67  * currently in the array (not including the terminator).  This should be
68  * used primarily for reading the size of the array.  It can be used for
69  * setting the size of the array, but it must be used with care since it
70  * does not eliminate elements (if the size decreases) or make sure there's
71  * enough room (if the size increases).  See vensure and vtrunc.
72  *
73  * aLEN return a length of zero if 'vary' is 0.
74  * aLen doesn't do this checking, but can be used as an lvalue
75  */
76 #define aLEN(a) ((a) ? *((int *)(a) - 1) : 0)
77 #define aLen(a) (*((int *)(a) - 1))
78
79 /* int alen(aELEMENT *ary);
80  * Compute length of char or variable length array by searching for termination
81  * element.  Returns 0 if 'vary' is 0.
82  */
83 int alen PARAMS((aELEMENT *ary));
84
85 /* aELEMENT *vaensure(aELEMENT *vary, int len);
86  * Make sure there's enough space in the array for 'len' elements.  Whenever
87  * vaensure reallocs the array, it allocates 25% more than the necessary
88  * minimum space in anticipation of future expansion.  If 'vary' is 0,
89  * it creates a new array.
90  */
91 aELEMENT *vaensure PARAMS((aELEMENT *vary, int len));
92
93 /* aELEMENT *vazap(aELEMENT *vary, int pos, int n);
94  * Destroy n elements from an array beginning at pos.  Is ok if pos/n go
95  * past end of array.  This does not change the aLEN() value of the array.
96  * This does nothing and returns 0 if 'vary' is 0.  Note that this
97  * function does not actually write to the array.  This does not stop if
98  * a aterm is encountered.
99  */
100 aELEMENT *vazap PARAMS((aELEMENT *vary, int pos, int n));
101
102 /* aELEMENT *vatrunc(aELEMENT *vary, int len);
103  * Truncate array to indicated size.  This zaps or expands with blank elements
104  * and sets the LEN() of the array.  A new array is created if 'vary' is 0.
105  */
106 aELEMENT *vatrunc PARAMS((aELEMENT *vary, int len));
107
108 /************************************/
109 /* Function which write to an array */
110 /************************************/
111
112 /* aELEMENT *vafill(aELEMENT *vary, int pos, aELEMENT el, int len);
113  * Set 'len' element of 'vary' beginning at 'pos' to duplications of 'el'.
114  * Ok, if pos/len are past end of array.  If 'vary' is 0, a new array is
115  * created.
116  *
117  * This does not zap previous values.  If you need that to happen, call
118  * vazap first.  It does move the terminator around properly though.
119  */
120 aELEMENT *vafill PARAMS((aELEMENT *vary, int pos, aELEMENT el, int len));
121
122 /* aELEMENT *vandup(aELEMENT *vary, int pos, aELEMENT *array, int len);
123  * Duplicate 'len' elements from 'array' onto 'vary' beginning at position
124  * 'pos'.  'array' can be a char array since its length is passed seperately.  A
125  * new array is created if 'vary' is 0.
126  */
127 aELEMENT *vandup PARAMS((aELEMENT *vary, int pos, aELEMENT *array, int len));
128
129 /* aELEMENT *vadup(aELEMENT *vary);
130  * Duplicate array.  This is just a functionalized version of:
131  *
132  *   vandup(NULL,0,vary,aLEN(vary));
133  *
134  * but since you need to be able to refer to this particular function by
135  * address often it's given here.
136  *
137  * (actually, there's bazillions of these simple combinations of the above
138  * functions and the macros of the next section.  You'll probably want to make
139  * functionalized instances of the ones you use most often - especially since
140  * the macros aren't safe).
141  */
142 aELEMENT *vadup PARAMS((aELEMENT *vary));
143
144 /* aELEMENT *vaset(aELEMENT *vary, int pos, aELEMENT element);
145  * Set an element in an array.  Any value of 'pos' is valid.  A new array
146  * is created if 'vary' is 0.  The previous contents of the position is
147  * deleted.    This does not duplicate 'element'.  If you need 'element'
148  * duplicated, call: vaset(vary,pos,adup(element));
149  */
150 aELEMENT *_vaset PARAMS((aELEMENT *vary, int pos, aELEMENT el));
151
152 #define vaset(v,p,el)  \
153  (!(v) || (p) > aLen(v) || ((p) == aLen(v) && (p) == aSiz(v)) ?  \
154   _vaset((v),(p),(el)) \
155  : \
156   ((p) == aLen(v) ? \
157    ((v)[(p)+1] = (v)[p], (v)[p] = (el), aLen(v) = (p)+1, (v)) \
158   : \
159    (adel((v)[p]), (v)[p] = (el), (v)) \
160   ) \
161  )
162
163 /* aELEMENT *vaadd(aELEMENT *vary, aELEMENT element);
164  * Concatenate a single element to the end of 'vary'.  A new array is created
165  * if 'vary' is 0.  This does not duplicate element: call
166  * vaadd(vary,adup(element));  If you need it duplicated.
167  */
168 #define vaadd(v,el) \
169  (!(v) || aLen(v) == aSiz(v) ? \
170   _vaset((v), aLEN(v), (el)) \
171  : \
172   ((v)[aLen(v) + 1] = (v)[aLen(v)], (v)[aLen(v)] = (el), \
173    aLen(v) = aLen(v) + 1, (v)) \
174  )
175
176 /**************************************/
177 /* Functions which read from an array */
178 /**************************************/
179
180 /* These macros are used to generate the address/size pairs which get
181  * passed to the functions of the previous section.
182  */
183
184 /* { aELEMENT *, int } av(aELEMENT *array);
185  * Return array,size pair.  Uses aLEN to get size.
186  */
187 #define av(a) (a), aLEN(a)
188
189 /* { aELEMENT *, int } az(aELEMENT *array);
190  * Return array,size pair.  Uses alen to get size.
191  */
192 #define az(a) (a), alen(a)
193
194 /* { aELEMENT *, int } ac(aELEMENT *array);
195  * Return array,size pair.  Uses 'sizeof' to get size.
196  */
197 #define ac(a) (a), (sizeof(a) / sizeof(aELEMENT))
198
199 /* { aELEMENT *, int } arest(aELEMENT *vary, int pos);
200  * Return array,size pair of rest of array beginning at pos.  If
201  * pos is past end of array, gives size of 0.
202  */
203 #define arest(a, p) ((a) + (p)), (((p) > aLEN(a)) ? 0 : aLen(a) - (p))
204
205 /* { aELEMENT *, int } apart(aELEMENT *vary, int pos, int len);
206  * Return array,size pair of 'len' elements of array beginning with pos.  If
207  * pos is past end of array, gives size of 0.  If pos+len is past end of array,
208  * returns number of elements to end of array.
209  */
210 #define apart(a, p, l) \
211  ((a) + (p)), ((p) >= aLEN(a) ? 0 : ((p) + (l) > aLen(a) ? aLen(a) - (p) : (l)))
212
213 /* aELEMENT vaget(aELEMENT *vary, int pos);
214  * Get an element from an array.  Any value of pos is valid; if it's past the
215  * end of the array or if 'vary' is 0, the terminator is returned.  This
216  * does not make a duplicate of the returned element.  If you want that, pass
217  * the return value of this to adup.
218  */
219 #define vaget(a, p) ((p) >= aLEN(a) ? aterm : (a)[p])
220
221 /*************************/
222 /* Searching and Sorting */
223 /*************************/
224
225 /* aELEMENT *vasort(aELEMENT *ary, int len)
226  * Sort the elements of an array (char or variable length) using qsort().
227  */
228 aELEMENT *vasort PARAMS((aELEMENT *ary, int len));
229
230 /* aELEMENT *vawords(aELEMENT *a, char *s, int len, char *sep, int seplen);
231  * Generate list of strings out of words in 's' seperated with the characters
232  * in 'sep'.  The characters in 'sep' must be sorted.
233  */
234 aELEMENT *vawords PARAMS((aELEMENT *a, unsigned char *s, int len, unsigned char *sep, int seplen));
235
236 #endif