Revision: 1153 http://svn.sourceforge.net/geany/?rev=1153&view=rev Author: ntrel Date: 2007-01-03 04:41:10 -0800 (Wed, 03 Jan 2007)
Log Message: ----------- Parse pointers in function return type for C-like files. Show scope in calltips. Made tm_tag_destroy() static.
Modified Paths: -------------- trunk/ChangeLog trunk/src/sci_cb.c trunk/tagmanager/c.c trunk/tagmanager/entry.h trunk/tagmanager/include/tm_tag.h trunk/tagmanager/tm_tag.c
Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2007-01-03 00:45:20 UTC (rev 1152) +++ trunk/ChangeLog 2007-01-03 12:41:10 UTC (rev 1153) @@ -1,3 +1,12 @@ +2007-01-03 Nick Treleaven nick.treleaven@btinternet.com + + * src/sci_cb.c, tagmanager/entry.h, tagmanager/tm_tag.c, + tagmanager/include/tm_tag.h, tagmanager/c.c: + Parse pointers in function return type for C-like files. + Show scope in calltips. + Made tm_tag_destroy() static. + + 2006-12-31 Enrico Tröger enrico.troeger@uvena.de
* src/treeviews.c: When opening a file, set the current selected
Modified: trunk/src/sci_cb.c =================================================================== --- trunk/src/sci_cb.c 2007-01-03 00:45:20 UTC (rev 1152) +++ trunk/src/sci_cb.c 2007-01-03 12:41:10 UTC (rev 1153) @@ -536,6 +536,44 @@ }
+static gchar *tag_to_calltip(const TMTag *tag, gint ft_id) +{ + GString *str; + gchar *result; + + if (! tag->atts.entry.arglist) return NULL; + + str = g_string_new(NULL); + + if (tag->atts.entry.var_type) + { + guint i; + + g_string_append(str, tag->atts.entry.var_type); + for (i = 0; i < tag->atts.entry.pointerOrder; i++) + { + g_string_append_c(str, '*'); + } + g_string_append_c(str, ' '); + } + if (tag->atts.entry.scope) + { + g_string_append(str, tag->atts.entry.scope); + if (ft_id == GEANY_FILETYPES_D) + g_string_append_c(str, '.'); + else + g_string_append(str, "::"); + } + g_string_append(str, tag->name); + g_string_append_c(str, ' '); + g_string_append(str, tag->atts.entry.arglist); + + result = str->str; + g_string_free(str, FALSE); + return result; +} + + static gchar *find_calltip(const gchar *word, filetype *ft) { TMTag *tag; @@ -551,11 +589,7 @@ tag = TM_TAG(tags->pdata[0]); if (tag->atts.entry.arglist) { - if (tag->atts.entry.var_type) - return g_strconcat(tag->atts.entry.var_type, " ", tag->name, - " ", tag->atts.entry.arglist, NULL); - else - return g_strconcat(tag->name, " ", tag->atts.entry.arglist, NULL); + return tag_to_calltip(tag, FILETYPE_ID(ft)); } else if (tag->type == tm_tag_class_t && FILETYPE_ID(ft) == GEANY_FILETYPES_D) { @@ -568,8 +602,7 @@ { tag = TM_TAG(tags->pdata[0]); if (tag->atts.entry.arglist) - return g_strconcat(tag->atts.entry.scope, ".this ", - tag->atts.entry.arglist, NULL); + return tag_to_calltip(tag, FILETYPE_ID(ft)); } } return NULL;
Modified: trunk/tagmanager/c.c =================================================================== --- trunk/tagmanager/c.c 2007-01-03 00:45:20 UTC (rev 1152) +++ trunk/tagmanager/c.c 2007-01-03 12:41:10 UTC (rev 1153) @@ -47,7 +47,7 @@ * DATA DECLARATIONS */
-enum { NumTokens = 3 }; +enum { NumTokens = 8 };
typedef enum eException { ExceptionNone, ExceptionEOF, ExceptionFormattingError, @@ -105,6 +105,7 @@ 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_COUNT } tokenType;
@@ -156,6 +157,8 @@ tokenType type; keywordId keyword; vString* name; /* the name of the token */ + int pointerOrder; /* 0=no pointer, 1=pointer, 2=pointer + to pointer, etc */ unsigned long lineNumber; /* line number of tag */ fpos_t filePosition; /* file position of line containing name */ } tokenInfo; @@ -178,7 +181,8 @@ boolean haveQualifyingName; /* do we have a name we are considering? */ boolean gotParenName; /* was a name inside parentheses parsed yet? */ boolean gotArgs; /* was a list of parameters parsed yet? */ - boolean isPointer; /* is 'name' a pointer? */ + int pointerOrder; /* 0=no pointer, 1=pointer, 2=pointer + to pointer, etc */ impType implementation; /* abstract or concrete implementation? */ unsigned int tokenIndex; /* currently active token */ tokenInfo* token [(int) NumTokens]; @@ -216,7 +220,7 @@ } tagType;
typedef struct sParenInfo { - boolean isPointer; + int pointerOrder; boolean isParamList; boolean isKnrParamList; boolean isNameCandidate; @@ -350,7 +354,7 @@ #if DEBUG_C static char *tokenTypeName[] = { "none", "args", "'}'", "'{'", "','", "'::'", "keyword", "name", - "package", "paren-name", "';'", "spec", "count" + "package", "paren-name", "';'", "spec", "*","count" };
static char *tagScopeNames[] = { @@ -427,6 +431,7 @@ { token->type = TOKEN_NONE; token->keyword = KEYWORD_NONE; + token->pointerOrder = 0; token->lineNumber = getSourceLineNumber (); token->filePosition = getInputFilePosition (); vStringClear (token->name); @@ -516,7 +521,7 @@ { static const char *const names [] = { "none", "args", "}", "{", "comma", "double colon", "keyword", "name", - "package", "paren-name", "semicolon", "specifier" + "package", "paren-name", "semicolon", "specifier", "*","count" }; Assert (sizeof (names) / sizeof (names [0]) == TOKEN_COUNT); Assert ((int) type < TOKEN_COUNT); @@ -603,6 +608,26 @@ * Statement management */
+static boolean isVariableKeyword (const tokenInfo *const token) +{ + switch (token->keyword) + { + case KEYWORD_CONST: + case KEYWORD_EXTERN: + case KEYWORD_REGISTER: + case KEYWORD_STATIC: +#if 0 + case KEYWORD_AUTO: + case KEYWORD_RESTRICT: +#endif + case KEYWORD_VIRTUAL: + case KEYWORD_SIGNED: + case KEYWORD_UNSIGNED: + return TRUE; + default: return FALSE; + } +} + static boolean isContextualKeyword (const tokenInfo *const token) { boolean result; @@ -694,7 +719,7 @@ st->declaration = DECL_NONE; } st->gotParenName = FALSE; - st->isPointer = FALSE; + st->pointerOrder = 0; st->implementation = IMP_DEFAULT; st->gotArgs = FALSE; st->gotName = FALSE; @@ -1031,6 +1056,7 @@ e.kindName = tagName (type); e.kind = tagLetter (type); e.type = type; + e.pointerOrder = token->pointerOrder;
findScopeHierarchy (scope, st); addOtherFields (&e, type, st, scope); @@ -1441,6 +1467,7 @@ dest->keyword = src->keyword; dest->filePosition = src->filePosition; dest->lineNumber = src->lineNumber; + dest->pointerOrder = src->pointerOrder; vStringCopy (dest->name, src->name); }
@@ -1819,7 +1846,8 @@ { case '&': case '*': - info->isPointer = TRUE; + /* DEBUG_PRINT("parseParens, po++\n"); */ + info->pointerOrder++; info->isKnrParamList = FALSE; if (identifierCount == 0) info->isParamList = FALSE; @@ -1944,7 +1972,7 @@
static void initParenInfo (parenInfo *const info) { - info->isPointer = FALSE; + info->pointerOrder = 0; info->isParamList = TRUE; info->isKnrParamList = TRUE; info->isNameCandidate = TRUE; @@ -1980,7 +2008,7 @@ processName (st); st->gotParenName = TRUE; if (! (c == '(' && info.nestedArgs)) - st->isPointer = info.isPointer; + st->pointerOrder = info.pointerOrder; } else if (! st->gotArgs && info.isParamList) { @@ -2143,7 +2171,10 @@ { case EOF: longjmp (Exception, (int) ExceptionEOF); break; case '(': analyzeParens (st); token = activeToken (st); break; - case '*': st->haveQualifyingName = FALSE; break; + case '*': + st->haveQualifyingName = FALSE; + setToken (st, TOKEN_STAR); + break; case ',': setToken (st, TOKEN_COMMA); break; case ':': processColon (st); break; case ';': setToken (st, TOKEN_SEMICOLON); break; @@ -2269,6 +2300,28 @@ setToken (st, TOKEN_BRACE_CLOSE); }
+static int getTokenPointerOrder (statementInfo *const st, int prev) +{ + const tokenInfo *prev_tmp = prevToken (st, prev); + int pointer_order = 0; + + /* ... , *const ptr; */ + if (isVariableKeyword ( prev_tmp )) + { + prev++; + prev_tmp = prevToken (st, prev); + } + + while (isType ( prev_tmp, TOKEN_STAR )) + { + pointer_order++; + prev++; + prev_tmp = prevToken (st, prev); + } + + return pointer_order; +} + static void tagCheck (statementInfo *const st) { const tokenInfo *const token = activeToken (st); @@ -2295,6 +2348,10 @@ 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); } } @@ -2315,13 +2372,20 @@ if (isContextualKeyword (prev2)) st->scope = SCOPE_EXTERN; else + { + if (!isLanguage (Lang_java)) + { + ((tokenInfo *)prev)->pointerOrder = getTokenPointerOrder (st, 2); + } qualifyVariableTag (st, prev); } + } else if (isType (prev, TOKEN_ARGS) && isType (prev2, TOKEN_NAME)) { - if (st->isPointer) - qualifyVariableTag (st, prev2); - else + if (!isLanguage (Lang_java)) + { + ((tokenInfo *)prev2)->pointerOrder = getTokenPointerOrder (st, 3); + } qualifyFunctionDeclTag (st, prev2); } break;
Modified: trunk/tagmanager/entry.h =================================================================== --- trunk/tagmanager/entry.h 2007-01-03 00:45:20 UTC (rev 1152) +++ trunk/tagmanager/entry.h 2007-01-03 12:41:10 UTC (rev 1153) @@ -60,6 +60,7 @@ boolean isFileScope; /* is tag visibile only within source file? */ boolean isFileEntry; /* is this just an entry for a file name? */ boolean truncateLine; /* truncate tag line at end of tag name? */ + int pointerOrder; /* The number of *'s this variable has */ const char *sourceFileName; /* name of source file */ const char *name; /* name of the tag */ const char *kindName; /* kind of tag */
Modified: trunk/tagmanager/include/tm_tag.h =================================================================== --- trunk/tagmanager/include/tm_tag.h 2007-01-03 00:45:20 UTC (rev 1152) +++ trunk/tagmanager/include/tm_tag.h 2007-01-03 12:41:10 UTC (rev 1153) @@ -96,7 +96,8 @@ tm_tag_attr_impl_t = 4096, /*!< Implementation (e.g. virtual) */ tm_tag_attr_lang_t = 8192, /*!< Language (File tag only) */ tm_tag_attr_inactive_t = 16384, /*!< Inactive file (File tag only) */ - tm_tag_attr_max_t = 32767 /*!< Maximum value */ + tm_tag_attr_pointer_t = 32768, /*!< Pointer type */ + tm_tag_attr_max_t = 65535 /*!< Maximum value */ } TMTagAttrType;
/*! Tag access type for C++/Java member functions and variables */ @@ -130,6 +131,7 @@ TMSourceFile *file; /*!< File in which the tag occurs */ gulong line; /*!< Line number of the tag */ gboolean local; /*!< Is the tag of local scope */ + guint pointerOrder; char *arglist; /*!< Argument list (functions/prototypes/macros) */ char *scope; /*!< Scope of tag */ char *inheritance; /*!< Parent classes */ @@ -291,12 +293,14 @@ */ void tm_tags_array_free(GPtrArray *tags_array, gboolean free_all);
+#if 0 /*! Destroys a TMTag structure, i.e. frees all elements except the tag itself. \param tag The TMTag structure to destroy \sa tm_tag_free() */ void tm_tag_destroy(TMTag *tag); +#endif
/*! Destroys all data in the tag and frees the tag structure as well.
Modified: trunk/tagmanager/tm_tag.c =================================================================== --- trunk/tagmanager/tm_tag.c 2007-01-03 00:45:20 UTC (rev 1152) +++ trunk/tagmanager/tm_tag.c 2007-01-03 12:41:10 UTC (rev 1153) @@ -44,7 +44,8 @@ TA_ACCESS, TA_IMPL, TA_LANG, - TA_INACTIVE + TA_INACTIVE, + TA_POINTER };
static guint *s_sort_attrs = NULL; @@ -136,6 +137,7 @@ 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.line = tag_entry->lineNumber; if (NULL != tag_entry->extensionFields.arglist) tag->atts.entry.arglist = g_strdup(tag_entry->extensionFields.arglist); @@ -197,7 +199,6 @@ TAG_FREE(tag); return NULL; } - return tag; }
@@ -246,6 +247,9 @@ case TA_SCOPE: tag->atts.entry.scope = g_strdup((gchar*)start + 1); break; + case TA_POINTER: + tag->atts.entry.pointerOrder = atoi((gchar*)start + 1); + break; case TA_VARTYPE: tag->atts.entry.var_type = g_strdup((gchar*)start + 1); break; @@ -372,6 +376,8 @@ fprintf(fp, "%c%s", TA_SCOPE, tag->atts.entry.scope); if ((attrs & tm_tag_attr_inheritance_t) && (NULL != tag->atts.entry.inheritance)) fprintf(fp, "%c%s", TA_INHERITS, tag->atts.entry.inheritance); + if (attrs & tm_tag_attr_pointer_t) + fprintf(fp, "%c%d", TA_POINTER, tag->atts.entry.pointerOrder); if ((attrs & tm_tag_attr_vartype_t) && (NULL != tag->atts.entry.var_type)) fprintf(fp, "%c%s", TA_VARTYPE, tag->atts.entry.var_type); if ((attrs & tm_tag_attr_access_t) && (TAG_ACCESS_UNKNOWN != tag->atts.entry.access)) @@ -385,7 +391,7 @@ return FALSE; }
-void tm_tag_destroy(TMTag *tag) +static void tm_tag_destroy(TMTag *tag) { g_free(tag->name); if (tm_tag_file_t != tag->type) @@ -486,7 +492,9 @@ for (i = 1; i < tags_array->len; ++i) { if (0 == tm_tag_compare(&(tags_array->pdata[i - 1]), &(tags_array->pdata[i]))) + { tags_array->pdata[i-1] = NULL; + } } tm_tags_prune(tags_array); return TRUE;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.