libstr-c

C string library
git clone https://git.sinitax.com/sinitax/libstr-c
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

str.c (2671B)


      1#include "str.h"
      2
      3#include <string.h>
      4#include <errno.h>
      5#include <stdio.h>
      6#include <stdarg.h>
      7#include <stdlib.h>
      8
      9char *
     10str_fmt(const struct allocator *allocator, int *rc, const char *fmtstr, ...)
     11{
     12	va_list ap, cpy;
     13	char *str;
     14	ssize_t n;
     15
     16	LIBSTR_ABORT_ON_ARGS(!allocator || !fmtstr);
     17
     18	va_copy(cpy, ap);
     19
     20	va_start(cpy, fmtstr);
     21	n = vsnprintf(NULL, 0, fmtstr, cpy);
     22	va_end(cpy);
     23
     24	if (n <= 0) {
     25		if (rc) *rc = 1;
     26		return NULL;
     27	}
     28
     29	str = allocator->alloc(allocator, (size_t) (n + 1), rc);
     30	LIBSTR_ABORT_ON_ALLOC(!str);
     31	if (!str && rc) *rc = -*rc;
     32	if (!str) return NULL;
     33
     34	va_start(ap, fmtstr);
     35	vsnprintf(str, (size_t) (n + 1), fmtstr, ap);
     36	va_end(ap);
     37
     38	return str;
     39}
     40
     41char *
     42str_fmt_realloc(const struct allocator *allocator, int *rc,
     43	void *alloc, const char *fmtstr, ...)
     44{
     45	va_list ap, cpy;
     46	char *str;
     47	ssize_t n;
     48
     49	LIBSTR_ABORT_ON_ARGS(!allocator || !fmtstr);
     50
     51	va_copy(cpy, ap);
     52
     53	va_start(cpy, fmtstr);
     54	n = vsnprintf(NULL, 0, fmtstr, cpy);
     55	va_end(cpy);
     56
     57	if (n <= 0) {
     58		if (rc) *rc = 1;
     59		return NULL;
     60	}
     61
     62	str = allocator->realloc(allocator, alloc, (size_t) (n + 1), rc);
     63	LIBSTR_ABORT_ON_ALLOC(!str);
     64	if (!str && rc) *rc = -*rc;
     65	if (!str) return NULL;
     66
     67	va_start(ap, fmtstr);
     68	vsnprintf(str, (size_t) (n + 1), fmtstr, ap);
     69	va_end(ap);
     70
     71	return str;
     72}
     73
     74char *
     75str_dup(const struct allocator *allocator, int *rc, const char *str)
     76{
     77	return str_ndup(allocator, rc, str, strlen(str));
     78}
     79
     80char *
     81str_dup_realloc(const struct allocator *allocator, int *rc,
     82	void *alloc, const char *str)
     83{
     84	return str_ndup_realloc(allocator, rc, alloc, str, strlen(str));
     85}
     86
     87char *
     88str_ndup(const struct allocator *allocator, int *rc, const char *str, size_t n)
     89{
     90	char *nstr;
     91
     92	LIBSTR_ABORT_ON_ARGS(!allocator || !str);
     93
     94	nstr = allocator->alloc(allocator, n + 1, rc);
     95	LIBSTR_ABORT_ON_ALLOC(!nstr);
     96	if (!nstr && rc) *rc = -*rc;
     97	if (!nstr) return NULL;
     98
     99	strncpy(nstr, str, n + 1);
    100
    101	return nstr;
    102}
    103
    104char *
    105str_ndup_realloc(const struct allocator *allocator, int *rc,
    106	void *alloc, const char *str, size_t n)
    107{
    108	char *nstr;
    109
    110	LIBSTR_ABORT_ON_ARGS(!allocator || !str);
    111
    112	nstr = allocator->realloc(allocator, alloc, n + 1, rc);
    113	LIBSTR_ABORT_ON_ALLOC(!nstr);
    114	if (!nstr && rc) *rc = -*rc;
    115	if (!nstr) return NULL;
    116
    117	strncpy(nstr, str, n + 1);
    118
    119	return nstr;
    120}
    121
    122char *
    123str_app(const struct allocator *allocator, int *rc, char *str, const char *app)
    124{
    125	size_t slen, alen;
    126
    127	LIBSTR_ABORT_ON_ARGS(!allocator);
    128
    129	alen = strlen(app);
    130	slen = str ? strlen(str) : 0;
    131
    132	str = allocator->realloc(allocator, str, slen + alen + 1, rc);
    133	LIBSTR_ABORT_ON_ALLOC(!str);
    134	if (!str && rc) *rc = -*rc;
    135	if (!str) return NULL;
    136
    137	memcpy(str + slen, app, alen + 1);
    138
    139	return str;
    140}