blob: a5fd1a44ec4e57abce9b3f2d318356cb8c4988c3 (
plain)
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
104
105
106
107
108
|
/**
* \file lib/stringbuf.c
*/
#include "system.h"
#include "stringbuf.h"
#include "debug.h"
#define BUF_CHUNK 1024
struct StringBufRec {
/*@owned@*/
char *buf;
/*@dependent@*/
char *tail; /* Points to first "free" char */
int allocated;
int free;
};
/**
* Locale insensitive isspace(3).
*/
/*@unused@*/ static inline int xisspace(int c) /*@*/ {
return (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v');
}
/**
* Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
* @param p memory to free
* @return NULL always
*/
/*@unused@*/ static inline /*@null@*/ void *
_free(/*@only@*/ /*@null@*/ /*@out@*/ const void * p) /*@modifies *p @*/
{
if (p != NULL) free((void *)p);
return NULL;
}
StringBuf newStringBuf(void)
{
StringBuf sb = xmalloc(sizeof(*sb));
sb->free = sb->allocated = BUF_CHUNK;
sb->buf = xcalloc(sb->allocated, sizeof(*sb->buf));
sb->buf[0] = '\0';
sb->tail = sb->buf;
return sb;
}
StringBuf freeStringBuf(StringBuf sb)
{
if (sb) {
sb->buf = _free(sb->buf);
sb = _free(sb);
}
return sb;
}
void truncStringBuf(StringBuf sb)
{
sb->buf[0] = '\0';
sb->tail = sb->buf;
sb->free = sb->allocated;
}
void stripTrailingBlanksStringBuf(StringBuf sb)
{
while (sb->free != sb->allocated) {
if (! xisspace(*(sb->tail - 1)))
break;
sb->free++;
sb->tail--;
}
sb->tail[0] = '\0';
}
char * getStringBuf(StringBuf sb)
{
return sb->buf;
}
void appendStringBufAux(StringBuf sb, const char *s, int nl)
{
int l;
l = strlen(s);
/* If free == l there is no room for NULL terminator! */
while ((l + nl + 1) > sb->free) {
sb->allocated += BUF_CHUNK;
sb->free += BUF_CHUNK;
sb->buf = xrealloc(sb->buf, sb->allocated);
sb->tail = sb->buf + (sb->allocated - sb->free);
}
/*@-mayaliasunique@*/ /* FIX: shrug */
strcpy(sb->tail, s);
/*@=mayaliasunique@*/
sb->tail += l;
sb->free -= l;
if (nl) {
sb->tail[0] = '\n';
sb->tail[1] = '\0';
sb->tail++;
sb->free--;
}
}
|