Browse Source

udata container to store plugin named data

Serj Kalichev 11 years ago
parent
commit
1db916faa1

+ 4 - 1
clish/module.am

@@ -28,7 +28,8 @@ nobase_include_HEADERS += \
 	clish/action.h \
 	clish/config.h \
 	clish/hotkey.h \
-	clish/plugin.h
+	clish/plugin.h \
+	clish/udata.h
 
 EXTRA_DIST += \
 	clish/command/module.am \
@@ -44,6 +45,7 @@ EXTRA_DIST += \
 	clish/hotkey/module.am \
 	clish/plugin/module.am \
 	clish/builtin/module.am \
+	clish/udata/module.am	\
 	clish/README
 
 include $(top_srcdir)/clish/command/module.am
@@ -59,3 +61,4 @@ include $(top_srcdir)/clish/config/module.am
 include $(top_srcdir)/clish/hotkey/module.am
 include $(top_srcdir)/clish/plugin/module.am
 include $(top_srcdir)/clish/builtin/module.am
+include $(top_srcdir)/clish/udata/module.am

+ 6 - 0
clish/shell.h

@@ -190,6 +190,12 @@ CLISH_HOOK_ACCESS(clish_shell_exec_access);
 CLISH_HOOK_CONFIG(clish_shell_exec_config);
 CLISH_HOOK_LOG(clish_shell_exec_log);
 
+/* User data functions */
+void *clish_shell__get_udata(const clish_shell_t *instance, const char *name);
+void *clish_shell__del_udata(clish_shell_t *instance, const char *name);
+int clish_shell__set_udata(clish_shell_t *instance,
+	const char *name, void *data);
+
 _END_C_DECL
 
 #endif				/* _clish_shell_h */

+ 2 - 1
clish/shell/module.am

@@ -20,5 +20,6 @@ libclish_la_SOURCES += \
 	clish/shell/xmlapi.h \
 	clish/shell/shell_roxml.c \
 	clish/shell/shell_libxml2.c \
-	clish/shell/shell_expat.c
+	clish/shell/shell_expat.c \
+	clish/shell/shell_udata.c
 

+ 4 - 0
clish/shell/private.h

@@ -9,6 +9,7 @@
 #include "clish/var.h"
 #include "clish/action.h"
 #include "clish/plugin.h"
+#include "clish/udata.h"
 
 /*-------------------------------------
  * PRIVATE TYPES
@@ -89,6 +90,9 @@ struct clish_shell_s {
 	/* Static params for var expanding. The refactoring is needed. */
 	clish_param_t *param_depth;
 	clish_param_t *param_pwd;
+
+	/* Userdata list holder */
+	lub_list_t *udata;
 };
 
 /**

+ 14 - 0
clish/shell/shell_new.c

@@ -46,6 +46,10 @@ static void clish_shell_init(clish_shell_t * this,
 	/* Initialise the list of unresolved (yet) symbols */
 	this->syms = lub_list_new(clish_sym_compare);
 
+	/* Create userdata storage */
+	this->udata = lub_list_new(clish_udata_compare);
+	assert(this->udata);
+
 	/* Default syms and hooks */
 	this->hooks[CLISH_SYM_TYPE_NONE] = NULL;
 	this->hooks[CLISH_SYM_TYPE_ACTION] = clish_sym_new(
@@ -160,6 +164,16 @@ static void clish_shell_fini(clish_shell_t * this)
 	}
 	lub_list_free(this->syms);
 
+	/* Free user data storage */
+	while ((iter = lub_list__get_head(this->udata))) {
+		/* Remove the symbol from the list */
+		lub_list_del(this->udata, iter);
+		/* Free the instance */
+		clish_udata_free((clish_udata_t *)lub_list_node__get_data(iter));
+		lub_list_node_free(iter);
+	}
+	lub_list_free(this->udata);
+
 	/* free the textual details */
 	lub_string_free(this->overview);
 

+ 95 - 0
clish/shell/shell_udata.c

@@ -0,0 +1,95 @@
+/*
+ * shell_udata.c
+ */
+#include <assert.h>
+#include <string.h>
+
+#include "private.h"
+#include "clish/udata.h"
+
+/*-------------------------------------------------------- */
+static lub_list_node_t *find_udata_node(const clish_shell_t *this, const char *name)
+{
+	lub_list_node_t *iter;
+	clish_udata_t *udata;
+
+	assert(this);
+	if (!name)
+		return NULL;
+
+	for(iter = lub_list__get_head(this->udata);
+		iter; iter = lub_list_node__get_next(iter)) {
+		int res;
+		udata = (clish_udata_t *)lub_list_node__get_data(iter);
+		res = strcmp(clish_udata__get_name(udata), name);
+		if (!res)
+			return iter;
+		if (res > 0) /* No chance to find name */
+			break;
+	}
+
+	return NULL;
+}
+
+/*-------------------------------------------------------- */
+static clish_udata_t *find_udata(const clish_shell_t *this, const char *name)
+{
+	lub_list_node_t *iter;
+
+	if (!(iter = find_udata_node(this, name)))
+		return NULL;
+	return (clish_udata_t *)lub_list_node__get_data(iter);
+}
+
+/*-------------------------------------------------------- */
+void *clish_shell__get_udata(const clish_shell_t *this, const char *name)
+{
+	clish_udata_t *udata;
+	assert (this);
+
+	udata = find_udata(this, name);
+	return clish_udata__get_data(udata);
+}
+
+/*-------------------------------------------------------- */
+void *clish_shell__del_udata(clish_shell_t *this, const char *name)
+{
+	lub_list_node_t *node = NULL;
+	clish_udata_t *pdata = NULL;
+
+	if (!this || !name)
+		return NULL;
+
+	if(!(node = find_udata_node(this, name)))
+		return NULL;
+
+	pdata = (clish_udata_t *)lub_list_node__get_data(node);
+	lub_list_del(this->udata, node);
+	lub_list_node_free(node);
+
+	return clish_udata_free(pdata);
+}
+
+/*-------------------------------------------------------- */
+int clish_shell__set_udata(clish_shell_t *this,
+	const char *name, void *data)
+{
+	clish_udata_t *pdata = NULL;
+
+	if (!this || !name)
+		return -1;
+
+	if ((pdata = find_udata(this, name))) {
+		clish_udata__set_data(pdata, data);
+		return 0;
+	}
+
+	if (!(pdata = clish_udata_new(name, data)))
+		return -1;
+	if (lub_list_add(this->udata, pdata))
+		return 0;
+
+	clish_udata_free(pdata);
+	return -1;
+}
+/*-------------------------------------------------------- */

+ 27 - 0
clish/udata.h

@@ -0,0 +1,27 @@
+/*
+ * udata.h
+ */
+ /**
+\ingroup clish
+\defgroup clish_udata udata
+@{
+
+\brief This class represents the top level container for CLI user data.
+*/
+#ifndef _clish_udata_h
+#define _clish_udata_h
+
+typedef struct clish_udata_s clish_udata_t;
+
+/*=================================
+ * USERDATA INTERFACE
+ *================================= */
+int clish_udata_compare(const void *first, const void *second);
+clish_udata_t *clish_udata_new(const char *name, void *data);
+void *clish_udata_free(clish_udata_t *instance);
+void *clish_udata__get_data(const clish_udata_t *instance);
+int clish_udata__set_data(clish_udata_t *instance, void *data);
+char *clish_udata__get_name(const clish_udata_t *instance);
+
+#endif				/* _clish_udata_h */
+/** @} clish_udata */

+ 3 - 0
clish/udata/module.am

@@ -0,0 +1,3 @@
+libclish_la_SOURCES += \
+	clish/udata/udata.c \
+	clish/udata/private.h

+ 10 - 0
clish/udata/private.h

@@ -0,0 +1,10 @@
+/*
+ * udata.h - private interface to the userdata class
+ */
+
+#include "clish/udata.h"
+
+struct clish_udata_s {
+	char *name;
+	void *data;
+};

+ 81 - 0
clish/udata/udata.c

@@ -0,0 +1,81 @@
+/*
+ * udata.c
+ */
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "lub/list.h"
+#include "lub/string.h"
+
+#include "private.h"
+
+/*--------------------------------------------------------- */
+int clish_udata_compare(const void *first, const void *second)
+{
+	const clish_udata_t *f = (const clish_udata_t *)first;
+	const clish_udata_t *s = (const clish_udata_t *)second;
+
+	return strcmp(f->name, s->name);
+}
+
+/*--------------------------------------------------------- */
+clish_udata_t *clish_udata_new(const char *name, void *data)
+{
+	clish_udata_t *pdata =
+		(clish_udata_t *)malloc(sizeof(clish_udata_t));
+
+	if (!name) {
+		free(pdata);
+		return NULL;
+	}
+	memset(pdata, 0, sizeof(*pdata));
+	pdata->name = lub_string_dup(name);
+	pdata->data = data;
+
+	return pdata;
+}
+
+/*--------------------------------------------------------- */
+void *clish_udata_free(clish_udata_t *this)
+{
+	void *data;
+
+	if (!this)
+		return NULL;
+	if (this->name)
+		lub_string_free(this->name);
+	data = this->data;
+	free(this);
+
+	return data;
+}
+
+/*--------------------------------------------------------- */
+void *clish_udata__get_data(const clish_udata_t *this)
+{
+	if (!this)
+		return NULL;
+	return this->data;
+}
+
+/*--------------------------------------------------------- */
+int clish_udata__set_data(clish_udata_t *this, void *data)
+{
+	if (!this)
+		return -1;
+	this->data = data;
+	return 0;
+}
+
+/*--------------------------------------------------------- */
+char *clish_udata__get_name(const clish_udata_t *this)
+{
+	if (!this)
+		return NULL;
+	return this->name;
+}
+
+
+/*--------------------------------------------------------- */