Revision: 1480 http://svn.sourceforge.net/geany/?rev=1480&view=rev Author: ntrel Date: 2007-04-27 04:00:29 -0700 (Fri, 27 Apr 2007)
Log Message: ----------- Add support for generating global tags files for non-C-like filetypes.
Modified Paths: -------------- trunk/ChangeLog trunk/src/main.c trunk/src/symbols.c trunk/tagmanager/include/tm_workspace.h trunk/tagmanager/tm_workspace.c
Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2007-04-27 10:58:41 UTC (rev 1479) +++ trunk/ChangeLog 2007-04-27 11:00:29 UTC (rev 1480) @@ -1,3 +1,14 @@ +2007-04-26 Nick Treleaven nick.treleaven@btinternet.com + + * tagmanager/tm_source_file.c, tagmanager/include/tm_source_file.h: + Add tm_source_file_get_lang_name() as a wrapper for getLanguageName() + in parse.c. + * src/main.c, src/symbols.c, tagmanager/tm_workspace.c, + tagmanager/include/tm_workspace.h: + Add support for generating global tags files for non-C-like + filetypes. + + 2007-04-25 Nick Treleaven nick.treleaven@btinternet.com
* src/filetypes.c, src/filetypes.h, src/main.c:
Modified: trunk/src/main.c =================================================================== --- trunk/src/main.c 2007-04-27 10:58:41 UTC (rev 1479) +++ trunk/src/main.c 2007-04-27 11:00:29 UTC (rev 1480) @@ -467,6 +467,8 @@ { gboolean ret;
+ filetypes_init_types(); + configuration_read_filetype_extensions(); // needed for *.lang.tags filetype matching ret = symbols_generate_global_tags(*argc, *argv); exit(ret); }
Modified: trunk/src/symbols.c =================================================================== --- trunk/src/symbols.c 2007-04-27 10:58:41 UTC (rev 1479) +++ trunk/src/symbols.c 2007-04-27 11:00:29 UTC (rev 1480) @@ -704,10 +704,33 @@ }
+/* Detects a global tags filetype from the *.lang.* language extension. + * Returns NULL if there was no matching TM language. */ +static filetype *detect_global_tags_filetype(const gchar *utf8_filename) +{ + gchar *tags_ext; + gchar *shortname = g_strdup(utf8_filename); + filetype *ft = NULL; + + tags_ext = strstr(shortname, ".tags"); + if (tags_ext) + { + *tags_ext = '\0'; // remove .tags extension + ft = filetypes_detect_from_filename(shortname); + } + g_free(shortname); + + if (filetypes[FILETYPE_ID(ft)]->lang < 0) + return NULL; + return ft; +} + + /* Adapted from anjuta-2.0.2/global-tags/tm_global_tags.c, thanks. - * Needs full path and " quoting characters around filenames. + * Needs full paths for filenames, except for C/C++ tag files, when CFLAGS includes + * the relevant path. * Example: - * geany -g tagsfile "/home/nmt/svn/geany/src/d*.h" */ + * CFLAGS=-I/home/user/libname-1.x geany -g libname.d.tags libname.h */ int symbols_generate_global_tags(int argc, char **argv) { /* -E pre-process, -dD output user macros, -p prof info (?), @@ -719,15 +742,34 @@ /* Create global taglist */ int status; char *command; - command = g_strdup_printf("%s %s", pre_process, - NVL(getenv("CFLAGS"), "")); - //printf(">%s<\n", command); + const char *tags_file = argv[1]; + char *utf8_fname; + filetype *ft; + + utf8_fname = utils_get_utf8_from_locale(tags_file); + ft = detect_global_tags_filetype(utf8_fname); + g_free(utf8_fname); + + if (ft == NULL) + { + fprintf(stderr, "Unknown filetype extension for "%s".\n", tags_file); + return 1; + } + if (ft->lang == 0 || ft->lang == 1) /* C/C++ */ + command = g_strdup_printf("%s %s", pre_process, NVL(getenv("CFLAGS"), "")); + else + command = NULL; // don't preprocess + + geany_debug("Generating %s tags file.", ft->name); status = tm_workspace_create_global_tags(command, (const char **) (argv + 2), - argc - 2, argv[1]); + argc - 2, tags_file, ft->lang); g_free(command); - if (!status) + if (! status) + { + fprintf(stderr, "Failed to create tags file.\n"); return 1; + } } else { @@ -741,34 +783,6 @@ }
-// fname should be in locale encoding -static gboolean load_tags_filename(const gchar *fname) -{ - gchar *tags_ext; - gchar *shortname = g_strdup(fname); - gboolean ret = FALSE; - - tags_ext = strstr(shortname, ".tags"); - if (tags_ext) - { - gchar *utf8_shortname; - filetype *ft; - - *tags_ext = '\0'; // remove .tags extension - utf8_shortname = utils_get_utf8_from_locale(shortname); - ft = filetypes_detect_from_filename(utf8_shortname); - g_free(utf8_shortname); - - if (ft) - { - ret = tm_workspace_load_global_tags(fname, ft->lang); - } - } - g_free(shortname); - return ret; -} - - void symbols_show_load_tags_dialog() { GtkWidget *dialog; @@ -793,13 +807,16 @@ { gchar *fname = item->data; gchar *utf8_fname; - gboolean ok; + filetype *ft;
- ok = load_tags_filename(fname); + utf8_fname = utils_get_utf8_from_locale(fname); + ft = detect_global_tags_filetype(utf8_fname);
- utf8_fname = utils_get_utf8_from_locale(fname); - msgwin_status_add(ok ? _("Loaded tags file '%s'.") : - _("Could not load tags file '%s'."), utf8_fname); + if (ft != NULL && tm_workspace_load_global_tags(fname, ft->lang)) + msgwin_status_add(_("Loaded %s tags file '%s'."), ft->name, utf8_fname); + else + msgwin_status_add(_("Could not load tags file '%s'."), utf8_fname); + g_free(utf8_fname); g_free(fname); }
Modified: trunk/tagmanager/include/tm_workspace.h =================================================================== --- trunk/tagmanager/include/tm_workspace.h 2007-04-27 10:58:41 UTC (rev 1479) +++ trunk/tagmanager/include/tm_workspace.h 2007-04-27 11:00:29 UTC (rev 1480) @@ -100,10 +100,11 @@ \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); + , int includes_count, const char *tags_file, int lang);
/*! Recreates the tag array of the workspace by collecting the tags of all member work objects. You shouldn't have to call this directly since
Modified: trunk/tagmanager/tm_workspace.c =================================================================== --- trunk/tagmanager/tm_workspace.c 2007-04-27 10:58:41 UTC (rev 1479) +++ trunk/tagmanager/tm_workspace.c 2007-04-27 11:00:29 UTC (rev 1480) @@ -187,8 +187,68 @@ *pp_list = g_list_prepend(*pp_list, value); }
+static void write_includes_file(FILE *fp, GList *includes_files) +{ + GList *node; + + node = includes_files; + while (node) + { + char *str = g_strdup_printf("#include "%s"\n", (char*)node->data); + int str_len = strlen(str); + + fwrite(str, str_len, 1, fp); + free(str); + node = g_list_next (node); + } +} + + +static void append_to_temp_file(FILE *fp, GList *file_list) +{ + GList *node; + + node = file_list; + while (node) + { + const char *fname = node->data; + char *contents; + size_t length; + GError *err = NULL; + + if (! g_file_get_contents(fname, &contents, &length, &err)) + { + fprintf(stderr, "Unable to read file: %s\n", err->message); + g_error_free(err); + } + else + { + fwrite(contents, length, 1, fp); + fwrite("\n", 1, 1, fp); // in case file doesn't end in newline (e.g. windows). + g_free(contents); + } + node = g_list_next (node); + } +} + +static gint get_global_tag_type_mask(gint lang) +{ + switch (lang) + { + case 0: + case 1: + // C/C++ + return tm_tag_class_t | tm_tag_typedef_t | tm_tag_enum_t | tm_tag_enumerator_t | + tm_tag_prototype_t | + tm_tag_function_t | tm_tag_method_t | // for inline functions + tm_tag_macro_t | tm_tag_macro_with_arg_t; + default: + return tm_tag_max_t; + } +} + gboolean tm_workspace_create_global_tags(const char *pre_process, const char **includes - , int includes_count, const char *tags_file) + , int includes_count, const char *tags_file, int lang) { #ifdef HAVE_GLOB_H glob_t globbuf; @@ -202,7 +262,6 @@ GPtrArray *tags_array; GHashTable *includes_files_hash; GList *includes_files = NULL; - GList *node; #ifdef G_OS_WIN32 char *temp_file = g_strdup_printf("%s_%d_%ld_1.cpp", P_tmpdir, getpid(), time(NULL)); char *temp_file2 = g_strdup_printf("%s_%d_%ld_2.cpp", P_tmpdir, getpid(), time(NULL)); @@ -259,6 +318,7 @@ } else #endif + // no glob support or globbing not wanted for(idx_inc = 0; idx_inc < includes_count; idx_inc++) { if (!g_hash_table_lookup(includes_files_hash, @@ -279,17 +339,11 @@ #ifdef TM_DEBUG g_message ("writing out files to %s\n", temp_file); #endif - node = includes_files; - while (node) - { - char *str = g_strdup_printf("#include "%s"\n", (char*)node->data); - int str_len = strlen(str); + if (pre_process != NULL) + write_includes_file(fp, includes_files); + else + append_to_temp_file(fp, includes_files);
- fwrite(str, str_len, 1, fp); - free(str); - node = g_list_next (node); - } - g_list_free (includes_files); g_hash_table_destroy(includes_files_hash); includes_files_hash = NULL; @@ -302,18 +356,26 @@ * following these lines are incorrectly parsed. The real fix should, * of course be in tagmanager (c) parser. This is just a temporary fix. */ - command = g_strdup_printf("%s %s | grep -v -E '^\s*(G_BEGIN_DECLS|G_END_DECLS)\s*$' > %s", + if (pre_process != NULL) + { + command = g_strdup_printf("%s %s | grep -v -E '^\s*(G_BEGIN_DECLS|G_END_DECLS)\s*$' > %s", pre_process, temp_file, temp_file2); - #ifdef TM_DEBUG - g_message("Executing: %s", command); + g_message("Executing: %s", command); #endif - - system(command); - g_free(command); - unlink(temp_file); - g_free(temp_file); - source_file = tm_source_file_new(temp_file2, TRUE, NULL); + system(command); + g_free(command); + unlink(temp_file); + g_free(temp_file); + } + else + { + // no pre-processing needed, so temp_file2 = temp_file + g_free(temp_file2); + temp_file2 = temp_file; + temp_file = NULL; + } + source_file = tm_source_file_new(temp_file2, TRUE, tm_source_file_get_lang_name(lang)); if (NULL == source_file) { unlink(temp_file2); @@ -326,10 +388,7 @@ tm_source_file_free(source_file); return FALSE; } - tags_array = tm_tags_extract(source_file->tags_array, tm_tag_class_t | - tm_tag_typedef_t | tm_tag_enum_t | tm_tag_enumerator_t | - tm_tag_prototype_t | tm_tag_function_t | tm_tag_method_t | // for inline functions - tm_tag_macro_t | tm_tag_macro_with_arg_t); + tags_array = tm_tags_extract(source_file->tags_array, get_global_tag_type_mask(lang)); if ((NULL == tags_array) || (0 == tags_array->len)) { if (tags_array)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.