Cleanup some GG utility functions

Mon, 21 Sep 2020 20:23:22 -0500

author
Elliott Sales de Andrade <quantum.analyst@gmail.com>
date
Mon, 21 Sep 2020 20:23:22 -0500
changeset 40538
222423055d93
parent 40537
fbf29150c28c
child 40539
2941deda6d8d

Cleanup some GG utility functions

* Remove unused `ggp_int64_compare`.
* Inline `ggp_list_copy_to_slist_deep`.
It's only used once.
* Rewrite `ggp_message_format_to_gg` using `GString`.
This may not be the best, but it's better than the implementation with `GList`.
* Use a string list pref to save gg server history.
This removes the need for gg to do the conversion to/from plain strings itself,
and thus removes the need for the `ggp_str*_list` functions.
* Embed `ggp_list_truncate` directly where used, and in simplified form.
* Embed `ggp_password_validate` at its caller.
There's only one use of it.

Testing Done:
Compile only.

Reviewed at https://reviews.imfreedom.org/r/117/

libpurple/protocols/gg/message-prpl.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/servconn.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/utils.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/utils.h file | annotate | diff | comparison | revisions
libpurple/protocols/gg/validator.c file | annotate | diff | comparison | revisions
--- a/libpurple/protocols/gg/message-prpl.c	Mon Sep 21 20:15:51 2020 -0500
+++ b/libpurple/protocols/gg/message-prpl.c	Mon Sep 21 20:23:22 2020 -0500
@@ -309,13 +309,14 @@
 	msg->text = text_new;
 }
 
-gchar * ggp_message_format_to_gg(PurpleConversation *conv, const gchar *text)
+gchar *
+ggp_message_format_to_gg(PurpleConversation *conv, const gchar *text)
 {
 	gchar *text_new, *tmp;
-	GList *rt = NULL; /* reformatted text */
+	GString *reformatted_text = NULL;
 	GMatchInfo *match;
 	guint pos = 0;
-	GList *pending_objects = NULL;
+	GString *pending_objects = NULL;
 	GList *font_stack = NULL;
 	static int html_sizes_pt[7] = { 7, 8, 9, 10, 12, 14, 16 };
 
@@ -346,6 +347,8 @@
 	text_new = g_strdup_printf("%s<eom></eom>", text_new);
 	g_free(tmp);
 
+	reformatted_text = g_string_new(NULL);
+	pending_objects = g_string_new(NULL);
 	g_regex_match(global_data.re_html_tag, text_new, 0, &match);
 	while (g_match_info_matches(match)) {
 		int m_start, m_end, m_pos;
@@ -370,76 +373,80 @@
 				"uknown tag %s\n", tag_str);
 		}
 
-		/* closing *all* formatting-related tags (GG11 weirness)
+		/* closing *all* formatting-related tags (GG11 weirdness)
 		 * and adding pending objects */
-		if ((text_before && (font_changed || pending_objects)) ||
-			(tag == GGP_HTML_TAG_EOM && tag_close))
-		{
+		if ((text_before && (font_changed || pending_objects->len > 0)) ||
+		    (tag == GGP_HTML_TAG_EOM && tag_close)) {
 			font_changed = FALSE;
 			if (in_any_tag) {
 				in_any_tag = FALSE;
-				if (font_current->s && !GGP_GG11_FORCE_COMPAT)
-					rt = g_list_prepend(rt,
-						g_strdup("</s>"));
-				if (font_current->u)
-					rt = g_list_prepend(rt,
-						g_strdup("</u>"));
-				if (font_current->i)
-					rt = g_list_prepend(rt,
-						g_strdup("</i>"));
-				if (font_current->b)
-					rt = g_list_prepend(rt,
-						g_strdup("</b>"));
-				rt = g_list_prepend(rt, g_strdup("</span>"));
+				if (font_current->s && !GGP_GG11_FORCE_COMPAT) {
+					g_string_append(reformatted_text, "</s>");
+				}
+				if (font_current->u) {
+					g_string_append(reformatted_text, "</u>");
+				}
+				if (font_current->i) {
+					g_string_append(reformatted_text, "</i>");
+				}
+				if (font_current->b) {
+					g_string_append(reformatted_text, "</b>");
+				}
+				g_string_append(reformatted_text, "</span>");
 			}
-			if (pending_objects) {
-				rt = g_list_concat(pending_objects, rt);
-				pending_objects = NULL;
+			if (pending_objects->len > 0) {
+				g_string_append(reformatted_text, pending_objects->str);
+				g_string_truncate(pending_objects, 0);
 			}
 		}
 
 		/* opening formatting-related tags again */
 		if (text_before && !in_any_tag) {
-			gchar *style;
-			GList *styles = NULL;
 			gboolean has_size = (font_new->size > 0 &&
 				font_new->size <= 7 && font_new->size != 3);
+			gboolean has_style =
+			        has_size || font_new->face ||
+			        (font_new->bgcolor >= 0 && !GGP_GG11_FORCE_COMPAT) ||
+			        font_new->color >= 0;
 
-			if (has_size)
-				styles = g_list_append(styles, g_strdup_printf(
-					"font-size:%dpt;",
-					html_sizes_pt[font_new->size - 1]));
-			if (font_new->face)
-				styles = g_list_append(styles, g_strdup_printf(
-					"font-family:%s;", font_new->face));
-			if (font_new->bgcolor >= 0 && !GGP_GG11_FORCE_COMPAT)
-				styles = g_list_append(styles, g_strdup_printf(
-					"background-color:#%06x;",
-					font_new->bgcolor));
-			if (font_new->color >= 0)
-				styles = g_list_append(styles, g_strdup_printf(
-					"color:#%06x;", font_new->color));
+			if (has_style) {
+				g_string_append(reformatted_text, "<span style=\"");
 
-			if (styles) {
-				gchar *combined = ggp_strjoin_list(" ", styles);
-				g_list_free_full(styles, g_free);
-				style = g_strdup_printf(" style=\"%s\"",
-					combined);
-				g_free(combined);
-			} else
-				style = g_strdup("");
-			rt = g_list_prepend(rt, g_strdup_printf("<span%s>",
-				style));
-			g_free(style);
+				if (has_size) {
+					g_string_append_printf(reformatted_text, "font-size:%dpt;",
+					                       html_sizes_pt[font_new->size - 1]);
+				}
+				if (font_new->face) {
+					g_string_append_printf(reformatted_text, "font-family:%s;",
+					                       font_new->face);
+				}
+				if (font_new->bgcolor >= 0 && !GGP_GG11_FORCE_COMPAT) {
+					g_string_append_printf(reformatted_text,
+					                       "background-color:#%06x;",
+					                       font_new->bgcolor);
+				}
+				if (font_new->color >= 0) {
+					g_string_append_printf(reformatted_text, "color:#%06x;",
+					                       font_new->color);
+				}
 
-			if (font_new->b)
-				rt = g_list_prepend(rt, g_strdup("<b>"));
-			if (font_new->i)
-				rt = g_list_prepend(rt, g_strdup("<i>"));
-			if (font_new->u)
-				rt = g_list_prepend(rt, g_strdup("<u>"));
-			if (font_new->s && !GGP_GG11_FORCE_COMPAT)
-				rt = g_list_prepend(rt, g_strdup("<s>"));
+				g_string_append(reformatted_text, "\">");
+			} else {
+				g_string_append(reformatted_text, "<span>");
+			}
+
+			if (font_new->b) {
+				g_string_append(reformatted_text, "<b>");
+			}
+			if (font_new->i) {
+				g_string_append(reformatted_text, "<i>");
+			}
+			if (font_new->u) {
+				g_string_append(reformatted_text, "<u>");
+			}
+			if (font_new->s && !GGP_GG11_FORCE_COMPAT) {
+				g_string_append(reformatted_text, "<s>");
+			}
 
 			ggp_font_free(font_current);
 			font_current = font_new;
@@ -448,8 +455,8 @@
 			in_any_tag = TRUE;
 		}
 		if (text_before) {
-			rt = g_list_prepend(rt,
-				g_strndup(text_new + pos, m_start - pos));
+			g_string_append_len(reformatted_text, text_new + pos,
+			                    m_start - pos);
 		}
 
 		/* set formatting of a following text */
@@ -480,10 +487,9 @@
 				res = ggp_image_prepare(conv, image, &id);
 
 			if (res == GGP_IMAGE_PREPARE_OK) {
-				pending_objects = g_list_prepend(
-					pending_objects, g_strdup_printf(
-					"<img name=\"" GGP_IMAGE_ID_FORMAT
-					"\">", id));
+				g_string_append_printf(pending_objects,
+				                       "<img name=\"" GGP_IMAGE_ID_FORMAT "\">",
+				                       id);
 			} else if (res == GGP_IMAGE_PREPARE_TOO_BIG) {
 				purple_conversation_write_system_message(conv,
 					_("Image is too large, please try "
@@ -541,9 +547,9 @@
 
 			font_stack = g_list_prepend(font_stack,
 				ggp_font_clone(font_new));
-			if (tag == GGP_HTML_TAG_DIV)
-				pending_objects = g_list_prepend(
-					pending_objects, g_strdup("<br>"));
+			if (tag == GGP_HTML_TAG_DIV) {
+				g_string_append(pending_objects, "<br>");
+			}
 
 			style = g_hash_table_lookup(attribs, "style");
 			if (style)
@@ -583,11 +589,9 @@
 			else
 				font_new = ggp_font_clone(font_base);
 		} else if (tag == GGP_HTML_TAG_BR) {
-			pending_objects = g_list_prepend(pending_objects,
-				g_strdup("<br>"));
+			g_string_append(pending_objects, "<br>");
 		} else if (tag == GGP_HTML_TAG_HR) {
-			pending_objects = g_list_prepend(pending_objects,
-				g_strdup("<br><span>---</span><br>"));
+			g_string_append(pending_objects, "<br><span>---</span><br>");
 		} else if (tag == GGP_HTML_TAG_A || tag == GGP_HTML_TAG_EOM) {
 			/* do nothing */
 		} else if (tag == GGP_HTML_TAG_UNKNOWN) {
@@ -616,10 +620,9 @@
 	g_list_free_full(font_stack, ggp_font_free);
 
 	/* combining reformatted text info one string */
-	rt = g_list_reverse(rt);
 	g_free(text_new);
-	text_new = ggp_strjoin_list("", rt);
-	g_list_free_full(rt, g_free);
+	g_string_free(pending_objects, TRUE);
+	text_new = g_string_free(reformatted_text, FALSE);
 
 	if (purple_debug_is_verbose())
 		purple_debug_info("gg", "reformatted text: [%s]", text_new);
--- a/libpurple/protocols/gg/servconn.c	Mon Sep 21 20:15:51 2020 -0500
+++ b/libpurple/protocols/gg/servconn.c	Mon Sep 21 20:23:22 2020 -0500
@@ -44,14 +44,18 @@
 
 void ggp_servconn_setup(PurpleAccountOption *server_option)
 {
-	purple_prefs_add_string(GGP_SERVCONN_HISTORY_PREF, "");
+	GList *extra;
+	purple_prefs_add_string_list(GGP_SERVCONN_HISTORY_PREF, NULL);
 
 	global_data.server_option = server_option;
-	global_data.server_history = ggp_strsplit_list(purple_prefs_get_string(
-		GGP_SERVCONN_HISTORY_PREF), ";", GGP_SERVCONN_HISTORY_MAXLEN + 1);
-	global_data.server_history = ggp_list_truncate(
-		global_data.server_history, GGP_SERVCONN_HISTORY_MAXLEN,
-		g_free);
+	global_data.server_history =
+	        purple_prefs_get_string_list(GGP_SERVCONN_HISTORY_PREF);
+	extra = g_list_nth(global_data.server_history, GGP_SERVCONN_HISTORY_MAXLEN);
+	if (extra != NULL) {
+		/* Truncate the list to the maximum. */
+		extra->prev->next = NULL;
+		g_list_free_full(extra, g_free);
+	}
 
 	purple_account_option_string_set_hints(global_data.server_option,
 		ggp_servconn_get_servers());
@@ -65,7 +69,6 @@
 void ggp_servconn_add_server(const gchar *server)
 {
 	GList *old_entry;
-	gchar *joined;
 
 	old_entry = g_list_find_custom(global_data.server_history, server,
 		(GCompareFunc)g_strcmp0);
@@ -77,21 +80,32 @@
 
 	global_data.server_history = g_list_prepend(global_data.server_history,
 		g_strdup(server));
-	global_data.server_history = ggp_list_truncate(
-		global_data.server_history, GGP_SERVCONN_HISTORY_MAXLEN,
-		g_free);
+	old_entry =
+	        g_list_nth(global_data.server_history, GGP_SERVCONN_HISTORY_MAXLEN);
+	if (old_entry != NULL) {
+		/* Truncate the list to the maximum. */
+		old_entry->prev->next = NULL;
+		g_list_free_full(old_entry, g_free);
+	}
 
-	joined = ggp_strjoin_list(";", global_data.server_history);
-	purple_prefs_set_string(GGP_SERVCONN_HISTORY_PREF, joined);
-	g_free(joined);
+	purple_prefs_set_string_list(GGP_SERVCONN_HISTORY_PREF,
+	                             global_data.server_history);
 	purple_account_option_string_set_hints(global_data.server_option,
 		ggp_servconn_get_servers());
 }
 
-GSList * ggp_servconn_get_servers(void)
+GSList *
+ggp_servconn_get_servers(void)
 {
-	return ggp_list_copy_to_slist_deep(global_data.server_history,
-		(GCopyFunc)g_strdup, NULL);
+	GSList *new_list = NULL;
+	GList *it;
+
+	it = g_list_first(global_data.server_history);
+	while (it) {
+		new_list = g_slist_append(new_list, g_strdup(it->data));
+		it = g_list_next(it);
+	}
+	return new_list;
 }
 
 void
--- a/libpurple/protocols/gg/utils.c	Mon Sep 21 20:15:51 2020 -0500
+++ b/libpurple/protocols/gg/utils.c	Mon Sep 21 20:23:22 2020 -0500
@@ -102,15 +102,6 @@
 	return ggp_convert(src, "CP1250", "UTF-8");
 }
 
-gboolean ggp_password_validate(const gchar *password)
-{
-	const int len = strlen(password);
-	if (len < 6 || len > 15)
-		return FALSE;
-	return g_regex_match_simple("^[ a-zA-Z0-9~`!@#$%^&*()_+=[\\]{};':\",./?"
-		"<>\\\\|-]+$", password, 0, 0);
-}
-
 gchar * ggp_utf8_strndup(const gchar *str, gsize n)
 {
 	size_t raw_len;
@@ -134,60 +125,6 @@
 	return g_strndup(str, raw_len);
 }
 
-GSList * ggp_list_copy_to_slist_deep(GList *list, GCopyFunc func,
-	gpointer user_data)
-{
-	GSList *new_list = NULL;
-	GList *it;
-
-	it = g_list_first(list);
-	while (it) {
-		new_list = g_slist_append(new_list, func(it->data, user_data));
-		it = g_list_next(it);
-	}
-	return new_list;
-}
-
-GList * ggp_strsplit_list(const gchar *string, const gchar *delimiter,
-	gint max_tokens)
-{
-	gchar **splitted, **it;
-	GList *list = NULL;
-
-	it = splitted = g_strsplit(string, delimiter, max_tokens);
-	while (*it) {
-		list = g_list_append(list, *it);
-		it++;
-	}
-	g_free(splitted);
-
-	return list;
-}
-
-gchar * ggp_strjoin_list(const gchar *separator, GList *list)
-{
-	gchar **str_array;
-	gchar *joined;
-	gint list_len, i;
-	GList *it;
-
-	list_len = g_list_length(list);
-	str_array = g_new(gchar*, list_len + 1);
-
-	it = g_list_first(list);
-	i = 0;
-	while (it) {
-		str_array[i++] = it->data;
-		it = g_list_next(it);
-	}
-	str_array[i] = NULL;
-
-	joined = g_strjoinv(separator, str_array);
-	g_free(str_array);
-
-	return joined;
-}
-
 const gchar * ggp_ipv4_to_str(uint32_t raw_ip)
 {
 	static gchar buff[INET_ADDRSTRLEN];
@@ -202,16 +139,6 @@
 	return buff;
 }
 
-GList * ggp_list_truncate(GList *list, guint length, GDestroyNotify free_func)
-{
-	while (g_list_length(list) > length) {
-		GList *last = g_list_last(list);
-		free_func(last->data);
-		list = g_list_delete_link(list, last);
-	}
-	return list;
-}
-
 gchar * ggp_free_if_equal(gchar *str, const gchar *pattern)
 {
 	if (g_strcmp0(str, pattern) == 0) {
@@ -228,18 +155,6 @@
 	return ptr;
 }
 
-gint ggp_int64_compare(gconstpointer _a, gconstpointer _b)
-{
-	const int64_t *ap = _a, *bp = _b;
-	const int64_t a = *ap, b = *bp;
-	if (a == b)
-		return 0;
-	if (a < b)
-		return -1;
-	else
-		return 1;
-}
-
 JsonParser * ggp_json_parse(const gchar *data)
 {
 	JsonParser *parser;
--- a/libpurple/protocols/gg/utils.h	Mon Sep 21 20:15:51 2020 -0500
+++ b/libpurple/protocols/gg/utils.h	Mon Sep 21 20:23:22 2020 -0500
@@ -81,28 +81,14 @@
  */
 gchar * ggp_convert_from_cp1250(const gchar *src);
 
-gboolean ggp_password_validate(const gchar *password);
-
 gchar * ggp_utf8_strndup(const gchar *str, gsize n);
 
-GSList * ggp_list_copy_to_slist_deep(GList *list, GCopyFunc func,
-	gpointer user_data);
-
-GList * ggp_strsplit_list(const gchar *string, const gchar *delimiter,
-	gint max_tokens);
-
-gchar * ggp_strjoin_list(const gchar *separator, GList *list);
-
 const gchar * ggp_ipv4_to_str(uint32_t raw_ip);
 
-GList * ggp_list_truncate(GList *list, guint length, GDestroyNotify free_func);
-
 gchar * ggp_free_if_equal(gchar *str, const gchar *pattern);
 
 uint64_t * ggp_uint64dup(uint64_t val);
 
-gint ggp_int64_compare(gconstpointer a, gconstpointer b);
-
 JsonParser * ggp_json_parse(const gchar *data);
 
 #endif /* PURPLE_GG_UTILS_H */
--- a/libpurple/protocols/gg/validator.c	Mon Sep 21 20:15:51 2020 -0500
+++ b/libpurple/protocols/gg/validator.c	Mon Sep 21 20:23:22 2020 -0500
@@ -44,8 +44,16 @@
 
 	value = purple_request_field_string_get_value(field);
 
-	if (value != NULL && ggp_password_validate(value))
-		return TRUE;
+	if (value != NULL) {
+		size_t len = strlen(value);
+		if (6 <= len && len <= 15) {
+			if (g_regex_match_simple(
+			            "^[ a-zA-Z0-9~`!@#$%^&*()_+=[\\]{};':\",./?<>\\\\|-]+$",
+			            value, 0, 0)) {
+				return TRUE;
+			}
+		}
+	}
 
 	if (errmsg)
 		*errmsg = g_strdup(_("Password can contain 6-15 alphanumeric characters"));

mercurial