From 8e5db471e4d8b052f072ce8a351222c6edb42d19 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Thu, 14 Jan 2016 14:10:00 +0100 Subject: [PATCH 1/7] Use GLib's regexp interface (backed by PCRE) --- src/core/ignore.c | 35 +++++++++++------------------ src/core/ignore.h | 8 +------ src/core/misc.c | 4 ---- src/fe-common/core/fe-ignore.c | 2 -- src/fe-common/core/hilight-text.c | 37 +++++++++++++------------------ src/fe-common/core/hilight-text.h | 8 +------ src/fe-text/textbuffer.c | 35 ++++++++++------------------- 7 files changed, 42 insertions(+), 87 deletions(-) diff --git a/src/core/ignore.c b/src/core/ignore.c index 2047dc9d..2b8299bd 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -67,12 +67,8 @@ static int ignore_match_pattern(IGNORE_REC *rec, const char *text) return FALSE; if (rec->regexp) { -#ifdef HAVE_REGEX_H return rec->regexp_compiled && - regexec(&rec->preg, text, 0, NULL, 0) == 0; -#else - return FALSE; -#endif + g_regex_match(rec->preg, text, 0, NULL); } return rec->fullword ? @@ -326,26 +322,23 @@ static void ignore_remove_config(IGNORE_REC *rec) static void ignore_init_rec(IGNORE_REC *rec) { -#ifdef HAVE_REGEX_H - char *errbuf; - int errcode, errbuf_len; + if (rec->regexp_compiled) { + g_regex_unref(rec->preg); + rec->regexp_compiled = FALSE; + } - if (rec->regexp_compiled) regfree(&rec->preg); - rec->regexp_compiled = FALSE; if (rec->regexp && rec->pattern != NULL) { - errcode = regcomp(&rec->preg, rec->pattern, - REG_EXTENDED|REG_ICASE|REG_NOSUB); - if (errcode != 0) { - errbuf_len = regerror(errcode, &rec->preg, 0, 0); - errbuf = g_malloc(errbuf_len); - regerror(errcode, &rec->preg, errbuf, errbuf_len); - g_warning("Failed to compile regexp '%s': %s", rec->pattern, errbuf); - g_free(errbuf); + GError *re_error; + + rec->preg = g_regex_new(rec->pattern, G_REGEX_CASELESS, 0, &re_error); + + if (rec->preg == NULL) { + g_warning("Failed to compile regexp '%s': %s", rec->pattern, re_error->message); + g_error_free(re_error); } else { rec->regexp_compiled = TRUE; } } -#endif } void ignore_add_rec(IGNORE_REC *rec) @@ -365,9 +358,7 @@ static void ignore_destroy(IGNORE_REC *rec, int send_signal) if (send_signal) signal_emit("ignore destroyed", 1, rec); -#ifdef HAVE_REGEX_H - if (rec->regexp_compiled) regfree(&rec->preg); -#endif + if (rec->regexp_compiled) g_regex_unref(rec->preg); if (rec->channels != NULL) g_strfreev(rec->channels); g_free_not_null(rec->mask); g_free_not_null(rec->servertag); diff --git a/src/core/ignore.h b/src/core/ignore.h index f889740f..6c9797f5 100644 --- a/src/core/ignore.h +++ b/src/core/ignore.h @@ -1,10 +1,6 @@ #ifndef __IGNORE_H #define __IGNORE_H -#ifdef HAVE_REGEX_H -# include -#endif - typedef struct _IGNORE_REC IGNORE_REC; struct _IGNORE_REC { @@ -20,10 +16,8 @@ struct _IGNORE_REC { unsigned int regexp:1; unsigned int fullword:1; unsigned int replies:1; /* ignore replies to nick in channel */ -#ifdef HAVE_REGEX_H unsigned int regexp_compiled:1; /* should always be TRUE, unless regexp is invalid */ - regex_t preg; -#endif + GRegex *preg; }; extern GSList *ignores; diff --git a/src/core/misc.c b/src/core/misc.c index 0bb1f7e6..c59eb126 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -22,10 +22,6 @@ #include "misc.h" #include "commands.h" -#ifdef HAVE_REGEX_H -# include -#endif - typedef struct { int condition; GInputFunction function; diff --git a/src/fe-common/core/fe-ignore.c b/src/fe-common/core/fe-ignore.c index 52b11e6b..addfa0b8 100644 --- a/src/fe-common/core/fe-ignore.c +++ b/src/fe-common/core/fe-ignore.c @@ -58,10 +58,8 @@ static void ignore_print(int index, IGNORE_REC *rec) g_string_append(options, "-regexp "); if (rec->pattern == NULL) g_string_append(options, "[INVALID! -pattern missing] "); -#ifdef HAVE_REGEX_H else if (!rec->regexp_compiled) g_string_append(options, "[INVALID!] "); -#endif } if (rec->fullword) g_string_append(options, "-full "); if (rec->replies) g_string_append(options, "-replies "); diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index 4691a708..83b6f67e 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -101,9 +101,7 @@ static void hilight_destroy(HILIGHT_REC *rec) { g_return_if_fail(rec != NULL); -#ifdef HAVE_REGEX_H - if (rec->regexp_compiled) regfree(&rec->preg); -#endif + if (rec->regexp_compiled) g_regex_unref(rec->preg); if (rec->channels != NULL) g_strfreev(rec->channels); g_free_not_null(rec->color); g_free_not_null(rec->act_color); @@ -120,14 +118,15 @@ static void hilights_destroy_all(void) static void hilight_init_rec(HILIGHT_REC *rec) { -#ifdef HAVE_REGEX_H - if (rec->regexp_compiled) regfree(&rec->preg); - if (!rec->regexp) + if (rec->regexp_compiled) { + g_regex_unref(rec->preg); rec->regexp_compiled = FALSE; - else - rec->regexp_compiled = regcomp(&rec->preg, rec->text, - rec->case_sensitive ? REG_EXTENDED : (REG_EXTENDED|REG_ICASE)) == 0; -#endif + } + + rec->preg = g_regex_new(rec->text, G_REGEX_CASELESS, 0, NULL); + + if (rec->preg != NULL) + rec->regexp_compiled = TRUE; } void hilight_create(HILIGHT_REC *rec) @@ -200,19 +199,15 @@ static int hilight_match_text(HILIGHT_REC *rec, const char *text, char *match; if (rec->regexp) { -#ifdef HAVE_REGEX_H - regmatch_t rmatch[1]; + GMatchInfo *match; - if (rec->regexp_compiled && - regexec(&rec->preg, text, 1, rmatch, 0) == 0) { - if (rmatch[0].rm_so > 0 && - match_beg != NULL && match_end != NULL) { - *match_beg = rmatch[0].rm_so; - *match_end = rmatch[0].rm_eo; + if (rec->regexp_compiled) { + g_regex_match (rec->preg, text, 0, &match); + + if (g_match_info_matches(match)) { + return g_match_info_fetch_pos(match, 0, match_beg, match_end); } - return TRUE; } -#endif } else { if (rec->case_sensitive) { match = rec->fullword ? @@ -509,10 +504,8 @@ static void hilight_print(int index, HILIGHT_REC *rec) if (rec->case_sensitive) g_string_append(options, "-matchcase "); if (rec->regexp) { g_string_append(options, "-regexp "); -#ifdef HAVE_REGEX_H if (!rec->regexp_compiled) g_string_append(options, "[INVALID!] "); -#endif } if (rec->priority != 0) diff --git a/src/fe-common/core/hilight-text.h b/src/fe-common/core/hilight-text.h index ae05e1ca..a74c38b0 100644 --- a/src/fe-common/core/hilight-text.h +++ b/src/fe-common/core/hilight-text.h @@ -1,10 +1,6 @@ #ifndef __HILIGHT_TEXT_H #define __HILIGHT_TEXT_H -#ifdef HAVE_REGEX_H -# include -#endif - #include "formats.h" struct _HILIGHT_REC { @@ -24,10 +20,8 @@ struct _HILIGHT_REC { unsigned int fullword:1; /* match `text' only for full words */ unsigned int regexp:1; /* `text' is a regular expression */ unsigned int case_sensitive:1;/* `text' must match case */ -#ifdef HAVE_REGEX_H unsigned int regexp_compiled:1; /* should always be TRUE, unless regexp is invalid */ - regex_t preg; -#endif + GRegex *preg; char *servertag; }; diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index 24ee62bc..979b2a46 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -27,10 +27,6 @@ #include "textbuffer.h" -#ifdef HAVE_REGEX_H -# include -#endif - #define TEXT_CHUNK_USABLE_SIZE (LINE_TEXT_CHUNK_SIZE-2-(int)sizeof(char*)) TEXT_BUFFER_REC *textbuffer_create(void) @@ -537,9 +533,7 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, int before, int after, int regexp, int fullword, int case_sensitive) { -#ifdef HAVE_REGEX_H - regex_t preg; -#endif + GRegex *preg; LINE_REC *line, *pre_line; GList *matches; GString *str; @@ -550,14 +544,10 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, g_return_val_if_fail(text != NULL, NULL); if (regexp) { -#ifdef HAVE_REGEX_H - int flags = REG_EXTENDED | REG_NOSUB | - (case_sensitive ? 0 : REG_ICASE); - if (regcomp(&preg, text, flags) != 0) + preg = g_regex_new(text, (case_sensitive ? 0 : G_REGEX_CASELESS), 0, NULL); + + if (preg == NULL) return NULL; -#else - return NULL; -#endif } matches = NULL; match_after = 0; @@ -577,12 +567,11 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, if (*text != '\0') { textbuffer_line2text(line, FALSE, str); - if (line_matched) - line_matched = -#ifdef HAVE_REGEX_H - regexp ? regexec(&preg, str->str, 0, NULL, 0) == 0 : -#endif - match_func(str->str, text) != NULL; + if (line_matched) { + line_matched = regexp ? + g_regex_match(preg, str->str, 0, NULL) : + match_func(str->str, text) != NULL; + } } if (line_matched) { @@ -610,9 +599,9 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, matches = g_list_append(matches, NULL); } } -#ifdef HAVE_REGEX_H - if (regexp) regfree(&preg); -#endif + + if (regexp) + g_regex_unref(preg); g_string_free(str, TRUE); return matches; } From b5a727c87cf7db944ade9c6714385f1e8598d37e Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Fri, 29 Jan 2016 16:08:40 +0100 Subject: [PATCH 2/7] Remove unused references to regex.h Also remove the prototype for regex_match since it has been removed. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index bf87f5aa..7eb1bfe1 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ AC_PATH_PROG(perlpath, perl) AC_CHECK_HEADERS(unistd.h dirent.h sys/ioctl.h sys/resource.h) # check posix headers.. -AC_CHECK_HEADERS(sys/socket.h sys/time.h sys/utsname.h regex.h) +AC_CHECK_HEADERS(sys/socket.h sys/time.h sys/utsname.h) AC_SYS_LARGEFILE From 3fcd3cd2b9fae07a0b7cd3e5ba91049f19cc6501 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Fri, 29 Jan 2016 16:22:14 +0100 Subject: [PATCH 3/7] Remove the regexp_compiled field. It was made redundant by the introduction of the pointer to the GRegex structure. Silence the compiler warning in textbuffer.c about preg being initialized by setting it to NULL. --- src/core/ignore.c | 14 ++++---------- src/core/ignore.h | 1 - src/fe-common/core/fe-ignore.c | 2 +- src/fe-common/core/hilight-text.c | 13 ++++--------- src/fe-common/core/hilight-text.h | 1 - src/fe-text/textbuffer.c | 2 ++ 6 files changed, 11 insertions(+), 22 deletions(-) diff --git a/src/core/ignore.c b/src/core/ignore.c index 2b8299bd..30cb7cb8 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -66,10 +66,8 @@ static int ignore_match_pattern(IGNORE_REC *rec, const char *text) if (text == NULL) return FALSE; - if (rec->regexp) { - return rec->regexp_compiled && - g_regex_match(rec->preg, text, 0, NULL); - } + if (rec->regexp) + return rec->preg && g_regex_match(rec->preg, text, 0, NULL); return rec->fullword ? stristr_full(text, rec->pattern) != NULL : @@ -322,10 +320,8 @@ static void ignore_remove_config(IGNORE_REC *rec) static void ignore_init_rec(IGNORE_REC *rec) { - if (rec->regexp_compiled) { + if (rec->preg != NULL) g_regex_unref(rec->preg); - rec->regexp_compiled = FALSE; - } if (rec->regexp && rec->pattern != NULL) { GError *re_error; @@ -335,8 +331,6 @@ static void ignore_init_rec(IGNORE_REC *rec) if (rec->preg == NULL) { g_warning("Failed to compile regexp '%s': %s", rec->pattern, re_error->message); g_error_free(re_error); - } else { - rec->regexp_compiled = TRUE; } } } @@ -358,7 +352,7 @@ static void ignore_destroy(IGNORE_REC *rec, int send_signal) if (send_signal) signal_emit("ignore destroyed", 1, rec); - if (rec->regexp_compiled) g_regex_unref(rec->preg); + if (rec->preg != NULL) g_regex_unref(rec->preg); if (rec->channels != NULL) g_strfreev(rec->channels); g_free_not_null(rec->mask); g_free_not_null(rec->servertag); diff --git a/src/core/ignore.h b/src/core/ignore.h index 6c9797f5..f37f8b28 100644 --- a/src/core/ignore.h +++ b/src/core/ignore.h @@ -16,7 +16,6 @@ struct _IGNORE_REC { unsigned int regexp:1; unsigned int fullword:1; unsigned int replies:1; /* ignore replies to nick in channel */ - unsigned int regexp_compiled:1; /* should always be TRUE, unless regexp is invalid */ GRegex *preg; }; diff --git a/src/fe-common/core/fe-ignore.c b/src/fe-common/core/fe-ignore.c index addfa0b8..03fd4dd2 100644 --- a/src/fe-common/core/fe-ignore.c +++ b/src/fe-common/core/fe-ignore.c @@ -58,7 +58,7 @@ static void ignore_print(int index, IGNORE_REC *rec) g_string_append(options, "-regexp "); if (rec->pattern == NULL) g_string_append(options, "[INVALID! -pattern missing] "); - else if (!rec->regexp_compiled) + else if (rec->preg == NULL) g_string_append(options, "[INVALID!] "); } if (rec->fullword) g_string_append(options, "-full "); diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index 83b6f67e..e3dcc2d9 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -101,7 +101,7 @@ static void hilight_destroy(HILIGHT_REC *rec) { g_return_if_fail(rec != NULL); - if (rec->regexp_compiled) g_regex_unref(rec->preg); + if (rec->preg != NULL) g_regex_unref(rec->preg); if (rec->channels != NULL) g_strfreev(rec->channels); g_free_not_null(rec->color); g_free_not_null(rec->act_color); @@ -118,15 +118,10 @@ static void hilights_destroy_all(void) static void hilight_init_rec(HILIGHT_REC *rec) { - if (rec->regexp_compiled) { + if (rec->preg != NULL) g_regex_unref(rec->preg); - rec->regexp_compiled = FALSE; - } rec->preg = g_regex_new(rec->text, G_REGEX_CASELESS, 0, NULL); - - if (rec->preg != NULL) - rec->regexp_compiled = TRUE; } void hilight_create(HILIGHT_REC *rec) @@ -201,7 +196,7 @@ static int hilight_match_text(HILIGHT_REC *rec, const char *text, if (rec->regexp) { GMatchInfo *match; - if (rec->regexp_compiled) { + if (rec->preg != NULL) { g_regex_match (rec->preg, text, 0, &match); if (g_match_info_matches(match)) { @@ -504,7 +499,7 @@ static void hilight_print(int index, HILIGHT_REC *rec) if (rec->case_sensitive) g_string_append(options, "-matchcase "); if (rec->regexp) { g_string_append(options, "-regexp "); - if (!rec->regexp_compiled) + if (rec->preg == NULL) g_string_append(options, "[INVALID!] "); } diff --git a/src/fe-common/core/hilight-text.h b/src/fe-common/core/hilight-text.h index a74c38b0..93c573c2 100644 --- a/src/fe-common/core/hilight-text.h +++ b/src/fe-common/core/hilight-text.h @@ -20,7 +20,6 @@ struct _HILIGHT_REC { unsigned int fullword:1; /* match `text' only for full words */ unsigned int regexp:1; /* `text' is a regular expression */ unsigned int case_sensitive:1;/* `text' must match case */ - unsigned int regexp_compiled:1; /* should always be TRUE, unless regexp is invalid */ GRegex *preg; char *servertag; }; diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index 979b2a46..7d0806d1 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -543,6 +543,8 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, g_return_val_if_fail(buffer != NULL, NULL); g_return_val_if_fail(text != NULL, NULL); + preg = NULL; + if (regexp) { preg = g_regex_new(text, (case_sensitive ? 0 : G_REGEX_CASELESS), 0, NULL); From 5eaead761f1812fb9d4058b2bc38468521794693 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sun, 19 Jun 2016 21:08:25 +0200 Subject: [PATCH 4/7] Rebase against master. --- src/core/ignore.c | 6 ++++-- src/fe-text/textbuffer.c | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/ignore.c b/src/core/ignore.c index 30cb7cb8..c91f6e4a 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -66,8 +66,10 @@ static int ignore_match_pattern(IGNORE_REC *rec, const char *text) if (text == NULL) return FALSE; - if (rec->regexp) - return rec->preg && g_regex_match(rec->preg, text, 0, NULL); + if (rec->regexp) { + return rec->preg != NULL && + g_regex_match(rec->preg, text, 0, NULL); + } return rec->fullword ? stristr_full(text, rec->pattern) != NULL : diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index 7d0806d1..f35848a2 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -570,7 +570,7 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, textbuffer_line2text(line, FALSE, str); if (line_matched) { - line_matched = regexp ? + line_matched = regexp ? g_regex_match(preg, str->str, 0, NULL) : match_func(str->str, text) != NULL; } From 5dcf291f2144564363f734dba15760d3a82b61c2 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Thu, 23 Jun 2016 13:25:23 +0200 Subject: [PATCH 5/7] Use the RAW flag when building the regexps. Also, plugged a memory leak when retrieving the match position. --- src/core/ignore.c | 2 +- src/fe-common/core/hilight-text.c | 23 +++++++++++++---------- src/fe-text/textbuffer.c | 4 ++-- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/core/ignore.c b/src/core/ignore.c index c91f6e4a..cfcbd792 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -328,7 +328,7 @@ static void ignore_init_rec(IGNORE_REC *rec) if (rec->regexp && rec->pattern != NULL) { GError *re_error; - rec->preg = g_regex_new(rec->pattern, G_REGEX_CASELESS, 0, &re_error); + rec->preg = g_regex_new(rec->pattern, G_REGEX_OPTIMIZE | G_REGEX_RAW | G_REGEX_CASELESS, 0, &re_error); if (rec->preg == NULL) { g_warning("Failed to compile regexp '%s': %s", rec->pattern, re_error->message); diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index e3dcc2d9..7a7f473c 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -121,7 +121,7 @@ static void hilight_init_rec(HILIGHT_REC *rec) if (rec->preg != NULL) g_regex_unref(rec->preg); - rec->preg = g_regex_new(rec->text, G_REGEX_CASELESS, 0, NULL); + rec->preg = g_regex_new(rec->text, G_REGEX_OPTIMIZE | G_REGEX_RAW | G_REGEX_CASELESS, 0, NULL); } void hilight_create(HILIGHT_REC *rec) @@ -188,22 +188,25 @@ static HILIGHT_REC *hilight_find(const char *text, char **channels) return NULL; } -static int hilight_match_text(HILIGHT_REC *rec, const char *text, +static gboolean hilight_match_text(HILIGHT_REC *rec, const char *text, int *match_beg, int *match_end) { - char *match; + gboolean ret = FALSE; if (rec->regexp) { - GMatchInfo *match; - if (rec->preg != NULL) { + GMatchInfo *match; + g_regex_match (rec->preg, text, 0, &match); - if (g_match_info_matches(match)) { - return g_match_info_fetch_pos(match, 0, match_beg, match_end); - } + if (g_match_info_matches(match)) + ret = g_match_info_fetch_pos(match, 0, match_beg, match_end); + + g_match_info_free(match); } } else { + char *match; + if (rec->case_sensitive) { match = rec->fullword ? strstr_full(text, rec->text) : @@ -218,11 +221,11 @@ static int hilight_match_text(HILIGHT_REC *rec, const char *text, *match_beg = (int) (match-text); *match_end = *match_beg + strlen(rec->text); } - return TRUE; + ret = TRUE; } } - return FALSE; + return ret; } #define hilight_match_level(rec, level) \ diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index f35848a2..979a6104 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -546,7 +546,7 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, preg = NULL; if (regexp) { - preg = g_regex_new(text, (case_sensitive ? 0 : G_REGEX_CASELESS), 0, NULL); + preg = g_regex_new(text, G_REGEX_RAW | (case_sensitive ? 0 : G_REGEX_CASELESS), 0, NULL); if (preg == NULL) return NULL; @@ -602,7 +602,7 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, } } - if (regexp) + if (preg != NULL) g_regex_unref(preg); g_string_free(str, TRUE); return matches; From f5cbbebc2ee858e8792ab40eea6abc9fd7865a28 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Tue, 3 Jan 2017 12:04:56 +0100 Subject: [PATCH 6/7] switch for gregex and regex.h --- configure.ac | 16 ++++++++++++++++ src/core/ignore.c | 31 ++++++++++++++++++++++++++++++ src/core/ignore.h | 9 +++++++++ src/core/misc.c | 4 ++++ src/fe-common/core/fe-ignore.c | 5 +++++ src/fe-common/core/hilight-text.c | 32 +++++++++++++++++++++++++++++++ src/fe-common/core/hilight-text.h | 9 +++++++++ src/fe-text/textbuffer.c | 29 ++++++++++++++++++++++++++-- 8 files changed, 133 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 7eb1bfe1..8d588408 100644 --- a/configure.ac +++ b/configure.ac @@ -144,6 +144,15 @@ AC_ARG_ENABLE(true-color, fi, want_truecolor=no) +AC_ARG_ENABLE(gregex, +[ --disable-gregex Build without GRegex (fall back to regex.h)], + if test x$enableval = xno ; then + want_gregex=no + else + want_gregex=yes + fi, + want_gregex=yes) + dnl ** dnl ** just some generic stuff... dnl ** @@ -534,6 +543,12 @@ else want_truecolor=no fi +if test "x$want_gregex" = "xyes"; then + AC_DEFINE([USE_GREGEX], [], [use GRegex for regular expressions]) +else + want_gregex=no +fi + AH_TEMPLATE(HAVE_GMODULE) AH_TEMPLATE(HAVE_SOCKS_H, [misc..]) AH_TEMPLATE(HAVE_STATIC_PERL) @@ -648,6 +663,7 @@ echo echo "Building with 64bit DCC support .. : $offt_64bit" echo "Building with true color support.. : $want_truecolor" +echo "Building with GRegex ............. : $want_gregex" echo echo "If there are any problems, read the INSTALL file." diff --git a/src/core/ignore.c b/src/core/ignore.c index cfcbd792..bf8db04f 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -67,8 +67,13 @@ static int ignore_match_pattern(IGNORE_REC *rec, const char *text) return FALSE; if (rec->regexp) { +#ifdef USE_GREGEX return rec->preg != NULL && g_regex_match(rec->preg, text, 0, NULL); +#else + return rec->regexp_compiled && + regexec(&rec->preg, text, 0, NULL, 0) == 0; +#endif } return rec->fullword ? @@ -322,6 +327,7 @@ static void ignore_remove_config(IGNORE_REC *rec) static void ignore_init_rec(IGNORE_REC *rec) { +#ifdef USE_GREGEX if (rec->preg != NULL) g_regex_unref(rec->preg); @@ -335,6 +341,27 @@ static void ignore_init_rec(IGNORE_REC *rec) g_error_free(re_error); } } +#else + char *errbuf; + int errcode, errbuf_len; + + if (rec->regexp_compiled) regfree(&rec->preg); + rec->regexp_compiled = FALSE; + + if (rec->regexp && rec->pattern != NULL) { + errcode = regcomp(&rec->preg, rec->pattern, + REG_EXTENDED|REG_ICASE|REG_NOSUB); + if (errcode != 0) { + errbuf_len = regerror(errcode, &rec->preg, 0, 0); + errbuf = g_malloc(errbuf_len); + regerror(errcode, &rec->preg, errbuf, errbuf_len); + g_warning("Failed to compile regexp '%s': %s", rec->pattern, errbuf); + g_free(errbuf); + } else { + rec->regexp_compiled = TRUE; + } + } +#endif } void ignore_add_rec(IGNORE_REC *rec) @@ -354,7 +381,11 @@ static void ignore_destroy(IGNORE_REC *rec, int send_signal) if (send_signal) signal_emit("ignore destroyed", 1, rec); +#ifdef USE_GREGEX if (rec->preg != NULL) g_regex_unref(rec->preg); +#else + if (rec->regexp_compiled) regfree(&rec->preg); +#endif if (rec->channels != NULL) g_strfreev(rec->channels); g_free_not_null(rec->mask); g_free_not_null(rec->servertag); diff --git a/src/core/ignore.h b/src/core/ignore.h index f37f8b28..80ae1d12 100644 --- a/src/core/ignore.h +++ b/src/core/ignore.h @@ -1,6 +1,10 @@ #ifndef __IGNORE_H #define __IGNORE_H +#ifndef USE_GREGEX +# include +#endif + typedef struct _IGNORE_REC IGNORE_REC; struct _IGNORE_REC { @@ -16,7 +20,12 @@ struct _IGNORE_REC { unsigned int regexp:1; unsigned int fullword:1; unsigned int replies:1; /* ignore replies to nick in channel */ +#ifdef USE_GREGEX GRegex *preg; +#else + unsigned int regexp_compiled:1; /* should always be TRUE, unless regexp is invalid */ + regex_t preg; +#endif }; extern GSList *ignores; diff --git a/src/core/misc.c b/src/core/misc.c index c59eb126..1cfa15b6 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -22,6 +22,10 @@ #include "misc.h" #include "commands.h" +#ifndef USE_GREGEX +# include +#endif + typedef struct { int condition; GInputFunction function; diff --git a/src/fe-common/core/fe-ignore.c b/src/fe-common/core/fe-ignore.c index 03fd4dd2..800e881d 100644 --- a/src/fe-common/core/fe-ignore.c +++ b/src/fe-common/core/fe-ignore.c @@ -58,8 +58,13 @@ static void ignore_print(int index, IGNORE_REC *rec) g_string_append(options, "-regexp "); if (rec->pattern == NULL) g_string_append(options, "[INVALID! -pattern missing] "); +#ifdef USE_GREGEX else if (rec->preg == NULL) g_string_append(options, "[INVALID!] "); +#else + else if (!rec->regexp_compiled) + g_string_append(options, "[INVALID!] "); +#endif } if (rec->fullword) g_string_append(options, "-full "); if (rec->replies) g_string_append(options, "-replies "); diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index 7a7f473c..037cde5c 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -101,7 +101,11 @@ static void hilight_destroy(HILIGHT_REC *rec) { g_return_if_fail(rec != NULL); +#ifdef USE_GREGEX if (rec->preg != NULL) g_regex_unref(rec->preg); +#else + if (rec->regexp_compiled) regfree(&rec->preg); +#endif if (rec->channels != NULL) g_strfreev(rec->channels); g_free_not_null(rec->color); g_free_not_null(rec->act_color); @@ -118,10 +122,19 @@ static void hilights_destroy_all(void) static void hilight_init_rec(HILIGHT_REC *rec) { +#ifdef USE_GREGEX if (rec->preg != NULL) g_regex_unref(rec->preg); rec->preg = g_regex_new(rec->text, G_REGEX_OPTIMIZE | G_REGEX_RAW | G_REGEX_CASELESS, 0, NULL); +#else + if (rec->regexp_compiled) regfree(&rec->preg); + if (!rec->regexp) + rec->regexp_compiled = FALSE; + else + rec->regexp_compiled = regcomp(&rec->preg, rec->text, + rec->case_sensitive ? REG_EXTENDED : (REG_EXTENDED|REG_ICASE)) == 0; +#endif } void hilight_create(HILIGHT_REC *rec) @@ -194,6 +207,7 @@ static gboolean hilight_match_text(HILIGHT_REC *rec, const char *text, gboolean ret = FALSE; if (rec->regexp) { +#ifdef USE_GREGEX if (rec->preg != NULL) { GMatchInfo *match; @@ -204,6 +218,19 @@ static gboolean hilight_match_text(HILIGHT_REC *rec, const char *text, g_match_info_free(match); } +#else + regmatch_t rmatch[1]; + + if (rec->regexp_compiled && + regexec(&rec->preg, text, 1, rmatch, 0) == 0) { + if (rmatch[0].rm_so > 0 && + match_beg != NULL && match_end != NULL) { + *match_beg = rmatch[0].rm_so; + *match_end = rmatch[0].rm_eo; + } + ret = TRUE; + } +#endif } else { char *match; @@ -502,8 +529,13 @@ static void hilight_print(int index, HILIGHT_REC *rec) if (rec->case_sensitive) g_string_append(options, "-matchcase "); if (rec->regexp) { g_string_append(options, "-regexp "); +#ifdef USE_GREGEX if (rec->preg == NULL) g_string_append(options, "[INVALID!] "); +#else + if (!rec->regexp_compiled) + g_string_append(options, "[INVALID!] "); +#endif } if (rec->priority != 0) diff --git a/src/fe-common/core/hilight-text.h b/src/fe-common/core/hilight-text.h index 93c573c2..76beec1f 100644 --- a/src/fe-common/core/hilight-text.h +++ b/src/fe-common/core/hilight-text.h @@ -1,6 +1,10 @@ #ifndef __HILIGHT_TEXT_H #define __HILIGHT_TEXT_H +#ifndef USE_GREGEX +# include +#endif + #include "formats.h" struct _HILIGHT_REC { @@ -20,7 +24,12 @@ struct _HILIGHT_REC { unsigned int fullword:1; /* match `text' only for full words */ unsigned int regexp:1; /* `text' is a regular expression */ unsigned int case_sensitive:1;/* `text' must match case */ +#ifdef USE_GREGEX GRegex *preg; +#else + unsigned int regexp_compiled:1; /* should always be TRUE, unless regexp is invalid */ + regex_t preg; +#endif char *servertag; }; diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index 979a6104..ae4636a5 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -27,6 +27,10 @@ #include "textbuffer.h" +#ifndef USE_GREGEX +# include +#endif + #define TEXT_CHUNK_USABLE_SIZE (LINE_TEXT_CHUNK_SIZE-2-(int)sizeof(char*)) TEXT_BUFFER_REC *textbuffer_create(void) @@ -533,7 +537,11 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, int before, int after, int regexp, int fullword, int case_sensitive) { +#ifdef USE_GREGEX GRegex *preg; +#else + regex_t preg; +#endif LINE_REC *line, *pre_line; GList *matches; GString *str; @@ -543,6 +551,7 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, g_return_val_if_fail(buffer != NULL, NULL); g_return_val_if_fail(text != NULL, NULL); +#ifdef USE_GREGEX preg = NULL; if (regexp) { @@ -551,6 +560,14 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, if (preg == NULL) return NULL; } +#else + if (regexp) { + int flags = REG_EXTENDED | REG_NOSUB | + (case_sensitive ? 0 : REG_ICASE); + if (regcomp(&preg, text, flags) != 0) + return NULL; + } +#endif matches = NULL; match_after = 0; str = g_string_new(NULL); @@ -571,8 +588,12 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, if (line_matched) { line_matched = regexp ? - g_regex_match(preg, str->str, 0, NULL) : - match_func(str->str, text) != NULL; +#ifdef USE_GREGEX + g_regex_match(preg, str->str, 0, NULL) +#else + regexec(&preg, str->str, 0, NULL, 0) == 0 +#endif + : match_func(str->str, text) != NULL; } } @@ -602,8 +623,12 @@ GList *textbuffer_find_text(TEXT_BUFFER_REC *buffer, LINE_REC *startline, } } +#ifdef USE_GREGEX if (preg != NULL) g_regex_unref(preg); +#else + if (regexp) regfree(&preg); +#endif g_string_free(str, TRUE); return matches; } From 1f72b8e66a06b484dde20b6031c766a2129e0bd2 Mon Sep 17 00:00:00 2001 From: Ailin Nemui Date: Tue, 3 Jan 2017 12:29:52 +0100 Subject: [PATCH 7/7] up abi version --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index 0a7b72f0..43596580 100644 --- a/src/common.h +++ b/src/common.h @@ -6,7 +6,7 @@ #define IRSSI_GLOBAL_CONFIG "irssi.conf" /* config file name in /etc/ */ #define IRSSI_HOME_CONFIG "config" /* config file name in ~/.irssi/ */ -#define IRSSI_ABI_VERSION 6 +#define IRSSI_ABI_VERSION 7 #define DEFAULT_SERVER_ADD_PORT 6667