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