summary refs log tree commit diff stats
path: root/plugins/python/python.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/python/python.c')
-rw-r--r--plugins/python/python.c166
1 files changed, 56 insertions, 110 deletions
diff --git a/plugins/python/python.c b/plugins/python/python.c
index 1904a3e9..1f9c7cc9 100644
--- a/plugins/python/python.c
+++ b/plugins/python/python.c
@@ -51,6 +51,8 @@
  *
  */
 
+#include "config.h"
+
 #include <glib.h>
 #include <glib/gstdio.h>
 #include <string.h>
@@ -64,9 +66,9 @@
 #include <dirent.h>
 #endif
 
-#include "../../config.h"
 #include "hexchat-plugin.h"
-#undef _POSIX_C_SOURCE	/* Avoid warning: also in /usr/include/features.h from glib.h */
+#undef _POSIX_C_SOURCE	/* Avoid warnings from /usr/include/features.h */
+#undef _XOPEN_SOURCE
 #include <Python.h>
 #include <structmember.h>
 #include <pythread.h>
@@ -414,6 +416,9 @@ Util_BuildEOLList(char *word[])
 	PyObject *list;
 	int listsize = 31;
 	int i;
+	char *accum = NULL;
+	char *last = NULL;
+
 	/* Find the last valid array member; there may be intermediate NULLs that
 	 * would otherwise cause us to drop some members. */
 	while (listsize > 0 &&
@@ -424,10 +429,9 @@ Util_BuildEOLList(char *word[])
 		PyErr_Print();
 		return NULL;
 	}
-	char *accum = NULL;
-	char *last = NULL;
 	for (i = listsize; i > 0; i--) {
 		char *part = word[i];
+		PyObject *uni_part;
 		if (accum == NULL) {
 			accum = g_strdup (part);
 		} else if (part != NULL && part[0] != 0) {
@@ -443,14 +447,12 @@ Util_BuildEOLList(char *word[])
 				return NULL;
 			}
 		}
-		PyObject *uni_part = PyUnicode_FromString(accum);
+		uni_part = PyUnicode_FromString(accum);
 		PyList_SetItem(list, i - 1, uni_part);
 	}
 
-	if (last)
-		g_free (last);
-	if (accum)
-		g_free (accum);
+	g_free (last);
+	g_free (accum);
 
 	return list;
 }
@@ -800,9 +802,7 @@ Callback_ThreadTimer(void *userdata)
 /* We keep this information global, so we can reset it when the
  * deinit function is called. */
 /* XXX This should be somehow bound to the printing context. */
-static char *xchatout_buffer = NULL;
-static int xchatout_buffer_size = 0;
-static int xchatout_buffer_pos = 0;
+static GString *xchatout_buffer = NULL;
 
 static PyObject *
 XChatOut_New()
@@ -826,76 +826,42 @@ XChatOut_dealloc(PyObject *self)
 static PyObject *
 XChatOut_write(PyObject *self, PyObject *args)
 {
-	int new_buffer_pos, data_size, print_limit, add_space;
+	gboolean add_space;
 	char *data, *pos;
-	if (!PyArg_ParseTuple(args, "s#:write", &data, &data_size))
+
+	if (!PyArg_ParseTuple(args, "s:write", &data))
 		return NULL;
-	if (!data_size) {
-		Py_INCREF(Py_None);
-		return Py_None;
+	if (!data || !*data) {
+		Py_RETURN_NONE;
 	}
 	BEGIN_XCHAT_CALLS(RESTORE_CONTEXT|ALLOW_THREADS);
 	if (((XChatOutObject *)self)->softspace) {
-		add_space = 1;
+		add_space = TRUE;
 		((XChatOutObject *)self)->softspace = 0;
 	} else {
-		add_space = 0;
-	}
-	if (xchatout_buffer_size-xchatout_buffer_pos < data_size+add_space) {
-		char *new_buffer;
-		/* This buffer grows whenever needed, and does not
-		 * shrink. If we ever implement unloading of the
-		 * python interface, we must find some way to free
-		 * this buffer as well. */
-		xchatout_buffer_size += data_size*2+16;
-		new_buffer = g_realloc(xchatout_buffer, xchatout_buffer_size);
-		if (new_buffer == NULL) {
-			hexchat_print(ph, "Not enough memory to print");
-			/* The system is out of resources. Let's help. */
-			g_free(xchatout_buffer);
-			xchatout_buffer = NULL;
-			xchatout_buffer_size = 0;
-			xchatout_buffer_pos = 0;
-			/* Return something valid, since we have
-			 * already warned the user, and he probably
-			 * won't be able to notice this exception. */
-			goto exit;
-		}
-		xchatout_buffer = new_buffer;
-	}
-	memcpy(xchatout_buffer+xchatout_buffer_pos, data, data_size);
-	print_limit = new_buffer_pos = xchatout_buffer_pos+data_size;
-	pos = xchatout_buffer+print_limit;
-	if (add_space && *(pos-1) != '\n') {
-		*pos = ' ';
-		*(pos+1) = 0;
-		new_buffer_pos++;
-	}
-	while (*pos != '\n' && print_limit > xchatout_buffer_pos) {
-		pos--;
-		print_limit--;
-	}
-	if (*pos == '\n') {
-		/* Crop it, inserting the string limiter there. */
-		*pos = 0;
-		hexchat_print(ph, xchatout_buffer);
-		if (print_limit < new_buffer_pos) {
-			/* There's still data to be printed. */
-			print_limit += 1; /* Include the limiter. */
-			xchatout_buffer_pos = new_buffer_pos-print_limit;
-			memmove(xchatout_buffer, xchatout_buffer+print_limit,
-				xchatout_buffer_pos);
-		} else {
-			xchatout_buffer_pos = 0;
-		}
-	} else {
-		xchatout_buffer_pos = new_buffer_pos;
+		add_space = FALSE;
+	}
+
+	g_string_append (xchatout_buffer, data);
+
+	/* If not end of line add space to continue buffer later */
+	if (add_space && xchatout_buffer->str[xchatout_buffer->len - 1] != '\n')
+	{
+		g_string_append_c (xchatout_buffer, ' ');
+	}
+
+	/* If there is an end of line print up to that */
+	if ((pos = strrchr (xchatout_buffer->str, '\n')))
+	{
+		*pos = '\0';
+		hexchat_print (ph, xchatout_buffer->str);
+
+		/* Then remove it from buffer */
+		g_string_erase (xchatout_buffer, 0, pos - xchatout_buffer->str + 1);
 	}
 
-exit:
 	END_XCHAT_CALLS();
-	Py_INCREF(Py_None);
-	return Py_None;
+	Py_RETURN_NONE;
 }
 
 #define OFF(x) offsetof(XChatOutObject, x)
@@ -1047,8 +1013,7 @@ Context_set(ContextObject *self, PyObject *args)
 {
 	PyObject *plugin = Plugin_GetCurrent();
 	Plugin_SetContext(plugin, self->context);
-	Py_INCREF(Py_None);
-	return Py_None;
+	Py_RETURN_NONE;
 }
 
 static PyObject *
@@ -1061,8 +1026,7 @@ Context_command(ContextObject *self, PyObject *args)
 	hexchat_set_context(ph, self->context);
 	hexchat_command(ph, text);
 	END_XCHAT_CALLS();
-	Py_INCREF(Py_None);
-	return Py_None;
+	Py_RETURN_NONE;
 }
 
 static PyObject *
@@ -1075,8 +1039,7 @@ Context_prnt(ContextObject *self, PyObject *args)
 	hexchat_set_context(ph, self->context);
 	hexchat_print(ph, text);
 	END_XCHAT_CALLS();
-	Py_INCREF(Py_None);
-	return Py_None;
+	Py_RETURN_NONE;
 }
 
 static PyObject *
@@ -1121,8 +1084,7 @@ Context_get_info(ContextObject *self, PyObject *args)
 	info = hexchat_get_info(ph, name);
 	END_XCHAT_CALLS();
 	if (info == NULL) {
-		Py_INCREF(Py_None);
-		return Py_None;
+		Py_RETURN_NONE;
 	}
 	return PyUnicode_FromString(info);
 }
@@ -1405,11 +1367,7 @@ static Hook *
 Plugin_AddHook(int type, PyObject *plugin, PyObject *callback,
 	       PyObject *userdata, char *name, void *data)
 {
-	Hook *hook = (Hook *) g_malloc(sizeof(Hook));
-	if (hook == NULL) {
-		PyErr_NoMemory();
-		return NULL;
-	}
+	Hook *hook = g_new(Hook, 1);
 	hook->type = type;
 	hook->plugin = plugin;
 	Py_INCREF(callback);
@@ -1463,8 +1421,7 @@ Plugin_RemoveHook(PyObject *plugin, Hook *hook)
 					       hook));
 		Py_DECREF(hook->callback);
 		Py_DECREF(hook->userdata);
-		if (hook->name)
-			g_free(hook->name);
+		g_free(hook->name);
 		g_free(hook);
 	}
 }
@@ -1483,8 +1440,7 @@ Plugin_RemoveAllHooks(PyObject *plugin)
 		}
 		Py_DECREF(hook->callback);
 		Py_DECREF(hook->userdata);
-		if (hook->name)
-			g_free(hook->name);
+		g_free(hook->name);
 		g_free(hook);
 		list = list->next;
 	}
@@ -1713,8 +1669,7 @@ Module_hexchat_command(PyObject *self, PyObject *args)
 	BEGIN_XCHAT_CALLS(RESTORE_CONTEXT|ALLOW_THREADS);
 	hexchat_command(ph, text);
 	END_XCHAT_CALLS();
-	Py_INCREF(Py_None);
-	return Py_None;
+	Py_RETURN_NONE;
 }
 
 static PyObject *
@@ -1726,8 +1681,7 @@ Module_xchat_prnt(PyObject *self, PyObject *args)
 	BEGIN_XCHAT_CALLS(RESTORE_CONTEXT|ALLOW_THREADS);
 	hexchat_print(ph, text);
 	END_XCHAT_CALLS();
-	Py_INCREF(Py_None);
-	return Py_None;
+	Py_RETURN_NONE;
 }
 
 static PyObject *
@@ -1770,8 +1724,7 @@ Module_hexchat_get_info(PyObject *self, PyObject *args)
 	info = hexchat_get_info(ph, name);
 	END_XCHAT_CALLS();
 	if (info == NULL) {
-		Py_INCREF(Py_None);
-		return Py_None;
+		Py_RETURN_NONE;
 	}
 	if (strcmp (name, "gtkwin_ptr") == 0)
 		return PyUnicode_FromFormat("%p", info); /* format as pointer */
@@ -1824,8 +1777,7 @@ Module_hexchat_get_context(PyObject *self, PyObject *args)
 		return NULL;
 	ctxobj = Context_FromContext(Plugin_GetContext(plugin));
 	if (ctxobj == NULL) {
-		Py_INCREF(Py_None);
-		return Py_None;
+		Py_RETURN_NONE;
 	}
 	return ctxobj;
 }
@@ -1842,8 +1794,7 @@ Module_hexchat_find_context(PyObject *self, PyObject *args, PyObject *kwargs)
 		return NULL;
 	ctxobj = Context_FromServerAndChannel(server, channel);
 	if (ctxobj == NULL) {
-		Py_INCREF(Py_None);
-		return Py_None;
+		Py_RETURN_NONE;
 	}
 	return ctxobj;
 }
@@ -1889,7 +1840,7 @@ Module_hexchat_pluginpref_get(PyObject *self, PyObject *args)
 	if (!PyArg_ParseTuple(args, "s:get_pluginpref", &var))
 		return NULL;
 		
-	// This will always return numbers as integers.
+	/* This will always return numbers as integers. */
 	BEGIN_XCHAT_CALLS(NONE);
 	result = hexchat_pluginpref_get_str(prefph, var, retstr);
 	END_XCHAT_CALLS();
@@ -2223,8 +2174,7 @@ Module_hexchat_unhook(PyObject *self, PyObject *args)
 		Plugin_RemoveHook(plugin, hook);
 	}	
 
-	Py_INCREF(Py_None);
-	return Py_None;
+	Py_RETURN_NONE;
 }
 
 static PyObject *
@@ -2532,11 +2482,8 @@ IInterp_Exec(char *command)
 	}
 	d = PyModule_GetDict(m);
 	len = strlen(command);
-	buffer = (char *) g_malloc(len+2);
-	if (buffer == NULL) {
-		hexchat_print(ph, "Not enough memory for command buffer");
-		goto fail;
-	}
+
+	buffer = g_malloc(len + 2);
 	memcpy(buffer, command, len);
 	buffer[len] = '\n';
 	buffer[len+1] = 0;
@@ -2782,6 +2729,7 @@ hexchat_plugin_init(hexchat_plugin *plugin_handle,
 	Py_Initialize();
 	PySys_SetArgv(1, argv);
 
+	xchatout_buffer = g_string_new (NULL);
 	xchatout = XChatOut_New();
 	if (xchatout == NULL) {
 		hexchat_print(ph, "Can't allocate xchatout object");
@@ -2852,10 +2800,8 @@ hexchat_plugin_deinit()
 	plugin_list = NULL;
 
 	/* Reset xchatout buffer. */
-	g_free(xchatout_buffer);
+	g_string_free (xchatout_buffer, TRUE);
 	xchatout_buffer = NULL;
-	xchatout_buffer_size = 0;
-	xchatout_buffer_pos = 0;
 
 	if (interp_plugin) {
 		Py_DECREF(interp_plugin);