Parse Pascal calltips (closes #2802640).

git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@3849 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
Enrico Tröger 2009-06-09 21:02:46 +00:00
parent aa4e9831c4
commit dcc89a6f61
2 changed files with 86 additions and 4 deletions

View File

@ -1,3 +1,9 @@
2009-06-09 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
* tagmanager/pascal.c:
Parse Pascal calltips (closes #2802640).
2009-06-09 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
* src/filetypes.c, src/ui_utils.c:

View File

@ -20,6 +20,7 @@
#include "entry.h"
#include "parse.h"
#include "read.h"
#include "main.h"
#include "vstring.h"
/*
@ -39,7 +40,8 @@ static kindOption PascalKinds [] = {
*/
static void createPascalTag (tagEntryInfo* const tag,
const vString* const name, const int kind)
const vString* const name, const int kind,
const char *arglist, const char *vartype)
{
if (PascalKinds [kind].enabled && name != NULL && vStringLength (name) > 0)
{
@ -47,6 +49,8 @@ static void createPascalTag (tagEntryInfo* const tag,
tag->kindName = PascalKinds [kind].name;
tag->kind = PascalKinds [kind].letter;
tag->extensionFields.arglist = arglist;
tag->extensionFields.varType = vartype;
}
else
initTagEntry (tag, NULL);
@ -79,6 +83,69 @@ static boolean tail (const char *cp)
return result;
}
static void parseArglist(const char *buf, char **arglist, char **vartype)
{
char *c, *start, *end;
int level;
if (NULL == buf || NULL == arglist)
return;
c = strdup(buf);
/* parse argument list which can be missing like in "function ginit:integer;" */
if (NULL != (start = strchr(c, '(')))
{
for (level = 1, end = start + 1; level > 0; ++end)
{
if ('\0' == *end)
break;
else if ('(' == *end)
++ level;
else if (')' == *end)
-- level;
}
}
else /* if no argument list was found, continue looking for a return value */
{
start = "()";
end = c;
}
/* 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 ':' */
while (isspace((int) *var))
++var;
if (starttoken(*var))
{
var_start = var;
var++;
while (intoken(*var))
var++;
if (endtoken(*var))
{
*var = '\0';
*vartype = strdup(var_start);
}
}
}
}
*end = '\0';
*arglist = strdup(start);
eFree(c);
}
/* 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"
@ -89,6 +156,8 @@ static void findPascalTags (void)
{
vString *name = vStringNew ();
tagEntryInfo tag;
char *arglist = NULL;
char *vartype = NULL;
pascalKind kind = K_FUNCTION;
/* each of these flags is TRUE iff: */
boolean incomment = FALSE; /* point is inside a comment */
@ -208,7 +277,11 @@ static void findPascalTags (void)
for (cp = dbp ; *cp != '\0' && !endtoken (*cp) ; cp++)
continue;
vStringNCopyS (name, (const char*) dbp, cp - dbp);
createPascalTag (&tag, name, kind);
eFree(arglist);
if (kind == K_FUNCTION)
eFree(vartype);
parseArglist((const char*) cp, &arglist, (kind == K_FUNCTION) ? &vartype : NULL);
createPascalTag (&tag, name, kind, arglist, vartype);
dbp = cp; /* set dbp to e-o-token */
get_tagname = FALSE;
found_tag = TRUE;
@ -256,6 +329,9 @@ static void findPascalTags (void)
}
} /* while not eof */
}
eFree(arglist);
eFree(vartype);
vStringDelete(name);
}
extern parserDefinition* PascalParser (void)