create float sum and mean for Rust
[liba.git] / src / str.c
blob9cf836ab04077cc4f06ceb654f100b3f41a23e25
1 #if defined(_MSC_VER)
2 #if !defined _CRT_SECURE_NO_WARNINGS
3 #define _CRT_SECURE_NO_WARNINGS /* NOLINT */
4 #endif /* _CRT_SECURE_NO_WARNINGS */
5 #endif /* _MSC_VER */
6 #include "a/str.h"
8 a_str *a_str_new(void)
10 a_str *const ctx = (a_str *)a_alloc(A_NULL, sizeof(a_str));
11 if (ctx) { a_str_ctor(ctx); }
12 return ctx;
15 void a_str_die(a_str *ctx)
17 if (ctx)
19 a_str_dtor(ctx);
20 a_alloc(ctx, 0);
24 void a_str_ctor(a_str *ctx)
26 ctx->ptr_ = A_NULL;
27 ctx->num_ = 0;
28 ctx->mem_ = 0;
31 void a_str_dtor(a_str *ctx)
33 if (ctx->ptr_)
35 a_alloc(ctx->ptr_, 0);
36 ctx->ptr_ = A_NULL;
38 ctx->num_ = 0;
39 ctx->mem_ = 0;
42 int a_str_copy(a_str *ctx, a_str const *obj)
44 int ok;
45 a_str_ctor(ctx);
46 ok = a_str_alloc_(ctx, obj->num_ + 1);
47 if (ok == A_SUCCESS)
49 if (obj->num_) { a_copy(ctx->ptr_, obj->ptr_, obj->num_); }
50 ctx->ptr_[obj->num_] = 0;
51 ctx->num_ = obj->num_;
53 return ok;
56 void a_str_move(a_str *ctx, a_str *obj)
58 a_copy(ctx, obj, sizeof(*obj));
59 a_zero(obj, sizeof(*obj));
62 char *a_str_exit(a_str *ctx)
64 char *const str = ctx->ptr_;
65 if (ctx->ptr_)
67 ctx->ptr_[ctx->num_] = 0;
68 ctx->ptr_ = A_NULL;
70 ctx->num_ = 0;
71 ctx->mem_ = 0;
72 return str;
75 int a_str_alloc_(a_str *ctx, a_size mem)
77 char *ptr;
78 mem = a_size_up(sizeof(void *), mem);
79 ptr = (char *)a_alloc(ctx->ptr_, mem);
80 if (ptr || mem == 0)
82 ctx->ptr_ = ptr;
83 ctx->mem_ = mem;
84 return A_SUCCESS;
86 return A_FAILURE;
89 int a_str_alloc(a_str *ctx, a_size mem)
91 if (mem > ctx->mem_)
93 return a_str_alloc_(ctx, mem);
95 return A_SUCCESS;
98 int a_str_cmp_(void const *p0, a_size n0, void const *p1, a_size n1)
100 int ok;
101 if (p0 && p1)
103 ok = memcmp(p0, p1, A_MIN(n0, n1));
104 if (ok) { return ok; }
106 return (n0 > n1) - (n0 < n1);
109 int a_str_cmp(a_str const *ctx, a_str const *str)
111 return a_str_cmp_(ctx->ptr_, ctx->num_, str->ptr_, str->num_);
114 int a_str_cmpn(a_str const *ctx, void const *pdata, a_size nbyte)
116 return a_str_cmp_(ctx->ptr_, ctx->num_, pdata, nbyte);
119 int a_str_cmps(a_str const *ctx, void const *str)
121 return a_str_cmp_(ctx->ptr_, ctx->num_, str, strlen((char const *)str));
124 int a_str_getc_(a_str *ctx)
126 int c = ~0;
127 if (ctx->num_)
129 c = (int)ctx->ptr_[--ctx->num_];
131 return c;
134 int a_str_getc(a_str *ctx)
136 int c = ~0;
137 if (ctx->num_)
139 c = (int)ctx->ptr_[--ctx->num_];
140 ctx->ptr_[ctx->num_] = 0;
142 return c;
145 int a_str_putc_(a_str *ctx, int c)
147 if (a_str_alloc(ctx, ctx->num_ + 1) == A_SUCCESS)
149 ctx->ptr_[ctx->num_++] = (char)c;
150 return c;
152 return ~0;
155 int a_str_putc(a_str *ctx, int c)
157 if (a_str_alloc(ctx, ctx->num_ + 2) == A_SUCCESS)
159 ctx->ptr_[ctx->num_++] = (char)c;
160 ctx->ptr_[ctx->num_] = 0;
161 return c;
163 return ~0;
166 a_size a_str_getn_(a_str *ctx, void *pdata, a_size nbyte)
168 if (nbyte > ctx->num_) { nbyte = ctx->num_; }
169 if (nbyte)
171 ctx->num_ -= nbyte;
172 if (pdata) { a_copy(pdata, ctx->ptr_ + ctx->num_, nbyte); }
174 return nbyte;
177 a_size a_str_getn(a_str *ctx, void *pdata, a_size nbyte)
179 if (nbyte > ctx->num_) { nbyte = ctx->num_; }
180 if (nbyte)
182 ctx->num_ -= nbyte;
183 if (pdata) { a_copy(pdata, ctx->ptr_ + ctx->num_, nbyte); }
184 ctx->ptr_[ctx->num_] = 0;
186 return nbyte;
189 int a_str_setn_(a_str *ctx, void const *pdata, a_size nbyte)
191 int ok = a_str_alloc(ctx, nbyte);
192 if (ok == A_SUCCESS && nbyte)
194 a_copy(ctx->ptr_, pdata, nbyte);
195 ctx->num_ = nbyte;
197 return ok;
200 int a_str_putn_(a_str *ctx, void const *pdata, a_size nbyte)
202 int ok = a_str_alloc(ctx, ctx->num_ + nbyte);
203 if (ok == A_SUCCESS && nbyte)
205 a_copy(ctx->ptr_ + ctx->num_, pdata, nbyte);
206 ctx->num_ += nbyte;
208 return ok;
211 int a_str_setn(a_str *ctx, void const *pdata, a_size nbyte)
213 int ok = a_str_alloc(ctx, nbyte + 1);
214 if (ok == A_SUCCESS)
216 if (nbyte) { a_copy(ctx->ptr_, pdata, nbyte); }
217 ctx->ptr_[nbyte] = 0;
218 ctx->num_ = nbyte;
220 return ok;
223 int a_str_putn(a_str *ctx, void const *pdata, a_size nbyte)
225 int ok = a_str_alloc(ctx, ctx->num_ + nbyte + 1);
226 if (ok == A_SUCCESS)
228 if (nbyte)
230 a_copy(ctx->ptr_ + ctx->num_, pdata, nbyte);
231 ctx->num_ += nbyte;
233 ctx->ptr_[ctx->num_] = 0;
235 return ok;
238 int a_str_sets_(a_str *ctx, void const *str)
240 return a_str_setn_(ctx, str, strlen((char const *)str));
242 int a_str_sets(a_str *ctx, void const *str)
244 return a_str_setn(ctx, str, strlen((char const *)str));
247 int a_str_puts_(a_str *ctx, void const *str)
249 return a_str_putn_(ctx, str, strlen((char const *)str));
251 int a_str_puts(a_str *ctx, void const *str)
253 return a_str_putn(ctx, str, strlen((char const *)str));
256 int a_str_set_(a_str *ctx, a_str const *obj)
258 return a_str_setn_(ctx, obj->ptr_, obj->num_);
260 int a_str_set(a_str *ctx, a_str const *obj)
262 return a_str_setn(ctx, obj->ptr_, obj->num_);
265 int a_str_put_(a_str *ctx, a_str const *obj)
267 return a_str_putn_(ctx, obj->ptr_, obj->num_);
269 int a_str_put(a_str *ctx, a_str const *obj)
271 return a_str_putn(ctx, obj->ptr_, obj->num_);
274 #include <stdio.h>
276 int a_str_setv(a_str *ctx, char const *fmt, va_list va)
278 int res;
279 va_list ap;
280 va_copy(ap, va);
281 res = vsnprintf(ctx->ptr_, ctx->mem_, fmt, ap);
282 va_end(ap);
283 if ((a_size)res + 1 > ctx->mem_)
285 if (A_UNLIKELY(a_str_alloc_(ctx, (a_size)res + 1))) { return 0; }
286 va_copy(ap, va);
287 res = vsnprintf(ctx->ptr_, ctx->mem_, fmt, ap);
288 va_end(ap);
290 if (res >= 0) { ctx->num_ = (a_size)res; }
291 return res;
294 int a_str_putv(a_str *ctx, char const *fmt, va_list va)
296 int res;
297 va_list ap;
298 a_size mem;
299 char *ptr = ctx->ptr_ ? ctx->ptr_ + ctx->num_ : ctx->ptr_;
300 va_copy(ap, va);
301 mem = ctx->mem_ - ctx->num_;
302 res = vsnprintf(ptr, mem, fmt, ap);
303 mem = ctx->num_ + (a_size)(res + 1);
304 va_end(ap);
305 if (mem > ctx->mem_)
307 if (A_UNLIKELY(a_str_alloc_(ctx, mem))) { return 0; }
308 va_copy(ap, va);
309 ptr = ctx->ptr_ + ctx->num_;
310 mem = ctx->mem_ - ctx->num_;
311 res = vsnprintf(ptr, mem, fmt, ap);
312 va_end(ap);
314 if (res > 0) { ctx->num_ += (a_size)res; }
315 return res;
318 int a_str_setf(a_str *ctx, char const *fmt, ...)
320 int res;
321 va_list va;
322 va_start(va, fmt);
323 res = a_str_setv(ctx, fmt, va);
324 va_end(va);
325 return res;
328 int a_str_putf(a_str *ctx, char const *fmt, ...)
330 int res;
331 va_list va;
332 va_start(va, fmt);
333 res = a_str_putv(ctx, fmt, va);
334 va_end(va);
335 return res;
338 #include "a/utf.h"
340 a_size a_str_utflen(a_str const *ctx)
342 a_size length = 0;
343 if (ctx->num_)
345 char const *head = ctx->ptr_;
346 char const *const tail = head + ctx->num_;
347 unsigned int offset = a_utf_decode(head, A_NULL);
348 for (; offset; offset = a_utf_decode(head, A_NULL))
350 ++length;
351 head += offset;
352 if (head >= tail) { break; }
355 return length;