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