diff --git a/mx_util.c b/mx_util.c index f783ed38..e2b488ce 100644 --- a/mx_util.c +++ b/mx_util.c @@ -856,6 +856,47 @@ int mx_strscan_ll(char **str, long long int *to) return res; } +char *_mx_strconcat_do(char *first, ...) +{ + va_list ap; + char *join = NULL; + char *str; + char *ptr; + size_t len; + + if (!first) { + join = strdup(""); + return join; + } + + len = strlen(first); + + va_start(ap, first); + do { + str = va_arg(ap, char *); + if (!str) + break; + len += strlen(str); + } while(1); + va_end(ap); + + join = malloc(len+1); + if (!join) + return NULL; + + ptr = stpcpy(join, first); + va_start(ap, first); + do { + str = va_arg(ap, char *); + if (!str) + break; + ptr = stpcpy(ptr, str); + } while(1); + va_end(ap); + + return join; +} + int mx_sleep(unsigned int seconds) { if (seconds) diff --git a/mx_util.h b/mx_util.h index 508476c6..92614fe5 100644 --- a/mx_util.h +++ b/mx_util.h @@ -136,6 +136,9 @@ int mx_read_first_line_from_file(char *fname, char **line); int mx_strscan_ull(char **str, unsigned long long int *to); int mx_strscan_ll(char **str, long long int *to); +char *_mx_strconcat_do(char *first, ...); +#define mx_strconcat(s, ...) _mx_strconcat_do((s), ##__VA_ARGS__, NULL) + int mx_sleep(unsigned int seconds); int mx_sleep_nofail(unsigned int seconds); diff --git a/test_mx_util.c b/test_mx_util.c index 06cfe728..2f6be8f7 100644 --- a/test_mx_util.c +++ b/test_mx_util.c @@ -384,6 +384,27 @@ static void test_mx_strvec() { mx_strvec_free(strvec); } +static void test_mx_strcat() { + char *str; + char *str2; + + assert(str = mx_strconcat(NULL)); + assert(mx_streq(str, "")); + mx_free_null(str); + + assert(str = mx_strconcat("abc", "123")); + assert(mx_streq(str, "abc123")); + + assert(str2 = mx_strconcat(str, "def", str, "456")); + assert(mx_streq(str2, "abc123defabc123456")); + mx_free_null(str2); + + assert(str2 = mx_strconcat(str)); + assert(mx_streq(str, str2)); + mx_free_null(str); + mx_free_null(str2); +} + static void test_mx_cpuset(void) { cpu_set_t cpuset; @@ -421,6 +442,7 @@ int main(int argc, char *argv[]) test_mx_read_first_line_from_file(); test_mx_strscan(); test_mx_strvec(); + test_mx_strcat(); test_mx_cpuset(); return 0; }