File indexing completed on 2024-04-28 11:21:06
0001 /* two template types: STRING(t) which defines a pascal-style string 0002 * of element (t) [STRING(char) is the closest to the pascal string], 0003 * and ANCHOR(t) which defines a baseplate that a linked list can be 0004 * built up from. [The linked list /must/ contain a ->next pointer 0005 * for linking the list together with.] 0006 */ 0007 #ifndef _CSTRING_D 0008 #define _CSTRING_D 0009 0010 #include <string.h> 0011 #include <stdlib.h> 0012 0013 #ifndef __WITHOUT_AMALLOC 0014 # include "amalloc.h" 0015 #endif 0016 0017 /* expandable Pascal-style string. 0018 */ 0019 #define STRING(type) struct { type *text; int size, alloc; } 0020 0021 #define CREATE(x) ( (T(x) = (void*)0), (S(x) = (x).alloc = 0) ) 0022 #define EXPAND(x) (S(x)++)[(S(x) < (x).alloc) \ 0023 ? (T(x)) \ 0024 : (T(x) = T(x) ? realloc(T(x), sizeof T(x)[0] * ((x).alloc += 100)) \ 0025 : malloc(sizeof T(x)[0] * ((x).alloc += 100)) )] 0026 0027 #define DELETE(x) ALLOCATED(x) ? (free(T(x)), S(x) = (x).alloc = 0) \ 0028 : ( S(x) = 0 ) 0029 #define CLIP(t,i,sz) \ 0030 S(t) -= ( ((i) >= 0) && ((sz) > 0) && (((i)+(sz)) <= S(t)) ) ? \ 0031 (memmove(&T(t)[i], &T(t)[i+sz], (S(t)-(i+sz)+1)*sizeof(T(t)[0])), \ 0032 (sz)) : 0 0033 0034 #define RESERVE(x, sz) T(x) = ((x).alloc > S(x) + (sz) \ 0035 ? T(x) \ 0036 : T(x) \ 0037 ? realloc(T(x), sizeof T(x)[0] * ((x).alloc = 100+(sz)+S(x))) \ 0038 : malloc(sizeof T(x)[0] * ((x).alloc = 100+(sz)+S(x)))) 0039 #define SUFFIX(t,p,sz) \ 0040 memcpy(((S(t) += (sz)) - (sz)) + \ 0041 (T(t) = T(t) ? realloc(T(t), sizeof T(t)[0] * ((t).alloc += sz)) \ 0042 : malloc(sizeof T(t)[0] * ((t).alloc += sz))), \ 0043 (p), sizeof(T(t)[0])*(sz)) 0044 0045 #define PREFIX(t,p,sz) \ 0046 RESERVE( (t), (sz) ); \ 0047 if ( S(t) ) { memmove(T(t)+(sz), T(t), S(t)); } \ 0048 memcpy( T(t), (p), (sz) ); \ 0049 S(t) += (sz) 0050 0051 /* reference-style links (and images) are stored in an array 0052 */ 0053 #define T(x) (x).text 0054 #define S(x) (x).size 0055 #define ALLOCATED(x) (x).alloc 0056 0057 /* abstract anchor type that defines a list base 0058 * with a function that attaches an element to 0059 * the end of the list. 0060 * 0061 * the list base field is named .text so that the T() 0062 * macro will work with it. 0063 */ 0064 #define ANCHOR(t) struct { t *text, *end; } 0065 #define E(t) ((t).end) 0066 0067 #define ATTACH(t, p) ( T(t) ? ( (E(t)->next = (p)), (E(t) = (p)) ) \ 0068 : ( (T(t) = E(t) = (p)) ) ) 0069 0070 typedef STRING(char) Cstring; 0071 0072 extern void Csputc(int, Cstring *); 0073 extern int Csprintf(Cstring *, char *, ...); 0074 extern int Cswrite(Cstring *, char *, int); 0075 0076 #endif/*_CSTRING_D*/