changeset 28369:5ff49aa05439

Don't put stuff into a linked list only to iterate through the linked list immediately afterward. Instead, just deal with the three items on the fly. So much simpler.
author Mark Doliner <mark@kingant.net>
date Thu, 20 Aug 2009 02:15:00 +0000
parents 8b68373bf393
children df76369ffde4 b168718d1072
files libpurple/protocols/yahoo/util.c libpurple/tests/test_yahoo_util.c
diffstat 2 files changed, 47 insertions(+), 98 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/yahoo/util.c	Thu Aug 20 01:51:37 2009 +0000
+++ b/libpurple/protocols/yahoo/util.c	Thu Aug 20 02:15:00 2009 +0000
@@ -669,23 +669,6 @@
 #define POINT_SIZE(x) (_point_sizes [MIN ((x > 0 ? x : 1), MAX_FONT_SIZE) - 1])
 static const gint _point_sizes [] = { 8, 10, 12, 14, 20, 30, 40 };
 
-enum fontattr_type
-{
-	FATYPE_SIZE,
-	FATYPE_COLOR,
-	FATYPE_FACE
-};
-
-typedef struct
-{
-	enum fontattr_type type;
-	union {
-		int size;
-		char *color;
-		char *face;
-	} u;
-} fontattr;
-
 typedef struct
 {
 	gboolean bold;
@@ -697,15 +680,6 @@
 	char *font_color;
 } CurrentMsgState;
 
-static void fontattr_free(fontattr *f)
-{
-	if (f->type == FATYPE_COLOR)
-		g_free(f->u.color);
-	else if (f->type == FATYPE_FACE)
-		g_free(f->u.face);
-	g_free(f);
-}
-
 static void yahoo_htc_list_cleanup(GSList *l)
 {
 	while (l != NULL) {
@@ -721,80 +695,38 @@
 	const char *end;
 	GData *attributes;
 	const char *attribute;
-	GSList *fontattrs = NULL;
 	gboolean needendtag;
-	fontattr *f;
 	GString *tmp;
 
 	purple_markup_find_tag(tag_name, tag, &start, &end, &attributes);
 
+	needendtag = FALSE;
+	tmp = g_string_new(NULL);
+
+	attribute = g_datalist_get_data(&attributes, "color");
+	if (attribute != NULL) {
+		g_string_append(tmp, *colors ? (*colors)->data : "\033[#000000m");
+		g_string_append_printf(dest, "\033[%sm", attribute);
+		*colors = g_slist_prepend(*colors,
+				g_strdup_printf("\033[%sm", attribute));
+	}
+
 	attribute = g_datalist_get_data(&attributes, "face");
 	if (attribute != NULL) {
-		f = g_new(fontattr, 1);
-		f->type = FATYPE_FACE;
-		f->u.face = g_strdup(attribute);
-		fontattrs = g_slist_prepend(fontattrs, f);
+		needendtag = TRUE;
+		g_string_append(dest, "<font ");
+		g_string_append_printf(dest, "face=\"%s\" ", attribute);
 	}
 
 	attribute = g_datalist_get_data(&attributes, "size");
 	if (attribute != NULL) {
-		f = g_new(fontattr, 1);
-		f->type = FATYPE_SIZE;
-		f->u.size = POINT_SIZE(strtol(attribute, NULL, 10));
-		fontattrs = g_slist_prepend(fontattrs, f);
-	}
-
-	attribute = g_datalist_get_data(&attributes, "color");
-	if (attribute != NULL) {
-		f = g_new(fontattr, 1);
-		f->type = FATYPE_COLOR;
-		f->u.color = g_strdup(attribute);
-		fontattrs = g_slist_prepend(fontattrs, f);
-	}
-
-	g_datalist_clear(&attributes);
-
-	if (fontattrs == NULL)
-		/* No recognized attributes in the font tag.  Nothing to do. */
-		return;
-
-	needendtag = FALSE;
-	tmp = g_string_new(NULL);
-
-	while (fontattrs != NULL) {
-		f = fontattrs->data;
-		fontattrs = g_slist_delete_link(fontattrs, fontattrs);
+		if (!needendtag) {
+			needendtag = TRUE;
+			g_string_append(dest, "<font ");
+		}
 
-		switch (f->type) {
-		case FATYPE_COLOR:
-			if (needendtag) {
-				g_string_append(tmp, "</font>");
-				dest->str[dest->len-1] = '>';
-			}
-
-			g_string_append(tmp, *colors ? (*colors)->data : "\033[#000000m");
-			g_string_append_printf(dest, "\033[%sm", f->u.color);
-			*colors = g_slist_prepend(*colors,
-					g_strdup_printf("\033[%sm", f->u.color));
-			break;
-		case FATYPE_FACE:
-			if (!needendtag) {
-				needendtag = TRUE;
-				g_string_append(dest, "<font ");
-			}
-
-			g_string_append_printf(dest, "face=\"%s\" ", f->u.face);
-			break;
-		case FATYPE_SIZE:
-			if (!needendtag) {
-				needendtag = TRUE;
-				g_string_append(dest, "<font ");
-			}
-
-			g_string_append_printf(dest, "size=\"%d\" ", f->u.size);
-			break;
-		}
-		fontattr_free(f);
+		g_string_append_printf(dest, "size=\"%d\" ",
+				POINT_SIZE(strtol(attribute, NULL, 10)));
 	}
 
 	if (needendtag) {
@@ -805,12 +737,21 @@
 		*tags = g_slist_prepend(*tags, tmp->str);
 		g_string_free(tmp, FALSE);
 	}
+
+	g_datalist_clear(&attributes);
 }
 
 char *yahoo_html_to_codes(const char *src)
 {
 	GSList *colors = NULL;
+
+	/**
+	 * A stack of char*s where each char* is the string that should be
+	 * appended to dest in order to close all the tags that were opened
+	 * by a <font> tag.
+	 */
 	GSList *tags = NULL;
+
 	size_t src_len;
 	int i, j;
 	GString *dest;
--- a/libpurple/tests/test_yahoo_util.c	Thu Aug 20 01:51:37 2009 +0000
+++ b/libpurple/tests/test_yahoo_util.c	Thu Aug 20 02:15:00 2009 +0000
@@ -127,16 +127,6 @@
 	assert_string_equal_free("plain &",
 			yahoo_html_to_codes("plain &amp;"));
 
-	/* link */
-	assert_string_equal_free("http://pidgin.im/",
-			yahoo_html_to_codes("<A HREF=\"http://pidgin.im/\">http://pidgin.im/</A>"));
-	assert_string_equal_free("mark@example.com",
-			yahoo_html_to_codes("<A HREF=\"mailto:mark@example.com\">mark@example.com</A>"));
-#if 0
-	assert_string_equal_free("http://pidgin.im/",
-			yahoo_html_to_codes("<A HREF=\"http://pidgin.im/\">Pidgin</A>"));
-#endif
-
 	/* bold/italic/underline */
 	assert_string_equal_free("\x1B[1mbold\x1B[x1m",
 			yahoo_html_to_codes("<b>bold</b>"));
@@ -153,6 +143,24 @@
 	assert_string_equal_free("\x1B[1mbold \x1B[2mbolditalic\x1B[x2m\x1B[x1m\x1B[2m \x1B[4mitalicunderline\x1B[x4m\x1B[x2m",
 			yahoo_html_to_codes("<b>bold <i>bolditalic</i></b><i> <u>italicunderline</u></i>"));
 
+	/* link */
+	assert_string_equal_free("http://pidgin.im/",
+			yahoo_html_to_codes("<A HREF=\"http://pidgin.im/\">http://pidgin.im/</A>"));
+	assert_string_equal_free("mark@example.com",
+			yahoo_html_to_codes("<A HREF=\"mailto:mark@example.com\">mark@example.com</A>"));
+#if 0
+	assert_string_equal_free("http://pidgin.im/",
+			yahoo_html_to_codes("<A HREF=\"http://pidgin.im/\">Pidgin</A>"));
+#endif
+
+	/* font nothing */
+	assert_string_equal_free("nothing",
+			yahoo_html_to_codes("<font>nothing</font>"));
+
+	/* font color */
+	assert_string_equal_free("\x1B[#E71414mred\x1B[#000000m",
+			yahoo_html_to_codes("<font color=\"#E71414\">red</font>"));
+
 	/* font size */
 	assert_string_equal_free("<font size=\"10\">test</font>",
 			yahoo_html_to_codes("<font size=\"2\">test</font>"));