#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 structure, and a few useful macros are: .EX typedef struct String { Lock; 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.
A string must be allocated before it can be used. One normally 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 freed.
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.
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 it.
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 .
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.
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 .LR # .
S_rdinstack will recursively read through files included with .L #include and discard all other lines beginning with .LR # . The next line read from a stack of include files is appended to to . S_rdinstack 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_allocinstack opens file for reading and returns a pointer to a new stack of include files, or nil on failure. S_freeinstack frees such a stack .