# HG changeset patch
# Node ID ca54d66f6c96
# Parent  c4a96b5eecba
diff --git a/ChangeLog.API b/ChangeLog.API
--- a/ChangeLog.API
+++ b/ChangeLog.API
@@ -509,6 +509,7 @@
 		  purple_ipv6_address_is_valid. Use g_hostname_is_ip_address()
 		  or #GInetAddress instead.
 		* purple_markup_extract_info_field
+		* purple_markup_find_tag
 		* purple_markup_get_css_property
 		* purple_markup_is_rtl
 		* purple_marshal_BOOLEAN__INT_POINTER
diff --git a/libpurple/purplemarkup.h b/libpurple/purplemarkup.h
--- a/libpurple/purplemarkup.h
+++ b/libpurple/purplemarkup.h
@@ -47,27 +47,6 @@
 gchar *purple_markup_escape_text(const gchar *text, gssize length);
 
 /**
- * purple_markup_find_tag:
- * @needle:	  The name of the tag
- * @haystack:	  The null-delimited string to search in
- * @start:		  A pointer to the start of the tag if found
- * @end:		  A pointer to the end of the tag if found
- * @attributes:  The attributes, if the tag was found.  This should
- *                    be freed with g_datalist_clear().
- *
- * Finds an HTML tag matching the given name.
- *
- * This locates an HTML tag's start and end, and stores its attributes
- * in a GData hash table. The names of the attributes are lower-cased
- * in the hash table, and the name of the tag is case insensitive.
- *
- * Returns: TRUE if the tag was found
- */
-gboolean purple_markup_find_tag(const char *needle, const char *haystack,
-							  const char **start, const char **end,
-							  GData **attributes);
-
-/**
  * purple_markup_html_to_xhtml:
  * @html:       The HTML markup.
  * @dest_xhtml: The destination XHTML output.
diff --git a/libpurple/purplemarkup.c b/libpurple/purplemarkup.c
--- a/libpurple/purplemarkup.c
+++ b/libpurple/purplemarkup.c
@@ -154,160 +154,6 @@
 	return pln;
 }
 
-gboolean
-purple_markup_find_tag(const char *needle, const char *haystack,
-					 const char **start, const char **end, GData **attributes)
-{
-	GData *attribs;
-	const char *cur = haystack;
-	char *name = NULL;
-	gboolean found = FALSE;
-	gboolean in_tag = FALSE;
-	gboolean in_attr = FALSE;
-	const char *in_quotes = NULL;
-	size_t needlelen;
-
-	g_return_val_if_fail(    needle != NULL, FALSE);
-	g_return_val_if_fail(   *needle != '\0', FALSE);
-	g_return_val_if_fail(  haystack != NULL, FALSE);
-	g_return_val_if_fail(     start != NULL, FALSE);
-	g_return_val_if_fail(       end != NULL, FALSE);
-	g_return_val_if_fail(attributes != NULL, FALSE);
-
-	needlelen = strlen(needle);
-	g_datalist_init(&attribs);
-
-	while (*cur && !found) {
-		if (in_tag) {
-			if (in_quotes) {
-				const char *close = cur;
-
-				while (*close && *close != *in_quotes)
-					close++;
-
-				/* if we got the close quote, store the value and carry on from    *
-				 * after it. if we ran to the end of the string, point to the NULL *
-				 * and we're outta here */
-				if (*close) {
-					/* only store a value if we have an attribute name */
-					if (name) {
-						size_t len = close - cur;
-						char *val = g_strndup(cur, len);
-
-						g_datalist_set_data_full(&attribs, name, val, g_free);
-						g_free(name);
-						name = NULL;
-					}
-
-					in_quotes = NULL;
-					cur = close + 1;
-				} else {
-					cur = close;
-				}
-			} else if (in_attr) {
-				const char *close = cur;
-
-				while (*close && *close != '>' && *close != '"' &&
-						*close != '\'' && *close != ' ' && *close != '=')
-					close++;
-
-				/* if we got the equals, store the name of the attribute. if we got
-				 * the quote, save the attribute and go straight to quote mode.
-				 * otherwise the tag closed or we reached the end of the string,
-				 * so we can get outta here */
-				switch (*close) {
-				case '"':
-				case '\'':
-					in_quotes = close;
-					/* fall through */
-				case '=':
-					{
-						size_t len = close - cur;
-
-						/* don't store a blank attribute name */
-						if (len) {
-							g_free(name);
-							name = g_ascii_strdown(cur, len);
-						}
-
-						in_attr = FALSE;
-						cur = close + 1;
-					}
-					break;
-				case ' ':
-				case '>':
-					in_attr = FALSE;
-					/* fall through */
-				default:
-					cur = close;
-					break;
-				}
-			} else {
-				switch (*cur) {
-				case ' ':
-					/* swallow extra spaces inside tag */
-					while (*cur && *cur == ' ') cur++;
-					in_attr = TRUE;
-					break;
-				case '>':
-					found = TRUE;
-					*end = cur;
-					break;
-				case '"':
-				case '\'':
-					in_quotes = cur;
-					/* fall through */
-				default:
-					cur++;
-					break;
-				}
-			}
-		} else {
-			/* if we hit a < followed by the name of our tag... */
-			if (*cur == '<' && !g_ascii_strncasecmp(cur + 1, needle, needlelen)) {
-				*start = cur;
-				cur = cur + needlelen + 1;
-
-				/* if we're pointing at a space or a >, we found the right tag. if *
-				 * we're not, we've found a longer tag, so we need to skip to the  *
-				 * >, but not being distracted by >s inside quotes.                */
-				if (*cur == ' ' || *cur == '>') {
-					in_tag = TRUE;
-				} else {
-					while (*cur && *cur != '"' && *cur != '\'' && *cur != '>') {
-						if (*cur == '"') {
-							cur++;
-							while (*cur && *cur != '"')
-								cur++;
-						} else if (*cur == '\'') {
-							cur++;
-							while (*cur && *cur != '\'')
-								cur++;
-						} else {
-							cur++;
-						}
-					}
-				}
-			} else {
-				cur++;
-			}
-		}
-	}
-
-	/* clean up any attribute name from a premature termination */
-	g_free(name);
-
-	if (found) {
-		*attributes = attribs;
-	} else {
-		*start = NULL;
-		*end = NULL;
-		*attributes = NULL;
-	}
-
-	return found;
-}
-
 struct purple_parse_tag {
 	char *src_tag;
 	char *dest_tag;
