4 #define _XOPEN_SOURCE 700
8 xstring *xstrNew(const size_t size)
22 x = malloc(sizeof(struct xstring));
28 xstrInit(x, str, size, 0);
32 int xstrInit(xstring *x, char *str, const size_t size, int keep)
34 assert(x && str && size > 0);
35 memset(x, 0, sizeof(*x));
41 x->len = strnlen(str, x->cap);
42 if (x->cap == x->len) {
48 *(x->str + x->len) = '\0';
53 int xstrAddChar(xstring *x, const char c)
57 if (x->truncated || c == '\0')
60 if (x->len + 1 < x->cap) {
61 char *p = x->str + x->len;
72 int xstrAdd(xstring *x, const char *src)
78 if (x->truncated || !src || *src == '\0')
83 q = x->str + x->cap - 1;
84 *s != '\0' && p < q; p++, s++) {
89 x->len = (size_t) (p - x->str);
97 int xstrAddSub(xstring *x, const char *src, size_t len)
101 if (x->truncated || !src || len == 0)
104 if (x->len + len + 1 > x->cap)
105 return x->truncated = -1;
107 memcpy(x->str + x->len, src, len);
110 *(x->str + x->len) = '\0';
115 int xstrCat(xstring *x, ...)
122 while ((s = va_arg(ap, char *)) != NULL) {
123 if (xstrAdd(x, s) == -1)
130 int xstrJoin(xstring *x, const char *sep, ...)
138 for (i = 0; (s = va_arg(ap, char *)) != NULL; i++) {
139 if (i && xstrAdd(x, sep) == -1)
141 if (xstrAdd(x, s) == -1)
148 int xstrAddSubs(xstring *x, ...)
155 while ((s = va_arg(ap, char *)) != NULL) {
156 size_t n = va_arg(ap, size_t);
157 if (xstrAddSub(x, s, n) == -1)
164 int xstrEq3(xstring *x, xstring *y)
168 if (x->truncated || y->truncated)
171 return x->len == y->len && xstrContains3(x, y, 1);
174 /* Does the first string contain the second */
175 int xstrContains3(xstring *x, xstring *y, int where)
179 assert(x && y && where >= -1 && where <= 1);
189 b = strncmp(x->str + x->len - y->len, y->str, y->len) == 0;
192 b = strstr(x->str, y->str) != NULL;
195 b = strncmp(x->str, y->str, y->len) == 0;
199 return b ? 1 : x->truncated ? unknown : 0;
202 void xstrFree(xstring *x)