/*
- * Copyright (C) 2004-2012 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 2004-2013 Andre Noll <maan@systemlinux.org>
*
* Licensed under the GPL v2. For licencing details see COPYING.
*/
}
/**
- * Used to distinguish between read-only and read-write mode.
+ * Controls behavior of for_each_complete_line().
*
* \sa for_each_line(), for_each_line_ro().
*/
-enum for_each_line_modes{
+enum for_each_line_flags {
/** Activate read-only mode. */
- LINE_MODE_RO,
- /** Activate read-write mode. */
- LINE_MODE_RW
+ FELF_READ_ONLY = 1 << 0,
};
-static int for_each_complete_line(enum for_each_line_modes mode, char *buf,
+static int for_each_complete_line(unsigned flags, char *buf,
size_t size, line_handler_t *line_handler, void *private_data)
{
char *start = buf, *end;
start = ++end;
continue;
}
- if (mode == LINE_MODE_RO) {
+ if (flags & FELF_READ_ONLY) {
size_t s = end - start;
char *b = para_malloc(s + 1);
memcpy(b, start, s);
return ret;
start = ++end;
}
- if (!line_handler || mode == LINE_MODE_RO)
+ if (!line_handler || (flags & FELF_READ_ONLY))
return num_lines;
i = buf + size - start;
if (i && i != size)
int for_each_line(char *buf, size_t size, line_handler_t *line_handler,
void *private_data)
{
- return for_each_complete_line(LINE_MODE_RW, buf, size, line_handler,
- private_data);
+ return for_each_complete_line(0, buf, size, line_handler, private_data);
}
/**
int for_each_line_ro(char *buf, size_t size, line_handler_t *line_handler,
void *private_data)
{
- return for_each_complete_line(LINE_MODE_RO, buf, size, line_handler,
+ return for_each_complete_line(FELF_READ_ONLY, buf, size, line_handler,
private_data);
}
}
/**
- * 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().
*/
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.
*
*/
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;
}
/**