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
|