Browse Source

Add list of unresolved symbols

Serj Kalichev 11 years ago
parent
commit
486a7ca821
5 changed files with 109 additions and 14 deletions
  1. 14 0
      clish/plugin.h
  2. 16 4
      clish/plugin/plugin.c
  3. 9 5
      clish/shell/private.h
  4. 13 0
      clish/shell/shell_new.c
  5. 57 5
      clish/shell/shell_plugin.c

+ 14 - 0
clish/plugin.h

@@ -6,15 +6,29 @@
 
 #include "clish/shell.h"
 
+/* Symbol types */
+
 typedef struct clish_sym_s clish_sym_t;
 typedef struct clish_plugin_s clish_plugin_t;
 
+/* Plugin types */
+
 typedef int clish_plugin_fn_t(clish_context_t *context, char **out);
 typedef int clish_plugin_init_t(clish_plugin_t *plugin);
 
 /* Name of init function within plugin */
 #define CLISH_PLUGIN_INIT "clish_plugin_init"
 
+/* Symbol */
+
+int clish_sym_compare(const void *first, const void *second);
+clish_sym_t *clish_sym_new(const char *name, clish_plugin_fn_t *func);
+void clish_sym_free(clish_sym_t *instance);
+void clish_sym__set_func(clish_sym_t *instance, clish_plugin_fn_t *func);
+clish_plugin_fn_t *clish_sym__get_func(clish_sym_t *instance);
+
+/* Plugin */
+
 clish_plugin_t *clish_plugin_new(const char *name, const char *file);
 void clish_plugin_free(clish_plugin_t *instance);
 void *clish_plugin_load(clish_plugin_t *instance);

+ 16 - 4
clish/plugin/plugin.c

@@ -16,7 +16,7 @@
  **********************************************************/
 
 /*--------------------------------------------------------- */
-static int clish_sym_compare(const void *first, const void *second)
+int clish_sym_compare(const void *first, const void *second)
 {
 	const clish_sym_t *f = (const clish_sym_t *)first;
 	const clish_sym_t *s = (const clish_sym_t *)second;
@@ -25,7 +25,7 @@ static int clish_sym_compare(const void *first, const void *second)
 }
 
 /*--------------------------------------------------------- */
-static clish_sym_t *clish_sym_new(const char *name, clish_plugin_fn_t *func)
+clish_sym_t *clish_sym_new(const char *name, clish_plugin_fn_t *func)
 {
 	clish_sym_t *this;
 
@@ -37,7 +37,7 @@ static clish_sym_t *clish_sym_new(const char *name, clish_plugin_fn_t *func)
 }
 
 /*--------------------------------------------------------- */
-static void clish_sym_free(clish_sym_t *this)
+void clish_sym_free(clish_sym_t *this)
 {
 	if (!this)
 		return;
@@ -45,6 +45,18 @@ static void clish_sym_free(clish_sym_t *this)
 	free(this);
 }
 
+/*--------------------------------------------------------- */
+void clish_sym__set_func(clish_sym_t *this, clish_plugin_fn_t *func)
+{
+	this->func = func;
+}
+
+/*--------------------------------------------------------- */
+clish_plugin_fn_t *clish_sym__get_func(clish_sym_t *this)
+{
+	return this->func;
+}
+
 /**********************************************************
  * PLUGIN functions                                       *
  **********************************************************/
@@ -126,7 +138,7 @@ clish_plugin_fn_t *clish_plugin_get_sym(clish_plugin_t *this, const char *name)
 		sym = (clish_sym_t *)lub_list_node__get_data(iter);
 		res = strcmp(sym->name, name);
 		if (!res)
-			return sym->func;
+			return clish_sym__get_func(sym);
 		if (res > 0) /* No chances to find name */
 			break;
 	}

+ 9 - 5
clish/shell/private.h

@@ -41,17 +41,20 @@ 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 var_tree; /* Maintain a tree of global variables */
+	lub_bintree_t view_tree; /* Tree of views */
+	lub_bintree_t ptype_tree; /* Tree of ptypes */
+	lub_bintree_t var_tree; /* 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. */
 	clish_command_t *startup; /* This is the startup command */
 	unsigned int idle_timeout; /* This is the idle timeout */
-	clish_command_t *wdog; /* This is the watchdog command */
-	unsigned int wdog_timeout; /* This is the watchdog timeout */
+
+	/* Watchdog */
+	clish_command_t *wdog; /* Watchdog command */
+	unsigned int wdog_timeout; /* Watchdog timeout */
 	bool_t wdog_active; /* If watchdog is active now */
+
 	clish_shell_state_t state; /* The current state */
 	char *overview; /* Overview text for this shell */
 	tinyrl_t *tinyrl; /* Tiny readline instance */
@@ -67,6 +70,7 @@ struct clish_shell_s {
 	bool_t log; /* If command logging is enabled */
 	struct passwd *user; /* Current user information */
 	lub_list_t *plugins; /* List of plugins */
+	lub_list_t *syms; /* List of all used symbols. Must be resolved. */
 
 	/* Static params for var expanding. The refactoring is needed. */
 	clish_param_t *param_depth;

+ 13 - 0
clish/shell/shell_new.c

@@ -40,6 +40,9 @@ static void clish_shell_init(clish_shell_t * this,
 	/* Initialize plugin list */
 	this->plugins = lub_list_new(NULL);
 
+	/* Initialise the list of unresolved (yet) symbols */
+	this->syms = lub_list_new(clish_sym_compare);
+
 	assert((NULL != hooks) && (NULL != hooks->script_fn));
 
 	/* set up defaults */
@@ -133,6 +136,16 @@ static void clish_shell_fini(clish_shell_t * this)
 	}
 	lub_list_free(this->plugins);
 
+	/* Free symbol list */
+	while ((iter = lub_list__get_head(this->syms))) {
+		/* Remove the symbol from the list */
+		lub_list_del(this->syms, iter);
+		/* Free the instance */
+		clish_sym_free((clish_sym_t *)lub_list_node__get_data(iter));
+		lub_list_node_free(iter);
+	}
+	lub_list_free(this->syms);
+
 	/* free the textual details */
 	lub_string_free(this->overview);
 

+ 57 - 5
clish/shell/shell_plugin.c

@@ -3,13 +3,20 @@
  */
 #include "private.h"
 #include <assert.h>
+#include <string.h>
 
+#include "lub/string.h"
 #include "lub/list.h"
 #include "lub/bintree.h"
 #include "clish/plugin.h"
 #include "clish/view.h"
 
 /*----------------------------------------------------------------------- */
+/* For all plugins:
+ *  * dlopen(plugin)
+ *  * dlsym(initialize function)
+ *  * exec init functions to get all plugin syms
+ */
 int clish_shell_load_plugins(clish_shell_t *this)
 {
 	lub_list_node_t *iter;
@@ -35,21 +42,66 @@ int clish_shell_load_plugins(clish_shell_t *this)
 }
 
 /*----------------------------------------------------------------------- */
-static clish_plugin_fn_t *plugins_find_sym(clish_shell_t *this, const char *name)
+/* Find plugin by name. */
+static clish_plugin_t *plugin_by_name(clish_shell_t *this, const char *name)
 {
 	lub_list_node_t *iter;
 	clish_plugin_t *plugin;
-	clish_plugin_fn_t *func = NULL;
-	assert(this);
 
 	/* Iterate elements */
 	for(iter = lub_list__get_head(this->plugins);
 		iter; iter = lub_list_node__get_next(iter)) {
 		plugin = (clish_plugin_t *)lub_list_node__get_data(iter);
-		if ((func = clish_plugin_get_sym(plugin, name)))
-			break;
+		if (!strcmp(clish_plugin__get_name(plugin), name))
+			return plugin;
 	}
 
+	return NULL;
+}
+
+/*----------------------------------------------------------------------- */
+/* Iterate plugins to find symbol by name.
+ * The symbol name can be simple or with namespace:
+ * mysym@plugin1
+ * The symbols with prefix will be resolved using specified plugin only.
+ */
+static clish_plugin_fn_t *plugins_find_sym(clish_shell_t *this, const char *name)
+{
+	lub_list_node_t *iter;
+	clish_plugin_t *plugin;
+	clish_plugin_fn_t *func = NULL;
+	/* To parse command name */
+	char *saveptr;
+	const char *delim = "@";
+	char *plugin_name = NULL;
+	char *cmdn = NULL;
+	char *str = lub_string_dup(name);
+
+	assert(this);
+
+	/* Parse name to get sym name and optional plugin name */
+	cmdn = strtok_r(str, delim, &saveptr);
+	if (!cmdn)
+		goto end;
+	plugin_name = strtok_r(NULL, delim, &saveptr);
+
+	if (plugin_name) {
+		/* Search for symbol in specified plugin */
+		plugin = plugin_by_name(this, plugin_name);
+		if (!plugin)
+			goto end;
+		func = clish_plugin_get_sym(plugin, cmdn);
+	} else {
+		/* Iterate all plugins */
+		for(iter = lub_list__get_head(this->plugins);
+			iter; iter = lub_list_node__get_next(iter)) {
+			plugin = (clish_plugin_t *)lub_list_node__get_data(iter);
+			if ((func = clish_plugin_get_sym(plugin, cmdn)))
+				break;
+		}
+	}
+end:
+	lub_string_free(str);
 	return func;
 }