Kaydet (Commit) b079b19d authored tarafından Nick Treleaven's avatar Nick Treleaven

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.



git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/branches/unstable@5976 ea778897-0a13-0410-b9d1-a72fbfd435f5
üst 53a0121f
...@@ -3,6 +3,14 @@ ...@@ -3,6 +3,14 @@
* src/utils.c, src/utils.h, src/editor.c: * src/utils.c, src/utils.h, src/editor.c:
Use GRegex for snippet indentation replacement - fixes wrong Use GRegex for snippet indentation replacement - fixes wrong
behaviour with Mac line endings. 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> 2011-09-29 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
......
...@@ -14,7 +14,7 @@ Note: features included in brackets have lower priority. ...@@ -14,7 +14,7 @@ Note: features included in brackets have lower priority.
o common default highlighting styles configurable for all o common default highlighting styles configurable for all
programming languages (done for C-like filetypes using programming languages (done for C-like filetypes using
filetypes.common named styles) 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 asynchronous build commands on Windows
o (filetype-independent run command in build dialog & keybinding) o (filetype-independent run command in build dialog & keybinding)
o (better custom filetype support) o (better custom filetype support)
......
...@@ -28,11 +28,6 @@ ...@@ -28,11 +28,6 @@
# ifdef HAVE_SYS_TYPES_H # ifdef HAVE_SYS_TYPES_H
# include <sys/types.h> /* declare off_t (not known to regex.h on FreeBSD) */ # include <sys/types.h> /* declare off_t (not known to regex.h on FreeBSD) */
# endif # endif
# ifdef HAVE_REGEX_H
# include <regex.h>
# else
# include "gnuregex.h"
# endif
#endif #endif
#include "main.h" #include "main.h"
...@@ -70,7 +65,7 @@ struct sKind { ...@@ -70,7 +65,7 @@ struct sKind {
enum pType { PTRN_TAG, PTRN_CALLBACK }; enum pType { PTRN_TAG, PTRN_CALLBACK };
typedef struct { typedef struct {
regex_t *pattern; GRegex *pattern;
enum pType type; enum pType type;
union { union {
struct { struct {
...@@ -113,10 +108,7 @@ static void clearPatternSet (const langType language) ...@@ -113,10 +108,7 @@ static void clearPatternSet (const langType language)
for (i = 0 ; i < set->count ; ++i) for (i = 0 ; i < set->count ; ++i)
{ {
regexPattern *p = &set->patterns [i]; regexPattern *p = &set->patterns [i];
#if defined (POSIX_REGEX) g_regex_unref(p->pattern);
regfree (p->pattern);
#endif
eFree (p->pattern);
p->pattern = NULL; p->pattern = NULL;
if (p->type == PTRN_TAG) if (p->type == PTRN_TAG)
...@@ -255,7 +247,7 @@ static boolean parseTagRegex ( ...@@ -255,7 +247,7 @@ static boolean parseTagRegex (
} }
static void addCompiledTagPattern ( 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 name, const char kind, char* const kindName,
char *const description) char *const description)
{ {
...@@ -287,7 +279,7 @@ static void addCompiledTagPattern ( ...@@ -287,7 +279,7 @@ static void addCompiledTagPattern (
} }
static void addCompiledCallbackPattern ( static void addCompiledCallbackPattern (
const langType language, regex_t* const pattern, const langType language, GRegex* const pattern,
const regexCallback callback) const regexCallback callback)
{ {
patternSet* set; patternSet* set;
...@@ -315,32 +307,27 @@ static void addCompiledCallbackPattern ( ...@@ -315,32 +307,27 @@ static void addCompiledCallbackPattern (
#if defined (POSIX_REGEX) #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; int cflags = G_REGEX_MULTILINE;
regex_t *result = NULL; GRegex *result = NULL;
int errcode; GError *error = NULL;
int i; int i;
for (i = 0 ; flags != NULL && flags [i] != '\0' ; ++i) for (i = 0 ; flags != NULL && flags [i] != '\0' ; ++i)
{ {
switch ((int) flags [i]) switch ((int) flags [i])
{ {
case 'b': cflags &= ~REG_EXTENDED; break; case 'b': g_warning("CTags 'b' flag not supported by Geany!"); break;
case 'e': cflags |= REG_EXTENDED; break; case 'e': break;
case 'i': cflags |= REG_ICASE; break; case 'i': cflags |= G_REGEX_CASELESS; break;
default: printf ("regex: unknown regex flag: '%c'\n", *flags); break; default: printf ("regex: unknown regex flag: '%c'\n", *flags); break;
} }
} }
result = xMalloc (1, regex_t); result = g_regex_new(regexp, cflags, 0, &error);
errcode = regcomp (result, regexp, cflags); if (error)
if (errcode != 0)
{ {
char errmsg[256]; printf ("regex: regcomp %s: %s\n", regexp, error->message);
regerror (errcode, result, errmsg, 256); g_error_free(error);
printf ("regex: regcomp %s: %s\n", regexp, errmsg);
regfree (result);
eFree (result);
result = NULL;
} }
return result; return result;
} }
...@@ -433,7 +420,7 @@ static void processLanguageRegex (const langType language, ...@@ -433,7 +420,7 @@ static void processLanguageRegex (const langType language,
static vString* substitute ( static vString* substitute (
const char* const in, const char* out, 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 (); vString* result = vStringNew ();
const char* p; const char* p;
...@@ -442,10 +429,12 @@ static vString* substitute ( ...@@ -442,10 +429,12 @@ static vString* substitute (
if (*p == '\\' && isdigit ((int) *++p)) if (*p == '\\' && isdigit ((int) *++p))
{ {
const int dig = *p - '0'; 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; const int diglen = eo - so;
vStringNCatS (result, in + pmatch [dig].rm_so, diglen); vStringNCatS (result, in + so, diglen);
} }
} }
else if (*p != '\n' && *p != '\r') else if (*p != '\n' && *p != '\r')
...@@ -457,10 +446,10 @@ static vString* substitute ( ...@@ -457,10 +446,10 @@ static vString* substitute (
static void matchTagPattern (const vString* const line, static void matchTagPattern (const vString* const line,
const regexPattern* const patbuf, const regexPattern* const patbuf,
const regmatch_t* const pmatch) const GMatchInfo* const minfo)
{ {
vString *const name = substitute (vStringValue (line), 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); vStringStripLeading (name);
vStringStripTrailing (name); vStringStripTrailing (name);
if (vStringLength (name) > 0) if (vStringLength (name) > 0)
...@@ -474,15 +463,18 @@ static void matchTagPattern (const vString* const line, ...@@ -474,15 +463,18 @@ static void matchTagPattern (const vString* const line,
static void matchCallbackPattern ( static void matchCallbackPattern (
const vString* const line, const regexPattern* const patbuf, const vString* const line, const regexPattern* const patbuf,
const regmatch_t* const pmatch) const GMatchInfo* const minfo)
{ {
regexMatch matches [BACK_REFERENCE_COUNT]; regexMatch matches [BACK_REFERENCE_COUNT];
unsigned int count = 0; unsigned int count = 0;
int i; 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; int so, eo;
matches [i].length = pmatch [i].rm_eo - pmatch [i].rm_so; if (!g_match_info_fetch_pos(minfo, i, &so, &eo) || so == -1)
break;
matches [i].start = so;
matches [i].length = eo - so;
++count; ++count;
} }
patbuf->u.callback.function (vStringValue (line), matches, count); patbuf->u.callback.function (vStringValue (line), matches, count);
...@@ -492,22 +484,21 @@ static boolean matchRegexPattern (const vString* const line, ...@@ -492,22 +484,21 @@ static boolean matchRegexPattern (const vString* const line,
const regexPattern* const patbuf) const regexPattern* const patbuf)
{ {
boolean result = FALSE; boolean result = FALSE;
regmatch_t pmatch [BACK_REFERENCE_COUNT]; GMatchInfo *minfo;
const int match = regexec (patbuf->pattern, vStringValue (line), if (g_regex_match(patbuf->pattern, vStringValue(line), 0, &minfo))
BACK_REFERENCE_COUNT, pmatch, 0);
if (match == 0)
{ {
result = TRUE; result = TRUE;
if (patbuf->type == PTRN_TAG) if (patbuf->type == PTRN_TAG)
matchTagPattern (line, patbuf, pmatch); matchTagPattern (line, patbuf, minfo);
else if (patbuf->type == PTRN_CALLBACK) else if (patbuf->type == PTRN_CALLBACK)
matchCallbackPattern (line, patbuf, pmatch); matchCallbackPattern (line, patbuf, minfo);
else else
{ {
Assert ("invalid pattern type" == NULL); Assert ("invalid pattern type" == NULL);
result = FALSE; result = FALSE;
} }
} }
g_match_info_free(minfo);
return result; return result;
} }
...@@ -554,7 +545,7 @@ extern void addTagRegex ( ...@@ -554,7 +545,7 @@ extern void addTagRegex (
Assert (name != NULL); Assert (name != NULL);
if (! regexBroken) if (! regexBroken)
{ {
regex_t* const cp = compileRegex (regex, flags); GRegex* const cp = compileRegex (regex, flags);
if (cp != NULL) if (cp != NULL)
{ {
char kind; char kind;
...@@ -578,7 +569,7 @@ extern void addCallbackRegex ( ...@@ -578,7 +569,7 @@ extern void addCallbackRegex (
Assert (regex != NULL); Assert (regex != NULL);
if (! regexBroken) if (! regexBroken)
{ {
regex_t* const cp = compileRegex (regex, flags); GRegex* const cp = compileRegex (regex, flags);
if (cp != NULL) if (cp != NULL)
addCompiledCallbackPattern (language, cp, callback); addCompiledCallbackPattern (language, cp, callback);
} }
...@@ -695,7 +686,7 @@ extern void freeRegexResources (void) ...@@ -695,7 +686,7 @@ extern void freeRegexResources (void)
/* Check for broken regcomp() on Cygwin */ /* Check for broken regcomp() on Cygwin */
extern void checkRegex (void) extern void checkRegex (void)
{ {
#if defined (HAVE_REGEX) && defined (CHECK_REGCOMP) #if 0 && defined (HAVE_REGEX) && defined (CHECK_REGCOMP)
regex_t patbuf; regex_t patbuf;
int errcode; int errcode;
if (regcomp (&patbuf, "/hello/", 0) != 0) if (regcomp (&patbuf, "/hello/", 0) != 0)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment