File: mstring.c

package info (click to toggle)
btyacc 3.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 828 kB
  • sloc: ansic: 6,566; yacc: 878; makefile: 69; sh: 12
file content (103 lines) | stat: -rw-r--r-- 2,156 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <ctype.h>
#include <string.h>
#include "mstring.h"

/* parameters about string length.  START is the starting size and
** START+TAIL should be a power of two */
#define START	24
#define TAIL	8

void msprintf(struct mstring *s, const char *fmt, ...)
{
static char	buf[4096];	/* a big static buffer */
va_list		args;
int		len;

    if (!s || !s->base) return;
    va_start(args, fmt);
    vsprintf(buf, fmt, args);
    va_end(args);

    len = strlen(buf);
    if (len > (s->end - s->ptr)) {
	int	cp = s->ptr - s->base, cl = s->end - s->base, nl = cl;
	while (len > (nl - cp))
	    nl = nl + nl + TAIL;
	if ((s->base = realloc(s->base, nl))) {
	    s->ptr = s->base + cp;
	    s->end = s->base + nl; }
	else {
	    s->ptr = s->end = 0;
	    return; } }
    memcpy(s->ptr, buf, len);
    s->ptr += len;
}

int mputchar(struct mstring *s, int ch)
{
    if (!s || !s->base) return ch;
    if (s->ptr == s->end) {
	int len = s->end - s->base;
	if ((s->base = realloc(s->base, len+len+TAIL))) {
	    s->ptr = s->base + len;
	    s->end = s->base + len+len+TAIL; }
	else {
	    s->ptr = s->end = 0;
	    return ch; } }
    *s->ptr++ = ch;
    return ch;
}

struct mstring *msnew(void) {
    struct mstring *n = malloc(sizeof(struct mstring));

    if (n && (n->base = n->ptr = malloc(START)))
	n->end = n->base + START;
    else if (n) {
	free(n);
	n = 0; }
    return n;
}

char *msdone(struct mstring *s)
{
char	*r = 0;
    if (s) {
	mputc(s, 0);
	r = s->base;
	free(s); }
    return r;
}

/* compare two strings, ignoring whitespace, except between two letters or
** digits (and treat all of these as equal) */
int strnscmp(const char *a, const char *b)
{
    while(1) {
	while (isspace(*a)) a++;
	while (isspace(*b)) b++;
	while (*a && *a == *b) a++,b++;
	if (isspace(*a)) {
	    if (isalnum(a[-1]) && isalnum(*b))
		break; }
	else if (isspace(*b)) {
	    if (isalnum(b[-1]) && isalnum(*a))
		break; }
	else
	    break; }
    return *a - *b;
}

unsigned int strnshash(const char *s)
{
unsigned int	h = 0;

    while (*s) {
	if (!isspace(*s))
	    h = (h<<5) - h + *s;
	s++; }
    return h;
}