From fc6a9bb9cb780e89cafe62a1a1a9126dca1f48dd Mon Sep 17 00:00:00 2001 From: Colomban Wendling Date: Fri, 9 Nov 2018 14:29:54 +0100 Subject: [PATCH 1/3] tm: Cleanup include lookup Don't use the files inode as the hash. Although it looks like a good idea for de-duplicating links as well, it has several issues, including non-uniqueness of inodes across file systems. The way it was done hashing the inode but comparing the file name string pointers also made the hash mostly irrelevant, as it just stored filenames sharing the same inode in the same hash bucket but without actually doing any de-duplication, making the whole thing a convoluted way of converting to a list. Instead, hash and compare the filenames themselves, which, even though it doesn't handle links de-duplication, is better than the non-functional previous code. Also, directly build the list and only use the hash table as a way for checking for duplicates, which is both faster and gives a stable output. --- src/tagmanager/tm_workspace.c | 35 ++++------------------------------- 1 file changed, 4 insertions(+), 31 deletions(-) diff --git a/src/tagmanager/tm_workspace.c b/src/tagmanager/tm_workspace.c index c798e95c30..58d9bf3839 100644 --- a/src/tagmanager/tm_workspace.c +++ b/src/tagmanager/tm_workspace.c @@ -370,34 +370,6 @@ gboolean tm_workspace_load_global_tags(const char *tags_file, TMParserType mode) } -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); - } - - return 0; -} - - -static void tm_move_entries_to_g_list(gpointer key, gpointer value, gpointer user_data) -{ - GList **pp_list = (GList**)user_data; - - if (user_data == NULL) - return; - - *pp_list = g_list_prepend(*pp_list, g_strdup(value)); -} - - static gboolean write_includes_file(const gchar *outf, GList *includes_files) { FILE *fp = g_fopen(outf, "w"); @@ -470,14 +442,14 @@ static gchar *create_temp_file(const gchar *tpl) static GList *lookup_includes(const gchar **includes, gint includes_count) { GList *includes_files = NULL; - GHashTable *table; + GHashTable *table; /* used for deduping */ gint i; #ifdef HAVE_GLOB_H glob_t globbuf; size_t idx_glob; #endif - table = g_hash_table_new_full(tm_file_inode_hash, g_direct_equal, NULL, g_free); + table = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); #ifdef HAVE_GLOB_H globbuf.gl_offs = 0; @@ -515,6 +487,7 @@ static GList *lookup_includes(const gchar **includes, gint includes_count) { gchar *file_name_copy = g_strdup(globbuf.gl_pathv[idx_glob]); + includes_files = g_list_prepend(includes_files, file_name_copy); g_hash_table_insert(table, file_name_copy, file_name_copy); #ifdef TM_DEBUG g_message ("Added ...\n"); @@ -535,12 +508,12 @@ static GList *lookup_includes(const gchar **includes, gint includes_count) { gchar* file_name_copy = g_strdup(includes[i]); + includes_files = g_list_prepend(includes_files, file_name_copy); 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); return includes_files; From 939dab08e0c12fb55aa34a1fab5d84e031dcb1fb Mon Sep 17 00:00:00 2001 From: Colomban Wendling Date: Mon, 12 Nov 2018 11:33:58 +0100 Subject: [PATCH 2/3] Process files in the order they are listed when generating a tags file --- src/tagmanager/tm_workspace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tagmanager/tm_workspace.c b/src/tagmanager/tm_workspace.c index 58d9bf3839..54563a7080 100644 --- a/src/tagmanager/tm_workspace.c +++ b/src/tagmanager/tm_workspace.c @@ -516,7 +516,7 @@ static GList *lookup_includes(const gchar **includes, gint includes_count) g_hash_table_destroy(table); - return includes_files; + return g_list_reverse(includes_files); } static gchar *pre_process_file(const gchar *cmd, const gchar *inf) From 8b68c5a2caec368d243c5a588c12121f7b20550c Mon Sep 17 00:00:00 2001 From: Colomban Wendling Date: Mon, 12 Nov 2018 11:34:55 +0100 Subject: [PATCH 3/3] Add a test for the processing order when generating a tags file --- tests/ctags/Makefile.am | 10 ++++++++++ tests/ctags/process_order.c.tags | 7 +++++++ tests/ctags/process_order_1.h | 4 ++++ tests/ctags/process_order_2.h | 4 ++++ tests/ctags/runner.sh | 18 +++++++++++++++--- 5 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 tests/ctags/process_order.c.tags create mode 100644 tests/ctags/process_order_1.h create mode 100644 tests/ctags/process_order_2.h diff --git a/tests/ctags/Makefile.am b/tests/ctags/Makefile.am index 90937900d5..b9ef000727 100644 --- a/tests/ctags/Makefile.am +++ b/tests/ctags/Makefile.am @@ -319,3 +319,13 @@ TAGS_LOG_COMPILER = $(srcdir)/runner.sh TESTS = $(test_results) EXTRA_DIST = $(test_sources) $(test_results) + +# check processing order of files on the command line +check_processing_order_sources = \ + process_order.c.tags process_order_1.h process_order_2.h +EXTRA_DIST += $(check_processing_order_sources) +.PHONY: check-processing-order +check-processing-order: $(check_processing_order_sources) + srcdir="$(srcdir)" top_builddir="$(top_builddir)" \ + $(srcdir)/runner.sh --result $(check_processing_order_sources:%=$(srcdir)/%) +check-local: check-processing-order diff --git a/tests/ctags/process_order.c.tags b/tests/ctags/process_order.c.tags new file mode 100644 index 0000000000..91b317c16d --- /dev/null +++ b/tests/ctags/process_order.c.tags @@ -0,0 +1,7 @@ +# format=tagmanager +I1_E1Ì4Îanon_enum_0Ö0 +I1_E2Ì4Îanon_enum_0Ö0 +I2_E1Ì4Îanon_enum_1Ö0 +I2_E2Ì4Îanon_enum_1Ö0 +anon_enum_0Ì2Ö0 +anon_enum_1Ì2Ö0 diff --git a/tests/ctags/process_order_1.h b/tests/ctags/process_order_1.h new file mode 100644 index 0000000000..99d6357131 --- /dev/null +++ b/tests/ctags/process_order_1.h @@ -0,0 +1,4 @@ +enum { + I1_E1, + I1_E2, +}; diff --git a/tests/ctags/process_order_2.h b/tests/ctags/process_order_2.h new file mode 100644 index 0000000000..338cdb0c4e --- /dev/null +++ b/tests/ctags/process_order_2.h @@ -0,0 +1,4 @@ +enum { + I2_E1, + I2_E2, +}; diff --git a/tests/ctags/runner.sh b/tests/ctags/runner.sh index 058f5c60b9..d722c9a879 100755 --- a/tests/ctags/runner.sh +++ b/tests/ctags/runner.sh @@ -17,9 +17,21 @@ mkdir -p "$CONFDIR/filedefs/" || exit 99 cp "${srcdir:-.}"/../../data/filetype_extensions.conf "$CONFDIR" || exit 99 cp "${srcdir:-.}"/../../data/filedefs/filetypes.* "$CONFDIR/filedefs/" || exit 99 -result="$1" -source="${result%.*}" +if [ "$1" = "--result" ]; then + # --result $result $source... + [ $# -gt 2 ] || exit 99 + shift + result="$1" + shift + source="$1" +else + # result is $1 and source is inferred from result + result="$1" + source="${result%.*}" +fi +shift + tagfile="$TMPDIR/test.${source##*.}.tags" -"$GEANY" -c "$CONFDIR" -P -g "$tagfile" "$source" || exit 1 +"$GEANY" -c "$CONFDIR" -P -g "$tagfile" "$source" "$@" || exit 1 diff -u "$result" "$tagfile" || exit 2