Browse Source

Move parse function from pargv to shell class

git-svn-id: https://klish.googlecode.com/svn/trunk@433 0eaa4687-2ee9-07dd-09d9-bcdd2d2dd5fb
Serj Kalichev 13 years ago
parent
commit
39b4383e7f

+ 2 - 3
clish/param.h

@@ -50,8 +50,7 @@ typedef enum {
  * meta functions
  *----------------- */
 clish_param_t *clish_param_new(const char *name,
-	const char *text, clish_ptype_t *ptype,
-	clish_var_expand_fn_t *fn);
+	const char *text, clish_ptype_t *ptype);
 /*-----------------
  * methods
  *----------------- */
@@ -84,7 +83,7 @@ char *clish_param__get_value(const clish_param_t * instance);
 void clish_param__set_hidden(clish_param_t * instance, bool_t hidden);
 bool_t clish_param__get_hidden(const clish_param_t * instance);
 void clish_param__set_test(clish_param_t * instance, const char *test);
-char *clish_param__get_test(const clish_param_t *instance, void *context);
+char *clish_param__get_test(const clish_param_t *instance);
 
 /* paramv methods */
 clish_paramv_t *clish_paramv_new(void);

+ 5 - 8
clish/param/param.c

@@ -17,13 +17,12 @@
  * PRIVATE METHODS
  *--------------------------------------------------------- */
 static void clish_param_init(clish_param_t *this, const char *name,
-	const char *text, clish_ptype_t *ptype, clish_var_expand_fn_t *fn)
+	const char *text, clish_ptype_t *ptype)
 {
 	/* initialise the help part */
 	this->name = lub_string_dup(name);
 	this->text = lub_string_dup(text);
 	this->ptype = ptype;
-	this->var_expand_fn = fn ? fn : clish_var_expand_default;
 
 	/* set up defaults */
 	this->defval = NULL;
@@ -58,12 +57,12 @@ static void clish_param_fini(clish_param_t * this)
  * PUBLIC META FUNCTIONS
  *--------------------------------------------------------- */
 clish_param_t *clish_param_new(const char *name, const char *text,
-	clish_ptype_t *ptype, clish_var_expand_fn_t *fn)
+	clish_ptype_t *ptype)
 {
 	clish_param_t *this = malloc(sizeof(clish_param_t));
 
 	if (this)
-		clish_param_init(this, name, text, ptype, fn);
+		clish_param_init(this, name, text, ptype);
 	return this;
 }
 
@@ -361,9 +360,7 @@ void clish_param__set_test(clish_param_t * this, const char *test)
 }
 
 /*--------------------------------------------------------- */
-char *clish_param__get_test(const clish_param_t * this, void *context)
+char *clish_param__get_test(const clish_param_t *this)
 {
-	if (!this->test)
-		return NULL;
-	return this->var_expand_fn(this->test, context);
+	return this->test;
 }

+ 0 - 1
clish/param/private.h

@@ -23,5 +23,4 @@ struct clish_param_s {
 	bool_t optional;
 	bool_t hidden;
 	char *test; /* the condition */
-	clish_var_expand_fn_t *var_expand_fn;
 };

+ 1 - 12
clish/pargv.h

@@ -43,20 +43,9 @@ const clish_parg_t *clish_pargv_find_arg(clish_pargv_t * instance,
 	const char *name);
 int clish_pargv_insert(clish_pargv_t * instance,
 	const clish_param_t * param, const char *value);
-clish_pargv_status_t clish_pargv_analyze(clish_pargv_t *instance,
-	const clish_command_t * cmd,
-	void *context,
-	const char *line,
-	size_t offset);
-clish_pargv_status_t clish_pargv_parse(clish_pargv_t *instance,
-	const clish_command_t * cmd,
-	void *context,
-	clish_paramv_t *paramv,
-	const lub_argv_t *argv,
-	unsigned *idx, clish_pargv_t *last, unsigned need_index);
 void clish_pargv_dump(const clish_pargv_t * instance);
 /*-----------------
- * attributes 
+ * attributes
  *----------------- */
 unsigned clish_pargv__get_count(clish_pargv_t * instance);
 clish_parg_t *clish_pargv__get_parg(clish_pargv_t * instance, unsigned index);

+ 0 - 276
clish/pargv/pargv.c

@@ -67,260 +67,6 @@ int clish_pargv_insert(clish_pargv_t * this,
 	return 0;
 }
 
-/*--------------------------------------------------------- */
-clish_pargv_status_t clish_pargv_parse(clish_pargv_t * this,
-	const clish_command_t * cmd,
-	void *context,
-	clish_paramv_t * paramv,
-	const lub_argv_t * argv,
-	unsigned *idx, clish_pargv_t * last, unsigned need_index)
-{
-	unsigned argc = lub_argv__get_count(argv);
-	unsigned index = 0;
-	unsigned nopt_index = 0;
-	clish_param_t *nopt_param = NULL;
-	unsigned i;
-	clish_pargv_status_t retval;
-	unsigned paramc = clish_paramv__get_count(paramv);
-	int up_level = 0; /* Is it a first level of param nesting? */
-
-	assert(this);
-	assert(cmd);
-
-	/* Check is it a first level of PARAM nesting. */
-	if (paramv == clish_command__get_paramv(cmd))
-		up_level = 1;
-
-	while (index < paramc) {
-		const char *arg = NULL;
-		clish_param_t *param = clish_paramv__get_param(paramv,index);
-		clish_param_t *cparam = NULL;
-		int is_switch = 0;
-
-		/* Use real arg or PARAM's default value as argument */
-		if (*idx < argc)
-			arg = lub_argv__get_arg(argv, *idx);
-
-		/* Is parameter in "switch" mode? */
-		if (CLISH_PARAM_SWITCH == clish_param__get_mode(param))
-			is_switch = 1;
-
-		/* Check the 'test' conditions */
-		if (param) {
-			char *str = clish_param__get_test(param, context);
-			if (str && !lub_system_line_test(str)) {
-				lub_string_free(str);
-				index++;
-				continue;
-			}
-			lub_string_free(str);
-		}
-
-		/* Add param for help and completion */
-		if (last && (*idx == need_index) &&
-			(NULL == clish_pargv_find_arg(this, clish_param__get_name(param)))) {
-			if (is_switch) {
-				unsigned rec_paramc = clish_param__get_param_count(param);
-				for (i = 0; i < rec_paramc; i++) {
-					cparam = clish_param__get_param(param, i);
-					if (!cparam)
-						break;
-					if (CLISH_PARAM_SUBCOMMAND ==
-						clish_param__get_mode(cparam)) {
-						const char *pname =
-							clish_param__get_value(cparam);
-						if (!arg || (arg && 
-							(pname == lub_string_nocasestr(pname,
-							arg))))
-							clish_pargv_insert(last,
-								cparam, arg);
-					} else {
-						clish_pargv_insert(last,
-							cparam, arg);
-					}
-				}
-			} else {
-				if (CLISH_PARAM_SUBCOMMAND ==
-					clish_param__get_mode(param)) {
-					const char *pname =
-					    clish_param__get_value(param);
-					if (!arg || (arg &&
-						(pname == lub_string_nocasestr(pname, arg))))
-						clish_pargv_insert(last, param, arg);
-				} else {
-					clish_pargv_insert(last, param, arg);
-				}
-			}
-		}
-
-		/* Set parameter value */
-		if (param) {
-			char *validated = NULL;
-			clish_paramv_t *rec_paramv =
-			    clish_param__get_paramv(param);
-			unsigned rec_paramc =
-			    clish_param__get_param_count(param);
-
-			/* Save the index of last non-option parameter
-			 * to restore index if the optional parameters
-			 * will be used.
-			 */
-			if (BOOL_TRUE != clish_param__get_optional(param)) {
-				nopt_param = param;
-				nopt_index = index;
-			}
-
-			/* Validate the current parameter. */
-			if (NULL != clish_pargv_find_arg(this, clish_param__get_name(param))) {
-				/* Duplicated parameter */
-				validated = NULL;
-			} else if (is_switch) {
-				for (i = 0; i < rec_paramc; i++) {
-					cparam =
-					    clish_param__get_param(param, i);
-					if (!cparam)
-						break;
-					if ((validated =
-					    arg ? clish_param_validate(cparam,
-								       arg) :
-					    NULL)) {
-						rec_paramv =
-						    clish_param__get_paramv
-						    (cparam);
-						rec_paramc =
-						    clish_param__get_param_count
-						    (cparam);
-						break;
-					}
-				}
-			} else {
-				validated =
-				    arg ? clish_param_validate(param,
-							       arg) : NULL;
-			}
-
-			if (validated) {
-				/* add (or update) this parameter */
-				if (is_switch) {
-					clish_pargv_insert(this, param,
-						clish_param__get_name(cparam));
-					clish_pargv_insert(this, cparam,
-						validated);
-				} else {
-					clish_pargv_insert(this, param,
-						validated);
-				}
-				lub_string_free(validated);
-
-				/* Next command line argument */
-				/* Don't change idx if this is the last
-				   unfinished optional argument.
-				 */
-				if (!(clish_param__get_optional(param) &&
-					(*idx == need_index) &&
-					(need_index == (argc - 1))))
-				(*idx)++;
-
-				/* Walk through the nested parameters */
-				if (rec_paramc) {
-					retval = clish_pargv_parse(this, cmd,
-						context, rec_paramv,
-						argv, idx, last, need_index);
-					if (CLISH_LINE_OK != retval)
-						return retval;
-				}
-
-				/* Choose the next parameter */
-				if (BOOL_TRUE == clish_param__get_optional(param)) {
-					if (nopt_param)
-						index = nopt_index + 1;
-					else
-						index = 0;
-				} else {
-					index++;
-				}
-
-			} else {
-				/* Choose the next parameter if current
-				 * is not validated.
-				 */
-				if (BOOL_TRUE ==
-					clish_param__get_optional(param))
-					index++;
-				else {
-					if (!arg)
-						break;
-					else
-						return CLISH_BAD_PARAM;
-				}
-			}
-		} else {
-			return CLISH_BAD_PARAM;
-		}
-	}
-
-	/* Check for non-optional parameters without values */
-	if ((*idx >= argc) && (index < paramc)) {
-		unsigned j = index;
-		const clish_param_t *param;
-		while (j < paramc) {
-			param = clish_paramv__get_param(paramv, j++);
-			if (BOOL_TRUE != clish_param__get_optional(param))
-				return CLISH_LINE_PARTIAL;
-		}
-	}
-
-	/* If the number of arguments is bigger than number of
-	 * params than it's a args. So generate the args entry
-	 * in the list of completions.
-	 */
-	if (last && up_level &&
-			clish_command__get_args(cmd) &&
-			(clish_pargv__get_count(last) == 0) &&
-			(*idx <= argc) && (index >= paramc)) {
-		clish_pargv_insert(last, clish_command__get_args(cmd), "");
-	}
-
-	/*
-	 * if we've satisfied all the parameters we can now construct
-	 * an 'args' parameter if one exists
-	 */
-	if (up_level && (*idx < argc) && (index >= paramc)) {
-		const char *arg = lub_argv__get_arg(argv, *idx);
-		const clish_param_t *param = clish_command__get_args(cmd);
-		char *args = NULL;
-
-		if (!param)
-			return CLISH_BAD_CMD;
-
-		/*
-		 * put all the argument into a single string
-		 */
-		while (NULL != arg) {
-			bool_t quoted = lub_argv__get_quoted(argv, *idx);
-			if (BOOL_TRUE == quoted) {
-				lub_string_cat(&args, "\"");
-			}
-			/* place the current argument in the string */
-			lub_string_cat(&args, arg);
-			if (BOOL_TRUE == quoted) {
-				lub_string_cat(&args, "\"");
-			}
-			(*idx)++;
-			arg = lub_argv__get_arg(argv, *idx);
-			if (NULL != arg) {
-				/* add a space if there are more arguments */
-				lub_string_cat(&args, " ");
-			}
-		}
-		/* add (or update) this parameter */
-		clish_pargv_insert(this, param, args);
-		lub_string_free(args);
-	}
-
-	return CLISH_LINE_OK;
-}
-
 /*--------------------------------------------------------- */
 clish_pargv_t *clish_pargv_new(void)
 {
@@ -333,28 +79,6 @@ clish_pargv_t *clish_pargv_new(void)
 	return this;
 }
 
-/*--------------------------------------------------------- */
-clish_pargv_status_t clish_pargv_analyze(clish_pargv_t *this,
-	const clish_command_t *cmd,
-	void *context,
-	const char *line,
-	size_t offset)
-{
-	lub_argv_t *argv = NULL;
-	unsigned int idx;
-	clish_pargv_status_t status;
-
-	assert(cmd);
-	idx = lub_argv_wordcount(clish_command__get_name(cmd));
-	argv = lub_argv_new(line, offset);
-	status = clish_pargv_parse(this, cmd, context,
-		clish_command__get_paramv(cmd),
-		argv, &idx, NULL, 0);
-	lub_argv_delete(argv);
-
-	return status;
-}
-
 /*--------------------------------------------------------- */
 static void clish_pargv_fini(clish_pargv_t * this)
 {

+ 6 - 0
clish/shell/private.h

@@ -93,6 +93,12 @@ clish_view_t *clish_shell_find_view(clish_shell_t * instance, const char *name);
 void clish_shell_insert_view(clish_shell_t * instance, clish_view_t * view);
 clish_pargv_status_t clish_shell_parse(clish_shell_t * instance,
 	const char *line, const clish_command_t ** cmd, clish_pargv_t ** pargv);
+clish_pargv_status_t clish_shell_parse_pargv(clish_pargv_t *pargv,
+	const clish_command_t *cmd,
+	void *context,
+	clish_paramv_t *paramv,
+	const lub_argv_t *argv,
+	unsigned *idx, clish_pargv_t *last, unsigned need_index);
 char *clish_shell_word_generator(clish_shell_t * instance,
 	const char *line, unsigned offset, unsigned state);
 const clish_command_t *clish_shell_resolve_command(const clish_shell_t *

+ 1 - 1
clish/shell/shell_command.c

@@ -99,7 +99,7 @@ void clish_shell_param_generator(clish_shell_t *this, lub_argv_t *matches,
 		context.shell = this;
 		context.cmd = cmd;
 		context.pargv = pargv;
-		clish_pargv_parse(pargv, cmd, &context,
+		clish_shell_parse_pargv(pargv, cmd, &context,
 			clish_command__get_paramv(cmd),
 			argv, &idx, completion, index + idx);
 		clish_pargv_delete(pargv);

+ 1 - 1
clish/shell/shell_help.c

@@ -66,7 +66,7 @@ static int available_params(clish_shell_t *this,
 	context.shell = this;
 	context.cmd = cmd;
 	context.pargv = pargv;
-	status = clish_pargv_parse(pargv, cmd, &context,
+	status = clish_shell_parse_pargv(pargv, cmd, &context,
 		clish_command__get_paramv(cmd),
 		argv, &idx, completion, index);
 	clish_pargv_delete(pargv);

+ 3 - 3
clish/shell/shell_new.c

@@ -61,7 +61,7 @@ static void clish_shell_init(clish_shell_t * this,
 		CLISH_PTYPE_REGEXP, CLISH_PTYPE_NONE);
 	assert(tmp_ptype);
 	this->param_depth = clish_param_new("__cur_depth",
-		"Current depth", tmp_ptype, clish_shell_expand);
+		"Current depth", tmp_ptype);
 	clish_param__set_hidden(this->param_depth, BOOL_TRUE);
 	/* Current pwd */
 	tmp_ptype = clish_shell_find_create_ptype(this,
@@ -69,7 +69,7 @@ static void clish_shell_init(clish_shell_t * this,
 		CLISH_PTYPE_REGEXP, CLISH_PTYPE_NONE);
 	assert(tmp_ptype);
 	this->param_pwd = clish_param_new("__cur_pwd",
-		"Current path", tmp_ptype, clish_shell_expand);
+		"Current path", tmp_ptype);
 	clish_param__set_hidden(this->param_pwd, BOOL_TRUE);
 	/* Interactive */
 	tmp_ptype = clish_shell_find_create_ptype(this,
@@ -77,7 +77,7 @@ static void clish_shell_init(clish_shell_t * this,
 		CLISH_PTYPE_REGEXP, CLISH_PTYPE_NONE);
 	assert(tmp_ptype);
 	this->param_interactive = clish_param_new("__interactive",
-		"Interactive flag", tmp_ptype, clish_shell_expand);
+		"Interactive flag", tmp_ptype);
 	clish_param__set_hidden(this->param_interactive, BOOL_TRUE);
 
 	/* Push non-NULL istream */

+ 269 - 5
clish/shell/shell_parse.c

@@ -1,12 +1,14 @@
 /*
  * shell_parse.c
  */
-#include "private.h"
-#include "lub/string.h"
 
 #include <string.h>
 #include <assert.h>
 
+#include "lub/string.h"
+#include "lub/system.h"
+#include "private.h"
+
 /*----------------------------------------------------------- */
 clish_pargv_status_t clish_shell_parse(
 	clish_shell_t *this, const char *line,
@@ -15,6 +17,8 @@ clish_pargv_status_t clish_shell_parse(
 	clish_pargv_status_t result = CLISH_BAD_CMD;
 	clish_context_t context;
 	const clish_command_t *cmd;
+	lub_argv_t *argv = NULL;
+	unsigned int idx;
 
 	*ret_cmd = cmd = clish_shell_resolve_command(this, line);
 	if (!cmd)
@@ -25,7 +29,13 @@ clish_pargv_status_t clish_shell_parse(
 	context.shell = this;
 	context.cmd = cmd;
 	context.pargv = *pargv;
-	result = clish_pargv_analyze(*pargv, cmd, &context, line, 0);
+
+	idx = lub_argv_wordcount(clish_command__get_name(cmd));
+	argv = lub_argv_new(line, 0);
+	result = clish_shell_parse_pargv(*pargv, cmd, &context,
+		clish_command__get_paramv(cmd),
+		argv, &idx, NULL, 0);
+	lub_argv_delete(argv);
 	if (CLISH_LINE_OK != result) {
 		clish_pargv_delete(*pargv);
 		*pargv = NULL;
@@ -54,14 +64,268 @@ clish_pargv_status_t clish_shell_parse(
 	return result;
 }
 
+/*--------------------------------------------------------- */
+clish_pargv_status_t clish_shell_parse_pargv(clish_pargv_t *pargv,
+	const clish_command_t *cmd,
+	void *context,
+	clish_paramv_t *paramv,
+	const lub_argv_t *argv,
+	unsigned *idx, clish_pargv_t *last, unsigned need_index)
+{
+	unsigned argc = lub_argv__get_count(argv);
+	unsigned index = 0;
+	unsigned nopt_index = 0;
+	clish_param_t *nopt_param = NULL;
+	unsigned i;
+	clish_pargv_status_t retval;
+	unsigned paramc = clish_paramv__get_count(paramv);
+	int up_level = 0; /* Is it a first level of param nesting? */
+
+	assert(pargv);
+	assert(cmd);
+
+	/* Check is it a first level of PARAM nesting. */
+	if (paramv == clish_command__get_paramv(cmd))
+		up_level = 1;
+
+	while (index < paramc) {
+		const char *arg = NULL;
+		clish_param_t *param = clish_paramv__get_param(paramv,index);
+		clish_param_t *cparam = NULL;
+		int is_switch = 0;
+
+		/* Use real arg or PARAM's default value as argument */
+		if (*idx < argc)
+			arg = lub_argv__get_arg(argv, *idx);
+
+		/* Is parameter in "switch" mode? */
+		if (CLISH_PARAM_SWITCH == clish_param__get_mode(param))
+			is_switch = 1;
+
+		/* Check the 'test' conditions */
+		if (param) {
+			char *str = clish_shell_expand(clish_param__get_test(param), context);
+			if (str && !lub_system_line_test(str)) {
+				lub_string_free(str);
+				index++;
+				continue;
+			}
+			lub_string_free(str);
+		}
+
+		/* Add param for help and completion */
+		if (last && (*idx == need_index) &&
+			(NULL == clish_pargv_find_arg(pargv, clish_param__get_name(param)))) {
+			if (is_switch) {
+				unsigned rec_paramc = clish_param__get_param_count(param);
+				for (i = 0; i < rec_paramc; i++) {
+					cparam = clish_param__get_param(param, i);
+					if (!cparam)
+						break;
+					if (CLISH_PARAM_SUBCOMMAND ==
+						clish_param__get_mode(cparam)) {
+						const char *pname =
+							clish_param__get_value(cparam);
+						if (!arg || (arg && 
+							(pname == lub_string_nocasestr(pname,
+							arg))))
+							clish_pargv_insert(last,
+								cparam, arg);
+					} else {
+						clish_pargv_insert(last,
+							cparam, arg);
+					}
+				}
+			} else {
+				if (CLISH_PARAM_SUBCOMMAND ==
+					clish_param__get_mode(param)) {
+					const char *pname =
+					    clish_param__get_value(param);
+					if (!arg || (arg &&
+						(pname == lub_string_nocasestr(pname, arg))))
+						clish_pargv_insert(last, param, arg);
+				} else {
+					clish_pargv_insert(last, param, arg);
+				}
+			}
+		}
+
+		/* Set parameter value */
+		if (param) {
+			char *validated = NULL;
+			clish_paramv_t *rec_paramv =
+			    clish_param__get_paramv(param);
+			unsigned rec_paramc =
+			    clish_param__get_param_count(param);
+
+			/* Save the index of last non-option parameter
+			 * to restore index if the optional parameters
+			 * will be used.
+			 */
+			if (BOOL_TRUE != clish_param__get_optional(param)) {
+				nopt_param = param;
+				nopt_index = index;
+			}
+
+			/* Validate the current parameter. */
+			if (NULL != clish_pargv_find_arg(pargv, clish_param__get_name(param))) {
+				/* Duplicated parameter */
+				validated = NULL;
+			} else if (is_switch) {
+				for (i = 0; i < rec_paramc; i++) {
+					cparam =
+					    clish_param__get_param(param, i);
+					if (!cparam)
+						break;
+					if ((validated =
+					    arg ? clish_param_validate(cparam,
+								       arg) :
+					    NULL)) {
+						rec_paramv =
+						    clish_param__get_paramv
+						    (cparam);
+						rec_paramc =
+						    clish_param__get_param_count
+						    (cparam);
+						break;
+					}
+				}
+			} else {
+				validated =
+				    arg ? clish_param_validate(param,
+							       arg) : NULL;
+			}
+
+			if (validated) {
+				/* add (or update) this parameter */
+				if (is_switch) {
+					clish_pargv_insert(pargv, param,
+						clish_param__get_name(cparam));
+					clish_pargv_insert(pargv, cparam,
+						validated);
+				} else {
+					clish_pargv_insert(pargv, param,
+						validated);
+				}
+				lub_string_free(validated);
+
+				/* Next command line argument */
+				/* Don't change idx if this is the last
+				   unfinished optional argument.
+				 */
+				if (!(clish_param__get_optional(param) &&
+					(*idx == need_index) &&
+					(need_index == (argc - 1))))
+				(*idx)++;
+
+				/* Walk through the nested parameters */
+				if (rec_paramc) {
+					retval = clish_shell_parse_pargv(pargv, cmd,
+						context, rec_paramv,
+						argv, idx, last, need_index);
+					if (CLISH_LINE_OK != retval)
+						return retval;
+				}
+
+				/* Choose the next parameter */
+				if (BOOL_TRUE == clish_param__get_optional(param)) {
+					if (nopt_param)
+						index = nopt_index + 1;
+					else
+						index = 0;
+				} else {
+					index++;
+				}
+
+			} else {
+				/* Choose the next parameter if current
+				 * is not validated.
+				 */
+				if (BOOL_TRUE ==
+					clish_param__get_optional(param))
+					index++;
+				else {
+					if (!arg)
+						break;
+					else
+						return CLISH_BAD_PARAM;
+				}
+			}
+		} else {
+			return CLISH_BAD_PARAM;
+		}
+	}
+
+	/* Check for non-optional parameters without values */
+	if ((*idx >= argc) && (index < paramc)) {
+		unsigned j = index;
+		const clish_param_t *param;
+		while (j < paramc) {
+			param = clish_paramv__get_param(paramv, j++);
+			if (BOOL_TRUE != clish_param__get_optional(param))
+				return CLISH_LINE_PARTIAL;
+		}
+	}
+
+	/* If the number of arguments is bigger than number of
+	 * params than it's a args. So generate the args entry
+	 * in the list of completions.
+	 */
+	if (last && up_level &&
+			clish_command__get_args(cmd) &&
+			(clish_pargv__get_count(last) == 0) &&
+			(*idx <= argc) && (index >= paramc)) {
+		clish_pargv_insert(last, clish_command__get_args(cmd), "");
+	}
+
+	/*
+	 * if we've satisfied all the parameters we can now construct
+	 * an 'args' parameter if one exists
+	 */
+	if (up_level && (*idx < argc) && (index >= paramc)) {
+		const char *arg = lub_argv__get_arg(argv, *idx);
+		const clish_param_t *param = clish_command__get_args(cmd);
+		char *args = NULL;
+
+		if (!param)
+			return CLISH_BAD_CMD;
+
+		/*
+		 * put all the argument into a single string
+		 */
+		while (NULL != arg) {
+			bool_t quoted = lub_argv__get_quoted(argv, *idx);
+			if (BOOL_TRUE == quoted) {
+				lub_string_cat(&args, "\"");
+			}
+			/* place the current argument in the string */
+			lub_string_cat(&args, arg);
+			if (BOOL_TRUE == quoted) {
+				lub_string_cat(&args, "\"");
+			}
+			(*idx)++;
+			arg = lub_argv__get_arg(argv, *idx);
+			if (NULL != arg) {
+				/* add a space if there are more arguments */
+				lub_string_cat(&args, " ");
+			}
+		}
+		/* add (or update) this parameter */
+		clish_pargv_insert(pargv, param, args);
+		lub_string_free(args);
+	}
+
+	return CLISH_LINE_OK;
+}
+
 /*----------------------------------------------------------- */
-clish_shell_state_t clish_shell__get_state(const clish_shell_t * this)
+clish_shell_state_t clish_shell__get_state(const clish_shell_t *this)
 {
 	return this->state;
 }
 
 /*----------------------------------------------------------- */
-void clish_shell__set_state(clish_shell_t * this,
+void clish_shell__set_state(clish_shell_t *this,
 	clish_shell_state_t state)
 {
 	assert(this);

+ 2 - 2
clish/shell/shell_tinyrl.c

@@ -28,7 +28,7 @@ static void clish_shell_renew_prompt(tinyrl_t *this)
 	/* Obtain the prompt */
 	view = clish_shell__get_view(context->shell);
 	assert(view);
-	prompt = clish_view__get_prompt(view, context);
+	prompt = clish_shell_expand(clish_view__get_prompt(view), context);
 	assert(prompt);
 	tinyrl__set_prompt(this, prompt);
 	lub_string_free(prompt);
@@ -409,7 +409,7 @@ bool_t clish_shell_execline(clish_shell_t *this, const char *line, char **out)
 	/* Obtain the prompt */
 	view = clish_shell__get_view(this);
 	assert(view);
-	prompt = clish_view__get_prompt(view, &context);
+	prompt = clish_shell_expand(clish_view__get_prompt(view), &context);
 	assert(prompt);
 
 	/* Push the specified line or interactive line */

+ 3 - 5
clish/shell/shell_tinyxml.cpp

@@ -266,8 +266,7 @@ process_command(clish_shell_t * shell, TiXmlElement * element, void *parent)
 			CLISH_PTYPE_REGEXP,
 			CLISH_PTYPE_NONE);
 		assert(tmp);
-		param = clish_param_new(args_name, args_help, tmp,
-			clish_shell_expand);
+		param = clish_param_new(args_name, args_help, tmp);
 		clish_command__set_args(cmd, param);
 	}
 	// define the view which this command changes to
@@ -375,7 +374,7 @@ process_param(clish_shell_t * shell, TiXmlElement * element, void *parent)
 				CLISH_PTYPE_NONE);
 			assert(tmp);
 		}
-		param = clish_param_new(name, help, tmp, clish_shell_expand);
+		param = clish_param_new(name, help, tmp);
 
 		/* If prefix is set clish will emulate old optional
 		 * command syntax over newer optional command mechanism.
@@ -397,8 +396,7 @@ process_param(clish_shell_t * shell, TiXmlElement * element, void *parent)
 					ptype_name, "Option", "[^\\]+",
 					CLISH_PTYPE_REGEXP, CLISH_PTYPE_NONE);
 			assert(tmp);
-			opt_param = clish_param_new(prefix, help, tmp,
-				clish_shell_expand);
+			opt_param = clish_param_new(prefix, help, tmp);
 			clish_param__set_mode(opt_param,
 					      CLISH_PARAM_SUBCOMMAND);
 			clish_param__set_optional(opt_param, BOOL_TRUE);

+ 4 - 2
clish/view.h

@@ -39,6 +39,7 @@ clish_view_t *clish_view_new(const char *name, const char *prompt,
 int clish_view_bt_compare(const void *clientnode, const void *clientkey);
 void clish_view_bt_getkey(const void *clientnode, lub_bintree_key_t * key);
 size_t clish_view_bt_offset(void);
+
 /*-----------------
  * methods
  *----------------- */
@@ -57,12 +58,13 @@ clish_command_t *clish_view_resolve_prefix(clish_view_t * instance,
 void clish_view_dump(clish_view_t * instance);
 void clish_view_insert_nspace(clish_view_t * instance, clish_nspace_t * nspace);
 void clish_view_clean_proxy(clish_view_t * instance);
+
 /*-----------------
- * attributes 
+ * attributes
  *----------------- */
 const char *clish_view__get_name(const clish_view_t * instance);
 void clish_view__set_prompt(clish_view_t * instance, const char *prompt);
-char *clish_view__get_prompt(const clish_view_t *instance, void *context);
+char *clish_view__get_prompt(const clish_view_t *instance);
 const unsigned clish_view__get_nspace_count(const clish_view_t * instance);
 clish_nspace_t *clish_view__get_nspace(const clish_view_t * instance,
 				       unsigned index);

+ 2 - 2
clish/view/view.c

@@ -338,9 +338,9 @@ void clish_view__set_prompt(clish_view_t * this, const char *prompt)
 }
 
 /*--------------------------------------------------------- */
-char *clish_view__get_prompt(const clish_view_t *this, void *context)
+char *clish_view__get_prompt(const clish_view_t *this)
 {
-	return this->var_expand_fn(this->prompt, context);
+	return this->prompt;
 }
 
 /*--------------------------------------------------------- */

+ 3 - 0
lub/system.h

@@ -8,6 +8,9 @@
 #include <stddef.h>
 
 #include "lub/c_decl.h"
+#include "lub/types.h"
+#include "lub/argv.h"
+
 _BEGIN_C_DECL bool_t lub_system_test(int argc, char **argv);
 bool_t lub_system_argv_test(const lub_argv_t * argv);
 bool_t lub_system_line_test(const char *line);