Branch: refs/heads/master Author: Jiří Techet techet@gmail.com Committer: Jiří Techet techet@gmail.com Date: Mon, 21 Mar 2016 17:28:36 UTC Commit: b72b8596346c5dcecb4ecb55d12311b2405a470f https://github.com/geany/geany/commit/b72b8596346c5dcecb4ecb55d12311b2405a47...
Log Message: ----------- Clean up messy tm_workspace_create_global_tags()
At the same time ignore tags of the type tm_tag_undef_t when parsing - we cannot query them anyway and this eliminates the need to call
tm_tags_extract(source_file->tags_array, tm_tag_max_t);
when creating tags file.
Modified Paths: -------------- tagmanager/src/tm_source_file.c tagmanager/src/tm_workspace.c
Modified: tagmanager/src/tm_source_file.c 17 lines changed, 12 insertions(+), 5 deletions(-) =================================================================== @@ -239,14 +239,17 @@ static char get_tag_access(const char *access) */ static gboolean init_tag(TMTag *tag, TMSourceFile *file, const tagEntryInfo *tag_entry) { - if (NULL == tag_entry) + TMTagType type; + + if (!tag_entry) return FALSE;
- /* This is a normal tag entry */ - if (NULL == tag_entry->name) + type = get_tag_type(tag_entry->kindName); + if (!tag_entry->name || type == tm_tag_undef_t) return FALSE; + tag->name = g_strdup(tag_entry->name); - tag->type = get_tag_type(tag_entry->kindName); + tag->type = type; tag->local = tag_entry->isFileScope; tag->pointerOrder = 0; /* backward compatibility (use var_type instead) */ tag->line = tag_entry->lineNumber; @@ -736,7 +739,11 @@ static gboolean tm_source_file_tags(const tagEntryInfo *const tag,
tm_tag = tm_tag_new();
- init_tag(tm_tag, current_source_file, tag); + if (!init_tag(tm_tag, current_source_file, tag)) + { + tm_tag_unref(tm_tag); + return TRUE; + }
if (tm_tag->lang == TM_PARSER_PYTHON) update_python_arglist(tm_tag, current_source_file);
Modified: tagmanager/src/tm_workspace.c 304 lines changed, 161 insertions(+), 143 deletions(-) =================================================================== @@ -372,15 +372,16 @@ static guint tm_file_inode_hash(gconstpointer key) { GStatBuf file_stat; const char *filename = (const char*)key; + if (g_stat(filename, &file_stat) == 0) { #ifdef TM_DEBUG g_message ("Hash for '%s' is '%d'\n", filename, file_stat.st_ino); #endif return g_direct_hash ((gpointer)(intptr_t)file_stat.st_ino); - } else { - return 0; } + + return 0; }
@@ -391,15 +392,18 @@ static void tm_move_entries_to_g_list(gpointer key, gpointer value, gpointer use if (user_data == NULL) return;
- *pp_list = g_list_prepend(*pp_list, value); + *pp_list = g_list_prepend(*pp_list, g_strdup(value)); }
-static void write_includes_file(FILE *fp, GList *includes_files) +static gboolean write_includes_file(const gchar *outf, GList *includes_files) { - GList *node; + FILE *fp = g_fopen(outf, "w"); + GList *node = includes_files; + + if (!fp) + return FALSE;
- node = includes_files; while (node) { char *str = g_strdup_printf("#include "%s"\n", (char*)node->data); @@ -409,14 +413,21 @@ static void write_includes_file(FILE *fp, GList *includes_files) g_free(str); node = g_list_next(node); } + + fclose(fp); + + return TRUE; }
-static void append_to_temp_file(FILE *fp, GList *file_list) +static gboolean append_to_temp_file(const gchar *outf, GList *file_list) { - GList *node; + FILE *fp = g_fopen(outf, "w"); + GList *node = file_list; + + if (!fp) + return FALSE;
- node = file_list; while (node) { const char *fname = node->data; @@ -437,6 +448,10 @@ static void append_to_temp_file(FILE *fp, GList *file_list) } node = g_list_next (node); } + + fclose(fp); + + return TRUE; }
@@ -454,187 +469,190 @@ static gchar *create_temp_file(const gchar *tpl) return name; }
- -/* Creates a list of global tags. Ideally, this should be created once during - installations so that all users can use the same file. This is because a full - scale global tag list can occupy several megabytes of disk space. - @param pre_process The pre-processing command. This is executed via system(), - so you can pass stuff like 'gcc -E -dD -P `gnome-config --cflags gnome`'. - @param includes Include files to process. Wildcards such as '/usr/include/a*.h' - are allowed. - @param tags_file The file where the tags will be stored. - @param lang The language to use for the tags file. - @return TRUE on success, FALSE on failure. -*/ -gboolean tm_workspace_create_global_tags(const char *pre_process, const char **includes, - int includes_count, const char *tags_file, TMParserType lang) +static GList *lookup_includes(const gchar **includes, gint includes_count) { + GList *includes_files = NULL; + GHashTable *table; + gint i; #ifdef HAVE_GLOB_H glob_t globbuf; size_t idx_glob; #endif - int idx_inc; - char *command; - guint i; - FILE *fp; - TMSourceFile *source_file; - GPtrArray *tags_array; - GHashTable *includes_files_hash; - GList *includes_files = NULL; - gchar *temp_file = create_temp_file("tmp_XXXXXX.cpp"); - gchar *temp_file2 = create_temp_file("tmp_XXXXXX.cpp"); - gboolean ret; - - if (NULL == temp_file || NULL == temp_file2 || - NULL == (fp = g_fopen(temp_file, "w"))) - { - g_free(temp_file); - g_free(temp_file2); - return FALSE; - }
- includes_files_hash = g_hash_table_new_full (tm_file_inode_hash, - g_direct_equal, - NULL, g_free); + table = g_hash_table_new_full(tm_file_inode_hash, g_direct_equal, NULL, g_free);
#ifdef HAVE_GLOB_H globbuf.gl_offs = 0;
if (includes[0][0] == '"') /* leading " char for glob matching */ - for(idx_inc = 0; idx_inc < includes_count; idx_inc++) { - size_t dirty_len = strlen(includes[idx_inc]); - char *clean_path = g_malloc(dirty_len - 1); + for (i = 0; i < includes_count; i++) + { + size_t dirty_len = strlen(includes[i]); + gchar *clean_path = g_malloc(dirty_len - 1);
- strncpy(clean_path, includes[idx_inc] + 1, dirty_len - 1); - clean_path[dirty_len - 2] = 0; + strncpy(clean_path, includes[i] + 1, dirty_len - 1); + clean_path[dirty_len - 2] = 0;
#ifdef TM_DEBUG - g_message ("[o][%s]\n", clean_path); + g_message ("[o][%s]\n", clean_path); #endif - glob(clean_path, 0, NULL, &globbuf); + glob(clean_path, 0, NULL, &globbuf);
#ifdef TM_DEBUG - g_message ("matches: %d\n", globbuf.gl_pathc); + g_message ("matches: %d\n", globbuf.gl_pathc); #endif
- for(idx_glob = 0; idx_glob < globbuf.gl_pathc; idx_glob++) - { + for (idx_glob = 0; idx_glob < globbuf.gl_pathc; idx_glob++) + { #ifdef TM_DEBUG - g_message (">>> %s\n", globbuf.gl_pathv[idx_glob]); + g_message (">>> %s\n", globbuf.gl_pathv[idx_glob]); #endif - if (!g_hash_table_lookup(includes_files_hash, - globbuf.gl_pathv[idx_glob])) - { - char* file_name_copy = strdup(globbuf.gl_pathv[idx_glob]); - g_hash_table_insert(includes_files_hash, file_name_copy, - file_name_copy); + if (!g_hash_table_lookup(table, globbuf.gl_pathv[idx_glob])) + { + gchar *file_name_copy = strdup(globbuf.gl_pathv[idx_glob]); + + g_hash_table_insert(table, file_name_copy, file_name_copy); #ifdef TM_DEBUG - g_message ("Added ...\n"); + g_message ("Added ...\n"); #endif + } } + globfree(&globbuf); + g_free(clean_path); } - globfree(&globbuf); - g_free(clean_path); - } - else -#endif - /* no glob support or globbing not wanted */ - for(idx_inc = 0; idx_inc < includes_count; idx_inc++) + } + else +#endif /* HAVE_GLOB_H */ { - if (!g_hash_table_lookup(includes_files_hash, - includes[idx_inc])) + /* no glob support or globbing not wanted */ + for (i = 0; i < includes_count; i++) { - char* file_name_copy = strdup(includes[idx_inc]); - g_hash_table_insert(includes_files_hash, file_name_copy, - file_name_copy); + if (!g_hash_table_lookup(table, includes[i])) + { + gchar* file_name_copy = strdup(includes[i]); + + g_hash_table_insert(table, file_name_copy, file_name_copy); + } } - } + } + + g_hash_table_foreach(table, tm_move_entries_to_g_list, &includes_files); + g_hash_table_destroy(table);
- /* Checks for duplicate file entries which would case trouble */ - g_hash_table_foreach(includes_files_hash, tm_move_entries_to_g_list, - &includes_files); + return g_list_reverse(includes_files); +}
- includes_files = g_list_reverse (includes_files); +static gchar *pre_process_file(const gchar *cmd, const gchar *inf) +{ + gint ret; + gchar *outf = create_temp_file("tmp_XXXXXX.cpp"); + gchar *tmp_errfile = create_temp_file("tmp_XXXXXX"); + gchar *errors = NULL; + gchar *command;
+ if (!outf) + return NULL; + if (!tmp_errfile) + { + g_unlink(outf); + g_free(outf); + return NULL; + } + + command = g_strdup_printf("%s %s >%s 2>%s", + cmd, inf, outf, tmp_errfile); #ifdef TM_DEBUG - g_message ("writing out files to %s\n", temp_file); + g_message("Executing: %s", command); #endif - if (pre_process != NULL) - write_includes_file(fp, includes_files); - else - append_to_temp_file(fp, includes_files); + ret = system(command); + g_free(command);
- g_list_free (includes_files); - g_hash_table_destroy(includes_files_hash); - includes_files_hash = NULL; - includes_files = NULL; - fclose(fp); + g_file_get_contents(tmp_errfile, &errors, NULL, NULL); + if (errors && *errors) + g_printerr("%s", errors); + g_free(errors); + g_unlink(tmp_errfile); + g_free(tmp_errfile);
- if (pre_process != NULL) + if (ret == -1) { - gint ret; - gchar *tmp_errfile = create_temp_file("tmp_XXXXXX"); - gchar *errors = NULL; - command = g_strdup_printf("%s %s >%s 2>%s", - pre_process, temp_file, temp_file2, tmp_errfile); + g_unlink(outf); + g_free(outf); + return NULL; + } + + return outf; +} + +/* Creates a list of global tags. Ideally, this should be created once during + installations so that all users can use the same file. This is because a full + scale global tag list can occupy several megabytes of disk space. + @param pre_process The pre-processing command. This is executed via system(), + so you can pass stuff like 'gcc -E -dD -P `gnome-config --cflags gnome`'. + @param includes Include files to process. Wildcards such as '/usr/include/a*.h' + are allowed. + @param tags_file The file where the tags will be stored. + @param lang The language to use for the tags file. + @return TRUE on success, FALSE on failure. +*/ +gboolean tm_workspace_create_global_tags(const char *pre_process, const char **includes, + int includes_count, const char *tags_file, TMParserType lang) +{ + gboolean ret = FALSE; + TMSourceFile *source_file; + GList *includes_files; + gchar *temp_file = create_temp_file("tmp_XXXXXX.cpp"); + + if (!temp_file) + return FALSE; + + includes_files = lookup_includes(includes, includes_count); + #ifdef TM_DEBUG - g_message("Executing: %s", command); + g_message ("writing out files to %s\n", temp_file); #endif - ret = system(command); - g_free(command); - g_unlink(temp_file); - g_free(temp_file); - g_file_get_contents(tmp_errfile, &errors, NULL, NULL); - if (errors && *errors) - g_printerr("%s", errors); - g_free(errors); - g_unlink(tmp_errfile); - g_free(tmp_errfile); - if (ret == -1) - { - g_unlink(temp_file2); - return FALSE; - } - } + if (pre_process) + ret = write_includes_file(temp_file, includes_files); else + ret = append_to_temp_file(temp_file, includes_files); + + g_list_free_full(includes_files, g_free); + if (!ret) + goto cleanup; + ret = FALSE; + + if (pre_process) { - /* no pre-processing needed, so temp_file2 = temp_file */ - g_unlink(temp_file2); - g_free(temp_file2); - temp_file2 = temp_file; - temp_file = NULL; + gchar *temp_file2 = pre_process_file(pre_process, temp_file); + + if (temp_file2) + { + g_unlink(temp_file); + g_free(temp_file); + temp_file = temp_file2; + } + else + goto cleanup; } - source_file = tm_source_file_new(temp_file2, tm_source_file_get_lang_name(lang)); + + source_file = tm_source_file_new(temp_file, tm_source_file_get_lang_name(lang)); + if (!source_file) + goto cleanup; update_source_file(source_file, NULL, 0, FALSE, FALSE); - if (NULL == source_file) + if (source_file->tags_array->len == 0) { - g_unlink(temp_file2); - return FALSE; - } - g_unlink(temp_file2); - g_free(temp_file2); - if (0 == source_file->tags_array->len) - { - tm_source_file_free(source_file); - return FALSE; - } - tags_array = tm_tags_extract(source_file->tags_array, tm_tag_max_t); - if ((NULL == tags_array) || (0 == tags_array->len)) - { - if (tags_array) - g_ptr_array_free(tags_array, TRUE); tm_source_file_free(source_file); - return FALSE; + goto cleanup; } - if (FALSE == tm_tags_sort(tags_array, global_tags_sort_attrs, TRUE, FALSE)) - { - tm_source_file_free(source_file); - return FALSE; - } - ret = tm_source_file_write_tags_file(tags_file, tags_array); + + tm_tags_sort(source_file->tags_array, global_tags_sort_attrs, TRUE, FALSE); + ret = tm_source_file_write_tags_file(tags_file, source_file->tags_array); tm_source_file_free(source_file); - g_ptr_array_free(tags_array, TRUE); + +cleanup: + g_unlink(temp_file); + g_free(temp_file); return ret; }
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).