Introduce the StringArray type

This breaks the libSystem API.
This commit is contained in:
Pierre Pronchery 2018-01-23 05:08:14 +01:00
parent 9381c413f7
commit b82b1b510e
5 changed files with 38 additions and 19 deletions

View File

@ -23,8 +23,20 @@
/* Array */ /* Array */
/* macros */ /* 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; \ 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) \ static Array * name ## array_new(void) \
{ return array_new(sizeof(type)); } { return array_new(sizeof(type)); }

View File

@ -19,12 +19,15 @@
# define LIBSYSTEM_SYSTEM_STRING_H # define LIBSYSTEM_SYSTEM_STRING_H
# include <sys/types.h> # include <sys/types.h>
# include "array.h"
/* String */ /* String */
/* types */ /* types */
typedef char String; typedef char String;
ARRAY3(String *, string, String)
/* macros */ /* macros */
/* XXX for compatibility */ /* 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, int string_compare_length(String const * string, String const * string2,
size_t length); 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); String * string_find(String const * string, String const * key);
ssize_t string_index(String const * string, String const * key); ssize_t string_index(String const * string, String const * key);

View File

@ -53,7 +53,7 @@ typedef struct _EventTimeout
EventTimeoutFunc func; EventTimeoutFunc func;
void * data; void * data;
} EventTimeout; } EventTimeout;
ARRAY(EventTimeout *, eventtimeout) ARRAY2(EventTimeout *, eventtimeout)
typedef struct _EventIO typedef struct _EventIO
{ {
@ -61,7 +61,7 @@ typedef struct _EventIO
EventIOFunc func; EventIOFunc func;
void * data; void * data;
} EventIO; } EventIO;
ARRAY(EventIO *, eventio) ARRAY2(EventIO *, eventio)
struct _Event struct _Event
{ {

View File

@ -32,7 +32,7 @@ typedef struct _HashEntry
void const * key; void const * key;
void * value; void * value;
} HashEntry; } HashEntry;
ARRAY(HashEntry, _hashentry) ARRAY2(HashEntry, _hashentry)
#define HashEntryArray _hashentryArray #define HashEntryArray _hashentryArray

View File

@ -260,12 +260,10 @@ int string_compare_length(String const * string, String const * string2,
/* string_explode */ /* string_explode */
/* FIXME return a StringArray instead? */ StringArray * string_explode(String const * string, String const * separator)
String ** string_explode(String const * string, String const * separator)
{ {
String ** ret = NULL; StringArray * ret;
size_t ret_cnt = 0; String * p; /* temporary pointer */
String ** p; /* temporary pointer */
size_t i; /* current position */ size_t i; /* current position */
String const * s; /* &string[i] */ String const * s; /* &string[i] */
ssize_t j; /* position of the next separator */ 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, fprintf(stderr, "DEBUG: %s(\"%s\", \"%s\")\n", __func__, string,
separator); separator);
#endif #endif
if((ret = stringarray_new()) == NULL)
return NULL;
if(separator == NULL || (l = string_get_length(separator)) == 0) if(separator == NULL || (l = string_get_length(separator)) == 0)
{ {
error_set_code(-EINVAL, "%s", strerror(EINVAL)); error_set_code(-EINVAL, "%s", strerror(EINVAL));
array_delete(ret);
return NULL; return NULL;
} }
for(i = 0;; i += j + l) for(i = 0;; i += j + l)
@ -287,31 +288,34 @@ String ** string_explode(String const * string, String const * separator)
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "DEBUG: %s(): i=%zu, j=%zd\n", __func__, i, j); fprintf(stderr, "DEBUG: %s(): i=%zu, j=%zd\n", __func__, i, j);
#endif #endif
if((p = realloc(ret, sizeof(*ret) * (ret_cnt + 2))) == NULL)
break;
ret = p;
if(j < 0) 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; break;
}
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "DEBUG: %s(): \"%s\"\n", __func__, fprintf(stderr, "DEBUG: %s(): \"%s\"\n", __func__,
ret[ret_cnt - 1]); ret[ret_cnt - 1]);
#endif #endif
ret[ret_cnt++] = NULL;
return ret; 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; break;
}
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "DEBUG: %s(): \"%s\"\n", __func__, fprintf(stderr, "DEBUG: %s(): \"%s\"\n", __func__,
ret[ret_cnt - 1]); ret[ret_cnt - 1]);
#endif #endif
} }
/* free everything */ /* free everything */
for(p = ret; *p != NULL; p++) array_foreach(ret, (ArrayForeach)string_delete, NULL);
string_delete(*p); array_delete(ret);
free(ret);
return NULL; return NULL;
} }