Branch: refs/heads/master Author: Jiří Techet techet@gmail.com Committer: Jiří Techet techet@gmail.com Date: Wed, 12 Oct 2016 15:09:19 UTC Commit: 501ebe94d59ea21a590d501019a24541e900fb6b https://github.com/geany/geany/commit/501ebe94d59ea21a590d501019a24541e900fb...
Log Message: ----------- lregex: Initialize lregex structures the universal-ctags way
I didn't check in detail what the changes are but since no GRegex code is involved and since everything seems to work after the patch, I think it's OK.
Modified Paths: -------------- ctags/main/lregex.c
Modified: ctags/main/lregex.c 196 lines changed, 145 insertions(+), 51 deletions(-) =================================================================== @@ -51,6 +51,11 @@ static bool regexAvailable = true; * DATA DECLARATIONS */
+union cptr { + char c; + void *p; +}; + enum pType { PTRN_TAG, PTRN_CALLBACK };
typedef struct { @@ -59,7 +64,7 @@ typedef struct { union { struct { char *name_pattern; - kindOption kind; + kindOption *kind; } tag; struct { regexCallback function; @@ -71,6 +76,7 @@ typedef struct { typedef struct { regexPattern *patterns; unsigned int count; + hashTable *kinds; } patternSet;
/* @@ -102,24 +108,20 @@ static void clearPatternSet (const langType language) { eFree (p->u.tag.name_pattern); p->u.tag.name_pattern = NULL; - eFree ((char *)p->u.tag.kind.name); - p->u.tag.kind.name = NULL; - if (p->u.tag.kind.description != NULL) - { - eFree ((char *)p->u.tag.kind.description); - p->u.tag.kind.description = NULL; - } + p->u.tag.kind = NULL; } } if (set->patterns != NULL) eFree (set->patterns); set->patterns = NULL; set->count = 0; + hashTableDelete (set->kinds); + set->kinds = NULL; } }
/* -* Regex psuedo-parser +* Regex pseudo-parser */
static void makeRegexTag ( @@ -229,44 +231,45 @@ static bool parseTagRegex ( return result; }
-static void addCompiledTagPattern ( - const langType language, GRegex* const pattern, - char* const name, const char kind, char* const kindName, - char *const description) + +static kindOption *kindNew () { - patternSet* set; - regexPattern *ptrn; - if (language > SetUpper) + kindOption *kind = xCalloc (1, kindOption); + kind->letter = '\0'; + kind->name = NULL; + kind->description = NULL; + kind->enabled = false; + kind->referenceOnly = false; + kind->nRoles = 0; + kind->roles = NULL; + return kind; +} + +static void kindFree (void *data) +{ + kindOption *kind = data; + kind->letter = '\0'; + if (kind->name) { - int i; - Sets = xRealloc (Sets, (language + 1), patternSet); - for (i = SetUpper + 1 ; i <= language ; ++i) - { - Sets [i].patterns = NULL; - Sets [i].count = 0; - } - SetUpper = language; + eFree ((void *)kind->name); + kind->name = NULL; } - set = Sets + language; - set->patterns = xRealloc (set->patterns, (set->count + 1), regexPattern); - ptrn = &set->patterns [set->count]; - set->count += 1; - - ptrn->pattern = pattern; - ptrn->type = PTRN_TAG; - ptrn->u.tag.name_pattern = name; - ptrn->u.tag.kind.enabled = true; - ptrn->u.tag.kind.letter = kind; - ptrn->u.tag.kind.name = kindName; - ptrn->u.tag.kind.description = description; + if (kind->description) + { + eFree ((void *)kind->description); + kind->description = NULL; + } + eFree (kind); }
-static void addCompiledCallbackPattern ( - const langType language, GRegex* const pattern, - const regexCallback callback) +static regexPattern* addCompiledTagCommon (const langType language, + GRegex* const pattern, + char kind_letter) { patternSet* set; regexPattern *ptrn; + kindOption *kind = NULL; + if (language > SetUpper) { int i; @@ -275,20 +278,84 @@ static void addCompiledCallbackPattern ( { Sets [i].patterns = NULL; Sets [i].count = 0; + Sets [i].kinds = hashTableNew (11, + hashPtrhash, + hashPtreq, + NULL, + kindFree); } SetUpper = language; } set = Sets + language; set->patterns = xRealloc (set->patterns, (set->count + 1), regexPattern); + + if (kind_letter) + { + union cptr c = { .p = NULL }; + + c.c = kind_letter; + kind = hashTableGetItem (set->kinds, c.p); + if (!kind) + { + kind = kindNew (); + hashTablePutItem (set->kinds, c.p, (void *)kind); + } + } ptrn = &set->patterns [set->count]; + memset (ptrn, 0, sizeof (*ptrn)); + ptrn->pattern = pattern; + if (kind_letter) + ptrn->u.tag.kind = kind; set->count += 1; + return ptrn; +}
- ptrn->pattern = pattern; +static regexPattern *addCompiledTagPattern (const langType language, GRegex* const pattern, + const char* const name, char kind, const char* kindName, + char *const description) +{ + regexPattern * ptrn; + bool exclusive = false; + unsigned long scopeActions = 0UL; + + if (*name == '\0' && exclusive && kind == KIND_REGEX_DEFAULT) + { + kind = KIND_GHOST; + kindName = KIND_GHOST_LONG; + } + ptrn = addCompiledTagCommon(language, pattern, kind); + ptrn->type = PTRN_TAG; + ptrn->u.tag.name_pattern = eStrdup (name); + if (ptrn->u.tag.kind->letter == '\0') + { + /* This is a newly registered kind. */ + ptrn->u.tag.kind->letter = kind; + ptrn->u.tag.kind->enabled = true; + ptrn->u.tag.kind->name = kindName? eStrdup (kindName): NULL; + ptrn->u.tag.kind->description = description? eStrdup (description): NULL; + } + else if (ptrn->u.tag.kind->name && kindName && strcmp(ptrn->u.tag.kind->name, kindName)) + { + /* When using a same kind letter for multiple regex patterns, the name of kind + should be the same. */ + error (WARNING, "Don't reuse the kind letter `%c' in a language %s (old: "%s", new: "%s")", + ptrn->u.tag.kind->letter, getLanguageName (language), + ptrn->u.tag.kind->name, kindName); + } + + return ptrn; +} + +static void addCompiledCallbackPattern (const langType language, GRegex* const pattern, + const regexCallback callback) +{ + regexPattern * ptrn; + bool exclusive = false; + ptrn = addCompiledTagCommon(language, pattern, '\0'); ptrn->type = PTRN_CALLBACK; ptrn->u.callback.function = callback; }
- static GRegex* compileRegex (const char* const regexp, const char* const flags) { int cflags = G_REGEX_MULTILINE; @@ -421,7 +488,7 @@ static void matchTagPattern (const vString* const line, vStringStripLeading (name); vStringStripTrailing (name); if (vStringLength (name) > 0) - makeRegexTag (name, &patbuf->u.tag.kind); + makeRegexTag (name, patbuf->u.tag.kind); else error (WARNING, "%s:%ld: null expansion of name pattern "%s"", getInputFileName (), getInputLineNumber (), @@ -504,13 +571,13 @@ extern void findRegexTags (void) ; }
-extern void addTagRegex ( - const langType language CTAGS_ATTR_UNUSED, - const char* const regex CTAGS_ATTR_UNUSED, - const char* const name CTAGS_ATTR_UNUSED, - const char* const kinds CTAGS_ATTR_UNUSED, - const char* const flags CTAGS_ATTR_UNUSED) +static regexPattern *addTagRegexInternal (const langType language, + const char* const regex, + const char* const name, + const char* const kinds, + const char* const flags) { + regexPattern *rptr = NULL; Assert (regex != NULL); Assert (name != NULL); if (regexAvailable) @@ -522,10 +589,37 @@ extern void addTagRegex ( char* kindName; char* description; parseKinds (kinds, &kind, &kindName, &description); - addCompiledTagPattern (language, cp, eStrdup (name), - kind, kindName, description); + if (kind == getLanguageFileKind (language)->letter) + error (FATAL, + "Kind letter '%c' used in regex definition "%s" of %s language is reserved in ctags main", + kind, + regex, + getLanguageName (language)); + + rptr = addCompiledTagPattern (language, cp, name, + kind, kindName, description); + if (kindName) + eFree (kindName); + if (description) + eFree (description); } } + + if (*name == '\0') + { + error (WARNING, "%s: regexp missing name pattern", regex); + } + + return rptr; +} + +extern void addTagRegex (const langType language CTAGS_ATTR_UNUSED, + const char* const regex CTAGS_ATTR_UNUSED, + const char* const name CTAGS_ATTR_UNUSED, + const char* const kinds CTAGS_ATTR_UNUSED, + const char* const flags CTAGS_ATTR_UNUSED) +{ + addTagRegexInternal (language, regex, name, kinds, flags); }
extern void addCallbackRegex (const langType language CTAGS_ATTR_UNUSED, @@ -551,7 +645,7 @@ extern void addLanguageRegex ( char *name, *kinds, *flags; if (parseTagRegex (regex_pat, &name, &kinds, &flags)) { - addTagRegex (language, regex_pat, name, kinds, flags); + addTagRegexInternal (language, regex_pat, name, kinds, flags); eFree (regex_pat); } }
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).