forked from Orc/discount
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cstring.h
76 lines (63 loc) · 2.35 KB
/
cstring.h
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
/* two template types: STRING(t) which defines a pascal-style string
* of element (t) [STRING(char) is the closest to the pascal string],
* and ANCHOR(t) which defines a baseplate that a linked list can be
* built up from. [The linked list /must/ contain a ->next pointer
* for linking the list together with.]
*/
#ifndef _CSTRING_D
#define _CSTRING_D
#include <string.h>
#include <stdlib.h>
#ifndef __WITHOUT_AMALLOC
# include "amalloc.h"
#endif
/* expandable Pascal-style string.
*/
#define STRING(type) struct { type *text; int size, alloc; }
#define CREATE(x) ( (T(x) = (void*)0), (S(x) = (x).alloc = 0) )
#define EXPAND(x) (S(x)++)[(S(x) < (x).alloc) \
? (T(x)) \
: (T(x) = T(x) ? realloc(T(x), sizeof T(x)[0] * ((x).alloc += 100)) \
: malloc(sizeof T(x)[0] * ((x).alloc += 100)) )]
#define DELETE(x) ALLOCATED(x) ? (free(T(x)), S(x) = (x).alloc = 0) \
: ( S(x) = 0 )
#define CLIP(t,i,sz) \
S(t) -= ( ((i) >= 0) && ((sz) > 0) && (((i)+(sz)) <= S(t)) ) ? \
(memmove(&T(t)[i], &T(t)[i+sz], (S(t)-(i+sz)+1)*sizeof(T(t)[0])), \
(sz)) : 0
#define RESERVE(x, sz) T(x) = ((x).alloc > S(x) + (sz) \
? T(x) \
: T(x) \
? realloc(T(x), sizeof T(x)[0] * ((x).alloc = 100+(sz)+S(x))) \
: malloc(sizeof T(x)[0] * ((x).alloc = 100+(sz)+S(x))))
#define SUFFIX(t,p,sz) \
memcpy(((S(t) += (sz)) - (sz)) + \
(T(t) = T(t) ? realloc(T(t), sizeof T(t)[0] * ((t).alloc += sz)) \
: malloc(sizeof T(t)[0] * ((t).alloc += sz))), \
(p), sizeof(T(t)[0])*(sz))
#define PREFIX(t,p,sz) \
RESERVE( (t), (sz) ); \
if ( S(t) ) { memmove(T(t)+(sz), T(t), S(t)); } \
memcpy( T(t), (p), (sz) ); \
S(t) += (sz)
/* reference-style links (and images) are stored in an array
*/
#define T(x) (x).text
#define S(x) (x).size
#define ALLOCATED(x) (x).alloc
/* abstract anchor type that defines a list base
* with a function that attaches an element to
* the end of the list.
*
* the list base field is named .text so that the T()
* macro will work with it.
*/
#define ANCHOR(t) struct { t *text, *end; }
#define E(t) ((t).end)
#define ATTACH(t, p) ( T(t) ? ( (E(t)->next = (p)), (E(t) = (p)) ) \
: ( (T(t) = E(t) = (p)) ) )
typedef STRING(char) Cstring;
extern void Csputc(int, Cstring *);
extern int Csprintf(Cstring *, char *, ...);
extern int Cswrite(Cstring *, char *, int);
#endif/*_CSTRING_D*/