mstring.c revision 264790
1264790Sbapt/* $Id: mstring.c,v 1.3 2014/04/08 20:37:26 tom Exp $ */ 2264790Sbapt 3264790Sbapt#include <stdlib.h> 4264790Sbapt#include <stdio.h> 5264790Sbapt#include <stdarg.h> 6264790Sbapt#include <ctype.h> 7264790Sbapt#include <string.h> 8264790Sbapt#include "defs.h" 9264790Sbapt 10264790Sbapt/* parameters about string length. HEAD is the starting size and 11264790Sbapt** HEAD+TAIL should be a power of two */ 12264790Sbapt#define HEAD 24 13264790Sbapt#define TAIL 8 14264790Sbapt 15264790Sbapt#if defined(YYBTYACC) 16264790Sbaptvoid 17264790Sbaptmsprintf(struct mstring *s, const char *fmt,...) 18264790Sbapt{ 19264790Sbapt static char buf[4096]; /* a big static buffer */ 20264790Sbapt va_list args; 21264790Sbapt size_t len; 22264790Sbapt 23264790Sbapt if (!s || !s->base) 24264790Sbapt return; 25264790Sbapt va_start(args, fmt); 26264790Sbapt vsprintf(buf, fmt, args); 27264790Sbapt va_end(args); 28264790Sbapt 29264790Sbapt len = strlen(buf); 30264790Sbapt if (len > (size_t) (s->end - s->ptr)) 31264790Sbapt { 32264790Sbapt size_t cp = (size_t) (s->ptr - s->base); 33264790Sbapt size_t cl = (size_t) (s->end - s->base); 34264790Sbapt size_t nl = cl; 35264790Sbapt while (len > (nl - cp)) 36264790Sbapt nl = nl + nl + TAIL; 37264790Sbapt if ((s->base = realloc(s->base, nl))) 38264790Sbapt { 39264790Sbapt s->ptr = s->base + cp; 40264790Sbapt s->end = s->base + nl; 41264790Sbapt } 42264790Sbapt else 43264790Sbapt { 44264790Sbapt s->ptr = s->end = 0; 45264790Sbapt return; 46264790Sbapt } 47264790Sbapt } 48264790Sbapt memcpy(s->ptr, buf, len); 49264790Sbapt s->ptr += len; 50264790Sbapt} 51264790Sbapt#endif 52264790Sbapt 53264790Sbaptint 54264790Sbaptmputchar(struct mstring *s, int ch) 55264790Sbapt{ 56264790Sbapt if (!s || !s->base) 57264790Sbapt return ch; 58264790Sbapt if (s->ptr == s->end) 59264790Sbapt { 60264790Sbapt size_t len = (size_t) (s->end - s->base); 61264790Sbapt if ((s->base = realloc(s->base, len + len + TAIL))) 62264790Sbapt { 63264790Sbapt s->ptr = s->base + len; 64264790Sbapt s->end = s->base + len + len + TAIL; 65264790Sbapt } 66264790Sbapt else 67264790Sbapt { 68264790Sbapt s->ptr = s->end = 0; 69264790Sbapt return ch; 70264790Sbapt } 71264790Sbapt } 72264790Sbapt *s->ptr++ = (char)ch; 73264790Sbapt return ch; 74264790Sbapt} 75264790Sbapt 76264790Sbaptstruct mstring * 77264790Sbaptmsnew(void) 78264790Sbapt{ 79264790Sbapt struct mstring *n = malloc(sizeof(struct mstring)); 80264790Sbapt 81264790Sbapt if (n) 82264790Sbapt { 83264790Sbapt if ((n->base = n->ptr = malloc(HEAD)) != 0) 84264790Sbapt { 85264790Sbapt n->end = n->base + HEAD; 86264790Sbapt } 87264790Sbapt else 88264790Sbapt { 89264790Sbapt free(n); 90264790Sbapt n = 0; 91264790Sbapt } 92264790Sbapt } 93264790Sbapt return n; 94264790Sbapt} 95264790Sbapt 96264790Sbaptchar * 97264790Sbaptmsdone(struct mstring *s) 98264790Sbapt{ 99264790Sbapt char *r = 0; 100264790Sbapt if (s) 101264790Sbapt { 102264790Sbapt mputc(s, 0); 103264790Sbapt r = s->base; 104264790Sbapt free(s); 105264790Sbapt } 106264790Sbapt return r; 107264790Sbapt} 108264790Sbapt 109264790Sbapt#if defined(YYBTYACC) 110264790Sbapt/* compare two strings, ignoring whitespace, except between two letters or 111264790Sbapt** digits (and treat all of these as equal) */ 112264790Sbaptint 113264790Sbaptstrnscmp(const char *a, const char *b) 114264790Sbapt{ 115264790Sbapt while (1) 116264790Sbapt { 117264790Sbapt while (isspace(*a)) 118264790Sbapt a++; 119264790Sbapt while (isspace(*b)) 120264790Sbapt b++; 121264790Sbapt while (*a && *a == *b) 122264790Sbapt a++, b++; 123264790Sbapt if (isspace(*a)) 124264790Sbapt { 125264790Sbapt if (isalnum(a[-1]) && isalnum(*b)) 126264790Sbapt break; 127264790Sbapt } 128264790Sbapt else if (isspace(*b)) 129264790Sbapt { 130264790Sbapt if (isalnum(b[-1]) && isalnum(*a)) 131264790Sbapt break; 132264790Sbapt } 133264790Sbapt else 134264790Sbapt break; 135264790Sbapt } 136264790Sbapt return *a - *b; 137264790Sbapt} 138264790Sbapt 139264790Sbaptunsigned int 140264790Sbaptstrnshash(const char *s) 141264790Sbapt{ 142264790Sbapt unsigned int h = 0; 143264790Sbapt 144264790Sbapt while (*s) 145264790Sbapt { 146264790Sbapt if (!isspace(*s)) 147264790Sbapt h = (h << 5) - h + (unsigned char)*s; 148264790Sbapt s++; 149264790Sbapt } 150264790Sbapt return h; 151264790Sbapt} 152264790Sbapt#endif 153