From b14e5a75903a9b98e6e7ab171c531e2c4863ae7f Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Wed, 17 Oct 2007 11:55:59 +0000 Subject: [PATCH] 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 --- ChangeLog | 8 ++ TODO | 2 - tagmanager/c.c | 176 +++++++++++++++++++++++++++----------------- tagmanager/tm_tag.c | 2 +- 4 files changed, 118 insertions(+), 70 deletions(-) diff --git a/ChangeLog b/ChangeLog index cc25a78c9..bb0260cb4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2007-10-17 Nick Treleaven + + * 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 * geany.glade, src/callbacks.c, src/callbacks.h, src/interface.c: diff --git a/TODO b/TODO index aae72e859..634ae6c50 100644 --- a/TODO +++ b/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. diff --git a/tagmanager/c.c b/tagmanager/c.c index b6593ec6c..2df8cac63 100644 --- a/tagmanager/c.c +++ b/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)) { diff --git a/tagmanager/tm_tag.c b/tagmanager/tm_tag.c index 59cc0c243..72bfad157 100644 --- a/tagmanager/tm_tag.c +++ b/tagmanager/tm_tag.c @@ -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);