Revision: 5976 http://geany.svn.sourceforge.net/geany/?rev=5976&view=rev Author: ntrel Date: 2011-09-30 14:43:18 +0000 (Fri, 30 Sep 2011) Log Message: ----------- Use GRegex for CTags instead of POSIX regex - GRegex is more powerful. This also fixes a (HTML) performance issue on Windows. Geany will now print a debug warning when using the "b" CTags regex flag option for non-extended syntax. This is not currently used by Geany's parsers. Note: GNU regex can't be removed yet as it's still used elsewhere by Geany.
Modified Paths: -------------- branches/unstable/ChangeLog branches/unstable/TODO branches/unstable/tagmanager/lregex.c
Modified: branches/unstable/ChangeLog =================================================================== --- branches/unstable/ChangeLog 2011-09-30 11:14:23 UTC (rev 5975) +++ branches/unstable/ChangeLog 2011-09-30 14:43:18 UTC (rev 5976) @@ -3,6 +3,14 @@ * src/utils.c, src/utils.h, src/editor.c: Use GRegex for snippet indentation replacement - fixes wrong behaviour with Mac line endings. + * tagmanager/lregex.c, TODO: + Use GRegex for CTags instead of POSIX regex - GRegex is more + powerful. This also fixes a (HTML) performance issue on Windows. + Geany will now print a debug warning when using the "b" CTags + regex flag option for non-extended syntax. This is not currently + used by Geany's parsers. + Note: GNU regex can't be removed yet as it's still used elsewhere + by Geany.
2011-09-29 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
Modified: branches/unstable/TODO =================================================================== --- branches/unstable/TODO 2011-09-30 11:14:23 UTC (rev 5975) +++ branches/unstable/TODO 2011-09-30 14:43:18 UTC (rev 5976) @@ -14,7 +14,7 @@ o common default highlighting styles configurable for all programming languages (done for C-like filetypes using filetypes.common named styles) - o update included regex library (and other CTags improvements) + o use GRegex only and remove GNU regex o asynchronous build commands on Windows o (filetype-independent run command in build dialog & keybinding) o (better custom filetype support)
Modified: branches/unstable/tagmanager/lregex.c =================================================================== --- branches/unstable/tagmanager/lregex.c 2011-09-30 11:14:23 UTC (rev 5975) +++ branches/unstable/tagmanager/lregex.c 2011-09-30 14:43:18 UTC (rev 5976) @@ -28,11 +28,6 @@ # ifdef HAVE_SYS_TYPES_H # include <sys/types.h> /* declare off_t (not known to regex.h on FreeBSD) */ # endif -# ifdef HAVE_REGEX_H -# include <regex.h> -# else -# include "gnuregex.h" -# endif #endif
#include "main.h" @@ -70,7 +65,7 @@ enum pType { PTRN_TAG, PTRN_CALLBACK };
typedef struct { - regex_t *pattern; + GRegex *pattern; enum pType type; union { struct { @@ -113,10 +108,7 @@ for (i = 0 ; i < set->count ; ++i) { regexPattern *p = &set->patterns [i]; -#if defined (POSIX_REGEX) - regfree (p->pattern); -#endif - eFree (p->pattern); + g_regex_unref(p->pattern); p->pattern = NULL;
if (p->type == PTRN_TAG) @@ -255,7 +247,7 @@ }
static void addCompiledTagPattern ( - const langType language, regex_t* const pattern, + const langType language, GRegex* const pattern, char* const name, const char kind, char* const kindName, char *const description) { @@ -287,7 +279,7 @@ }
static void addCompiledCallbackPattern ( - const langType language, regex_t* const pattern, + const langType language, GRegex* const pattern, const regexCallback callback) { patternSet* set; @@ -315,32 +307,27 @@
#if defined (POSIX_REGEX)
-static regex_t* compileRegex (const char* const regexp, const char* const flags) +static GRegex* compileRegex (const char* const regexp, const char* const flags) { - int cflags = REG_EXTENDED | REG_NEWLINE; - regex_t *result = NULL; - int errcode; + int cflags = G_REGEX_MULTILINE; + GRegex *result = NULL; + GError *error = NULL; int i; for (i = 0 ; flags != NULL && flags [i] != '\0' ; ++i) { switch ((int) flags [i]) { - case 'b': cflags &= ~REG_EXTENDED; break; - case 'e': cflags |= REG_EXTENDED; break; - case 'i': cflags |= REG_ICASE; break; + case 'b': g_warning("CTags 'b' flag not supported by Geany!"); break; + case 'e': break; + case 'i': cflags |= G_REGEX_CASELESS; break; default: printf ("regex: unknown regex flag: '%c'\n", *flags); break; } } - result = xMalloc (1, regex_t); - errcode = regcomp (result, regexp, cflags); - if (errcode != 0) + result = g_regex_new(regexp, cflags, 0, &error); + if (error) { - char errmsg[256]; - regerror (errcode, result, errmsg, 256); - printf ("regex: regcomp %s: %s\n", regexp, errmsg); - regfree (result); - eFree (result); - result = NULL; + printf ("regex: regcomp %s: %s\n", regexp, error->message); + g_error_free(error); } return result; } @@ -433,7 +420,7 @@
static vString* substitute ( const char* const in, const char* out, - const int nmatch, const regmatch_t* const pmatch) + const int nmatch, const GMatchInfo* const minfo) { vString* result = vStringNew (); const char* p; @@ -442,10 +429,12 @@ if (*p == '\' && isdigit ((int) *++p)) { const int dig = *p - '0'; - if (0 < dig && dig < nmatch && pmatch [dig].rm_so != -1) + int so, eo; + if (0 < dig && dig < nmatch && + g_match_info_fetch_pos(minfo, dig, &so, &eo) && so != -1) { - const int diglen = pmatch [dig].rm_eo - pmatch [dig].rm_so; - vStringNCatS (result, in + pmatch [dig].rm_so, diglen); + const int diglen = eo - so; + vStringNCatS (result, in + so, diglen); } } else if (*p != '\n' && *p != '\r') @@ -457,10 +446,10 @@
static void matchTagPattern (const vString* const line, const regexPattern* const patbuf, - const regmatch_t* const pmatch) + const GMatchInfo* const minfo) { vString *const name = substitute (vStringValue (line), - patbuf->u.tag.name_pattern, BACK_REFERENCE_COUNT, pmatch); + patbuf->u.tag.name_pattern, BACK_REFERENCE_COUNT, minfo); vStringStripLeading (name); vStringStripTrailing (name); if (vStringLength (name) > 0) @@ -474,15 +463,18 @@
static void matchCallbackPattern ( const vString* const line, const regexPattern* const patbuf, - const regmatch_t* const pmatch) + const GMatchInfo* const minfo) { regexMatch matches [BACK_REFERENCE_COUNT]; unsigned int count = 0; int i; - for (i = 0 ; i < BACK_REFERENCE_COUNT && pmatch [i].rm_so != -1 ; ++i) + for (i = 0 ; i < BACK_REFERENCE_COUNT ; ++i) { - matches [i].start = pmatch [i].rm_so; - matches [i].length = pmatch [i].rm_eo - pmatch [i].rm_so; + int so, eo; + if (!g_match_info_fetch_pos(minfo, i, &so, &eo) || so == -1) + break; + matches [i].start = so; + matches [i].length = eo - so; ++count; } patbuf->u.callback.function (vStringValue (line), matches, count); @@ -492,22 +484,21 @@ const regexPattern* const patbuf) { boolean result = FALSE; - regmatch_t pmatch [BACK_REFERENCE_COUNT]; - const int match = regexec (patbuf->pattern, vStringValue (line), - BACK_REFERENCE_COUNT, pmatch, 0); - if (match == 0) + GMatchInfo *minfo; + if (g_regex_match(patbuf->pattern, vStringValue(line), 0, &minfo)) { result = TRUE; if (patbuf->type == PTRN_TAG) - matchTagPattern (line, patbuf, pmatch); + matchTagPattern (line, patbuf, minfo); else if (patbuf->type == PTRN_CALLBACK) - matchCallbackPattern (line, patbuf, pmatch); + matchCallbackPattern (line, patbuf, minfo); else { Assert ("invalid pattern type" == NULL); result = FALSE; } } + g_match_info_free(minfo); return result; }
@@ -554,7 +545,7 @@ Assert (name != NULL); if (! regexBroken) { - regex_t* const cp = compileRegex (regex, flags); + GRegex* const cp = compileRegex (regex, flags); if (cp != NULL) { char kind; @@ -578,7 +569,7 @@ Assert (regex != NULL); if (! regexBroken) { - regex_t* const cp = compileRegex (regex, flags); + GRegex* const cp = compileRegex (regex, flags); if (cp != NULL) addCompiledCallbackPattern (language, cp, callback); } @@ -695,7 +686,7 @@ /* Check for broken regcomp() on Cygwin */ extern void checkRegex (void) { -#if defined (HAVE_REGEX) && defined (CHECK_REGCOMP) +#if 0 && defined (HAVE_REGEX) && defined (CHECK_REGCOMP) regex_t patbuf; int errcode; if (regcomp (&patbuf, "/hello/", 0) != 0)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.