diff --git a/incdefs.sh b/incdefs.sh index cf00eaf..5bbdcea 100755 --- a/incdefs.sh +++ b/incdefs.sh @@ -23,12 +23,15 @@ # user_flags() { + # Needed for vasprintf(). + printf " -D_GNU_SOURCE" + dirs=$(echo "" | ${CROSS_COMPILE}cpp -Wp,-v 2>&1 >/dev/null | grep ^" /") for d in $dirs; do files=$(find $d -type f -name time.h) for f in $files; do if grep -q clock_adjtime $f; then - printf " -D_GNU_SOURCE -DHAVE_CLOCK_ADJTIME" + printf " -DHAVE_CLOCK_ADJTIME" return fi done diff --git a/util.c b/util.c index cb428b1..06c3296 100644 --- a/util.c +++ b/util.c @@ -18,6 +18,7 @@ */ #include #include +#include #include #include #include @@ -342,3 +343,97 @@ int is_running(void) { return running; } + +char *string_newf(const char *format, ...) +{ + va_list ap; + char *s; + + va_start(ap, format); + if (vasprintf(&s, format, ap) < 0) + s = NULL; + va_end(ap); + + return s; +} + +void string_append(char **s, const char *str) +{ + size_t len1, len2; + + len1 = strlen(*s); + len2 = strlen(str); + *s = realloc(*s, len1 + len2 + 1); + if (*s) + memcpy((*s) + len1, str, len2 + 1); +} + +void string_appendf(char **s, const char *format, ...) +{ + va_list ap; + size_t len1, len2; + char *s2; + + len1 = strlen(*s); + + va_start(ap, format); + len2 = vasprintf(&s2, format, ap); + va_end(ap); + + if (len2 < 0) { + *s = NULL; + return; + } + + *s = realloc(*s, len1 + len2 + 1); + if (*s) + memcpy((*s) + len1, s2, len2 + 1); + free(s2); +} + +void **parray_new(void) +{ + void **a = malloc(sizeof(*a)); + + if (a) + *a = NULL; + return a; +} + +void parray_append(void ***a, void *p) +{ + parray_extend(a, p, NULL); +} + +void parray_extend(void ***a, ...) +{ + va_list ap; + int ilen, len, alloced; + void *p; + + for (len = 0; (*a)[len]; len++) + ; + len++; + + va_start(ap, a); + for (ilen = 0; va_arg(ap, void *); ilen++) + ; + va_end(ap); + + /* Reallocate in exponentially increasing sizes. */ + for (alloced = 1; alloced < len; alloced <<= 1) + ; + if (alloced < len + ilen) { + while (alloced < len + ilen) + alloced *= 2; + *a = realloc(*a, alloced * sizeof **a); + if (!*a) + return; + } + + va_start(ap, a); + while ((p = va_arg(ap, void *))) + (*a)[len++ - 1] = p; + va_end(ap); + (*a)[len - 1] = NULL; +} diff --git a/util.h b/util.h index bb29e11..98b395b 100644 --- a/util.h +++ b/util.h @@ -236,4 +236,61 @@ int handle_term_signals(void); */ int is_running(void); +/** + * Get an allocated and formatted string. This is a wrapper around asprintf(). + * + * @param format printf() format string. + * @param ... printf() arguments. + * @return Pointer to the allocated string, NULL on error. + */ +#ifdef __GNUC__ +__attribute__ ((format (printf, 1, 2))) +#endif +char *string_newf(const char *format, ...); + +/** + * Reallocate a string and append another string to it. + * + * @param s String that should be extended, set to NULL on error. + * @param str String appended to s. + */ +void string_append(char **s, const char *str); +#ifdef __GNUC__ +__attribute__ ((format (printf, 2, 3))) +#endif +/** + * Reallocate a string and append a formatted string to it. + * + * @param s String that should be extended, set to NULL on error. + * @param format printf() format string. + * @param ... printf() arguments. + */ +void string_appendf(char **s, const char *format, ...); + +/** + * Get an empty array of pointers terminated by NULL. + * + * @return Pointer to the allocated array, NULL on error. + */ +void **parray_new(void); + +/** + * Append pointer to a NULL-terminated pointer array. The array is reallocated + * in exponentially increasing sizes. + * + * @param a Pointer to pointer array, set to NULL on error. + * @param p Pointer appended to the array. + */ +void parray_append(void ***a, void *p); + + +/** + * Append pointers to a NULL-terminated pointer array. The array is reallocated + * in exponentially increasing sizes. + * + * @param a Pointer to pointer array, set to NULL on error. + * @param ... NULL-terminated list of pointers. + */ +void parray_extend(void ***a, ...); + #endif