|
@@ -1,199 +1,119 @@
|
|
|
-
|
|
|
- * argv.c
|
|
|
+
|
|
|
+ * @brief Functions to parse string to arguments.
|
|
|
*/
|
|
|
-#include "private.h"
|
|
|
-#include "lub/string.h"
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
+#include <stdio.h>
|
|
|
#include <string.h>
|
|
|
#include <assert.h>
|
|
|
#include <ctype.h>
|
|
|
|
|
|
-
|
|
|
-static void lub_argv_init(lub_argv_t * this, const char *line, size_t offset)
|
|
|
-{
|
|
|
- size_t len;
|
|
|
- const char *word;
|
|
|
- lub_arg_t *arg;
|
|
|
- size_t quoted;
|
|
|
-
|
|
|
- this->argv = NULL;
|
|
|
- this->argc = 0;
|
|
|
- if (!line)
|
|
|
- return;
|
|
|
-
|
|
|
- this->argc = lub_string_wordcount(line);
|
|
|
- if (0 == this->argc)
|
|
|
- return;
|
|
|
-
|
|
|
- arg = this->argv = faux_zmalloc(sizeof(lub_arg_t) * this->argc);
|
|
|
- assert(arg);
|
|
|
-
|
|
|
-
|
|
|
- for (word = lub_string_nextword(line, &len, &offset, "ed);
|
|
|
- *word || quoted;
|
|
|
- word = lub_string_nextword(word + len, &len, &offset, "ed)) {
|
|
|
- (*arg).arg = lub_string_ndecode(word, len);
|
|
|
- (*arg).offset = offset;
|
|
|
- (*arg).quoted = quoted ? BOOL_TRUE : BOOL_FALSE;
|
|
|
-
|
|
|
- offset += len;
|
|
|
-
|
|
|
- if (quoted) {
|
|
|
- len += quoted - 1;
|
|
|
- offset += quoted;
|
|
|
- }
|
|
|
- arg++;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-lub_argv_t *lub_argv_new(const char *line, size_t offset)
|
|
|
-{
|
|
|
- lub_argv_t *this;
|
|
|
-
|
|
|
- this = faux_zmalloc(sizeof(lub_argv_t));
|
|
|
- if (this)
|
|
|
- lub_argv_init(this, line, offset);
|
|
|
-
|
|
|
- return this;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-void lub_argv_add(lub_argv_t * this, const char *text)
|
|
|
-{
|
|
|
- lub_arg_t * arg;
|
|
|
-
|
|
|
- if (!text)
|
|
|
- return;
|
|
|
+#include "private.h"
|
|
|
+#include "faux/faux.h"
|
|
|
+#include "faux/str.h"
|
|
|
+#include "faux/list.h"
|
|
|
+#include "faux/argv.h"
|
|
|
|
|
|
-
|
|
|
- arg = realloc(this->argv, sizeof(lub_arg_t) * (this->argc + 1));
|
|
|
- assert(arg);
|
|
|
- this->argv = arg;
|
|
|
- (this->argv[this->argc++]).arg = strdup(text);
|
|
|
-}
|
|
|
|
|
|
-
|
|
|
-static void lub_argv_fini(lub_argv_t * this)
|
|
|
+
|
|
|
+ *
|
|
|
+ * Before working with argument list it must be allocated and initialized.
|
|
|
+ *
|
|
|
+ * @return Allocated and initialized argument list or NULL on error.
|
|
|
+ */
|
|
|
+faux_argv_t *faux_argv_new(void)
|
|
|
{
|
|
|
- unsigned i;
|
|
|
-
|
|
|
- for (i = 0; i < this->argc; i++)
|
|
|
- faux_free(this->argv[i].arg);
|
|
|
- faux_free(this->argv);
|
|
|
- this->argv = NULL;
|
|
|
-}
|
|
|
+ faux_argv_t *fargv = NULL;
|
|
|
|
|
|
-
|
|
|
-void lub_argv_delete(lub_argv_t * this)
|
|
|
-{
|
|
|
- lub_argv_fini(this);
|
|
|
- faux_free(this);
|
|
|
-}
|
|
|
+ fargv = faux_zmalloc(sizeof(*fargv));
|
|
|
+ assert(fargv);
|
|
|
+ if (!fargv)
|
|
|
+ return NULL;
|
|
|
|
|
|
-
|
|
|
-char *lub_argv__get_line(const lub_argv_t * this)
|
|
|
-{
|
|
|
- int space = 0;
|
|
|
- const char *p;
|
|
|
- unsigned i;
|
|
|
- char *line = NULL;
|
|
|
-
|
|
|
- for (i = 0; i < this->argc; i++) {
|
|
|
- if (i != 0)
|
|
|
- lub_string_cat(&line, " ");
|
|
|
- space = 0;
|
|
|
-
|
|
|
- for (p = this->argv[i].arg; *p; p++) {
|
|
|
- if (isspace(*p)) {
|
|
|
- space = 1;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- if (space)
|
|
|
- lub_string_cat(&line, "\"");
|
|
|
- lub_string_cat(&line, this->argv[i].arg);
|
|
|
- if (space)
|
|
|
- lub_string_cat(&line, "\"");
|
|
|
- }
|
|
|
+
|
|
|
+ fargv->list = faux_list_new(FAUX_LIST_UNSORTED, FAUX_LIST_NONUNIQUE,
|
|
|
+ NULL, NULL, (void (*)(void *))faux_str_free);
|
|
|
+ fargv->quotes = NULL;
|
|
|
|
|
|
- return line;
|
|
|
+ return fargv;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-char **lub_argv__get_argv(const lub_argv_t * this, const char *argv0)
|
|
|
-{
|
|
|
- char **result = NULL;
|
|
|
- unsigned i;
|
|
|
- unsigned a = 0;
|
|
|
-
|
|
|
- if (argv0)
|
|
|
- a = 1;
|
|
|
-
|
|
|
- result = faux_zmalloc(sizeof(char *) * (this->argc + 1 + a));
|
|
|
|
|
|
- if (argv0)
|
|
|
- result[0] = strdup(argv0);
|
|
|
- for (i = 0; i < this->argc; i++)
|
|
|
- result[i + a] = strdup(this->argv[i].arg);
|
|
|
- result[i + a] = NULL;
|
|
|
-
|
|
|
- return result;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-void lub_argv__free_argv(char **argv)
|
|
|
+
|
|
|
+ *
|
|
|
+ * After using the argv object must be freed. Function frees argv object.
|
|
|
+ */
|
|
|
+void faux_argv_free(faux_argv_t *fargv)
|
|
|
{
|
|
|
- unsigned i;
|
|
|
-
|
|
|
- if (!argv)
|
|
|
+ assert(fargv);
|
|
|
+ if (!fargv)
|
|
|
return;
|
|
|
|
|
|
- for (i = 0; argv[i]; i++)
|
|
|
- faux_free(argv[i]);
|
|
|
- faux_free(argv);
|
|
|
+ faux_list_free(fargv->list);
|
|
|
+ faux_str_free(fargv->quotes);
|
|
|
+ faux_free(fargv);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-const char *lub_argv__get_arg(const lub_argv_t *this, unsigned int index)
|
|
|
-{
|
|
|
- const char *result = NULL;
|
|
|
|
|
|
- if (!this)
|
|
|
+
|
|
|
+ *
|
|
|
+ * Before iterating with the faux_argv_each() function the iterator must be
|
|
|
+ * initialized. This function do it.
|
|
|
+ *
|
|
|
+ * @param [in] fargv Allocated and initialized argv object.
|
|
|
+ * @return Initialized iterator.
|
|
|
+ * @sa faux_argv_each()
|
|
|
+ */
|
|
|
+faux_argv_node_t *faux_argv_iter(const faux_argv_t *fargv)
|
|
|
+{
|
|
|
+ assert(fargv);
|
|
|
+ if (!fargv)
|
|
|
return NULL;
|
|
|
- if (this->argc > index)
|
|
|
- result = this->argv[index].arg;
|
|
|
|
|
|
- return result;
|
|
|
+ return (faux_argv_node_t *)faux_list_head(fargv->list);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-unsigned lub_argv__get_count(const lub_argv_t * this)
|
|
|
+
|
|
|
+
|
|
|
+ *
|
|
|
+ * Before iteration the iterator must be initialized by faux_argv_iter()
|
|
|
+ * function. Doesn't use faux_argv_each() with uninitialized iterator.
|
|
|
+ *
|
|
|
+ * On each call function returns string (argument) and modifies iterator.
|
|
|
+ * Stop iteration when function returns NULL.
|
|
|
+ *
|
|
|
+ * @param [in,out] iter Iterator.
|
|
|
+ * @return String.
|
|
|
+ * @sa faux_argv_iter()
|
|
|
+ */
|
|
|
+const char *faux_argv_each(faux_argv_node_t **iter)
|
|
|
{
|
|
|
- return this->argc;
|
|
|
+ return (const char *)faux_list_each((faux_list_node_t **)iter);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-size_t lub_argv__get_offset(const lub_argv_t * this, unsigned index)
|
|
|
-{
|
|
|
- size_t result = 0;
|
|
|
|
|
|
- if (this->argc > index)
|
|
|
- result = this->argv[index].offset;
|
|
|
+void faux_argv_quotes(faux_argv_t *fargv, const char *quotes)
|
|
|
+{
|
|
|
+ assert(fargv);
|
|
|
+ if (!fargv)
|
|
|
+ return;
|
|
|
|
|
|
- return result;
|
|
|
+ faux_str_free(fargv->quotes);
|
|
|
+ if (!quotes) {
|
|
|
+ fargv->quotes = NULL;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ fargv->quotes = faux_str_dup(quotes);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-bool_t lub_argv__get_quoted(const lub_argv_t * this, unsigned index)
|
|
|
+
|
|
|
+ssize_t faux_argv_parse_str(faux_argv_t *fargv, const char *str)
|
|
|
{
|
|
|
- bool_t result = BOOL_FALSE;
|
|
|
+ assert(fargv);
|
|
|
+ if (!fargv)
|
|
|
+ return -1;
|
|
|
|
|
|
- if (this->argc > index)
|
|
|
- result = this->argv[index].quoted;
|
|
|
|
|
|
- return result;
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
-
|