cstring.h 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. /* two template types: STRING(t) which defines a pascal-style string
  2. * of element (t) [STRING(char) is the closest to the pascal string],
  3. * and ANCHOR(t) which defines a baseplate that a linked list can be
  4. * built up from. [The linked list /must/ contain a ->next pointer
  5. * for linking the list together with.]
  6. */
  7. #ifndef _CSTRING_D
  8. #define _CSTRING_D
  9. #include <string.h>
  10. #include <stdlib.h>
  11. #ifndef __WITHOUT_AMALLOC
  12. # include "amalloc.h"
  13. #endif
  14. /* expandable Pascal-style string.
  15. */
  16. #define STRING(type) struct { type *text; int size, alloc; }
  17. #define CREATE(x) ( (T(x) = (void*)0), (S(x) = (x).alloc = 0) )
  18. #define EXPAND(x) (S(x)++)[(S(x) < (x).alloc) \
  19. ? (T(x)) \
  20. : (T(x) = T(x) ? realloc(T(x), sizeof T(x)[0] * ((x).alloc += 100)) \
  21. : malloc(sizeof T(x)[0] * ((x).alloc += 100)) )]
  22. #define DELETE(x) ALLOCATED(x) ? (free(T(x)), S(x) = (x).alloc = 0) \
  23. : ( S(x) = 0 )
  24. #define CLIP(t,i,sz) \
  25. S(t) -= ( ((i) >= 0) && ((sz) > 0) && (((i)+(sz)) <= S(t)) ) ? \
  26. (memmove(&T(t)[i], &T(t)[i+sz], (S(t)-(i+sz)+1)*sizeof(T(t)[0])), \
  27. (sz)) : 0
  28. #define RESERVE(x, sz) T(x) = ((x).alloc > S(x) + (sz) \
  29. ? T(x) \
  30. : T(x) \
  31. ? realloc(T(x), sizeof T(x)[0] * ((x).alloc = 100+(sz)+S(x))) \
  32. : malloc(sizeof T(x)[0] * ((x).alloc = 100+(sz)+S(x))))
  33. #define SUFFIX(t,p,sz) \
  34. memcpy(((S(t) += (sz)) - (sz)) + \
  35. (T(t) = T(t) ? realloc(T(t), sizeof T(t)[0] * ((t).alloc += sz)) \
  36. : malloc(sizeof T(t)[0] * ((t).alloc += sz))), \
  37. (p), sizeof(T(t)[0])*(sz))
  38. #define PREFIX(t,p,sz) \
  39. RESERVE( (t), (sz) ); \
  40. if ( S(t) ) { memmove(T(t)+(sz), T(t), S(t)); } \
  41. memcpy( T(t), (p), (sz) ); \
  42. S(t) += (sz)
  43. /* reference-style links (and images) are stored in an array
  44. */
  45. #define T(x) (x).text
  46. #define S(x) (x).size
  47. #define ALLOCATED(x) (x).alloc
  48. /* abstract anchor type that defines a list base
  49. * with a function that attaches an element to
  50. * the end of the list.
  51. *
  52. * the list base field is named .text so that the T()
  53. * macro will work with it.
  54. */
  55. #define ANCHOR(t) struct { t *text, *end; }
  56. #define E(t) ((t).end)
  57. #define ATTACH(t, p) ( T(t) ? ( (E(t)->next = (p)), (E(t) = (p)) ) \
  58. : ( (T(t) = E(t) = (p)) ) )
  59. typedef STRING(char) Cstring;
  60. extern void Csputc(int, Cstring *);
  61. extern int Csprintf(Cstring *, char *, ...);
  62. extern int Cswrite(Cstring *, char *, int);
  63. #endif/*_CSTRING_D*/