3
* Copyright (c) 2001-2002, Biswapesh Chattopadhyay
5
* This source code is released for free distribution under the terms of the
6
* GNU General Public License.
11
* @file tm_workspace.h
12
The TMWorkspace structure is meant to be used as a singleton to store application
15
The workspace is intended to contain a list of global tags
16
and a set of work objects (projects or individual files). You need not use the
17
workspace, though, to use tag manager, unless you need things like global tags
18
and a place to store all current open projects and individual files. TMWorkspace
19
is derived from TMWorkObject.
28
#include <sys/types.h>
34
#include <glib/gstdio.h>
37
#include "tm_workspace.h"
38
#include "tm_project.h"
41
static TMWorkspace *theWorkspace = NULL;
42
guint workspace_class_id = 0;
44
static gboolean tm_create_workspace(void)
46
workspace_class_id = tm_work_object_register(tm_workspace_free, tm_workspace_update
47
, tm_workspace_find_object);
48
theWorkspace = g_new(TMWorkspace, 1);
49
if (FALSE == tm_work_object_init(TM_WORK_OBJECT(theWorkspace),
50
workspace_class_id, NULL, TRUE))
54
g_warning("Failed to initialize workspace");
58
theWorkspace->global_tags = NULL;
59
theWorkspace->work_objects = NULL;
63
void tm_workspace_free(gpointer workspace)
67
if (workspace != theWorkspace)
71
g_message("Workspace destroyed");
76
if (theWorkspace->work_objects)
78
for (i=0; i < theWorkspace->work_objects->len; ++i)
79
tm_work_object_free(theWorkspace->work_objects->pdata[i]);
80
g_ptr_array_free(theWorkspace->work_objects, TRUE);
82
if (theWorkspace->global_tags)
84
for (i=0; i < theWorkspace->global_tags->len; ++i)
85
tm_tag_unref(theWorkspace->global_tags->pdata[i]);
86
g_ptr_array_free(theWorkspace->global_tags, TRUE);
88
tm_work_object_destroy(TM_WORK_OBJECT(theWorkspace));
94
const TMWorkspace *tm_get_workspace()
96
if (NULL == theWorkspace)
97
tm_create_workspace();
101
gboolean tm_workspace_add_object(TMWorkObject *work_object)
103
/* theWorkspace should already have been created otherwise something went wrong */
104
if (NULL == theWorkspace)
106
if (NULL == theWorkspace->work_objects)
107
theWorkspace->work_objects = g_ptr_array_new();
108
g_ptr_array_add(theWorkspace->work_objects, work_object);
109
work_object->parent = TM_WORK_OBJECT(theWorkspace);
113
gboolean tm_workspace_remove_object(TMWorkObject *w, gboolean do_free, gboolean update)
116
if ((NULL == theWorkspace) || (NULL == theWorkspace->work_objects)
121
for (i=0; i < theWorkspace->work_objects->len; ++i)
123
if (theWorkspace->work_objects->pdata[i] == w)
126
tm_work_object_free(w);
127
g_ptr_array_remove_index_fast(theWorkspace->work_objects, i);
129
tm_workspace_update(TM_WORK_OBJECT(theWorkspace), TRUE, FALSE, FALSE);
137
static TMTagAttrType global_tags_sort_attrs[] =
139
tm_tag_attr_name_t, tm_tag_attr_scope_t,
140
tm_tag_attr_type_t, tm_tag_attr_arglist_t, 0
143
gboolean tm_workspace_load_global_tags(const char *tags_file, gint mode)
149
gboolean format_pipe = FALSE;
151
if (NULL == theWorkspace)
153
if (NULL == (fp = g_fopen(tags_file, "r")))
155
if (NULL == theWorkspace->global_tags)
156
theWorkspace->global_tags = g_ptr_array_new();
157
orig_len = theWorkspace->global_tags->len;
158
if ((NULL == fgets((gchar*) buf, BUFSIZ, fp)) || ('\0' == *buf))
161
return FALSE; /* early out on error */
164
{ /* We read the first line for the format specification. */
165
if (buf[0] == '#' && strstr((gchar*) buf, "format=pipe") != NULL)
167
else if (buf[0] == '#' && strstr((gchar*) buf, "format=tagmanager") != NULL)
170
{ /* We didn't find a valid format specification, so we try to auto-detect the format
171
* by counting the pipe characters on the first line and asumme pipe format when
172
* we find more than one pipe on the line. */
173
guint i, pipe_cnt = 0;
174
for (i = 0; i < BUFSIZ && buf[i] != '\0' && pipe_cnt < 2; i++)
179
format_pipe = (pipe_cnt > 1);
181
rewind(fp); /* reset the file pointer, to start reading again from the beginning */
183
while (NULL != (tag = tm_tag_new_from_file(NULL, fp, mode, format_pipe)))
184
g_ptr_array_add(theWorkspace->global_tags, tag);
187
/* reorder the whole array, because tm_tags_find expects a sorted array */
188
tm_tags_merge(theWorkspace->global_tags, orig_len, global_tags_sort_attrs, TRUE);
192
static guint tm_file_inode_hash(gconstpointer key)
194
struct stat file_stat;
195
const char *filename = (const char*)key;
196
if (g_stat(filename, &file_stat) == 0)
199
g_message ("Hash for '%s' is '%d'\n", filename, file_stat.st_ino);
201
return g_direct_hash (GUINT_TO_POINTER (file_stat.st_ino));
207
static void tm_move_entries_to_g_list(gpointer key, gpointer value, gpointer user_data)
209
GList **pp_list = (GList**)user_data;
211
if (user_data == NULL)
214
*pp_list = g_list_prepend(*pp_list, value);
217
static void write_includes_file(FILE *fp, GList *includes_files)
221
node = includes_files;
224
char *str = g_strdup_printf("#include \"%s\"\n", (char*)node->data);
225
int str_len = strlen(str);
227
fwrite(str, str_len, 1, fp);
229
node = g_list_next(node);
234
static void append_to_temp_file(FILE *fp, GList *file_list)
241
const char *fname = node->data;
246
if (! g_file_get_contents(fname, &contents, &length, &err))
248
fprintf(stderr, "Unable to read file: %s\n", err->message);
253
fwrite(contents, length, 1, fp);
254
fwrite("\n", 1, 1, fp); /* in case file doesn't end in newline (e.g. windows). */
257
node = g_list_next (node);
261
static gchar *create_temp_file(const gchar *tpl)
266
fd = g_file_open_tmp(tpl, &name, NULL);
275
gboolean tm_workspace_create_global_tags(const char *pre_process, const char **includes,
276
int includes_count, const char *tags_file, int lang)
286
TMWorkObject *source_file;
287
GPtrArray *tags_array;
288
GHashTable *includes_files_hash;
289
GList *includes_files = NULL;
290
gchar *temp_file = create_temp_file("tmp_XXXXXX.cpp");
291
gchar *temp_file2 = create_temp_file("tmp_XXXXXX.cpp");
293
if (NULL == temp_file || NULL == temp_file2 ||
294
NULL == theWorkspace || NULL == (fp = g_fopen(temp_file, "w")))
301
includes_files_hash = g_hash_table_new_full (tm_file_inode_hash,
308
if (includes[0][0] == '"') /* leading \" char for glob matching */
309
for(idx_inc = 0; idx_inc < includes_count; idx_inc++)
311
int dirty_len = strlen(includes[idx_inc]);
312
char *clean_path = g_malloc(dirty_len - 1);
314
strncpy(clean_path, includes[idx_inc] + 1, dirty_len - 1);
315
clean_path[dirty_len - 2] = 0;
318
g_message ("[o][%s]\n", clean_path);
320
glob(clean_path, 0, NULL, &globbuf);
323
g_message ("matches: %d\n", globbuf.gl_pathc);
326
for(idx_glob = 0; idx_glob < globbuf.gl_pathc; idx_glob++)
329
g_message (">>> %s\n", globbuf.gl_pathv[idx_glob]);
331
if (!g_hash_table_lookup(includes_files_hash,
332
globbuf.gl_pathv[idx_glob]))
334
char* file_name_copy = strdup(globbuf.gl_pathv[idx_glob]);
335
g_hash_table_insert(includes_files_hash, file_name_copy,
338
g_message ("Added ...\n");
347
/* no glob support or globbing not wanted */
348
for(idx_inc = 0; idx_inc < includes_count; idx_inc++)
350
if (!g_hash_table_lookup(includes_files_hash,
353
char* file_name_copy = strdup(includes[idx_inc]);
354
g_hash_table_insert(includes_files_hash, file_name_copy,
359
/* Checks for duplicate file entries which would case trouble */
360
g_hash_table_foreach(includes_files_hash, tm_move_entries_to_g_list,
363
includes_files = g_list_reverse (includes_files);
366
g_message ("writing out files to %s\n", temp_file);
368
if (pre_process != NULL)
369
write_includes_file(fp, includes_files);
371
append_to_temp_file(fp, includes_files);
373
g_list_free (includes_files);
374
g_hash_table_destroy(includes_files_hash);
375
includes_files_hash = NULL;
376
includes_files = NULL;
379
if (pre_process != NULL)
382
gchar *tmp_errfile = create_temp_file("tmp_XXXXXX");
383
gchar *errors = NULL;
384
command = g_strdup_printf("%s %s >%s 2>%s",
385
pre_process, temp_file, temp_file2, tmp_errfile);
387
g_message("Executing: %s", command);
389
ret = system(command);
393
g_file_get_contents(tmp_errfile, &errors, NULL, NULL);
394
if (errors && *errors)
395
g_printerr("%s", errors);
397
g_unlink(tmp_errfile);
401
g_unlink(temp_file2);
407
/* no pre-processing needed, so temp_file2 = temp_file */
408
g_unlink(temp_file2);
410
temp_file2 = temp_file;
413
source_file = tm_source_file_new(temp_file2, TRUE, tm_source_file_get_lang_name(lang));
414
if (NULL == source_file)
416
g_unlink(temp_file2);
419
g_unlink(temp_file2);
421
if ((NULL == source_file->tags_array) || (0 == source_file->tags_array->len))
423
tm_source_file_free(source_file);
426
tags_array = tm_tags_extract(source_file->tags_array, tm_tag_max_t);
427
if ((NULL == tags_array) || (0 == tags_array->len))
430
g_ptr_array_free(tags_array, TRUE);
431
tm_source_file_free(source_file);
434
if (FALSE == tm_tags_sort(tags_array, global_tags_sort_attrs, TRUE))
436
tm_source_file_free(source_file);
439
if (NULL == (fp = g_fopen(tags_file, "w")))
441
tm_source_file_free(source_file);
444
fprintf(fp, "# format=tagmanager\n");
445
for (i = 0; i < tags_array->len; ++i)
447
tm_tag_write(TM_TAG(tags_array->pdata[i]), fp, tm_tag_attr_type_t
448
| tm_tag_attr_scope_t | tm_tag_attr_arglist_t | tm_tag_attr_vartype_t
449
| tm_tag_attr_pointer_t);
452
tm_source_file_free(source_file);
453
g_ptr_array_free(tags_array, TRUE);
457
TMWorkObject *tm_workspace_find_object(TMWorkObject *work_object, const char *file_name
458
, gboolean name_only)
460
TMWorkObject *w = NULL;
463
if (work_object != TM_WORK_OBJECT(theWorkspace))
465
if ((NULL == theWorkspace) || (NULL == theWorkspace->work_objects)
466
|| (0 == theWorkspace->work_objects->len))
468
for (i = 0; i < theWorkspace->work_objects->len; ++i)
470
if (NULL != (w = tm_work_object_find(TM_WORK_OBJECT(theWorkspace->work_objects->pdata[i])
471
, file_name, name_only)))
477
void tm_workspace_recreate_tags_array(void)
481
TMTagAttrType sort_attrs[] = { tm_tag_attr_name_t, tm_tag_attr_file_t
482
, tm_tag_attr_scope_t, tm_tag_attr_type_t, tm_tag_attr_arglist_t, 0};
485
g_message("Recreating workspace tags array");
488
if ((NULL == theWorkspace) || (NULL == theWorkspace->work_objects))
490
if (NULL != theWorkspace->work_object.tags_array)
491
g_ptr_array_set_size(theWorkspace->work_object.tags_array, 0);
493
theWorkspace->work_object.tags_array = g_ptr_array_new();
496
g_message("Total %d objects", theWorkspace->work_objects->len);
498
for (i=0; i < theWorkspace->work_objects->len; ++i)
500
w = TM_WORK_OBJECT(theWorkspace->work_objects->pdata[i]);
502
g_message("Adding tags of %s", w->file_name);
504
if ((NULL != w) && (NULL != w->tags_array) && (w->tags_array->len > 0))
506
for (j = 0; j < w->tags_array->len; ++j)
508
g_ptr_array_add(theWorkspace->work_object.tags_array,
509
w->tags_array->pdata[j]);
514
g_message("Total: %d tags", theWorkspace->work_object.tags_array->len);
516
tm_tags_sort(theWorkspace->work_object.tags_array, sort_attrs, TRUE);
519
gboolean tm_workspace_update(TMWorkObject *workspace, gboolean force
520
, gboolean recurse, gboolean __unused__ update_parent)
523
gboolean update_tags = force;
526
g_message("Updating workspace");
529
if (workspace != TM_WORK_OBJECT(theWorkspace))
531
if (NULL == theWorkspace)
533
if ((recurse) && (theWorkspace->work_objects))
535
for (i=0; i < theWorkspace->work_objects->len; ++i)
537
if (TRUE == tm_work_object_update(TM_WORK_OBJECT(
538
theWorkspace->work_objects->pdata[i]), FALSE, TRUE, FALSE))
543
tm_workspace_recreate_tags_array();
544
/* workspace->analyze_time = time(NULL); */
548
void tm_workspace_dump(void)
553
g_message("Dumping TagManager workspace tree..");
555
tm_work_object_dump(TM_WORK_OBJECT(theWorkspace));
556
if (theWorkspace->work_objects)
559
for (i=0; i < theWorkspace->work_objects->len; ++i)
561
if (IS_TM_PROJECT(TM_WORK_OBJECT(theWorkspace->work_objects->pdata[i])))
562
tm_project_dump(TM_PROJECT(theWorkspace->work_objects->pdata[i]));
564
tm_work_object_dump(TM_WORK_OBJECT(theWorkspace->work_objects->pdata[i]));
570
const GPtrArray *tm_workspace_find(const char *name, int type, TMTagAttrType *attrs
571
, gboolean partial, langType lang)
573
static GPtrArray *tags = NULL;
575
int len, tagCount[2]={0,0}, tagIter;
578
if ((!theWorkspace) || (!name))
584
g_ptr_array_set_size(tags, 0);
586
tags = g_ptr_array_new();
588
matches[0] = tm_tags_find(theWorkspace->work_object.tags_array, name, partial, &tagCount[0]);
589
matches[1] = tm_tags_find(theWorkspace->global_tags, name, partial, &tagCount[1]);
592
if (matches[0] && *matches[0])
594
/* tag->atts.file.lang contains the line of the tag and
595
* tags->atts.entry.file->lang contains the language */
596
tags_lang = (*matches[0])->atts.entry.file->lang;
598
for (tagIter=0;tagIter<tagCount[0];++tagIter)
600
if ((type & (*matches[0])->type) && (lang == -1 || tags_lang == lang))
601
g_ptr_array_add(tags, *matches[0]);
604
if (0 != strncmp((*matches[0])->name, name, len))
609
if (0 != strcmp((*matches[0])->name, name))
617
if (matches[1] && *matches[1])
619
int tags_lang_alt = 0;
620
/* tag->atts.file.lang contains the language and
621
* tags->atts.entry.file is NULL */
622
tags_lang = (*matches[1])->atts.file.lang;
623
/* tags_lang_alt is used to load C global tags only once for C and C++
624
* lang = 1 is C++, lang = 0 is C
625
* if we have lang 0, than accept also lang 1 for C++ */
626
if (tags_lang == 0) /* C or C++ */
629
tags_lang_alt = tags_lang; /* otherwise just ignore it */
631
for (tagIter=0;tagIter<tagCount[1];++tagIter)
633
if ((type & (*matches[1])->type) && (lang == -1 ||
634
tags_lang == lang || tags_lang_alt == lang))
635
g_ptr_array_add(tags, *matches[1]);
639
if (0 != strncmp((*matches[1])->name, name, len))
644
if (0 != strcmp((*matches[1])->name, name))
652
tm_tags_sort(tags, attrs, TRUE);
656
static gboolean match_langs(gint lang, const TMTag *tag)
658
if (tag->atts.entry.file)
659
{ /* workspace tag */
660
if (lang == tag->atts.entry.file->lang)
665
if (lang == tag->atts.file.lang)
671
/* scope can be NULL.
674
fill_find_tags_array (GPtrArray *dst, const GPtrArray *src,
675
const char *name, const char *scope, int type, gboolean partial,
676
gint lang, gboolean first)
681
if ((!src) || (!dst) || (!name) || (!*name))
684
match = tm_tags_find (src, name, partial, &count);
685
if (count && match && *match)
687
for (tagIter = 0; tagIter < count; ++tagIter)
689
if (! scope || (match[tagIter]->atts.entry.scope &&
690
0 == strcmp(match[tagIter]->atts.entry.scope, scope)))
692
if (type & match[tagIter]->type)
693
if (lang == -1 || match_langs(lang, match[tagIter]))
695
g_ptr_array_add (dst, match[tagIter]);
706
/* adapted from tm_workspace_find, Anjuta 2.02 */
708
tm_workspace_find_scoped (const char *name, const char *scope, gint type,
709
TMTagAttrType *attrs, gboolean partial, langType lang, gboolean global_search)
711
static GPtrArray *tags = NULL;
717
g_ptr_array_set_size (tags, 0);
719
tags = g_ptr_array_new ();
721
fill_find_tags_array (tags, theWorkspace->work_object.tags_array,
722
name, scope, type, partial, lang, FALSE);
725
/* for a scoped tag, I think we always want the same language */
726
fill_find_tags_array (tags, theWorkspace->global_tags,
727
name, scope, type, partial, lang, FALSE);
730
tm_tags_sort (tags, attrs, TRUE);
736
tm_get_current_function (GPtrArray * file_tags, const gulong line)
738
GPtrArray *const local = tm_tags_extract (file_tags, tm_tag_function_t);
739
if (local && local->len)
742
TMTag *tag, *function_tag = NULL;
743
gulong function_line = 0;
746
for (i = 0; (i < local->len); ++i)
748
tag = TM_TAG (local->pdata[i]);
749
delta = line - tag->atts.entry.line;
750
if (delta >= 0 && (gulong)delta < line - function_line)
753
function_line = tag->atts.entry.line;
756
g_ptr_array_free (local, TRUE);
764
find_scope_members_tags (const GPtrArray * all, GPtrArray * tags,
765
const langType langJava, const char *name,
766
const char *filename, gboolean no_definitions)
768
GPtrArray *local = g_ptr_array_new ();
771
size_t len = strlen (name);
772
for (i = 0; (i < all->len); ++i)
774
tag = TM_TAG (all->pdata[i]);
775
if (no_definitions && filename && tag->atts.entry.file &&
776
0 != strcmp (filename,
777
tag->atts.entry.file->work_object.short_name))
781
if (tag && tag->atts.entry.scope && tag->atts.entry.scope[0] != '\0')
783
if (0 == strncmp (name, tag->atts.entry.scope, len))
785
g_ptr_array_add (local, tag);
794
char *s_backup = NULL;
795
char *var_type = NULL;
797
for (i = 0; (i < local->len); ++i)
799
tag = TM_TAG (local->pdata[i]);
800
scope = tag->atts.entry.scope;
801
if (scope && 0 == strcmp (name, scope))
803
g_ptr_array_add (tags, tag);
807
j = 0; /* someone could write better code :P */
812
backup = s_backup[0];
814
if (0 == strcmp (name, tag->atts.entry.scope))
817
s_backup[0] = backup;
821
if (tag->atts.entry.file
822
&& tag->atts.entry.file->lang == langJava)
824
scope = strrchr (tag->atts.entry.scope, '.');
826
var_type = scope + 1;
830
scope = strrchr (tag->atts.entry.scope, ':');
833
var_type = scope + 1;
839
s_backup[0] = backup;
845
backup = s_backup[0];
848
for (j = 0; (j < local->len); ++j)
852
tag2 = TM_TAG (local->pdata[j]);
853
if (tag2->atts.entry.var_type &&
854
0 == strcmp (var_type, tag2->atts.entry.var_type))
860
s_backup[0] = backup;
870
g_ptr_array_add (tags, tag);
874
g_ptr_array_free (local, TRUE);
875
return (int) tags->len;
881
find_namespace_members_tags (const GPtrArray * all, GPtrArray * tags,
882
const langType langJava, const char *name,
883
const char *filename)
885
GPtrArray *local = g_ptr_array_new ();
888
size_t len = strlen (name);
890
g_return_val_if_fail (all != NULL, 0);
892
for (i = 0; (i < all->len); ++i)
894
tag = TM_TAG (all->pdata[i]);
895
if (filename && tag->atts.entry.file &&
896
0 != strcmp (filename,
897
tag->atts.entry.file->work_object.short_name))
902
if (tag && tag->atts.entry.scope && tag->atts.entry.scope[0] != '\0')
904
if (0 == strncmp (name, tag->atts.entry.scope, len))
906
g_ptr_array_add (local, tag);
914
for (i = 0; (i < local->len); ++i)
916
tag = TM_TAG (local->pdata[i]);
917
scope = tag->atts.entry.scope;
919
/* if we wanna complete something like
921
* we'll just return the tags that have "namespace1"
922
* as their scope. So we won't return classes/members/namespaces
923
* under, for example, namespace2, where namespace1::namespace2
925
if (scope && 0 == strcmp (name, scope))
927
g_ptr_array_add (tags, tag);
932
g_ptr_array_free (local, TRUE);
933
return (int) tags->len;
937
tm_workspace_find_namespace_members (const GPtrArray * file_tags, const char *name,
938
gboolean search_global)
940
static GPtrArray *tags = NULL;
941
GPtrArray *local = NULL;
942
char *new_name = (char *) name;
943
char *filename = NULL;
944
int found = 0, del = 0;
945
static langType langJava = -1;
948
g_return_val_if_fail ((theWorkspace && name && name[0] != '\0'), NULL);
951
tags = g_ptr_array_new ();
955
const GPtrArray *tags2;
956
int got = 0, types = (tm_tag_class_t | tm_tag_namespace_t |
957
tm_tag_struct_t | tm_tag_typedef_t |
958
tm_tag_union_t | tm_tag_enum_t);
962
g_ptr_array_set_size (tags, 0);
963
got = fill_find_tags_array (tags, file_tags,
964
new_name, NULL, types, FALSE, -1, FALSE);
974
TMTagAttrType attrs[] = {
975
tm_tag_attr_name_t, tm_tag_attr_type_t,
978
tags2 = tm_workspace_find (new_name, types, attrs, FALSE, -1);
981
if ((tags2) && (tags2->len == 1) && (tag = TM_TAG (tags2->pdata[0])))
983
if (tag->type == tm_tag_typedef_t && tag->atts.entry.var_type
984
&& tag->atts.entry.var_type[0] != '\0')
986
new_name = tag->atts.entry.var_type;
989
filename = (tag->atts.entry.file ?
990
tag->atts.entry.file->work_object.short_name : NULL);
991
if (tag->atts.entry.scope && tag->atts.entry.scope[0] != '\0')
994
if (tag->atts.entry.file &&
995
tag->atts.entry.file->lang == langJava)
997
new_name = g_strdup_printf ("%s.%s",
998
tag->atts.entry.scope,
1003
new_name = g_strdup_printf ("%s::%s",
1004
tag->atts.entry.scope,
1016
g_ptr_array_set_size (tags, 0);
1018
if (tag && tag->atts.entry.file)
1020
local = tm_tags_extract (tag->atts.entry.file->work_object.tags_array,
1021
(tm_tag_function_t |
1022
tm_tag_field_t | tm_tag_enumerator_t |
1023
tm_tag_namespace_t | tm_tag_class_t ));
1027
local = tm_tags_extract (theWorkspace->work_object.tags_array,
1028
(tm_tag_function_t | tm_tag_prototype_t |
1030
tm_tag_field_t | tm_tag_enumerator_t |
1031
tm_tag_namespace_t | tm_tag_class_t ));
1036
found = find_namespace_members_tags (local, tags,
1037
langJava, new_name, filename);
1038
g_ptr_array_free (local, TRUE);
1042
if (!found && search_global)
1044
GPtrArray *global = tm_tags_extract (theWorkspace->global_tags,
1046
tm_tag_prototype_t |
1050
tm_tag_enumerator_t |
1051
tm_tag_namespace_t |
1056
find_namespace_members_tags (global, tags, langJava,
1057
new_name, filename);
1059
DEBUG_PRINT ("returning these");
1061
for (i=0; i < tags->len; i++) {
1064
cur_tag = (TMTag*)g_ptr_array_index (tags, i);
1065
tm_tag_print (cur_tag, stdout );
1068
g_ptr_array_free (global, TRUE);
1083
tm_workspace_find_scope_members (const GPtrArray * file_tags, const char *name,
1084
gboolean search_global, gboolean no_definitions)
1086
static GPtrArray *tags = NULL;
1087
GPtrArray *local = NULL;
1088
char *new_name = (char *) name;
1089
char *filename = NULL;
1090
int found = 0, del = 0;
1091
static langType langJava = -1;
1095
/* langJava = getNamedLanguage ("Java"); */
1097
g_return_val_if_fail ((theWorkspace && name && name[0] != '\0'), NULL);
1100
tags = g_ptr_array_new ();
1104
const GPtrArray *tags2;
1105
int got = 0, types = (tm_tag_class_t | tm_tag_namespace_t |
1106
tm_tag_struct_t | tm_tag_typedef_t |
1107
tm_tag_union_t | tm_tag_enum_t);
1111
g_ptr_array_set_size (tags, 0);
1112
got = fill_find_tags_array (tags, file_tags,
1113
new_name, NULL, types, FALSE, -1, FALSE);
1121
TMTagAttrType attrs[] = {
1122
tm_tag_attr_name_t, tm_tag_attr_type_t,
1125
tags2 = tm_workspace_find (new_name, types, attrs, FALSE, -1);
1128
if ((tags2) && (tags2->len == 1) && (tag = TM_TAG (tags2->pdata[0])))
1130
if (tag->type == tm_tag_typedef_t && tag->atts.entry.var_type
1131
&& tag->atts.entry.var_type[0] != '\0')
1134
tmp_name = tag->atts.entry.var_type;
1135
if (strcmp(tmp_name, new_name) == 0) {
1139
new_name = tmp_name;
1143
filename = (tag->atts.entry.file ?
1144
tag->atts.entry.file->work_object.short_name : NULL);
1145
if (tag->atts.entry.scope && tag->atts.entry.scope[0] != '\0')
1148
if (tag->atts.entry.file &&
1149
tag->atts.entry.file->lang == langJava)
1151
new_name = g_strdup_printf ("%s.%s",
1152
tag->atts.entry.scope,
1157
new_name = g_strdup_printf ("%s::%s",
1158
tag->atts.entry.scope,
1170
g_ptr_array_set_size (tags, 0);
1172
if (no_definitions && tag && tag->atts.entry.file)
1174
local = tm_tags_extract (tag->atts.entry.file->work_object.tags_array,
1175
(tm_tag_function_t | tm_tag_prototype_t |
1176
tm_tag_member_t | tm_tag_field_t |
1177
tm_tag_method_t | tm_tag_enumerator_t));
1181
local = tm_tags_extract (theWorkspace->work_object.tags_array,
1182
(tm_tag_function_t | tm_tag_prototype_t |
1183
tm_tag_member_t | tm_tag_field_t |
1184
tm_tag_method_t | tm_tag_enumerator_t));
1188
found = find_scope_members_tags (local, tags, langJava, new_name,
1189
filename, no_definitions);
1190
g_ptr_array_free (local, TRUE);
1192
if (!found && search_global)
1194
GPtrArray *global = tm_tags_extract (theWorkspace->global_tags,
1196
tm_tag_prototype_t |
1201
|tm_tag_struct_t | tm_tag_typedef_t |
1202
tm_tag_union_t | tm_tag_enum_t));
1205
find_scope_members_tags (global, tags, langJava, new_name,
1206
filename, no_definitions);
1207
g_ptr_array_free (global, TRUE);
1218
const GPtrArray *tm_workspace_get_parents(const gchar *name)
1220
static TMTagAttrType type[] = { tm_tag_attr_name_t, tm_tag_attr_none_t };
1221
static GPtrArray *parents = NULL;
1222
const GPtrArray *matches;
1229
g_return_val_if_fail(name && isalpha(*name),NULL);
1231
if (NULL == parents)
1232
parents = g_ptr_array_new();
1234
g_ptr_array_set_size(parents, 0);
1235
matches = tm_workspace_find(name, tm_tag_class_t, type, FALSE, -1);
1236
if ((NULL == matches) || (0 == matches->len))
1238
g_ptr_array_add(parents, matches->pdata[0]);
1239
while (i < parents->len)
1241
tag = TM_TAG(parents->pdata[i]);
1242
if ((NULL != tag->atts.entry.inheritance) && (isalpha(tag->atts.entry.inheritance[0])))
1244
klasses = g_strsplit(tag->atts.entry.inheritance, ",", 10);
1245
for (klass = klasses; (NULL != *klass); ++ klass)
1247
for (j=0; j < parents->len; ++j)
1249
if (0 == strcmp(*klass, TM_TAG(parents->pdata[j])->name))
1252
if (parents->len == j)
1254
matches = tm_workspace_find(*klass, tm_tag_class_t, type, FALSE, -1);
1255
if ((NULL != matches) && (0 < matches->len))
1256
g_ptr_array_add(parents, matches->pdata[0]);
1259
g_strfreev(klasses);