1 #if !defined _CRT_SECURE_NO_WARNINGS && defined(_MSC_VER)
2 #define _CRT_SECURE_NO_WARNINGS /* NOLINT */
3 #endif /* _CRT_SECURE_NO_WARNINGS */
4 #if !defined _GNU_SOURCE && defined(__linux__)
6 #endif /* _GNU_SOURCE */
11 a_str
*const ctx
= (a_str
*)a_alloc(A_NULL
, sizeof(a_str
));
12 if (ctx
) { a_str_ctor(ctx
); }
16 void a_str_die(a_str
*ctx
)
25 void a_str_ctor(a_str
*ctx
)
32 void a_str_dtor(a_str
*ctx
)
36 a_alloc(ctx
->ptr_
, 0);
43 int a_str_copy(a_str
*ctx
, a_str
const *obj
)
47 ok
= a_str_alloc_(ctx
, obj
->num_
+ 1);
50 if (obj
->num_
) { a_copy(ctx
->ptr_
, obj
->ptr_
, obj
->num_
); }
51 ctx
->ptr_
[obj
->num_
] = 0;
52 ctx
->num_
= obj
->num_
;
57 void a_str_move(a_str
*ctx
, a_str
*obj
)
59 a_copy(ctx
, obj
, sizeof(*obj
));
60 a_zero(obj
, sizeof(*obj
));
63 char *a_str_exit(a_str
*ctx
)
65 char *const str
= ctx
->ptr_
;
68 ctx
->ptr_
[ctx
->num_
] = 0;
76 int a_str_alloc_(a_str
*ctx
, a_size mem
)
79 mem
= a_size_up(sizeof(void *), mem
);
80 ptr
= (char *)a_alloc(ctx
->ptr_
, mem
);
90 int a_str_alloc(a_str
*ctx
, a_size mem
)
94 return a_str_alloc_(ctx
, mem
);
99 int a_str_cmp_(void const *p0
, a_size n0
, void const *p1
, a_size n1
)
104 ok
= memcmp(p0
, p1
, A_MIN(n0
, n1
));
105 if (ok
) { return ok
; }
107 return (n0
> n1
) - (n0
< n1
);
110 int a_str_cmp(a_str
const *ctx
, a_str
const *str
)
112 return a_str_cmp_(ctx
->ptr_
, ctx
->num_
, str
->ptr_
, str
->num_
);
115 int a_str_cmpn(a_str
const *ctx
, void const *pdata
, a_size nbyte
)
117 return a_str_cmp_(ctx
->ptr_
, ctx
->num_
, pdata
, nbyte
);
120 int a_str_cmps(a_str
const *ctx
, void const *str
)
122 return a_str_cmp_(ctx
->ptr_
, ctx
->num_
, str
, strlen((char const *)str
));
125 int a_str_getc_(a_str
*ctx
)
130 c
= (int)ctx
->ptr_
[--ctx
->num_
];
135 int a_str_getc(a_str
*ctx
)
140 c
= (int)ctx
->ptr_
[--ctx
->num_
];
141 ctx
->ptr_
[ctx
->num_
] = 0;
146 int a_str_putc_(a_str
*ctx
, int c
)
148 if (a_str_alloc(ctx
, ctx
->num_
+ 1) == A_SUCCESS
)
150 ctx
->ptr_
[ctx
->num_
++] = (char)c
;
156 int a_str_putc(a_str
*ctx
, int c
)
158 if (a_str_alloc(ctx
, ctx
->num_
+ 2) == A_SUCCESS
)
160 ctx
->ptr_
[ctx
->num_
++] = (char)c
;
161 ctx
->ptr_
[ctx
->num_
] = 0;
167 a_size
a_str_getn_(a_str
*ctx
, void *pdata
, a_size nbyte
)
169 if (nbyte
> ctx
->num_
) { nbyte
= ctx
->num_
; }
173 if (pdata
) { a_copy(pdata
, ctx
->ptr_
+ ctx
->num_
, nbyte
); }
178 a_size
a_str_getn(a_str
*ctx
, void *pdata
, a_size nbyte
)
180 if (nbyte
> ctx
->num_
) { nbyte
= ctx
->num_
; }
184 if (pdata
) { a_copy(pdata
, ctx
->ptr_
+ ctx
->num_
, nbyte
); }
185 ctx
->ptr_
[ctx
->num_
] = 0;
190 int a_str_setn_(a_str
*ctx
, void const *pdata
, a_size nbyte
)
192 int ok
= a_str_alloc(ctx
, nbyte
);
193 if (ok
== A_SUCCESS
&& nbyte
)
195 a_copy(ctx
->ptr_
, pdata
, nbyte
);
201 int a_str_putn_(a_str
*ctx
, void const *pdata
, a_size nbyte
)
203 int ok
= a_str_alloc(ctx
, ctx
->num_
+ nbyte
);
204 if (ok
== A_SUCCESS
&& nbyte
)
206 a_copy(ctx
->ptr_
+ ctx
->num_
, pdata
, nbyte
);
212 int a_str_setn(a_str
*ctx
, void const *pdata
, a_size nbyte
)
214 int ok
= a_str_alloc(ctx
, nbyte
+ 1);
217 if (nbyte
) { a_copy(ctx
->ptr_
, pdata
, nbyte
); }
218 ctx
->ptr_
[nbyte
] = 0;
224 int a_str_putn(a_str
*ctx
, void const *pdata
, a_size nbyte
)
226 int ok
= a_str_alloc(ctx
, ctx
->num_
+ nbyte
+ 1);
231 a_copy(ctx
->ptr_
+ ctx
->num_
, pdata
, nbyte
);
234 ctx
->ptr_
[ctx
->num_
] = 0;
239 int a_str_sets_(a_str
*ctx
, void const *str
)
241 return a_str_setn_(ctx
, str
, strlen((char const *)str
));
243 int a_str_sets(a_str
*ctx
, void const *str
)
245 return a_str_setn(ctx
, str
, strlen((char const *)str
));
248 int a_str_puts_(a_str
*ctx
, void const *str
)
250 return a_str_putn_(ctx
, str
, strlen((char const *)str
));
252 int a_str_puts(a_str
*ctx
, void const *str
)
254 return a_str_putn(ctx
, str
, strlen((char const *)str
));
257 int a_str_set_(a_str
*ctx
, a_str
const *obj
)
259 return a_str_setn_(ctx
, obj
->ptr_
, obj
->num_
);
261 int a_str_set(a_str
*ctx
, a_str
const *obj
)
263 return a_str_setn(ctx
, obj
->ptr_
, obj
->num_
);
266 int a_str_put_(a_str
*ctx
, a_str
const *obj
)
268 return a_str_putn_(ctx
, obj
->ptr_
, obj
->num_
);
270 int a_str_put(a_str
*ctx
, a_str
const *obj
)
272 return a_str_putn(ctx
, obj
->ptr_
, obj
->num_
);
275 #if !defined va_copy && \
276 (A_PREREQ_GNUC(3, 0) || __has_builtin(__builtin_va_copy))
277 #define va_copy(d, s) __builtin_va_copy(d, s)
278 #elif !defined va_copy
279 #define va_copy(d, s) ((d) = (s))
283 int a_str_setv(a_str
*ctx
, char const *fmt
, va_list va
)
288 res
= vsnprintf(ctx
->ptr_
, ctx
->mem_
, fmt
, ap
);
290 if ((a_size
)res
+ 1 > ctx
->mem_
)
292 if (A_UNLIKELY(a_str_alloc_(ctx
, (a_size
)res
+ 1))) { return 0; }
293 res
= vsnprintf(ctx
->ptr_
, ctx
->mem_
, fmt
, va
);
295 if (res
>= 0) { ctx
->num_
= (a_size
)res
; }
299 int a_str_putv(a_str
*ctx
, char const *fmt
, va_list va
)
304 char *ptr
= ctx
->ptr_
;
305 if (ptr
) { ptr
+= ctx
->num_
; }
306 mem
= ctx
->mem_
- ctx
->num_
;
308 res
= vsnprintf(ptr
, mem
, fmt
, ap
);
310 mem
= ctx
->num_
+ (a_size
)(res
+ 1);
313 if (A_UNLIKELY(a_str_alloc_(ctx
, mem
))) { return 0; }
314 ptr
= ctx
->ptr_
+ ctx
->num_
;
315 mem
= ctx
->mem_
- ctx
->num_
;
316 res
= vsnprintf(ptr
, mem
, fmt
, va
);
318 if (res
> 0) { ctx
->num_
+= (a_size
)res
; }
322 int a_str_setf(a_str
*ctx
, char const *fmt
, ...)
327 res
= a_str_setv(ctx
, fmt
, va
);
332 int a_str_putf(a_str
*ctx
, char const *fmt
, ...)
337 res
= a_str_putv(ctx
, fmt
, va
);
344 a_size
a_str_utflen(a_str
const *ctx
)
349 char const *head
= ctx
->ptr_
;
350 char const *const tail
= head
+ ctx
->num_
;
351 unsigned int offset
= a_utf_decode(head
, A_NULL
);
352 for (; offset
; offset
= a_utf_decode(head
, A_NULL
))
356 if (head
>= tail
) { break; }