Fix a Gtk warning when checking path input in the log viewer.
[anjuta-git-plugin.git] / tagmanager / tm_tag.c
bloba4efb099d32618556a602e4f64f25622c1381475
1 /*
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.
8 */
10 #include <stdlib.h>
11 #include <string.h>
13 #include "general.h"
14 #include "entry.h"
15 #include "parse.h"
16 #include "read.h"
17 #define LIBCTAGS_DEFINED
18 #include "tm_tag.h"
20 static GMemChunk *s_tag_mem_chunk = NULL;
22 #define TAG_NEW(T) {\
23 if (!s_tag_mem_chunk) \
24 s_tag_mem_chunk = g_mem_chunk_new("TMTag memChunk", sizeof(TMTag), 10000 \
25 , G_ALLOC_AND_FREE); \
26 (T) = g_chunk_new0(TMTag, s_tag_mem_chunk);}
28 #define TAG_FREE(T) g_mem_chunk_free(s_tag_mem_chunk, (T))
30 /* Note: To preserve binary compatibility, it is very important
31 that you only *append* to this list ! */
32 enum
34 TA_NAME = 200,
35 TA_LINE,
36 TA_LOCAL,
37 TA_POS, /* Obsolete */
38 TA_TYPE,
39 TA_ARGLIST,
40 TA_SCOPE,
41 TA_VARTYPE,
42 TA_INHERITS,
43 TA_TIME,
44 TA_ACCESS,
45 TA_IMPL,
46 TA_LANG,
47 TA_INACTIVE,
48 TA_POINTER
51 static guint *s_sort_attrs = NULL;
52 static gboolean s_partial = FALSE;
54 static const char *s_tag_type_names[] = {
55 "class", /* classes */
56 "enum", /* enumeration names */
57 "enumerator", /* enumerators (values inside an enumeration) */
58 "externvar", /* external variable declarations */
59 "field", /* fields */
60 "function", /* function definitions */
61 "interface", /* interfaces */
62 "macro", /* macro definitions */
63 "member", /* class, struct, and union members */
64 "method", /* methods */
65 "namespace", /* namespaces */
66 "package", /* packages */
67 "prototype", /* function prototypes */
68 "struct", /* structure names */
69 "typedef", /* typedefs */
70 "union", /* union names */
71 "variable", /* variable definitions */
72 "other" /* Other tag type (non C/C++/Java) */
75 static int s_tag_types[] = {
76 tm_tag_class_t,
77 tm_tag_enum_t,
78 tm_tag_enumerator_t,
79 tm_tag_externvar_t,
80 tm_tag_field_t,
81 tm_tag_function_t,
82 tm_tag_interface_t,
83 tm_tag_macro_t,
84 tm_tag_member_t,
85 tm_tag_method_t,
86 tm_tag_namespace_t,
87 tm_tag_package_t,
88 tm_tag_prototype_t,
89 tm_tag_struct_t,
90 tm_tag_typedef_t,
91 tm_tag_union_t,
92 tm_tag_variable_t,
93 tm_tag_other_t
96 static int get_tag_type(const char *tag_name)
98 unsigned int i;
99 int cmp;
100 g_return_val_if_fail(tag_name, 0);
101 for (i=0; i < sizeof(s_tag_type_names)/sizeof(char *); ++i)
103 cmp = strcmp(tag_name, s_tag_type_names[i]);
104 if (0 == cmp)
105 return s_tag_types[i];
106 else if (cmp < 0)
107 break;
109 #ifdef TM_DEBUG
110 fprintf(stderr, "Unknown tag type %s\n", tag_name);
111 #endif
112 return tm_tag_undef_t;
115 gboolean tm_tag_init(TMTag *tag, TMSourceFile *file, const tagEntryInfo *tag_entry)
117 if (NULL == tag_entry)
119 /* This is a file tag */
120 if (NULL == file)
121 return FALSE;
122 else
124 tag->name = g_strdup(file->work_object.file_name);
125 tag->type = tm_tag_file_t;
126 tag->atts.file.timestamp = file->work_object.analyze_time;
127 tag->atts.file.lang = file->lang;
128 tag->atts.file.inactive = FALSE;
129 return TRUE;
132 else
134 /* This is a normal tag entry */
135 if (NULL == tag_entry->name)
136 return FALSE;
137 tag->name = g_strdup(tag_entry->name);
138 tag->type = get_tag_type(tag_entry->kindName);
139 tag->atts.entry.local = tag_entry->isFileScope;
140 tag->atts.entry.pointerOrder = 0; /*FIXME: tag_entry->pointerOrder; */
141 tag->atts.entry.line = tag_entry->lineNumber;
142 if (NULL != tag_entry->extensionFields.signature)
143 tag->atts.entry.arglist = g_strdup(tag_entry->extensionFields.signature);
144 if ((NULL != tag_entry->extensionFields.scope[1]) &&
145 (isalpha(tag_entry->extensionFields.scope[1][0]) ||
146 tag_entry->extensionFields.scope[1][0] == '_')) {
147 tag->atts.entry.scope = g_strdup(tag_entry->extensionFields.scope[1]);
150 if (tag_entry->extensionFields.inheritance != NULL)
151 tag->atts.entry.inheritance = g_strdup(tag_entry->extensionFields.inheritance);
152 if (tag_entry->extensionFields.typeRef[0] != NULL)
153 tag->atts.entry.type_ref[0] = g_strdup(tag_entry->extensionFields.typeRef[0]);
154 if (tag_entry->extensionFields.typeRef[1] != NULL)
155 tag->atts.entry.type_ref[1] = g_strdup(tag_entry->extensionFields.typeRef[1]);
156 if (tag_entry->extensionFields.access != NULL)
158 if (0 == strcmp("public", tag_entry->extensionFields.access))
159 tag->atts.entry.access = TAG_ACCESS_PUBLIC;
160 else if (0 == strcmp("protected", tag_entry->extensionFields.access))
161 tag->atts.entry.access = TAG_ACCESS_PROTECTED;
162 else if (0 == strcmp("private", tag_entry->extensionFields.access))
163 tag->atts.entry.access = TAG_ACCESS_PRIVATE;
164 else if (0 == strcmp("friend", tag_entry->extensionFields.access))
165 tag->atts.entry.access = TAG_ACCESS_FRIEND;
166 else if (0 == strcmp("default", tag_entry->extensionFields.access))
167 tag->atts.entry.access = TAG_ACCESS_DEFAULT;
168 else
170 #ifdef TM_DEBUG
171 g_warning("Unknown access type %s", tag_entry->extensionFields.access);
172 #endif
173 tag->atts.entry.access = TAG_ACCESS_UNKNOWN;
176 if (tag_entry->extensionFields.implementation != NULL)
178 if ((0 == strcmp("virtual", tag_entry->extensionFields.implementation))
179 || (0 == strcmp("pure virtual", tag_entry->extensionFields.implementation)))
180 tag->atts.entry.impl = TAG_IMPL_VIRTUAL;
181 else
183 #ifdef TM_DEBUG
184 g_warning("Unknown implementation %s", tag_entry->extensionFields.implementation);
185 #endif
186 tag->atts.entry.impl = TAG_IMPL_UNKNOWN;
189 if ((tm_tag_macro_t == tag->type) && (NULL != tag->atts.entry.arglist))
190 tag->type = tm_tag_macro_with_arg_t;
191 tag->atts.entry.file = file;
192 return TRUE;
196 TMTag *tm_tag_new(TMSourceFile *file, const tagEntryInfo *tag_entry)
198 TMTag *tag;
200 TAG_NEW(tag);
201 if (FALSE == tm_tag_init(tag, file, tag_entry))
203 TAG_FREE(tag);
204 return NULL;
206 return tag;
209 gboolean tm_tag_init_from_file(TMTag *tag, TMSourceFile *file, FILE *fp)
211 gchar buf[BUFSIZ];
212 guchar *start, *end;
213 gboolean status;
214 guchar changed_char = TA_NAME;
216 if ((NULL == fgets(buf, BUFSIZ, fp)) || ('\0' == *buf))
217 return FALSE;
218 for (start = end = (guchar*)buf, status = TRUE; (TRUE == status); start = end, ++ end)
220 while ((*end < TA_NAME) && (*end != '\0') && (*end != '\n'))
221 ++ end;
222 if (('\0' == *end) || ('\n' == *end))
223 status = FALSE;
224 changed_char = *end;
225 *end = '\0';
226 if (NULL == tag->name)
228 if (!isprint(*start))
229 return FALSE;
230 else
231 tag->name = g_strdup( (gchar*)start );
233 else
235 switch (*start)
237 case TA_LINE:
238 tag->atts.entry.line = atol( (gchar*)start + 1);
239 break;
240 case TA_LOCAL:
241 tag->atts.entry.local = atoi( (gchar*)start + 1);
242 break;
243 case TA_TYPE:
244 tag->type = (TMTagType) atoi( (gchar*)start + 1);
245 break;
246 case TA_ARGLIST:
247 tag->atts.entry.arglist = g_strdup( (gchar*)start + 1);
248 break;
249 case TA_SCOPE:
250 tag->atts.entry.scope = g_strdup( (gchar*)start + 1);
251 break;
252 case TA_POINTER:
253 tag->atts.entry.pointerOrder = atoi( (gchar*)start + 1);
254 break;
255 case TA_VARTYPE:
256 tag->atts.entry.type_ref[1] = g_strdup ( (gchar*)start + 1);
257 break;
258 case TA_INHERITS:
259 tag->atts.entry.inheritance = g_strdup( (gchar*)start + 1);
260 break;
261 case TA_TIME:
262 if (tm_tag_file_t != tag->type)
264 g_warning("Got time attribute for non-file tag %s", tag->name);
265 return FALSE;
267 else
268 tag->atts.file.timestamp = atol( (gchar*)start + 1);
269 break;
270 case TA_LANG:
271 if (tm_tag_file_t != tag->type)
273 g_warning("Got lang attribute for non-file tag %s", tag->name);
274 return FALSE;
276 else
277 tag->atts.file.lang = atoi( (gchar*)start + 1);
278 break;
279 case TA_INACTIVE:
280 if (tm_tag_file_t != tag->type)
282 g_warning("Got inactive attribute for non-file tag %s", tag->name);
283 return FALSE;
285 else
286 tag->atts.file.inactive = (gboolean) atoi( (gchar*)start + 1);
287 break;
288 case TA_ACCESS:
289 tag->atts.entry.access = *(start + 1);
290 break;
291 case TA_IMPL:
292 tag->atts.entry.impl = *(start + 1);
293 break;
294 default:
295 #ifdef TM_DEBUG
296 g_warning("Unknown attribute %s", start + 1);
297 #endif
298 break;
301 *end = changed_char;
303 if (NULL == tag->name)
304 return FALSE;
305 if (tm_tag_file_t != tag->type)
306 tag->atts.entry.file = file;
307 return TRUE;
310 TMTag *tm_tag_new_from_file(TMSourceFile *file, FILE *fp)
312 TMTag *tag;
314 TAG_NEW(tag);
315 if (FALSE == tm_tag_init_from_file(tag, file, fp))
317 TAG_FREE(tag);
318 return NULL;
320 return tag;
323 gboolean tm_tag_write(TMTag *tag, FILE *fp, guint attrs)
325 fprintf(fp, "%s", tag->name);
326 if (attrs & tm_tag_attr_type_t)
327 fprintf(fp, "%c%d", TA_TYPE, tag->type);
328 if (tag->type == tm_tag_file_t)
330 if (attrs & tm_tag_attr_time_t)
331 fprintf(fp, "%c%ld", TA_TIME, tag->atts.file.timestamp);
332 if (attrs & tm_tag_attr_lang_t)
333 fprintf(fp, "%c%d", TA_LANG, tag->atts.file.lang);
334 if ((attrs & tm_tag_attr_inactive_t) && tag->atts.file.inactive)
335 fprintf(fp, "%c%d", TA_INACTIVE, tag->atts.file.inactive);
337 else
339 if ((attrs & tm_tag_attr_arglist_t) && (NULL != tag->atts.entry.arglist))
340 fprintf(fp, "%c%s", TA_ARGLIST, tag->atts.entry.arglist);
341 if (attrs & tm_tag_attr_line_t)
342 fprintf(fp, "%c%ld", TA_LINE, tag->atts.entry.line);
343 if (attrs & tm_tag_attr_local_t)
344 fprintf(fp, "%c%d", TA_LOCAL, tag->atts.entry.local);
345 if ((attrs & tm_tag_attr_scope_t) && (NULL != tag->atts.entry.scope))
346 fprintf(fp, "%c%s", TA_SCOPE, tag->atts.entry.scope);
347 if ((attrs & tm_tag_attr_inheritance_t) && (NULL != tag->atts.entry.inheritance))
348 fprintf(fp, "%c%s", TA_INHERITS, tag->atts.entry.inheritance);
349 if (attrs & tm_tag_attr_pointer_t)
350 fprintf(fp, "%c%d", TA_POINTER, tag->atts.entry.pointerOrder);
351 if ((attrs & tm_tag_attr_vartype_t) && (NULL != tag->atts.entry.type_ref[1]))
352 fprintf(fp, "%c%s", TA_VARTYPE, tag->atts.entry.type_ref[1]);
353 if ((attrs & tm_tag_attr_access_t) && (TAG_ACCESS_UNKNOWN != tag->atts.entry.access))
354 fprintf(fp, "%c%c", TA_ACCESS, tag->atts.entry.access);
355 if ((attrs & tm_tag_attr_impl_t) && (TAG_IMPL_UNKNOWN != tag->atts.entry.impl))
356 fprintf(fp, "%c%c", TA_IMPL, tag->atts.entry.impl);
358 if (fprintf(fp, "\n"))
359 return TRUE;
360 else
361 return FALSE;
364 static void tm_tag_destroy(TMTag *tag)
366 g_free(tag->name);
367 //if (tm_tag_file_t != tag->type)
369 g_free(tag->atts.entry.arglist);
370 g_free(tag->atts.entry.scope);
371 g_free(tag->atts.entry.inheritance);
372 g_free(tag->atts.entry.type_ref[0]);
373 g_free(tag->atts.entry.type_ref[1]);
377 void tm_tag_free(gpointer tag)
379 if (NULL != tag)
381 tm_tag_destroy((TMTag *) tag);
382 TAG_FREE(tag);
386 int tm_tag_compare(const void *ptr1, const void *ptr2)
388 guint *sort_attr;
389 int returnval = 0;
390 TMTag *t1 = *((TMTag **) ptr1);
391 TMTag *t2 = *((TMTag **) ptr2);
393 if ((NULL == t1) || (NULL == t2))
395 g_warning("Found NULL tag");
396 return t2 - t1;
398 if (NULL == s_sort_attrs)
400 if (s_partial)
401 return strncmp(NVL(t1->name, ""), NVL(t2->name, ""), strlen(NVL(t1->name, "")));
402 else
403 return strcmp(NVL(t1->name, ""), NVL(t2->name, ""));
406 for (sort_attr = s_sort_attrs; *sort_attr != tm_tag_attr_none_t; ++ sort_attr)
408 switch (*sort_attr)
410 case tm_tag_attr_name_t:
411 if (s_partial)
412 returnval = strncmp(NVL(t1->name, ""), NVL(t2->name, ""), strlen(NVL(t1->name, "")));
413 else
414 returnval = strcmp(NVL(t1->name, ""), NVL(t2->name, ""));
415 if (0 != returnval)
416 return returnval;
417 break;
418 case tm_tag_attr_type_t:
419 if (0 != (returnval = (t1->type - t2->type)))
420 return returnval;
421 break;
422 case tm_tag_attr_file_t:
423 if (0 != (returnval = (t1->atts.entry.file - t2->atts.entry.file)))
424 return returnval;
425 break;
426 case tm_tag_attr_scope_t:
427 if (0 != (returnval = strcmp(NVL(t1->atts.entry.scope, ""), NVL(t2->atts.entry.scope, ""))))
428 return returnval;
429 break;
430 case tm_tag_attr_vartype_t:
431 if (0 != (returnval = strcmp(NVL(t1->atts.entry.type_ref[1], ""), NVL(t2->atts.entry.type_ref[1], ""))))
432 return returnval;
433 break;
434 case tm_tag_attr_line_t:
435 if (0 != (returnval = (t1->atts.entry.line - t2->atts.entry.line)))
436 return returnval;
437 break;
440 return returnval;
443 gboolean tm_tags_prune(GPtrArray *tags_array)
445 guint i, count;
446 for (i=0, count = 0; i < tags_array->len; ++i)
448 if (NULL != tags_array->pdata[i])
449 tags_array->pdata[count++] = tags_array->pdata[i];
451 tags_array->len = count;
452 return TRUE;
455 gboolean tm_tags_dedup(GPtrArray *tags_array, TMTagAttrType *sort_attributes)
457 guint i;
459 if ((!tags_array) || (!tags_array->len))
460 return TRUE;
461 s_sort_attrs = sort_attributes;
462 s_partial = FALSE;
463 for (i = 1; i < tags_array->len; ++i)
465 if (0 == tm_tag_compare(&(tags_array->pdata[i - 1]), &(tags_array->pdata[i])))
467 tags_array->pdata[i-1] = NULL;
470 tm_tags_prune(tags_array);
471 return TRUE;
474 gboolean tm_tags_custom_dedup(GPtrArray *tags_array, TMTagCompareFunc compare_func)
476 guint i;
478 if ((!tags_array) || (!tags_array->len))
479 return TRUE;
480 for (i = 1; i < tags_array->len; ++i)
482 if (0 == compare_func(&(tags_array->pdata[i - 1]), &(tags_array->pdata[i])))
483 tags_array->pdata[i-1] = NULL;
485 tm_tags_prune(tags_array);
486 return TRUE;
489 gboolean tm_tags_sort(GPtrArray *tags_array, TMTagAttrType *sort_attributes, gboolean dedup)
491 if ((!tags_array) || (!tags_array->len))
492 return TRUE;
493 s_sort_attrs = sort_attributes;
494 s_partial = FALSE;
495 qsort(tags_array->pdata, tags_array->len, sizeof(gpointer), tm_tag_compare);
496 s_sort_attrs = NULL;
497 if (dedup)
498 tm_tags_dedup(tags_array, sort_attributes);
499 return TRUE;
502 gboolean tm_tags_custom_sort(GPtrArray *tags_array, TMTagCompareFunc compare_func, gboolean dedup)
504 if ((!tags_array) || (!tags_array->len))
505 return TRUE;
506 qsort(tags_array->pdata, tags_array->len, sizeof(gpointer), compare_func);
507 if (dedup)
508 tm_tags_custom_dedup(tags_array, compare_func);
509 return TRUE;
512 GPtrArray *tm_tags_extract(const GPtrArray *tags_array, guint tag_types)
514 GPtrArray *new_tags;
515 guint i;
516 if (NULL == tags_array)
517 return NULL;
518 new_tags = g_ptr_array_new();
519 for (i=0; i < tags_array->len; ++i)
521 if (NULL != tags_array->pdata[i])
523 if (tag_types & (((TMTag *) tags_array->pdata[i])->type))
524 g_ptr_array_add(new_tags, tags_array->pdata[i]);
527 return new_tags;
530 void tm_tags_array_free(GPtrArray *tags_array, gboolean free_all)
532 if (tags_array)
534 guint i;
535 for (i = 0; i < tags_array->len; ++i)
536 tm_tag_free(tags_array->pdata[i]);
537 if (free_all)
538 g_ptr_array_free(tags_array, TRUE);
539 else
540 g_ptr_array_set_size(tags_array, 0);
544 TMTag **tm_tags_find (const GPtrArray *sorted_tags_array, const char *name,
545 gboolean partial, int * tagCount)
547 static TMTag *tag = NULL;
548 TMTag **result;
549 int tagMatches=0;
551 if ((!sorted_tags_array) || (!sorted_tags_array->len))
552 return NULL;
554 if (NULL == tag)
555 tag = g_new0(TMTag, 1);
556 tag->name = (char *) name;
557 s_sort_attrs = NULL;
558 s_partial = partial;
559 result = (TMTag **) bsearch(&tag, sorted_tags_array->pdata, sorted_tags_array->len
560 , sizeof(gpointer), tm_tag_compare);
561 /* There can be matches on both sides of result */
562 if (result)
564 TMTag **last = (TMTag **) &sorted_tags_array->pdata[sorted_tags_array->len - 1];
565 TMTag **adv;
567 /* First look for any matches after result */
568 adv = result;
569 adv++;
570 for (; adv <= last && *adv; ++ adv)
572 if (0 != tm_tag_compare(&tag, adv))
573 break;
574 ++tagMatches;
576 /* Now look for matches from result and below */
577 for (; result >= (TMTag **) sorted_tags_array->pdata; -- result)
579 if (0 != tm_tag_compare(&tag, (TMTag **) result))
580 break;
581 ++tagMatches;
583 *tagCount=tagMatches;
584 ++ result; /* Correct address for the last successful match */
586 s_partial = FALSE;
587 return (TMTag **) result;
590 const char *tm_tag_type_name(const TMTag *tag)
592 g_return_val_if_fail(tag, NULL);
593 switch(tag->type)
595 case tm_tag_class_t: return "class";
596 case tm_tag_enum_t: return "enum";
597 case tm_tag_enumerator_t: return "enumval";
598 case tm_tag_field_t: return "field";
599 case tm_tag_function_t: return "function";
600 case tm_tag_interface_t: return "interface";
601 case tm_tag_member_t: return "member";
602 case tm_tag_method_t: return "method";
603 case tm_tag_namespace_t: return "namespace";
604 case tm_tag_package_t: return "package";
605 case tm_tag_prototype_t: return "prototype";
606 case tm_tag_struct_t: return "struct";
607 case tm_tag_typedef_t: return "typedef";
608 case tm_tag_union_t: return "union";
609 case tm_tag_variable_t: return "variable";
610 case tm_tag_externvar_t: return "extern";
611 case tm_tag_macro_t: return "define";
612 case tm_tag_macro_with_arg_t: return "macro";
613 case tm_tag_file_t: return "file";
614 default: return NULL;
616 return NULL;
619 TMTagType tm_tag_name_type(const char* tag_name)
621 g_return_val_if_fail(tag_name, tm_tag_undef_t);
623 if (strcmp(tag_name, "class") == 0) return tm_tag_class_t;
624 else if (strcmp(tag_name, "enum") == 0) return tm_tag_enum_t;
625 else if (strcmp(tag_name, "enumval") == 0) return tm_tag_enumerator_t;
626 else if (strcmp(tag_name, "field") == 0) return tm_tag_field_t;
627 else if (strcmp(tag_name, "function") == 0) return tm_tag_function_t;
628 else if (strcmp(tag_name, "interface") == 0) return tm_tag_interface_t;
629 else if (strcmp(tag_name, "member") == 0) return tm_tag_member_t;
630 else if (strcmp(tag_name, "method") == 0) return tm_tag_method_t;
631 else if (strcmp(tag_name, "namespace") == 0) return tm_tag_namespace_t;
632 else if (strcmp(tag_name, "package") == 0) return tm_tag_package_t;
633 else if (strcmp(tag_name, "prototype") == 0) return tm_tag_prototype_t;
634 else if (strcmp(tag_name, "struct") == 0) return tm_tag_struct_t;
635 else if (strcmp(tag_name, "typedef") == 0) return tm_tag_typedef_t;
636 else if (strcmp(tag_name, "union") == 0) return tm_tag_union_t;
637 else if (strcmp(tag_name, "variable") == 0) return tm_tag_variable_t;
638 else if (strcmp(tag_name, "extern") == 0) return tm_tag_externvar_t;
639 else if (strcmp(tag_name, "define") == 0) return tm_tag_macro_t;
640 else if (strcmp(tag_name, "macro") == 0) return tm_tag_macro_with_arg_t;
641 else if (strcmp(tag_name, "file") == 0) return tm_tag_file_t;
642 else return tm_tag_undef_t;
645 static const char *tm_tag_impl_name(TMTag *tag)
647 g_return_val_if_fail(tag && (tm_tag_file_t != tag->type), NULL);
648 if (TAG_IMPL_VIRTUAL == tag->atts.entry.impl)
649 return "virtual";
650 else
651 return NULL;
654 static const char *tm_tag_access_name(TMTag *tag)
656 g_return_val_if_fail(tag && (tm_tag_file_t != tag->type), NULL);
657 if (TAG_ACCESS_PUBLIC == tag->atts.entry.access)
658 return "public";
659 else if (TAG_ACCESS_PROTECTED == tag->atts.entry.access)
660 return "protected";
661 else if (TAG_ACCESS_PRIVATE == tag->atts.entry.access)
662 return "private";
663 else
664 return NULL;
667 void tm_tag_print(TMTag *tag, FILE *fp)
669 const char *access, *impl, *type;
670 if (!tag || !fp)
671 return;
672 if (tm_tag_file_t == tag->type)
674 fprintf(fp, "%s\n", tag->name);
675 return;
677 access = tm_tag_access_name(tag);
678 impl = tm_tag_impl_name(tag);
679 type = tm_tag_type_name(tag);
680 if (access)
681 fprintf(fp, "%s ", access);
682 if (impl)
683 fprintf(fp, "%s ", impl);
684 if (type)
685 fprintf(fp, "%s ", type);
686 if (tag->atts.entry.type_ref[1])
687 fprintf(fp, "%s ", tag->atts.entry.type_ref[1]);
688 if (tag->atts.entry.scope)
689 fprintf(fp, "%s::", tag->atts.entry.scope);
690 fprintf(fp, "%s", tag->name);
691 if (tag->atts.entry.arglist)
692 fprintf(fp, "%s", tag->atts.entry.arglist);
693 if (tag->atts.entry.inheritance)
694 fprintf(fp, " : from %s", tag->atts.entry.inheritance);
695 if ((tag->atts.entry.file) && (tag->atts.entry.line > 0))
696 fprintf(fp, "[%s:%ld]", tag->atts.entry.file->work_object.file_name
697 , tag->atts.entry.line);
698 fprintf(fp, "\n");
701 void tm_tags_array_print(GPtrArray *tags, FILE *fp)
703 guint i;
704 TMTag *tag;
705 if (!(tags && (tags->len > 0) && fp))
706 return;
707 for (i = 0; i < tags->len; ++i)
709 tag = TM_TAG(tags->pdata[i]);
710 tm_tag_print(tag, fp);
714 gint tm_tag_scope_depth(const TMTag *t)
716 gint depth;
717 char *s;
718 if(!(t && t->atts.entry.scope))
719 return 0;
720 for (s = t->atts.entry.scope, depth = 0; s; s = strstr(s, "::"))
722 ++ depth;
723 ++ s;
725 return depth;
728 void tm_tag_chunk_clean (void)
730 if (s_tag_mem_chunk)
731 g_mem_chunk_clean (s_tag_mem_chunk);