xref: /freebsd/contrib/byacc/mstring.c (revision 822ca3276345b4a67ccbc9b54616d8b205fd37f2)
1*822ca327SBaptiste Daroussin /* $Id: mstring.c,v 1.10 2023/02/26 10:15:01 tom Exp $ */
20c8de5b0SBaptiste Daroussin 
30c8de5b0SBaptiste Daroussin #include <stdlib.h>
40c8de5b0SBaptiste Daroussin #include <stdio.h>
50c8de5b0SBaptiste Daroussin #include <stdarg.h>
60c8de5b0SBaptiste Daroussin #include <ctype.h>
70c8de5b0SBaptiste Daroussin #include <string.h>
80c8de5b0SBaptiste Daroussin #include "defs.h"
90c8de5b0SBaptiste Daroussin 
100c8de5b0SBaptiste Daroussin /* parameters about string length.  HEAD is the starting size and
110c8de5b0SBaptiste Daroussin ** HEAD+TAIL should be a power of two */
120c8de5b0SBaptiste Daroussin #define HEAD	24
130c8de5b0SBaptiste Daroussin #define TAIL	8
140c8de5b0SBaptiste Daroussin 
15497dcf4cSBaptiste Daroussin static char *buf_ptr;
16497dcf4cSBaptiste Daroussin static size_t buf_len;
17497dcf4cSBaptiste Daroussin 
180c8de5b0SBaptiste Daroussin void
msprintf(struct mstring * s,const char * fmt,...)190c8de5b0SBaptiste Daroussin msprintf(struct mstring *s, const char *fmt, ...)
200c8de5b0SBaptiste Daroussin {
210c8de5b0SBaptiste Daroussin     va_list args;
220c8de5b0SBaptiste Daroussin     size_t len;
23497dcf4cSBaptiste Daroussin #ifdef HAVE_VSNPRINTF
24497dcf4cSBaptiste Daroussin     int changed;
25497dcf4cSBaptiste Daroussin #endif
260c8de5b0SBaptiste Daroussin 
270c8de5b0SBaptiste Daroussin     if (!s || !s->base)
280c8de5b0SBaptiste Daroussin 	return;
290c8de5b0SBaptiste Daroussin 
30497dcf4cSBaptiste Daroussin     if (buf_len == 0)
31497dcf4cSBaptiste Daroussin     {
32497dcf4cSBaptiste Daroussin 	buf_ptr = malloc(buf_len = 4096);
33497dcf4cSBaptiste Daroussin     }
34497dcf4cSBaptiste Daroussin     if (buf_ptr == 0)
35497dcf4cSBaptiste Daroussin     {
36497dcf4cSBaptiste Daroussin 	return;
37497dcf4cSBaptiste Daroussin     }
38497dcf4cSBaptiste Daroussin 
39497dcf4cSBaptiste Daroussin #ifdef HAVE_VSNPRINTF
40497dcf4cSBaptiste Daroussin     do
41497dcf4cSBaptiste Daroussin     {
42497dcf4cSBaptiste Daroussin 	va_start(args, fmt);
43497dcf4cSBaptiste Daroussin 	len = (size_t)vsnprintf(buf_ptr, buf_len, fmt, args);
44497dcf4cSBaptiste Daroussin 	va_end(args);
45497dcf4cSBaptiste Daroussin 	if ((changed = (len > buf_len)) != 0)
46497dcf4cSBaptiste Daroussin 	{
47497dcf4cSBaptiste Daroussin 	    char *new_ptr = realloc(buf_ptr, (buf_len * 3) / 2);
48497dcf4cSBaptiste Daroussin 	    if (new_ptr == 0)
49497dcf4cSBaptiste Daroussin 	    {
50497dcf4cSBaptiste Daroussin 		free(buf_ptr);
51497dcf4cSBaptiste Daroussin 		buf_ptr = 0;
52497dcf4cSBaptiste Daroussin 		return;
53497dcf4cSBaptiste Daroussin 	    }
54497dcf4cSBaptiste Daroussin 	    buf_ptr = new_ptr;
55497dcf4cSBaptiste Daroussin 	}
56497dcf4cSBaptiste Daroussin     }
57497dcf4cSBaptiste Daroussin     while (changed);
58497dcf4cSBaptiste Daroussin #else
59497dcf4cSBaptiste Daroussin     va_start(args, fmt);
60497dcf4cSBaptiste Daroussin     len = (size_t)vsprintf(buf_ptr, fmt, args);
61497dcf4cSBaptiste Daroussin     va_end(args);
62497dcf4cSBaptiste Daroussin     if (len >= buf_len)
63497dcf4cSBaptiste Daroussin 	return;
64497dcf4cSBaptiste Daroussin #endif
65497dcf4cSBaptiste Daroussin 
660c8de5b0SBaptiste Daroussin     if (len > (size_t)(s->end - s->ptr))
670c8de5b0SBaptiste Daroussin     {
68497dcf4cSBaptiste Daroussin 	char *new_base;
690c8de5b0SBaptiste Daroussin 	size_t cp = (size_t)(s->ptr - s->base);
700c8de5b0SBaptiste Daroussin 	size_t cl = (size_t)(s->end - s->base);
710c8de5b0SBaptiste Daroussin 	size_t nl = cl;
720c8de5b0SBaptiste Daroussin 	while (len > (nl - cp))
730c8de5b0SBaptiste Daroussin 	    nl = nl + nl + TAIL;
74497dcf4cSBaptiste Daroussin 	if ((new_base = realloc(s->base, nl)))
750c8de5b0SBaptiste Daroussin 	{
76497dcf4cSBaptiste Daroussin 	    s->base = new_base;
770c8de5b0SBaptiste Daroussin 	    s->ptr = s->base + cp;
780c8de5b0SBaptiste Daroussin 	    s->end = s->base + nl;
790c8de5b0SBaptiste Daroussin 	}
800c8de5b0SBaptiste Daroussin 	else
810c8de5b0SBaptiste Daroussin 	{
82497dcf4cSBaptiste Daroussin 	    free(s->base);
83497dcf4cSBaptiste Daroussin 	    s->base = 0;
84497dcf4cSBaptiste Daroussin 	    s->ptr = 0;
85497dcf4cSBaptiste Daroussin 	    s->end = 0;
860c8de5b0SBaptiste Daroussin 	    return;
870c8de5b0SBaptiste Daroussin 	}
880c8de5b0SBaptiste Daroussin     }
89497dcf4cSBaptiste Daroussin     memcpy(s->ptr, buf_ptr, len);
900c8de5b0SBaptiste Daroussin     s->ptr += len;
910c8de5b0SBaptiste Daroussin }
920c8de5b0SBaptiste Daroussin 
930c8de5b0SBaptiste Daroussin int
mputchar(struct mstring * s,int ch)940c8de5b0SBaptiste Daroussin mputchar(struct mstring *s, int ch)
950c8de5b0SBaptiste Daroussin {
960c8de5b0SBaptiste Daroussin     if (!s || !s->base)
970c8de5b0SBaptiste Daroussin 	return ch;
980c8de5b0SBaptiste Daroussin     if (s->ptr == s->end)
990c8de5b0SBaptiste Daroussin     {
1000c8de5b0SBaptiste Daroussin 	size_t len = (size_t)(s->end - s->base);
1010c8de5b0SBaptiste Daroussin 	if ((s->base = realloc(s->base, len + len + TAIL)))
1020c8de5b0SBaptiste Daroussin 	{
1030c8de5b0SBaptiste Daroussin 	    s->ptr = s->base + len;
1040c8de5b0SBaptiste Daroussin 	    s->end = s->base + len + len + TAIL;
1050c8de5b0SBaptiste Daroussin 	}
1060c8de5b0SBaptiste Daroussin 	else
1070c8de5b0SBaptiste Daroussin 	{
1080c8de5b0SBaptiste Daroussin 	    s->ptr = s->end = 0;
1090c8de5b0SBaptiste Daroussin 	    return ch;
1100c8de5b0SBaptiste Daroussin 	}
1110c8de5b0SBaptiste Daroussin     }
1120c8de5b0SBaptiste Daroussin     *s->ptr++ = (char)ch;
1130c8de5b0SBaptiste Daroussin     return ch;
1140c8de5b0SBaptiste Daroussin }
1150c8de5b0SBaptiste Daroussin 
1160c8de5b0SBaptiste Daroussin struct mstring *
msnew(void)1170c8de5b0SBaptiste Daroussin msnew(void)
1180c8de5b0SBaptiste Daroussin {
119497dcf4cSBaptiste Daroussin     struct mstring *n = TMALLOC(struct mstring, 1);
1200c8de5b0SBaptiste Daroussin 
1210c8de5b0SBaptiste Daroussin     if (n)
1220c8de5b0SBaptiste Daroussin     {
123497dcf4cSBaptiste Daroussin 	if ((n->base = n->ptr = MALLOC(HEAD)) != 0)
1240c8de5b0SBaptiste Daroussin 	{
1250c8de5b0SBaptiste Daroussin 	    n->end = n->base + HEAD;
1260c8de5b0SBaptiste Daroussin 	}
1270c8de5b0SBaptiste Daroussin 	else
1280c8de5b0SBaptiste Daroussin 	{
1290c8de5b0SBaptiste Daroussin 	    free(n);
1300c8de5b0SBaptiste Daroussin 	    n = 0;
1310c8de5b0SBaptiste Daroussin 	}
1320c8de5b0SBaptiste Daroussin     }
1330c8de5b0SBaptiste Daroussin     return n;
1340c8de5b0SBaptiste Daroussin }
1350c8de5b0SBaptiste Daroussin 
136b53bb29fSJung-uk Kim struct mstring *
msrenew(char * value)137b53bb29fSJung-uk Kim msrenew(char *value)
138b53bb29fSJung-uk Kim {
139b53bb29fSJung-uk Kim     struct mstring *r = 0;
140b53bb29fSJung-uk Kim     if (value != 0)
141b53bb29fSJung-uk Kim     {
142b53bb29fSJung-uk Kim 	r = msnew();
143b53bb29fSJung-uk Kim 	r->base = value;
144b53bb29fSJung-uk Kim 	r->end = value + strlen(value);
145b53bb29fSJung-uk Kim 	r->ptr = r->end;
146b53bb29fSJung-uk Kim     }
147b53bb29fSJung-uk Kim     return r;
148b53bb29fSJung-uk Kim }
149b53bb29fSJung-uk Kim 
1500c8de5b0SBaptiste Daroussin char *
msdone(struct mstring * s)1510c8de5b0SBaptiste Daroussin msdone(struct mstring *s)
1520c8de5b0SBaptiste Daroussin {
1530c8de5b0SBaptiste Daroussin     char *r = 0;
1540c8de5b0SBaptiste Daroussin     if (s)
1550c8de5b0SBaptiste Daroussin     {
1560c8de5b0SBaptiste Daroussin 	mputc(s, 0);
1570c8de5b0SBaptiste Daroussin 	r = s->base;
1580c8de5b0SBaptiste Daroussin 	free(s);
1590c8de5b0SBaptiste Daroussin     }
1600c8de5b0SBaptiste Daroussin     return r;
1610c8de5b0SBaptiste Daroussin }
1620c8de5b0SBaptiste Daroussin 
1630c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
1640c8de5b0SBaptiste Daroussin /* compare two strings, ignoring whitespace, except between two letters or
1650c8de5b0SBaptiste Daroussin ** digits (and treat all of these as equal) */
1660c8de5b0SBaptiste Daroussin int
strnscmp(const char * a,const char * b)1670c8de5b0SBaptiste Daroussin strnscmp(const char *a, const char *b)
1680c8de5b0SBaptiste Daroussin {
1690c8de5b0SBaptiste Daroussin     while (1)
1700c8de5b0SBaptiste Daroussin     {
1712aca18c7SJung-uk Kim 	while (isspace(UCH(*a)))
1720c8de5b0SBaptiste Daroussin 	    a++;
1732aca18c7SJung-uk Kim 	while (isspace(UCH(*b)))
1740c8de5b0SBaptiste Daroussin 	    b++;
1750c8de5b0SBaptiste Daroussin 	while (*a && *a == *b)
1760c8de5b0SBaptiste Daroussin 	    a++, b++;
1772aca18c7SJung-uk Kim 	if (isspace(UCH(*a)))
1780c8de5b0SBaptiste Daroussin 	{
1792aca18c7SJung-uk Kim 	    if (isalnum(UCH(a[-1])) && isalnum(UCH(*b)))
1800c8de5b0SBaptiste Daroussin 		break;
1810c8de5b0SBaptiste Daroussin 	}
1822aca18c7SJung-uk Kim 	else if (isspace(UCH(*b)))
1830c8de5b0SBaptiste Daroussin 	{
1842aca18c7SJung-uk Kim 	    if (isalnum(UCH(b[-1])) && isalnum(UCH(*a)))
1850c8de5b0SBaptiste Daroussin 		break;
1860c8de5b0SBaptiste Daroussin 	}
1870c8de5b0SBaptiste Daroussin 	else
1880c8de5b0SBaptiste Daroussin 	    break;
1890c8de5b0SBaptiste Daroussin     }
1900c8de5b0SBaptiste Daroussin     return *a - *b;
1910c8de5b0SBaptiste Daroussin }
1920c8de5b0SBaptiste Daroussin 
1930c8de5b0SBaptiste Daroussin unsigned int
strnshash(const char * s)1940c8de5b0SBaptiste Daroussin strnshash(const char *s)
1950c8de5b0SBaptiste Daroussin {
1960c8de5b0SBaptiste Daroussin     unsigned int h = 0;
1970c8de5b0SBaptiste Daroussin 
1980c8de5b0SBaptiste Daroussin     while (*s)
1990c8de5b0SBaptiste Daroussin     {
2002aca18c7SJung-uk Kim 	if (!isspace(UCH(*s)))
2010c8de5b0SBaptiste Daroussin 	    h = (h << 5) - h + (unsigned char)*s;
2020c8de5b0SBaptiste Daroussin 	s++;
2030c8de5b0SBaptiste Daroussin     }
2040c8de5b0SBaptiste Daroussin     return h;
2050c8de5b0SBaptiste Daroussin }
2060c8de5b0SBaptiste Daroussin #endif
207497dcf4cSBaptiste Daroussin 
208497dcf4cSBaptiste Daroussin #ifdef NO_LEAKS
209497dcf4cSBaptiste Daroussin void
mstring_leaks(void)210497dcf4cSBaptiste Daroussin mstring_leaks(void)
211497dcf4cSBaptiste Daroussin {
212497dcf4cSBaptiste Daroussin     free(buf_ptr);
213497dcf4cSBaptiste Daroussin     buf_ptr = 0;
214497dcf4cSBaptiste Daroussin     buf_len = 0;
215497dcf4cSBaptiste Daroussin }
216497dcf4cSBaptiste Daroussin #endif
217