[geany/geany] b72b85: Clean up messy tm_workspace_create_global_tags()

Jiří Techet git-noreply at xxxxx
Fri Jun 10 21:57:26 UTC 2016


Branch:      refs/heads/master
Author:      Jiří Techet <techet at gmail.com>
Committer:   Jiří Techet <techet at gmail.com>
Date:        Mon, 21 Mar 2016 17:28:36 UTC
Commit:      b72b8596346c5dcecb4ecb55d12311b2405a470f
             https://github.com/geany/geany/commit/b72b8596346c5dcecb4ecb55d12311b2405a470f

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


More information about the Commits mailing list