From b82b1b510e722ef63dd9678ff9286977c2ff9737 Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Tue, 23 Jan 2018 05:08:14 +0100 Subject: [PATCH] Introduce the StringArray type This breaks the libSystem API. --- include/System/array.h | 14 +++++++++++++- include/System/string.h | 5 ++++- src/event.c | 4 ++-- src/hash.c | 2 +- src/string.c | 32 ++++++++++++++++++-------------- 5 files changed, 38 insertions(+), 19 deletions(-) diff --git a/include/System/array.h b/include/System/array.h index 072ecf6..2b7c7b9 100644 --- a/include/System/array.h +++ b/include/System/array.h @@ -23,8 +23,20 @@ /* Array */ /* macros */ -# define ARRAY(type, name) \ +/* XXX avoid using attributes */ +# define ARRAY(type) \ + typedef struct _Array type ## Array; \ + static Array * type ## array_new(void) __attribute__ ((unused)); \ + static Array * type ## array_new(void) \ + { return array_new(sizeof(type)); } +# define ARRAY2(type, name) \ typedef struct _Array name ## Array; \ + static Array * name ## array_new(void) __attribute__ ((unused)); \ + static Array * name ## array_new(void) \ + { return array_new(sizeof(type)); } +# define ARRAY3(type, name, prefix) \ + typedef struct _Array prefix ## Array; \ + static Array * name ## array_new(void) __attribute__ ((unused)); \ static Array * name ## array_new(void) \ { return array_new(sizeof(type)); } diff --git a/include/System/string.h b/include/System/string.h index 04fe4cc..d476ccd 100644 --- a/include/System/string.h +++ b/include/System/string.h @@ -19,12 +19,15 @@ # define LIBSYSTEM_SYSTEM_STRING_H # include +# include "array.h" /* String */ /* types */ typedef char String; +ARRAY3(String *, string, String) + /* macros */ /* XXX for compatibility */ @@ -57,7 +60,7 @@ int string_compare(String const * string, String const * string2); int string_compare_length(String const * string, String const * string2, size_t length); -String ** string_explode(String const * string, String const * separator); +StringArray * string_explode(String const * string, String const * separator); String * string_find(String const * string, String const * key); ssize_t string_index(String const * string, String const * key); diff --git a/src/event.c b/src/event.c index 799701d..1617f76 100644 --- a/src/event.c +++ b/src/event.c @@ -53,7 +53,7 @@ typedef struct _EventTimeout EventTimeoutFunc func; void * data; } EventTimeout; -ARRAY(EventTimeout *, eventtimeout) +ARRAY2(EventTimeout *, eventtimeout) typedef struct _EventIO { @@ -61,7 +61,7 @@ typedef struct _EventIO EventIOFunc func; void * data; } EventIO; -ARRAY(EventIO *, eventio) +ARRAY2(EventIO *, eventio) struct _Event { diff --git a/src/hash.c b/src/hash.c index 999c8d8..79c7ce3 100644 --- a/src/hash.c +++ b/src/hash.c @@ -32,7 +32,7 @@ typedef struct _HashEntry void const * key; void * value; } HashEntry; -ARRAY(HashEntry, _hashentry) +ARRAY2(HashEntry, _hashentry) #define HashEntryArray _hashentryArray diff --git a/src/string.c b/src/string.c index 749792a..19306db 100644 --- a/src/string.c +++ b/src/string.c @@ -260,12 +260,10 @@ int string_compare_length(String const * string, String const * string2, /* string_explode */ -/* FIXME return a StringArray instead? */ -String ** string_explode(String const * string, String const * separator) +StringArray * string_explode(String const * string, String const * separator) { - String ** ret = NULL; - size_t ret_cnt = 0; - String ** p; /* temporary pointer */ + StringArray * ret; + String * p; /* temporary pointer */ size_t i; /* current position */ String const * s; /* &string[i] */ ssize_t j; /* position of the next separator */ @@ -275,9 +273,12 @@ String ** string_explode(String const * string, String const * separator) fprintf(stderr, "DEBUG: %s(\"%s\", \"%s\")\n", __func__, string, separator); #endif + if((ret = stringarray_new()) == NULL) + return NULL; if(separator == NULL || (l = string_get_length(separator)) == 0) { error_set_code(-EINVAL, "%s", strerror(EINVAL)); + array_delete(ret); return NULL; } for(i = 0;; i += j + l) @@ -287,31 +288,34 @@ String ** string_explode(String const * string, String const * separator) #ifdef DEBUG fprintf(stderr, "DEBUG: %s(): i=%zu, j=%zd\n", __func__, i, j); #endif - if((p = realloc(ret, sizeof(*ret) * (ret_cnt + 2))) == NULL) - break; - ret = p; if(j < 0) { - if((ret[ret_cnt++] = string_new(s)) == NULL) + if((p = string_new(s)) == NULL + || array_append(ret, p) != 0) + { + string_delete(p); break; + } #ifdef DEBUG fprintf(stderr, "DEBUG: %s(): \"%s\"\n", __func__, ret[ret_cnt - 1]); #endif - ret[ret_cnt++] = NULL; return ret; } - if((ret[ret_cnt++] = string_new_length(s, j)) == NULL) + if((p = string_new_length(s, j)) == NULL + || array_append(ret, p) != 0) + { + string_delete(p); break; + } #ifdef DEBUG fprintf(stderr, "DEBUG: %s(): \"%s\"\n", __func__, ret[ret_cnt - 1]); #endif } /* free everything */ - for(p = ret; *p != NULL; p++) - string_delete(*p); - free(ret); + array_foreach(ret, (ArrayForeach)string_delete, NULL); + array_delete(ret); return NULL; }