Skip to content

Commit

Permalink
Use Pascal parser from uctags
Browse files Browse the repository at this point in the history
Fixes #2358, fixes #2982, fixes #2428 and fixes #2987.
  • Loading branch information
eht16 committed Dec 11, 2021
1 parent ad1debc commit 683c846
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 60 deletions.
2 changes: 1 addition & 1 deletion ctags/Makefile.am
Expand Up @@ -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 \
Expand Down
100 changes: 42 additions & 58 deletions ctags/parsers/geany_pascal.c → ctags/parsers/pascal.c
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
{
Expand All @@ -106,45 +109,41 @@ 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 */
if (NULL != 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"
Expand All @@ -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 */
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
}

Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion tests/ctags/bug612019.pas.tags
@@ -1,4 +1,4 @@
# format=tagmanager
TTest�16�()�0
Test1�16�()�0
Test2�16�()�0
Test3�16�()�0

0 comments on commit 683c846

Please sign in to comment.