Browse Source

faux.argv: Some base functions

Serj Kalichev 4 years ago
parent
commit
a52056b71a
7 changed files with 114 additions and 257 deletions
  1. 3 0
      faux/Makefile.am
  2. 17 69
      faux/argv.h
  3. 3 0
      faux/argv/Makefile.am
  4. 81 161
      faux/argv/argv.c
  5. 0 6
      faux/argv/module.am
  6. 6 17
      faux/argv/private.h
  7. 4 4
      faux/ini/ini.c

+ 3 - 0
faux/Makefile.am

@@ -16,6 +16,7 @@ nobase_include_HEADERS += \
 	faux/list.h \
 	faux/ini.h \
 	faux/file.h \
+	faux/argv.h \
 	faux/testc_helpers.h
 
 EXTRA_DIST += \
@@ -28,6 +29,7 @@ EXTRA_DIST += \
 	faux/list/Makefile.am \
 	faux/ini/Makefile.am \
 	faux/file/Makefile.am \
+	faux/argv/Makefile.am \
 	faux/testc_helpers/Makefile.am
 
 include $(top_srcdir)/faux/base/Makefile.am
@@ -39,6 +41,7 @@ include $(top_srcdir)/faux/log/Makefile.am
 include $(top_srcdir)/faux/list/Makefile.am
 include $(top_srcdir)/faux/ini/Makefile.am
 include $(top_srcdir)/faux/file/Makefile.am
+include $(top_srcdir)/faux/argv/Makefile.am
 include $(top_srcdir)/faux/testc_helpers/Makefile.am
 
 if TESTC

+ 17 - 69
faux/argv.h

@@ -1,79 +1,27 @@
-/*
- * argv.h
+/** @file argv.h
+ * @brief Parse string to arguments.
  */
-/**
-\ingroup lub
-\defgroup lub_argv argv
-@{
 
-\brief This utility provides a simple means of manipulating a vector of 
-command textual words.
+#ifndef _faux_argv_h
+#define _faux_argv_h
 
-A word is either separated by whitespace, or if quotes are used a word is
-defined by the scope of the quotes.
+#include "faux/faux.h"
+#include "faux/list.h"
 
-e.g.
-\verbatim
-one two "this is the third word" four
-\endverbatim
-contains four "words" the third of which is a string.
+typedef struct faux_argv_s faux_argv_t;
+typedef faux_list_node_t faux_argv_node_t;
 
-*/
-#ifndef _lub_argv_h
-#define _lub_argv_h
+C_DECL_BEGIN
 
-#include <stddef.h>
+faux_argv_t *faux_argv_new(void);
+void faux_argv_free(faux_argv_t *fargv);
+void faux_argv_quotes(faux_argv_t *fargv, const char *quotes);
 
-#include "c_decl.h"
-#include "faux.h"
+faux_argv_node_t *faux_argv_iter(const faux_argv_t *fargv);
+const char *faux_argv_each(faux_argv_node_t **iter);
 
-_BEGIN_C_DECL
-/**
- * This type is used to reference an instance of an argument vector
- */
-typedef struct lub_argv_s lub_argv_t;
-
-/*=====================================
- * ARGV INTERFACE
- *===================================== */
-/**
- *  This operation is used to construct an instance of this class. The client
- * species a string and an offset within that string, from which to start
- * collecting "words" to place into the vector instance.
- *
- * \pre
- * - none
- *
- * \return
- * - A instance of an argument vector, which represents the words contained in
- * the provided string.
- * - NULL if there is insuffcient resource
- *
- * \post
- * - The client becomes resposible for releasing the instance when they are
- *   finished with it, by calling lub_argv_delete()
- */
-lub_argv_t *lub_argv_new(
-	/**
-         * The string to analyse
-         */
-	const char *line,
-	/**
-         * The offset in the string to start from
-         */
-	size_t offset);
+ssize_t faux_argv_parse_str(faux_argv_t *fargv, const char *str);
 
-void lub_argv_delete(lub_argv_t * instance);
-unsigned lub_argv__get_count(const lub_argv_t * instance);
-const char *lub_argv__get_arg(const lub_argv_t * instance, unsigned index);
-size_t lub_argv__get_offset(const lub_argv_t * instance, unsigned index);
-bool_t lub_argv__get_quoted(const lub_argv_t * instance, unsigned index);
-void lub_argv__set_arg(lub_argv_t * instance, unsigned index, const char *arg);
-char **lub_argv__get_argv(const lub_argv_t * instance, const char *argv0);
-void lub_argv__free_argv(char **argv);
-char *lub_argv__get_line(const lub_argv_t * instance);
-void lub_argv_add(lub_argv_t * instance, const char *text);
+C_DECL_END
 
-_END_C_DECL
-#endif				/* _lub_argv_h */
-/** @} lub_argv */
+#endif				/* _faux_argv_h */

+ 3 - 0
faux/argv/Makefile.am

@@ -0,0 +1,3 @@
+libfaux_la_SOURCES += \
+	faux/argv/argv.c \
+	faux/argv/private.h

+ 81 - 161
faux/argv/argv.c

@@ -1,199 +1,119 @@
-/*
- * argv.c
+/** @file 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;
-	/* first of all count the words in the line */
-	this->argc = lub_string_wordcount(line);
-	if (0 == this->argc)
-		return;
-	/* allocate space to hold the vector */
-	arg = this->argv = faux_zmalloc(sizeof(lub_arg_t) * this->argc);
-	assert(arg);
-
-	/* then fill out the array with the words */
-	for (word = lub_string_nextword(line, &len, &offset, &quoted);
-		*word || quoted;
-		word = lub_string_nextword(word + len, &len, &offset, &quoted)) {
-		(*arg).arg = lub_string_ndecode(word, len);
-		(*arg).offset = offset;
-		(*arg).quoted = quoted ? BOOL_TRUE : BOOL_FALSE;
-
-		offset += len;
-
-		if (quoted) {
-			len += quoted - 1; /* account for terminating quotation mark */
-			offset += quoted; /* account for quotation marks */
-		}
-		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"
 
-	/* allocate space to hold the vector */
-	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)
+/** @brief Allocates new argv object.
+ *
+ * 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;
-		/* Search for spaces */
-		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, "\"");
-	}
+	// Init
+	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)
+/** @brief Frees the argv object object.
+ *
+ * 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)
+/** @brief Initializes iterator to iterate through the entire argv object.
+ *
+ * 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)
+
+/** @brief Iterate entire argv object for arguments.
+ *
+ * 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; // No additional quotes
+		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;
 }
 
-/*--------------------------------------------------------- */

+ 0 - 6
faux/argv/module.am

@@ -1,6 +0,0 @@
-liblub_la_SOURCES += \
-	lub/argv/argv.c \
-	lub/argv/private.h
-
-
-

+ 6 - 17
faux/argv/private.h

@@ -1,19 +1,8 @@
-/*
- * private.h
- *
- * Class to deal with splitting a command line into multiple arguments.
- * This class deals with full quoted text "like this" as a single argument.
- */
-#include "lub/argv.h"
+#include "faux/faux.h"
+#include "faux/list.h"
+#include "faux/argv.h"
 
-typedef struct lub_arg_s lub_arg_t;
-struct lub_arg_s {
-	char *arg;
-	size_t offset;
-	bool_t quoted;
-};
-
-struct lub_argv_s {
-	unsigned argc;
-	lub_arg_t *argv;
+struct faux_argv_s {
+	faux_list_t *list;
+	char *quotes; // List of possible quotes chars
 };

+ 4 - 4
faux/ini/ini.c

@@ -23,7 +23,7 @@
  */
 faux_ini_t *faux_ini_new(void)
 {
-	faux_ini_t *ini;
+	faux_ini_t *ini = NULL;
 
 	ini = faux_zmalloc(sizeof(*ini));
 	if (!ini)
@@ -39,7 +39,7 @@ faux_ini_t *faux_ini_new(void)
 
 /** @brief Frees the INI object.
  *
- * After using the INI object must be freed. Function frees INI objecr itself
+ * After using the INI object must be freed. Function frees INI object itself
  * and all pairs 'name/value' stored within INI object.
  */
 void faux_ini_free(faux_ini_t *ini)
@@ -195,7 +195,7 @@ faux_ini_node_t *faux_ini_iter(const faux_ini_t *ini)
  * Before iteration the iterator must be initialized by faux_ini_iter()
  * function. Doesn't use faux_ini_each() with uninitialized iterator.
  *
- * On each call function returns pair 'name/value' and modify iterator.
+ * On each call function returns pair 'name/value' and modifies iterator.
  * Stop iteration when function returns NULL.
  *
  * @param [in,out] iter Iterator.
@@ -226,7 +226,7 @@ const faux_pair_t *faux_ini_each(faux_ini_node_t **iter)
  */
 static char *faux_ini_purify_word(const char *str)
 {
-	const char *word;
+	const char *word = NULL;
 	const char *string = str;
 	bool_t quoted = BOOL_FALSE;
 	size_t len = 0;