Parse arrays, const and pointers in C-like function return types
(and store in varType). Fix some indentation. git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@1952 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
parent
ea11001ef5
commit
b14e5a7590
@ -1,3 +1,11 @@
|
||||
2007-10-17 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
|
||||
|
||||
* tagmanager/tm_tag.c, tagmanager/c.c, TODO:
|
||||
Parse arrays, const and pointers in C-like function return types
|
||||
(and store in varType).
|
||||
Fix some indentation.
|
||||
|
||||
|
||||
2007-10-16 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
|
||||
|
||||
* geany.glade, src/callbacks.c, src/callbacks.h, src/interface.c:
|
||||
|
2
TODO
2
TODO
@ -8,8 +8,6 @@ TODO List:
|
||||
|
||||
Next version or later:
|
||||
|
||||
o make calltips show full function signature for C-like files (e.g.
|
||||
return type with const, [] for D, etc.)
|
||||
o documentation: list and explain filetype modes
|
||||
o documentation: preferences
|
||||
o line breaking mode to limit words on a line for e.g. XML content.
|
||||
|
176
tagmanager/c.c
176
tagmanager/c.c
@ -45,7 +45,7 @@
|
||||
* DATA DECLARATIONS
|
||||
*/
|
||||
|
||||
enum { NumTokens = 8 };
|
||||
enum { NumTokens = 12 };
|
||||
|
||||
typedef enum eException {
|
||||
ExceptionNone, ExceptionEOF, ExceptionFormattingError,
|
||||
@ -114,7 +114,8 @@ typedef enum eTokenType {
|
||||
TOKEN_PAREN_NAME, /* a single name in parentheses */
|
||||
TOKEN_SEMICOLON, /* the semicolon character */
|
||||
TOKEN_SPEC, /* a storage class specifier, qualifier, type, etc. */
|
||||
TOKEN_STAR, /* pointer detection */
|
||||
TOKEN_STAR, /* pointer detection */
|
||||
TOKEN_ARRAY, /* array detection */
|
||||
TOKEN_COUNT
|
||||
} tokenType;
|
||||
|
||||
@ -432,6 +433,7 @@ static const keywordDesc KeywordTable [] = {
|
||||
*/
|
||||
static void createTags (const unsigned int nestLevel, statementInfo *const parent);
|
||||
static void copyToken (tokenInfo *const dest, const tokenInfo *const src);
|
||||
static const char *getVarType (const statementInfo *const st);
|
||||
|
||||
/*
|
||||
* FUNCTION DEFINITIONS
|
||||
@ -441,7 +443,7 @@ static void copyToken (tokenInfo *const dest, const tokenInfo *const src);
|
||||
#if DEBUG_C
|
||||
static char *tokenTypeName[] = {
|
||||
"none", "args", "'}'", "'{'", "','", "'::'", "keyword", "name",
|
||||
"package", "paren-name", "';'", "spec", "*","count"
|
||||
"package", "paren-name", "';'", "spec", "*", "[]", "count"
|
||||
};
|
||||
|
||||
static char *tagScopeNames[] = {
|
||||
@ -608,7 +610,7 @@ static const char *tokenString (const tokenType type)
|
||||
{
|
||||
static const char *const names [] = {
|
||||
"none", "args", "}", "{", "comma", "double colon", "keyword", "name",
|
||||
"package", "paren-name", "semicolon", "specifier", "*","count"
|
||||
"package", "paren-name", "semicolon", "specifier", "*", "[]", "count"
|
||||
};
|
||||
Assert (sizeof (names) / sizeof (names [0]) == TOKEN_COUNT);
|
||||
Assert ((int) type < TOKEN_COUNT);
|
||||
@ -1074,10 +1076,50 @@ static void addOtherFields (tagEntryInfo* const tag, const tagType type,
|
||||
{
|
||||
if (((TOKEN_NAME == st->firstToken->type) || isDataTypeKeyword(st->firstToken))
|
||||
&& (0 != strcmp(vStringValue(st->firstToken->name), tag->name)))
|
||||
tag->extensionFields.varType = vStringValue(st->firstToken->name);
|
||||
tag->extensionFields.varType = getVarType(st);
|
||||
}
|
||||
}
|
||||
|
||||
static const char *getVarType (const statementInfo *const st)
|
||||
{
|
||||
static vString *vt = NULL;
|
||||
unsigned int i;
|
||||
|
||||
if (! st->gotArgs)
|
||||
return vStringValue(st->firstToken->name); /* ignore non-functions */
|
||||
|
||||
if (vt == NULL)
|
||||
vt = vStringNew();
|
||||
else
|
||||
vStringClear(vt);
|
||||
|
||||
for (i = 0; i < st->tokenIndex; i++)
|
||||
{
|
||||
tokenInfo *t = st->token[i];
|
||||
|
||||
switch (t->type)
|
||||
{
|
||||
case TOKEN_NAME: /* user typename */
|
||||
if (strcmp(vStringValue(t->name), vStringValue(st->firstToken->name)) != 0)
|
||||
continue;
|
||||
break;
|
||||
case TOKEN_KEYWORD:
|
||||
if (t->keyword != KEYWORD_EXTERN && t->keyword != KEYWORD_STATIC) /* uninteresting keywords */
|
||||
break;
|
||||
continue;
|
||||
case TOKEN_STAR: vStringCatS(vt, " *"); continue;
|
||||
case TOKEN_ARRAY: vStringCatS(vt, "[]"); continue;
|
||||
default: continue;
|
||||
}
|
||||
if (vStringLength(vt) > 0)
|
||||
if (isalpha(vStringValue(vt)[vStringLength(vt) - 1]))
|
||||
vStringPut(vt, ' ');
|
||||
vStringCat(vt, t->name);
|
||||
}
|
||||
vStringTerminate(vt);
|
||||
return vStringValue(vt);
|
||||
}
|
||||
|
||||
static void addContextSeparator (vString *const scope)
|
||||
{
|
||||
if (isLanguage (Lang_c) || isLanguage (Lang_cpp))
|
||||
@ -1251,13 +1293,13 @@ static void qualifyFunctionTag (const statementInfo *const st,
|
||||
{
|
||||
if (isType (nameToken, TOKEN_NAME))
|
||||
{
|
||||
const tagType type = (isLanguage (Lang_java) || isLanguage (Lang_csharp))
|
||||
? TAG_METHOD : TAG_FUNCTION;
|
||||
const boolean isFileScope =
|
||||
(boolean) (st->member.access == ACCESS_PRIVATE ||
|
||||
(!isMember (st) && st->scope == SCOPE_STATIC));
|
||||
const tagType type = (isLanguage (Lang_java) || isLanguage (Lang_csharp))
|
||||
? TAG_METHOD : TAG_FUNCTION;
|
||||
const boolean isFileScope =
|
||||
(boolean) (st->member.access == ACCESS_PRIVATE ||
|
||||
(!isMember (st) && st->scope == SCOPE_STATIC));
|
||||
|
||||
makeTag (nameToken, st, isFileScope, type);
|
||||
makeTag (nameToken, st, isFileScope, type);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1265,7 +1307,7 @@ static void qualifyFunctionDeclTag (const statementInfo *const st,
|
||||
const tokenInfo *const nameToken)
|
||||
{
|
||||
if (! isType (nameToken, TOKEN_NAME))
|
||||
;
|
||||
;
|
||||
else if (isLanguage (Lang_java) || isLanguage (Lang_csharp))
|
||||
qualifyFunctionTag (st, nameToken);
|
||||
else if (st->scope == SCOPE_TYPEDEF)
|
||||
@ -2413,7 +2455,7 @@ static void nextToken (statementInfo *const st)
|
||||
case ';': setToken (st, TOKEN_SEMICOLON); break;
|
||||
case '<': skipToMatch ("<>"); break;
|
||||
case '=': processInitializer (st); break;
|
||||
case '[': skipToMatch ("[]"); break;
|
||||
case '[': setToken (st, TOKEN_ARRAY); skipToMatch ("[]"); break;
|
||||
case '{': setToken (st, TOKEN_BRACE_OPEN); break;
|
||||
case '}': setToken (st, TOKEN_BRACE_CLOSE); break;
|
||||
default: parseGeneralToken (st, c); break;
|
||||
@ -2581,72 +2623,72 @@ static void tagCheck (statementInfo *const st)
|
||||
case TOKEN_BRACE_OPEN:
|
||||
if (isType (prev, TOKEN_ARGS))
|
||||
{
|
||||
if (st->haveQualifyingName)
|
||||
{
|
||||
st->declaration = DECL_FUNCTION;
|
||||
if (isType (prev2, TOKEN_NAME))
|
||||
copyToken (st->blockName, prev2);
|
||||
if (st->haveQualifyingName)
|
||||
{
|
||||
st->declaration = DECL_FUNCTION;
|
||||
if (isType (prev2, TOKEN_NAME))
|
||||
copyToken (st->blockName, prev2);
|
||||
|
||||
if (!isLanguage (Lang_java))
|
||||
{
|
||||
((tokenInfo *)prev2)->pointerOrder = getTokenPointerOrder (st, 3);
|
||||
}
|
||||
qualifyFunctionTag (st, prev2);
|
||||
}
|
||||
if (!isLanguage (Lang_java))
|
||||
{
|
||||
((tokenInfo *)prev2)->pointerOrder = getTokenPointerOrder (st, 3);
|
||||
}
|
||||
qualifyFunctionTag (st, prev2);
|
||||
}
|
||||
}
|
||||
else if (isContextualStatement (st))
|
||||
{
|
||||
tokenInfo *name_token = (tokenInfo *)prev;
|
||||
if (isType (name_token, TOKEN_NAME))
|
||||
{
|
||||
copyToken (st->blockName, name_token);
|
||||
}
|
||||
else if (isLanguage (Lang_csharp))
|
||||
makeTag (prev, st, FALSE, TAG_PROPERTY);
|
||||
else
|
||||
{
|
||||
tokenInfo *contextual_token = (tokenInfo *)prev;
|
||||
if(isContextualKeyword (contextual_token))
|
||||
{
|
||||
char buffer[64];
|
||||
|
||||
name_token = newToken ();
|
||||
copyToken (name_token, contextual_token);
|
||||
|
||||
sprintf(buffer, "anon_%s_%d", name_token->name->buffer, contextual_fake_count++);
|
||||
vStringClear(name_token->name);
|
||||
vStringCatS(name_token->name, buffer);
|
||||
|
||||
name_token->type = TOKEN_NAME;
|
||||
name_token->keyword = KEYWORD_NONE;
|
||||
|
||||
advanceToken (st);
|
||||
contextual_token = activeToken (st);
|
||||
copyToken (contextual_token, token);
|
||||
copyToken ((tokenInfo *const)token, name_token);
|
||||
tokenInfo *name_token = (tokenInfo *)prev;
|
||||
if (isType (name_token, TOKEN_NAME))
|
||||
{
|
||||
copyToken (st->blockName, name_token);
|
||||
copyToken (st->firstToken, name_token);
|
||||
}
|
||||
}
|
||||
qualifyBlockTag (st, name_token);
|
||||
}
|
||||
else if (isLanguage (Lang_csharp))
|
||||
makeTag (prev, st, FALSE, TAG_PROPERTY);
|
||||
else
|
||||
{
|
||||
tokenInfo *contextual_token = (tokenInfo *)prev;
|
||||
if(isContextualKeyword (contextual_token))
|
||||
{
|
||||
char buffer[64];
|
||||
|
||||
name_token = newToken ();
|
||||
copyToken (name_token, contextual_token);
|
||||
|
||||
sprintf(buffer, "anon_%s_%d", name_token->name->buffer, contextual_fake_count++);
|
||||
vStringClear(name_token->name);
|
||||
vStringCatS(name_token->name, buffer);
|
||||
|
||||
name_token->type = TOKEN_NAME;
|
||||
name_token->keyword = KEYWORD_NONE;
|
||||
|
||||
advanceToken (st);
|
||||
contextual_token = activeToken (st);
|
||||
copyToken (contextual_token, token);
|
||||
copyToken ((tokenInfo *const)token, name_token);
|
||||
copyToken (st->blockName, name_token);
|
||||
copyToken (st->firstToken, name_token);
|
||||
}
|
||||
}
|
||||
qualifyBlockTag (st, name_token);
|
||||
}
|
||||
break;
|
||||
case TOKEN_SEMICOLON:
|
||||
case TOKEN_COMMA:
|
||||
if (insideEnumBody (st))
|
||||
;
|
||||
;
|
||||
else if (isType (prev, TOKEN_NAME))
|
||||
{
|
||||
if (isContextualKeyword (prev2))
|
||||
makeTag (prev, st, TRUE, TAG_EXTERN_VAR);
|
||||
else
|
||||
{
|
||||
if (!isLanguage (Lang_java))
|
||||
{
|
||||
((tokenInfo *)prev)->pointerOrder = getTokenPointerOrder (st, 2);
|
||||
}
|
||||
qualifyVariableTag (st, prev);
|
||||
}
|
||||
if (isContextualKeyword (prev2))
|
||||
makeTag (prev, st, TRUE, TAG_EXTERN_VAR);
|
||||
else
|
||||
{
|
||||
if (!isLanguage (Lang_java))
|
||||
{
|
||||
((tokenInfo *)prev)->pointerOrder = getTokenPointerOrder (st, 2);
|
||||
}
|
||||
qualifyVariableTag (st, prev);
|
||||
}
|
||||
}
|
||||
else if (isType (prev, TOKEN_ARGS) && isType (prev2, TOKEN_NAME))
|
||||
{
|
||||
|
@ -137,7 +137,7 @@ gboolean tm_tag_init(TMTag *tag, TMSourceFile *file, const tagEntryInfo *tag_ent
|
||||
tag->name = g_strdup(tag_entry->name);
|
||||
tag->type = get_tag_type(tag_entry->kindName);
|
||||
tag->atts.entry.local = tag_entry->isFileScope;
|
||||
tag->atts.entry.pointerOrder = tag_entry->pointerOrder;
|
||||
tag->atts.entry.pointerOrder = 0; /* backward compatibility (use var_type instead) */
|
||||
tag->atts.entry.line = tag_entry->lineNumber;
|
||||
if (NULL != tag_entry->extensionFields.arglist)
|
||||
tag->atts.entry.arglist = g_strdup(tag_entry->extensionFields.arglist);
|
||||
|
Loading…
x
Reference in New Issue
Block a user