SF.net SVN: geany: [1153] trunk

ntrel at users.sourceforge.net ntrel at xxxxx
Wed Jan 3 12:41:11 UTC 2007


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 at 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 at 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.



More information about the Commits mailing list