[ekg2-commit] r3854 - in trunk: ekg plugins/gtk plugins/irc plugins/ncurses plugins/readline: trunk/ekg/commands.c trunk/ekg/commands.h trunk/ekg/dynstuff.c trunk/ekg/dynstuff.h trunk/ekg/plugins.c trunk/ekg/plugins.h trunk/ekg/stuff.c trunk/plugins/gtk/completion.c trunk/plugins/irc/irc.c trunk/plugins/ncurses/completion.c trunk/plugins/readline/readline-completion.c

SVN commit svn w toxygen.net
Sob, 8 Mar 2008, 12:20:35 CET


Author: peres
Date: 2008-03-08 12:20:34 +0100 (Sat, 08 Mar 2008)
New Revision: 3854

Modified:
   trunk/ekg/commands.c
   trunk/ekg/commands.h
   trunk/ekg/dynstuff.c
   trunk/ekg/dynstuff.h
   trunk/ekg/plugins.c
   trunk/ekg/plugins.h
   trunk/ekg/stuff.c
   trunk/plugins/gtk/completion.c
   trunk/plugins/irc/irc.c
   trunk/plugins/ncurses/completion.c
   trunk/plugins/readline/readline-completion.c
Log:

/* WARNING: experimental commit */

First try of replacing list_t:
- new list*3() functions, working like normal ones, but returning/using whole
  struct pointer instead of ->data,
- moved 'next' to the beginning of list_t and added one in the beginning
  of command_t,
- changed 'commands' and 'commands_lock' globals to new command_t* lists
  instead of list_t.



Modified: trunk/ekg/commands.c
===================================================================
--- trunk/ekg/commands.c	2008-03-07 18:41:00 UTC (rev 3853)
+++ trunk/ekg/commands.c	2008-03-08 11:20:34 UTC (rev 3854)
@@ -108,8 +108,8 @@
 int send_nicks_count = 0, send_nicks_index = 0;
 static int quit_command = 0;
 
-list_t commands = NULL;
-list_t *commands_lock = NULL;
+command_t *commands = NULL;
+command_t **commands_lock = NULL;
 
 /*
  * match_arg()
@@ -211,13 +211,11 @@
  */
 command_t *command_find(const char *name)
 {
-        list_t l;
+        command_t *c;
 
         if (!name)
                 return NULL;
-        for (l = commands; l; l = l->next) {
-                command_t *c = l->data;
-
+        for (c = commands; c; c = c->next) {
                 if (!xstrcasecmp(c->name, name)) {
                         return c;
 		}
@@ -1009,7 +1007,7 @@
 
 static COMMAND(cmd_help)
 {
-	list_t l;
+	command_t *c;
 	if (params[0]) {
 		const char *p = (params[0][0] == '/' && xstrlen(params[0]) > 1) ? params[0] + 1 : params[0];
 		int plen;
@@ -1032,9 +1030,7 @@
 		} else
 			plen = 0;
 	
-		for (l = commands; l; l = l->next) {
-			command_t *c = l->data;
-			
+		for (c = commands; c; c = c->next) {
 			if (!xstrcasecmp(c->name, p) && (c->flags & COMMAND_ISALIAS)) {
 				printq("help_alias", p);
 				return -1;
@@ -1153,9 +1149,7 @@
 		}
 	}
 
-	for (l = commands; l; l = l->next) {
-		command_t *c = l->data;
-
+	for (c = commands; c; c = c->next) {
 		if (xisalnum(*c->name) && !(c->flags & COMMAND_ISALIAS)) {
 		    	char *blah = NULL;
                         FILE *f;
@@ -2523,7 +2517,7 @@
 
 	int exact = 0;
 
-	list_t l;
+	command_t *c;
 
 	if (!xline)
 		return 0;
@@ -2534,8 +2528,7 @@
 	
 		/* wykrywanie przypadkowo wpisanych poleceń */
 		if (config_query_commands) {
-			for (l = commands; l; l = l->next) {
-				command_t *c = l->data;
+			for (c = commands; c; c = c->next) {
 				size_t l = xstrlen(c->name);
 
 				if (l < 3 || xstrncasecmp(xline, c->name, l))
@@ -2573,9 +2566,7 @@
 		line++;
 	}
 
-	for (l = commands; l; l = l->next) {
-		command_t *c = l->data;
-
+	for (c = commands; c; c = c->next) {
 		if (!isalpha_pl_PL(c->name[0]) && xstrlen(c->name) == 1 && line[0] == c->name[0]) {
 			short_cmd[0] = c->name[0];
 			cmd = short_cmd;
@@ -2599,9 +2590,7 @@
 	if (session && session->uid) {
 		int plen = (int)(xstrchr(session->uid, ':') - session->uid) + 1;
 		
-		for (l = commands; l; l = l->next) {
-			command_t *c = l->data;
-
+		for (c = commands; c; c = c->next) {
 			if (xstrncasecmp(c->name, session->uid, plen))
 				continue;
 		
@@ -2622,9 +2611,7 @@
 		}
 	}
 	if (!exact) {
-		for (l = commands; l; l = l->next) {
-			command_t *c = l->data;
-
+		for (c = commands; c; c = c->next) {
 			if (!xstrcasecmp(c->name, cmd)) {
 				last_command = c;
 				abbrs = 1;
@@ -4185,18 +4172,17 @@
 	if (commands_lock) {				/* if we lock commands */
 		if (*commands_lock == commands) {	/* if lock_command points to commands */
 			/* then we need to find place where to add it.. */
-			for (; *commands_lock && (command_add_compare((*commands_lock)->data, c) < 0); commands_lock = &((*commands_lock)->next));
+			for (; *commands_lock && (command_add_compare(*commands_lock, c) < 0); commands_lock = &((*commands_lock)->next));
 		} else		commands_lock = &((*commands_lock)->next);	/* otherwise if we have list... move to next */
-		list_add_beginning(commands_lock, c);		/* add to commands */
+		LIST_ADD_BEGINNING2(commands_lock, c);		/* add to commands */
 		return c;
 	}
-	return LIST_ADD_SORTED(&commands, c, command_add_compare);
+	return LIST_ADD_SORTED2(&commands, c, command_add_compare);
 }
 
 static LIST_FREE_ITEM(list_command_free, command_t *) {
 	array_free(data->params);
 	array_free(data->possibilities);
-	xfree(data);
 }
 
 /*
@@ -4209,22 +4195,23 @@
  */
 
 void command_freeone(command_t *c) {
-	LIST_REMOVE(&commands, c, list_command_free);
+	LIST_REMOVE2(&commands, c, list_command_free);
 }
 
 int command_remove(plugin_t *plugin, const char *name)
 {
-	list_t l;
+	command_t *c;
 
-	for (l = commands; l;) {
-		command_t *c = l->data;
-		l = l->next;
+	for (c = commands; c;) {
+		command_t *next = c->next;
 
 		if (!xstrcasecmp(name, c->name) && plugin == c->plugin) {
 			command_freeone(c);
 
 			return 0;
 		}
+
+		c = next;
 	}
 
 	return -1;
@@ -4240,7 +4227,7 @@
  */
 
 void command_free() {
-	LIST_DESTROY(commands, list_command_free);
+	LIST_DESTROY2(commands, list_command_free);
 	commands = NULL;
 }
 

Modified: trunk/ekg/commands.h
===================================================================
--- trunk/ekg/commands.h	2008-03-07 18:41:00 UTC (rev 3853)
+++ trunk/ekg/commands.h	2008-03-08 11:20:34 UTC (rev 3854)
@@ -56,7 +56,9 @@
 
 typedef COMMAND(command_func_t);
 
-typedef struct {
+typedef struct command {
+	struct command	*next;
+
 /* public: */
 	const char	*name;
 	plugin_t	*plugin;
@@ -69,8 +71,8 @@
 } command_t;
 
 #ifndef EKG2_WIN32_NOFUNCTION
-extern list_t commands;
-extern list_t *commands_lock;
+extern command_t *commands;
+extern command_t **commands_lock;
 
 command_t *command_add(plugin_t *plugin, const char *name, char *params, command_func_t function, command_flags_t flags, char *possibilities);
 void command_freeone(command_t *c);

Modified: trunk/ekg/dynstuff.c
===================================================================
--- trunk/ekg/dynstuff.c	2008-03-07 18:41:00 UTC (rev 3853)
+++ trunk/ekg/dynstuff.c	2008-03-08 11:20:34 UTC (rev 3854)
@@ -131,6 +131,65 @@
 	return list_add_sorted(list, data, NULL);
 }
 
+void *list_add_sorted3(list_t *list, list_t new, int (*comparision)(void *, void *))
+{
+	list_t tmp;
+
+	if (!list) {
+		errno = EFAULT;
+		return NULL;
+	}
+
+	new->next = NULL;
+	if (!(tmp = *list)) {
+		*list = new;
+	} else {
+		if (!comparision) {
+			while (tmp->next)
+				tmp = tmp->next;
+			tmp->next = new;
+		} else {
+			list_t prev = NULL;
+			
+			while (comparision(new, tmp) > 0) {
+				prev = tmp;
+				tmp = tmp->next;
+				if (!tmp)
+					break;
+			}
+			
+			if (!prev) {
+				new->next = *list;
+				*list = new;
+			} else {
+				prev->next = new;
+				new->next = tmp;
+			}
+		}
+	}
+
+	return new;
+}
+
+void *list_add_beginning3(list_t *list, list_t new)
+{
+	if (!list) {
+		errno = EFAULT;
+		return NULL;
+	}
+
+	new->next = *list;
+	*list	  = new;
+
+	return new;
+
+}
+
+void *list_add3(list_t *list, list_t new)
+{
+	return list_add_sorted3(list, new, NULL);
+}
+
 /**
  * list_remove_safe()
  *
@@ -228,6 +287,34 @@
 	return 0;
 }
 
+int list_remove3(list_t *list, void *data, void (*func)(void *data)) {
+	list_t tmp, last = NULL;
+
+	if (!list) {
+		errno = EFAULT;
+		return -1;
+	}
+
+	tmp = *list;
+	if (tmp && tmp == data) {
+		*list = tmp->next;
+	} else {
+		for (; tmp && tmp != data; tmp = tmp->next)
+			last = tmp;
+		if (!tmp) {
+			errno = ENOENT;
+			return -1;
+		}
+		last->next = tmp->next;
+	}
+
+	if (func)
+		func(tmp);
+	xfree(tmp);
+
+	return 0;
+}
+
 /**
  * list_remove()
  *
@@ -272,6 +359,20 @@
 	return NULL;
 }
 
+void *list_get_nth3(list_t list, int id) {
+	while (list) {
+		if ((--id) == 0) {
+			/* errno = !ENOENT; */
+			return list;
+		}
+
+		list = list->next;
+	}
+
+	errno = ENOENT;
+	return NULL;
+}
+
 void list_resort(list_t *list, int (*comparision)(void *, void *)) {
 	list_t tmplist = NULL;
 	list_t l = *list;
@@ -289,6 +390,23 @@
 	*list = tmplist;
 }
 
+void list_resort3(list_t *list, int (*comparision)(void *, void *)) {
+	list_t tmplist = NULL;
+	list_t l = *list;
+
+	while (l) {
+		list_t cur = l;
+
+		l = l->next;
+
+		list_add_sorted3(&tmplist, cur, comparision);
+
+		xfree(cur);
+	}
+
+	*list = tmplist;
+}
+
 /**
  * list_count()
  *
@@ -324,6 +442,23 @@
 	return 0;
 }
 
+int list_destroy3(list_t list, void (*func)(void *)) {
+	list_t tmp;
+	
+	while (list) {
+		if (func)
+			func(list);
+
+		tmp = list->next;
+
+		xfree(list);
+
+		list = tmp;
+	}
+
+	return 0;
+}
+
 /**
  * list_destroy()
  *

Modified: trunk/ekg/dynstuff.h
===================================================================
--- trunk/ekg/dynstuff.h	2008-03-07 18:41:00 UTC (rev 3853)
+++ trunk/ekg/dynstuff.h	2008-03-08 11:20:34 UTC (rev 3854)
@@ -42,10 +42,31 @@
  * jest dostępne bezpośrednio, reszta przez odpowiednie funkcje.
  */
 
+/*
+ * New *3() lists
+ *
+ * Instead of allocing additional list of dual-pointer structs, we add
+ * 'next' field to the beginning of real struct. C allows us to point
+ * to that first field independently of which struct is it, so we can
+ * use some type-indepdendent functions for that. The main target is
+ * to totally remove old functions, but leave 'list_t'.
+ *
+ * Then, for example, session_t would point to first entry of userlist
+ * (as userlist_t*), and that entry would point to second one, second
+ * one to third, etc. But if we want to group few userlist entries
+ * independently of their original structure, we could just catch them
+ * in standard list_t and use its' 'next' field.
+ */
+
 struct list {
+		/* it is important that we keep 'next' first field,
+		 * because C allows us to call first field of any structure
+		 * without knowing its' type
+		 *
+		 * so *3() would work peacefully w/ both list_t and not-list_t lists */
+	struct list *next;
+
 	void *data;
-	/*struct list *prev;*/
-	struct list *next;
 };
 
 typedef struct list *list_t;
@@ -53,27 +74,41 @@
 #ifndef EKG2_WIN32_NOFUNCTION
 #define LIST_ADD_COMPARE(x, type)			int x(const type data1, const type data2)
 #define LIST_ADD_SORTED(list, data, comp)		list_add_sorted(list, data, (void *) comp)
+#define LIST_ADD_SORTED2(list, data, comp)		list_add_sorted3((list_t *) list, (list_t) data, (void *) comp)
+#define LIST_ADD_BEGINNING2(list, data)			list_add_beginning((list_t *) list, (list_t) data)
 
 #define LIST_RESORT(list, comp)				list_resort(list, (void *) comp)
+#define LIST_RESORT2(list, comp)			list_resort3((list_t *) list, (void *) comp)
 
 #define LIST_REMOVE(list, data, func)			list_remove2(list, data, (void *) func)
+#define LIST_REMOVE2(list, elem, func)			list_remove3((list_t *) list, (list_t) elem, (void *) func)
 #define LIST_FREE_ITEM(x, type)				void x(type data)
 
 #define LIST_DESTROY(list, func)			list_destroy2(list, (void *) func)
+#define LIST_DESTROY2(list, func)			list_destroy3((list_t) list, (void *) func)
 
 void *list_add(list_t *list, void *data);
 void *list_add_beginning(list_t *list, void *data);
 void *list_add_sorted(list_t *list, void *data, int (*comparision)(void *, void *));
 
+void *list_add3(list_t *list, list_t new);
+void *list_add_beginning3(list_t *list, list_t new);
+void *list_add_sorted3(list_t *list, list_t new, int (*comparision)(void *, void *));
+
+
 int list_count(list_t list);
 void *list_get_nth(list_t list, int id);
+void *list_get_nth3(list_t list, int id);
 void list_resort(list_t *list, int (*comparision)(void *, void *));
+void list_resort3(list_t *list, int (*comparision)(void *, void *));
 
 int list_remove(list_t *list, void *data, int free_data);
 int list_remove2(list_t *list, void *data, void (*func)(void *));
+int list_remove3(list_t *list, void *elem, void (*func)(void *));
 
 int list_destroy(list_t list, int free_data);
 int list_destroy2(list_t list, void (*func)(void *));
+int list_destroy3(list_t list, void (*func)(void *));
 
 void list_cleanup(list_t *list);
 int list_remove_safe(list_t *list, void *data, int free_data);

Modified: trunk/ekg/plugins.c
===================================================================
--- trunk/ekg/plugins.c	2008-03-07 18:41:00 UTC (rev 3853)
+++ trunk/ekg/plugins.c	2008-03-08 11:20:34 UTC (rev 3854)
@@ -512,6 +512,7 @@
 	 */
 
 	list_t l;
+	command_t *c;
 
 	if (!p)
 		return -1;
@@ -576,13 +577,13 @@
 			variable_remove(v->plugin, v->name);
 	}
 
-	for (l = commands; l; ) {
-		command_t *c = l->data;
+	for (c = commands; c; ) {
+		command_t *next = c->next;
 
-		l = l->next;
-
 		if (c->plugin == p)
 			command_freeone(c);
+
+		c = next;
 	}
 
 	list_remove(&plugins, p, 0);

Modified: trunk/ekg/plugins.h
===================================================================
--- trunk/ekg/plugins.h	2008-03-07 18:41:00 UTC (rev 3853)
+++ trunk/ekg/plugins.h	2008-03-08 11:20:34 UTC (rev 3854)
@@ -26,7 +26,7 @@
 #include "dynstuff.h"
 #include "sessions.h"
 
-#define EKG_ABI_VER 3846
+#define EKG_ABI_VER 3854
 
 #define EXPORT __attribute__ ((visibility("default")))
 

Modified: trunk/ekg/stuff.c
===================================================================
--- trunk/ekg/stuff.c	2008-03-07 18:41:00 UTC (rev 3853)
+++ trunk/ekg/stuff.c	2008-03-08 11:20:34 UTC (rev 3854)
@@ -260,6 +260,7 @@
 {
 	char *cmd;
 	list_t l;
+	command_t *c;
 	struct alias *a;
 	char **params = NULL;
 	char *array;
@@ -277,14 +278,10 @@
 				printq("aliases_exist", string);
 				return -1;
 			} else {
-				list_t l;
-
 				list_add(&j->commands, xstrdup(cmd));
 				
 				/* przy wielu komendach trudno dopełniać, bo wg. której? */
-				for (l = commands; l; l = l->next) {
-					command_t *c = l->data;
-
+				for (c = commands; c; c = c->next) {
 					if (!xstrcasecmp(c->name, j->name)) {
 						xfree(c->params);
 						c->params = array_make(("?"), (" "), 0, 1, 1);
@@ -299,8 +296,7 @@
 		}
 	}
 
-	for (l = commands; l; l = l->next) {
-		command_t *c = l->data;
+	for (c = commands; c; c = c->next) {
 		char *tmp = ((*cmd == '/') ? cmd + 1 : cmd);
 
 		if (!xstrcasecmp(string, c->name) && !(c->flags & COMMAND_ISALIAS)) {

Modified: trunk/plugins/gtk/completion.c
===================================================================
--- trunk/plugins/gtk/completion.c	2008-03-07 18:41:00 UTC (rev 3853)
+++ trunk/plugins/gtk/completion.c	2008-03-08 11:20:34 UTC (rev 3854)
@@ -57,7 +57,7 @@
 static void command_generator(const char *text, int len)
 {
 	const char *slash = (""), *dash = ("");
-	list_t l;
+	command_t *c;
 	session_t *session = session_current;
 	if (*text == ('/')) {
 		slash = ("/");
@@ -74,8 +74,7 @@
 	if (window_current->target)
 		slash = ("/");
 
-	for (l = commands; l; l = l->next) {
-		command_t *c = l->data;
+	for (c = commands; c; c = c->next) {
 		char *without_sess_id = NULL;
 		int plen = 0;
 		if (session && session->uid)
@@ -999,7 +998,7 @@
 	} else {
 		char **params = NULL;
 		int i;
-		list_t l;
+		command_t *c;
                 char *cmd = (line[0] == '/') ? line + 1 : line;
 		int len;
 
@@ -1010,9 +1009,7 @@
 			session_t *session = session_current;
 			int plen = (int)(xstrchr(session->uid, ':') - session->uid) + 1;
 
-			for (l = commands; l; l = l->next) {
-				command_t *c = l->data;
-
+			for (c = commands; c; c = c->next) {
 	                        if (xstrncasecmp(c->name, session->uid, plen))
 	                                continue;
 
@@ -1024,9 +1021,7 @@
 			}
 		}
 
-        	for (l = commands; l; l = l->next) {
-	                command_t *c = l->data;
-
+        	for (c = commands; c; c = c->next) {
 	                if (!xstrncasecmp(c->name, cmd, len)) {
 	                        params = c->params;
 	                        actual_completed_command = c;

Modified: trunk/plugins/irc/irc.c
===================================================================
--- trunk/plugins/irc/irc.c	2008-03-07 18:41:00 UTC (rev 3853)
+++ trunk/plugins/irc/irc.c	2008-03-08 11:20:34 UTC (rev 3854)
@@ -1391,7 +1391,7 @@
 	char		*chan, *tmpname;
 	const char	*tf, *ts, *tp; /* first, second */
 	int		i = 0, parnum = 0, argnum = 0, hasq = 0;
-	list_t		l;
+	command_t	*c;
 
 	if (params) tf = params[0];
 	else tf = NULL;
@@ -1411,9 +1411,7 @@
 	}
 
 	tmpname = saprintf("irc:%s", name);
-	for (l = commands; l; l = l->next) {
-		command_t *c = l->data;
-
+	for (c = commands; c; c = c->next) {
 		if (&irc_plugin == c->plugin && !xstrcmp(tmpname, c->name))
 		{
 			while (c->params[parnum])

Modified: trunk/plugins/ncurses/completion.c
===================================================================
--- trunk/plugins/ncurses/completion.c	2008-03-07 18:41:00 UTC (rev 3853)
+++ trunk/plugins/ncurses/completion.c	2008-03-08 11:20:34 UTC (rev 3854)
@@ -57,7 +57,7 @@
 static void command_generator(const char *text, int len)
 {
 	const char *slash = (""), *dash = ("");
-	list_t l;
+	command_t *c;
 	session_t *session = session_current;
 	if (*text == ('/')) {
 		slash = ("/");
@@ -74,8 +74,7 @@
 	if (window_current->target)
 		slash = ("/");
 
-	for (l = commands; l; l = l->next) {
-		command_t *c = l->data;
+	for (c = commands; c; c = c->next) {
 		char *without_sess_id = NULL;
 		int plen = 0;
 		if (session && session->uid)
@@ -994,7 +993,7 @@
 	} else {
 		char **params = NULL;
 		int i;
-		list_t l;
+		command_t *c;
                 char *cmd = (line[0] == '/') ? line + 1 : line;
 		int len;
 
@@ -1005,9 +1004,7 @@
 			session_t *session = session_current;
 			int plen = (int)(xstrchr(session->uid, ':') - session->uid) + 1;
 
-			for (l = commands; l; l = l->next) {
-				command_t *c = l->data;
-
+			for (c = commands; c; c = c->next) {
 	                        if (xstrncasecmp(c->name, session->uid, plen))
 	                                continue;
 
@@ -1019,9 +1016,7 @@
 			}
 		}
 
-        	for (l = commands; l; l = l->next) {
-	                command_t *c = l->data;
-
+        	for (c = commands; c; c = c->next) {
 	                if (!xstrncasecmp(c->name, cmd, len)) {
 	                        params = c->params;
 	                        actual_completed_command = c;

Modified: trunk/plugins/readline/readline-completion.c
===================================================================
--- trunk/plugins/readline/readline-completion.c	2008-03-07 18:41:00 UTC (rev 3853)
+++ trunk/plugins/readline/readline-completion.c	2008-03-08 11:20:34 UTC (rev 3854)
@@ -157,7 +157,7 @@
 
 GENERATOR(command) {
 	static int len;
-	static list_t el;
+	static command_t *c;
 	int slash = 0;
 	int dash = 0;
 
@@ -204,7 +204,7 @@
 #endif
 
 	if (!state) {
-		el = commands;
+		c = commands;
 		len = xstrlen(text);
 	}
 
@@ -222,14 +222,12 @@
 
 	if (window_current->target) slash = 1;
 
-	while (el) {
-		command_t *c = el->data;
+	while (c) {
 		char *without_sess_id = NULL;
+		command_t *next = c->next;
 		int plen = 0;
 		session_t *session = session_current;
 
-		el = el->next;
-
 		if (session && session->uid)
 			plen =  (int)(xstrchr(session->uid, ':') - session->uid) + 1;
 
@@ -246,6 +244,8 @@
 					slash ? "/" : "",
 					dash ? "^" : "",
 					without_sess_id + 1);
+
+		c = next;
 	}
 
 	return NULL;
@@ -493,7 +493,7 @@
 	char **params = NULL;
 	int word = 0, i, abbrs = 0;
 	CPFunction *func = known_uin_generator;
-	list_t l;
+	command_t *c;
 	static int my_send_nicks_count = 0;
 
 	if (start) {
@@ -556,8 +556,7 @@
 		}
 		word--;
 
-		for (l = commands; l; l = l->next) {
-			command_t *c = l->data;
+		for (c = commands; c; c = c->next) {
 			int len = xstrlen(c->name);
 			char *cmd = (*rl_line_buffer == '/') ? rl_line_buffer + 1 : rl_line_buffer;
 



Więcej informacji o liście dyskusyjnej ekg2-commit