balsa r8014 - in trunk: . libbalsa src



Author: PeterB
Date: Sat Dec  6 17:55:58 2008
New Revision: 8014
URL: http://svn.gnome.org/viewvc/balsa?rev=8014&view=rev

Log:
rewrite of libbalsa_insert_with_url

Modified:
   trunk/ChangeLog
   trunk/libbalsa/mime.c
   trunk/libbalsa/misc.h
   trunk/src/balsa-mime-widget-text.c
   trunk/src/sendmsg-window.c

Modified: trunk/libbalsa/mime.c
==============================================================================
--- trunk/libbalsa/mime.c	(original)
+++ trunk/libbalsa/mime.c	Sat Dec  6 17:55:58 2008
@@ -661,7 +661,7 @@
  * num_paras < 0, process the whole buffer. */
 
 /* Forward references: */
-static gboolean prescanner(const gchar * p);
+static gboolean prescanner(const gchar * p, guint len);
 static void mark_urls(GtkTextBuffer * buffer, GtkTextIter * iter,
                       GtkTextTag * tag, const gchar * p);
 #if USE_GREGEX
@@ -729,7 +729,7 @@
 	}
 
 	line = get_line(buffer, &start);
-	if (prescanner(line))
+	if (prescanner(line, strlen(line)))
 	    mark_urls(buffer, &start, url_tag, line);
 	g_free(line);
     }
@@ -741,6 +741,7 @@
           const gchar * line)
 {
     const gchar *p = line;
+    const gchar * const line_end = line + strlen(line);
 #if USE_GREGEX
     GRegex *url_reg = get_url_reg();
     GMatchInfo *url_match;
@@ -759,10 +760,9 @@
 
             p += end_pos;
         }
-        if (prescanner(p))
-            g_match_info_free(url_match);
-        else
+        if (!prescanner(p, line_end - p))
             break;
+        g_match_info_free(url_match);
     }
     g_match_info_free(url_match);
 #else                          /* USE_GREGEX */
@@ -779,7 +779,7 @@
         gtk_text_buffer_apply_tag(buffer, tag, &start, &end);
 
         p += url_match.rm_eo;
-        if (!prescanner(p))
+        if (!prescanner(p, line_end - p))
             break;
     }
 #endif                          /* USE_GREGEX */
@@ -801,14 +801,11 @@
  * returns TRUE if the line may contain an URL.
  */
 static gboolean
-prescanner(const gchar * s)
+prescanner(const gchar * s, guint len)
 {
-    gint left = strlen(s) - 6;
-
-    if (left <= 0)
-        return FALSE;
+    gint left = len - 5;
 
-    while (left--) {
+    while (--left > 0) {
         switch (tolower(*s++)) {
         case 'f':              /* ftp:/, ftps: */
             if (tolower(*s) == 't' &&
@@ -886,7 +883,10 @@
 {
     static struct url_regex_info info = {
         NULL,
-        "(%[0-9A-F]{2}|[-_.!~*';/?:@&=+$,#[:alnum:]]|[ \t]*[\r\n]+[ \t]*)+>",
+        "("
+        "%[0-9A-F]{2}|[-_.!~*';/?:@&=+$,#[:alnum:]]|[ \t]*[\r\n]+[ \t>]*"
+        ")+"
+        "(%[0-9A-F]{2}|[-_.!~*';/?:@&=+$,#[:alnum:]])>",
         __func__,
         "multiline url regex compilation failed"
     };
@@ -935,7 +935,10 @@
     if (!url_reg) {
         /* one-time compilation of a constant url_str expression */
         static const char url_str[] =
-	    "(%[0-9A-F]{2}|[-_.!~*';/?:@&=+$,#[:alnum:]]|[ \t]*[\r\n]+[ \t]*)+>";
+            "("
+            "%[0-9A-F]{2}|[-_.!~*';/?:@&=+$,#[:alnum:]]|[ \t]*[\r\n]+[ \t>]*"
+            ")+"
+            "(%[0-9A-F]{2}|[-_.!~*';/?:@&=+$,#[:alnum:]])>";
 
 	url_reg = g_new(regex_t, 1);
         if (regcomp(url_reg, url_str, REG_EXTENDED | REG_ICASE) != 0)
@@ -969,276 +972,240 @@
 gboolean
 libbalsa_insert_with_url(GtkTextBuffer * buffer,
                          const char *chars,
-			 const char *all_chars,
+                         guint len,
                          GtkTextTag * tag,
                          LibBalsaUrlInsertInfo *url_info)
 {
-    gchar *p, *buf;
-    const gchar *all_p;
     GtkTextIter iter;
+    GtkTextTagTable *table = gtk_text_buffer_get_tag_table(buffer);
+    GtkTextTag *url_tag = gtk_text_tag_table_lookup(table, "url");
+    gboolean match;
+#if USE_GREGEX
+    gint start_pos, end_pos;
+    GRegex *url_reg;
+    GMatchInfo *url_match;
+#else                           /* USE_GREGEX */
+    regex_t *url_reg;
+    regmatch_t url_match;
+#endif                          /* USE_GREGEX */
+    const gchar * const line_end = chars + len;
 
-    buf = p = g_strdup(chars);
-    all_p = all_chars;
     gtk_text_buffer_get_iter_at_mark(buffer, &iter,
                                      gtk_text_buffer_get_insert(buffer));
 
-    /* if there shouldn't be a callback for URL's we don't need to detect
-       them... */
-    if (url_info) {
-	GtkTextTagTable *table = gtk_text_buffer_get_tag_table(buffer);
-	GtkTextTag *url_tag = gtk_text_tag_table_lookup(table, "url");
-
-	if (url_info->ml_url) {
-	    gchar *url_end = strchr(p, '>');
-
-	    if (url_end) {
-		url_info->ml_url_buffer =
-		    g_string_append_len(url_info->ml_url_buffer, p, url_end - p);
-		gtk_text_buffer_insert_with_tags(buffer, &iter,
-						 url_info->ml_url_buffer->str, -1,
-						 url_tag, tag, NULL);
-		if (url_info->callback)
-		    url_info->callback(buffer, &iter, url_info->ml_url, url_info->callback_data);
-		g_string_free(url_info->ml_url_buffer, TRUE);
-		g_free(url_info->ml_url);
-		url_info->ml_url_buffer = NULL;
-		url_info->ml_url = NULL;
-		p = url_end;
-	    } else {
-		url_info->ml_url_buffer =
-		    g_string_append(url_info->ml_url_buffer, p);
-		url_info->ml_url_buffer =
-		    g_string_append_c(url_info->ml_url_buffer, '\n');
-		return TRUE;
-	    }
-	}
+    if (url_info->ml_url_buffer) {
+        const gchar *url_end;
+        gchar *url, *q, *r;
+
+        if (!(url_end = strchr(chars, '>')) || url_end >= line_end) {
+            g_string_append_len(url_info->ml_url_buffer, chars,
+                                line_end - chars);
+            g_string_append_c(url_info->ml_url_buffer, '\n');
+            return TRUE;
+        }
+
+        g_string_append_len(url_info->ml_url_buffer, chars,
+                            url_end - chars);
+        gtk_text_buffer_insert_with_tags(buffer, &iter,
+                                         url_info->ml_url_buffer->str,
+                                         url_info->ml_url_buffer->len,
+                                         url_tag, tag, NULL);
+        q = url = g_new(gchar, url_info->ml_url_buffer->len);
+        for (r = url_info->ml_url_buffer->str; *r; r++)
+            if (*r > ' ')
+                *q++ = *r;
+        url_info->callback(buffer, &iter, url, q - url,
+                           url_info->callback_data);
+        g_free(url);
+        g_string_free(url_info->ml_url_buffer, TRUE);
+        url_info->ml_url_buffer = NULL;
+        chars = url_end;
+    }
+
+    if (!prescanner(chars, line_end - chars)) {
+        gtk_text_buffer_insert_with_tags(buffer, &iter, chars,
+                                         line_end - chars, tag, NULL);
+        return FALSE;
+    }
 
-	if (prescanner(p)) {
-	    gint offset = 0;
 #if USE_GREGEX
-            GRegex *url_reg = get_url_reg();
-            GMatchInfo *url_match;
-            gboolean match = g_regex_match(url_reg, p, 0, &url_match);
-
-	    while (match) {
-		gchar *buf;
-		gchar *spc;
-                gint start_pos, end_pos;
-
-                if (!g_match_info_fetch_pos(url_match, 0, &start_pos, &end_pos))
-                    break;
-
-		if (start_pos > 0) {
-		    /* check if we hit a multi-line URL... (see RFC 1738) */
-		    if (all_p && (p[start_pos - 1] == '<' ||
-				  (start_pos > 4 &&
-				   !g_ascii_strncasecmp(p + start_pos - 5, "<URL:", 5)))) {
-			/* if the input is flowed, we will see a space at
-			 * url_match.rm_eo - in this case the complete remainder
-			 * of the ml uri should be in the passed buffer... */
-			if (url_info && url_info->buffer_is_flowed &&
-			    *(p + end_pos) == ' ') {
-                            GRegex *ml_flowed_url_reg = get_ml_flowed_url_reg();
-                            GMatchInfo *ml_url_match;
-                            gint ml_start_pos, ml_end_pos;
-
-                            if (g_regex_match(ml_flowed_url_reg,
-                                              all_chars + offset + end_pos,
-                                              0, &ml_url_match)
-                                && g_match_info_fetch_pos(ml_url_match, 0,
-                                                          &ml_start_pos,
-                                                          &ml_end_pos)
-                                && ml_start_pos == 0)
-                                end_pos += ml_end_pos - 1;
-                            g_match_info_free(ml_url_match);
-			} else if (!strchr(p + end_pos, '>')) {
-                            gint ml_end_pos;
-                            GRegex *ml_url_reg = get_ml_url_reg();
-                            GMatchInfo *ml_url_match;
-
-                            if (g_regex_match(ml_url_reg,
-                                              all_chars + offset + end_pos,
-                                              0, &ml_url_match)
-                                && g_match_info_fetch_pos(ml_url_match, 0,
-                                                          NULL,
-                                                          &ml_end_pos)) {
-				GString *ml_url = g_string_new("");
-				const gchar *ml_p =
-                                    all_chars + offset + start_pos;
-				gint ml_cnt;
-
-				ml_cnt = end_pos - start_pos + ml_end_pos - 1;
-				for (; ml_cnt; (ml_p++, ml_cnt--))
-				    if (*ml_p > ' ')
-					ml_url = g_string_append_c(ml_url, *ml_p);
-				url_info->ml_url = ml_url->str;
-				g_string_free(ml_url, FALSE);
-			    }
-                            g_match_info_free(ml_url_match);
-			}
-		    }
+    url_reg = get_url_reg();
+    match = g_regex_match(url_reg, chars, 0, &url_match)
+        && g_match_info_fetch_pos(url_match, 0, &start_pos, &end_pos)
+        && chars + start_pos < line_end;
 
-		    buf = g_strndup(p, start_pos);
-		    gtk_text_buffer_insert_with_tags(buffer, &iter,
-						     buf, -1, tag, NULL);
-		    g_free(buf);
-		}
+    while (match) {
+        gchar *spc;
 
-		if (url_info->ml_url) {
-		    url_info->ml_url_buffer = g_string_new(p + start_pos);
-		    url_info->ml_url_buffer =
-			g_string_append_c(url_info->ml_url_buffer, '\n');
-		    return TRUE;
-		}
+        gtk_text_buffer_insert_with_tags(buffer, &iter, chars,
+                                         start_pos, tag, NULL);
 
-		/* add the url - it /may/ contain spaces if the text is flowed */
-		buf = g_strndup(p + start_pos, end_pos - start_pos);
-		if ((spc = strchr(buf, ' '))) {
-		    GString *uri_real = g_string_new("");
-		    gchar * p = buf;
-
-		    while (spc) {
-			*spc = '\n';
-			g_string_append_len(uri_real, p, spc - p);
-			p = spc + 1;
-			spc = strchr(p, ' ');
-		    }
-		    g_string_append(uri_real, p);
-		    gtk_text_buffer_insert_with_tags(buffer, &iter, buf, -1,
-						     url_tag, tag, NULL);
-		    if (url_info->callback)
-			url_info->callback(buffer, &iter, uri_real->str, url_info->callback_data);
-		    g_string_free(uri_real, TRUE);
-		} else {
-		    gtk_text_buffer_insert_with_tags(buffer, &iter, buf, -1,
-						     url_tag, tag, NULL);
-
-		    /* remember the URL and its position within the text */
-		    if (url_info->callback)
-			url_info->callback(buffer, &iter, buf, url_info->callback_data);
-		}
-		g_free(buf);
+        /* check if we hit a multi-line URL... (see RFC 1738) */
+        if ((start_pos > 0 && (chars[start_pos - 1] == '<')) ||
+            (start_pos > 4 &&
+             !g_ascii_strncasecmp(chars + start_pos - 5, "<URL:", 5))) {
+            GMatchInfo *ml_url_match;
+            gint ml_start_pos, ml_end_pos;
+
+            /* if the input is flowed, we may see a space at
+             * url_match.rm_eo - in this case the complete remainder
+             * of the ml uri should be in the passed buffer... */
+            if (url_info->buffer_is_flowed && chars[end_pos] == ' ') {
+                if (g_regex_match(get_ml_flowed_url_reg(), chars + end_pos,
+                                  0, &ml_url_match)
+                    && g_match_info_fetch_pos(ml_url_match, 0,
+                                              &ml_start_pos, &ml_end_pos)
+                    && ml_start_pos == 0)
+                    end_pos += ml_end_pos - 1;
+                g_match_info_free(ml_url_match);
+            } else if (chars[end_pos] != '>') {
+                if (g_regex_match(get_ml_url_reg(), chars + end_pos,
+                                  0, &ml_url_match)
+                    && g_match_info_fetch_pos(ml_url_match, 0,
+                                              &ml_start_pos, NULL)
+                    && ml_start_pos == 0) {
+                    chars += start_pos;
+                    url_info->ml_url_buffer =
+                        g_string_new_len(chars, line_end - chars);
+                    g_string_append_c(url_info->ml_url_buffer, '\n');
+                }
+                g_match_info_free(ml_url_match);
+                if (url_info->ml_url_buffer)
+                    return TRUE;
+            }
+        }
 
-		p += end_pos;
-		offset += end_pos;
-		if (prescanner(p)) {
-                    g_match_info_free(url_match);
-                    match = g_regex_match(url_reg, p, 0, &url_match);
-                } else
-		    match = FALSE;
-	    }
+        /* add the url - it /may/ contain spaces if the text is flowed */
+        if ((spc = strchr(chars + start_pos, ' ')) && spc < chars + end_pos) {
+            GString *uri_real = g_string_new("");
+            gchar *q, *buf;
+
+            q = buf = g_strndup(chars + start_pos, end_pos - start_pos);
+            spc = buf + (spc - (chars + start_pos));
+            do {
+                *spc = '\n';
+                g_string_append_len(uri_real, q, spc - q);
+                q = spc + 1;
+            } while ((spc = strchr(q, ' ')));
+            g_string_append(uri_real, q);
+            gtk_text_buffer_insert_with_tags(buffer, &iter, buf, -1,
+                                             url_tag, tag, NULL);
+            g_free(buf);
+            url_info->callback(buffer, &iter,
+                               uri_real->str, uri_real->len,
+                               url_info->callback_data);
+            g_string_free(uri_real, TRUE);
+        } else {
+            gtk_text_buffer_insert_with_tags(buffer, &iter,
+                                             chars + start_pos,
+                                             end_pos - start_pos,
+                                             url_tag, tag, NULL);
+
+            /* remember the URL and its position within the text */
+            url_info->callback(buffer, &iter, chars + start_pos,
+                               end_pos - start_pos,
+                               url_info->callback_data);
+        }
+
+        chars += end_pos;
+        if (prescanner(chars, line_end - chars)) {
             g_match_info_free(url_match);
+            match = g_regex_match(url_reg, chars, 0, &url_match)
+                && g_match_info_fetch_pos(url_match, 0, &start_pos,
+                                          &end_pos)
+                && chars + start_pos < line_end;
+        } else
+            match = FALSE;
+    }
+    g_match_info_free(url_match);
 #else                           /* USE_GREGEX */
-	    regex_t *url_reg = get_url_reg();
-	    regmatch_t url_match;
-	    gboolean match = regexec(url_reg, p, 1, &url_match, 0) == 0;
-
-	    while (match) {
-		gchar *buf;
-		gchar *spc;
-                gint start_pos, end_pos;
-
-                start_pos = url_match.rm_so;
-                end_pos   = url_match.rm_eo;
-
-		if (start_pos > 0) {
-		    /* check if we hit a multi-line URL... (see RFC 1738) */
-		    if (all_p && (p[start_pos - 1] == '<' ||
-				  (start_pos > 4 &&
-				   !g_ascii_strncasecmp(p + start_pos - 5, "<URL:", 5)))) {
-			/* if the input is flowed, we will see a space at
-			 * url_match.rm_eo - in this case the complete remainder
-			 * of the ml uri should be in the passed buffer... */
-			if (url_info && url_info->buffer_is_flowed &&
-			    *(p + end_pos) == ' ') {
-			    regex_t *ml_flowed_url_reg = get_ml_flowed_url_reg();
-			    regmatch_t ml_url_match;
-
-			    if (!regexec(ml_flowed_url_reg,
-					 all_chars + offset + end_pos, 1,
-					 &ml_url_match, 0)
-                                && ml_url_match.rm_so == 0)
-				end_pos += ml_url_match.rm_eo - 1;
-			} else if (!strchr(p + end_pos, '>')) {
-                            gint ml_end_pos;
-			    regex_t *ml_url_reg = get_ml_url_reg();
-			    regmatch_t ml_url_match;
-		    
-			    if (!regexec(ml_url_reg,
-					 all_chars + offset + end_pos, 1,
-					 &ml_url_match, 0)
-                                && ml_url_match.rm_so == 0) {
-				GString *ml_url = g_string_new("");
-				const gchar *ml_p =
-                                    all_chars + offset + start_pos;
-				gint ml_cnt;
-
-                                ml_end_pos = ml_url_match.rm_eo;
-				ml_cnt = end_pos - start_pos + ml_end_pos - 1;
-				for (; ml_cnt; (ml_p++, ml_cnt--))
-				    if (*ml_p > ' ')
-					ml_url = g_string_append_c(ml_url, *ml_p);
-				url_info->ml_url = ml_url->str;
-				g_string_free(ml_url, FALSE);
-			    }
-			}
-		    }
+    url_reg = get_url_reg();
+    match = regexec(url_reg, chars, 1, &url_match, 0) == 0
+        && chars + url_match.rm_so < line_end;
 
-		    buf = g_strndup(p, start_pos);
-		    gtk_text_buffer_insert_with_tags(buffer, &iter,
-						     buf, -1, tag, NULL);
-		    g_free(buf);
-		}
+    while (match) {
+        gchar *spc;
+        gint start_pos, end_pos;
 
-		if (url_info->ml_url) {
-		    url_info->ml_url_buffer = g_string_new(p + start_pos);
-		    url_info->ml_url_buffer =
-			g_string_append_c(url_info->ml_url_buffer, '\n');
-		    return TRUE;
-		}
+        start_pos = url_match.rm_so;
+        end_pos = url_match.rm_eo;
 
-		/* add the url - it /may/ contain spaces if the text is flowed */
-		buf = g_strndup(p + start_pos, end_pos - start_pos);
-		if ((spc = strchr(buf, ' '))) {
-		    GString *uri_real = g_string_new("");
-		    gchar * p = buf;
-
-		    while (spc) {
-			*spc = '\n';
-			g_string_append_len(uri_real, p, spc - p);
-			p = spc + 1;
-			spc = strchr(p, ' ');
-		    }
-		    g_string_append(uri_real, p);
-		    gtk_text_buffer_insert_with_tags(buffer, &iter, buf, -1,
-						     url_tag, tag, NULL);
-		    if (url_info->callback)
-			url_info->callback(buffer, &iter, uri_real->str, url_info->callback_data);
-		    g_string_free(uri_real, TRUE);
-		} else {
-		    gtk_text_buffer_insert_with_tags(buffer, &iter, buf, -1,
-						     url_tag, tag, NULL);
-
-		    /* remember the URL and its position within the text */
-		    if (url_info->callback)
-			url_info->callback(buffer, &iter, buf, url_info->callback_data);
-		}
-		g_free(buf);
+        gtk_text_buffer_insert_with_tags(buffer, &iter, chars,
+                                         start_pos, tag, NULL);
 
-		p += end_pos;
-		offset += end_pos;
-		if (prescanner(p))
-		    match = regexec(url_reg, p, 1, &url_match, 0) == 0;
-		else
-		    match = FALSE;
-	    }
-#endif                          /* USE_GREGEX */
-	}
+        /* check if we hit a multi-line URL... (see RFC 1738) */
+        if ((start_pos > 0 && (chars[start_pos - 1] == '<')) ||
+            (start_pos > 4 &&
+             !g_ascii_strncasecmp(chars + start_pos - 5, "<URL:", 5))) {
+            regex_t *ml_url_reg;
+            regmatch_t ml_url_match;
+
+            /* if the input is flowed, we may see a space at
+             * url_match.rm_eo - in this case the complete remainder
+             * of the ml uri should be in the passed buffer... */
+            if (url_info->buffer_is_flowed && chars[end_pos] == ' ') {
+                ml_url_reg = get_ml_flowed_url_reg();
+                if (!regexec(ml_url_reg, chars + end_pos, 1,
+                             &ml_url_match, 0)
+                    && ml_url_match.rm_so == 0)
+                    end_pos += ml_url_match.rm_eo - 1;
+            } else if (chars[end_pos] != '>') {
+                ml_url_reg = get_ml_url_reg();
+                if (!regexec(ml_url_reg, chars + end_pos, 1,
+                             &ml_url_match, 0)
+                    && ml_url_match.rm_so == 0) {
+                    chars += start_pos;
+                    url_info->ml_url_buffer =
+                        g_string_new_len(chars, line_end - chars);
+                    g_string_append_c(url_info->ml_url_buffer, '\n');
+                    return TRUE;
+                }
+            }
+        }
+
+        /* add the url - it /may/ contain spaces if the text is flowed */
+        if ((spc = strchr(chars + start_pos, ' ')) && spc < chars + end_pos) {
+            GString *uri_real = g_string_new("");
+            gchar *q, *buf;
+
+            q = buf = g_strndup(chars + start_pos, end_pos - start_pos);
+            spc = buf + (spc - (chars + start_pos));
+            do {
+                *spc = '\n';
+                g_string_append_len(uri_real, q, spc - q);
+                q = spc + 1;
+            } while ((spc = strchr(q, ' ')));
+            g_string_append(uri_real, q);
+            gtk_text_buffer_insert_with_tags(buffer, &iter, buf, -1,
+                                             url_tag, tag, NULL);
+            g_free(buf);
+            url_info->callback(buffer, &iter,
+                               uri_real->str, uri_real->len,
+                               url_info->callback_data);
+            g_string_free(uri_real, TRUE);
+        } else {
+            gtk_text_buffer_insert_with_tags(buffer, &iter,
+                                             chars + start_pos,
+                                             end_pos - start_pos,
+                                             url_tag, tag, NULL);
+
+            /* remember the URL and its position within the text */
+            url_info->callback(buffer, &iter, chars + start_pos,
+                               end_pos - start_pos,
+                               url_info->callback_data);
+        }
+
+        chars += end_pos;
+        if (prescanner(chars, line_end - chars))
+            match = regexec(url_reg, chars, 1, &url_match, 0) == 0
+                && chars + url_match.rm_so < line_end;
+        else
+            match = FALSE;
     }
+#endif                          /* USE_GREGEX */
 
-    if (*p)
-        gtk_text_buffer_insert_with_tags(buffer, &iter, p, -1, tag, NULL);
-    g_free(buf);
+    gtk_text_buffer_insert_with_tags(buffer, &iter, chars,
+                                     line_end - chars, tag, NULL);
 
     return FALSE;
 }
@@ -1383,7 +1350,7 @@
     gchar * markup;
 
     /* check for any url */
-    if (!prescanner(paragraph->str)) {
+    if (!prescanner(paragraph->str, paragraph->len)) {
         markup = g_markup_escape_text(paragraph->str, -1);
         g_string_assign(paragraph, markup);
         g_free(markup);
@@ -1425,7 +1392,7 @@
 
         /* find next (if any) */
         p += end_pos;
-        if (prescanner(p)) {
+        if (prescanner(p, paragraph->len - (p - paragraph->str))) {
 #if USE_GREGEX
             g_match_info_free(url_match);
             match = g_regex_match(url_reg, p, 0, &url_match);

Modified: trunk/libbalsa/misc.h
==============================================================================
--- trunk/libbalsa/misc.h	(original)
+++ trunk/libbalsa/misc.h	Sat Dec  6 17:55:58 2008
@@ -86,13 +86,12 @@
 };
 
 typedef void (*libbalsa_url_cb_t) (GtkTextBuffer *, GtkTextIter *,
-				   const gchar *, gpointer);
+				   const gchar *, guint, gpointer);
 typedef struct _LibBalsaUrlInsertInfo LibBalsaUrlInsertInfo;
 struct _LibBalsaUrlInsertInfo {
     libbalsa_url_cb_t callback;
     gpointer callback_data;
     gboolean buffer_is_flowed;
-    gchar *ml_url;
     GString *ml_url_buffer;
 };
 
@@ -138,7 +137,7 @@
 gboolean libbalsa_utf8_strstr(const gchar *s1,const gchar *s2);
 gboolean libbalsa_insert_with_url(GtkTextBuffer * buffer,
 				  const char *chars,
-				  const char *all_chars,
+				  guint len,
 				  GtkTextTag * tag,
 				  LibBalsaUrlInsertInfo *url_info);
 #if USE_GREGEX

Modified: trunk/src/balsa-mime-widget-text.c
==============================================================================
--- trunk/src/balsa-mime-widget-text.c	(original)
+++ trunk/src/balsa-mime-widget-text.c	Sat Dec  6 17:55:58 2008
@@ -104,7 +104,8 @@
 static gboolean check_over_url(GtkWidget * widget, GdkEventMotion * event, GList * url_list);
 static void pointer_over_url(GtkWidget * widget, message_url_t * url, gboolean set);
 static void prepare_url_offsets(GtkTextBuffer * buffer, GList * url_list);
-static void url_found_cb(GtkTextBuffer * buffer, GtkTextIter * iter, const gchar * buf, gpointer data);
+static void url_found_cb(GtkTextBuffer * buffer, GtkTextIter * iter,
+                         const gchar * buf, guint len, gpointer data);
 static gboolean check_call_url(GtkWidget * widget, GdkEventButton * event, GList * url_list);
 static message_url_t * find_url(GtkWidget * widget, gint x, gint y, GList * url_list);
 static void handle_url(const message_url_t* url);
@@ -254,7 +255,7 @@
     }
 #endif                          /* USE_GREGEX */
     else {
-	gchar *line_start;
+	const gchar *line_start;
 	LibBalsaUrlInsertInfo url_info;
 	GList * cite_bars_list;
 	guint cite_level;
@@ -276,23 +277,19 @@
 	url_info.callback = url_found_cb;
 	url_info.callback_data = &url_list;
 	url_info.buffer_is_flowed = libbalsa_message_body_is_flowed(mime_body);
-	url_info.ml_url = NULL;
 	url_info.ml_url_buffer = NULL;
 
 	line_start = ptr;
 	cite_bars_list = NULL;
 	cite_level = 0;
 	cite_start = 0;
-	while (line_start) {
-	    gchar *newline, *this_line;
+	while (*line_start) {
+	    const gchar *line_end;
 	    GtkTextTag *tag = NULL;
 	    int len;
 
-	    newline = strchr(line_start, '\n');
-	    if (newline)
-		this_line = g_strndup(line_start, newline - line_start);
-	    else
-		this_line = g_strdup(line_start);
+	    if (!(line_end = strchr(line_start, '\n')))
+                line_end = line_start + strlen(line_start);
 
 	    if (is_text_plain) {
 		guint quote_level;
@@ -300,9 +297,11 @@
 
 		/* get the cite level only for text/plain parts */
 #if USE_GREGEX
-		libbalsa_match_regex(this_line, rex, &quote_level, &cite_idx);
+		libbalsa_match_regex(line_start, rex, &quote_level,
+                                     &cite_idx);
 #else                           /* USE_GREGEX */
-		libbalsa_match_regex(this_line, &rex, &quote_level, &cite_idx);
+		libbalsa_match_regex(line_start, &rex, &quote_level,
+                                     &cite_idx);
 #endif                          /* USE_GREGEX */
 	    
 		/* check if the citation level changed */
@@ -320,31 +319,26 @@
 		    cite_level = quote_level;
 		}
 
-		/* strip off the citation prefix */
+		/* skip the citation prefix */
 		if (quote_level) {
-		    gchar *new;
-		
-		    new = this_line + cite_idx;
-		    if (g_unichar_isspace(g_utf8_get_char(new)))
-			new = g_utf8_next_char(new);
-		    new = g_strdup(new);
-		    g_free(this_line);
-		    this_line = new;
+		    line_start += cite_idx;
+                    if (line_start < line_end
+                        && g_unichar_isspace(g_utf8_get_char(line_start)))
+                        line_start = g_utf8_next_char(line_start);
 		}
 		tag = quote_tag(buffer, quote_level, margin);
 	    }
 
-	    len = strlen(this_line);
-	    if (len > 0 && this_line[len - 1] == '\r')
-		this_line[len - 1] = '\0';
+            len = line_end - line_start;
+	    if (len > 0 && line_start[len - 1] == '\r')
+                --len;
 	    /* tag is NULL if the line isn't quoted, but it causes
 	     * no harm */
-	    if (!libbalsa_insert_with_url(buffer, this_line, line_start,
+	    if (!libbalsa_insert_with_url(buffer, line_start, len,
 					  tag, &url_info))
 		gtk_text_buffer_insert_at_cursor(buffer, "\n", 1);
 	    
-	    g_free(this_line);
-	    line_start = newline ? newline + 1 : NULL;
+	    line_start = *line_end ? line_end + 1 : line_end;
 	}
 
 	/* add any pending cited part */
@@ -836,7 +830,7 @@
 
 static void
 url_found_cb(GtkTextBuffer * buffer, GtkTextIter * iter,
-             const gchar * buf, gpointer data)
+             const gchar * buf, guint len, gpointer data)
 {
     GList **url_list = data;
     message_url_t *url_found;
@@ -844,7 +838,7 @@
     url_found = g_new(message_url_t, 1);
     url_found->end_mark =
         gtk_text_buffer_create_mark(buffer, NULL, iter, TRUE);
-    url_found->url = g_strdup(buf);       /* gets freed later... */
+    url_found->url = g_strndup(buf, len);       /* gets freed later... */
     *url_list = g_list_append(*url_list, url_found);
 }
 

Modified: trunk/src/sendmsg-window.c
==============================================================================
--- trunk/src/sendmsg-window.c	(original)
+++ trunk/src/sendmsg-window.c	Sat Dec  6 17:55:58 2008
@@ -1140,7 +1140,7 @@
     gtk_text_buffer_set_text(buffer, "", 0);
     curposition = 0;
     while(fgets(line, sizeof(line), tmp))
-        libbalsa_insert_with_url(buffer, line, NULL, NULL, NULL);
+        gtk_text_buffer_insert_at_cursor(buffer, line, -1);
     sw_buffer_signals_unblock(data_real->bsmsg, buffer);
 
     g_free(data_real->filename);
@@ -1335,7 +1335,7 @@
         gtk_text_buffer_get_end_iter(buffer, &ins);
     }
     gtk_text_buffer_place_cursor(buffer, &ins);
-    libbalsa_insert_with_url(buffer, new_sig, NULL, NULL, NULL);
+    gtk_text_buffer_insert_at_cursor(buffer, new_sig, -1);
 }
 
 /*
@@ -2377,7 +2377,7 @@
 	for (node = l; node; node = g_list_next(node)) {
 	    LibBalsaMessage *message = node->data;
             GString *body = quote_message_body(bsmsg, message, type);
-            libbalsa_insert_with_url(buffer, body->str, NULL, NULL, NULL);
+            gtk_text_buffer_insert_at_cursor(buffer, body->str, body->len);
             g_string_free(body, TRUE);
 	}
 	g_list_foreach(l, (GFunc)g_object_unref, NULL);
@@ -3099,7 +3099,7 @@
 
             body = quote_message_body(bsmsg, message, QUOTE_ALL);
 	    g_object_unref(message);
-            libbalsa_insert_with_url(buffer, body->str, NULL, NULL, NULL);
+            gtk_text_buffer_insert_at_cursor(buffer, body->str, body->len);
             g_string_free(body, TRUE);
         }
         balsa_index_selected_msgnos_free(index, selected);
@@ -3289,7 +3289,7 @@
 	    if (!strcmp(body_type, "text/plain") &&
 		(rbdy = process_mime_part(message, body, NULL, llen, FALSE,
                                           bsmsg->flow))) {
-                libbalsa_insert_with_url(buffer, rbdy->str, NULL, NULL, NULL);
+                gtk_text_buffer_insert_at_cursor(buffer, rbdy->str, rbdy->len);
 		g_string_free(rbdy, TRUE);
 	    }
 	    g_free(body_type);
@@ -3882,7 +3882,7 @@
 
     if(body->len && body->str[body->len] != '\n')
         g_string_append_c(body, '\n');
-    libbalsa_insert_with_url(buffer, body->str, NULL, NULL, NULL);
+    gtk_text_buffer_insert_at_cursor(buffer, body->str, body->len);
     
     if(qtype == QUOTE_HEADERS)
         gtk_text_buffer_get_end_iter(buffer, &start);
@@ -3932,7 +3932,7 @@
         sw_buffer_save(bsmsg);
 #endif                          /* HAVE_GTKSOURCEVIEW */	
         sw_buffer_signals_block(bsmsg, buffer);
-        libbalsa_insert_with_url(buffer, signature, NULL, NULL, NULL);
+        gtk_text_buffer_insert_at_cursor(buffer, signature, -1);
         sw_buffer_signals_unblock(bsmsg, buffer);
 	
 	g_free(signature);
@@ -5182,7 +5182,7 @@
         GtkTextBuffer *buffer =
             gtk_text_view_get_buffer(GTK_TEXT_VIEW(bsmsg->text));
 
-        libbalsa_insert_with_url(buffer, val, NULL, NULL, NULL);
+        gtk_text_buffer_insert_at_cursor(buffer, val, -1);
 
         return;
     }
@@ -5265,7 +5265,7 @@
 
         g_print("Trying charset: %s\n", charset);
         if (sw_can_convert(string, len, "UTF-8", charset, &s)) {
-            libbalsa_insert_with_url(buffer, s, NULL, NULL, NULL);
+            gtk_text_buffer_insert_at_cursor(buffer, s, -1);
             g_free(s);
             break;
         }
@@ -5310,7 +5310,7 @@
         attr = libbalsa_text_attr_string(string);
         if (!attr || attr & LIBBALSA_TEXT_HI_UTF8)
             /* Ascii or utf-8 */
-            libbalsa_insert_with_url(buffer, string, NULL, NULL, NULL);
+            gtk_text_buffer_insert_at_cursor(buffer, string, -1);
         else {
             /* Neither ascii nor utf-8... */
             gchar *s = NULL;
@@ -5318,7 +5318,7 @@
 
             if (sw_can_convert(string, -1, "UTF-8", charset, &s)) {
                 /* ...but seems to be in current charset. */
-                libbalsa_insert_with_url(buffer, s, NULL, NULL, NULL);
+                gtk_text_buffer_insert_at_cursor(buffer, s, -1);
                 g_free(s);
             } else
                 /* ...and can't be decoded from current charset. */
@@ -5397,7 +5397,7 @@
         the_text = gtk_text_iter_get_text(&start, &end);
         libbalsa_wrap_string(the_text, balsa_app.wraplength);
         gtk_text_buffer_set_text(buffer, "", 0);
-        libbalsa_insert_with_url(buffer, the_text, NULL, NULL, NULL);
+        gtk_text_buffer_insert_at_cursor(buffer, the_text, -1);
         g_free(the_text);
 
         gtk_text_buffer_get_iter_at_offset(buffer, &now, pos);
@@ -6730,7 +6730,7 @@
         else if (type == SEND_FORWARD_INLINE) {
             GString *body =
                 quote_message_body(bsmsg, message, QUOTE_NOPREFIX);
-            libbalsa_insert_with_url(buffer, body->str, NULL, NULL, NULL);
+            gtk_text_buffer_insert_at_cursor(buffer, body->str, body->len);
             g_string_free(body, TRUE);
         }
         g_object_unref(message);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]