Browse Source

Add var subsystem

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

File diff suppressed because it is too large
+ 40 - 60
Makefile.in


+ 35 - 17
clish.xsd

@@ -16,12 +16,12 @@
     <xs:element name="PARAM" type="param_t"/>
     <xs:element name="NAMESPACE" type="namespace_t"/>
     <xs:element name="CONFIG" type="config_t"/>
-
+    <xs:element name="VAR" type="var_t"/>
 
     <!--
-*********************************************************** 
+***********************************************************
 * The common simple types
-*********************************************************** 
+***********************************************************
 -->
     <xs:simpleType name="bool_t">
         <xs:restriction base="xs:string">
@@ -31,11 +31,11 @@
     </xs:simpleType>
 
     <!--
-*********************************************************** 
+***********************************************************
 * <CLISH_MODULE> is the top level container.
 * Any commands which are defined within this tag are global in scope 
 * i.e. they are visible from all views.
-*********************************************************** 
+***********************************************************
 -->
     <xs:complexType name="clish_module_t">
         <xs:sequence>
@@ -45,6 +45,7 @@
             <xs:element ref="COMMAND" minOccurs="0" maxOccurs="unbounded"/>
             <xs:element ref="VIEW" minOccurs="0" maxOccurs="unbounded"/>
             <xs:element ref="NAMESPACE" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element ref="VAR" minOccurs="0" maxOccurs="unbounded"/>
         </xs:sequence>
     </xs:complexType>
     <!--
@@ -61,7 +62,7 @@
 * <PTYPE> is used to define the syntax for a parameter type.
 *
 * name    - a textual name for this type. This name can be used to
-*         reference this type within a <PARAM? ptype attribute. 
+*         reference this type within a <PARAM? ptype attribute.
 *
 * help    - a textual string which describes the syntax of this type.
 *         When a parameter is filled out incorrectly on the CLI, this
@@ -76,12 +77,12 @@
 *
 *               "integer"          - A numeric definition "min..max"
 *
-*               "select"           - A list of possible values. 
-*               The syntax of the string is of the form: 
+*               "select"           - A list of possible values.
+*               The syntax of the string is of the form:
 *                 "valueOne(ONE) valueTwo(TWO) valueThree(THREE)"
 *               where the text before the parethesis defines the syntax 
 *               that the user must use, and the value within the parenthesis 
-*               is the result expanded as a parameter value. 
+*               is the result expanded as a parameter value.
 *
 * preprocess  - An optional directive to process the value entered before
 *               validating it. This can greatly simplify the regular expressions
@@ -115,8 +116,8 @@
 
     <xs:complexType name="ptype_t">
         <xs:attributeGroup ref="menu_item_g"/>
-        <xs:attribute name="pattern"     type="xs:string"/>
-        <xs:attribute name="method"      type="ptype_method_e"      use="optional" default="regexp"/>
+        <xs:attribute name="pattern" type="xs:string"/>
+        <xs:attribute name="method" type="ptype_method_e" use="optional" default="regexp"/>
         <xs:attribute name="preprocess" type="ptype_preprocess_e" use="optional" default="none"/>
     </xs:complexType>
     <!--
@@ -199,7 +200,7 @@
 * [viewid]       - defined the new value of the ${VIEWID} variable to
 *                be used if a transition to a new view occurs. By default
 *                the viewid will retain it's current value.
-* 
+*
 * [access]       - defines the user group/level to which execution of this 
 *                command is restricted. By default there is no restriction.
 *                The exact interpretation of this field is dependant on the
@@ -269,7 +270,7 @@
 *
 * [optional]- Specify whether parameter is optional. The allowed values
 *           is "true" or "false". It false by default.
-* 
+*
 * [default] - defines a default value for a parameter. Any parameters
 *           at the end of command line which have default values need 
 *           not explicitly be entered.
@@ -315,8 +316,8 @@
     <!--
 ********************************************************
 * <ACTION> specifies the action to be taken for
-* a command. 
-* 
+* a command.
+*
 * The textual contents of the tag are variable expanded
 * (environment, dynamic and parameter) the the resulting
 * text is interpreted by the client's script interpreter.
@@ -347,7 +348,7 @@
     <!--
 ********************************************************
 * <OVERVIEW> specifies a textual description of the shell.
-* 
+*
 * This should provide instructions about key bindings and
 * escape sequences which can be used in the CLI.
 *
@@ -361,7 +362,7 @@
     <!--
 ********************************************************
 * <DETAIL> specifies a textual description.
-* 
+*
 * This may be used within the scope of a <COMMAND> 
 * element, in which case it would typically contain 
 * detailed usage instructions including examples.
@@ -442,3 +443,20 @@
     </xs:complexType>
 
 </xs:schema>
+
+<!--
+*******************************************************
+* <VAR> Specify the variable.
+*
+*
+*
+********************************************************
+-->
+    <xs:complexType name="var_t">
+        <xs:sequence>
+            <xs:element ref="ACTION" minOccurs="0"/>
+        </xs:sequence>
+        <xs:attributeGroup ref="menu_item_g"/>
+        <xs:attribute name="value" type="xs:string" use="optional"/>
+        <xs:attribute name="dynamic" type="bool_t" use="optional" default="false"/>
+    </xs:complexType>

+ 0 - 0
clish/clish_access_callback.c → clish/callback_access.c


+ 0 - 0
clish/clish_config_callback.c → clish/callback_config.c


+ 0 - 0
clish/clish_script_callback.c → clish/callback_script.c


+ 6 - 3
clish/module.am

@@ -2,9 +2,9 @@
 lib_LTLIBRARIES += libclish.la
 
 libclish_la_SOURCES = \
-    clish/clish_access_callback.c \
-    clish/clish_script_callback.c \
-    clish/clish_config_callback.c \
+    clish/callback_access.c \
+    clish/callback_script.c \
+    clish/callback_config.c \
     clish/private.h
 
 libclish_la_CFLAGS = @LUB_CFLAGS@ @LUBHEAP_CFLAGS@ $(DEBUG_CFLAGS)
@@ -24,6 +24,7 @@ nobase_include_HEADERS += \
 	clish/variable.h \
 	clish/view.h \
 	clish/nspace.h \
+	clish/var.h \
 	clish/internal.h
 
 EXTRA_DIST += \
@@ -35,6 +36,7 @@ EXTRA_DIST += \
 	clish/variable/module.am \
 	clish/view/module.am \
 	clish/nspace/module.am \
+	clish/var/module.am \
 	clish/README
 
 include $(top_srcdir)/clish/command/module.am
@@ -45,3 +47,4 @@ 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

+ 6 - 5
clish/shell.h

@@ -18,10 +18,10 @@
 #include "lub/c_decl.h"
 #include "lub/types.h"
 #include "lub/argv.h"
-
 #include "tinyrl/tinyrl.h"
-
-#include "view.h"
+#include "clish/view.h"
+#include "clish/ptype.h"
+#include "clish/var.h"
 #include "konf/net.h"
 
 #define CLISH_LOCK_PATH "/tmp/clish.lock"
@@ -327,10 +327,9 @@ bool_t clish_shell_line(clish_shell_t * instance, const char *prompt,
 	const clish_command_t ** cmd, clish_pargv_t ** pargv, const char *str);
 bool_t clish_shell_forceline(clish_shell_t *instance, const char *line, char ** out);
 bool_t clish_shell_readline(clish_shell_t *instance, char ** out);
-void clish_shell_set_context(clish_shell_t * instance, const char *viewname);
 void clish_shell_dump(clish_shell_t * instance);
 void clish_shell_close(clish_shell_t * instance);
-/** 
+/**
  * Push the specified file handle on to the stack of file handles
  * for this shell. The specified file will become the source of 
  * commands, until it is exhausted.
@@ -343,6 +342,8 @@ bool_t clish_shell_push_file(clish_shell_t * instance, const char * fname,
 	bool_t stop_on_error);
 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);
 
 /*-----------------
  * attributes

+ 6 - 18
clish/shell/module.am

@@ -1,29 +1,17 @@
 libclish_la_SOURCES += \
-	clish/shell/shell__get_view.c \
-	clish/shell/shell__get_viewid.c \
-	clish/shell/shell__get_client_cookie.c \
-	clish/shell/shell__get_tinyrl.c \
-	clish/shell/shell_command_generator.c \
-	clish/shell/shell_delete.c \
+	clish/shell/shell_view.c \
+	clish/shell/shell_ptype.c \
+	clish/shell/shell_var.c \
+	clish/shell/shell_command.c \
 	clish/shell/shell_dump.c \
 	clish/shell/shell_execute.c \
-	clish/shell/shell_find_create_ptype.c \
-	clish/shell/shell_find_create_view.c \
-	clish/shell/shell_find_view.c \
 	clish/shell/shell_help.c \
-	clish/shell/shell_insert_ptype.c \
-	clish/shell/shell_insert_view.c \
 	clish/shell/shell_new.c \
 	clish/shell/shell_parse.c \
-	clish/shell/shell_pop_file.c \
-	clish/shell/shell_push_file.c \
-	clish/shell/shell_resolve_command.c \
-	clish/shell/shell_resolve_prefix.c \
-	clish/shell/shell_set_context.c \
+	clish/shell/shell_file.c \
 	clish/shell/shell_spawn.c \
 	clish/shell/shell_startup.c \
 	clish/shell/shell_pwd.c \
 	clish/shell/shell_tinyrl.c \
-	clish/shell/shell_tinyxml_read.cpp \
-	clish/shell/shell_expand.c \
+	clish/shell/shell_tinyxml.cpp \
 	clish/shell/private.h

+ 6 - 4
clish/shell/private.h

@@ -1,11 +1,12 @@
 /*
  * shell.h - private interface to the shell class
  */
+#include "lub/bintree.h"
+#include "tinyrl/tinyrl.h"
 #include "clish/shell.h"
 #include "clish/pargv.h"
 #include "clish/variable.h"
-#include "lub/bintree.h"
-#include "tinyrl/tinyrl.h"
+#include "clish/var.h"
 
 /*-------------------------------------
  * PRIVATE TYPES
@@ -36,8 +37,9 @@ typedef struct {
 } clish_shell_pwd_t;
 
 struct clish_shell_s {
-	lub_bintree_t view_tree;	/* Maintain a tree of views      */
-	lub_bintree_t ptype_tree;	/* Maintain a tree of ptypes     */
+	lub_bintree_t view_tree; /* Maintain a tree of views */
+	lub_bintree_t ptype_tree; /* Maintain a tree of ptypes */
+	lub_bintree_t var_tree; /* Maintain a tree of global variables */
 	const clish_shell_hooks_t *client_hooks;	/* Client callback hooks         */
 	void *client_cookie;	/* Client callback cookie        */
 	clish_view_t *global;	/* Reference to the global view. */

+ 0 - 12
clish/shell/shell__get_client_cookie.c

@@ -1,12 +0,0 @@
-/*
- * shell__get_client_cookie.c
- */
-#include "private.h"
-
-/*--------------------------------------------------------- */
-void *clish_shell__get_client_cookie(const clish_shell_t * this)
-{
-	return this->client_cookie;
-}
-
-/*--------------------------------------------------------- */

+ 0 - 12
clish/shell/shell__get_tinyrl.c

@@ -1,12 +0,0 @@
-/*
- * shell__get_tinyrl.c
- */
-#include "private.h"
-
-/*--------------------------------------------------------- */
-tinyrl_t *clish_shell__get_tinyrl(const clish_shell_t * this)
-{
-	return this->tinyrl;
-}
-
-/*--------------------------------------------------------- */

+ 0 - 23
clish/shell/shell__get_view.c

@@ -1,23 +0,0 @@
-/*
- * shell__get_view.c
- */
-
-#include <assert.h>
-
-#include "private.h"
-
-/*--------------------------------------------------------- */
-const clish_view_t *clish_shell__get_view(const clish_shell_t * this)
-{
-	assert(this);
-	return this->view;
-}
-
-/*--------------------------------------------------------- */
-unsigned clish_shell__get_depth(const clish_shell_t * this)
-{
-	assert(this);
-	return clish_view__get_depth(this->view);
-}
-
-/*--------------------------------------------------------- */

+ 0 - 16
clish/shell/shell__get_viewid.c

@@ -1,16 +0,0 @@
-/*
- * shell__get_viewid.c
- */
-
-#include <assert.h>
-
-#include "private.h"
-
-/*--------------------------------------------------------- */
-const char *clish_shell__get_viewid(const clish_shell_t * this)
-{
-	assert(this);
-	return this->viewid;
-}
-
-/*--------------------------------------------------------- */

+ 33 - 0
clish/shell/shell_command_generator.c → clish/shell/shell_command.c

@@ -6,6 +6,7 @@
 #include "private.h"
 #include "lub/string.h"
 #include "lub/argv.h"
+
 /*-------------------------------------------------------- */
 void
 clish_shell_iterator_init(clish_shell_iterator_t * iter,
@@ -15,6 +16,38 @@ clish_shell_iterator_init(clish_shell_iterator_t * iter,
 	iter->field = field;
 }
 
+/*--------------------------------------------------------- */
+const clish_command_t *clish_shell_resolve_command(const clish_shell_t * this,
+	const char *line)
+{
+	clish_command_t *cmd, *result;
+
+	/* Search the current view */
+	result = clish_view_resolve_command(this->view, line, BOOL_TRUE);
+	/* Search the global view */
+	cmd = clish_view_resolve_command(this->global, line, BOOL_TRUE);
+
+	result = clish_command_choose_longest(result, cmd);
+
+	return result;
+}
+
+/*--------------------------------------------------------- */
+const clish_command_t *clish_shell_resolve_prefix(const clish_shell_t * this,
+	const char *line)
+{
+	clish_command_t *cmd, *result;
+
+	/* Search the current view */
+	result = clish_view_resolve_prefix(this->view, line, BOOL_TRUE);
+	/* Search the global view */
+	cmd = clish_view_resolve_prefix(this->global, line, BOOL_TRUE);
+
+	result = clish_command_choose_longest(result, cmd);
+
+	return result;
+}
+
 /*-------------------------------------------------------- */
 const clish_command_t *clish_shell_find_next_completion(const clish_shell_t *
 	this, const char *line, clish_shell_iterator_t * iter)

+ 0 - 81
clish/shell/shell_delete.c

@@ -1,81 +0,0 @@
-/*
- * shell_delete.c
- */
-
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "private.h"
-#include "lub/string.h"
-
-/*--------------------------------------------------------- */
-static void clish_shell_fini(clish_shell_t * this)
-{
-	clish_view_t *view;
-	clish_ptype_t *ptype;
-	unsigned i;
-
-	/* delete each view held  */
-	while ((view = lub_bintree_findfirst(&this->view_tree))) {
-		/* remove the view from the tree */
-		lub_bintree_remove(&this->view_tree, view);
-		/* release the instance */
-		clish_view_delete(view);
-	}
-
-	/* delete each ptype held  */
-	while ((ptype = lub_bintree_findfirst(&this->ptype_tree))) {
-		/* remove the command from the tree */
-		lub_bintree_remove(&this->ptype_tree, ptype);
-		/* release the instance */
-		clish_ptype_delete(ptype);
-	}
-	/* free the textual details */
-	lub_string_free(this->overview);
-	lub_string_free(this->viewid);
-
-	/* remove the startup command */
-	if (this->startup)
-		clish_command_delete(this->startup);
-	/* clean up the file stack */
-	while (BOOL_TRUE == clish_shell_pop_file(this));
-	/* delete the tinyrl object */
-	clish_shell_tinyrl_delete(this->tinyrl);
-
-	/* finalize each of the pwd strings */
-	for (i = 0; i < this->cfg_pwdc; i++) {
-		lub_string_free(this->cfg_pwdv[i]->line);
-		lub_string_free(this->cfg_pwdv[i]->viewid);
-		free(this->cfg_pwdv[i]);
-	}
-	/* free the pwd vector */
-	free(this->cfg_pwdv);
-	this->cfg_pwdc = 0;
-	this->cfg_pwdv = NULL;
-	konf_client_free(this->client);
-
-	/* Free internal params */
-	clish_param_delete(this->param_depth);
-	clish_param_delete(this->param_pwd);
-	clish_param_delete(this->param_interactive);
-
-	lub_string_free(this->lockfile);
-	lub_string_free(this->default_shebang);
-	if (this->fifo_name) {
-		unlink(this->fifo_name);
-		lub_string_free(this->fifo_name);
-	}
-}
-
-/*--------------------------------------------------------- */
-void clish_shell_delete(clish_shell_t * this)
-{
-	/* now call the client finalisation */
-	if (this->client_hooks->fini_fn)
-		this->client_hooks->fini_fn(this);
-	clish_shell_fini(this);
-
-	free(this);
-}
-
-/*--------------------------------------------------------- */

+ 9 - 0
clish/shell/shell_dump.c

@@ -9,6 +9,7 @@ void clish_shell_dump(clish_shell_t * this)
 {
 	clish_view_t *v;
 	clish_ptype_t *t;
+	clish_var_t *var;
 	lub_bintree_iterator_t iter;
 
 	lub_dump_printf("shell(%p)\n", this);
@@ -29,6 +30,14 @@ void clish_shell_dump(clish_shell_t * this)
 		t; t = lub_bintree_iterator_next(&iter)) {
 		clish_ptype_dump(t);
 	}
+
+	/* iterate the tree of vars */
+	var = lub_bintree_findfirst(&this->var_tree);
+	for (lub_bintree_iterator_init(&iter, &this->var_tree, var);
+		var; var = lub_bintree_iterator_next(&iter)) {
+		clish_var_dump(var);
+	}
+
 	lub_dump_undent();
 }
 

+ 6 - 0
clish/shell/shell_execute.c

@@ -415,4 +415,10 @@ const char * clish_shell__get_fifo(clish_shell_t * this)
 	return this->fifo_name;
 }
 
+/*--------------------------------------------------------- */
+void *clish_shell__get_client_cookie(const clish_shell_t * this)
+{
+	return this->client_cookie;
+}
+
 /*----------------------------------------------------------- */

+ 78 - 0
clish/shell/shell_file.c

@@ -0,0 +1,78 @@
+#include <stdlib.h>
+#include <assert.h>
+
+#include "private.h"
+
+/*----------------------------------------------------------- */
+bool_t clish_shell_push_file(clish_shell_t * this, const char * fname,
+	bool_t stop_on_error)
+{
+	FILE *file;
+	bool_t res;
+
+	assert(this);
+	if (!fname)
+		return BOOL_FALSE;
+	file = fopen(fname, "r");
+	if (!file)
+		return BOOL_FALSE;
+	res = clish_shell_push_fd(this, file, stop_on_error);
+	if (!res)
+		fclose(file);
+
+	return res;
+}
+
+/*----------------------------------------------------------- */
+bool_t clish_shell_push_fd(clish_shell_t * this, FILE * file,
+	bool_t stop_on_error)
+{
+	assert(this);
+
+	/* allocate a control node */
+	clish_shell_file_t *node = malloc(sizeof(clish_shell_file_t));
+	bool_t result = BOOL_TRUE;
+
+	if (node) {
+		/* intialise the node */
+		node->file = file;
+		node->stop_on_error = stop_on_error;
+		node->next = this->current_file;
+
+		/* put the node at the top of the file stack */
+		this->current_file = node;
+
+		/* now switch the terminal's input stream */
+		tinyrl__set_istream(this->tinyrl, file);
+
+		result = BOOL_TRUE;
+	}
+	return result;
+}
+
+/*----------------------------------------------------------- */
+bool_t clish_shell_pop_file(clish_shell_t * this)
+{
+	bool_t result = BOOL_FALSE;
+	clish_shell_file_t *node = this->current_file;
+
+	if (node) {
+		/* remove the current file from the stack... */
+		this->current_file = node->next;
+
+		/* and close the current file...
+		 */
+		fclose(node->file);
+
+		if (node->next) {
+			/* now switch the terminal's input stream */
+			tinyrl__set_istream(this->tinyrl, node->next->file);
+			result = BOOL_TRUE;
+		}
+		/* and free up the memory */
+		free(node);
+	}
+	return result;
+}
+
+/*----------------------------------------------------------- */

+ 0 - 26
clish/shell/shell_find_create_view.c

@@ -1,26 +0,0 @@
-/*
- * shell_find_create_view.c
- */
-#include "private.h"
-
-#include <assert.h>
-/*--------------------------------------------------------- */
-clish_view_t *clish_shell_find_create_view(clish_shell_t * this,
-	const char *name, const char *prompt)
-{
-	clish_view_t *view = lub_bintree_find(&this->view_tree, name);
-
-	if (NULL == view) {
-		/* create a view */
-		view = clish_view_new(name, prompt);
-		assert(view);
-		clish_shell_insert_view(this, view);
-	} else {
-		/* set the prompt */
-		if (prompt)
-			clish_view__set_prompt(view, prompt);
-	}
-	return view;
-}
-
-/*--------------------------------------------------------- */

+ 0 - 12
clish/shell/shell_find_view.c

@@ -1,12 +0,0 @@
-/*
- * shell_find_view.c
- */
-#include "private.h"
-
-/*--------------------------------------------------------- */
-clish_view_t *clish_shell_find_view(clish_shell_t * this, const char *name)
-{
-	return lub_bintree_find(&this->view_tree, name);
-}
-
-/*--------------------------------------------------------- */

+ 0 - 12
clish/shell/shell_insert_ptype.c

@@ -1,12 +0,0 @@
-/*
- * shell_insert_view.c
- */
-#include "private.h"
-
-/*--------------------------------------------------------- */
-void clish_shell_insert_ptype(clish_shell_t * this, clish_ptype_t * ptype)
-{
-	(void)lub_bintree_insert(&this->ptype_tree, ptype);
-}
-
-/*--------------------------------------------------------- */

+ 0 - 12
clish/shell/shell_insert_view.c

@@ -1,12 +0,0 @@
-/*
- * shell_insert_view.c
- */
-#include "private.h"
-
-/*--------------------------------------------------------- */
-void clish_shell_insert_view(clish_shell_t * this, clish_view_t * view)
-{
-	(void)lub_bintree_insert(&this->view_tree, view);
-}
-
-/*--------------------------------------------------------- */

+ 81 - 2
clish/shell/shell_new.c

@@ -5,12 +5,12 @@
 
 #include <assert.h>
 #include <stdlib.h>
+#include <unistd.h>
 
 #include "lub/string.h"
 
 /*-------------------------------------------------------- */
-static void
-clish_shell_init(clish_shell_t * this,
+static void clish_shell_init(clish_shell_t * this,
 	const clish_shell_hooks_t * hooks,
 	void *cookie, FILE * istream,
 	FILE * ostream,
@@ -28,6 +28,11 @@ clish_shell_init(clish_shell_t * this,
 		clish_ptype_bt_offset(),
 		clish_ptype_bt_compare, clish_ptype_bt_getkey);
 
+	/* initialise the tree of vars */
+	lub_bintree_init(&this->var_tree,
+		clish_var_bt_offset(),
+		clish_var_bt_compare, clish_var_bt_getkey);
+
 	assert((NULL != hooks) && (NULL != hooks->script_fn));
 
 	/* set up defaults */
@@ -80,6 +85,69 @@ clish_shell_init(clish_shell_t * this,
 		clish_shell_push_fd(this, istream, stop_on_error);
 }
 
+/*--------------------------------------------------------- */
+static void clish_shell_fini(clish_shell_t * this)
+{
+	clish_view_t *view;
+	clish_ptype_t *ptype;
+	clish_var_t *var;
+	unsigned i;
+
+	/* delete each VIEW held  */
+	while ((view = lub_bintree_findfirst(&this->view_tree))) {
+		lub_bintree_remove(&this->view_tree, view);
+		clish_view_delete(view);
+	}
+
+	/* delete each PTYPE held  */
+	while ((ptype = lub_bintree_findfirst(&this->ptype_tree))) {
+		lub_bintree_remove(&this->ptype_tree, ptype);
+		clish_ptype_delete(ptype);
+	}
+
+	/* delete each VAR held  */
+	while ((var = lub_bintree_findfirst(&this->var_tree))) {
+		lub_bintree_remove(&this->var_tree, var);
+		clish_var_delete(var);
+	}
+
+	/* free the textual details */
+	lub_string_free(this->overview);
+	lub_string_free(this->viewid);
+
+	/* remove the startup command */
+	if (this->startup)
+		clish_command_delete(this->startup);
+	/* clean up the file stack */
+	while (BOOL_TRUE == clish_shell_pop_file(this));
+	/* delete the tinyrl object */
+	clish_shell_tinyrl_delete(this->tinyrl);
+
+	/* finalize each of the pwd strings */
+	for (i = 0; i < this->cfg_pwdc; i++) {
+		lub_string_free(this->cfg_pwdv[i]->line);
+		lub_string_free(this->cfg_pwdv[i]->viewid);
+		free(this->cfg_pwdv[i]);
+	}
+	/* free the pwd vector */
+	free(this->cfg_pwdv);
+	this->cfg_pwdc = 0;
+	this->cfg_pwdv = NULL;
+	konf_client_free(this->client);
+
+	/* Free internal params */
+	clish_param_delete(this->param_depth);
+	clish_param_delete(this->param_pwd);
+	clish_param_delete(this->param_interactive);
+
+	lub_string_free(this->lockfile);
+	lub_string_free(this->default_shebang);
+	if (this->fifo_name) {
+		unlink(this->fifo_name);
+		lub_string_free(this->fifo_name);
+	}
+}
+
 /*-------------------------------------------------------- */
 clish_shell_t *clish_shell_new(const clish_shell_hooks_t * hooks,
 	void *cookie,
@@ -102,4 +170,15 @@ clish_shell_t *clish_shell_new(const clish_shell_hooks_t * hooks,
 	return this;
 }
 
+/*--------------------------------------------------------- */
+void clish_shell_delete(clish_shell_t * this)
+{
+	/* now call the client finalisation */
+	if (this->client_hooks->fini_fn)
+		this->client_hooks->fini_fn(this);
+	clish_shell_fini(this);
+
+	free(this);
+}
+
 /*-------------------------------------------------------- */

+ 0 - 28
clish/shell/shell_pop_file.c

@@ -1,28 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "private.h"
-
-bool_t clish_shell_pop_file(clish_shell_t * this)
-{
-	bool_t result = BOOL_FALSE;
-	clish_shell_file_t *node = this->current_file;
-
-	if (node) {
-		/* remove the current file from the stack... */
-		this->current_file = node->next;
-
-		/* and close the current file...
-		 */
-		fclose(node->file);
-
-		if (node->next) {
-			/* now switch the terminal's input stream */
-			tinyrl__set_istream(this->tinyrl, node->next->file);
-			result = BOOL_TRUE;
-		}
-		/* and free up the memory */
-		free(node);
-	}
-	return result;
-}

+ 6 - 0
clish/shell/shell_find_create_ptype.c → clish/shell/shell_ptype.c

@@ -33,3 +33,9 @@ clish_ptype_t *clish_shell_find_create_ptype(clish_shell_t * this,
 }
 
 /*--------------------------------------------------------- */
+void clish_shell_insert_ptype(clish_shell_t * this, clish_ptype_t * ptype)
+{
+	(void)lub_bintree_insert(&this->ptype_tree, ptype);
+}
+
+/*--------------------------------------------------------- */

+ 0 - 49
clish/shell/shell_push_file.c

@@ -1,49 +0,0 @@
-#include <stdlib.h>
-#include <assert.h>
-
-#include "private.h"
-
-bool_t
-clish_shell_push_file(clish_shell_t * this, const char * fname, bool_t stop_on_error)
-{
-	FILE *file;
-	bool_t res;
-
-	assert(this);
-	if (!fname)
-		return BOOL_FALSE;
-	file = fopen(fname, "r");
-	if (!file)
-		return BOOL_FALSE;
-	res = clish_shell_push_fd(this, file, stop_on_error);
-	if (!res)
-		fclose(file);
-
-	return res;
-}
-
-bool_t
-clish_shell_push_fd(clish_shell_t * this, FILE * file, bool_t stop_on_error)
-{
-	assert(this);
-
-	/* allocate a control node */
-	clish_shell_file_t *node = malloc(sizeof(clish_shell_file_t));
-	bool_t result = BOOL_TRUE;
-
-	if (NULL != node) {
-		/* intialise the node */
-		node->file = file;
-		node->stop_on_error = stop_on_error;
-		node->next = this->current_file;
-
-		/* put the node at the top of the file stack */
-		this->current_file = node;
-
-		/* now switch the terminal's input stream */
-		tinyrl__set_istream(this->tinyrl, file);
-
-		result = BOOL_TRUE;
-	}
-	return result;
-}

+ 0 - 22
clish/shell/shell_resolve_command.c

@@ -1,22 +0,0 @@
-/*
- * shell_resolve_command.c
- */
-#include "private.h"
-
-/*--------------------------------------------------------- */
-const clish_command_t *clish_shell_resolve_command(const clish_shell_t * this,
-	const char *line)
-{
-	clish_command_t *cmd, *result;
-
-	/* Search the current view */
-	result = clish_view_resolve_command(this->view, line, BOOL_TRUE);
-	/* Search the global view */
-	cmd = clish_view_resolve_command(this->global, line, BOOL_TRUE);
-
-	result = clish_command_choose_longest(result, cmd);
-
-	return result;
-}
-
-/*----------------------------------------------------------- */

+ 0 - 22
clish/shell/shell_resolve_prefix.c

@@ -1,22 +0,0 @@
-/*
- * shell_resolve_prefix.c
- */
-#include "private.h"
-
-/*--------------------------------------------------------- */
-const clish_command_t *clish_shell_resolve_prefix(const clish_shell_t * this,
-	const char *line)
-{
-	clish_command_t *cmd, *result;
-
-	/* Search the current view */
-	result = clish_view_resolve_prefix(this->view, line, BOOL_TRUE);
-	/* Search the global view */
-	cmd = clish_view_resolve_prefix(this->global, line, BOOL_TRUE);
-
-	result = clish_command_choose_longest(result, cmd);
-
-	return result;
-}
-
-/*----------------------------------------------------------- */

+ 0 - 15
clish/shell/shell_set_context.c

@@ -1,15 +0,0 @@
-/*
- * shell_set_context.c
- */
-#include "private.h"
-
-#include <assert.h>
-/*--------------------------------------------------------- */
-void clish_shell_set_context(clish_shell_t * this, const char *viewname)
-{
-	this->view = clish_shell_find_view(this, viewname);
-	assert(this->view);
-	assert(this->global);
-}
-
-/*--------------------------------------------------------- */

+ 6 - 0
clish/shell/shell_tinyrl.c

@@ -502,4 +502,10 @@ void clish_shell__set_utf8(clish_shell_t * this, bool_t utf8)
 	tinyrl__set_utf8(this->tinyrl, utf8);
 }
 
+/*--------------------------------------------------------- */
+tinyrl_t *clish_shell__get_tinyrl(const clish_shell_t * this)
+{
+	return this->tinyrl;
+}
+
 /*-------------------------------------------------------- */

+ 42 - 10
clish/shell/shell_tinyxml_read.cpp → clish/shell/shell_tinyxml.cpp

@@ -25,14 +25,18 @@ struct clish_xml_cb_s {
 
 // forward declare the handler functions
 static PROCESS_FN
-    process_clish_module,
-    process_startup,
-    process_view,
-    process_command,
-    process_param,
-    process_action,
-    process_ptype,
-    process_overview, process_detail, process_namespace, process_config;
+	process_clish_module,
+	process_startup,
+	process_view,
+	process_command,
+	process_param,
+	process_action,
+	process_ptype,
+	process_overview,
+	process_detail,
+	process_namespace,
+	process_config,
+	process_var;
 
 static clish_xml_cb_t xml_elements[] = {
 	{"CLISH_MODULE", process_clish_module},
@@ -46,6 +50,7 @@ static clish_xml_cb_t xml_elements[] = {
 	{"DETAIL", process_detail},
 	{"NAMESPACE", process_namespace},
 	{"CONFIG", process_config},
+	{"VAR", process_var},
 	{NULL, NULL}
 };
 
@@ -84,8 +89,7 @@ static void process_node(clish_shell_t * shell, TiXmlNode * node, void *parent)
 }
 
 ///////////////////////////////////////
-static void
-process_children(clish_shell_t * shell,
+static void process_children(clish_shell_t * shell,
 	TiXmlElement * element, void *parent = NULL)
 {
 	for (TiXmlNode * node = element->FirstChild();
@@ -631,7 +635,35 @@ process_config(clish_shell_t * shell, TiXmlElement * element, void *parent)
 
 	if (cfg_depth)
 		clish_command__set_cfg_depth(cmd, cfg_depth);
+}
+
+///////////////////////////////////////
+static void process_var(clish_shell_t * shell, TiXmlElement * element, void *)
+{
+	clish_var_t *var = NULL;
+	const char *name = element->Attribute("name");
+	const char *dynamic = element->Attribute("dynamic");
+	const char *value = element->Attribute("value");
+
+	assert(name);
+	/* Check if this var doesn't already exist */
+	var = clish_shell_find_var(shell, name);
+	if (var) {
+		printf("DUPLICATE VAR: %s\n", name);
+		assert(!var);
+	}
+
+	/* Create var instance */
+	var = clish_var_new(name);
+	clish_shell_insert_var(shell, var);
+
+	if (dynamic && (lub_string_nocasecmp(dynamic, "true") == 0))
+		clish_var__set_dynamic(var, BOOL_TRUE);
+
+	if (value)
+		clish_var__set_value(var, value);
 
+	process_children(shell, element, var);
 }
 
 ///////////////////////////////////////

+ 19 - 0
clish/shell/shell_expand.c → clish/shell/shell_var.c

@@ -7,6 +7,18 @@
 #include "lub/string.h"
 #include "private.h"
 
+/*--------------------------------------------------------- */
+void clish_shell_insert_var(clish_shell_t *this, clish_var_t *var)
+{
+	(void)lub_bintree_insert(&this->var_tree, var);
+}
+
+/*--------------------------------------------------------- */
+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)
@@ -27,4 +39,11 @@ char * clish_shell__expand_variable(const clish_shell_t *this,
 	return clish_variable__get_value(var, this->viewid, cmd, pargv);
 }
 
+/*--------------------------------------------------------- */
+const char *clish_shell__get_viewid(const clish_shell_t *this)
+{
+	assert(this);
+	return this->viewid;
+}
+
 /*----------------------------------------------------------- */

+ 54 - 0
clish/shell/shell_view.c

@@ -0,0 +1,54 @@
+/*
+ * shell_find_create_view.c
+ */
+
+#include <assert.h>
+
+#include "private.h"
+
+/*--------------------------------------------------------- */
+clish_view_t *clish_shell_find_create_view(clish_shell_t * this,
+	const char *name, const char *prompt)
+{
+	clish_view_t *view = lub_bintree_find(&this->view_tree, name);
+
+	if (NULL == view) {
+		/* create a view */
+		view = clish_view_new(name, prompt);
+		assert(view);
+		clish_shell_insert_view(this, view);
+	} else {
+		/* set the prompt */
+		if (prompt)
+			clish_view__set_prompt(view, prompt);
+	}
+	return view;
+}
+
+/*--------------------------------------------------------- */
+clish_view_t *clish_shell_find_view(clish_shell_t * this, const char *name)
+{
+	return lub_bintree_find(&this->view_tree, name);
+}
+
+/*--------------------------------------------------------- */
+void clish_shell_insert_view(clish_shell_t * this, clish_view_t * view)
+{
+	(void)lub_bintree_insert(&this->view_tree, view);
+}
+
+/*--------------------------------------------------------- */
+const clish_view_t *clish_shell__get_view(const clish_shell_t * this)
+{
+	assert(this);
+	return this->view;
+}
+
+/*--------------------------------------------------------- */
+unsigned clish_shell__get_depth(const clish_shell_t * this)
+{
+	assert(this);
+	return clish_view__get_depth(this->view);
+}
+
+/*--------------------------------------------------------- */

+ 33 - 0
clish/var.h

@@ -0,0 +1,33 @@
+#ifndef _clish_var_h
+#define _clish_var_h
+
+#include "lub/types.h"
+#include "lub/bintree.h"
+
+typedef struct clish_var_s clish_var_t;
+
+/*=====================================
+ * VAR INTERFACE
+ *===================================== */
+/*-----------------
+ * meta functions
+ *----------------- */
+int clish_var_bt_compare(const void *clientnode, const void *clientkey);
+void clish_var_bt_getkey(const void *clientnode, lub_bintree_key_t * key);
+size_t clish_var_bt_offset(void);
+clish_var_t *clish_var_new(const char *name);
+/*-----------------
+ * methods
+ *----------------- */
+void clish_var_delete(clish_var_t *instance);
+void clish_var_dump(const clish_var_t *instance);
+/*-----------------
+ * attributes
+ *----------------- */
+const char *clish_var__get_name(const clish_var_t *instance);
+void clish_var__set_dynamic(clish_var_t *instance, bool_t defval);
+bool_t clish_var__get_dynamic(const clish_var_t *instance);
+void clish_var__set_value(clish_var_t *instance, const char *value);
+char *clish_var__get_value(const clish_var_t *instance);
+
+#endif /* _clish_var_h */

+ 4 - 0
clish/var/module.am

@@ -0,0 +1,4 @@
+libclish_la_SOURCES += \
+	clish/var/var.c \
+	clish/var/var_dump.c \
+	clish/var/private.h

+ 15 - 0
clish/var/private.h

@@ -0,0 +1,15 @@
+/*
+ * var/private.h
+ */
+#include "clish/var.h"
+
+/*---------------------------------------------------------
+ * PRIVATE TYPES
+ *--------------------------------------------------------- */
+
+struct clish_var_s {
+	lub_bintree_node_t bt_node;
+	char *name;
+	bool_t dynamic;
+	char *value;
+};

+ 112 - 0
clish/var/var.c

@@ -0,0 +1,112 @@
+/*
+ * var.c
+ *
+ * This file provides the implementation of the "var" class
+ */
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "lub/string.h"
+#include "private.h"
+
+/*---------------------------------------------------------
+ * PRIVATE METHODS
+ *--------------------------------------------------------- */
+static void clish_var_init(clish_var_t *this, const char *name)
+{
+	this->name = lub_string_dup(name);
+	this->dynamic = BOOL_FALSE;
+	this->value = NULL;
+
+	/* Be a good binary tree citizen */
+	lub_bintree_node_init(&this->bt_node);
+}
+
+/*--------------------------------------------------------- */
+static void clish_var_fini(clish_var_t *this)
+{
+	lub_string_free(this->name);
+	lub_string_free(this->value);
+}
+
+/*---------------------------------------------------------
+ * PUBLIC META FUNCTIONS
+ *--------------------------------------------------------- */
+int clish_var_bt_compare(const void *clientnode, const void *clientkey)
+{
+	const clish_var_t *this = clientnode;
+	const char *key = clientkey;
+
+	return strcmp(this->name, key);
+}
+
+/*-------------------------------------------------------- */
+void clish_var_bt_getkey(const void *clientnode, lub_bintree_key_t * key)
+{
+	const clish_var_t *this = clientnode;
+
+	/* fill out the opaque key */
+	strcpy((char *)key, this->name);
+}
+
+/*--------------------------------------------------------- */
+size_t clish_var_bt_offset(void)
+{
+	return offsetof(clish_var_t, bt_node);
+}
+
+/*--------------------------------------------------------- */
+clish_var_t *clish_var_new(const char *name)
+{
+	clish_var_t *this = malloc(sizeof(clish_var_t));
+	if (this)
+		clish_var_init(this, name);
+	return this;
+}
+
+/*---------------------------------------------------------
+ * PUBLIC METHODS
+ *--------------------------------------------------------- */
+void clish_var_delete(clish_var_t *this)
+{
+	clish_var_fini(this);
+	free(this);
+}
+
+/*---------------------------------------------------------
+ * PUBLIC ATTRIBUTES
+ *--------------------------------------------------------- */
+const char *clish_var__get_name(const clish_var_t *this)
+{
+	if (!this)
+		return NULL;
+	return this->name;
+}
+
+/*--------------------------------------------------------- */
+void clish_var__set_dynamic(clish_var_t *this, bool_t dynamic)
+{
+	this->dynamic = dynamic;
+}
+
+/*--------------------------------------------------------- */
+bool_t clish_var__get_dynamic(const clish_var_t *this)
+{
+	return this->dynamic;
+}
+
+/*--------------------------------------------------------- */
+void clish_var__set_value(clish_var_t *this, const char *value)
+{
+	if (this->value)
+		lub_string_free(this->value);
+	this->value = lub_string_dup(value);
+}
+
+/*--------------------------------------------------------- */
+char *clish_var__get_value(const clish_var_t *this)
+{
+	return this->value;
+}

+ 20 - 0
clish/var/var_dump.c

@@ -0,0 +1,20 @@
+/*
+ * var_dump.c
+ */
+#include "private.h"
+#include "lub/dump.h"
+/*--------------------------------------------------------- */
+void clish_var_dump(const clish_var_t *this)
+{
+	lub_dump_printf("var(%p)\n", this);
+	lub_dump_indent();
+
+	lub_dump_printf("name     : %s\n", this->name);
+	lub_dump_printf("dynamic  : %s\n",
+		this->dynamic ? "true" : "false");
+	lub_dump_printf("value    : %s\n", this->value);
+
+	lub_dump_undent();
+}
+
+/*--------------------------------------------------------- */

+ 1 - 1
clish/variable/variable_expand.c

@@ -94,7 +94,7 @@ static char *find_context_var(const context_t * this, const char *name)
 }
 
 /*--------------------------------------------------------- */
-static char *context_retrieve(const context_t * this, const char *name)
+static char *context_retrieve(const context_t *this, const char *name)
 {
 	char *result = NULL;
 	const char *tmp = NULL;

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