Browse Source

Big variable refactoring. Unfinished. Don't use this revision.

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

File diff suppressed because it is too large
+ 4 - 8
Makefile.in


+ 9 - 8
clish/callback_config.c

@@ -23,9 +23,11 @@
 static int send_request(konf_client_t * client, char *command);
 
 /*--------------------------------------------------------- */
-bool_t clish_config_callback(const clish_shell_t * this,
-	const clish_command_t * cmd, clish_pargv_t * pargv)
+bool_t clish_config_callback(clish_context_t *context)
 {
+	clish_shell_t *this = context->shell;
+	const clish_command_t *cmd = context->cmd;
+	clish_pargv_t *pargv = context->pargv;
 	char *command = NULL;
 	konf_client_t *client;
 	konf_buf_t *buf = NULL;
@@ -54,7 +56,7 @@ bool_t clish_config_callback(const clish_shell_t * this,
 		lub_string_cat(&command, "-s");
 
 		/* Add entered line */
-		str = clish_variable__get_line(cmd, pargv);
+		str = clish_shell__get_line(cmd, pargv);
 		lub_string_cat(&command, " -l \"");
 		lub_string_cat(&command, str);
 		lub_string_cat(&command, "\"");
@@ -80,7 +82,7 @@ bool_t clish_config_callback(const clish_shell_t * this,
 		lub_string_cat(&command, "-d");
 
 		/* Add filename */
-		str = clish_command__get_file(cmd, viewid, pargv);
+		str = clish_command__get_file(cmd, context);
 		if (str) {
 			lub_string_cat(&command, " -f \"");
 			if (str[0] != '\0')
@@ -98,7 +100,7 @@ bool_t clish_config_callback(const clish_shell_t * this,
 
 	/* Add pattern */
 	if ((CLISH_CONFIG_SET == op) || (CLISH_CONFIG_UNSET == op)) {
-		str = clish_command__get_pattern(cmd, viewid, pargv);
+		str = clish_command__get_pattern(cmd, context);
 		if (!str) {
 			lub_string_free(command);
 			return BOOL_FALSE;
@@ -120,15 +122,14 @@ bool_t clish_config_callback(const clish_shell_t * this,
 	/* Add sequence */
 	if (clish_command__is_seq(cmd)) {
 		snprintf(tmp, sizeof(tmp) - 1, " -q %u",
-			clish_command__get_seq(cmd,
-			viewid, pargv));
+			clish_command__get_seq(cmd, context));
 		tmp[sizeof(tmp) - 1] = '\0';
 		lub_string_cat(&command, tmp);
 	}
 
 	/* Add pwd */
 	str = clish_shell__get_pwd_full(this,
-		clish_command__get_cfg_depth(cmd, viewid, pargv));
+		clish_command__get_cfg_depth(cmd, context));
 	if (str) {
 		lub_string_cat(&command, " ");
 		lub_string_cat(&command, str);

+ 6 - 4
clish/callback_script.c

@@ -21,9 +21,11 @@
 #include "internal.h"
 
 /*--------------------------------------------------------- */
-bool_t clish_script_callback(clish_shell_t * this,
-	const clish_command_t * cmd, const char *script, char ** out)
+bool_t clish_script_callback(clish_context_t *context,
+	const char *script, char ** out)
 {
+	clish_shell_t *this = context->shell;
+	const clish_command_t *cmd = context->cmd;
 	const char * shebang = NULL;
 	pid_t cpid;
 	int res;
@@ -149,8 +151,8 @@ bool_t clish_script_callback(clish_shell_t * this,
 }
 
 /*--------------------------------------------------------- */
-bool_t clish_dryrun_callback(clish_shell_t * this,
-	const clish_command_t * cmd, const char *script, char ** out)
+bool_t clish_dryrun_callback(clish_context_t *context,
+	const char *script, char ** out)
 {
 #ifdef DEBUG
 	fprintf(stderr, "DRY-RUN: %s\n", script);

+ 8 - 13
clish/command.h

@@ -26,7 +26,8 @@ typedef enum {
 /*-----------------
  * meta functions
  *----------------- */
-clish_command_t *clish_command_new(const char *name, const char *help);
+clish_command_t *clish_command_new(const char *name, const char *help,
+	clish_var_expand_fn_t *fn);
 clish_command_t *clish_command_new_link(const char *name,
 	const char *help, const clish_command_t * ref);
 clish_command_t * clish_command_alias_to_link(clish_command_t * instance);
@@ -58,11 +59,9 @@ const char *clish_command__get_detail(const clish_command_t * instance);
 const char *clish_command__get_builtin(const clish_command_t * instance);
 const char *clish_command__get_escape_chars(const clish_command_t * instance);
 const clish_param_t *clish_command__get_args(const clish_command_t * instance);
-char *clish_command__get_action(const clish_command_t * instance,
-	const char *viewid, clish_pargv_t * pargv);
+char *clish_command__get_action(const clish_command_t * instance, void *context);
 clish_view_t *clish_command__get_view(const clish_command_t * instance);
-char *clish_command__get_viewid(const clish_command_t * instance,
-	const char *viewid, clish_pargv_t * pargv);
+char *clish_command__get_viewid(const clish_command_t *instance, void *context);
 const unsigned clish_command__get_param_count(const clish_command_t * instance);
 const clish_param_t *clish_command__get_param(const clish_command_t * instance,
 	unsigned index);
@@ -91,25 +90,21 @@ void clish_command__set_priority(clish_command_t * instance, unsigned short prio
 unsigned short clish_command__get_priority(const clish_command_t * instance);
 void
 clish_command__set_pattern(clish_command_t * instance, const char *pattern);
-char *clish_command__get_pattern(const clish_command_t * instance,
-	const char * viewid, clish_pargv_t * pargv);
+char *clish_command__get_pattern(const clish_command_t *instance, void *context);
 void clish_command__set_file(clish_command_t * instance, const char *file);
-char *clish_command__get_file(const clish_command_t * instance,
-	const char * viewid, clish_pargv_t * pargv);
+char *clish_command__get_file(const clish_command_t *instance, void *context);
 void clish_command__set_splitter(clish_command_t * instance, bool_t splitter);
 bool_t clish_command__get_splitter(const clish_command_t * instance);
 const char * clish_command__is_seq(const clish_command_t * instance);
 void clish_command__set_seq(clish_command_t * instance, const char * seq_num);
-unsigned short clish_command__get_seq(const clish_command_t * instance,
-	const char *viewid, clish_pargv_t * pargv);
+unsigned short clish_command__get_seq(const clish_command_t * instance, void *context);
 clish_view_restore_t clish_command__get_restore(const clish_command_t * instance);
 bool_t clish_command__get_unique(const clish_command_t * instance);
 void clish_command__set_unique(clish_command_t * instance, bool_t unique);
 const clish_command_t * clish_command__get_orig(const clish_command_t * instance);
 const clish_command_t * clish_command__get_cmd(const clish_command_t * instance);
 void clish_command__set_cfg_depth(clish_command_t * instance, const char * cfg_depth);
-unsigned clish_command__get_cfg_depth(const clish_command_t * instance,
-	const char *viewid, clish_pargv_t * pargv);
+unsigned clish_command__get_cfg_depth(const clish_command_t *instance, void *context);
 bool_t clish_command__get_lock(const clish_command_t * instance);
 void clish_command__set_lock(clish_command_t * instance, bool_t lock);
 const char * clish_command__get_shebang(const clish_command_t * instance);

+ 18 - 21
clish/command/command.c

@@ -18,11 +18,13 @@
  * PRIVATE METHODS
  *--------------------------------------------------------- */
 static void
-clish_command_init(clish_command_t * this, const char *name, const char *text)
+clish_command_init(clish_command_t * this, const char *name, const char *text,
+	clish_var_expand_fn_t *fn)
 {
 	/* initialise the node part */
 	this->name = lub_string_dup(name);
 	this->text = lub_string_dup(text);
+	this->var_expand_fn = fn;
 
 	/* Be a good binary tree citizen */
 	lub_bintree_node_init(&this->bt_node);
@@ -131,12 +133,13 @@ void clish_command_bt_getkey(const void *clientnode, lub_bintree_key_t * key)
 }
 
 /*--------------------------------------------------------- */
-clish_command_t *clish_command_new(const char *name, const char *help)
+clish_command_t *clish_command_new(const char *name, const char *help,
+	clish_var_expand_fn_t *fn)
 {
 	clish_command_t *this = malloc(sizeof(clish_command_t));
 
 	if (this)
-		clish_command_init(this, name, help);
+		clish_command_init(this, name, help, fn);
 
 	return this;
 }
@@ -332,10 +335,9 @@ void clish_command__set_detail(clish_command_t * this, const char *detail)
 }
 
 /*--------------------------------------------------------- */
-char *clish_command__get_action(const clish_command_t * this,
-	const char *viewid, clish_pargv_t * pargv)
+char *clish_command__get_action(const clish_command_t * this, void *context)
 {
-	return clish_variable_expand(this->action, viewid, this, pargv);
+	return this->var_expand_fn(this->action, context);
 }
 
 /*--------------------------------------------------------- */
@@ -371,10 +373,9 @@ void clish_command__force_viewid(clish_command_t * this, const char *viewid)
 }
 
 /*--------------------------------------------------------- */
-char *clish_command__get_viewid(const clish_command_t * this,
-	const char *viewid, clish_pargv_t * pargv)
+char *clish_command__get_viewid(const clish_command_t * this, void *context)
 {
-	return clish_variable_expand(this->viewid, viewid, this, pargv);
+	return this->var_expand_fn(this->viewid, context);
 }
 
 /*--------------------------------------------------------- */
@@ -497,10 +498,9 @@ void clish_command__set_pattern(clish_command_t * this, const char *pattern)
 }
 
 /*--------------------------------------------------------- */
-char *clish_command__get_pattern(const clish_command_t * this,
-	const char *viewid, clish_pargv_t * pargv)
+char *clish_command__get_pattern(const clish_command_t * this, void *context)
 {
-	return clish_variable_expand(this->pattern, viewid, this, pargv);
+	return this->var_expand_fn(this->pattern, context);
 }
 
 /*--------------------------------------------------------- */
@@ -511,10 +511,9 @@ void clish_command__set_file(clish_command_t * this, const char *file)
 }
 
 /*--------------------------------------------------------- */
-char *clish_command__get_file(const clish_command_t * this,
-	const char *viewid, clish_pargv_t * pargv)
+char *clish_command__get_file(const clish_command_t *this, void *context)
 {
-	return clish_variable_expand(this->file, viewid, this, pargv);
+	return this->var_expand_fn(this->file, context);
 }
 
 /*--------------------------------------------------------- */
@@ -537,8 +536,7 @@ void clish_command__set_seq(clish_command_t * this, const char * seq)
 }
 
 /*--------------------------------------------------------- */
-unsigned short clish_command__get_seq(const clish_command_t * this,
-	const char *viewid, clish_pargv_t * pargv)
+unsigned short clish_command__get_seq(const clish_command_t *this, void *context)
 {
 	unsigned short num = 0;
 	char *str;
@@ -546,7 +544,7 @@ unsigned short clish_command__get_seq(const clish_command_t * this,
 	if (!this->seq)
 		return 0;
 
-	str = clish_variable_expand(this->seq, viewid, this, pargv);
+	str = this->var_expand_fn(this->seq, context);
 	if (str && (*str != '\0')) {
 		long val = 0;
 		char *endptr;
@@ -608,8 +606,7 @@ void clish_command__set_cfg_depth(clish_command_t * this, const char * cfg_depth
 }
 
 /*--------------------------------------------------------- */
-unsigned clish_command__get_cfg_depth(const clish_command_t * this,
-	const char *viewid, clish_pargv_t * pargv)
+unsigned clish_command__get_cfg_depth(const clish_command_t *this, void *context)
 {
 	unsigned num = 0;
 	char *str;
@@ -617,7 +614,7 @@ unsigned clish_command__get_cfg_depth(const clish_command_t * this,
 	if (!this->cfg_depth)
 		return clish_command__get_depth(this);
 
-	str = clish_variable_expand(this->cfg_depth, viewid, this, pargv);
+	str = this->var_expand_fn(this->cfg_depth, context);
 	if (str && (*str != '\0')) {
 		long val = 0;
 		char *endptr;

+ 1 - 0
clish/command/private.h

@@ -24,6 +24,7 @@ struct clish_command_s {
 	bool_t lock;
 	bool_t interrupt;
 	bool_t dynamic; /* Is command dynamically created */
+	clish_var_expand_fn_t *var_expand_fn;
 
 	/* ACTION params: */
 	char *builtin;

+ 0 - 2
clish/module.am

@@ -33,7 +33,6 @@ EXTRA_DIST += \
 	clish/pargv/module.am \
 	clish/ptype/module.am \
 	clish/shell/module.am \
-	clish/variable/module.am \
 	clish/view/module.am \
 	clish/nspace/module.am \
 	clish/var/module.am \
@@ -44,7 +43,6 @@ include $(top_srcdir)/clish/param/module.am
 include $(top_srcdir)/clish/pargv/module.am
 include $(top_srcdir)/clish/ptype/module.am
 include $(top_srcdir)/clish/shell/module.am
-include $(top_srcdir)/clish/variable/module.am
 include $(top_srcdir)/clish/view/module.am
 include $(top_srcdir)/clish/nspace/module.am
 include $(top_srcdir)/clish/var/module.am

+ 4 - 4
clish/param.h

@@ -21,6 +21,7 @@ typedef struct clish_param_s clish_param_t;
 #include "clish/types.h"
 #include "clish/ptype.h"
 #include "clish/pargv.h"
+#include "clish/var.h"
 
 /**
  * The means by which the param is interpreted.
@@ -49,7 +50,8 @@ typedef enum {
  * meta functions
  *----------------- */
 clish_param_t *clish_param_new(const char *name,
-			       const char *text, clish_ptype_t * ptype);
+	const char *text, clish_ptype_t *ptype,
+	clish_var_expand_fn_t *fn);
 /*-----------------
  * methods
  *----------------- */
@@ -82,9 +84,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,
-	const char * viewid, const clish_command_t * cmd,
-	clish_pargv_t * pargv);
+char *clish_param__get_test(const clish_param_t *instance, void *context);
 
 /* paramv methods */
 clish_paramv_t *clish_paramv_new(void);

+ 8 - 11
clish/param/param.c

@@ -16,14 +16,14 @@
 /*---------------------------------------------------------
  * PRIVATE METHODS
  *--------------------------------------------------------- */
-static void
-clish_param_init(clish_param_t * this,
-	const char *name, const char *text, clish_ptype_t * ptype)
+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)
 {
 	/* initialise the help part */
 	this->name = lub_string_dup(name);
 	this->text = lub_string_dup(text);
 	this->ptype = ptype;
+	this->var_expand_fn = fn;
 
 	/* set up defaults */
 	this->defval = NULL;
@@ -57,13 +57,13 @@ 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_param_t *clish_param_new(const char *name, const char *text,
+	clish_ptype_t *ptype, clish_var_expand_fn_t *fn)
 {
 	clish_param_t *this = malloc(sizeof(clish_param_t));
 
 	if (this)
-		clish_param_init(this, name, text, ptype);
+		clish_param_init(this, name, text, ptype, fn);
 	return this;
 }
 
@@ -361,12 +361,9 @@ void clish_param__set_test(clish_param_t * this, const char *test)
 }
 
 /*--------------------------------------------------------- */
-char *clish_param__get_test(const clish_param_t * this,
-	const char * viewid, const clish_command_t * cmd,
-	clish_pargv_t * pargv)
+char *clish_param__get_test(const clish_param_t * this, void *context)
 {
 	if (!this->test)
 		return NULL;
-	return clish_variable_expand(this->test, viewid, cmd, pargv);
+	return this->var_expand_fn(this->test, context);
 }
-

+ 1 - 0
clish/param/private.h

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

+ 3 - 4
clish/pargv/pargv.c

@@ -70,7 +70,7 @@ int clish_pargv_insert(clish_pargv_t * this,
 /*--------------------------------------------------------- */
 clish_pargv_status_t clish_pargv_parse(clish_pargv_t * this,
 	const clish_command_t * cmd,
-	const char *viewid,
+	void *context,
 	clish_paramv_t * paramv,
 	const lub_argv_t * argv,
 	unsigned *idx, clish_pargv_t * last, unsigned need_index)
@@ -107,8 +107,7 @@ clish_pargv_status_t clish_pargv_parse(clish_pargv_t * this,
 
 		/* Check the 'test' conditions */
 		if (param) {
-			char *str = clish_param__get_test(param,
-				viewid, cmd, this);
+			char *str = clish_param__get_test(param, context);
 			if (str && !lub_system_line_test(str)) {
 				lub_string_free(str);
 				index++;
@@ -225,7 +224,7 @@ clish_pargv_status_t clish_pargv_parse(clish_pargv_t * this,
 				/* Walk through the nested parameters */
 				if (rec_paramc) {
 					retval = clish_pargv_parse(this, cmd,
-						viewid, rec_paramv,
+						context, rec_paramv,
 						argv, idx, last, need_index);
 					if (CLISH_LINE_OK != retval)
 						return retval;

+ 14 - 28
clish/shell.h

@@ -27,9 +27,16 @@
 #define CLISH_LOCK_PATH "/tmp/clish.lock"
 #define CLISH_LOCK_WAIT 20
 
-typedef struct clish_context_s clish_context_t;
 typedef struct clish_shell_s clish_shell_t;
 
+/* This is used to hold context during callbacks */
+struct clish_context_s {
+	clish_shell_t *shell;
+	const clish_command_t *cmd;
+	clish_pargv_t *pargv;
+};
+typedef struct clish_context_s clish_context_t;
+
 typedef enum {
 	SHELL_STATE_INITIALISING,
 	SHELL_STATE_OK,
@@ -137,17 +144,7 @@ typedef void clish_shell_cmd_line_fn_t(
   *   command will be honored. i.e. the CLI will switch to the new view
   */
 typedef bool_t clish_shell_script_fn_t(
-	/** 
-         * The shell instance which invoked this call
-         */
-	clish_shell_t * instance,
-	/** 
-         * The command which invoked this call
-         */
-	const clish_command_t * cmd,
-	/** 
-         * The script to be evaluated
-         */
+	clish_context_t *context,
 	const char *script,
 	char ** out);
 
@@ -156,18 +153,7 @@ typedef bool_t clish_shell_script_fn_t(
   * 
   */
 typedef bool_t clish_shell_config_fn_t(
-	/** 
-         * The shell instance which invoked this call
-         */
-					      const clish_shell_t * instance,
-	/** 
-         * The command
-         */
-					      const clish_command_t * cmd,
-	/** 
-         * Argument vector
-         */
-					      clish_pargv_t * pargv);
+	clish_context_t *context);
 
  /**
   * A hook function used to control access for the current user.
@@ -344,6 +330,8 @@ bool_t clish_shell_push_fd(clish_shell_t * instance, FILE * file,
 	bool_t stop_on_error);
 void clish_shell_insert_var(clish_shell_t *instance, clish_var_t *var);
 clish_var_t *clish_shell_find_var(clish_shell_t *instance, const char *name);
+char *clish_shell_expand_var(const char *name, void *context);
+char *clish_shell_expand(const char *str, void *context);
 
 /*-----------------
  * attributes
@@ -385,15 +373,13 @@ void clish_shell__set_startup_view(clish_shell_t * instance, const char * viewna
 void clish_shell__set_startup_viewid(clish_shell_t * instance, const char * viewid);
 void clish_shell__set_default_shebang(clish_shell_t * instance, const char * shebang);
 const char * clish_shell__get_default_shebang(const clish_shell_t * instance);
-char * clish_shell__expand_text(const clish_shell_t *instance,
-	clish_command_t *cmd, clish_pargv_t *pargv, const char *text);
-char * clish_shell__expand_variable(const clish_shell_t *instance,
-	clish_command_t *cmd, clish_pargv_t *pargv, const char *var);
 const char * clish_shell__get_fifo(clish_shell_t * instance);
 void clish_shell__set_interactive(clish_shell_t * instance, bool_t interactive);
 bool_t clish_shell__get_interactive(const clish_shell_t * instance);
 bool_t clish_shell__get_utf8(const clish_shell_t * instance);
 void clish_shell__set_utf8(clish_shell_t * instance, bool_t utf8);
+char *clish_shell__get_line(const clish_command_t * cmd, clish_pargv_t * pargv);
+char *clish_shell__get_params(const clish_command_t * cmd, clish_pargv_t * pargv);
 
 _END_C_DECL
 

+ 1 - 1
clish/shell/shell_execute.c

@@ -326,7 +326,7 @@ clish_shell_execute(clish_shell_t * this,
 			this->viewid, pargv);
 		if (view) {
 			/* Save the current config PWD */
-			char *line = clish_variable__get_line(cmd, pargv);
+			char *line = clish_shell__get_line(cmd, pargv);
 			clish_shell__set_pwd(this,
 				clish_command__get_depth(cmd),
 				line, this->view, this->viewid);

+ 15 - 24
clish/shell/shell_tinyrl.c

@@ -1,8 +1,8 @@
 /*
  * shell_tinyrl.c
- * 
+ *
  * This is a specialisation of the tinyrl_t class which maps the readline
- * functionality to the CLISH envrionment.
+ * functionality to the CLISH environment.
  */
 #include "private.h"
 
@@ -18,14 +18,6 @@
 
 #include "lub/string.h"
 
-/* This is used to hold context during tinyrl callbacks */
-typedef struct _context context_t;
-struct _context {
-	clish_shell_t *shell;
-	const clish_command_t *cmd;
-	clish_pargv_t *pargv;
-};
-
 /*-------------------------------------------------------- */
 static bool_t clish_shell_tinyrl_key_help(tinyrl_t * this, int key)
 {
@@ -36,7 +28,7 @@ static bool_t clish_shell_tinyrl_key_help(tinyrl_t * this, int key)
 		result = tinyrl_insert_text(this, "?");
 	} else {
 		/* get the context */
-		context_t *context = tinyrl__get_context(this);
+		clish_context_t *context = tinyrl__get_context(this);
 
 		tinyrl_crlf(this);
 		clish_shell_help(context->shell, tinyrl__get_line(this));
@@ -100,7 +92,7 @@ static clish_pargv_status_t clish_shell_tinyrl_expand(tinyrl_t * this)
  */
 static tinyrl_match_e clish_shell_tinyrl_complete(tinyrl_t * this)
 {
-//	context_t *context = tinyrl__get_context(this);
+/*	context_t *context = tinyrl__get_context(this); */
 	tinyrl_match_e status;
 
 	/* first of all perform any history expansion */
@@ -111,12 +103,12 @@ static tinyrl_match_e clish_shell_tinyrl_complete(tinyrl_t * this)
 	case TINYRL_NO_MATCH:
 		if (BOOL_FALSE == tinyrl_is_completion_error_over(this)) {
 			/* The user hasn't even entered a valid prefix!!! */
-//			tinyrl_crlf(this);
-//			clish_shell_help(context->shell,
-//				tinyrl__get_line(this));
-//			tinyrl_crlf(this);
-//			tinyrl_reset_line_state(this);
-		}
+/*			tinyrl_crlf(this);
+			clish_shell_help(context->shell,
+				tinyrl__get_line(this));
+			tinyrl_crlf(this);
+			tinyrl_reset_line_state(this);
+*/		}
 		break;
 	default:
 		/* the default completion function will have prompted for completions as
@@ -132,7 +124,7 @@ static bool_t clish_shell_tinyrl_key_space(tinyrl_t * this, int key)
 {
 	bool_t result = BOOL_FALSE;
 	tinyrl_match_e status;
-	context_t *context = tinyrl__get_context(this);
+	clish_context_t *context = tinyrl__get_context(this);
 	const char *line = tinyrl__get_line(this);
 	clish_pargv_status_t arg_status;
 	const clish_command_t *cmd = NULL;
@@ -196,7 +188,7 @@ static bool_t clish_shell_tinyrl_key_space(tinyrl_t * this, int key)
 /*-------------------------------------------------------- */
 static bool_t clish_shell_tinyrl_key_enter(tinyrl_t * this, int key)
 {
-	context_t *context = tinyrl__get_context(this);
+	clish_context_t *context = tinyrl__get_context(this);
 	const clish_command_t *cmd = NULL;
 	const char *line = tinyrl__get_line(this);
 	bool_t result = BOOL_FALSE;
@@ -274,7 +266,7 @@ char **clish_shell_tinyrl_completion(tinyrl_t * tinyrl,
 	const char *line, unsigned start, unsigned end)
 {
 	lub_argv_t *matches = lub_argv_new(NULL, 0);
-	context_t *context = tinyrl__get_context(tinyrl);
+	clish_context_t *context = tinyrl__get_context(tinyrl);
 	clish_shell_t *this = context->shell;
 	clish_shell_iterator_t iter;
 	const clish_command_t *cmd = NULL;
@@ -379,7 +371,7 @@ bool_t clish_shell_execline(clish_shell_t *this, const char *line, char ** out)
 	char *prompt = NULL;
 	const clish_view_t *view;
 	char *str;
-	context_t con;
+	clish_context_t con;
 	tinyrl_history_t *history;
 	int lerror = 0;
 
@@ -398,8 +390,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,
-		clish_shell__get_viewid(this));
+	prompt = clish_view__get_prompt(view, &con);
 	assert(prompt);
 
 	/* Push the specified line or interactive line */

+ 278 - 15
clish/shell/shell_var.c

@@ -1,8 +1,10 @@
 /*
- * shell_expand.c
+ * shell_var.c
  */
+
 #include <stdlib.h>
 #include <assert.h>
+#include <string.h>
 
 #include "lub/string.h"
 #include "private.h"
@@ -19,31 +21,292 @@ clish_var_t *clish_shell_find_var(clish_shell_t *this, const char *name)
 	return lub_bintree_find(&this->var_tree, name);
 }
 
-/*----------------------------------------------------------- */
-char * clish_shell__expand_text(const clish_shell_t *this,
-	clish_command_t *cmd, clish_pargv_t *pargv, const char *text)
+/*--------------------------------------------------------- */
+const char *clish_shell__get_viewid(const clish_shell_t *this)
 {
 	assert(this);
-	if (!text)
-		return NULL;
-	return clish_variable_expand(text, this->viewid, cmd, pargv);
+	return this->viewid;
 }
 
 /*----------------------------------------------------------- */
-char * clish_shell__expand_variable(const clish_shell_t *this,
-	clish_command_t *cmd, clish_pargv_t *pargv, const char *var)
+/*
+ * search the current viewid string for a variable
+ */
+static char *find_viewid_var(const char *name, const char *viewid)
 {
-	assert(this);
-	if (!var)
+	char *result = NULL;
+	regex_t regex;
+	int status;
+	char *pattern = NULL;
+	regmatch_t pmatches[2];
+
+	/* build up the pattern to match */
+	lub_string_cat(&pattern, name);
+	lub_string_cat(&pattern, "[ ]*=([^;]*)");
+
+	/* compile the regular expression to find this variable */
+	status = regcomp(&regex, pattern, REG_EXTENDED);
+	assert(0 == status);
+	lub_string_free(pattern);
+
+	/* now perform the matching */
+	/*lint -e64 Type mismatch (arg. no. 4) */
+	/*
+	 * lint seems to equate regmatch_t[] as being of type regmatch_t !!!
+	 */
+	status = regexec(&regex, viewid, 2, pmatches, 0);
+	/*lint +e64 */
+	if (0 == status) {
+		regoff_t len = pmatches[1].rm_eo - pmatches[1].rm_so;
+		const char *value = &viewid[pmatches[1].rm_so];
+		/* found a match */
+		result = lub_string_dupn(value, (unsigned)len);
+	}
+	/* release the regular expression */
+	regfree(&regex);
+
+	return result;
+}
+
+/*----------------------------------------------------------- */
+/*
+ * expand context dependent fixed-name variables
+ */
+static char *find_context_var(const char *name, clish_context_t *this)
+{
+	char *result = NULL;
+
+	if (!this->cmd)
 		return NULL;
-	return clish_variable__get_value(var, this->viewid, cmd, pargv);
+	if (!lub_string_nocasecmp(name, "__full_cmd")) {
+		result = lub_string_dup(clish_command__get_name(this->cmd));
+	} else if (!lub_string_nocasecmp(name, "__cmd")) {
+		result = lub_string_dup(clish_command__get_name(
+			clish_command__get_cmd(this->cmd)));
+	} else if (!lub_string_nocasecmp(name, "__orig_cmd")) {
+		result = lub_string_dup(clish_command__get_name(
+			clish_command__get_orig(this->cmd)));
+	} else if (!lub_string_nocasecmp(name, "__line")) {
+		if (this->pargv)
+			result = clish_shell__get_line(this->cmd, this->pargv);
+	} else if (!lub_string_nocasecmp(name, "__params")) {
+		if (this->pargv)
+			result = clish_shell__get_params(this->cmd, this->pargv);
+	} else if (lub_string_nocasestr(name, "__prefix") == name) {
+		int idx = 0;
+		int pnum = 0;
+		pnum = lub_argv_wordcount(clish_command__get_name(this->cmd)) -
+			lub_argv_wordcount(clish_command__get_name(
+			clish_command__get_cmd(this->cmd)));
+		idx = atoi(name + strlen("__prefix"));
+		if (idx < pnum) {
+			lub_argv_t *argv = lub_argv_new(
+				clish_command__get_name(this->cmd), 0);
+			result = lub_string_dup(lub_argv__get_arg(argv, idx));
+			lub_argv_delete(argv);
+		}
+	}
+
+	return result;
 }
 
 /*--------------------------------------------------------- */
-const char *clish_shell__get_viewid(const clish_shell_t *this)
+/*
+ * return the next segment of text from the provided string
+ * segments are delimited by variables within the string.
+ */
+static char *expand_nextsegment(const char **string, clish_context_t *this)
 {
-	assert(this);
-	return this->viewid;
+	const char *p = *string;
+	char *result = NULL;
+	size_t len = 0;
+
+	if (p) {
+		if (*p && (p[0] == '$') && (p[1] == '{')) {
+			/* start of a variable */
+			const char *tmp;
+			p += 2;
+			tmp = p;
+
+			/*
+			 * find the end of the variable 
+			 */
+			while (*p && p++[0] != '}') {
+				len++;
+			}
+
+			/* ignore non-terminated variables */
+			if (p[-1] == '}') {
+				bool_t valid = BOOL_FALSE;
+				char *text, *q;
+				char *saveptr;
+
+				/* get the variable text */
+				text = lub_string_dupn(tmp, len);
+				/*
+				 * tokenise this INTO ':' separated words
+				 * and either expand or duplicate into the result string.
+				 * Only return a result if at least 
+				 * of the words is an expandable variable
+				 */
+				for (q = strtok_r(text, ":", &saveptr);
+					q; q = strtok_r(NULL, ":", &saveptr)) {
+					char *var = clish_shell_expand_var(q, this);
+
+					/* copy the expansion or the raw word */
+					lub_string_cat(&result, var ? var : q);
+
+					/* record any expansions */
+					if (var)
+						valid = BOOL_TRUE;
+					lub_string_free(var);
+				}
+
+				if (!valid) {
+					/* not a valid variable expansion */
+					lub_string_free(result);
+					result = lub_string_dup("");
+				}
+
+				/* finished with the variable text */
+				lub_string_free(text);
+			}
+		} else {
+			/* find the start of a variable */
+			while (*p) {
+				if ((p[0] == '$') && (p[1] == '{'))
+					break;
+				len++;
+				p++;
+			}
+			if (len > 0)
+				result = lub_string_dupn(*string, len);
+		}
+		/* move the string pointer on for next time... */
+		*string = p;
+	}
+	return result;
+}
+
+/*--------------------------------------------------------- */
+/*
+ * This function builds a dynamic string based on that provided
+ * subtituting each occurance of a "${FRED}" type variable sub-string
+ * with the appropriate value.
+ */
+char *clish_shell_expand(const char *str, void *context)
+{
+	char *seg, *result = NULL;
+
+	/* read each segment and extend the result */
+	while ((seg = expand_nextsegment(&str, context))) {
+		lub_string_cat(&result, seg);
+		lub_string_free(seg);
+	}
+
+	return result;
+}
+
+/*--------------------------------------------------------- */
+char *clish_shell__get_params(const clish_command_t *cmd, clish_pargv_t *pargv)
+{
+	char *line = NULL;
+	unsigned i, cnt;
+	const clish_param_t *param;
+	const clish_parg_t *parg;
+
+	if (!pargv)
+		return NULL;
+
+	cnt = clish_pargv__get_count(pargv);
+	for (i = 0; i < cnt; i++) {
+		const char *tmp;
+		char *space = NULL;
+		param = clish_pargv__get_param(pargv, i);
+		if (clish_param__get_hidden(param))
+			continue;
+		parg = clish_pargv__get_parg(pargv, i);
+		tmp = clish_parg__get_value(parg);
+		space = strchr(tmp, ' ');
+		if (line)
+			lub_string_cat(&line, " ");
+		if (space)
+			lub_string_cat(&line, "\\\"");
+		lub_string_cat(&line, tmp);
+		if (space)
+			lub_string_cat(&line, "\\\"");
+	}
+
+	return line;
+}
+
+/*--------------------------------------------------------- */
+char *clish_shell__get_line(const clish_command_t *cmd, clish_pargv_t *pargv)
+{
+	char *line = NULL;
+	char *params = NULL;
+
+	lub_string_cat(&line, clish_command__get_name(
+		clish_command__get_cmd(cmd)));
+
+	if (!pargv)
+		return line;
+
+	params = clish_shell__get_params(cmd, pargv);
+	if (params) {
+		lub_string_cat(&line, " ");
+		lub_string_cat(&line, params);
+	}
+	lub_string_free(params);
+
+	return line;
+}
+
+/*--------------------------------------------------------- */
+char *clish_shell_expand_var(const char *name, void *context)
+{
+	clish_shell_context_t *this = (clish_context_t *)context;
+	char *result = NULL;
+	const char *tmp = NULL;
+	const char *escape_chars = NULL;
+	char *string = NULL;
+	assert(name);
+
+	/* try and substitute a parameter value */
+	if (this && this->pargv) {
+		const clish_parg_t *parg =
+			clish_pargv_find_arg(this->pargv, name);
+		/* substitute the command line value */
+		if (parg)
+			tmp = clish_parg__get_value(parg);
+	}
+	/* try and substitute the param's default */
+	if (!tmp) {
+		if (this && this->cmd)
+			tmp = clish_paramv_find_default(
+				clish_command__get_paramv(this->cmd), name);
+	}
+	/* try and substitute a viewId variable */
+	if (!tmp) {
+		if (this && this->shell->viewid)
+			tmp = string = find_viewid_var(name, this->shell->viewid);
+	}
+	/* try and substitute context fixed variable */
+	if (!tmp)
+		tmp = string = find_context_var(name, this);
+	/* get the contents of an environment variable */
+	if (!tmp)
+		tmp = getenv(name);
+
+	/* override the escape characters */
+	if (this && this->cmd)
+		escape_chars = clish_command__get_escape_chars(this->cmd);
+	result = lub_string_encode(tmp, escape_chars);
+	/* free the dynamic memory */
+	if (string)
+		lub_string_free(string);
+
+	return result;
 }
 
 /*----------------------------------------------------------- */

+ 1 - 1
clish/shell/shell_view.c

@@ -14,7 +14,7 @@ clish_view_t *clish_shell_find_create_view(clish_shell_t * this,
 
 	if (NULL == view) {
 		/* create a view */
-		view = clish_view_new(name, prompt);
+		view = clish_view_new(name, prompt, clish_shell_expand);
 		assert(view);
 		clish_shell_insert_view(this, view);
 	} else {

+ 2 - 0
clish/var.h

@@ -6,6 +6,8 @@
 
 typedef struct clish_var_s clish_var_t;
 
+typedef char *clish_var_expand_fn_t(const char *str, void *context);
+
 /*=====================================
  * VAR INTERFACE
  *===================================== */

+ 4 - 2
clish/view.h

@@ -26,6 +26,7 @@ typedef enum {
 
 #include "clish/command.h"
 #include "clish/nspace.h"
+#include "clish/var.h"
 
 /*=====================================
  * VIEW INTERFACE
@@ -33,7 +34,8 @@ typedef enum {
 /*-----------------
  * meta functions
  *----------------- */
-clish_view_t *clish_view_new(const char *name, const char *prompt);
+clish_view_t *clish_view_new(const char *name, const char *prompt,
+	clish_var_expand_fn_t *fn);
 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);
@@ -60,7 +62,7 @@ void clish_view_clean_proxy(clish_view_t * instance);
  *----------------- */
 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, const char *viewid);
+char *clish_view__get_prompt(const clish_view_t *instance, void *context);
 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);

+ 3 - 2
clish/view/private.h

@@ -12,8 +12,9 @@ struct clish_view_s {
 	lub_bintree_node_t bt_node;
 	char *name;
 	char *prompt;
-	unsigned nspacec;
+	unsigned int nspacec;
 	clish_nspace_t **nspacev;
-	unsigned depth;
+	unsigned int depth;
 	clish_view_restore_t restore;
+	clish_var_expand_fn_t *var_expand_fn;
 };

+ 8 - 6
clish/view/view.c

@@ -37,8 +37,8 @@ void clish_view_bt_getkey(const void *clientnode, lub_bintree_key_t * key)
 /*---------------------------------------------------------
  * PRIVATE METHODS
  *--------------------------------------------------------- */
-static void
-clish_view_init(clish_view_t * this, const char *name, const char *prompt)
+static void clish_view_init(clish_view_t * this, const char *name, const char *prompt,
+	clish_var_expand_fn_t *fn)
 {
 	/* set up defaults */
 	this->name = lub_string_dup(name);
@@ -47,6 +47,7 @@ clish_view_init(clish_view_t * this, const char *name, const char *prompt)
 	this->nspacev = NULL;
 	this->depth = 0;
 	this->restore = CLISH_RESTORE_NONE;
+	this->var_expand_fn = fn;
 
 	/* Be a good binary tree citizen */
 	lub_bintree_node_init(&this->bt_node);
@@ -99,12 +100,13 @@ size_t clish_view_bt_offset(void)
 }
 
 /*--------------------------------------------------------- */
-clish_view_t *clish_view_new(const char *name, const char *prompt)
+clish_view_t *clish_view_new(const char *name, const char *prompt,
+	clish_var_expand_fn_t *fn)
 {
 	clish_view_t *this = malloc(sizeof(clish_view_t));
 
 	if (this)
-		clish_view_init(this, name, prompt);
+		clish_view_init(this, name, prompt, fn);
 	return this;
 }
 
@@ -335,9 +337,9 @@ void clish_view__set_prompt(clish_view_t * this, const char *prompt)
 }
 
 /*--------------------------------------------------------- */
-char *clish_view__get_prompt(const clish_view_t * this, const char *viewid)
+char *clish_view__get_prompt(const clish_view_t *this, void *context)
 {
-	return clish_variable_expand(this->prompt, viewid, NULL, NULL);
+	return this->var_expand_fn(this->prompt, context);
 }
 
 /*--------------------------------------------------------- */

Some files were not shown because too many files changed in this diff