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