X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=string.c;h=e5de147c65975c21018b3e0b6d30eb932e52edf1;hp=aa3bcbddabe425cc823e3ad5e567f707f70dbccb;hb=24758c5f;hpb=6101e63b98b5517b65bd967e6efbb0af47738084 diff --git a/string.c b/string.c index aa3bcbdd..e5de147c 100644 --- a/string.c +++ b/string.c @@ -1,12 +1,11 @@ /* - * Copyright (C) 2004-2012 Andre Noll + * Copyright (C) 2004-2013 Andre Noll * * Licensed under the GPL v2. For licencing details see COPYING. */ /** \file string.c Memory allocation and string handling functions. */ -#include /* gettimeofday */ #include #include /* uname() */ #include @@ -800,7 +799,7 @@ int compute_word_num(const char *buf, const char *delim, int point) } /** - * Free an array of words created by create_argv(). + * Free an array of words created by create_argv() or create_shifted_argv(). * * \param argv A pointer previously obtained by \ref create_argv(). */ @@ -815,6 +814,35 @@ void free_argv(char **argv) free(argv); } +static int create_argv_offset(int offset, const char *buf, const char *delim, + char ***result) +{ + char *word, **argv = para_malloc((offset + 1) * sizeof(char *)); + const char *p; + int i, ret; + + for (i = 0; i < offset; i++) + argv[i] = NULL; + for (p = buf; p && *p; p += ret, i++) { + ret = get_next_word(p, delim, &word); + if (ret < 0) + goto err; + if (!ret) + break; + argv = para_realloc(argv, (i + 2) * sizeof(char*)); + argv[i] = word; + } + argv[i] = NULL; + *result = argv; + return i; +err: + while (i > 0) + free(argv[--i]); + free(argv); + *result = NULL; + return ret; +} + /** * Split a buffer into words. * @@ -831,28 +859,47 @@ void free_argv(char **argv) */ int create_argv(const char *buf, const char *delim, char ***result) { - char *word, **argv = para_malloc(2 * sizeof(char *)); - const char *p; - int ret, num_words; + return create_argv_offset(0, buf, delim, result); +} - for (p = buf, num_words = 0; ; p += ret, num_words++) { - ret = get_next_word(p, delim, &word); - if (ret < 0) - goto err; - if (!ret) - break; - argv = para_realloc(argv, (num_words + 2) * sizeof(char*)); - argv[num_words] = word; - } - argv[num_words] = NULL; - *result = argv; - return num_words; -err: - while (num_words > 0) - free(argv[--num_words]); - free(argv); - *result = NULL; - return ret; +/** + * Split a buffer into words, offset one. + * + * This is similar to \ref create_argv() but the returned array is one element + * larger, words start at index one and element zero is initialized to \p NULL. + * Callers must set element zero to a non-NULL value before calling free_argv() + * on the returned array to avoid a memory leak. + * + * \param buf See \ref create_argv(). + * \param delim See \ref create_argv(). + * \param result See \ref create_argv(). + * + * \return Number of words plus one on success, negative on errors. + */ +int create_shifted_argv(const char *buf, const char *delim, char ***result) +{ + return create_argv_offset(1, buf, delim, result); +} + +/** + * Find out if the given string is contained in the arg vector. + * + * \param arg The string to look for. + * \param argv The array to search. + * + * \return The first index whose value equals \a arg, or \p -E_ARG_NOT_FOUND if + * arg was not found in \a argv. + */ +int find_arg(const char *arg, char **argv) +{ + int i; + + if (!argv) + return -E_ARG_NOT_FOUND; + for (i = 0; argv[i]; i++) + if (strcmp(arg, argv[i]) == 0) + return i; + return -E_ARG_NOT_FOUND; } /**