X-Git-Url: http://git.tuebingen.mpg.de/?p=dss.git;a=blobdiff_plain;f=string.c;h=d370a81667af4c56509a9d85d9712b6c3a268a92;hp=ac9c336ed7a599fac069221741be4d72e2060367;hb=17eea857c175123d68e7dffc28134befa4c0aa5f;hpb=a0b87ba0529cc6ab075e1d7a11f8b4adc47948eb diff --git a/string.c b/string.c index ac9c336..d370a81 100644 --- a/string.c +++ b/string.c @@ -1,5 +1,11 @@ +/* + * Copyright (C) 2004-2010 Andre Noll + * + * Licensed under the GPL v2. For licencing details see COPYING. + */ #include #include +#include #include #include #include @@ -9,14 +15,11 @@ #include -#include "cmdline.h" #include "gcc-compat.h" #include "log.h" #include "error.h" #include "string.h" -__noreturn void clean_exit(int status); - /** * Write a message to a dynamically allocated string. * @@ -71,7 +74,7 @@ __must_check __malloc void *dss_realloc(void *p, size_t size) if (!(p = realloc(p, size))) { DSS_EMERG_LOG("realloc failed (size = %zu), aborting\n", size); - clean_exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } return p; } @@ -96,7 +99,7 @@ __must_check __malloc void *dss_malloc(size_t size) if (!p) { DSS_EMERG_LOG("malloc failed (size = %zu), aborting\n", size); - clean_exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } return p; } @@ -142,7 +145,7 @@ __must_check __malloc char *dss_strdup(const char *s) if ((ret = strdup(s? s: ""))) return ret; DSS_EMERG_LOG("strdup failed, aborting\n"); - clean_exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } /** @@ -166,12 +169,6 @@ __must_check __printf_1_2 __malloc char *make_message(const char *fmt, ...) return msg; } -__printf_1_2 void make_err_msg(const char* fmt,...) -{ - free(dss_error_txt); - VSPRINTF(fmt, dss_error_txt); -} - /** * Get the home directory of the current user. * @@ -201,22 +198,14 @@ int dss_atoi64(const char *str, int64_t *value) errno = 0; /* To distinguish success/failure after call */ tmp = strtoll(str, &endptr, 10); - if (errno == ERANGE && (tmp == LLONG_MAX || tmp == LLONG_MIN)) { - make_err_msg("%s", str); + if (errno == ERANGE && (tmp == LLONG_MAX || tmp == LLONG_MIN)) return -E_ATOI_OVERFLOW; - } - if (errno != 0 && tmp == 0) { /* other error */ - make_err_msg("%s", str); + if (errno != 0 && tmp == 0) /* other error */ return -E_STRTOLL; - } - if (endptr == str) { - make_err_msg("%s", str); + if (endptr == str) return -E_ATOI_NO_DIGITS; - } - if (*endptr != '\0') { /* Further characters after number */ - make_err_msg("%s", str); + if (*endptr != '\0') /* Further characters after number */ return -E_ATOI_JUNK_AT_END; - } *value = tmp; return 1; } @@ -236,3 +225,52 @@ __must_check __malloc char *dss_logname(void) return dss_strdup(pw? pw->pw_name : "unknown_user"); } +/** + * Split string and return pointers to its parts. + * + * \param args The string to be split. + * \param argv_ptr Pointer to the list of substrings. + * \param delim Delimiter. + * + * This function modifies \a args by replacing each occurance of \a delim by + * zero. A \p NULL-terminated array of pointers to char* is allocated dynamically + * and these pointers are initialized to point to the broken-up substrings + * within \a args. A pointer to this array is returned via \a argv_ptr. + * + * \return The number of substrings found in \a args. + */ +__must_check unsigned split_args(char *args, char *** const argv_ptr, const char *delim) +{ + char *p = args; + char **argv; + size_t n = 0, i, j; + + p = args + strspn(args, delim); + for (;;) { + i = strcspn(p, delim); + if (!i) + break; + p += i; + n++; + p += strspn(p, delim); + } + *argv_ptr = dss_malloc((n + 1) * sizeof(char *)); + argv = *argv_ptr; + i = 0; + p = args + strspn(args, delim); + while (p) { + argv[i] = p; + j = strcspn(p, delim); + if (!j) + break; + p += strcspn(p, delim); + if (*p) { + *p = '\0'; + p++; + p += strspn(p, delim); + } + i++; + } + argv[n] = NULL; + return n; +}