Explorar o código

Some PTYPE work

Serj Kalichev %!s(int64=6) %!d(string=hai) anos
pai
achega
bff04eda60

+ 0 - 1
clish/plugin/plugin.c

@@ -155,7 +155,6 @@ clish_sym_t *clish_plugin_add_phook(clish_plugin_t *this,
 		name, type, BOOL_TRUE);
 }
 
-
 /*--------------------------------------------------------- */
 clish_sym_t *clish_plugin_get_sym(clish_plugin_t *this, const char *name, int type)
 {

+ 25 - 38
clish/ptype.h

@@ -19,58 +19,45 @@ typedef struct clish_ptype_s clish_ptype_t;
 /* The means by which the pattern is interpreted and validated. */
 typedef enum {
 	/* [default] - A POSIX regular expression. */
-	CLISH_PTYPE_REGEXP,
+	CLISH_PTYPE_METHOD_REGEXP,
 	/* A numeric definition "min..max" signed and unsigned versions */
-	CLISH_PTYPE_INTEGER,
-	CLISH_PTYPE_UNSIGNEDINTEGER,
-	/**
-	* 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. 
+	CLISH_PTYPE_METHOD_INTEGER,
+	CLISH_PTYPE_METHOD_UNSIGNEDINTEGER,
+	/* 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.
 	*/
-	CLISH_PTYPE_SELECT,
+	CLISH_PTYPE_METHOD_SELECT,
 	/* User-defined code in ACTION */
-	CLISH_PTYPE_CODE,
+	CLISH_PTYPE_METHOD_CODE,
 	/* Used to detect errors */
-	CLISH_PTYPE_MAX
+	CLISH_PTYPE_METHOD_MAX
 
 } clish_ptype_method_e;
-/**
- * This defines the pre processing which is to be
- * performed before a string is validated.
- */
+
+/* This defines the pre processing which is to be performed before a string is validated. */
 typedef enum {
-    /**
-     * [default] - do nothing
-     */
-	CLISH_PTYPE_NONE,
-    /**
-     * before validation convert to uppercase.
-     */
-	CLISH_PTYPE_TOUPPER,
-    /**
-     * before validation convert to lowercase.
-     */
-	CLISH_PTYPE_TOLOWER
+	/* [default] - do nothing */
+	CLISH_PTYPE_PRE_NONE,
+	/* before validation convert to uppercase. */
+	CLISH_PTYPE_PRE_TOUPPER,
+	/* before validation convert to lowercase. */
+	CLISH_PTYPE_PRE_TOLOWER,
+	/* Used to detect errors */
+	CLISH_PTYPE_PRE_MAX
 } clish_ptype_preprocess_e;
 
-int clish_ptype_bt_compare(const void *clientnode, const void *clientkey);
-void clish_ptype_bt_getkey(const void *clientnode, lub_bintree_key_t * key);
-size_t clish_ptype_bt_offset(void);
-const char *clish_ptype_method__get_name(clish_ptype_method_e method);
+int clish_ptype_compare(const void *first, const void *second);
+const char *clish_ptype__get_method_name(clish_ptype_method_e method);
 clish_ptype_method_e clish_ptype_method_resolve(const char *method_name);
-const char *clish_ptype_preprocess__get_name(clish_ptype_preprocess_e
-	preprocess);
-clish_ptype_preprocess_e clish_ptype_preprocess_resolve(const char
-	*preprocess_name);
+const char *clish_ptype__get_preprocess_name(clish_ptype_preprocess_e preprocess);
+clish_ptype_preprocess_e clish_ptype_preprocess_resolve(const char *preprocess_name);
 clish_ptype_t *clish_ptype_new(const char *name, const char *text,
 	const char *pattern, clish_ptype_method_e method,
 	clish_ptype_preprocess_e preprocess);
 
-void clish_ptype_delete(clish_ptype_t * instance);
+void clish_ptype_free(clish_ptype_t *instance);
 /**
  * This is the validation method for the specified type.
  * \return

+ 0 - 1
clish/ptype/private.h

@@ -20,7 +20,6 @@ struct clish_ptype_select_s {
 };
 
 struct clish_ptype_s {
-	lub_bintree_node_t bt_node;
 	char *name;
 	char *text;
 	char *pattern;

+ 121 - 140
clish/ptype/ptype.c

@@ -13,9 +13,90 @@
 #include <limits.h>
 #include <stdio.h>
 
+/*--------------------------------------------------------- */
+int clish_ptype_compare(const void *first, const void *second)
+{
+	const clish_ptype_t *f = (const clish_ptype_t *)first;
+	const clish_ptype_t *s = (const clish_ptype_t *)second;
+
+	return strcmp(f->name, s->name);
+}
+
+/*--------------------------------------------------------- */
+static void clish_ptype_init(clish_ptype_t * this,
+	const char *name, const char *text, const char *pattern,
+	clish_ptype_method_e method, clish_ptype_preprocess_e preprocess)
+{
+	assert(this);
+	assert(name);
+	this->name = lub_string_dup(name);
+	this->text = NULL;
+	this->pattern = NULL;
+	this->preprocess = preprocess;
+	this->range = NULL;
+	this->action = clish_action_new();
+
+	if (pattern) {
+		/* set the pattern for this type */
+		clish_ptype__set_pattern(this, pattern, method);
+	} else {
+		/* The method is regexp by default */
+		this->method = CLISH_PTYPE_METHOD_REGEXP;
+	}
+	
+	/* set the help text for this type */
+	if (text)
+		clish_ptype__set_text(this, text);
+}
+
+/*--------------------------------------------------------- */
+static void clish_ptype_fini(clish_ptype_t * this)
+{
+	if (this->pattern) {
+		switch (this->method) {
+		case CLISH_PTYPE_METHOD_REGEXP:
+			regfree(&this->u.regexp);
+			break;
+		case CLISH_PTYPE_METHOD_INTEGER:
+		case CLISH_PTYPE_METHOD_UNSIGNEDINTEGER:
+			break;
+		case CLISH_PTYPE_METHOD_SELECT:
+			lub_argv_delete(this->u.select.items);
+			break;
+		default:
+			break;
+		}
+	}
+
+	lub_string_free(this->name);
+	lub_string_free(this->text);
+	lub_string_free(this->pattern);
+	lub_string_free(this->range);
+	clish_action_delete(this->action);
+}
+
+/*--------------------------------------------------------- */
+clish_ptype_t *clish_ptype_new(const char *name,
+	const char *help, const char *pattern,
+	clish_ptype_method_e method, clish_ptype_preprocess_e preprocess)
+{
+	clish_ptype_t *this = malloc(sizeof(clish_ptype_t));
+
+	if (this)
+		clish_ptype_init(this, name, help, pattern, method, preprocess);
+	return this;
+}
+
+/*--------------------------------------------------------- */
+void clish_ptype_free(clish_ptype_t *this)
+{
+	clish_ptype_fini(this);
+	free(this);
+}
+
 /*--------------------------------------------------------- */
 static char *clish_ptype_select__get_name(const clish_ptype_t * this,
-	unsigned index)
+	unsigned int index)
 {
 	char *result = NULL;
 	const char *arg = lub_argv__get_arg(this->u.select.items, index);
@@ -31,7 +112,7 @@ static char *clish_ptype_select__get_name(const clish_ptype_t * this,
 
 /*--------------------------------------------------------- */
 static char *clish_ptype_select__get_value(const clish_ptype_t * this,
-	unsigned index)
+	unsigned int index)
 {
 	char *result = NULL;
 	const char *arg = lub_argv__get_arg(this->u.select.items, index);
@@ -58,11 +139,11 @@ static void clish_ptype__set_range(clish_ptype_t * this)
 	/* Now set up the range values */
 	switch (this->method) {
 	/*------------------------------------------------- */
-	case CLISH_PTYPE_REGEXP:
+	case CLISH_PTYPE_METHOD_REGEXP:
 		/* Nothing more to do */
 		break;
 	/*------------------------------------------------- */
-	case CLISH_PTYPE_INTEGER:
+	case CLISH_PTYPE_METHOD_INTEGER:
 		/* Setup the integer range */
 		snprintf(tmp, sizeof(tmp), "%d..%d",
 			this->u.integer.min, this->u.integer.max);
@@ -70,7 +151,7 @@ static void clish_ptype__set_range(clish_ptype_t * this)
 		this->range = lub_string_dup(tmp);
 		break;
 	/*------------------------------------------------- */
-	case CLISH_PTYPE_UNSIGNEDINTEGER:
+	case CLISH_PTYPE_METHOD_UNSIGNEDINTEGER:
 		/* Setup the unsigned integer range */
 		snprintf(tmp, sizeof(tmp), "%u..%u",
 			(unsigned int)this->u.integer.min,
@@ -79,7 +160,7 @@ static void clish_ptype__set_range(clish_ptype_t * this)
 		this->range = lub_string_dup(tmp);
 		break;
 	/*------------------------------------------------- */
-	case CLISH_PTYPE_SELECT:
+	case CLISH_PTYPE_METHOD_SELECT:
 	{
 		/* Setup the selection values to the help text */
 		unsigned int i;
@@ -103,30 +184,6 @@ static void clish_ptype__set_range(clish_ptype_t * this)
 	}
 }
 
-/*--------------------------------------------------------- */
-int clish_ptype_bt_compare(const void *clientnode, const void *clientkey)
-{
-	const clish_ptype_t *this = clientnode;
-	const char *key = clientkey;
-
-	return strcmp(this->name, key);
-}
-
-/*-------------------------------------------------------- */
-void clish_ptype_bt_getkey(const void *clientnode, lub_bintree_key_t * key)
-{
-	const clish_ptype_t *this = clientnode;
-
-	/* fill out the opaque key */
-	strcpy((char *)key, this->name);
-}
-
-/*--------------------------------------------------------- */
-size_t clish_ptype_bt_offset(void)
-{
-	return offsetof(clish_ptype_t, bt_node);
-}
-
 /*--------------------------------------------------------- */
 static const char *method_names[] = {
 	"regexp",
@@ -137,24 +194,22 @@ static const char *method_names[] = {
 };
 
 /*--------------------------------------------------------- */
-const char *clish_ptype_method__get_name(clish_ptype_method_e method)
+const char *clish_ptype__get_method_name(clish_ptype_method_e method)
 {
-	unsigned int max_method = sizeof(method_names) / sizeof(char *);
-
-	if (method >= max_method)
+	if (method >= CLISH_PTYPE_METHOD_MAX)
 		return NULL;
 	return method_names[method];
 }
 
 /*--------------------------------------------------------- */
-/* Return value CLISH_PTYPE_MAX indicates an illegal method */
+/* Return value CLISH_PTYPE_METHOD_MAX indicates an illegal method */
 clish_ptype_method_e clish_ptype_method_resolve(const char *name)
 {
 	unsigned int i;
 
 	if (NULL == name)
-		return CLISH_PTYPE_REGEXP;
-	for (i = 0; i < CLISH_PTYPE_MAX; i++) {
+		return CLISH_PTYPE_METHOD_REGEXP;
+	for (i = 0; i < CLISH_PTYPE_METHOD_MAX; i++) {
 		if (!strcmp(name, method_names[i]))
 			break;
 	}
@@ -170,28 +225,27 @@ static const char *preprocess_names[] = {
 };
 
 /*--------------------------------------------------------- */
-const char *clish_ptype_preprocess__get_name(
-	clish_ptype_preprocess_e preprocess)
+const char *clish_ptype__get_preprocess_name(clish_ptype_preprocess_e preprocess)
 {
+	if (preprocess >= CLISH_PTYPE_PRE_MAX)
+		return NULL;
+
 	return preprocess_names[preprocess];
 }
 
 /*--------------------------------------------------------- */
 clish_ptype_preprocess_e clish_ptype_preprocess_resolve(const char *name)
 {
-	clish_ptype_preprocess_e result = CLISH_PTYPE_NONE;
-	if (name) {
-		unsigned i;
-		for (i = 0; i < CLISH_PTYPE_TOLOWER + 1; i++) {
-			if (0 == strcmp(name, preprocess_names[i])) {
-				result = (clish_ptype_preprocess_e) i;
-				break;
-			}
-		}
-		/* error for incorrect type spec */
-		assert((clish_ptype_preprocess_e) i <= CLISH_PTYPE_TOLOWER);
+	unsigned int i;
+
+	if (NULL == name)
+		return CLISH_PTYPE_PRE_NONE;
+	for (i = 0; i < CLISH_PTYPE_PRE_MAX; i++) {
+		if (!strcmp(name, preprocess_names[i]))
+			break;
 	}
-	return result;
+
+	return (clish_ptype_preprocess_e)i;
 }
 
 /*--------------------------------------------------------- */
@@ -202,7 +256,7 @@ void clish_ptype_word_generator(clish_ptype_t * this,
 	unsigned i = 0;
 
 	/* Another ptypes has no completions */
-	if (this->method != CLISH_PTYPE_SELECT)
+	if (this->method != CLISH_PTYPE_METHOD_SELECT)
 		return;
 
 	/* First of all simply try to validate the result */
@@ -231,10 +285,10 @@ static char *clish_ptype_validate_or_translate(const clish_ptype_t * this,
 
 	switch (this->preprocess) {
 	/*----------------------------------------- */
-	case CLISH_PTYPE_NONE:
+	case CLISH_PTYPE_PRE_NONE:
 		break;
 	/*----------------------------------------- */
-	case CLISH_PTYPE_TOUPPER:
+	case CLISH_PTYPE_PRE_TOUPPER:
 	{
 		char *p = result;
 		while (*p) {
@@ -248,7 +302,7 @@ static char *clish_ptype_validate_or_translate(const clish_ptype_t * this,
 		break;
 	}
 	/*----------------------------------------- */
-	case CLISH_PTYPE_TOLOWER:
+	case CLISH_PTYPE_PRE_TOLOWER:
 	{
 		char *p = result;
 		while (*p) {
@@ -258,13 +312,15 @@ static char *clish_ptype_validate_or_translate(const clish_ptype_t * this,
 		break;
 	}
 	/*----------------------------------------- */
+	default:
+		break;
 	}
 	/*
 	 * now validate according the specified method 
 	 */
 	switch (this->method) {
 	/*------------------------------------------------- */
-	case CLISH_PTYPE_REGEXP:
+	case CLISH_PTYPE_METHOD_REGEXP:
 		/* test the regular expression against the string */
 		/*lint -e64 Type mismatch (arg. no. 4) */
 		/*
@@ -277,7 +333,7 @@ static char *clish_ptype_validate_or_translate(const clish_ptype_t * this,
 		/*lint +e64 */
 		break;
 	/*------------------------------------------------- */
-	case CLISH_PTYPE_INTEGER:
+	case CLISH_PTYPE_METHOD_INTEGER:
 	{
 		/* first of all check that this is a number */
 		bool_t ok = BOOL_TRUE;
@@ -307,7 +363,7 @@ static char *clish_ptype_validate_or_translate(const clish_ptype_t * this,
 		break;
 	}
 	/*------------------------------------------------- */
-	case CLISH_PTYPE_UNSIGNEDINTEGER:
+	case CLISH_PTYPE_METHOD_UNSIGNEDINTEGER:
 	{
 		/* first of all check that this is a number */
 		bool_t ok = BOOL_TRUE;
@@ -334,7 +390,7 @@ static char *clish_ptype_validate_or_translate(const clish_ptype_t * this,
 		break;
 	}
 	/*------------------------------------------------- */
-	case CLISH_PTYPE_SELECT:
+	case CLISH_PTYPE_METHOD_SELECT:
 	{
 		unsigned i;
 		for (i = 0; i < lub_argv__get_count(this->u.select.items);
@@ -362,38 +418,12 @@ static char *clish_ptype_validate_or_translate(const clish_ptype_t * this,
 		break;
 	}
 	/*------------------------------------------------- */
+	default:
+		break;
 	}
 	return (char *)result;
 }
 
-/*--------------------------------------------------------- */
-static void clish_ptype_init(clish_ptype_t * this,
-	const char *name, const char *text, const char *pattern,
-	clish_ptype_method_e method, clish_ptype_preprocess_e preprocess)
-{
-	assert(name);
-	this->name = lub_string_dup(name);
-	this->text = NULL;
-	this->pattern = NULL;
-	this->preprocess = preprocess;
-	this->range = NULL;
-	this->action = clish_action_new();
-
-	/* Be a good binary tree citizen */
-	lub_bintree_node_init(&this->bt_node);
-
-	if (pattern) {
-		/* set the pattern for this type */
-		clish_ptype__set_pattern(this, pattern, method);
-	} else {
-		/* The method is regexp by default */
-		this->method = CLISH_PTYPE_REGEXP;
-	}
-	
-	/* set the help text for this type */
-	if (text)
-		clish_ptype__set_text(this, text);
-}
 
 /*--------------------------------------------------------- */
 char *clish_ptype_validate(const clish_ptype_t * this, const char *text)
@@ -407,55 +437,6 @@ char *clish_ptype_translate(const clish_ptype_t * this, const char *text)
 	return clish_ptype_validate_or_translate(this, text, BOOL_TRUE);
 }
 
-/*--------------------------------------------------------- */
-clish_ptype_t *clish_ptype_new(const char *name,
-	const char *help, const char *pattern,
-	clish_ptype_method_e method, clish_ptype_preprocess_e preprocess)
-{
-	clish_ptype_t *this = malloc(sizeof(clish_ptype_t));
-
-	if (this)
-		clish_ptype_init(this, name, help, pattern, method, preprocess);
-	return this;
-}
-
-/*--------------------------------------------------------- */
-static void clish_ptype_fini(clish_ptype_t * this)
-{
-	if (this->pattern) {
-		switch (this->method) {
-		case CLISH_PTYPE_REGEXP:
-			regfree(&this->u.regexp);
-			break;
-		case CLISH_PTYPE_INTEGER:
-		case CLISH_PTYPE_UNSIGNEDINTEGER:
-			break;
-		case CLISH_PTYPE_SELECT:
-			lub_argv_delete(this->u.select.items);
-			break;
-		default:
-			break;
-		}
-	}
-
-	lub_string_free(this->name);
-	this->name = NULL;
-	lub_string_free(this->text);
-	this->text = NULL;
-	lub_string_free(this->pattern);
-	this->pattern = NULL;
-	lub_string_free(this->range);
-	this->range = NULL;
-	clish_action_delete(this->action);
-}
-
-/*--------------------------------------------------------- */
-void clish_ptype_delete(clish_ptype_t * this)
-{
-	clish_ptype_fini(this);
-	free(this);
-}
-
 CLISH_GET_STR(ptype, name);
 CLISH_SET_STR_ONCE(ptype, text);
 CLISH_GET_STR(ptype, text);
@@ -472,7 +453,7 @@ void clish_ptype__set_pattern(clish_ptype_t * this,
 
 	switch (this->method) {
 	/*------------------------------------------------- */
-	case CLISH_PTYPE_REGEXP:
+	case CLISH_PTYPE_METHOD_REGEXP:
 	{
 		int result;
 
@@ -488,7 +469,7 @@ void clish_ptype__set_pattern(clish_ptype_t * this,
 		break;
 	}
 	/*------------------------------------------------- */
-	case CLISH_PTYPE_INTEGER:
+	case CLISH_PTYPE_METHOD_INTEGER:
 		/* default the range to that of an integer */
 		this->u.integer.min = INT_MIN;
 		this->u.integer.max = INT_MAX;
@@ -498,7 +479,7 @@ void clish_ptype__set_pattern(clish_ptype_t * this,
 			&this->u.integer.min, &this->u.integer.max);
 		break;
 	/*------------------------------------------------- */
-	case CLISH_PTYPE_UNSIGNEDINTEGER:
+	case CLISH_PTYPE_METHOD_UNSIGNEDINTEGER:
 		/* default the range to that of an unsigned integer */
 		this->u.integer.min = 0;
 		this->u.integer.max = (int)UINT_MAX;
@@ -509,7 +490,7 @@ void clish_ptype__set_pattern(clish_ptype_t * this,
 			(unsigned int *)&this->u.integer.max);
 		break;
 	/*------------------------------------------------- */
-	case CLISH_PTYPE_SELECT:
+	case CLISH_PTYPE_METHOD_SELECT:
 		this->pattern = lub_string_dup(pattern);
 		/* store a vector of item descriptors */
 		this->u.select.items = lub_argv_new(this->pattern, 0);

+ 1 - 1
clish/ptype/ptype_dump.c

@@ -15,7 +15,7 @@ void clish_ptype_dump(clish_ptype_t * this)
 	lub_dump_printf("text       : %s\n", LUB_DUMP_STR(clish_ptype__get_text(this)));
 	lub_dump_printf("pattern    : %s\n", LUB_DUMP_STR(this->pattern));
 	lub_dump_printf("method     : %s\n",
-		clish_ptype_method__get_name(this->method));
+		clish_ptype__get_method_name(this->method));
 	lub_dump_printf("postprocess: %s\n",
 		clish_ptype_preprocess__get_name(this->preprocess));
 	lub_dump_undent();

+ 2 - 11
clish/shell/private.h

@@ -11,15 +11,7 @@
 #include "clish/plugin.h"
 #include "clish/udata.h"
 
-/*-------------------------------------
- * PRIVATE TYPES
- *------------------------------------- */
-
-/*-------------------------------------------------------- */
-
-/*
- * iterate around commands
- */
+/* iterate around commands */
 typedef struct {
 	const char *last_cmd;
 	clish_nspace_visibility_e field;
@@ -55,7 +47,7 @@ struct clish_context_s {
 /* Shell structure */
 struct clish_shell_s {
 	lub_bintree_t view_tree; /* Tree of views */
-	lub_bintree_t ptype_tree; /* Tree of ptypes */
+	lub_list_t *ptype_tree; /* PTYPE list */
 	lub_bintree_t var_tree; /* Tree of global variables */
 
 	/* Hooks */
@@ -139,7 +131,6 @@ const clish_command_t *clish_shell_resolve_command(const clish_shell_t *
 	instance, const char *line);
 const clish_command_t *clish_shell_resolve_prefix(const clish_shell_t *
 	instance, const char *line);
-void clish_shell_insert_ptype(clish_shell_t * instance, clish_ptype_t * ptype);
 void clish_shell_tinyrl_history(clish_shell_t * instance, unsigned int *limit);
 tinyrl_t *clish_shell_tinyrl_new(FILE * instream,
 	FILE * outstream, unsigned stifle);

+ 10 - 11
clish/shell/shell_new.c

@@ -28,10 +28,8 @@ static void clish_shell_init(clish_shell_t * this,
 		clish_view_bt_offset(),
 		clish_view_bt_compare, clish_view_bt_getkey);
 
-	/* initialise the tree of ptypes */
-	lub_bintree_init(&this->ptype_tree,
-		clish_ptype_bt_offset(),
-		clish_ptype_bt_compare, clish_ptype_bt_getkey);
+	/* Init PTYPE list */
+	this->ptype_tree = lub_list_new(clish_ptype_compare);
 
 	/* initialise the tree of vars */
 	lub_bintree_init(&this->var_tree,
@@ -90,8 +88,8 @@ static void clish_shell_init(clish_shell_t * this,
 	tmp_ptype = clish_shell_find_create_ptype(this,
 		"__ptype_ARGS",
 		"Arguments", "[^\\\\]+",
-		CLISH_PTYPE_REGEXP,
-		CLISH_PTYPE_NONE);
+		CLISH_PTYPE_METHOD_REGEXP,
+		CLISH_PTYPE_PRE_NONE);
 	assert(tmp_ptype);
 
 	/* Push non-NULL istream */
@@ -103,7 +101,6 @@ static void clish_shell_init(clish_shell_t * this,
 static void clish_shell_fini(clish_shell_t *this)
 {
 	clish_view_t *view;
-	clish_ptype_t *ptype;
 	clish_var_t *var;
 	unsigned i;
 	lub_list_node_t *iter;
@@ -125,11 +122,13 @@ static void clish_shell_fini(clish_shell_t *this)
 		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 PTYPE  */
+	while ((iter = lub_list__get_head(this->ptype_tree))) {
+		lub_list_del(this->ptype_tree, iter);
+		clish_ptype_free((clish_ptype_t *)lub_list_node__get_data(iter));
+		lub_list_node_free(iter);
 	}
+	lub_list_free(this->ptype_tree);
 
 	/* delete each VAR held  */
 	while ((var = lub_bintree_findfirst(&this->var_tree))) {

+ 23 - 13
clish/shell/shell_ptype.c

@@ -2,15 +2,33 @@
  * shell_find_create_ptype.c
  */
 
+#include <string.h>
 #include <assert.h>
 
 #include "private.h"
 
 /*--------------------------------------------------------- */
-clish_ptype_t *clish_shell_find_ptype(clish_shell_t *this,
-	const char *name)
+clish_ptype_t *clish_shell_find_ptype(clish_shell_t *this, const char *name)
 {
-	return lub_bintree_find(&this->ptype_tree, name);
+	lub_list_node_t *iter;
+
+	assert(this);
+
+	if (!name || !name[0])
+		return NULL;
+	/* Iterate elements */
+	for(iter = lub_list__get_head(this->ptype_tree);
+		iter; iter = lub_list_node__get_next(iter)) {
+		int r;
+		clish_ptype_t *ptype = (clish_ptype_t *)lub_list_node__get_data(iter);
+		r = strcmp(name, clish_ptype__get_name(ptype));
+		if (!r)
+			return ptype;
+		if (r > 0)
+			break;
+	}
+
+	return NULL;
 }
 
 /*--------------------------------------------------------- */
@@ -18,14 +36,14 @@ clish_ptype_t *clish_shell_find_create_ptype(clish_shell_t * this,
 	const char *name, const char *text, const char *pattern,
 	clish_ptype_method_e method, clish_ptype_preprocess_e preprocess)
 {
-	clish_ptype_t *ptype = lub_bintree_find(&this->ptype_tree, name);
+	clish_ptype_t *ptype = clish_shell_find_ptype(this, name);
 
 	if (!ptype) {
 		/* create a ptype */
 		ptype = clish_ptype_new(name, text, pattern,
 			method, preprocess);
 		assert(ptype);
-		clish_shell_insert_ptype(this, ptype);
+		lub_list_add(this->ptype_tree, ptype);
 	} else {
 		if (pattern) {
 			/* set the pattern */
@@ -40,11 +58,3 @@ clish_ptype_t *clish_shell_find_create_ptype(clish_shell_t * this,
 
 	return ptype;
 }
-
-/*--------------------------------------------------------- */
-void clish_shell_insert_ptype(clish_shell_t * this, clish_ptype_t * ptype)
-{
-	(void)lub_bintree_insert(&this->ptype_tree, ptype);
-}
-
-/*--------------------------------------------------------- */

+ 5 - 8
clish/shell/shell_xml.c

@@ -388,11 +388,11 @@ static int process_ptype(clish_shell_t *shell, clish_xmlnode_t *element,
 	}
 
 	method = clish_ptype_method_resolve(method_name);
-	if (CLISH_PTYPE_MAX == method) {
+	if (CLISH_PTYPE_METHOD_MAX == method) {
 		fprintf(stderr, CLISH_XML_ERROR_ATTR("method"));
 		goto error;
 	}
-	if ((method != CLISH_PTYPE_CODE) && !pattern) {
+	if ((method != CLISH_PTYPE_METHOD_CODE) && !pattern) {
 		fprintf(stderr, CLISH_XML_ERROR_ATTR("pattern"));
 		goto error;
 	}
@@ -756,12 +756,9 @@ static int process_param(clish_shell_t *shell, clish_xmlnode_t *element,
 		 * name of ptype is hardcoded. It's not good but
 		 * it's only the service ptype.
 		 */
-		tmp = (clish_ptype_t *)lub_bintree_find(
-			&shell->ptype_tree, ptype_name);
-		if (!tmp)
-			tmp = clish_shell_find_create_ptype(shell,
-				ptype_name, "Option", "[^\\\\]+",
-				CLISH_PTYPE_REGEXP, CLISH_PTYPE_NONE);
+		tmp = clish_shell_find_create_ptype(shell,
+			ptype_name, "Option", "[^\\\\]+",
+			CLISH_PTYPE_METHOD_REGEXP, CLISH_PTYPE_PRE_NONE);
 		assert(tmp);
 		lub_string_cat(&str, "_prefix_");
 		lub_string_cat(&str, name);

+ 2 - 1
lub/list.h

@@ -27,7 +27,8 @@ lub_list_node_t *lub_list_iterator_next(lub_list_node_t *node);
 lub_list_node_t *lub_list_iterator_prev(lub_list_node_t *node);
 lub_list_node_t *lub_list_add(lub_list_t *list, void *data);
 void lub_list_del(lub_list_t *list, lub_list_node_t *node);
-lub_list_node_t *lub_list_search(lub_list_t *list, void *data);
+lub_list_node_t *lub_list_search_node(lub_list_t *list, void *data);
+void *lub_list_search(lub_list_t *list, void *data);
 unsigned int lub_list_len(lub_list_t *list);
 
 _END_C_DECL

+ 14 - 2
lub/list/list.c

@@ -178,9 +178,10 @@ inline void lub_list_node_copy(lub_list_node_t *dst, lub_list_node_t *src)
 }
 
 /*--------------------------------------------------------- */
-lub_list_node_t *lub_list_search(lub_list_t *this, void *data)
+lub_list_node_t *lub_list_search_node(lub_list_t *this, void *data)
 {
 	lub_list_node_t *iter;
+	int res;
 
 	/* Empty list */
 	if (!this->head)
@@ -192,14 +193,25 @@ lub_list_node_t *lub_list_search(lub_list_t *this, void *data)
 	/* Sorted list */
 	iter = this->head;
 	while (iter) {
-		if (!this->compareFn(data, iter->data))
+		res = this->compareFn(data, iter->data);
+		if (!res)
 			return iter;
+		if (res > 0)
+			break; // No chances to find it
 		iter = iter->next;
 	}
 
 	return NULL;
 }
 
+/*--------------------------------------------------------- */
+void *lub_list_search(lub_list_t *this, void *data)
+{
+	lub_list_node_t *iter = lub_list_search_node(this, data);
+
+	return iter->data;
+}
+
 /*--------------------------------------------------------- */
 inline unsigned int lub_list_len(lub_list_t *this)
 {