[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