Branch: refs/heads/master Author: Jiří Techet techet@gmail.com Committer: Jiří Techet techet@gmail.com Date: Tue, 11 Oct 2016 10:26:51 UTC Commit: aafb12702427793cfe1e4f9dd1b77db9c5c9f3cc https://github.com/geany/geany/commit/aafb12702427793cfe1e4f9dd1b77db9c5c9f3...
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).