30#include <glib/gstdio.h>
95 g_message(
"Workspace destroyed");
128 g_ptr_array_free(*big_array, TRUE);
129 *big_array = new_tags;
139 g_ptr_array_free(arr, TRUE);
144 gsize buf_size, gboolean use_buffer, gboolean update_workspace)
147 g_message(
"Source file updating based on source file %s", source_file->
file_name);
150 if (update_workspace)
159 if (update_workspace)
162 g_message(
"Updating workspace from source file");
170 g_message(
"Skipping workspace update because update_workspace is %s",
171 update_workspace?
"TRUE":
"FALSE");
183 g_return_if_fail(source_file !=
NULL);
192 g_return_if_fail(source_file !=
NULL);
227 g_return_if_fail(source_file !=
NULL);
253 g_message(
"Recreating workspace tags array");
265 g_message(
"Adding tags of %s", source_file->
file_name);
269 for (j = 0; j < source_file->
tags_array->len; ++j)
296 g_return_if_fail(source_files !=
NULL);
298 for (i = 0; i < source_files->len; i++)
321 g_return_if_fail(source_files !=
NULL);
324 for (i = 0; i < source_files->len; i++)
350 GPtrArray *file_tags, *new_tags;
362 g_ptr_array_free(file_tags, TRUE);
374 FILE *fp = g_fopen(outf,
"w");
375 GList *node = includes_files;
382 char *str = g_strdup_printf(
"#include \"%s\"\n", (
char*)node->data);
383 size_t str_len = strlen(str);
385 fwrite(str, str_len, 1, fp);
387 node = g_list_next(node);
390 return fclose(fp) == 0;
396 FILE *fp = g_fopen(outf,
"w");
397 GList *node = file_list;
404 const char *fname = node->data;
409 if (! g_file_get_contents(fname, &contents, &length, &err))
411 fprintf(stderr,
"Unable to read file: %s\n", err->message);
416 fwrite(contents, length, 1, fp);
417 fwrite(
"\n", 1, 1, fp);
420 node = g_list_next (node);
423 return fclose(fp) == 0;
432 fd = g_file_open_tmp(tpl, &
name,
NULL);
443 GList *includes_files =
NULL;
451 table = g_hash_table_new_full(g_str_hash, g_str_equal,
NULL,
NULL);
456 if (includes[0][0] ==
'"')
458 for (i = 0; i < includes_count; i++)
460 size_t dirty_len = strlen(includes[i]);
466 clean_path = g_malloc(dirty_len - 1);
468 strncpy(clean_path, includes[i] + 1, dirty_len - 1);
469 clean_path[dirty_len - 2] = 0;
472 g_message (
"[o][%s]\n", clean_path);
474 glob(clean_path, 0,
NULL, &globbuf);
477 g_message (
"matches: %d\n", globbuf.gl_pathc);
480 for (idx_glob = 0; idx_glob < globbuf.gl_pathc; idx_glob++)
483 g_message (
">>> %s\n", globbuf.gl_pathv[idx_glob]);
485 if (!g_hash_table_lookup(table, globbuf.gl_pathv[idx_glob]))
487 gchar *file_name_copy = g_strdup(globbuf.gl_pathv[idx_glob]);
489 includes_files = g_list_prepend(includes_files, file_name_copy);
490 g_hash_table_insert(table, file_name_copy, file_name_copy);
492 g_message (
"Added ...\n");
504 for (i = 0; i < includes_count; i++)
506 if (!g_hash_table_lookup(table, includes[i]))
508 gchar* file_name_copy = g_strdup(includes[i]);
510 includes_files = g_list_prepend(includes_files, file_name_copy);
511 g_hash_table_insert(table, file_name_copy, file_name_copy);
516 g_hash_table_destroy(table);
518 return g_list_reverse(includes_files);
526 gchar *errors =
NULL;
540 command = g_strdup_printf(
"%s %s >%s 2>%s",
541 cmd, inf, outf, tmp_errfile);
543 g_message(
"Executing: %s",
command);
548 g_file_get_contents(tmp_errfile, &errors,
NULL,
NULL);
549 if (errors && *errors)
550 g_printerr(
"%s\n", errors);
552 g_unlink(tmp_errfile);
577 int includes_count,
const char *tags_file,
TMParserType lang)
579 gboolean ret = FALSE;
581 GList *includes_files;
590 g_message (
"writing out files to %s\n", temp_file);
597 g_list_free_full(includes_files, g_free);
610 temp_file = temp_file2;
643 if (!src || !dst || !
name || !*
name)
647 for (i = 0; i < num; ++i)
649 if ((type & (*tag)->type) &&
651 (!
scope || g_strcmp0((*tag)->scope,
scope) == 0))
653 g_ptr_array_add(dst, *tag);
672 GPtrArray *tags = g_ptr_array_new();
690 if (!src || !dst || !
name || !*
name)
695 for (i = 0; i <
count && num < max_num; ++i)
699 (!last || g_strcmp0(last->
name, (*tag)->name) != 0))
701 g_ptr_array_add(dst, *tag);
721 GPtrArray *tags = g_ptr_array_new();
727 if (tags->len > max_num)
745 GPtrArray *tags = g_ptr_array_new();
757 for (i = 0; i < all->len; ++i)
761 if (tag && (tag->
type & member_types) &&
767 g_ptr_array_add (tags, tag);
775 g_ptr_array_free(tags, TRUE);
785 if (scoped_name !=
NULL)
789 const gchar *base = g_strrstr(scoped_name, sep);
790 gchar *
name = base ? g_strdup(base + strlen(sep)) : g_strdup(scoped_name);
793 g_strdelimit(
name,
"*^",
' ');
807 GPtrArray *res =
NULL;
813 type_name = g_strdup(
name);
820 for (i = 0; i < 5; i++)
823 GPtrArray *type_tags;
828 types &= ~tm_tag_enum_t;
830 type_tags = g_ptr_array_new();
833 for (j = 0; j < type_tags->len; j++)
849 g_ptr_array_free(type_tags, TRUE);
885 gboolean ret = FALSE;
890 comps = g_strsplit (method_scope, sep, 0);
891 len = g_strv_length(comps);
894 gchar *method, *member_scope, *cls, *cls_scope;
897 method = comps[len - 1];
898 comps[len - 1] =
NULL;
899 member_scope = g_strjoinv(sep, comps);
900 comps[len - 1] = method;
903 cls = comps[len - 2];
904 comps[len - 2] =
NULL;
905 cls_scope = g_strjoinv(sep, comps);
906 comps[len - 2] = cls;
907 cls_scope = strlen(cls_scope) > 0 ? cls_scope :
NULL;
910 if (g_strcmp0(member_tag->
scope, member_scope) == 0)
913 GPtrArray *cls_tags = g_ptr_array_new();
917 ret = cls_tags->len > 0;
918 g_ptr_array_free(cls_tags, TRUE);
922 g_free(member_scope);
933 gboolean member,
const gchar *current_scope)
935 GPtrArray *member_tags =
NULL;
940 for (i = 0; i < tags->len && !member_tags; i++)
946 if (tag->
type & types)
961 if (!(tag->
type & member_types) || member ||
978 GPtrArray *member_tags =
NULL;
981 for (i = 0; i < tags->len && !member_tags; i++)
1003 gboolean function, gboolean member,
const gchar *current_scope, gboolean search_namespace)
1006 GPtrArray *tags, *member_tags =
NULL;
1013 if (search_namespace)
1021 g_ptr_array_free(tags, TRUE);
1027 tag_type = function_types;
1037 lang, member, current_scope);
1040 member, current_scope);
1043 member, current_scope);
1045 g_ptr_array_free(tags, TRUE);
1058void tm_workspace_dump(
void)
1063 g_message(
"Dumping TagManager workspace tree..");
1068 fprintf(stderr,
"%s", source_file->
file_name);
1079static const GPtrArray *tm_workspace_get_parents(
const gchar *
name)
1082 static GPtrArray *parents =
NULL;
1083 const GPtrArray *matches;
1092 if (
NULL == parents)
1093 parents = g_ptr_array_new();
1095 g_ptr_array_set_size(parents, 0);
1097 if ((
NULL == matches) || (0 == matches->len))
1099 g_ptr_array_add(parents, matches->pdata[0]);
1100 while (i < parents->len)
1102 tag =
TM_TAG(parents->pdata[i]);
1106 for (klass = klasses; (
NULL != *klass); ++ klass)
1108 for (j=0; j < parents->len; ++j)
1110 if (0 == strcmp(*klass,
TM_TAG(parents->pdata[j])->name))
1113 if (parents->len == j)
1116 if ((
NULL != matches) && (0 < matches->len))
1117 g_ptr_array_add(parents, matches->pdata[0]);
1120 g_strfreev(klasses);
The TMSourceFile structure represents the source file and its tags in the tag manager.
GPtrArray * tags_array
Sorted tag array obtained by parsing the object.
char * file_name
Full file name (inc.
The TMTag structure represents a single tag in the tag manager.
char * scope
Scope of tag.
char * inheritance
Parent classes.
char * var_type
Variable type (maps to struct for typedefs)
TMSourceFile * file
These are tag attributes.
The Tag Manager Workspace.
GPtrArray * global_typename_array
GPtrArray * typename_array
GPtrArray * global_tags
Global tags loaded at startup.
GPtrArray * source_files
An array of TMSourceFile pointers.
GPtrArray * tags_array
Sorted tags from all source files (just pointers to source file tags, the tag objects are owned by th...
const gchar * tm_parser_context_separator(TMParserType lang)
gboolean tm_parser_langs_compatible(TMParserType lang, TMParserType other)
void tm_parser_verify_type_mappings(void)
@ tm_tag_function_t
Function definition.
@ tm_tag_package_t
Package (Java only)
@ tm_tag_interface_t
Interface (Java only)
@ tm_tag_field_t
Field (Java only)
@ tm_tag_class_t
Class declaration.
@ tm_tag_enumerator_t
Enumerator value.
@ tm_tag_max_t
Maximum value of TMTagType.
@ tm_tag_member_t
Member variable of class/struct.
@ tm_tag_method_t
Class method (Java only)
@ tm_tag_struct_t
Struct declaration.
@ tm_tag_macro_with_arg_t
Parameterized macro.
@ tm_tag_namespace_t
Namespace declaration.
@ tm_tag_prototype_t
Function prototype.
@ tm_tag_typedef_t
Typedef.
@ tm_tag_enum_t
Enum declaration.
void tm_source_file_free(TMSourceFile *source_file)
Decrements the reference count of source_file.
GPtrArray * tm_source_file_read_tags_file(const gchar *tags_file, TMParserType mode)
TMSourceFile * tm_source_file_new(const char *file_name, const char *name)
Initializes a TMSourceFile structure and returns a pointer to it.
gboolean tm_source_file_write_tags_file(const gchar *tags_file, GPtrArray *tags_array)
gboolean tm_source_file_parse(TMSourceFile *source_file, guchar *text_buf, gsize buf_size, gboolean use_buffer)
const gchar * tm_source_file_get_lang_name(TMParserType lang)
GPtrArray * tm_tags_merge(GPtrArray *big_array, GPtrArray *small_array, TMTagAttrType *sort_attributes, gboolean unref_duplicates)
GPtrArray * tm_tags_extract(GPtrArray *tags_array, TMTagType tag_types)
void tm_tags_array_free(GPtrArray *tags_array, gboolean free_all)
void tm_tags_remove_file_tags(TMSourceFile *source_file, GPtrArray *tags_array)
TMTag ** tm_tags_find(const GPtrArray *tags_array, const char *name, gboolean partial, guint *tagCount)
gboolean tm_tag_is_anon(const TMTag *tag)
void tm_tags_sort(GPtrArray *tags_array, TMTagAttrType *sort_attributes, gboolean dedup, gboolean unref_duplicates)
void tm_tags_dedup(GPtrArray *tags_array, TMTagAttrType *sort_attributes, gboolean unref_duplicates)
#define TM_TAG(tag)
Use the TM_TAG() macro to cast a pointer to (TMTag *)
TMTagAttrType
Tag Attributes.
@ tm_tag_attr_none_t
Undefined.
@ tm_tag_attr_name_t
Tag Name.
@ tm_tag_attr_file_t
File in which tag exists.
@ tm_tag_attr_scope_t
Scope of the tag.
@ tm_tag_attr_arglist_t
Argument list.
@ tm_tag_attr_line_t
Line number of tag.
@ tm_tag_attr_type_t
Tag Type.
static TMWorkspace * theWorkspace
GPtrArray * tm_workspace_find(const char *name, const char *scope, TMTagType type, TMTagAttrType *attrs, TMParserType lang)
void tm_workspace_remove_source_files(GPtrArray *source_files)
Removes multiple source files from the workspace and updates the workspace tag arrays.
static void fill_find_tags_array(GPtrArray *dst, const GPtrArray *src, const char *name, const char *scope, TMTagType type, TMParserType lang)
static TMTagAttrType file_tags_sort_attrs[]
GPtrArray * tm_workspace_find_prefix(const char *prefix, TMParserType lang, guint max_num)
static TMTagAttrType workspace_tags_sort_attrs[]
static GList * lookup_includes(const gchar **includes, gint includes_count)
void tm_workspace_add_source_files(GPtrArray *source_files)
Adds multiple source files to the workspace and updates the workspace tag arrays.
static void tm_workspace_merge_tags(GPtrArray **big_array, GPtrArray *small_array)
static void fill_find_tags_array_prefix(GPtrArray *dst, const GPtrArray *src, const char *name, TMParserType lang, guint max_num)
static gboolean write_includes_file(const gchar *outf, GList *includes_files)
static GPtrArray * find_namespace_members_all(const GPtrArray *tags, const GPtrArray *searched_array, TMParserType lang)
static GPtrArray * find_scope_members(const GPtrArray *tags_array, const gchar *name, TMSourceFile *file, TMParserType lang, gboolean namespace)
static TMTagType TM_GLOBAL_TYPE_MASK
static TMTagAttrType global_tags_sort_attrs[]
static void merge_extracted_tags(GPtrArray **dest, GPtrArray *src, TMTagType tag_types)
static GPtrArray * find_scope_members_all(const GPtrArray *tags, const GPtrArray *searched_array, TMParserType lang, gboolean member, const gchar *current_scope)
void tm_workspace_add_source_file_noupdate(TMSourceFile *source_file)
static TMTagType TM_TYPE_WITH_MEMBERS
static void tm_workspace_update(void)
static gboolean combine_include_files(const gchar *outf, GList *file_list)
static gboolean member_at_method_scope(const GPtrArray *tags, const gchar *method_scope, TMTag *member_tag, TMParserType lang)
void tm_workspace_remove_source_file(TMSourceFile *source_file)
Removes a source file from the workspace if it exists.
static void update_source_file(TMSourceFile *source_file, guchar *text_buf, gsize buf_size, gboolean use_buffer, gboolean update_workspace)
void tm_workspace_add_source_file(TMSourceFile *source_file)
Adds a source file to the workspace, parses it and updates the workspace tags.
GPtrArray * tm_workspace_find_scope_members(TMSourceFile *source_file, const char *name, gboolean function, gboolean member, const gchar *current_scope, gboolean search_namespace)
gboolean tm_workspace_load_global_tags(const char *tags_file, TMParserType mode)
static GPtrArray * find_scope_members_tags(const GPtrArray *all, TMTag *type_tag, gboolean namespace)
static gboolean tm_create_workspace(void)
static gchar * strip_type(const gchar *scoped_name, TMParserType lang)
static gchar * pre_process_file(const gchar *cmd, const gchar *inf)
gboolean tm_workspace_create_global_tags(const char *pre_process, const char **includes, int includes_count, const char *tags_file, TMParserType lang)
void tm_workspace_free(void)
const TMWorkspace * tm_get_workspace(void)
static gchar * create_temp_file(const gchar *tpl)
void tm_workspace_update_source_file_buffer(TMSourceFile *source_file, guchar *text_buf, gsize buf_size)
The TMWorkspace structure is meant to be used as a singleton to store application wide tag informatio...