python: Scan for non-NULLs in print events

Closes #916
Closes #915
This commit is contained in:
Adam Dane [:hobophobe] 2014-03-15 20:50:13 -05:00 committed by TingPing
parent 8bdde3a2df
commit 7e55e4ee73
1 changed files with 70 additions and 100 deletions

View File

@ -271,6 +271,7 @@ typedef struct {
/* Function declarations */ /* Function declarations */
static PyObject *Util_BuildList(char *word[]); static PyObject *Util_BuildList(char *word[]);
static PyObject *Util_BuildEOLList(char *word[]);
static void Util_Autoload(); static void Util_Autoload();
static char *Util_Expand(char *filename); static char *Util_Expand(char *filename);
@ -382,27 +383,79 @@ static PyObject *
Util_BuildList(char *word[]) Util_BuildList(char *word[])
{ {
PyObject *list; PyObject *list;
int listsize = 0; int listsize = 31;
int i; int i;
while (word[listsize] && word[listsize][0]) /* Find the last valid array member; there may be intermediate NULLs that
listsize++; * would otherwise cause us to drop some members. */
while (listsize > 0 &&
(word[listsize] == NULL || word[listsize][0] == 0))
listsize--;
list = PyList_New(listsize); list = PyList_New(listsize);
if (list == NULL) { if (list == NULL) {
PyErr_Print(); PyErr_Print();
return NULL; return NULL;
} }
for (i = 0; i != listsize; i++) { for (i = 1; i <= listsize; i++) {
PyObject *o = PyUnicode_FromString(word[i]); PyObject *o;
if (o == NULL) { if (word[i] == NULL) {
Py_DECREF(list); Py_INCREF(Py_None);
PyErr_Print(); o = Py_None;
return NULL; } else {
/* This handles word[i][0] == 0 automatically. */
o = PyUnicode_FromString(word[i]);
} }
PyList_SetItem(list, i, o); PyList_SetItem(list, i - 1, o);
} }
return list; return list;
} }
static PyObject *
Util_BuildEOLList(char *word[])
{
PyObject *list;
int listsize = 31;
int i;
/* Find the last valid array member; there may be intermediate NULLs that
* would otherwise cause us to drop some members. */
while (listsize > 0 &&
(word[listsize] == NULL || word[listsize][0] == 0))
listsize--;
list = PyList_New(listsize);
if (list == NULL) {
PyErr_Print();
return NULL;
}
char *accum = NULL;
char *last = NULL;
for (i = listsize; i > 0; i--) {
char *part = word[i];
if (accum == NULL) {
accum = g_strdup (part);
} else if (part != NULL && part[0] != 0) {
last = accum;
accum = g_strjoin(" ", part, last, NULL);
g_free (last);
last = NULL;
if (accum == NULL) {
Py_DECREF(list);
hexchat_print(ph, "Not enough memory to alloc accum"
"for python plugin callback");
return NULL;
}
}
PyObject *uni_part = PyUnicode_FromString(accum);
PyList_SetItem(list, i - 1, uni_part);
}
if (last)
g_free (last);
if (accum)
g_free (accum);
return list;
}
static void static void
Util_Autoload_from (const char *dir_name) Util_Autoload_from (const char *dir_name)
{ {
@ -515,12 +568,12 @@ Callback_Server(char *word[], char *word_eol[], hexchat_event_attrs *attrs, void
plugin = hook->plugin; plugin = hook->plugin;
BEGIN_PLUGIN(plugin); BEGIN_PLUGIN(plugin);
word_list = Util_BuildList(word+1); word_list = Util_BuildList(word);
if (word_list == NULL) { if (word_list == NULL) {
END_PLUGIN(plugin); END_PLUGIN(plugin);
return 0; return 0;
} }
word_eol_list = Util_BuildList(word_eol+1); word_eol_list = Util_BuildList(word_eol);
if (word_eol_list == NULL) { if (word_eol_list == NULL) {
Py_DECREF(word_list); Py_DECREF(word_list);
END_PLUGIN(plugin); END_PLUGIN(plugin);
@ -566,12 +619,12 @@ Callback_Command(char *word[], char *word_eol[], void *userdata)
plugin = hook->plugin; plugin = hook->plugin;
BEGIN_PLUGIN(plugin); BEGIN_PLUGIN(plugin);
word_list = Util_BuildList(word+1); word_list = Util_BuildList(word);
if (word_list == NULL) { if (word_list == NULL) {
END_PLUGIN(plugin); END_PLUGIN(plugin);
return 0; return 0;
} }
word_eol_list = Util_BuildList(word_eol+1); word_eol_list = Util_BuildList(word_eol);
if (word_eol_list == NULL) { if (word_eol_list == NULL) {
Py_DECREF(word_list); Py_DECREF(word_list);
END_PLUGIN(plugin); END_PLUGIN(plugin);
@ -606,58 +659,19 @@ Callback_Print_Attrs(char *word[], hexchat_event_attrs *attrs, void *userdata)
PyObject *word_list; PyObject *word_list;
PyObject *word_eol_list; PyObject *word_eol_list;
PyObject *attributes; PyObject *attributes;
char **word_eol;
char *word_eol_raw;
int listsize = 0;
int next = 0;
int i;
int ret = 0; int ret = 0;
PyObject *plugin; PyObject *plugin;
/* Cut off the message identifier. */
word += 1;
/* HexChat doesn't provide a word_eol for print events, so we
* build our own here. */
while (word[listsize] && word[listsize][0])
listsize++;
word_eol = (char **) g_malloc(sizeof(char*)*(listsize+1));
if (word_eol == NULL) {
hexchat_print(ph, "Not enough memory to alloc word_eol "
"for python plugin callback.");
return 0;
}
/* First build a word clone, but NULL terminated. */
memcpy(word_eol, word, listsize*sizeof(char*));
word_eol[listsize] = NULL;
/* Then join it. */
word_eol_raw = g_strjoinv(" ", word_eol);
if (word_eol_raw == NULL) {
hexchat_print(ph, "Not enough memory to alloc word_eol_raw "
"for python plugin callback.");
return 0;
}
/* And rebuild the real word_eol. */
for (i = 0; i != listsize; i++) {
word_eol[i] = word_eol_raw+next;
next += strlen(word[i])+1;
}
word_eol[i] = "";
plugin = hook->plugin; plugin = hook->plugin;
BEGIN_PLUGIN(plugin); BEGIN_PLUGIN(plugin);
word_list = Util_BuildList(word); word_list = Util_BuildList(word);
if (word_list == NULL) { if (word_list == NULL) {
g_free(word_eol_raw);
g_free(word_eol);
END_PLUGIN(plugin); END_PLUGIN(plugin);
return 0; return 0;
} }
word_eol_list = Util_BuildList(word_eol); word_eol_list = Util_BuildEOLList(word);
if (word_eol_list == NULL) { if (word_eol_list == NULL) {
g_free(word_eol_raw);
g_free(word_eol);
Py_DECREF(word_list); Py_DECREF(word_list);
END_PLUGIN(plugin); END_PLUGIN(plugin);
return 0; return 0;
@ -672,8 +686,6 @@ Callback_Print_Attrs(char *word[], hexchat_event_attrs *attrs, void *userdata)
Py_DECREF(word_eol_list); Py_DECREF(word_eol_list);
Py_DECREF(attributes); Py_DECREF(attributes);
g_free(word_eol_raw);
g_free(word_eol);
if (retobj == Py_None) { if (retobj == Py_None) {
ret = HEXCHAT_EAT_NONE; ret = HEXCHAT_EAT_NONE;
Py_DECREF(retobj); Py_DECREF(retobj);
@ -696,72 +708,30 @@ Callback_Print(char *word[], void *userdata)
PyObject *retobj; PyObject *retobj;
PyObject *word_list; PyObject *word_list;
PyObject *word_eol_list; PyObject *word_eol_list;
char **word_eol;
char *word_eol_raw;
int listsize = 0;
int next = 0;
int i;
int ret = 0; int ret = 0;
PyObject *plugin; PyObject *plugin;
/* Cut off the message identifier. */
word += 1;
/* HexChat doesn't provide a word_eol for print events, so we
* build our own here. */
while (word[listsize] && word[listsize][0])
listsize++;
word_eol = (char **) g_malloc(sizeof(char*)*(listsize+1));
if (word_eol == NULL) {
hexchat_print(ph, "Not enough memory to alloc word_eol "
"for python plugin callback.");
return 0;
}
/* First build a word clone, but NULL terminated. */
memcpy(word_eol, word, listsize*sizeof(char*));
word_eol[listsize] = NULL;
/* Then join it. */
word_eol_raw = g_strjoinv(" ", word_eol);
if (word_eol_raw == NULL) {
hexchat_print(ph, "Not enough memory to alloc word_eol_raw "
"for python plugin callback.");
return 0;
}
/* And rebuild the real word_eol. */
for (i = 0; i != listsize; i++) {
word_eol[i] = word_eol_raw+next;
next += strlen(word[i])+1;
}
word_eol[i] = "";
plugin = hook->plugin; plugin = hook->plugin;
BEGIN_PLUGIN(plugin); BEGIN_PLUGIN(plugin);
word_list = Util_BuildList(word); word_list = Util_BuildList(word);
if (word_list == NULL) { if (word_list == NULL) {
g_free(word_eol_raw);
g_free(word_eol);
END_PLUGIN(plugin); END_PLUGIN(plugin);
return 0; return 0;
} }
word_eol_list = Util_BuildList(word_eol); word_eol_list = Util_BuildEOLList(word);
if (word_eol_list == NULL) { if (word_eol_list == NULL) {
g_free(word_eol_raw);
g_free(word_eol);
Py_DECREF(word_list); Py_DECREF(word_list);
END_PLUGIN(plugin); END_PLUGIN(plugin);
return 0; return 0;
} }
retobj = PyObject_CallFunction(hook->callback, "(OOO)", word_list, retobj = PyObject_CallFunction(hook->callback, "(OOO)", word_list,
word_eol_list, hook->userdata); word_eol_list, hook->userdata);
Py_DECREF(word_list); Py_DECREF(word_list);
Py_DECREF(word_eol_list); Py_DECREF(word_eol_list);
g_free(word_eol_raw);
g_free(word_eol);
if (retobj == Py_None) { if (retobj == Py_None) {
ret = HEXCHAT_EAT_NONE; ret = HEXCHAT_EAT_NONE;
Py_DECREF(retobj); Py_DECREF(retobj);