[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