Skip to content

Commit

Permalink
Pascal: Use vString to simplify string manipulations
Browse files Browse the repository at this point in the history
Also add a new variant to the text case to test for an empty
argument list.
  • Loading branch information
eht16 committed Dec 2, 2021
1 parent 8c02ce0 commit 6205ac2
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 30 deletions.
1 change: 1 addition & 0 deletions Units/parser-pascal.r/simple-pascal.d/expected.tags
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
helloproc input.pas /^PROCEDURE helloproc(param1: STRING; param2: BYTE);$/;" p signature:(param1: STRING; param2: BYTE)
max input.pas /^FUNCTION max(num1, num2: INTEGER): INTEGER;$/;" f typeref:typename:INTEGER signature:(num1, num2: INTEGER)
noargs input.pas /^FUNCTION noargs: STRING;$/;" f typeref:typename:STRING signature:()
emptyargs input.pas /^FUNCTION emptyargs(): STRING;$/;" f typeref:typename:STRING signature:()
5 changes: 5 additions & 0 deletions Units/parser-pascal.r/simple-pascal.d/input.pas
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@
noargs := 'functon without arguments';
END;

FUNCTION emptyargs(): STRING;
BEGIN
emptyargs := 'functon without arguments';
END;


VAR result : INTEGER;
BEGIN
Expand Down
58 changes: 28 additions & 30 deletions parsers/pascal.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,20 @@ static kindDefinition PascalKinds [] = {

static void createPascalTag (
tagEntryInfo* const tag, const vString* const name, const int kind,
const char *arglist, const char *vartype)
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[0] = "typename";
tag->extensionFields.typeRef[1] = vartype;
if (arglist != NULL && !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 */
Expand Down Expand Up @@ -80,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 @@ -104,17 +109,15 @@ 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, ':')))
{
var++; /* skip ':' */
Expand All @@ -129,17 +132,16 @@ static void parseArglist(const char *buf, char **arglist, char **vartype)
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.
Expand All @@ -151,9 +153,9 @@ 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 */
Expand Down Expand Up @@ -276,11 +278,9 @@ static void findPascalTags (void)
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 */
Expand Down Expand Up @@ -323,10 +323,8 @@ static void findPascalTags (void)
}
} /* while not eof */
}
if (arglist != NULL)
eFree(arglist);
if (vartype != NULL)
eFree(vartype);
vStringDelete (arglist);
vStringDelete (vartype);
vStringDelete (name);
}

Expand Down

0 comments on commit 6205ac2

Please sign in to comment.