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}