STRING(2)                                               STRING(2)

          s_alloc, s_append, s_array, s_copy, s_error, s_free,
          s_incref, s_memappend, s_nappend, s_new, s_newalloc,
          s_parse, s_reset, s_restart, s_terminate, s_tolower, s_putc,
          s_unique, s_grow, s_read, s_read_line, s_getline,
          s_allocinstack, s_freeinstack, s_rdinstack - extensible

          #include <u.h>
          #include <libc.h>
          #include <String.h>

          String*   s_new(void)
          void      s_free(String *s)
          String*   s_newalloc(int n)
          String*   s_array(char *p, int n)
          String*   s_grow(String *s, int n)

          void      s_putc(String *s, int c)
          void      s_terminate(String *s)
          String*   s_reset(String *s)
          String*   s_restart(String *s)
          String*   s_append(String *s, char *p)
          String*   s_nappend(String *s, char *p, int n)
          String*   s_memappend(String *s, char *p, int n)
          String*   s_copy(char *p)
          String*   s_parse(String *s1, String *s2)

          void      s_tolower(String *s)

          String*   s_incref(String *s)
          String*   s_unique(String *s)

          #include <bio.h>

          int       s_read(Biobuf *b, String *s, int n)
          char*     s_read_line(Biobuf *b, String *s)
          char*     s_getline(Biobuf *b, String *s)
          Sinstack* s_allocinstack(char *file)
          void      s_freeinstack(Sinstack *stack)
          char*     s_rdinstack(Sinstack *stack, String *to)

          These routines manipulate extensible strings. The basic type
          is String, which points to an array of characters.  The
          string maintains pointers to the beginning and end of the
          allocated array.  In addition a finger pointer keeps track
          of where parsing will start (for s_parse) or new characters
          will be added (for s_putc, s_append, and s_nappend). The

     STRING(2)                                               STRING(2)

          structure, and a few useful macros are:

          typedef struct String {
               char *base;    /* base of String */
               char *end;     /* end of allocated space+1 */
               char *ptr;     /* ptr into String */
          } String;

          #define s_to_c(s) ((s)->base)
          #define s_len(s) ((s)->ptr-(s)->base)
          #define s_clone(s) s_copy((s)->base)

          S_to_c is used when code needs a reference to the character
          array.  Using s->base directly is frowned upon since it
          exposes too much of the implementation.

        allocation and freeing
          A string must be allocated before it can be used.  One nor-
          mally does this using s_new, giving the string an initial
          allocation of 128 bytes.  If you know that the string will
          need to grow much longer, you can use s_newalloc instead,
          specifying the number of bytes in the initial allocation.

          S_free causes both the string and its character array to be

          S_grow grows a string's allocation by a fixed amount.  It is
          useful if you are reading directly into a string's character
          array but should be avoided if possible.

          S_array is used to create a constant array, that is, one
          whose contents won't change.  It points directly to the
          character array given as an argument.  Tread lightly when
          using this call.

        Filling the string
          After its initial allocation, the string points to the
          beginning of an allocated array of characters starting with

          S_putc writes a character into the string at the pointer and
          advances the pointer to point after it.

          S_terminate writes a NUL at the pointer but doesn't advance

          S_restart resets the pointer to the begining of the string
          but doesn't change the contents.

          S_reset is equivalent to s_restart followed by s_terminate.

     STRING(2)                                               STRING(2)

          S_append and s_nappend copy characters into the string at
          the pointer and advance the pointer.  They also write a NUL
          at the pointer without advancing the pointer beyond it.
          Both routines stop copying on encountering a NUL.
          S_memappend is like s_nappend but doesn't stop at a NUL.

          If you know the initial character array to be copied into a
          string, you can allocate a string and copy in the bytes
          using s_copy. This is the equivalent of a s_new followed by
          an s_append.

          S_parse copies the next white space terminated token from s1
          to the end of s2. White space is defined as space, tab, and
          newline.  Both single and double quoted strings are treated
          as a single token.  The bounding quotes are not copied.
          There is no escape mechanism.

          S_tolower converts all ASCII characters in the string to
          lower case.

          S_incref is used by multithreaded programs to avoid having
          the string memory released until the last user of the string
          performs an s_free. S_unique returns a unique copy of the
          string: if the reference count it 1 it returns the string,
          otherwise it returns an s_clone of the string.

        Bio interaction
          S_read reads the requested number of characters through a
          Biobuf into a string.  The string is grown as necessary.  An
          eof or error terminates the read.  The number of bytes read
          is returned.  The string is ASCII NUL terminated.

          S_read_line reads up to and including the next newline and
          returns a pointer to the beginning of the bytes read.  An
          eof or error terminates the read and returns 0.  The string
          is NUL terminated.

          S_getline reads up to the next newline and returns a pointer
          to the beginning of the bytes read (0 on eof or error).
          Leading spaces and tabs and the trailing newline are all
          discarded.  S_getline will discard all lines beginning with

          S_rdinstack will recursively read through files included
          with `#include' and discard all other lines beginning with
          `#'.  The next line read from a stack of include files is
          appended to to. S_rdinstack returns a pointer to the begin-
          ning of the bytes read.  An eof or error terminates the read
          and returns 0.  The string is NUL terminated.
          S_allocinstack opens file for reading and returns a pointer
          to a new stack of include files, or nil on failure.

     STRING(2)                                               STRING(2)

          S_freeinstack frees such a stack.