[geany/geany] 63fbe2: c.c, lcpp.c: Avoid using File.mio

Jiří Techet git-noreply at xxxxx
Mon Dec 17 21:05:47 UTC 2018


Branch:      refs/heads/master
Author:      Jiří Techet <techet at gmail.com>
Committer:   Jiří Techet <techet at gmail.com>
Date:        Mon, 10 Oct 2016 22:03:18 UTC
Commit:      63fbe2f6a27fb051285ee6321c9c90e0d176e7f5
             https://github.com/geany/geany/commit/63fbe2f6a27fb051285ee6321c9c90e0d176e7f5

Log Message:
-----------
c.c, lcpp.c: Avoid using File.mio

In uctags File is made private and mio gets inaccessible. At the moment
it's used by c.c and lcpp.c to get the parameter list. The C parser
"marks" the position where the argument list starts and once the right
")" is reached, string corresponding to this range is read from MIO,
filtered and used for parameter list.

For macro parameters the end of parameter list is handled in a slightly
obfuscated way - since the code from read.c reads the code by lines,
getInputFilePosition() returns the position of EOL so the parameter list
is read between '(' and EOL.

The code had to be modified to collect the potential parameter string
on the way - vString *signature has been added to lcpp.c and every
getcFromInputFile() and ungetcToInputFile() has been converted to
getcAndCollect() and ungetcAndCollect(), respectively, which in addition
perform the parameter collection when needed. Unfortunately this involves
many places in lcpp.c and we must be careful to always use these instead
of the standard ones from read.c.

We cannot rely on the implicit reading of whole lines and must add such
a code ourselves: just plain reading and collecting is enough. In addition
I added handling of multi-line signatures which was missing before.

In tests "bug1585745.cpp" and "cpp_destructor.cpp" the new code fixes
missing () in destructors when there's a space between tilde and name.
In "simple.d" test it fixes wrong function prototype.

The output of test "bug507864.c" seems to be worse than before but it was
already broken before and apparently the compiler is confused by it.


Modified Paths:
--------------
    ctags/main/lcpp.c
    ctags/main/lcpp.h
    ctags/parsers/c.c
    tests/ctags/bug1585745.cpp.tags
    tests/ctags/bug507864.c.tags
    tests/ctags/cpp_destructor.cpp.tags
    tests/ctags/simple.d.tags

Modified: ctags/main/lcpp.c
179 lines changed, 96 insertions(+), 83 deletions(-)
===================================================================
@@ -80,6 +80,9 @@ typedef struct sCppState {
 *   DATA DEFINITIONS
 */
 
+static vString *signature = NULL;
+static bool collectingSignature = false;
+
 /*  Use brace formatting to detect end of block.
  */
 static bool BraceFormat = false;
@@ -174,6 +177,21 @@ extern void cppUngetc (const int c)
 	Cpp.ungetch = c;
 }
 
+static inline int getcAndCollect ()
+{
+	int c = getcFromInputFile ();
+	if (collectingSignature && c != EOF)
+		vStringPut (signature, c);
+	return c;
+}
+
+static inline void ungetcAndCollect (int c)
+{
+	ungetcToInputFile (c);
+	if (collectingSignature)
+		vStringChop (signature);
+}
+
 /*  Reads a directive, whose first character is given by "c", into "name".
  */
 static bool readDirective (int c, char *const name, unsigned int maxLength)
@@ -184,10 +202,10 @@ static bool readDirective (int c, char *const name, unsigned int maxLength)
 	{
 		if (i > 0)
 		{
-			c = getcFromInputFile ();
+			c = getcAndCollect ();
 			if (c == EOF  ||  ! isalpha (c))
 			{
-				ungetcToInputFile (c);
+				ungetcAndCollect (c);
 				break;
 			}
 		}
@@ -207,9 +225,9 @@ static void readIdentifier (int c, vString *const name)
 	do
 	{
 		vStringPut (name, c);
-		c = getcFromInputFile ();
+		c = getcAndCollect ();
 	} while (c != EOF && cppIsident (c));
-	ungetcToInputFile (c);
+	ungetcAndCollect (c);
 }
 
 static conditionalInfo *currentConditional (void)
@@ -323,7 +341,7 @@ static int makeDefineTag (const char *const name, bool parameterized, bool undef
 		e.isFileScope  = isFileScope;
 		e.truncateLine = true;
 		if (parameterized)
-			e.extensionFields.signature = cppGetArglistFromFilePos(getInputFilePosition(), e.name);
+			e.extensionFields.signature = cppGetSignature ();
 		makeTagEntry (&e);
 		if (parameterized)
 			eFree((char *) e.extensionFields.signature);
@@ -333,16 +351,29 @@ static int makeDefineTag (const char *const name, bool parameterized, bool undef
 
 static int directiveDefine (const int c, bool undef)
 {
-	bool parameterized;
-	int nc;
 	int r = CORK_NIL;
 
 	if (cppIsident1 (c))
 	{
+		bool parameterized;
+		int nc;
+
 		readIdentifier (c, Cpp.directive.name);
-		nc = getcFromInputFile ();
-		ungetcToInputFile (nc);
-		parameterized = (bool) (nc == '(');
+		nc = getcAndCollect ();
+		parameterized = (nc == '(');
+		if (parameterized)
+		{
+			cppStartCollectingSignature ();
+			while (nc != EOF)
+			{
+				int lastC = nc;
+				nc = getcAndCollect ();
+				if (nc == '\n' && lastC != '\\')
+					break;
+			}
+			cppStopCollectingSignature ();
+		}
+		ungetcAndCollect (nc);
 		if (! isIgnore ())
 			makeDefineTag (vStringValue (Cpp.directive.name), parameterized, undef);
 	}
@@ -372,7 +403,7 @@ static void directivePragma (int c)
 			/* generate macro tag for weak name */
 			do
 			{
-				c = getcFromInputFile ();
+				c = getcAndCollect ();
 			} while (c == SPACE);
 			if (cppIsident1 (c))
 			{
@@ -456,7 +487,7 @@ static bool handleDirective (const int c, int *macroCorkIndex)
 static Comment isComment (void)
 {
 	Comment comment;
-	const int next = getcFromInputFile ();
+	const int next = getcAndCollect ();
 
 	if (next == '*')
 		comment = COMMENT_C;
@@ -466,7 +497,7 @@ static Comment isComment (void)
 		comment = COMMENT_D;
 	else
 	{
-		ungetcToInputFile (next);
+		ungetcAndCollect (next);
 		comment = COMMENT_NONE;
 	}
 	return comment;
@@ -477,15 +508,15 @@ static Comment isComment (void)
  */
 int cppSkipOverCComment (void)
 {
-	int c = getcFromInputFile ();
+	int c = getcAndCollect ();
 
 	while (c != EOF)
 	{
 		if (c != '*')
-			c = getcFromInputFile ();
+			c = getcAndCollect ();
 		else
 		{
-			const int next = getcFromInputFile ();
+			const int next = getcAndCollect ();
 
 			if (next != '/')
 				c = next;
@@ -505,10 +536,10 @@ static int skipOverCplusComment (void)
 {
 	int c;
 
-	while ((c = getcFromInputFile ()) != EOF)
+	while ((c = getcAndCollect ()) != EOF)
 	{
 		if (c == BACKSLASH)
-			getcFromInputFile ();  /* throw away next character, too */
+			getcAndCollect ();  /* throw away next character, too */
 		else if (c == NEWLINE)
 			break;
 	}
@@ -520,15 +551,15 @@ static int skipOverCplusComment (void)
  */
 static int skipOverDComment (void)
 {
-	int c = getcFromInputFile ();
+	int c = getcAndCollect ();
 
 	while (c != EOF)
 	{
 		if (c != '+')
-			c = getcFromInputFile ();
+			c = getcAndCollect ();
 		else
 		{
-			const int next = getcFromInputFile ();
+			const int next = getcAndCollect ();
 
 			if (next != '/')
 				c = next;
@@ -549,10 +580,10 @@ static int skipToEndOfString (bool ignoreBackslash)
 {
 	int c;
 
-	while ((c = getcFromInputFile ()) != EOF)
+	while ((c = getcAndCollect ()) != EOF)
 	{
 		if (c == BACKSLASH && ! ignoreBackslash)
-			getcFromInputFile ();  /* throw away next character, too */
+			getcAndCollect ();  /* throw away next character, too */
 		else if (c == DOUBLE_QUOTE)
 			break;
 	}
@@ -567,11 +598,11 @@ static int isCxxRawLiteralDelimiterChar (int c)
 
 static int skipToEndOfCxxRawLiteralString (void)
 {
-	int c = getcFromInputFile ();
+	int c = getcAndCollect ();
 
 	if (c != '(' && ! isCxxRawLiteralDelimiterChar (c))
 	{
-		ungetcToInputFile (c);
+		ungetcAndCollect (c);
 		c = skipToEndOfString (false);
 	}
 	else
@@ -594,15 +625,15 @@ static int skipToEndOfCxxRawLiteralString (void)
 			{
 				unsigned int i = 0;
 
-				while ((c = getcFromInputFile ()) != EOF && i < delimLen && delim[i] == c)
+				while ((c = getcAndCollect ()) != EOF && i < delimLen && delim[i] == c)
 					i++;
 				if (i == delimLen && c == DOUBLE_QUOTE)
 					break;
 				else
-					ungetcToInputFile (c);
+					ungetcAndCollect (c);
 			}
 		}
-		while ((c = getcFromInputFile ()) != EOF);
+		while ((c = getcAndCollect ()) != EOF);
 		c = STRING_SYMBOL;
 	}
 	return c;
@@ -617,16 +648,16 @@ static int skipToEndOfChar (void)
 	int c;
 	int count = 0, veraBase = '\0';
 
-	while ((c = getcFromInputFile ()) != EOF)
+	while ((c = getcAndCollect ()) != EOF)
 	{
 	    ++count;
 		if (c == BACKSLASH)
-			getcFromInputFile ();  /* throw away next character, too */
+			getcAndCollect ();  /* throw away next character, too */
 		else if (c == SINGLE_QUOTE)
 			break;
 		else if (c == NEWLINE)
 		{
-			ungetcToInputFile (c);
+			ungetcAndCollect (c);
 			break;
 		}
 	}
@@ -655,7 +686,7 @@ extern int cppGetc (void)
 	else do
 	{
 start_loop:
-		c = getcFromInputFile ();
+		c = getcAndCollect ();
 process:
 		switch (c)
 		{
@@ -707,7 +738,7 @@ extern int cppGetc (void)
 				{
 					c = skipOverCplusComment ();
 					if (c == NEWLINE)
-						ungetcToInputFile (c);
+						ungetcAndCollect (c);
 				}
 				else if (comment == COMMENT_D)
 					c = skipOverDComment ();
@@ -718,23 +749,23 @@ extern int cppGetc (void)
 
 			case BACKSLASH:
 			{
-				int next = getcFromInputFile ();
+				int next = getcAndCollect ();
 
 				if (next == NEWLINE)
 					goto start_loop;
 				else
-					ungetcToInputFile (next);
+					ungetcAndCollect (next);
 				break;
 			}
 
 			case '?':
 			{
-				int next = getcFromInputFile ();
+				int next = getcAndCollect ();
 				if (next != '?')
-					ungetcToInputFile (next);
+					ungetcAndCollect (next);
 				else
 				{
-					next = getcFromInputFile ();
+					next = getcAndCollect ();
 					switch (next)
 					{
 						case '(':          c = '[';       break;
@@ -747,8 +778,8 @@ extern int cppGetc (void)
 						case '-':          c = '~';       break;
 						case '=':          c = '#';       goto process;
 						default:
-							ungetcToInputFile ('?');
-							ungetcToInputFile (next);
+							ungetcAndCollect ('?');
+							ungetcAndCollect (next);
 							break;
 					}
 				}
@@ -760,48 +791,48 @@ extern int cppGetc (void)
 			 */
 			case '<':
 			{
-				int next = getcFromInputFile ();
+				int next = getcAndCollect ();
 				switch (next)
 				{
 					case ':':	c = '['; break;
 					case '%':	c = '{'; break;
-					default: ungetcToInputFile (next);
+					default: ungetcAndCollect (next);
 				}
 				goto enter;
 			}
 			case ':':
 			{
-				int next = getcFromInputFile ();
+				int next = getcAndCollect ();
 				if (next == '>')
 					c = ']';
 				else
-					ungetcToInputFile (next);
+					ungetcAndCollect (next);
 				goto enter;
 			}
 			case '%':
 			{
-				int next = getcFromInputFile ();
+				int next = getcAndCollect ();
 				switch (next)
 				{
 					case '>':	c = '}'; break;
 					case ':':	c = '#'; goto process;
-					default: ungetcToInputFile (next);
+					default: ungetcAndCollect (next);
 				}
 				goto enter;
 			}
 
 			default:
 				if (c == '@' && Cpp.hasAtLiteralStrings)
 				{
-					int next = getcFromInputFile ();
+					int next = getcAndCollect ();
 					if (next == DOUBLE_QUOTE)
 					{
 						Cpp.directive.accept = false;
 						c = skipToEndOfString (true);
 						break;
 					}
 					else
-						ungetcToInputFile (next);
+						ungetcAndCollect (next);
 				}
 				else if (c == 'R' && Cpp.hasCxxRawLiteralStrings)
 				{
@@ -830,9 +861,9 @@ extern int cppGetc (void)
 					    (! cppIsident (prev2) && (prev == 'L' || prev == 'u' || prev == 'U')) ||
 					    (! cppIsident (prev3) && (prev2 == 'u' && prev == '8')))
 					{
-						int next = getcFromInputFile ();
+						int next = getcAndCollect ();
 						if (next != DOUBLE_QUOTE)
-							ungetcToInputFile (next);
+							ungetcAndCollect (next);
 						else
 						{
 							Cpp.directive.accept = false;
@@ -944,17 +975,16 @@ static void stripCodeBuffer(char *buf)
 	return;
 }
 
-static char *getArglistFromStr(char *buf, const char *name)
+extern char *cppGetSignature(void)
 {
 	char *start, *end;
 	int level;
-	if ((NULL == buf) || (NULL == name) || ('\0' == name[0]))
-		return NULL;
-	stripCodeBuffer(buf);
-	if (NULL == (start = strstr(buf, name)))
-		return NULL;
-	if (NULL == (start = strchr(start, '(')))
+
+	if (NULL == signature || vStringLength (signature) < 2)
 		return NULL;
+
+	start = strdup (vStringValue (signature));
+	stripCodeBuffer(start);
 	for (level = 1, end = start + 1; level > 0; ++end)
 	{
 		if ('\0' == *end)
@@ -965,34 +995,17 @@ static char *getArglistFromStr(char *buf, const char *name)
 			-- level;
 	}
 	*end = '\0';
-	return strdup(start);
+	return start;
 }
 
-extern char *cppGetArglistFromFilePos(MIOPos startPosition, const char *tokenName)
+extern void cppStartCollectingSignature (void)
 {
-	MIOPos originalPosition;
-	char *result = NULL;
-	char *arglist = NULL;
-	long pos1, pos2;
-
-	pos2 = mio_tell(File.mio);
-
-	mio_getpos(File.mio, &originalPosition);
-	mio_setpos(File.mio, &startPosition);
-	pos1 = mio_tell(File.mio);
-
-	if (pos2 > pos1)
-	{
-		size_t len = pos2 - pos1;
+	signature = vStringNewOrClear (signature);
+	vStringPut (signature, '(');
+	collectingSignature = true;
+}
 
-		result = (char *) eMalloc(len + 1);
-		if (result != NULL && (len = mio_read(File.mio, result, 1, len)) > 0)
-		{
-			result[len] = '\0';
-			arglist = getArglistFromStr(result, tokenName);
-		}
-		eFree(result);
-	}
-	mio_setpos(File.mio, &originalPosition);
-	return arglist;
+extern void cppStopCollectingSignature (void)
+{
+	collectingSignature = false;
 }


Modified: ctags/main/lcpp.h
5 lines changed, 4 insertions(+), 1 deletions(-)
===================================================================
@@ -71,6 +71,9 @@ extern void cppEndStatement (void);
 extern void cppUngetc (const int c);
 extern int cppGetc (void);
 extern int cppSkipOverCComment (void);
-extern char *cppGetArglistFromFilePos(MIOPos startPosition, const char *tokenName);
+
+extern char *cppGetSignature (void);
+extern void cppStartCollectingSignature (void);
+extern void cppStopCollectingSignature (void);
 
 #endif  /* CTAGS_MAIN_GET_H */


Modified: ctags/parsers/c.c
11 lines changed, 5 insertions(+), 6 deletions(-)
===================================================================
@@ -215,7 +215,6 @@ typedef struct sStatementInfo
 	memberInfo	member;         /* information regarding parent class/struct */
 	vString*	parentClasses;  /* parent classes */
 	struct sStatementInfo *parent;  /* statement we are nested within */
-	long 			argEndPosition; /* Position where argument list ended */
 	tokenInfo* 		firstToken; /* First token in the statement */
 } statementInfo;
 
@@ -947,7 +946,6 @@ static void reinitStatement (statementInfo *const st, const bool partial)
 	st->gotName				= false;
 	st->nSemicolons			= 0;
 	st->haveQualifyingName	= false;
-	st->argEndPosition		= 0;
 
 	st->tokenIndex			= 0;
 	for (i = 0  ;  i < (unsigned int) NumTokens  ;  ++i)
@@ -1225,8 +1223,7 @@ static void addOtherFields (tagEntryInfo* const tag, const tagType type,
             if ((true == st->gotArgs) &&
 				((TAG_FUNCTION == type) || (TAG_METHOD == type) || (TAG_PROTOTYPE == type)))
 			{
-				tag->extensionFields.signature = cppGetArglistFromFilePos(
-						tag->filePosition, tag->name);
+				tag->extensionFields.signature = cppGetSignature ();
 			}
 			break;
 		}
@@ -2420,6 +2417,8 @@ static int parseParens (statementInfo *const st, parenInfo *const info)
 	bool firstChar = true;
 	int nextChar = '\0';
 
+	cppStartCollectingSignature ();
+
 	info->parameterCount = 1;
 	do
 	{
@@ -2560,8 +2559,8 @@ static int parseParens (statementInfo *const st, parenInfo *const info)
 		skipToMatch ("()");
 		--depth;
 	}
-	if (st->argEndPosition == 0)
-		st->argEndPosition = mio_tell (File.mio);
+
+	cppStopCollectingSignature ();
 
 	if (! info->isNameCandidate)
 		initToken (token);


Modified: tests/ctags/bug1585745.cpp.tags
6 lines changed, 3 insertions(+), 3 deletions(-)
===================================================================
@@ -1,7 +1,7 @@
 # format=tagmanager
 Class5�1�0
 ~Class1�16�()�Class1�0�Class1
-~Class2�16�Class2�0�Class2
+~Class2�16�()�Class2�0�Class2
 ~Class3�16�()�Class3�0�Class3
-~Class4�16�Class4�0�Class4
-~Class5�16�Class5�0
+~Class4�16�()�Class4�0�Class4
+~Class5�16�()�Class5�0


Modified: tests/ctags/bug507864.c.tags
7 lines changed, 4 insertions(+), 3 deletions(-)
===================================================================
@@ -1,4 +1,5 @@
 # format=tagmanager
-ENTSEQNO�16�(seq)�0�FUNCSTS
-MEMTXT�16�(form_msg)�0�
-MEMTXT�1024�(form_msg)�0�
+ENTSEQNO�16�(eq)�0�FUNCSTS
+MEMTXT�16�(mail)�0�
+MEMTXT�1024�(orm_msg)�0�FUNCSTS
+MEMTXT�1024�(text)�0�


Modified: tests/ctags/cpp_destructor.cpp.tags
2 lines changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -1,4 +1,4 @@
 # format=tagmanager
 ~A�16�()�A�0�A
 ~B�16�()�B�0�B
-~C�16�C�0�C
+~C�16�()�C�0�C


Modified: tests/ctags/simple.d.tags
2 lines changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -20,5 +20,5 @@ obj
 qar�64�Struct.Union�0�int
 quxx�64�Struct.Union�0�bool
 test.simple�256�0
-tfun�16�(T)�Class�0�auto
+tfun�16�(T v)�Class�0�auto
 this�16�(AliasInt x)�Class�0



--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).


More information about the Commits mailing list