From: Colin Leroy Date: Thu, 25 Oct 2012 07:45:01 +0000 (+0000) Subject: 2012-10-25 [colin] 3.8.1cvs106 X-Git-Tag: REL_3_9_0~18 X-Git-Url: http://git.claws-mail.org/?p=claws.git;a=commitdiff_plain;h=a40588e25fabcfe13c8984486f17cc58eecc7f79 2012-10-25 [colin] 3.8.1cvs106 * src/common/utils.c * src/common/utils.h * src/textview.c Avoid strlen() on inner loop in textview_make_clickable_parts*() reduces cost of strcasestr() in textview_make_clickable_parts*() from 30% to 15%. Patch by Igor Mammedov --- diff --git a/ChangeLog b/ChangeLog index 60736b996..298ce3432 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2012-10-25 [colin] 3.8.1cvs106 + + * src/common/utils.c + * src/common/utils.h + * src/textview.c + Avoid strlen() on inner loop in textview_make_clickable_parts*() + reduces cost of strcasestr() in textview_make_clickable_parts*() + from 30% to 15%. Patch by Igor Mammedov + 2012-10-25 [colin] 3.8.1cvs105 * src/textview.c diff --git a/PATCHSETS b/PATCHSETS index c2376f372..9b34efd37 100644 --- a/PATCHSETS +++ b/PATCHSETS @@ -4480,3 +4480,4 @@ ( cvs diff -u -r 1.1.2.6 -r 1.1.2.7 src/advsearch.c; ) > 3.8.1cvs103.patchset ( cvs diff -u -r 1.100.2.85 -r 1.100.2.86 AUTHORS; cvs diff -u -r 1.96.2.249 -r 1.96.2.250 src/textview.c; cvs diff -u -r 1.12.2.35 -r 1.12.2.36 src/textview.h; cvs diff -u -r 1.1.2.81 -r 1.1.2.82 src/gtk/authors.h; ) > 3.8.1cvs104.patchset ( cvs diff -u -r 1.96.2.250 -r 1.96.2.251 src/textview.c; ) > 3.8.1cvs105.patchset +( cvs diff -u -r 1.36.2.207 -r 1.36.2.208 src/common/utils.c; cvs diff -u -r 1.20.2.82 -r 1.20.2.83 src/common/utils.h; cvs diff -u -r 1.96.2.251 -r 1.96.2.252 src/textview.c; ) > 3.8.1cvs106.patchset diff --git a/configure.ac b/configure.ac index c6e137514..60bbc1584 100644 --- a/configure.ac +++ b/configure.ac @@ -12,7 +12,7 @@ MINOR_VERSION=8 MICRO_VERSION=1 INTERFACE_AGE=0 BINARY_AGE=0 -EXTRA_VERSION=105 +EXTRA_VERSION=106 EXTRA_RELEASE= EXTRA_GTK2_VERSION= diff --git a/src/common/utils.c b/src/common/utils.c index 1e39043b5..6cb336cf8 100644 --- a/src/common/utils.c +++ b/src/common/utils.c @@ -534,9 +534,15 @@ freeout: /* Similar to `strstr' but this function ignores the case of both strings. */ gchar *strcasestr(const gchar *haystack, const gchar *needle) { - register size_t haystack_len, needle_len; + size_t haystack_len = strlen(haystack); + + return strncasestr(haystack, haystack_len, needle); +} + +gchar *strncasestr(const gchar *haystack, gint haystack_len, const gchar *needle) +{ + register size_t needle_len; - haystack_len = strlen(haystack); needle_len = strlen(needle); if (haystack_len < needle_len || needle_len == 0) diff --git a/src/common/utils.h b/src/common/utils.h index df340e7ff..b701ae92d 100644 --- a/src/common/utils.h +++ b/src/common/utils.h @@ -309,6 +309,9 @@ gchar *strcrchomp (gchar *str); gint file_strip_crs (const gchar *file); gchar *strcasestr (const gchar *haystack, const gchar *needle); +gchar *strncasestr (const gchar *haystack, + gint haystack_len, + const gchar *needle); gpointer my_memmem (gconstpointer haystack, size_t haystacklen, gconstpointer needle, diff --git a/src/textview.c b/src/textview.c index c1f06e03d..8dd88635a 100644 --- a/src/textview.c +++ b/src/textview.c @@ -1311,7 +1311,8 @@ static void textview_make_clickable_parts(TextView *textview, GtkTextView *text = GTK_TEXT_VIEW(textview->text); GtkTextBuffer *buffer = gtk_text_view_get_buffer(text); GtkTextIter iter; - gchar *mybuf = g_strdup(linebuf); + gint mybuf_len = strlen(linebuf); + gchar *mybuf = g_strndup(linebuf, mybuf_len); /* parse table - in order of priority */ struct table { @@ -1319,6 +1320,7 @@ static void textview_make_clickable_parts(TextView *textview, /* token search function */ gchar *(*search) (const gchar *haystack, + gint haystack_len, const gchar *needle); /* part parsing function */ gboolean (*parse) (const gchar *start, @@ -1332,14 +1334,14 @@ static void textview_make_clickable_parts(TextView *textview, }; static struct table parser[] = { - {"http://", strcasestr, get_uri_part, make_uri_string}, - {"https://", strcasestr, get_uri_part, make_uri_string}, - {"ftp://", strcasestr, get_uri_part, make_uri_string}, - {"sftp://", strcasestr, get_uri_part, make_uri_string}, - {"gopher://",strcasestr, get_uri_part, make_uri_string}, - {"www.", strcasestr, get_uri_part, make_http_string}, - {"mailto:", strcasestr, get_uri_part, make_uri_string}, - {"@", strcasestr, get_email_part, make_email_string} + {"http://", strncasestr, get_uri_part, make_uri_string}, + {"https://", strncasestr, get_uri_part, make_uri_string}, + {"ftp://", strncasestr, get_uri_part, make_uri_string}, + {"sftp://", strncasestr, get_uri_part, make_uri_string}, + {"gopher://",strncasestr, get_uri_part, make_uri_string}, + {"www.", strncasestr, get_uri_part, make_http_string}, + {"mailto:", strncasestr, get_uri_part, make_uri_string}, + {"@", strncasestr, get_email_part, make_email_string} }; const gint PARSE_ELEMS = sizeof parser / sizeof parser[0]; @@ -1354,25 +1356,30 @@ static void textview_make_clickable_parts(TextView *textview, if (!g_utf8_validate(linebuf, -1, NULL)) { g_free(mybuf); - mybuf = g_malloc(strlen(linebuf)*2 +1); - conv_localetodisp(mybuf, strlen(linebuf)*2 +1, linebuf); + mybuf = g_malloc(mybuf_len*2 +1); + conv_localetodisp(mybuf, mybuf_len*2 +1, linebuf); + mybuf_len = strlen(mybuf); } gtk_text_buffer_get_end_iter(buffer, &iter); /* parse for clickable parts, and build a list of begin and end positions */ for (n = 0; n < PARSE_ELEMS; n++) { + gint len = mybuf_len; + gint needle_len = strlen(parser[n].needle); for (walk = mybuf;;) { - gchar *scanpos = parser[n].search(walk, parser[n].needle); + gchar *scanpos = parser[n].search(walk, len, parser[n].needle); if (scanpos) { /* check if URI can be parsed */ if (parser[n].parse(walk, scanpos, &bp, &ep, hdr) - && (size_t) (ep - bp - 1) > strlen(parser[n].needle)) { + && (size_t) (ep - bp - 1) > needle_len) { ADD_TXT_POS(bp, ep, n); + len -= ep - walk; walk = ep; - } else - walk = scanpos + - strlen(parser[n].needle); + } else { + len -= (scanpos + needle_len) - walk; + walk = scanpos + needle_len; + } } else break; } @@ -1423,6 +1430,7 @@ static void textview_make_clickable_parts_later(TextView *textview, GtkTextBuffer *buffer = gtk_text_view_get_buffer(text); GtkTextIter start_iter, end_iter; gchar *mybuf; + gint mybuf_len; gint offset = 0; /* parse table - in order of priority */ struct table { @@ -1430,6 +1438,7 @@ static void textview_make_clickable_parts_later(TextView *textview, /* token search function */ gchar *(*search) (const gchar *haystack, + gint haystack_len, const gchar *needle); /* part parsing function */ gboolean (*parse) (const gchar *start, @@ -1443,13 +1452,13 @@ static void textview_make_clickable_parts_later(TextView *textview, }; static struct table parser[] = { - {"http://", strcasestr, get_uri_part, make_uri_string}, - {"https://", strcasestr, get_uri_part, make_uri_string}, - {"ftp://", strcasestr, get_uri_part, make_uri_string}, - {"sftp://", strcasestr, get_uri_part, make_uri_string}, - {"www.", strcasestr, get_uri_part, make_http_string}, - {"mailto:", strcasestr, get_uri_part, make_uri_string}, - {"@", strcasestr, get_email_part, make_email_string} + {"http://", strncasestr, get_uri_part, make_uri_string}, + {"https://", strncasestr, get_uri_part, make_uri_string}, + {"ftp://", strncasestr, get_uri_part, make_uri_string}, + {"sftp://", strncasestr, get_uri_part, make_uri_string}, + {"www.", strncasestr, get_uri_part, make_http_string}, + {"mailto:", strncasestr, get_uri_part, make_uri_string}, + {"@", strncasestr, get_email_part, make_email_string} }; const gint PARSE_ELEMS = sizeof parser / sizeof parser[0]; @@ -1468,18 +1477,23 @@ static void textview_make_clickable_parts_later(TextView *textview, offset = gtk_text_iter_get_offset(&start_iter); /* parse for clickable parts, and build a list of begin and end positions */ + mybuf_len = strlen(mybuf); for (n = 0; n < PARSE_ELEMS; n++) { + gint len = mybuf_len; + gint needle_len = strlen(parser[n].needle); for (walk = mybuf;;) { - gchar *scanpos = parser[n].search(walk, parser[n].needle); + gchar *scanpos = parser[n].search(walk, len, parser[n].needle); if (scanpos) { /* check if URI can be parsed */ if (parser[n].parse(walk, scanpos, &bp, &ep, FALSE) - && (size_t) (ep - bp - 1) > strlen(parser[n].needle)) { + && (size_t) (ep - bp - 1) > needle_len) { ADD_TXT_POS_LATER(bp, ep, n); + len -= ep - walk; walk = ep; - } else - walk = scanpos + - strlen(parser[n].needle); + } else { + len -= (scanpos + needle_len) - walk; + walk = scanpos + needle_len; + } } else break; }