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_tag (GPtrArray
* file_tags
, const gulong line
, const guint tag_types
)
738 GPtrArray
*const local
= tm_tags_extract (file_tags
, tag_types
);
739 TMTag
*matching_tag
= NULL
;
740 if (local
&& local
->len
)
743 gulong matching_line
= 0;
746 for (i
= 0; (i
< local
->len
); ++i
)
748 TMTag
*tag
= TM_TAG (local
->pdata
[i
]);
749 delta
= line
- tag
->atts
.entry
.line
;
750 if (delta
>= 0 && (gulong
)delta
< line
- matching_line
)
753 matching_line
= tag
->atts
.entry
.line
;
758 g_ptr_array_free (local
, TRUE
);
764 tm_get_current_function (GPtrArray
* file_tags
, const gulong line
)
766 return tm_get_current_tag (file_tags
, line
, tm_tag_function_t
| tm_tag_method_t
);
771 find_scope_members_tags (const GPtrArray
* all
, GPtrArray
* tags
,
772 const langType langJava
, const char *name
,
773 const char *filename
, gboolean no_definitions
)
775 GPtrArray
*local
= g_ptr_array_new ();
778 size_t len
= strlen (name
);
779 for (i
= 0; (i
< all
->len
); ++i
)
781 tag
= TM_TAG (all
->pdata
[i
]);
782 if (no_definitions
&& filename
&& tag
->atts
.entry
.file
&&
783 0 != strcmp (filename
,
784 tag
->atts
.entry
.file
->work_object
.short_name
))
788 if (tag
&& tag
->atts
.entry
.scope
&& tag
->atts
.entry
.scope
[0] != '\0')
790 if (0 == strncmp (name
, tag
->atts
.entry
.scope
, len
))
792 g_ptr_array_add (local
, tag
);
801 char *s_backup
= NULL
;
802 char *var_type
= NULL
;
804 for (i
= 0; (i
< local
->len
); ++i
)
806 tag
= TM_TAG (local
->pdata
[i
]);
807 scope
= tag
->atts
.entry
.scope
;
808 if (scope
&& 0 == strcmp (name
, scope
))
810 g_ptr_array_add (tags
, tag
);
814 j
= 0; /* someone could write better code :P */
819 backup
= s_backup
[0];
821 if (0 == strcmp (name
, tag
->atts
.entry
.scope
))
824 s_backup
[0] = backup
;
828 if (tag
->atts
.entry
.file
829 && tag
->atts
.entry
.file
->lang
== langJava
)
831 scope
= strrchr (tag
->atts
.entry
.scope
, '.');
833 var_type
= scope
+ 1;
837 scope
= strrchr (tag
->atts
.entry
.scope
, ':');
840 var_type
= scope
+ 1;
846 s_backup
[0] = backup
;
852 backup
= s_backup
[0];
855 for (j
= 0; (j
< local
->len
); ++j
)
859 tag2
= TM_TAG (local
->pdata
[j
]);
860 if (tag2
->atts
.entry
.var_type
&&
861 0 == strcmp (var_type
, tag2
->atts
.entry
.var_type
))
867 s_backup
[0] = backup
;
877 g_ptr_array_add (tags
, tag
);
881 g_ptr_array_free (local
, TRUE
);
882 return (int) tags
->len
;
888 find_namespace_members_tags (const GPtrArray
* all
, GPtrArray
* tags
,
889 const langType langJava
, const char *name
,
890 const char *filename
)
892 GPtrArray
*local
= g_ptr_array_new ();
895 size_t len
= strlen (name
);
897 g_return_val_if_fail (all
!= NULL
, 0);
899 for (i
= 0; (i
< all
->len
); ++i
)
901 tag
= TM_TAG (all
->pdata
[i
]);
902 if (filename
&& tag
->atts
.entry
.file
&&
903 0 != strcmp (filename
,
904 tag
->atts
.entry
.file
->work_object
.short_name
))
909 if (tag
&& tag
->atts
.entry
.scope
&& tag
->atts
.entry
.scope
[0] != '\0')
911 if (0 == strncmp (name
, tag
->atts
.entry
.scope
, len
))
913 g_ptr_array_add (local
, tag
);
921 for (i
= 0; (i
< local
->len
); ++i
)
923 tag
= TM_TAG (local
->pdata
[i
]);
924 scope
= tag
->atts
.entry
.scope
;
926 /* if we wanna complete something like
928 * we'll just return the tags that have "namespace1"
929 * as their scope. So we won't return classes/members/namespaces
930 * under, for example, namespace2, where namespace1::namespace2
932 if (scope
&& 0 == strcmp (name
, scope
))
934 g_ptr_array_add (tags
, tag
);
939 g_ptr_array_free (local
, TRUE
);
940 return (int) tags
->len
;
944 tm_workspace_find_namespace_members (const GPtrArray
* file_tags
, const char *name
,
945 gboolean search_global
)
947 static GPtrArray
*tags
= NULL
;
948 GPtrArray
*local
= NULL
;
949 char *new_name
= (char *) name
;
950 char *filename
= NULL
;
951 int found
= 0, del
= 0;
952 static langType langJava
= -1;
955 g_return_val_if_fail ((theWorkspace
&& name
&& name
[0] != '\0'), NULL
);
958 tags
= g_ptr_array_new ();
962 const GPtrArray
*tags2
;
963 int got
= 0, types
= (tm_tag_class_t
| tm_tag_namespace_t
|
964 tm_tag_struct_t
| tm_tag_typedef_t
|
965 tm_tag_union_t
| tm_tag_enum_t
);
969 g_ptr_array_set_size (tags
, 0);
970 got
= fill_find_tags_array (tags
, file_tags
,
971 new_name
, NULL
, types
, FALSE
, -1, FALSE
);
981 TMTagAttrType attrs
[] = {
982 tm_tag_attr_name_t
, tm_tag_attr_type_t
,
985 tags2
= tm_workspace_find (new_name
, types
, attrs
, FALSE
, -1);
988 if ((tags2
) && (tags2
->len
== 1) && (tag
= TM_TAG (tags2
->pdata
[0])))
990 if (tag
->type
== tm_tag_typedef_t
&& tag
->atts
.entry
.var_type
991 && tag
->atts
.entry
.var_type
[0] != '\0')
993 new_name
= tag
->atts
.entry
.var_type
;
996 filename
= (tag
->atts
.entry
.file
?
997 tag
->atts
.entry
.file
->work_object
.short_name
: NULL
);
998 if (tag
->atts
.entry
.scope
&& tag
->atts
.entry
.scope
[0] != '\0')
1001 if (tag
->atts
.entry
.file
&&
1002 tag
->atts
.entry
.file
->lang
== langJava
)
1004 new_name
= g_strdup_printf ("%s.%s",
1005 tag
->atts
.entry
.scope
,
1010 new_name
= g_strdup_printf ("%s::%s",
1011 tag
->atts
.entry
.scope
,
1023 g_ptr_array_set_size (tags
, 0);
1025 if (tag
&& tag
->atts
.entry
.file
)
1027 local
= tm_tags_extract (tag
->atts
.entry
.file
->work_object
.tags_array
,
1028 (tm_tag_function_t
|
1029 tm_tag_field_t
| tm_tag_enumerator_t
|
1030 tm_tag_namespace_t
| tm_tag_class_t
));
1034 local
= tm_tags_extract (theWorkspace
->work_object
.tags_array
,
1035 (tm_tag_function_t
| tm_tag_prototype_t
|
1037 tm_tag_field_t
| tm_tag_enumerator_t
|
1038 tm_tag_namespace_t
| tm_tag_class_t
));
1043 found
= find_namespace_members_tags (local
, tags
,
1044 langJava
, new_name
, filename
);
1045 g_ptr_array_free (local
, TRUE
);
1049 if (!found
&& search_global
)
1051 GPtrArray
*global
= tm_tags_extract (theWorkspace
->global_tags
,
1053 tm_tag_prototype_t
|
1057 tm_tag_enumerator_t
|
1058 tm_tag_namespace_t
|
1063 find_namespace_members_tags (global
, tags
, langJava
,
1064 new_name
, filename
);
1066 DEBUG_PRINT ("returning these");
1068 for (i=0; i < tags->len; i++) {
1071 cur_tag = (TMTag*)g_ptr_array_index (tags, i);
1072 tm_tag_print (cur_tag, stdout );
1075 g_ptr_array_free (global, TRUE);
1090 tm_workspace_find_scope_members (const GPtrArray * file_tags, const char *name,
1091 gboolean search_global, gboolean no_definitions)
1093 static GPtrArray *tags = NULL;
1094 GPtrArray *local = NULL;
1095 char *new_name = (char *) name;
1096 char *filename = NULL;
1097 int found = 0, del = 0;
1098 static langType langJava = -1;
1102 /* langJava = getNamedLanguage ("Java"); */
1104 g_return_val_if_fail ((theWorkspace
&& name
&& name
[0] != '\0'), NULL
);
1107 tags
= g_ptr_array_new ();
1111 const GPtrArray
*tags2
;
1112 int got
= 0, types
= (tm_tag_class_t
| tm_tag_namespace_t
|
1113 tm_tag_struct_t
| tm_tag_typedef_t
|
1114 tm_tag_union_t
| tm_tag_enum_t
);
1118 g_ptr_array_set_size (tags
, 0);
1119 got
= fill_find_tags_array (tags
, file_tags
,
1120 new_name
, NULL
, types
, FALSE
, -1, FALSE
);
1128 TMTagAttrType attrs
[] = {
1129 tm_tag_attr_name_t
, tm_tag_attr_type_t
,
1132 tags2
= tm_workspace_find (new_name
, types
, attrs
, FALSE
, -1);
1135 if ((tags2
) && (tags2
->len
== 1) && (tag
= TM_TAG (tags2
->pdata
[0])))
1137 if (tag
->type
== tm_tag_typedef_t
&& tag
->atts
.entry
.var_type
1138 && tag
->atts
.entry
.var_type
[0] != '\0')
1141 tmp_name
= tag
->atts
.entry
.var_type
;
1142 if (strcmp(tmp_name
, new_name
) == 0) {
1146 new_name
= tmp_name
;
1150 filename
= (tag
->atts
.entry
.file
?
1151 tag
->atts
.entry
.file
->work_object
.short_name
: NULL
);
1152 if (tag
->atts
.entry
.scope
&& tag
->atts
.entry
.scope
[0] != '\0')
1155 if (tag
->atts
.entry
.file
&&
1156 tag
->atts
.entry
.file
->lang
== langJava
)
1158 new_name
= g_strdup_printf ("%s.%s",
1159 tag
->atts
.entry
.scope
,
1164 new_name
= g_strdup_printf ("%s::%s",
1165 tag
->atts
.entry
.scope
,
1177 g_ptr_array_set_size (tags
, 0);
1179 if (no_definitions
&& tag
&& tag
->atts
.entry
.file
)
1181 local
= tm_tags_extract (tag
->atts
.entry
.file
->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 local
= tm_tags_extract (theWorkspace
->work_object
.tags_array
,
1189 (tm_tag_function_t
| tm_tag_prototype_t
|
1190 tm_tag_member_t
| tm_tag_field_t
|
1191 tm_tag_method_t
| tm_tag_enumerator_t
));
1195 found
= find_scope_members_tags (local
, tags
, langJava
, new_name
,
1196 filename
, no_definitions
);
1197 g_ptr_array_free (local
, TRUE
);
1199 if (!found
&& search_global
)
1201 GPtrArray
*global
= tm_tags_extract (theWorkspace
->global_tags
,
1203 tm_tag_prototype_t
|
1208 |tm_tag_struct_t
| tm_tag_typedef_t
|
1209 tm_tag_union_t
| tm_tag_enum_t
));
1212 find_scope_members_tags (global
, tags
, langJava
, new_name
,
1213 filename
, no_definitions
);
1214 g_ptr_array_free (global
, TRUE
);
1225 const GPtrArray
*tm_workspace_get_parents(const gchar
*name
)
1227 static TMTagAttrType type
[] = { tm_tag_attr_name_t
, tm_tag_attr_none_t
};
1228 static GPtrArray
*parents
= NULL
;
1229 const GPtrArray
*matches
;
1236 g_return_val_if_fail(name
&& isalpha(*name
),NULL
);
1238 if (NULL
== parents
)
1239 parents
= g_ptr_array_new();
1241 g_ptr_array_set_size(parents
, 0);
1242 matches
= tm_workspace_find(name
, tm_tag_class_t
, type
, FALSE
, -1);
1243 if ((NULL
== matches
) || (0 == matches
->len
))
1245 g_ptr_array_add(parents
, matches
->pdata
[0]);
1246 while (i
< parents
->len
)
1248 tag
= TM_TAG(parents
->pdata
[i
]);
1249 if ((NULL
!= tag
->atts
.entry
.inheritance
) && (isalpha(tag
->atts
.entry
.inheritance
[0])))
1251 klasses
= g_strsplit(tag
->atts
.entry
.inheritance
, ",", 10);
1252 for (klass
= klasses
; (NULL
!= *klass
); ++ klass
)
1254 for (j
=0; j
< parents
->len
; ++j
)
1256 if (0 == strcmp(*klass
, TM_TAG(parents
->pdata
[j
])->name
))
1259 if (parents
->len
== j
)
1261 matches
= tm_workspace_find(*klass
, tm_tag_class_t
, type
, FALSE
, -1);
1262 if ((NULL
!= matches
) && (0 < matches
->len
))
1263 g_ptr_array_add(parents
, matches
->pdata
[0]);
1266 g_strfreev(klasses
);