#ifndef _S_STRING_H
#define _S_STRING_H
#include <string.h>
typedef struct string {
char *base;
char *end;
char *ptr;
} string;
#define s_clone(s) s_copy((s)->ptr)
#define s_curlen(s) ((s)->ptr - (s)->base)
#define s_dup(s) s_copy((s)->base)
#define s_getc(s) (*((s)->ptr++))
#define s_peek(s) (*((s)->ptr))
#define s_putc(s, c) (((s)->ptr < (s)->end) ? \
(*((s)->ptr)++ = (char)(c)) : s_grow((s), (c)))
#define s_reset(s) ((s) ? (*((s)->ptr = (s)->base) = '\0', (s)) : s_new())
#define s_restart(s) ((s)->ptr = (s)->base)
#define s_skipc(s) ((s)->ptr++)
#define s_space(s) ((s)->end - (s)->base)
#define s_terminate(s) (((s)->ptr < (s)->end) ? \
(*(s)->ptr = 0) : (s_grow((s), 0), (s)->ptr--, 0))
#define s_to_c(s) ((s)->base)
#define s_ptr_to_c(s) ((s)->ptr)
#ifdef __STDC__
extern string *s_append(string *to, char *from);
extern string *s_array(char *, size_t len);
extern string *s_copy(char *);
extern void s_free(string *);
extern int s_grow(string *sp, int c);
extern string *s_new(void);
extern string *s_parse(string *from, string *to);
extern char *s_read_line(FILE *fp, string *to);
extern size_t s_read_to_eof(FILE *fp, string *to);
extern string *s_seq_read(FILE *fp, string *to, int lineortoken);
extern void s_skipwhite(string *from);
extern string *s_tok(string *, char *);
extern void s_tolower(string *);
#else
extern string *s_append();
extern string *s_array();
extern string *s_copy();
extern void s_free();
extern int s_grow();
extern string *s_new();
extern string *s_parse();
extern char *s_read_line();
extern size_t s_read_to_eof();
extern string *s_seq_read();
extern void s_skipwhite();
extern string *s_tok();
extern void s_tolower();
#endif
#define TOKEN 0
#define LINE 1
#define s_getline(a, b) s_seq_read(a, b, LINE)
#define s_gettoken(a, b) s_seq_read(a, b, TOKEN)
#endif