[geany/geany] aafb12: read: implement openBuffer() using openInputFile()

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


Branch:      refs/heads/master
Author:      Jiří Techet <techet at gmail.com>
Committer:   Jiří Techet <techet at gmail.com>
Date:        Tue, 11 Oct 2016 10:26:51 UTC
Commit:      aafb12702427793cfe1e4f9dd1b77db9c5c9f3cc
             https://github.com/geany/geany/commit/aafb12702427793cfe1e4f9dd1b77db9c5c9f3cc

Log Message:
-----------
read: implement openBuffer() using openInputFile()

In addition, add automatic memory MIO opening to read.c for small files
and remove the same optimization from Geany. Simplify tm_ctags_parse()
as the memory/file branches are identical now.


Modified Paths:
--------------
    ctags/main/parse.c
    ctags/main/read.c
    ctags/main/read.h
    src/tagmanager/tm_ctags_wrappers.c
    src/tagmanager/tm_source_file.c

Modified: ctags/main/parse.c
2 lines changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -574,7 +574,7 @@ static bool createTagsForFile (const char *const fileName,
 {
 	bool retried = false;
 
-	if (openInputFile (fileName, language))
+	if (openInputFile (fileName, language, NULL))
 	{
 
 		makeFileTag (fileName);


Modified: ctags/main/read.c
83 lines changed, 46 insertions(+), 37 deletions(-)
===================================================================
@@ -401,10 +401,46 @@ static bool parseLineDirective (char *s)
  *   Input file I/O operations
  */
 
+#define MAX_IN_MEMORY_FILE_SIZE (1024*1024)
+
+extern MIO *getMio (const char *const fileName, const char *const openMode,
+		    bool memStreamRequired)
+{
+	FILE *src;
+	fileStatus *st;
+	unsigned long size;
+	unsigned char *data;
+
+	st = eStat (fileName);
+	size = st->size;
+	eStatFree (st);
+	if ((!memStreamRequired)
+	    && (size > MAX_IN_MEMORY_FILE_SIZE || size == 0))
+		return mio_new_file (fileName, openMode);
+
+	src = fopen (fileName, openMode);
+	if (!src)
+		return NULL;
+
+	data = eMalloc (size);
+	if (fread (data, 1, size, src) != size)
+	{
+		eFree (data);
+		fclose (src);
+		if (memStreamRequired)
+			return NULL;
+		else
+			return mio_new_file (fileName, openMode);
+	}
+	fclose (src);
+	return mio_new_memory (data, size, eRealloc, eFree);
+}
+
 /*  This function opens an input file, and resets the line counter.  If it
  *  fails, it will display an error message and leave the File.mio set to NULL.
  */
-extern bool openInputFile (const char *const fileName, const langType language)
+extern bool openInputFile (const char *const fileName, const langType language,
+			      MIO *mio)
 {
 	const char *const openMode = "rb";
 	bool opened = false;
@@ -417,7 +453,8 @@ extern bool openInputFile (const char *const fileName, const langType language)
 		File.mio = NULL;
 	}
 
-	File.mio = mio_new_file (fileName, openMode);
+	File.mio = mio? mio_ref (mio): getMio (fileName, openMode, true);
+
 	if (File.mio == NULL)
 		error (WARNING | PERROR, "cannot open \"%s\"", fileName);
 	else
@@ -447,43 +484,15 @@ extern bool openInputFile (const char *const fileName, const langType language)
  * This func is NOT THREAD SAFE.
  * The user should not tamper with the buffer while this func is executing.
  */
-extern bool bufferOpen (unsigned char *buffer, size_t buffer_size,
-						const char *const fileName, const langType language )
+extern bool bufferOpen (const char *const fileName, const langType language,
+						unsigned char *buffer, size_t buffer_size)
 {
-	bool opened = false;
-		
-	/* Check whether a file of a buffer were already open, then close them.
-	 */
-	if (File.mio != NULL) {
-		mio_free (File.mio);            /* close any open source file */
-		File.mio = NULL;
-	}
-
-	/* check if we got a good buffer */
-	if (buffer == NULL || buffer_size == 0) {
-		opened = false;
-		return opened;
-	}
-		
-	opened = true;
-			
-	File.mio = mio_new_memory (buffer, buffer_size, NULL, NULL);
-	setInputFileName (fileName);
-	mio_getpos (File.mio, &StartOfLine);
-	mio_getpos (File.mio, &File.filePosition);
-	File.currentLine  = NULL;
-	File.input.lineNumber   = 0L;
-
-	if (File.line != NULL)
-		vStringClear (File.line);
-
-	setSourceFileParameters (vStringNewInit (fileName), language);
-	File.source.lineNumber = 0L;
-
-	verbose ("OPENING %s as %s language %sfile\n", fileName,
-			getLanguageName (language),
-			File.source.isHeader ? "include " : "");
+	MIO *mio;
+	bool opened;
 
+	mio = mio_new_memory (buffer, buffer_size, NULL, NULL);
+	opened = openInputFile (fileName, language, mio);
+	mio_free (mio);
 	return opened;
 }
 


Modified: ctags/main/read.h
12 lines changed, 9 insertions(+), 3 deletions(-)
===================================================================
@@ -70,15 +70,21 @@ extern kindOption *getInputLanguageFileKind (void);
 extern bool doesInputLanguageRequestAutomaticFQTag (void);
 
 extern void freeInputFileResources (void);
-extern bool openInputFile (const char *const fileName, const langType language);
+/* Stream opend by getMio can be passed to openInputFile as the 3rd
+   argument. If the 3rd argument is NULL, openInputFile calls getMio
+   internally. The 3rd argument is introduced for reusing mio object
+   created in parser guessing stage. */
+extern bool openInputFile (const char *const fileName, const langType language, MIO *mio);
+extern bool bufferOpen (const char *const fileName, const langType language,
+						unsigned char *buffer, size_t buffer_size);
+extern MIO *getMio (const char *const fileName, const char *const openMode,
+				    bool memStreamRequired);
 extern void closeInputFile (void);
 extern int getcFromInputFile (void);
 extern int getNthPrevCFromInputFile (unsigned int nth, int def);
 extern int skipToCharacterInInputFile (int c);
 extern void ungetcToInputFile (int c);
 extern const unsigned char *readLineFromInputFile (void);
-extern bool bufferOpen (unsigned char *buffer, size_t buffer_size,
-                        const char *const fileName, const langType language );
 
 extern const char *getSourceFileTagPath (void);
 extern const char *getSourceLanguageName (void);


Modified: src/tagmanager/tm_ctags_wrappers.c
20 lines changed, 3 insertions(+), 17 deletions(-)
===================================================================
@@ -69,27 +69,13 @@ void tm_ctags_parse(guchar *buffer, gsize buffer_size,
 	while (retry && passCount < 3)
 	{
 		pass_callback(user_data);
-		if (!buffer && openInputFile (file_name, lang))
+		if ((!buffer && openInputFile (file_name, lang, NULL)) ||
+			(buffer && bufferOpen (file_name, lang, buffer, buffer_size)))
 		{
 			if (LanguageTable [lang]->parser != NULL)
 			{
 				LanguageTable [lang]->parser ();
-				closeInputFile ();
 				retry = FALSE;
-				break;
-			}
-			else if (LanguageTable [lang]->parser2 != NULL)
-				retry = LanguageTable [lang]->parser2 (passCount);
-			closeInputFile ();
-		}
-		else if (buffer && bufferOpen (buffer, buffer_size, file_name, lang))
-		{
-			if (LanguageTable [lang]->parser != NULL)
-			{
-				LanguageTable [lang]->parser ();
-				closeInputFile ();
-				retry = FALSE;
-				break;
 			}
 			else if (LanguageTable [lang]->parser2 != NULL)
 				retry = LanguageTable [lang]->parser2 (passCount);
@@ -98,7 +84,7 @@ void tm_ctags_parse(guchar *buffer, gsize buffer_size,
 		else
 		{
 			g_warning("Unable to open %s", file_name);
-			return;
+			break;
 		}
 		++ passCount;
 	}


Modified: src/tagmanager/tm_source_file.c
28 lines changed, 2 insertions(+), 26 deletions(-)
===================================================================
@@ -790,8 +790,6 @@ gboolean tm_source_file_parse(TMSourceFile *source_file, guchar* text_buf, gsize
 {
 	const char *file_name;
 	gboolean retry = TRUE;
-	gboolean parse_file = FALSE;
-	gboolean free_buf = FALSE;
 
 	if ((NULL == source_file) || (NULL == source_file->file_name))
 	{
@@ -807,40 +805,18 @@ gboolean tm_source_file_parse(TMSourceFile *source_file, guchar* text_buf, gsize
 	
 	file_name = source_file->file_name;
 	
-	if (!use_buffer)
-	{
-		GStatBuf s;
-		
-		/* load file to memory and parse it from memory unless the file is too big */
-		if (g_stat(file_name, &s) != 0 || s.st_size > 10*1024*1024)
-			parse_file = TRUE;
-		else
-		{
-			if (!g_file_get_contents(file_name, (gchar**)&text_buf, (gsize*)&buf_size, NULL))
-			{
-				g_warning("Unable to open %s", file_name);
-				return FALSE;
-			}
-			free_buf = TRUE;
-		}
-	}
-
-	if (!parse_file && (NULL == text_buf || 0 == buf_size))
+	if (use_buffer && (NULL == text_buf || 0 == buf_size))
 	{
 		/* Empty buffer, "parse" by setting empty tag array */
 		tm_tags_array_free(source_file->tags_array, FALSE);
-		if (free_buf)
-			g_free(text_buf);
 		return TRUE;
 	}
 
 	tm_tags_array_free(source_file->tags_array, FALSE);
 
-	tm_ctags_parse(parse_file ? NULL : text_buf, buf_size, file_name,
+	tm_ctags_parse(use_buffer ? text_buf : NULL, buf_size, file_name,
 		source_file->lang, ctags_new_tag, ctags_pass_start, source_file);
 
-	if (free_buf)
-		g_free(text_buf);
 	return !retry;
 }
 



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