From 683c846873461d35f3deeabb7648a5d09bc73050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrico=20Tr=C3=B6ger?= Date: Sun, 5 Dec 2021 13:11:06 +0100 Subject: [PATCH] Use Pascal parser from uctags Fixes #2358, fixes #2982, fixes #2428 and fixes #2987. --- ctags/Makefile.am | 2 +- ctags/parsers/{geany_pascal.c => pascal.c} | 100 +++++++++------------ tests/ctags/bug612019.pas.tags | 2 +- 3 files changed, 44 insertions(+), 60 deletions(-) rename ctags/parsers/{geany_pascal.c => pascal.c} (81%) diff --git a/ctags/Makefile.am b/ctags/Makefile.am index f9587b9b8d..f10561e6a8 100644 --- a/ctags/Makefile.am +++ b/ctags/Makefile.am @@ -43,7 +43,7 @@ parsers = \ parsers/geany_matlab.c \ parsers/nsis.c \ parsers/objc.c \ - parsers/geany_pascal.c \ + parsers/pascal.c \ parsers/perl.c \ parsers/perl.h \ parsers/php.c \ diff --git a/ctags/parsers/geany_pascal.c b/ctags/parsers/pascal.c similarity index 81% rename from ctags/parsers/geany_pascal.c rename to ctags/parsers/pascal.c index fd4fbdd19b..bc526ecc63 100644 --- a/ctags/parsers/geany_pascal.c +++ b/ctags/parsers/pascal.c @@ -37,22 +37,26 @@ static kindDefinition PascalKinds [] = { * FUNCTION DEFINITIONS */ -static void createPascalTag (tagEntryInfo* const tag, - const vString* const name, const int kind, - const char *arglist, const char *vartype) +static void createPascalTag ( + tagEntryInfo* const tag, const vString* const name, const int kind, + const vString *arglist, const vString *vartype) { if (PascalKinds [kind].enabled && name != NULL && vStringLength (name) > 0) { initTagEntry (tag, vStringValue (name), kind); - - tag->extensionFields.signature = arglist; - tag->extensionFields.typeRef[1] = vartype; + if (arglist && !vStringIsEmpty (arglist)) + { + tag->extensionFields.signature = vStringValue (arglist); + } + if (vartype && !vStringIsEmpty (vartype)) + { + tag->extensionFields.typeRef[0] = "typename"; + tag->extensionFields.typeRef[1] = vStringValue (vartype); + } } else - { /* TODO: Passing NULL as name makes an assertion behind initTagEntry failure */ - /* initTagEntry (tag, NULL, NULL); */ - } + initTagEntry (tag, NULL, KIND_GHOST_INDEX); } static void makePascalTag (const tagEntryInfo* const tag) @@ -82,17 +86,16 @@ static bool tail (const char *cp) return result; } -static void parseArglist(const char *buf, char **arglist, char **vartype) +static void parseArglist (const char *buf, vString *arglist, vString *vartype) { - char *c, *start, *end; + const char *start, *end; int level; - if (NULL == buf || NULL == arglist) + if (NULL == buf || arglist == NULL) return; - c = strdup(buf); /* parse argument list which can be missing like in "function ginit:integer;" */ - if (NULL != (start = strchr(c, '('))) + if (NULL != (start = strchr (buf, '('))) { for (level = 1, end = start + 1; level > 0; ++end) { @@ -106,8 +109,8 @@ static void parseArglist(const char *buf, char **arglist, char **vartype) } else /* if no argument list was found, continue looking for a return value */ { - start = "()"; - end = c; + start = NULL; + end = buf; } /* parse return type if requested by passing a non-NULL vartype argument */ @@ -115,36 +118,32 @@ static void parseArglist(const char *buf, char **arglist, char **vartype) { char *var, *var_start; - *vartype = NULL; - - if (NULL != (var = strchr(end, ':'))) + if (NULL != (var = strchr (end, ':'))) { var++; /* skip ':' */ - while (isspace((int) *var)) + while (isspace ((int) *var)) ++var; - if (starttoken(*var)) + if (starttoken (*var)) { var_start = var; var++; - while (intoken(*var)) + while (intoken (*var)) var++; - if (endtoken(*var)) + if (endtoken (*var)) { - *var = '\0'; - *vartype = strdup(var_start); + vStringNCatS (vartype, var_start, var - var_start); } } } } - *end = '\0'; - *arglist = strdup(start); - - eFree(c); + if (NULL == start) /* no argument list */ + vStringCatS (arglist, "()"); + else + vStringNCatS (arglist, start, end - start); } - /* Algorithm adapted from from GNU etags. * Locates tags for procedures & functions. Doesn't do any type- or * var-definitions. It does look for the keyword "extern" or "forward" @@ -154,13 +153,13 @@ static void parseArglist(const char *buf, char **arglist, char **vartype) static void findPascalTags (void) { vString *name = vStringNew (); + vString *arglist = vStringNew (); + vString *vartype = vStringNew (); tagEntryInfo tag; - char *arglist = NULL; - char *vartype = NULL; pascalKind kind = K_FUNCTION; /* each of these flags is true iff: */ bool incomment = false; /* point is inside a comment */ - int comment_char = '\0'; /* type of current comment */ + int comment_char = '\0'; /* type of current comment */ bool inquote = false; /* point is inside '..' string */ bool get_tagname = false;/* point is after PROCEDURE/FUNCTION keyword, so next item = potential tag */ @@ -257,14 +256,6 @@ static void findPascalTags (void) verify_tag = false; } } - else if (tolower ((int) *dbp) == 't') - { - if (tail ("type")) /* check for forward reference */ - { - found_tag = false; - verify_tag = false; - } - } if (found_tag && verify_tag) /* not external proc, so make tag */ { found_tag = false; @@ -283,14 +274,16 @@ static void findPascalTags (void) /* grab block name */ while (isspace ((int) *dbp)) ++dbp; + if (!starttoken(*dbp)) + continue; for (cp = dbp ; *cp != '\0' && !endtoken (*cp) ; cp++) continue; vStringNCopyS (name, (const char*) dbp, cp - dbp); - if (arglist != NULL) - eFree(arglist); - if (kind == K_FUNCTION && vartype != NULL) - eFree(vartype); - parseArglist((const char*) cp, &arglist, (kind == K_FUNCTION) ? &vartype : NULL); + + vStringClear (arglist); + vStringClear (vartype); + parseArglist ((const char*) cp, arglist, (kind == K_FUNCTION) ? vartype : NULL); + createPascalTag (&tag, name, kind, arglist, (kind == K_FUNCTION) ? vartype : NULL); dbp = cp; /* set dbp to e-o-token */ get_tagname = false; @@ -329,20 +322,11 @@ static void findPascalTags (void) kind = K_FUNCTION; } break; - case 't': - if (tail ("ype")) - { - get_tagname = true; - kind = K_FUNCTION; - } - break; } } /* while not eof */ } - if (arglist != NULL) - eFree(arglist); - if (vartype != NULL) - eFree(vartype); + vStringDelete (arglist); + vStringDelete (vartype); vStringDelete (name); } @@ -351,7 +335,7 @@ extern parserDefinition* PascalParser (void) static const char *const extensions [] = { "p", "pas", NULL }; parserDefinition* def = parserNew ("Pascal"); def->extensions = extensions; - def->kindTable = PascalKinds; + def->kindTable = PascalKinds; def->kindCount = ARRAY_SIZE (PascalKinds); def->parser = findPascalTags; return def; diff --git a/tests/ctags/bug612019.pas.tags b/tests/ctags/bug612019.pas.tags index c0d147dcf5..b7f834de4e 100644 --- a/tests/ctags/bug612019.pas.tags +++ b/tests/ctags/bug612019.pas.tags @@ -1,4 +1,4 @@ # format=tagmanager -TTestÌ16Í()Ö0 +Test1Ì16Í()Ö0 Test2Ì16Í()Ö0 Test3Ì16Í()Ö0