1*7dd7cddfSDavid du Colombier /* 2*7dd7cddfSDavid du Colombier * Expanding strings 3*7dd7cddfSDavid du Colombier */ 4*7dd7cddfSDavid du Colombier /* $Id$ */ 5*7dd7cddfSDavid du Colombier 6*7dd7cddfSDavid du Colombier #define X_EXTRA 8 /* this many extra bytes in X string */ 7*7dd7cddfSDavid du Colombier 8*7dd7cddfSDavid du Colombier #if 0 /* Usage */ 9*7dd7cddfSDavid du Colombier XString xs; 10*7dd7cddfSDavid du Colombier char *xp; 11*7dd7cddfSDavid du Colombier 12*7dd7cddfSDavid du Colombier Xinit(xs, xp, 128, ATEMP); /* allocate initial string */ 13*7dd7cddfSDavid du Colombier while ((c = generate()) { 14*7dd7cddfSDavid du Colombier Xcheck(xs, xp); /* expand string if neccessary */ 15*7dd7cddfSDavid du Colombier Xput(xs, xp, c); /* add character */ 16*7dd7cddfSDavid du Colombier } 17*7dd7cddfSDavid du Colombier return Xclose(xs, xp); /* resize string */ 18*7dd7cddfSDavid du Colombier /* 19*7dd7cddfSDavid du Colombier * NOTE: 20*7dd7cddfSDavid du Colombier * The Xcheck and Xinit macros have a magic + X_EXTRA in the lengths. 21*7dd7cddfSDavid du Colombier * This is so that you can put up to X_EXTRA characters in a XString 22*7dd7cddfSDavid du Colombier * before calling Xcheck. (See yylex in lex.c) 23*7dd7cddfSDavid du Colombier */ 24*7dd7cddfSDavid du Colombier #endif /* 0 */ 25*7dd7cddfSDavid du Colombier 26*7dd7cddfSDavid du Colombier typedef struct XString { 27*7dd7cddfSDavid du Colombier char *end, *beg; /* end, begin of string */ 28*7dd7cddfSDavid du Colombier size_t len; /* length */ 29*7dd7cddfSDavid du Colombier Area *areap; /* area to allocate/free from */ 30*7dd7cddfSDavid du Colombier } XString; 31*7dd7cddfSDavid du Colombier 32*7dd7cddfSDavid du Colombier typedef char * XStringP; 33*7dd7cddfSDavid du Colombier 34*7dd7cddfSDavid du Colombier /* initialize expandable string */ 35*7dd7cddfSDavid du Colombier #define Xinit(xs, xp, length, area) do { \ 36*7dd7cddfSDavid du Colombier (xs).len = length; \ 37*7dd7cddfSDavid du Colombier (xs).areap = (area); \ 38*7dd7cddfSDavid du Colombier (xs).beg = alloc((xs).len + X_EXTRA, (xs).areap); \ 39*7dd7cddfSDavid du Colombier (xs).end = (xs).beg + (xs).len; \ 40*7dd7cddfSDavid du Colombier xp = (xs).beg; \ 41*7dd7cddfSDavid du Colombier } while (0) 42*7dd7cddfSDavid du Colombier 43*7dd7cddfSDavid du Colombier /* stuff char into string */ 44*7dd7cddfSDavid du Colombier #define Xput(xs, xp, c) (*xp++ = (c)) 45*7dd7cddfSDavid du Colombier 46*7dd7cddfSDavid du Colombier /* check if there are at least n bytes left */ 47*7dd7cddfSDavid du Colombier #define XcheckN(xs, xp, n) do { \ 48*7dd7cddfSDavid du Colombier int more = ((xp) + (n)) - (xs).end; \ 49*7dd7cddfSDavid du Colombier if (more > 0) \ 50*7dd7cddfSDavid du Colombier xp = Xcheck_grow_(&xs, xp, more); \ 51*7dd7cddfSDavid du Colombier } while (0) 52*7dd7cddfSDavid du Colombier 53*7dd7cddfSDavid du Colombier /* check for overflow, expand string */ 54*7dd7cddfSDavid du Colombier #define Xcheck(xs, xp) XcheckN(xs, xp, 1) 55*7dd7cddfSDavid du Colombier 56*7dd7cddfSDavid du Colombier /* free string */ 57*7dd7cddfSDavid du Colombier #define Xfree(xs, xp) afree((void*) (xs).beg, (xs).areap) 58*7dd7cddfSDavid du Colombier 59*7dd7cddfSDavid du Colombier /* close, return string */ 60*7dd7cddfSDavid du Colombier #define Xclose(xs, xp) (char*) aresize((void*)(xs).beg, \ 61*7dd7cddfSDavid du Colombier (size_t)((xp) - (xs).beg), (xs).areap) 62*7dd7cddfSDavid du Colombier /* begin of string */ 63*7dd7cddfSDavid du Colombier #define Xstring(xs, xp) ((xs).beg) 64*7dd7cddfSDavid du Colombier 65*7dd7cddfSDavid du Colombier #define Xnleft(xs, xp) ((xs).end - (xp)) /* may be less than 0 */ 66*7dd7cddfSDavid du Colombier #define Xlength(xs, xp) ((xp) - (xs).beg) 67*7dd7cddfSDavid du Colombier #define Xsize(xs, xp) ((xs).end - (xs).beg) 68*7dd7cddfSDavid du Colombier #define Xsavepos(xs, xp) ((xp) - (xs).beg) 69*7dd7cddfSDavid du Colombier #define Xrestpos(xs, xp, n) ((xs).beg + (n)) 70*7dd7cddfSDavid du Colombier 71*7dd7cddfSDavid du Colombier char * Xcheck_grow_ ARGS((XString *xsp, char *xp, int more)); 72*7dd7cddfSDavid du Colombier 73*7dd7cddfSDavid du Colombier /* 74*7dd7cddfSDavid du Colombier * expandable vector of generic pointers 75*7dd7cddfSDavid du Colombier */ 76*7dd7cddfSDavid du Colombier 77*7dd7cddfSDavid du Colombier typedef struct XPtrV { 78*7dd7cddfSDavid du Colombier void **cur; /* next avail pointer */ 79*7dd7cddfSDavid du Colombier void **beg, **end; /* begin, end of vector */ 80*7dd7cddfSDavid du Colombier } XPtrV; 81*7dd7cddfSDavid du Colombier 82*7dd7cddfSDavid du Colombier #define XPinit(x, n) do { \ 83*7dd7cddfSDavid du Colombier register void **vp__; \ 84*7dd7cddfSDavid du Colombier vp__ = (void**) alloc(sizeofN(void*, n), ATEMP); \ 85*7dd7cddfSDavid du Colombier (x).cur = (x).beg = vp__; \ 86*7dd7cddfSDavid du Colombier (x).end = vp__ + n; \ 87*7dd7cddfSDavid du Colombier } while (0) 88*7dd7cddfSDavid du Colombier 89*7dd7cddfSDavid du Colombier #define XPput(x, p) do { \ 90*7dd7cddfSDavid du Colombier if ((x).cur >= (x).end) { \ 91*7dd7cddfSDavid du Colombier int n = XPsize(x); \ 92*7dd7cddfSDavid du Colombier (x).beg = (void**) aresize((void*) (x).beg, \ 93*7dd7cddfSDavid du Colombier sizeofN(void*, n*2), ATEMP); \ 94*7dd7cddfSDavid du Colombier (x).cur = (x).beg + n; \ 95*7dd7cddfSDavid du Colombier (x).end = (x).cur + n; \ 96*7dd7cddfSDavid du Colombier } \ 97*7dd7cddfSDavid du Colombier *(x).cur++ = (p); \ 98*7dd7cddfSDavid du Colombier } while (0) 99*7dd7cddfSDavid du Colombier 100*7dd7cddfSDavid du Colombier #define XPptrv(x) ((x).beg) 101*7dd7cddfSDavid du Colombier #define XPsize(x) ((x).cur - (x).beg) 102*7dd7cddfSDavid du Colombier 103*7dd7cddfSDavid du Colombier #define XPclose(x) (void**) aresize((void*)(x).beg, \ 104*7dd7cddfSDavid du Colombier sizeofN(void*, XPsize(x)), ATEMP) 105*7dd7cddfSDavid du Colombier 106*7dd7cddfSDavid du Colombier #define XPfree(x) afree((void*) (x).beg, ATEMP) 107