[ekg2-commit] r3861 - in trunk: ekg plugins/gtk plugins/ncurses plugins/readline: trunk/ekg/metacontacts.c trunk/ekg/metacontacts.h trunk/plugins/gtk/completion.c trunk/plugins/ncurses/completion.c trunk/plugins/ncurses/contacts.c trunk/plugins/readline/readline-completion.c

SVN commit svn w toxygen.net
Sob, 8 Mar 2008, 19:26:30 CET


Author: peres
Date: 2008-03-08 19:26:30 +0100 (Sat, 08 Mar 2008)
New Revision: 3861

Modified:
   trunk/ekg/metacontacts.c
   trunk/ekg/metacontacts.h
   trunk/plugins/gtk/completion.c
   trunk/plugins/ncurses/completion.c
   trunk/plugins/ncurses/contacts.c
   trunk/plugins/readline/readline-completion.c
Log:

Now metacontacts. Also changed few things:
- now on session alias change, we resort whole list, not only
  elements from that session,
- we don't remove removed users from metacontacts (now jabber
  contacts could be easily used),
- full status prioritization is used, that is ekg2 selects
  metauid with higher 'availability', and uses user-given prio
  only if two have the same status,
- struct freeing is performed by destroy-handlers instead of
  user code.



Modified: trunk/ekg/metacontacts.c
===================================================================
--- trunk/ekg/metacontacts.c	2008-03-08 16:09:25 UTC (rev 3860)
+++ trunk/ekg/metacontacts.c	2008-03-08 18:26:30 UTC (rev 3861)
@@ -35,7 +35,7 @@
 #include "metacontacts.h"
 #include "queries.h"
 
-list_t metacontacts = NULL;
+metacontact_t *metacontacts = NULL;
 
 static int metacontact_add_item(metacontact_t *m, const char *session, const char *name, unsigned int prio, int quiet);
 static int metacontact_remove_item(metacontact_t *m, const char *session, const char *name, int quiet);
@@ -49,13 +49,10 @@
         metacontact_t *m;
 
 	if (!params[0] || match_arg(params[0], 'l', ("list"), 2)) {
-                list_t l;
+        	metacontact_t *m;
 
-                for (l = metacontacts; l; l = l->next) {
-                        metacontact_t *m = l->data;
-                        
+                for (m = metacontacts; m; m = m->next)
 			printq("metacontact_list", m->name);
-                }
 
                 if (!metacontacts)
                         printq("metacontact_list_empty");
@@ -159,17 +156,16 @@
 
 
 	if (params[0] && (m = metacontact_find(params[0]))) {
-                list_t l;
+                metacontact_item_t *i = m->metacontact_items;
 
-                if (!m->metacontact_items) {
+                if (!i) {
                         printq("metacontact_item_list_empty");
 			return 0;
 		}
 
 		printq("metacontact_item_list_header", params[0]);
 		
-                for (l = m->metacontact_items; l; l = l->next) {
-                        metacontact_item_t *i = l->data;
+                for (; i; i = i->next) {
 			userlist_t *u = userlist_find_n(i->s_uid, i->name);
 			char *tmp;
 
@@ -206,11 +202,9 @@
  */
 metacontact_t *metacontact_find(const char *name) 
 {
-	list_t l;
+	metacontact_t *m;
 
-	for (l = metacontacts; l; l = l->next) {
-        	metacontact_t *m = l->data;
-
+	for (m = metacontacts; m; m = m->next) {
         	if (!xstrcasecmp(name, m->name))
 			return m;
 	}
@@ -246,7 +240,7 @@
 	m = xmalloc(sizeof(metacontact_t));
 	m->name = xstrdup(name);
 
-	return LIST_ADD_SORTED(&metacontacts, m, metacontact_add_compare);
+	return LIST_ADD_SORTED2(&metacontacts, m, metacontact_add_compare);
 }
 
 /*
@@ -272,14 +266,12 @@
  */
 static metacontact_item_t *metacontact_find_item(metacontact_t *m, const char *name, const char *uid)
 {
-        list_t l;
+        metacontact_item_t *i;
 
 	if (!m)
 		return NULL;
 
-        for (l = m->metacontact_items; l; l = l->next) {
-                metacontact_item_t *i = l->data;
-
+        for (i = m->metacontact_items; i; i = i->next) {
                 if (!xstrcasecmp(name, i->name) && !xstrcasecmp(uid, i->s_uid))
                         return i;
         }
@@ -326,11 +318,21 @@
 	i->s_uid	= xstrdup(s->uid);
 	i->prio		= prio;
 
-	LIST_ADD_SORTED(&m->metacontact_items, i, metacontact_add_item_compare);
+	LIST_ADD_SORTED2(&m->metacontact_items, i, metacontact_add_item_compare);
 
 	return 1;
 }
 
+static LIST_FREE_ITEM(metacontact_item_free, metacontact_item_t *) {
+	xfree(data->name);
+	xfree(data->s_uid);
+}
+
+static LIST_FREE_ITEM(metacontact_list_free, metacontact_t *) {
+        LIST_DESTROY2(data->metacontact_items, metacontact_item_free);
+	xfree(data->name);
+}
+
 /* 
  * metacotact_remove_item()
  * 
@@ -358,9 +360,7 @@
 		return 0;
 	}	
 
-	xfree(i->name);
-	xfree(i->s_uid);
-	list_remove(&m->metacontact_items, i, 1);
+	LIST_REMOVE2(&m->metacontact_items, i, metacontact_item_free);
 	
 	return 1;
 }
@@ -374,21 +374,17 @@
 static int metacontact_remove(const char *name)
 {
 	metacontact_t *m = metacontact_find(name);
-	list_t l;
+	metacontact_item_t *i;
 
-        for (l = m->metacontact_items; l; ) {
-		metacontact_item_t *i = l->data;
+        for (i = m->metacontact_items; i; ) {
+		metacontact_item_t *next = i->next;
 
-		l = l->next;
-
 		metacontact_remove_item(m, i->s_uid, i->name, 1);
+		i = next;
 	}
 
-        list_destroy(m->metacontact_items, 1);
-        xfree(m->name);
+        LIST_REMOVE2(&metacontacts, m, metacontact_list_free);
 
-        list_remove(&metacontacts, m, 1);
-
 	return 1;
 }
 
@@ -400,28 +396,27 @@
  */
 static int metacontact_session_renamed_handler(void *data, va_list ap)
 {
+	/* We don't change alias so frequently,
+	 * so we can resort whole list, not only items w/ that session */
+
+	LIST_RESORT2(metacontacts, metacontact_add_item_compare);
+#if 0
 	char **tmp = va_arg(ap, char**);
 	session_t *s = session_find(*tmp);
         char *session;
-	list_t l;
+	metacontact_t *m;
 
 	if (!s)
 		return 0;
 
 	session = s->uid;
 
-	for (l = metacontacts; l; l = l->next) {
-        	metacontact_t *m = l->data;
-		list_t l2;
+	for (m = metacontacts; m; m = m->next) {
+		metacontact_item_t *i;
 
-		for (l2 = m->metacontact_items; l2;) {
-			metacontact_item_t *i = (l2 && l2->data) ? l2->data : NULL;
-			
-			if (!i)
-				break;
+		for (i = m->metacontact_items; i;) {
+			metacontact_item_t *next = i->next;
 
-			l2 = l2->next;
-
 			if (!xstrcasecmp(session, i->s_uid)) {
 				char *s_uid, *name;
 				int prio;
@@ -435,9 +430,16 @@
 			
 				xfree(s_uid);
 				xfree(name);
+
+					/* list has changed, so we need to start from beginning */
+				m = metacontacts;
+				break;
 			}
+
+			i = next;
 		}
 	}
+#endif
 	
 	return 1;
 }
@@ -450,15 +452,16 @@
  */
 static int metacontact_userlist_removed_handler(void *data, va_list ap)
 {
+	/* XXX: disabled it to allow jabber metacontacts
+	 * 	but think about it */
+#if 0
         char **name = va_arg(ap, char**);
-        list_t l;
+	metacontact_t *m;
 
-        for (l = metacontacts; l; l = l->next) {
-                metacontact_t *m = l->data;
-                list_t l2;
+        for (m = metacontacts; m; m = m->next) {
+		metacontact_item_t *i;
 
-                for (l2 = m->metacontact_items; l2; l2 = l2->next) {
-			metacontact_item_t *i = (l2 && l2->data) ? l2->data : NULL;
+                for (i = m->metacontact_items; i; i = i->next) {
 			userlist_t *u;
 			
 			if (!i) 
@@ -480,6 +483,7 @@
 			}
 		}		
 	}
+#endif
 
 	return 0;
 }
@@ -487,21 +491,20 @@
 /* 
  * metacontact_find_prio()
  * 
- * it finds and return metacontact_item with the higher priority 
- * first it looks at the status, then if all are notavail the one 
- * with higher priority is returned 
+ * it finds and return metacontact_item with the 'most available'
+ * status; if more than uids have the same one, it also looks
+ * at the priority
  */
 metacontact_item_t *metacontact_find_prio(metacontact_t *m)
 {
-        list_t l;
+        metacontact_item_t *i;
 	metacontact_item_t *ret = NULL;
 	userlist_t *last = NULL;
 
         if (!m)
                 return NULL;
 
-        for (l = m->metacontact_items; l; l = l->next) {
-                metacontact_item_t *i = l->data;
+        for (i = m->metacontact_items; i; i = i->next) {
 		userlist_t *u = userlist_find_n(i->s_uid, i->name);
 		
 		if (!u)
@@ -512,17 +515,10 @@
 			continue;
 		}
 
-		{
-			/* hardly simplified that, XXX could you check it?
-			 * additional todo: use state priorities? */
-			const int last_na = EKG_STATUS_IS_NA(last->status);
-			const int u_na = EKG_STATUS_IS_NA(u->status);
-
-			if (((last_na == u_na) && ret->prio < i->prio) || (last_na && !u_na)) {
-				ret = i;
-				last = u;
-				continue;
-			}
+		if (u->status > last->status || (u->status == last->status && i->prio > ret->prio)) {
+			ret = i;
+			last = u;
+			continue;
 		}
         }
 
@@ -547,16 +543,8 @@
  */
 void metacontact_free()
 {
-	list_t l;
 
-        for (l = metacontacts; l;) {
-                metacontact_t *m = l->data;
-		
-		l = l->next;
-		metacontact_remove(m->name);		
-	}
-
-        list_destroy(metacontacts, 1);
+	LIST_DESTROY2(metacontacts, metacontact_list_free);
 }
 
 /*
@@ -566,7 +554,7 @@
  */
 int metacontact_write()
 {
-        list_t l;
+        metacontact_t *m;
         FILE *f = NULL;
 
         f = fopen(prepare_path("metacontacts", 1), "w");
@@ -574,17 +562,12 @@
         if (!f)
                 return -1;
 
-        for (l = metacontacts; l; l = l->next) {
-                metacontact_t *m = l->data;
-                list_t lp;
-
+        for (m = metacontacts; m; m = m->next) {
+		metacontact_item_t *i;
                 fprintf(f, "[%s]\n", m->name);
 
-                for (lp = m->metacontact_items; lp; lp = lp->next) {
-                        metacontact_item_t *i = lp->data;
-
+                for (i = m->metacontact_items; i; i = i->next)
                         fprintf(f, "%s %s %d\n", i->s_uid, i->name, i->prio);
-                }
         }
         fclose(f);
 

Modified: trunk/ekg/metacontacts.h
===================================================================
--- trunk/ekg/metacontacts.h	2008-03-08 16:09:25 UTC (rev 3860)
+++ trunk/ekg/metacontacts.h	2008-03-08 18:26:30 UTC (rev 3861)
@@ -21,19 +21,23 @@
 #define __EKG_METACONTACTS_H
 #include "dynstuff.h" 
 
-typedef struct {
-	char		*name; /* uid or name */
-	unsigned int	prio; /* prio */
-	char		*s_uid; /* session uid */
+typedef struct metacontact_item {
+	struct metacontact_item	*next;
+
+	char			*name;	/* uid or name */
+	unsigned int		prio;	/* prio */
+	char			*s_uid;	/* session uid */
 } metacontact_item_t;
 
-typedef struct {
-	char *name; /* name of metacontact */
-	list_t metacontact_items;
+typedef struct metacontact {
+	struct metacontact	*next;
+
+	char			*name; /* name of metacontact */
+	metacontact_item_t	*metacontact_items;
 } metacontact_t;
 
 #ifndef EKG2_WIN32_NOFUNCTION 
-extern list_t metacontacts;
+extern metacontact_t *metacontacts;
 
 metacontact_t *metacontact_add(const char *name);
 metacontact_t *metacontact_find(const char *name);

Modified: trunk/plugins/gtk/completion.c
===================================================================
--- trunk/plugins/gtk/completion.c	2008-03-08 16:09:25 UTC (rev 3860)
+++ trunk/plugins/gtk/completion.c	2008-03-08 18:26:30 UTC (rev 3861)
@@ -605,11 +605,9 @@
 
 static void metacontacts_generator(const char *text, int len)
 {
-        list_t l;
+        metacontact_t *m;
 
-        for (l = metacontacts; l; l = l->next) {
-		metacontact_t *m = l->data;
-		
+        for (m = metacontacts; m; m = m->next) {
 		if (!xstrncasecmp(text, m->name, len)) 
                 	array_add_check(&completions, xstrdup(m->name), 1);
         }

Modified: trunk/plugins/ncurses/completion.c
===================================================================
--- trunk/plugins/ncurses/completion.c	2008-03-08 16:09:25 UTC (rev 3860)
+++ trunk/plugins/ncurses/completion.c	2008-03-08 18:26:30 UTC (rev 3861)
@@ -605,11 +605,9 @@
 
 static void metacontacts_generator(const char *text, int len)
 {
-        list_t l;
+        metacontact_t *m;
 
-        for (l = metacontacts; l; l = l->next) {
-		metacontact_t *m = l->data;
-		
+        for (m = metacontacts; m; m = m->next) {
 		if (!xstrncasecmp(text, m->name, len)) 
                 	array_add_check(&completions, xstrdup(m->name), 1);
         }

Modified: trunk/plugins/ncurses/contacts.c
===================================================================
--- trunk/plugins/ncurses/contacts.c	2008-03-08 16:09:25 UTC (rev 3860)
+++ trunk/plugins/ncurses/contacts.c	2008-03-08 18:26:30 UTC (rev 3861)
@@ -256,21 +256,19 @@
 	}
 
 	if (all == 1 || all == 2) {
-		list_t l;
+		metacontact_t *m;
 
 		/* Remove contacts contained in metacontacts. */
 		if (all == 1 && config_contacts_metacontacts_swallow) {
-			for (l = metacontacts; l; l = l->next) {
-				metacontact_t *m = l->data;
-				list_t ml;
+			for (m = metacontacts; m; m = m->next) {
+				metacontact_item_t *i;
 
 				/* metacontact_find_prio() should always success [for current API] */
 /*
 				if (!metacontact_find_prio(m)) 
 					continue;
 */
-				for (ml = m->metacontact_items; ml; ml = ml->next) {
-					metacontact_item_t *i = ml->data;
+				for (i = m->metacontact_items; i; i = i->next) {
 					userlist_t *u;
 					list_t sl;
 
@@ -288,9 +286,7 @@
 			}
 		}
 
-		for (l = metacontacts; l; l = l->next) {
-			metacontact_t *m = l->data;
-
+		for (m = metacontacts; m; m = m->next) {
 			metacontact_item_t *i;
 			userlist_t *u;
 

Modified: trunk/plugins/readline/readline-completion.c
===================================================================
--- trunk/plugins/readline/readline-completion.c	2008-03-08 16:09:25 UTC (rev 3860)
+++ trunk/plugins/readline/readline-completion.c	2008-03-08 18:26:30 UTC (rev 3861)
@@ -132,20 +132,18 @@
 
 GENERATOR(metacontacts) {
 	static int len;
-	static list_t el;
+	static metacontact_t *m;
 
 	if (!state) {
 		len = xstrlen(text);
-		el = metacontacts;
+		m = metacontacts;
 	}
 
-	while (el) {
-		metacontact_t *m = el->data;
-
-		el = el->next;
-
+	while (m) {
 		if (!xstrncasecmp(text, m->name, len)) 
 			return xstrdup(m->name);
+
+		m = m->next;
 	}
 	return NULL;
 }
@@ -224,7 +222,6 @@
 
 	while (c) {
 		char *without_sess_id = NULL;
-		command_t *next = c->next;
 		int plen = 0;
 		session_t *session = session_current;
 
@@ -245,7 +242,7 @@
 					dash ? "^" : "",
 					without_sess_id + 1);
 
-		c = next;
+		c = c->next;
 	}
 
 	return NULL;



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