summaryrefslogtreecommitdiff
path: root/include/ec.h
blob: 7473a5996b1bbd3367344a3acd9a945e2d58c3ee (plain)
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
# ifndef EC_H
# define EC_H

# ifndef CORD_H
#  include "cord.h"
# endif

#ifdef __cplusplus
  extern "C" {
#endif

/* Extensible cords are strings that may be destructively appended to.  */
/* They allow fast construction of cords from characters that are       */
/* being read from a stream.                                            */
/*
 * A client might look like:
 *
 *      {
 *          CORD_ec x;
 *          CORD result;
 *          char c;
 *          FILE *f;
 *
 *          ...
 *          CORD_ec_init(x);
 *          while(...) {
 *              c = getc(f);
 *              ...
 *              CORD_ec_append(x, c);
 *          }
 *          result = CORD_balance(CORD_ec_to_cord(x));
 *
 * If a C string is desired as the final result, the call to CORD_balance
 * may be replaced by a call to CORD_to_char_star.
 */

# ifndef CORD_BUFSZ
#   define CORD_BUFSZ 128
# endif

typedef struct CORD_ec_struct {
    CORD ec_cord;
    char * ec_bufptr;
    char ec_buf[CORD_BUFSZ+1];
} CORD_ec[1];

/* This structure represents the concatenation of ec_cord with  */
/* ec_buf[0 ... (ec_bufptr-ec_buf-1)]                           */

/* Flush the buffer part of the extended cord into ec_cord.     */
/* Note that this is almost the only real function, and it is   */
/* implemented in 6 lines in cordxtra.c                         */
void CORD_ec_flush_buf(CORD_ec x);

/* Convert an extensible cord to a cord. */
# define CORD_ec_to_cord(x) (CORD_ec_flush_buf(x), (x)[0].ec_cord)

/* Initialize an extensible cord. */
#define CORD_ec_init(x) \
                ((x)[0].ec_cord = 0, (void)((x)[0].ec_bufptr = (x)[0].ec_buf))

/* Append a character to an extensible cord.    */
#define CORD_ec_append(x, c) \
                ((void)((x)[0].ec_bufptr == (x)[0].ec_buf + CORD_BUFSZ \
                        ? (CORD_ec_flush_buf(x), 0) : 0), \
                 (void)(*(x)[0].ec_bufptr++ = (c)))

/* Append a cord to an extensible cord.  Structure remains shared with  */
/* original.                                                            */
void CORD_ec_append_cord(CORD_ec x, CORD s);

#ifdef __cplusplus
  } /* extern "C" */
#endif

# endif /* EC_H */