ckiss

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 55f587ec2b698c13db8296be3fc60ed321ce0911
parent 775467c94dd003050758aa6f787b9133c20fb49a
Author: aabacchus <ben@bvnf.space>
Date:   Sat, 22 Apr 2023 04:05:52 +0100

add append_to_array utility function

Diffstat:
Msrc/ckiss.h | 5+++++
Msrc/utils.c | 62++++++++++++++++++++++++++++++--------------------------------
2 files changed, 35 insertions(+), 32 deletions(-)

diff --git a/src/ckiss.h b/src/ckiss.h @@ -50,6 +50,11 @@ noreturn void die_perror(const char *s); * terminated with a NULL. Returned string must be freed by caller.*/ char *concat(char *s, ...); +/* Appends to *arr (allocs if NULL). If you don't know the length of arr but it + * has a terminating NULL, supply an n < 0. If s should be strdup'd then set dup + * to true. */ +char **append_to_array(char ***arr, char *s, int n, bool dup); + /* splits s by any delimiters in sep into an array of strings. Each string and * the array must be freed by the caller. */ char **split(char *s, char *sep); diff --git a/src/utils.c b/src/utils.c @@ -93,40 +93,51 @@ concat(char *s, ...) { } char ** +append_to_array(char ***arr, char *s, int n, bool dup) { + if (n < 0) { + /* need to walk it to find out how many existing entries. */ + n = 0; + if (*arr) { + char **t = *arr; + while (*t != NULL) { + t++; + n++; + } + } + } + char **tmp = realloc(*arr, sizeof(char *) * ++n); + if (tmp == NULL) { + free(*arr); + die_perror("realloc"); + } + *arr = tmp; + (*arr)[n - 1] = dup ? strdup(s) : s; + return *arr; +} + +char ** split(char *s, char *sep) { if (s == NULL) return NULL; - char **res = NULL, **tmp; + char **res = NULL; char *p = strtok(s, sep); int n = 0; while (p) { - tmp = realloc(res, sizeof(char *) * ++n); - if (tmp == NULL) { - free(res); - die_perror("realloc"); - } - res = tmp; - res[n - 1] = strdup(p); + append_to_array(&res, p, n++, true); p = strtok(NULL, sep); } /* add a NULL terminator */ - tmp = realloc(res, sizeof(char *) * (n + 1)); - if (tmp == NULL) { - free(res); - die_perror("realloc"); - } - res = tmp; - res[n] = NULL; + append_to_array(&res, NULL, n, false); return res; } char ** find_in_path(char *name, char **path, mode_t test_flags, bool limit, bool isglob) { - char **s = NULL, **tmp; + char **s = NULL; int n = 0; if (path == NULL || name == NULL) return s; @@ -164,17 +175,10 @@ find_in_path(char *name, char **path, mode_t test_flags, bool limit, bool isglob free(list[j]); } else { char *found = list[j]; - tmp = realloc(s, sizeof(char *) * ++n); - if (tmp == NULL) { - free(found); - free(s); - free(list); - die_perror("realloc"); - } - s = tmp; - s[n - 1] = found; + append_to_array(&s, found, n++, false); if (limit) { free(list); + append_to_array(&s, NULL, n, false); return s; } } @@ -183,13 +187,7 @@ find_in_path(char *name, char **path, mode_t test_flags, bool limit, bool isglob } if (s != NULL) { /* add terminating NULL */ - tmp = realloc(s, sizeof(char *) * (n+1)); - if (tmp == NULL) { - free(s); - die_perror("realloc"); - } - s = tmp; - s[n] = NULL; + append_to_array(&s, NULL, n, false); } return s; }