1 : /* Copyright (c) 2007 James Antill -- See LICENSE file for terms. */
2 :
3 : #ifndef USTR_SET_H
4 : #error " You should have already included ustr-set.h, or just include ustr.h."
5 : #endif
6 :
7 : USTR_CONF_i_PROTO
8 : int ustrp__set_undef(struct Ustr_pool *p, struct Ustr **ps1, size_t nlen)
9 422 : {
10 422 : struct Ustr *s1 = USTR_NULL;
11 422 : struct Ustr *ret = USTR_NULL;
12 422 : size_t clen = 0;
13 422 : size_t sz = 0;
14 422 : size_t oh = 0;
15 422 : size_t osz = 0;
16 422 : size_t nsz = 0;
17 422 : int alloc = USTR_FALSE;
18 :
19 229 : USTR_ASSERT(ps1 && ustrp__assert_valid(!!p, *ps1));
20 :
21 422 : s1 = *ps1;
22 305 : clen = ustr_len(s1);
23 422 : if (nlen == clen)
24 : {
25 40 : if (ustr_owner(s1))
26 34 : return (USTR_TRUE);
27 : }
28 382 : else if (ustr__rw_mod(s1, nlen, &sz, &oh, &osz, &nsz, &alloc))
29 : {
30 190 : if (nlen > clen)
31 94 : return (ustrp__add_undef(p, ps1, (nlen - clen)));
32 : else
33 96 : return (ustrp__del(p, ps1, (clen - nlen)));
34 : }
35 192 : else if (ustr_limited(s1))
36 4 : goto fail_enomem;
37 :
38 563 : if (!(ret = ustrp__dupx_undef(p, USTR__DUPX_FROM(s1), nlen)))
39 132 : goto fail_enomem;
40 :
41 62 : ustrp__sc_free2(p, ps1, ret);
42 62 : return (USTR_TRUE);
43 :
44 136 : fail_enomem:
45 136 : ustr_setf_enomem_err(s1);
46 136 : return (USTR_FALSE);
47 : }
48 : USTR_CONF_I_PROTO int ustr_set_undef(struct Ustr **ps1, size_t nlen)
49 120 : { return (ustrp__set_undef(0, ps1, nlen)); }
50 : USTR_CONF_I_PROTO
51 : int ustrp_set_undef(struct Ustr_pool *p, struct Ustrp **ps1, size_t nlen)
52 4 : {
53 4 : struct Ustr *tmp = &(*ps1)->s;
54 4 : int ret = ustrp__set_undef(p, &tmp, nlen);
55 4 : *ps1 = USTRP(tmp);
56 4 : return (ret);
57 : }
58 :
59 : USTR_CONF_i_PROTO int ustrp__set_empty(struct Ustr_pool *p, struct Ustr **ps1)
60 28 : {
61 28 : struct Ustr *ret = USTR_NULL;
62 :
63 14 : USTR_ASSERT(ps1 && ustrp__assert_valid(!!p, *ps1));
64 :
65 42 : if (ustr_sized(*ps1) && ustr_owner(*ps1))
66 5 : return (ustrp__del(p, ps1, ustr_len(*ps1)));
67 :
68 86 : if (!(ret = ustrp__dupx_empty(p, USTR__DUPX_FROM(*ps1))))
69 : {
70 2 : ustr_setf_enomem_err(*ps1);
71 2 : return (USTR_FALSE);
72 : }
73 :
74 22 : ustrp__sc_free2(p, ps1, ret);
75 22 : return (USTR_TRUE);
76 : }
77 : USTR_CONF_I_PROTO int ustr_set_empty(struct Ustr **ps1)
78 4 : { return (ustrp__set_empty(0, ps1)); }
79 : USTR_CONF_I_PROTO int ustrp_set_empty(struct Ustr_pool *p, struct Ustrp **ps1)
80 24 : {
81 24 : struct Ustr *tmp = &(*ps1)->s;
82 24 : int ret = ustrp__set_empty(p, &tmp);
83 24 : *ps1 = USTRP(tmp);
84 24 : return (ret);
85 : }
86 :
87 : USTR_CONF_i_PROTO int ustrp__set_buf(struct Ustr_pool *p, struct Ustr **ps1,
88 : const void *buf, size_t len)
89 234 : {
90 117 : USTR_ASSERT(ps1 && ustrp__assert_valid(!!p, *ps1));
91 :
92 234 : if (!ustrp__set_undef(p, ps1, len))
93 12 : return (USTR_FALSE);
94 :
95 222 : ustr__memcpy(*ps1, 0, buf, len);
96 :
97 111 : USTR_ASSERT(ustrp__assert_valid(!!p, *ps1));
98 222 : return (USTR_TRUE);
99 : }
100 : USTR_CONF_I_PROTO
101 : int ustr_set_buf(struct Ustr **ps1, const void *buf, size_t len)
102 108 : { return (ustrp__set_buf(0, ps1, buf, len)); }
103 : USTR_CONF_I_PROTO int ustrp_set_buf(struct Ustr_pool *p, struct Ustrp **ps1,
104 : const void *buf, size_t len)
105 14 : {
106 14 : struct Ustr *tmp = &(*ps1)->s;
107 14 : int ret = ustrp__set_buf(p, &tmp, buf, len);
108 14 : *ps1 = USTRP(tmp);
109 14 : return (ret);
110 : }
111 :
112 : USTR_CONF_i_PROTO
113 : int ustrp__set(struct Ustr_pool *p, struct Ustr **ps1, const struct Ustr *s2)
114 72 : {
115 72 : struct Ustr *ret = USTR_NULL;
116 :
117 36 : USTR_ASSERT(ps1 &&
118 : ustrp__assert_valid(!!p, *ps1) && ustrp__assert_valid(!!p, s2));
119 :
120 72 : if (*ps1 == s2)
121 20 : return (USTR_TRUE);
122 :
123 52 : if (ustr__treat_as_buf(*ps1, 0, ustr_len(s2)))
124 16 : return (ustrp__set_buf(p, ps1, ustr_cstr(s2), ustr_len(s2)));
125 :
126 140 : if (!(ret = ustrp__dupx(p, USTR__DUPX_FROM(*ps1), s2)))
127 : {
128 4 : ustr_setf_enomem_err(*ps1);
129 4 : return (USTR_FALSE);
130 : }
131 :
132 32 : ustrp__sc_free2(p, ps1, ret);
133 32 : return (USTR_TRUE);
134 : }
135 : USTR_CONF_I_PROTO int ustr_set(struct Ustr **ps1, const struct Ustr *s2)
136 24 : { return (ustrp__set(0, ps1, s2)); }
137 : USTR_CONF_I_PROTO
138 : int ustrp_set(struct Ustr_pool *p, struct Ustrp **ps1, const struct Ustrp *s2)
139 36 : {
140 36 : struct Ustr *tmp = &(*ps1)->s;
141 36 : int ret = ustrp__set(p, &tmp, &s2->s);
142 36 : *ps1 = USTRP(tmp);
143 36 : return (ret);
144 : }
145 :
146 : USTR_CONF_i_PROTO
147 : int ustrp__set_subustr(struct Ustr_pool *p, struct Ustr **ps1,
148 : const struct Ustr *s2, size_t pos, size_t len)
149 70 : {
150 70 : size_t clen = 0;
151 :
152 34 : USTR_ASSERT(ps1 && ustrp__assert_valid(!!p, *ps1));
153 :
154 70 : if (!len)
155 10 : return (ustrp__del(p, ps1, ustr_len(*ps1)));
156 :
157 62 : clen = ustrp__assert_valid_subustr(!!p, s2, pos, len);
158 62 : if (!clen)
159 2 : return (USTR_FALSE);
160 60 : if (len == clen)
161 4 : return (ustrp__set(p, ps1, s2));
162 :
163 58 : if ((*ps1 == s2) && ustr_owner(s2) && ustr_alloc(s2))
164 : { /* only one reference, so we can't take _cstr() before we realloc */
165 4 : --pos;
166 4 : ustrp__del(p, ps1, clen - (pos + len)); /* delete bit after */
167 4 : ustrp__del_subustr(p, ps1, 1, pos); /* delete bit before */
168 4 : return (USTR_TRUE);
169 : }
170 :
171 52 : return (ustrp__set_buf(p, ps1, ustr_cstr(s2) + pos - 1, len));
172 : }
173 : USTR_CONF_I_PROTO int ustr_set_subustr(struct Ustr **ps1, const struct Ustr *s2,
174 : size_t pos, size_t len)
175 8 : { return (ustrp__set_subustr(0, ps1, s2, pos, len)); }
176 : USTR_CONF_I_PROTO
177 : int ustrp_set_subustrp(struct Ustr_pool *p, struct Ustrp **ps1,
178 : const struct Ustrp *s2, size_t pos, size_t len)
179 14 : {
180 14 : struct Ustr *tmp = &(*ps1)->s;
181 14 : int ret = ustrp__set_subustr(p, &tmp, &s2->s, pos, len);
182 14 : *ps1 = USTRP(tmp);
183 14 : return (ret);
184 : }
185 :
186 : USTR_CONF_i_PROTO int ustrp__set_rep_chr(struct Ustr_pool *p, struct Ustr **ps1,
187 : char chr, size_t len)
188 44 : {
189 22 : USTR_ASSERT(ps1 && ustrp__assert_valid(!!p, *ps1));
190 :
191 44 : if (!ustrp__set_undef(p, ps1, len))
192 4 : return (USTR_FALSE);
193 :
194 40 : ustr__memset(*ps1, 0, chr, len);
195 :
196 20 : USTR_ASSERT(ustrp__assert_valid(!!p, *ps1));
197 40 : return (USTR_TRUE);
198 : }
199 : USTR_CONF_I_PROTO
200 : int ustr_set_rep_chr(struct Ustr **ps1, char chr, size_t len)
201 20 : { return (ustrp__set_rep_chr(0, ps1, chr, len)); }
202 : USTR_CONF_I_PROTO int ustrp_set_rep_chr(struct Ustr_pool *p, struct Ustrp **ps1,
203 : char chr, size_t len)
204 24 : {
205 24 : struct Ustr *tmp = &(*ps1)->s;
206 24 : int ret = ustrp__set_rep_chr(p, &tmp, chr, len);
207 24 : *ps1 = USTRP(tmp);
208 24 : return (ret);
209 : }
210 :
211 : #ifdef USTR_FMT_H
212 : # if USTR_CONF_HAVE_VA_COPY
213 : USTR_CONF_i_PROTO
214 : int ustrp__set_vfmt_lim(struct Ustr_pool *p, struct Ustr **ps1, size_t lim,
215 : const char *fmt, va_list ap)
216 68 : { /* NOTE: Copy and pasted so we can use ustrp_set_undef() */
217 : va_list nap;
218 68 : int rc = -1;
219 : char buf[USTR__SNPRINTF_LOCAL];
220 :
221 68 : USTR__VA_COPY(nap, ap);
222 68 : rc = USTR_CONF_VSNPRINTF_BEG(buf, sizeof(buf), fmt, nap);
223 68 : va_end(nap);
224 :
225 68 : if ((rc == -1) && ((rc = ustr__retard_vfmt_ret(fmt, ap)) == -1))
226 4 : return (USTR_FALSE);
227 :
228 64 : if (lim && ((size_t)rc > lim))
229 16 : rc = lim;
230 :
231 64 : if ((size_t)rc < sizeof(buf)) /* everything is done */
232 44 : return (ustrp__set_buf(p, ps1, buf, rc));
233 :
234 20 : if (!ustrp__set_undef(p, ps1, rc))
235 4 : return (USTR_FALSE);
236 :
237 16 : USTR_CONF_VSNPRINTF_END(ustr_wstr(*ps1), rc + 1, fmt, ap);
238 :
239 8 : USTR_ASSERT(ustrp__assert_valid(!!p, *ps1));
240 :
241 16 : return (USTR_TRUE);
242 : }
243 : USTR_CONF_I_PROTO int ustr_set_vfmt_lim(struct Ustr **ps1, size_t lim,
244 : const char *fmt, va_list ap)
245 52 : { return (ustrp__set_vfmt_lim(0, ps1, lim, fmt, ap)); }
246 : USTR_CONF_I_PROTO
247 : int ustrp_set_vfmt_lim(struct Ustr_pool *p,struct Ustrp **ps1, size_t lim,
248 : const char *fmt, va_list ap)
249 16 : {
250 16 : struct Ustr *tmp = &(*ps1)->s;
251 16 : int ret = ustrp__set_vfmt_lim(p, &tmp, lim, fmt, ap);
252 16 : *ps1 = USTRP(tmp);
253 16 : return (ret);
254 : }
255 :
256 : USTR_CONF_I_PROTO
257 : int ustr_set_fmt_lim(struct Ustr **ps1, size_t lim, const char *fmt, ...)
258 8 : {
259 : va_list ap;
260 8 : int ret = USTR_FALSE;
261 :
262 8 : va_start(ap, fmt);
263 8 : ret = ustr_set_vfmt_lim(ps1, lim, fmt, ap);
264 8 : va_end(ap);
265 :
266 8 : return (ret);
267 : }
268 :
269 : USTR_CONF_I_PROTO
270 : int ustrp_set_fmt_lim(struct Ustr_pool *p, struct Ustrp **ps1, size_t lim,
271 : const char*fmt, ...)
272 8 : {
273 : va_list ap;
274 8 : int ret = USTR_FALSE;
275 :
276 8 : va_start(ap, fmt);
277 8 : ret = ustrp_set_vfmt_lim(p, ps1, lim, fmt, ap);
278 8 : va_end(ap);
279 :
280 8 : return (ret);
281 : }
282 :
283 : USTR_CONF_I_PROTO int ustr_set_vfmt(struct Ustr **ps1,
284 : const char *fmt, va_list ap)
285 44 : { return (ustr_set_vfmt_lim(ps1, 0, fmt, ap)); }
286 :
287 : USTR_CONF_I_PROTO int ustrp_set_vfmt(struct Ustr_pool *p, struct Ustrp **ps1,
288 : const char *fmt, va_list ap)
289 8 : { return (ustrp_set_vfmt_lim(p, ps1, 0, fmt, ap)); }
290 :
291 : USTR_CONF_I_PROTO int ustr_set_fmt(struct Ustr **ps1, const char *fmt, ...)
292 36 : {
293 : va_list ap;
294 36 : int ret = USTR_FALSE;
295 :
296 36 : va_start(ap, fmt);
297 36 : ret = ustr_set_vfmt(ps1, fmt, ap);
298 36 : va_end(ap);
299 :
300 36 : return (ret);
301 : }
302 :
303 : USTR_CONF_I_PROTO int ustrp_set_fmt(struct Ustr_pool *p, struct Ustrp **ps1,
304 : const char *fmt, ...)
305 8 : {
306 : va_list ap;
307 8 : int ret = USTR_FALSE;
308 :
309 8 : va_start(ap, fmt);
310 8 : ret = ustrp_set_vfmt(p, ps1, fmt, ap);
311 8 : va_end(ap);
312 :
313 8 : return (ret);
314 : }
315 : # endif
316 : #endif
|