8 * struct xstring - string metadata
10 * @len: current length of buf contents
11 * @cap: maximum capacity of buf
12 * @truncated: -1 indicates truncation
14 typedef struct xstring {
22 * xstrNew - mallocs and inits
23 * @size: size of buffer to allocate
25 * mallocs both buffer and struct, calls xstrInit
27 * Return: ptr to xstring or NULL
29 xstring *xstrNew(const size_t size);
32 * xstrInit - initialize an xstring struct
33 * @x: pointer to xstring
34 * @str: buffer to manage
36 * @keep: if !0, keep existing contents of str;
37 * otherwise, str[0] = '\0'
39 * Return: x->truncated
41 int xstrInit(xstring *x, char *str, const size_t size, int keep);
44 * xstrClear - clear xstring
45 * @x: pointer to xstring
47 * This sets x->len and x->truncated to 0 and str[0] to '\0';
49 * Return: x->truncated (always 0)
51 #define xstrClear(x) (xstrInit((x), (x)->str, (x)->cap, 0))
54 * xstrAddChar - add a single character
55 * @x: pointer to xstring
56 * @c: character to append
58 * Return: x->truncated
60 int xstrAddChar(xstring *x, const char c);
63 * xstrAdd - append a string
64 * @x: pointer to xstring
65 * @src: string to append
67 * Append as much from src as fits - if not all, flag truncation.
69 * Return: x->truncated
71 int xstrAdd(xstring *x, const char *src);
74 * xstrAddSub - append a substring
75 * @x: pointer to xstring
76 * @src: string to append
77 * @len: length of substring
79 * Append substring and '\0' if len fits, otherwise flag truncation.
81 * Return: x->truncated
83 int xstrAddSub(xstring *x, const char *src, size_t len);
85 /** xstrCat - append multiple strings
86 * @x: pointer to xstring
87 * @...: one or more strings followed by NULL
89 * Run xstrAdd for each string.
91 * Return: x->truncated
93 int xstrCat(xstring *x, ...);
95 /** xstrJoin - append multiple strings joined by sep
96 * @x: pointer to xstring
97 * @sep: separator string
98 * @...: one or more strings followed by NULL
100 * Run xstrAdd for each string and append sep between each pair.
102 * Return: x->truncated
104 int xstrJoin(xstring *x, const char *sep, ...);
107 * xstrAddSubs - append multiple substrings
108 * @x: pointer to xstring
109 * @...: one or more pairs of string and length followed by NULL
111 * Run xstrAddSub for each pair of string and length.
113 * Return: x->truncated
115 int xstrAddSubs(xstring *x, ...);
117 #define transact(x, y) ({ \
122 if ((ret = (y)) == -1) { \
124 *((x)->str + (x)->len) = '\0'; \
130 * xstrAddT - append a string as a transaction
131 * @x: pointer to xstring
132 * @src: string to append
134 * Run xstrAdd. Reterminate at inital length if truncation occurs.
136 * Return: x->truncated
138 #define xstrAddT(x, y) transact(x, xstrAdd((x), y))
140 /** xstrCatT - append multiple strings as one transaction
141 * @x: pointer to xstring
142 * @...: one or more strings followed by NULL
144 * Run xstrCat. Reterminate at inital length if truncation occurs.
146 * Return: x->truncated
148 #define xstrCatT(x, y...) transact(x, xstrCat((x) , ## y))
150 /** xstrJoinT - append multiple strings joined by sep as one transaction
151 * @x: pointer to xstring
152 * @sep: separator string
153 * @...: one or more strings followed by NULL
155 * Run xstrJoin. Reterminate at inital length if truncation occurs.
157 * Return: x->truncated
159 #define xstrJoinT(x, y...) transact(x, xstrJoin((x) , ## y))
162 * xstrAddSubsT - append multiple substrings as one transaction
163 * @x: pointer to xstring
164 * @...: one or more pairs of string and length followed by NULL
166 * Run xstrAddSubs. Reterminate at inital length if truncation occurs.
168 * Return: x->truncated
170 #define xstrAddSubsT(x, y...) transact(x, xstrAddSubs((x) , ## y))
173 * xstrAddSubT - same as xstrAddSub
175 // addsub is already transactional
176 #define xstrAddSubT xstrAddSub
181 * xstrEq3 - test if two strings are equal
182 * @x: pointer to xstring
183 * @y: pointer to xstring
185 * Return true (1) if the strings held by x and y match and no truncation has occurred.
186 * Return unknown (-1) if either is flagged as truncated.
187 * Return false (0) otherwise.
189 * Return: -1, 0, or 1
191 int xstrEq3(xstring *x, xstring *y);
194 * xstrEq - test if two strings are equal
195 * @x: pointer to xstring
196 * @y: pointer to xstring
198 * Same as xstrEq3, but return false (0) for unknown (-1).
202 #define xstrEq(x, y) (xstrEq3((x), (y)) == 1)
205 * xstrContains3 - test if first string contains second
206 * @x: pointer to xstring
207 * @y: pointer to xstring
208 * @where: -1 (ends), 0 (anywhere), 1 (begins)
210 * If neither x nor y are truncated, returns true (1) or false (0).
211 * If y is truncated, return unknown (-1).
212 * If x is truncated, return true (1) if known portion of x contains y, unknown (-1) otherwise.
214 * Return: -1, 0, or 1
216 int xstrContains3(xstring *x, xstring *y, int where);
219 * xstrContains3 - test if first string contains second
220 * @x: pointer to xstring
221 * @y: pointer to xstring
222 * @where: -1 (ends), 0 (anywhere), 1 (begins)
224 * Same as xstrContains3, but return false (0) for unknown (-1).
228 #define xstrContains(x, y, w) (xstrContains3((x), (y), (w)) == 1)
231 * xstrFree - free malloced memory
232 * @x: pointer to xstring
234 void xstrFree(xstring *x);