]> git.kaiwu.me - klib.git/commitdiff
Merged with attractivechaos/klib:
authorJames Bonfield <jkb@sanger.ac.uk>
Wed, 17 Jul 2013 16:51:13 +0000 (17:51 +0100)
committerJames Bonfield <jkb@sanger.ac.uk>
Wed, 17 Jul 2013 16:51:13 +0000 (17:51 +0100)
- 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
kstring.h

index 8ecda502b893669b68c2e587532e17b2325861c0..f0293172a8fd6c739271c6a117379df794d94aa1 100644 (file)
--- 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) {
index 13a555972029820d3a503402a8700b0266b42112..9438b7faf8b2649d97dc6896239a4cd3e9e8d303 100644 (file)
--- a/kstring.h
+++ b/kstring.h
@@ -30,6 +30,7 @@
 #include <string.h>
 #include <stdarg.h>
 #include <stdint.h>
+#include <stdio.h>
 
 #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;