From 133bb25dfedb8fe02dacf790fd032330c4fc11ae Mon Sep 17 00:00:00 2001 From: James Bonfield Date: Wed, 17 Jul 2013 17:51:13 +0100 Subject: [PATCH] Merged with attractivechaos/klib: - add upstream kvsprintf and rework ksprintf - add upstream printf attribute checks - use our kputw (has MIN_INT bug fix) - keep our extra functions (kputc_, kputsn_, kputl) Added ks_str and ks_len functions for tidier manipulation of internals. Added error checking to all functions that allocate memory and could potentially fail; ie return EOF or negative values as per stdio equivalents. --- kstring.c | 25 ++++++++----- kstring.h | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 112 insertions(+), 16 deletions(-) diff --git a/kstring.c b/kstring.c index 8ecda50..f029317 100644 --- a/kstring.c +++ b/kstring.c @@ -67,15 +67,22 @@ int ksplit_core(char *s, int delimiter, int *_max, int **_offsets) n = 0; max = *_max; offsets = *_offsets; l = strlen(s); -#define __ksplit_aux do { \ - if (_offsets) { \ - s[i] = 0; \ - if (n == max) { \ - max = max? max<<1 : 2; \ - offsets = (int*)realloc(offsets, sizeof(int) * max); \ - } \ - offsets[n++] = last_start; \ - } else ++n; \ +#define __ksplit_aux do { \ + if (_offsets) { \ + s[i] = 0; \ + if (n == max) { \ + int *tmp; \ + max = max? max<<1 : 2; \ + if ((tmp = (int*)realloc(offsets, sizeof(int) * max))) { \ + offsets = tmp; \ + } else { \ + free(offsets); \ + *_offsets = NULL; \ + return 0; \ + } \ + } \ + offsets[n++] = last_start; \ + } else ++n; \ } while (0) for (i = 0, last_char = last_start = 0; i <= l; ++i) { diff --git a/kstring.h b/kstring.h index 13a5559..9438b7f 100644 --- a/kstring.h +++ b/kstring.h @@ -30,6 +30,7 @@ #include #include #include +#include #ifndef kroundup32 #define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) @@ -77,21 +78,40 @@ extern "C" { } #endif -static inline void ks_resize(kstring_t *s, size_t size) +static inline int ks_resize(kstring_t *s, size_t size) { if (s->m < size) { + char *tmp; s->m = size; kroundup32(s->m); - s->s = (char*)realloc(s->s, s->m); + if ((tmp = (char*)realloc(s->s, s->m))) + s->s = tmp; + else + return -1; } + return 0; +} + +static inline char *ks_str(kstring_t *s) +{ + return s->s; +} + +static inline size_t ks_len(kstring_t *s) +{ + return s->l; } static inline int kputsn(const char *p, int l, kstring_t *s) { if (s->l + l + 1 >= s->m) { + char *tmp; s->m = s->l + l + 2; kroundup32(s->m); - s->s = (char*)realloc(s->s, s->m); + if ((tmp = (char*)realloc(s->s, s->m))) + s->s = tmp; + else + return EOF; } memcpy(s->s + s->l, p, l); s->l += l; @@ -107,26 +127,66 @@ static inline int kputs(const char *p, kstring_t *s) static inline int kputc(int c, kstring_t *s) { if (s->l + 1 >= s->m) { + char *tmp; s->m = s->l + 2; kroundup32(s->m); - s->s = (char*)realloc(s->s, s->m); + if ((tmp = (char*)realloc(s->s, s->m))) + s->s = tmp; + else + return EOF; } s->s[s->l++] = c; s->s[s->l] = 0; return c; } +static inline int kputc_(int c, kstring_t *s) +{ + if (s->l + 1 > s->m) { + char *tmp; + s->m = s->l + 1; + kroundup32(s->m); + if ((tmp = (char*)realloc(s->s, s->m))) + s->s = tmp; + else + return EOF; + } + s->s[s->l++] = c; + return 1; +} + +static inline int kputsn_(const void *p, int l, kstring_t *s) +{ + if (s->l + l > s->m) { + char *tmp; + s->m = s->l + l; + kroundup32(s->m); + if ((tmp = (char*)realloc(s->s, s->m))) + s->s = tmp; + else + return EOF; + } + memcpy(s->s + s->l, p, l); + s->l += l; + return l; +} + static inline int kputw(int c, kstring_t *s) { char buf[16]; int l, x; if (c == 0) return kputc('0', s); - for (l = 0, x = c < 0? -c : c; x > 0; x /= 10) buf[l++] = x%10 + '0'; + if (c < 0) for (l = 0, x = c; x < 0; x /= 10) buf[l++] = '0' - (x%10); + else for (l = 0, x = c; x > 0; x /= 10) buf[l++] = x%10 + '0'; if (c < 0) buf[l++] = '-'; if (s->l + l + 1 >= s->m) { + char *tmp; s->m = s->l + l + 2; kroundup32(s->m); - s->s = (char*)realloc(s->s, s->m); + if ((tmp = (char*)realloc(s->s, s->m))) + s->s = tmp; + else + return EOF; } for (x = l - 1; x >= 0; --x) s->s[s->l++] = buf[x]; s->s[s->l] = 0; @@ -141,15 +201,44 @@ static inline int kputuw(unsigned c, kstring_t *s) if (c == 0) return kputc('0', s); for (l = 0, x = c; x > 0; x /= 10) buf[l++] = x%10 + '0'; if (s->l + l + 1 >= s->m) { + char *tmp; s->m = s->l + l + 2; kroundup32(s->m); - s->s = (char*)realloc(s->s, s->m); + if ((tmp = (char*)realloc(s->s, s->m))) + s->s = tmp; + else + return EOF; } for (i = l - 1; i >= 0; --i) s->s[s->l++] = buf[i]; s->s[s->l] = 0; return 0; } +static inline int kputl(long c, kstring_t *s) +{ + char buf[32]; + long l, x; + if (c == 0) return kputc('0', s); + for (l = 0, x = c < 0? -c : c; x > 0; x /= 10) buf[l++] = x%10 + '0'; + if (c < 0) buf[l++] = '-'; + if (s->l + l + 1 >= s->m) { + char *tmp; + s->m = s->l + l + 2; + kroundup32(s->m); + if ((tmp = (char*)realloc(s->s, s->m))) + s->s = tmp; + else + return EOF; + } + for (x = l - 1; x >= 0; --x) s->s[s->l++] = buf[x]; + s->s[s->l] = 0; + return 0; +} + +/* + * Returns 's' split by delimiter, with *n being the number of components; + * NULL on failue. + */ static inline int *ksplit(kstring_t *s, int delimiter, int *n) { int max = 0, *offsets = 0; -- 2.47.3