[geany/geany] 37f015: Implement iFileGetLine() using gets()

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


Branch:      refs/heads/master
Author:      Jiří Techet <techet at gmail.com>
Committer:   Jiří Techet <techet at gmail.com>
Date:        Sat, 08 Oct 2016 12:13:41 UTC
Commit:      37f015d993ad1bc1e052503582a745e5b3c94ca7
             https://github.com/geany/geany/commit/37f015d993ad1bc1e052503582a745e5b3c94ca7

Log Message:
-----------
Implement iFileGetLine() using gets()


Modified Paths:
--------------
    ctags/main/read.c
    ctags/main/read.h

Modified: ctags/main/read.c
197 lines changed, 81 insertions(+), 116 deletions(-)
===================================================================
@@ -127,27 +127,27 @@ static bool setSourceFileName (vString *const fileName)
  *   Line directive parsing
  */
 
-static int skipWhite (void)
+static void skipWhite (char **str)
 {
-	int c;
-	do
-		c = mio_getc (File.mio);
-	while (c == ' '  ||  c == '\t');
-	return c;
+	while (**str == ' '  ||  **str == '\t')
+		(*str)++;
 }
 
-static unsigned long readLineNumber (void)
+static unsigned long readLineNumber (char **str)
 {
+	char *s;
 	unsigned long lNum = 0;
-	int c = skipWhite ();
-	while (c != EOF  &&  isdigit (c))
+
+	skipWhite (str);
+	s = *str;
+	while (*s != '\0' && isdigit (*s))
 	{
-		lNum = (lNum * 10) + (c - '0');
-		c = mio_getc (File.mio);
+		lNum = (lNum * 10) + (*s - '0');
+		s++;
 	}
-	mio_ungetc (File.mio, c);
-	if (c != ' '  &&  c != '\t')
+	if (*s != ' ' && *s != '\t')
 		lNum = 0;
+	*str = s;
 
 	return lNum;
 }
@@ -160,59 +160,54 @@ static unsigned long readLineNumber (void)
  *   # n "filename"
  * So we need to be fairly flexible in what we accept.
  */
-static vString *readFileName (void)
+static vString *readFileName (char *s)
 {
 	vString *const fileName = vStringNew ();
 	bool quoteDelimited = false;
-	int c = skipWhite ();
 
-	if (c == '"')
+	skipWhite (&s);
+	if (*s == '"')
 	{
-		c = mio_getc (File.mio);  /* skip double-quote */
+		s++;  /* skip double-quote */
 		quoteDelimited = true;
 	}
-	while (c != EOF  &&  c != '\n'  &&
-			(quoteDelimited ? (c != '"') : (c != ' '  &&  c != '\t')))
+	while (*s != '\0'  &&  *s != '\n'  &&
+			(quoteDelimited ? (*s != '"') : (*s != ' '  &&  *s != '\t')))
 	{
-		vStringPut (fileName, c);
-		c = mio_getc (File.mio);
+		vStringPut (fileName, *s);
+		s++;
 	}
-	if (c == '\n')
-		mio_ungetc (File.mio, c);
 	vStringPut (fileName, '\0');
 
 	return fileName;
 }
 
-static bool parseLineDirective (void)
+static bool parseLineDirective (char *s)
 {
 	bool result = false;
-	int c = skipWhite ();
+
+	skipWhite (&s);
 	DebugStatement ( const char* lineStr = ""; )
 
-	if (isdigit (c))
-	{
-		mio_ungetc (File.mio, c);
+	if (isdigit (*s))
 		result = true;
-	}
-	else if (c == 'l'  &&  mio_getc (File.mio) == 'i'  &&
-			 mio_getc (File.mio) == 'n'  &&  mio_getc (File.mio) == 'e')
+	else if (strncmp (s, "line", 4) == 0)
 	{
-		c = mio_getc (File.mio);
-		if (c == ' '  ||  c == '\t')
+		s += 4;
+		if (*s == ' '  ||  *s == '\t')
 		{
 			DebugStatement ( lineStr = "line"; )
 			result = true;
 		}
 	}
 	if (result)
 	{
-		const unsigned long lNum = readLineNumber ();
+		const unsigned long lNum = readLineNumber (&s);
 		if (lNum == 0)
 			result = false;
 		else
 		{
-			vString *const fileName = readFileName ();
+			vString *const fileName = readFileName (s);
 			if (vStringLength (fileName) == 0)
 			{
 				File.source.lineNumber = lNum - 1;  /* applies to NEXT line */
@@ -225,7 +220,7 @@ static bool parseLineDirective (void)
 								lineStr, lNum, vStringValue (fileName)); )
 			}
 
-			if (Option.include.fileNames && vStringLength (fileName) > 0 &&
+			if (vStringLength (fileName) > 0 &&
 				lNum == 1)
 			{
 				tagEntryInfo tag;
@@ -276,8 +271,6 @@ extern bool fileOpen (const char *const fileName, const langType language)
 		mio_getpos (File.mio, &File.filePosition);
 		File.currentLine  = NULL;
 		File.input.lineNumber   = 0L;
-		File.eof          = false;
-		File.newLine      = true;
 
 		if (File.line != NULL)
 			vStringClear (File.line);
@@ -322,8 +315,6 @@ extern bool bufferOpen (unsigned char *buffer, size_t buffer_size,
 	mio_getpos (File.mio, &File.filePosition);
 	File.currentLine  = NULL;
 	File.input.lineNumber   = 0L;
-	File.eof          = false;
-	File.newLine      = true;
 
 	if (File.line != NULL)
 		vStringClear (File.line);
@@ -356,74 +347,17 @@ extern void fileClose (void)
 	}
 }
 
-extern bool fileEOF (void)
-{
-	return File.eof;
-}
-
 /*  Action to take for each encountered input newline.
  */
 static void fileNewline (void)
 {
 	File.filePosition = StartOfLine;
-	File.newLine = false;
 	File.input.lineNumber++;
 	File.source.lineNumber++;
 	DebugStatement ( if (Option.breakLine == File.input.lineNumber) lineBreak (); )
 	DebugStatement ( debugPrintf (DEBUG_RAW, "%6ld: ", File.input.lineNumber); )
 }
 
-/*  This function reads a single character from the stream, performing newline
- *  canonicalization.
- */
-static int iFileGetc (void)
-{
-	int	c;
-readnext:
-	c = mio_getc (File.mio);
-
-	/*	If previous character was a newline, then we're starting a line.
-	 */
-	if (File.newLine  &&  c != EOF)
-	{
-		fileNewline ();
-		if (c == '#'  &&  Option.lineDirectives)
-		{
-			if (parseLineDirective ())
-				goto readnext;
-			else
-			{
-				mio_setpos (File.mio, &StartOfLine);
-				c = mio_getc (File.mio);
-			}
-		}
-	}
-
-	if (c == EOF)
-		File.eof = true;
-	else if (c == NEWLINE)
-	{
-		File.newLine = true;
-		mio_getpos (File.mio, &StartOfLine);
-	}
-	else if (c == CRETURN)
-	{
-		/* Turn line breaks into a canonical form. The three commonly
-		 * used forms if line breaks: LF (UNIX/Mac OS X), CR (Mac OS 9),
-		 * and CR-LF (MS-DOS) are converted into a generic newline.
-		 */
-		const int next = mio_getc (File.mio);  /* is CR followed by LF? */
-		if (next != NEWLINE)
-			mio_ungetc (File.mio, next);
-
-		c = NEWLINE;  /* convert CR into newline */
-		File.newLine = true;
-		mio_getpos (File.mio, &StartOfLine);
-	}
-	DebugStatement ( debugPutc (DEBUG_RAW, c); )
-	return c;
-}
-
 extern void ungetcToInputFile (int c)
 {
 	const size_t len = ARRAY_SIZE (File.ungetchBuf);
@@ -436,28 +370,59 @@ extern void ungetcToInputFile (int c)
 
 static vString *iFileGetLine (void)
 {
-	vString *result = NULL;
-	int c;
-	if (File.line == NULL)
-		File.line = vStringNew ();
-	vStringClear (File.line);
-	do
+	char *str;
+	size_t size;
+	bool haveLine;
+
+	File.line = vStringNewOrClear (File.line);
+	str = vStringValue (File.line);
+	size = vStringSize (File.line);
+
+	for (;;)
 	{
-		c = iFileGetc ();
-		if (c != EOF)
-			vStringPut (File.line, c);
-		if (c == '\n'  ||  (c == EOF  &&  vStringLength (File.line) > 0))
+		bool newLine;
+		bool eof;
+
+		mio_gets (File.mio, str, size);
+		vStringSetLength (File.line);
+		haveLine = vStringLength (File.line) > 0;
+		newLine = haveLine && vStringLast (File.line) == '\n';
+		eof = mio_eof (File.mio);
+
+		/* Turn line breaks into a canonical form. The three commonly
+		 * used forms of line breaks are: LF (UNIX/Mac OS X), CR-LF (MS-DOS) and
+		 * CR (Mac OS 9). As CR-only EOL isn't haneled by gets() and Mac OS 9
+		 * is dead, we only handle CR-LF EOLs and convert them into LF. */
+		if (newLine && vStringLength (File.line) > 1 &&
+			vStringItem (File.line, vStringLength (File.line) - 2) == '\r')
 		{
-#ifdef HAVE_REGEX
-			if (vStringLength (File.line) > 0)
-				matchRegex (File.line, File.source.language);
-#endif
-			result = File.line;
-			break;
+			vStringItem (File.line, vStringLength (File.line) - 2) = '\n';
+			vStringChop (File.line);
 		}
-	} while (c != EOF);
-	Assert (result != NULL  ||  File.eof);
-	return result;
+
+		if (newLine || eof)
+			break;
+
+		vStringResize (File.line, vStringLength (File.line) * 2);
+		str = vStringValue (File.line) + vStringLength (File.line);
+		size = vStringSize (File.line) - vStringLength (File.line);
+	}
+
+	if (haveLine)
+	{
+		/* Use StartOfLine from previous iFileGetLine() call */
+		fileNewline ();
+		/* Store StartOfLine for the next iFileGetLine() call */
+		mio_getpos (File.mio, &StartOfLine);
+
+		if (Option.lineDirectives && vStringChar (File.line, 0) == '#')
+			parseLineDirective (vStringValue (File.line) + 1);
+		matchRegex (File.line, File.source.language);
+
+		return File.line;
+	}
+
+	return NULL;
 }
 
 /*  Do not mix use of readLineFromInputFile () and getcFromInputFile () for the same file.


Modified: ctags/main/read.h
3 lines changed, 0 insertions(+), 3 deletions(-)
===================================================================
@@ -78,8 +78,6 @@ typedef struct sInputFile {
 	MIOPos  filePosition;   /* file position of current line */
 	unsigned int ungetchIdx;
 	int     ungetchBuf[3];  /* characters that were ungotten */
-	bool eof;           /* have we reached the end of file? */
-	bool newLine;       /* will the next character begin a new line? */
 
 	/*  Contains data pertaining to the original source file in which the tag
 	 *  was defined. This may be different from the input file when #line
@@ -104,7 +102,6 @@ extern kindOption *getInputLanguageFileKind (void);
 
 extern void freeSourceFileResources (void);
 extern bool fileOpen (const char *const fileName, const langType language);
-extern bool fileEOF (void);
 extern void fileClose (void);
 extern int getcFromInputFile (void);
 extern int getNthPrevCFromInputFile (unsigned int nth, int def);



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