| 1 | # ifndef EC_H
|
|---|
| 2 | # define EC_H
|
|---|
| 3 |
|
|---|
| 4 | # ifndef CORD_H
|
|---|
| 5 | # include "cord.h"
|
|---|
| 6 | # endif
|
|---|
| 7 |
|
|---|
| 8 | /* Extensible cords are strings that may be destructively appended to. */
|
|---|
| 9 | /* They allow fast construction of cords from characters that are */
|
|---|
| 10 | /* being read from a stream. */
|
|---|
| 11 | /*
|
|---|
| 12 | * A client might look like:
|
|---|
| 13 | *
|
|---|
| 14 | * {
|
|---|
| 15 | * CORD_ec x;
|
|---|
| 16 | * CORD result;
|
|---|
| 17 | * char c;
|
|---|
| 18 | * FILE *f;
|
|---|
| 19 | *
|
|---|
| 20 | * ...
|
|---|
| 21 | * CORD_ec_init(x);
|
|---|
| 22 | * while(...) {
|
|---|
| 23 | * c = getc(f);
|
|---|
| 24 | * ...
|
|---|
| 25 | * CORD_ec_append(x, c);
|
|---|
| 26 | * }
|
|---|
| 27 | * result = CORD_balance(CORD_ec_to_cord(x));
|
|---|
| 28 | *
|
|---|
| 29 | * If a C string is desired as the final result, the call to CORD_balance
|
|---|
| 30 | * may be replaced by a call to CORD_to_char_star.
|
|---|
| 31 | */
|
|---|
| 32 |
|
|---|
| 33 | # ifndef CORD_BUFSZ
|
|---|
| 34 | # define CORD_BUFSZ 128
|
|---|
| 35 | # endif
|
|---|
| 36 |
|
|---|
| 37 | typedef struct CORD_ec_struct {
|
|---|
| 38 | CORD ec_cord;
|
|---|
| 39 | char * ec_bufptr;
|
|---|
| 40 | char ec_buf[CORD_BUFSZ+1];
|
|---|
| 41 | } CORD_ec[1];
|
|---|
| 42 |
|
|---|
| 43 | /* This structure represents the concatenation of ec_cord with */
|
|---|
| 44 | /* ec_buf[0 ... (ec_bufptr-ec_buf-1)] */
|
|---|
| 45 |
|
|---|
| 46 | /* Flush the buffer part of the extended chord into ec_cord. */
|
|---|
| 47 | /* Note that this is almost the only real function, and it is */
|
|---|
| 48 | /* implemented in 6 lines in cordxtra.c */
|
|---|
| 49 | void CORD_ec_flush_buf(CORD_ec x);
|
|---|
| 50 |
|
|---|
| 51 | /* Convert an extensible cord to a cord. */
|
|---|
| 52 | # define CORD_ec_to_cord(x) (CORD_ec_flush_buf(x), (x)[0].ec_cord)
|
|---|
| 53 |
|
|---|
| 54 | /* Initialize an extensible cord. */
|
|---|
| 55 | # define CORD_ec_init(x) ((x)[0].ec_cord = 0, (x)[0].ec_bufptr = (x)[0].ec_buf)
|
|---|
| 56 |
|
|---|
| 57 | /* Append a character to an extensible cord. */
|
|---|
| 58 | # define CORD_ec_append(x, c) \
|
|---|
| 59 | { \
|
|---|
| 60 | if ((x)[0].ec_bufptr == (x)[0].ec_buf + CORD_BUFSZ) { \
|
|---|
| 61 | CORD_ec_flush_buf(x); \
|
|---|
| 62 | } \
|
|---|
| 63 | *((x)[0].ec_bufptr)++ = (c); \
|
|---|
| 64 | }
|
|---|
| 65 |
|
|---|
| 66 | /* Append a cord to an extensible cord. Structure remains shared with */
|
|---|
| 67 | /* original. */
|
|---|
| 68 | void CORD_ec_append_cord(CORD_ec x, CORD s);
|
|---|
| 69 |
|
|---|
| 70 | # endif /* EC_H */
|
|---|