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*/