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.
17 #define LIBCTAGS_DEFINED
21 #if GLIB_CHECK_VERSION (2, 10, 0)
22 /* Use GSlices if present */
24 #define TAG_NEW(T) ((T) = g_slice_new0(TMTag))
25 #define TAG_FREE(T) g_slice_free(TMTag, (T))
27 #else /* GLib < 2.10 */
29 static GMemChunk
*s_tag_mem_chunk
= NULL
;
32 if (!s_tag_mem_chunk) \
33 s_tag_mem_chunk = g_mem_chunk_new("TMTag memChunk", sizeof(TMTag), 1024 \
34 , G_ALLOC_AND_FREE); \
35 (T) = g_chunk_new0(TMTag, s_tag_mem_chunk);}
37 #define TAG_FREE(T) g_mem_chunk_free(s_tag_mem_chunk, (T))
39 #endif /* GLib version check */
42 /* Note: To preserve binary compatibility, it is very important
43 that you only *append* to this list ! */
49 TA_POS
, /* Obsolete */
63 static guint
*s_sort_attrs
= NULL
;
64 static gboolean s_partial
= FALSE
;
66 static const char *s_tag_type_names
[] = {
67 "class", /* classes */
68 "enum", /* enumeration names */
69 "enumerator", /* enumerators (values inside an enumeration) */
70 "externvar", /* external variable declarations */
72 "function", /* function definitions */
73 "interface", /* interfaces */
74 "macro", /* macro definitions */
75 "member", /* class, struct, and union members */
76 "method", /* methods */
77 "namespace", /* namespaces */
78 "package", /* packages */
79 "prototype", /* function prototypes */
80 "struct", /* structure names */
81 "typedef", /* typedefs */
82 "union", /* union names */
83 "variable", /* variable definitions */
84 "other" /* Other tag type (non C/C++/Java) */
87 static int s_tag_types
[] = {
108 static int get_tag_type(const char *tag_name
)
112 g_return_val_if_fail(tag_name
, 0);
113 for (i
=0; i
< sizeof(s_tag_type_names
)/sizeof(char *); ++i
)
115 cmp
= strcmp(tag_name
, s_tag_type_names
[i
]);
117 return s_tag_types
[i
];
121 /* other is not checked above as it is last, not sorted alphabetically */
122 if (strcmp(tag_name
, "other") == 0)
123 return tm_tag_other_t
;
125 fprintf(stderr
, "Unknown tag type %s\n", tag_name
);
127 return tm_tag_undef_t
;
130 gboolean
tm_tag_init(TMTag
*tag
, TMSourceFile
*file
, const tagEntryInfo
*tag_entry
)
132 if (NULL
== tag_entry
)
134 /* This is a file tag */
139 tag
->name
= g_strdup(file
->work_object
.file_name
);
140 tag
->type
= tm_tag_file_t
;
141 /* tag->atts.file.timestamp = file->work_object.analyze_time; */
142 tag
->atts
.file
.lang
= file
->lang
;
143 tag
->atts
.file
.inactive
= FALSE
;
149 /* This is a normal tag entry */
150 if (NULL
== tag_entry
->name
)
152 tag
->name
= g_strdup(tag_entry
->name
);
153 tag
->type
= get_tag_type(tag_entry
->kindName
);
154 tag
->atts
.entry
.local
= tag_entry
->isFileScope
;
155 tag
->atts
.entry
.pointerOrder
= 0; /* backward compatibility (use var_type instead) */
156 tag
->atts
.entry
.line
= tag_entry
->lineNumber
;
157 if (NULL
!= tag_entry
->extensionFields
.arglist
)
158 tag
->atts
.entry
.arglist
= g_strdup(tag_entry
->extensionFields
.arglist
);
159 if ((NULL
!= tag_entry
->extensionFields
.scope
[1]) &&
160 (isalpha(tag_entry
->extensionFields
.scope
[1][0]) ||
161 tag_entry
->extensionFields
.scope
[1][0] == '_'))
162 tag
->atts
.entry
.scope
= g_strdup(tag_entry
->extensionFields
.scope
[1]);
163 if (tag_entry
->extensionFields
.inheritance
!= NULL
)
164 tag
->atts
.entry
.inheritance
= g_strdup(tag_entry
->extensionFields
.inheritance
);
165 if (tag_entry
->extensionFields
.varType
!= NULL
)
166 tag
->atts
.entry
.var_type
= g_strdup(tag_entry
->extensionFields
.varType
);
167 if (tag_entry
->extensionFields
.access
!= NULL
)
169 if (0 == strcmp("public", tag_entry
->extensionFields
.access
))
170 tag
->atts
.entry
.access
= TAG_ACCESS_PUBLIC
;
171 else if (0 == strcmp("protected", tag_entry
->extensionFields
.access
))
172 tag
->atts
.entry
.access
= TAG_ACCESS_PROTECTED
;
173 else if (0 == strcmp("private", tag_entry
->extensionFields
.access
))
174 tag
->atts
.entry
.access
= TAG_ACCESS_PRIVATE
;
175 else if (0 == strcmp("friend", tag_entry
->extensionFields
.access
))
176 tag
->atts
.entry
.access
= TAG_ACCESS_FRIEND
;
177 else if (0 == strcmp("default", tag_entry
->extensionFields
.access
))
178 tag
->atts
.entry
.access
= TAG_ACCESS_DEFAULT
;
182 g_warning("Unknown access type %s", tag_entry
->extensionFields
.access
);
184 tag
->atts
.entry
.access
= TAG_ACCESS_UNKNOWN
;
187 if (tag_entry
->extensionFields
.implementation
!= NULL
)
189 if ((0 == strcmp("virtual", tag_entry
->extensionFields
.implementation
))
190 || (0 == strcmp("pure virtual", tag_entry
->extensionFields
.implementation
)))
191 tag
->atts
.entry
.impl
= TAG_IMPL_VIRTUAL
;
195 g_warning("Unknown implementation %s", tag_entry
->extensionFields
.implementation
);
197 tag
->atts
.entry
.impl
= TAG_IMPL_UNKNOWN
;
200 if ((tm_tag_macro_t
== tag
->type
) && (NULL
!= tag
->atts
.entry
.arglist
))
201 tag
->type
= tm_tag_macro_with_arg_t
;
202 tag
->atts
.entry
.file
= file
;
207 TMTag
*tm_tag_new(TMSourceFile
*file
, const tagEntryInfo
*tag_entry
)
212 if (FALSE
== tm_tag_init(tag
, file
, tag_entry
))
220 gboolean
tm_tag_init_from_file(TMTag
*tag
, TMSourceFile
*file
, FILE *fp
)
225 guchar changed_char
= TA_NAME
;
227 if ((NULL
== fgets((gchar
*)buf
, BUFSIZ
, fp
)) || ('\0' == *buf
))
229 for (start
= end
= buf
, status
= TRUE
; (TRUE
== status
); start
= end
, ++ end
)
231 while ((*end
< TA_NAME
) && (*end
!= '\0') && (*end
!= '\n'))
233 if (('\0' == *end
) || ('\n' == *end
))
237 if (NULL
== tag
->name
)
239 if (!isprint(*start
))
242 tag
->name
= g_strdup((gchar
*)start
);
249 tag
->atts
.entry
.line
= atol((gchar
*)start
+ 1);
252 tag
->atts
.entry
.local
= atoi((gchar
*)start
+ 1);
255 tag
->type
= (TMTagType
) atoi((gchar
*)start
+ 1);
258 tag
->atts
.entry
.arglist
= g_strdup((gchar
*)start
+ 1);
261 tag
->atts
.entry
.scope
= g_strdup((gchar
*)start
+ 1);
264 tag
->atts
.entry
.pointerOrder
= atoi((gchar
*)start
+ 1);
267 tag
->atts
.entry
.var_type
= g_strdup((gchar
*)start
+ 1);
270 tag
->atts
.entry
.inheritance
= g_strdup((gchar
*)start
+ 1);
273 if (tm_tag_file_t
!= tag
->type
)
275 g_warning("Got time attribute for non-file tag %s", tag
->name
);
279 tag
->atts
.file
.timestamp
= atol((gchar
*)start
+ 1);
282 if (tm_tag_file_t
!= tag
->type
)
284 g_warning("Got lang attribute for non-file tag %s", tag
->name
);
288 tag
->atts
.file
.lang
= atoi((gchar
*)start
+ 1);
291 if (tm_tag_file_t
!= tag
->type
)
293 g_warning("Got inactive attribute for non-file tag %s", tag
->name
);
297 tag
->atts
.file
.inactive
= (gboolean
) atoi((gchar
*)start
+ 1);
300 tag
->atts
.entry
.access
= *(start
+ 1);
303 tag
->atts
.entry
.impl
= *(start
+ 1);
307 g_warning("Unknown attribute %s", start
+ 1);
314 if (NULL
== tag
->name
)
316 if (tm_tag_file_t
!= tag
->type
)
317 tag
->atts
.entry
.file
= file
;
321 /* alternative parser for Pascal and LaTeX global tags files with the following format
322 * tagname|return value|arglist|description\n */
323 gboolean
tm_tag_init_from_file_alt(TMTag
*tag
, TMSourceFile
*file
, FILE *fp
)
328 /*guchar changed_char = TA_NAME;*/
330 if ((NULL
== fgets((gchar
*)buf
, BUFSIZ
, fp
)) || ('\0' == *buf
))
335 for (start
= end
= buf
, status
= TRUE
; (TRUE
== status
); start
= end
, ++ end
)
337 while ((*end
< TA_NAME
) && (*end
!= '\0') && (*end
!= '\n'))
339 if (('\0' == *end
) || ('\n' == *end
))
341 /*changed_char = *end;*/
343 if (NULL
== tag
->name
&& !isprint(*start
))
346 fields
= g_strsplit((gchar
*)start
, "|", -1);
347 field_len
= g_strv_length(fields
);
349 if (field_len
>= 1) tag
->name
= g_strdup(fields
[0]);
350 else tag
->name
= NULL
;
351 if (field_len
>= 2 && fields
[1] != NULL
) tag
->atts
.entry
.var_type
= g_strdup(fields
[1]);
352 if (field_len
>= 3 && fields
[2] != NULL
) tag
->atts
.entry
.arglist
= g_strdup(fields
[2]);
353 tag
->type
= tm_tag_prototype_t
;
358 if (NULL
== tag
->name
)
360 if (tm_tag_file_t
!= tag
->type
)
361 tag
->atts
.entry
.file
= file
;
365 TMTag
*tm_tag_new_from_file(TMSourceFile
*file
, FILE *fp
, gint mode
, gboolean format_pipe
)
373 result
= tm_tag_init_from_file_alt(tag
, file
, fp
);
375 result
= tm_tag_init_from_file(tag
, file
, fp
);
382 tag
->atts
.file
.lang
= mode
;
386 gboolean
tm_tag_write(TMTag
*tag
, FILE *fp
, guint attrs
)
388 fprintf(fp
, "%s", tag
->name
);
389 if (attrs
& tm_tag_attr_type_t
)
390 fprintf(fp
, "%c%d", TA_TYPE
, tag
->type
);
391 if (tag
->type
== tm_tag_file_t
)
393 if (attrs
& tm_tag_attr_time_t
)
394 fprintf(fp
, "%c%ld", TA_TIME
, tag
->atts
.file
.timestamp
);
395 if (attrs
& tm_tag_attr_lang_t
)
396 fprintf(fp
, "%c%d", TA_LANG
, tag
->atts
.file
.lang
);
397 if ((attrs
& tm_tag_attr_inactive_t
) && tag
->atts
.file
.inactive
)
398 fprintf(fp
, "%c%d", TA_INACTIVE
, tag
->atts
.file
.inactive
);
402 if ((attrs
& tm_tag_attr_arglist_t
) && (NULL
!= tag
->atts
.entry
.arglist
))
403 fprintf(fp
, "%c%s", TA_ARGLIST
, tag
->atts
.entry
.arglist
);
404 if (attrs
& tm_tag_attr_line_t
)
405 fprintf(fp
, "%c%ld", TA_LINE
, tag
->atts
.entry
.line
);
406 if (attrs
& tm_tag_attr_local_t
)
407 fprintf(fp
, "%c%d", TA_LOCAL
, tag
->atts
.entry
.local
);
408 if ((attrs
& tm_tag_attr_scope_t
) && (NULL
!= tag
->atts
.entry
.scope
))
409 fprintf(fp
, "%c%s", TA_SCOPE
, tag
->atts
.entry
.scope
);
410 if ((attrs
& tm_tag_attr_inheritance_t
) && (NULL
!= tag
->atts
.entry
.inheritance
))
411 fprintf(fp
, "%c%s", TA_INHERITS
, tag
->atts
.entry
.inheritance
);
412 if (attrs
& tm_tag_attr_pointer_t
)
413 fprintf(fp
, "%c%d", TA_POINTER
, tag
->atts
.entry
.pointerOrder
);
414 if ((attrs
& tm_tag_attr_vartype_t
) && (NULL
!= tag
->atts
.entry
.var_type
))
415 fprintf(fp
, "%c%s", TA_VARTYPE
, tag
->atts
.entry
.var_type
);
416 if ((attrs
& tm_tag_attr_access_t
) && (TAG_ACCESS_UNKNOWN
!= tag
->atts
.entry
.access
))
417 fprintf(fp
, "%c%c", TA_ACCESS
, tag
->atts
.entry
.access
);
418 if ((attrs
& tm_tag_attr_impl_t
) && (TAG_IMPL_UNKNOWN
!= tag
->atts
.entry
.impl
))
419 fprintf(fp
, "%c%c", TA_IMPL
, tag
->atts
.entry
.impl
);
421 if (fprintf(fp
, "\n"))
427 static void tm_tag_destroy(TMTag
*tag
)
430 if (tm_tag_file_t
!= tag
->type
)
432 g_free(tag
->atts
.entry
.arglist
);
433 g_free(tag
->atts
.entry
.scope
);
434 g_free(tag
->atts
.entry
.inheritance
);
435 g_free(tag
->atts
.entry
.var_type
);
439 void tm_tag_free(gpointer tag
)
443 tm_tag_destroy((TMTag
*) tag
);
448 int tm_tag_compare(const void *ptr1
, const void *ptr2
)
450 unsigned int *sort_attr
;
452 TMTag
*t1
= *((TMTag
**) ptr1
);
453 TMTag
*t2
= *((TMTag
**) ptr2
);
455 if ((NULL
== t1
) || (NULL
== t2
))
457 g_warning("Found NULL tag");
460 if (NULL
== s_sort_attrs
)
463 return strncmp(NVL(t1
->name
, ""), NVL(t2
->name
, ""), strlen(NVL(t1
->name
, "")));
465 return strcmp(NVL(t1
->name
, ""), NVL(t2
->name
, ""));
468 for (sort_attr
= s_sort_attrs
; *sort_attr
!= tm_tag_attr_none_t
; ++ sort_attr
)
472 case tm_tag_attr_name_t
:
474 returnval
= strncmp(NVL(t1
->name
, ""), NVL(t2
->name
, ""), strlen(NVL(t1
->name
, "")));
476 returnval
= strcmp(NVL(t1
->name
, ""), NVL(t2
->name
, ""));
480 case tm_tag_attr_type_t
:
481 if (0 != (returnval
= (t1
->type
- t2
->type
)))
484 case tm_tag_attr_file_t
:
485 if (0 != (returnval
= (t1
->atts
.entry
.file
- t2
->atts
.entry
.file
)))
488 case tm_tag_attr_scope_t
:
489 if (0 != (returnval
= strcmp(NVL(t1
->atts
.entry
.scope
, ""), NVL(t2
->atts
.entry
.scope
, ""))))
492 case tm_tag_attr_arglist_t
:
493 if (0 != (returnval
= strcmp(NVL(t1
->atts
.entry
.arglist
, ""), NVL(t2
->atts
.entry
.arglist
, ""))))
495 int line_diff
= (t1
->atts
.entry
.line
- t2
->atts
.entry
.line
);
497 return line_diff
? line_diff
: returnval
;
500 case tm_tag_attr_vartype_t
:
501 if (0 != (returnval
= strcmp(NVL(t1
->atts
.entry
.var_type
, ""), NVL(t2
->atts
.entry
.var_type
, ""))))
504 case tm_tag_attr_line_t
:
505 if (0 != (returnval
= (t1
->atts
.entry
.line
- t2
->atts
.entry
.line
)))
513 gboolean
tm_tags_prune(GPtrArray
*tags_array
)
516 for (i
=0, count
= 0; i
< tags_array
->len
; ++i
)
518 if (NULL
!= tags_array
->pdata
[i
])
519 tags_array
->pdata
[count
++] = tags_array
->pdata
[i
];
521 tags_array
->len
= count
;
525 gboolean
tm_tags_dedup(GPtrArray
*tags_array
, TMTagAttrType
*sort_attributes
)
529 if ((!tags_array
) || (!tags_array
->len
))
531 s_sort_attrs
= sort_attributes
;
533 for (i
= 1; i
< tags_array
->len
; ++i
)
535 if (0 == tm_tag_compare(&(tags_array
->pdata
[i
- 1]), &(tags_array
->pdata
[i
])))
537 tags_array
->pdata
[i
-1] = NULL
;
540 tm_tags_prune(tags_array
);
544 gboolean
tm_tags_custom_dedup(GPtrArray
*tags_array
, TMTagCompareFunc compare_func
)
548 if ((!tags_array
) || (!tags_array
->len
))
550 for (i
= 1; i
< tags_array
->len
; ++i
)
552 if (0 == compare_func(&(tags_array
->pdata
[i
- 1]), &(tags_array
->pdata
[i
])))
553 tags_array
->pdata
[i
-1] = NULL
;
555 tm_tags_prune(tags_array
);
559 gboolean
tm_tags_sort(GPtrArray
*tags_array
, TMTagAttrType
*sort_attributes
, gboolean dedup
)
561 if ((!tags_array
) || (!tags_array
->len
))
563 s_sort_attrs
= sort_attributes
;
565 qsort(tags_array
->pdata
, tags_array
->len
, sizeof(gpointer
), tm_tag_compare
);
568 tm_tags_dedup(tags_array
, sort_attributes
);
572 gboolean
tm_tags_custom_sort(GPtrArray
*tags_array
, TMTagCompareFunc compare_func
, gboolean dedup
)
574 if ((!tags_array
) || (!tags_array
->len
))
576 qsort(tags_array
->pdata
, tags_array
->len
, sizeof(gpointer
), compare_func
);
578 tm_tags_custom_dedup(tags_array
, compare_func
);
582 GPtrArray
*tm_tags_extract(GPtrArray
*tags_array
, guint tag_types
)
586 if (NULL
== tags_array
)
588 new_tags
= g_ptr_array_new();
589 for (i
=0; i
< tags_array
->len
; ++i
)
591 if (NULL
!= tags_array
->pdata
[i
])
593 if (tag_types
& (((TMTag
*) tags_array
->pdata
[i
])->type
))
594 g_ptr_array_add(new_tags
, tags_array
->pdata
[i
]);
600 void tm_tags_array_free(GPtrArray
*tags_array
, gboolean free_all
)
605 for (i
= 0; i
< tags_array
->len
; ++i
)
606 tm_tag_free(tags_array
->pdata
[i
]);
608 g_ptr_array_free(tags_array
, TRUE
);
610 g_ptr_array_set_size(tags_array
, 0);
614 TMTag
**tm_tags_find(const GPtrArray
*sorted_tags_array
, const char *name
,
615 gboolean partial
, int * tagCount
)
617 static TMTag
*tag
= NULL
;
621 if ((!sorted_tags_array
) || (!sorted_tags_array
->len
))
625 tag
= g_new0(TMTag
, 1);
626 tag
->name
= (char *) name
;
629 result
= (TMTag
**) bsearch(&tag
, sorted_tags_array
->pdata
, sorted_tags_array
->len
630 , sizeof(gpointer
), tm_tag_compare
);
631 /* There can be matches on both sides of result */
634 TMTag
**last
= (TMTag
**) &sorted_tags_array
->pdata
[sorted_tags_array
->len
- 1];
637 /* First look for any matches after result */
640 for (; adv
<= last
&& *adv
; ++ adv
)
642 if (0 != tm_tag_compare(&tag
, adv
))
646 /* Now look for matches from result and below */
647 for (; result
>= (TMTag
**) sorted_tags_array
->pdata
; -- result
)
649 if (0 != tm_tag_compare(&tag
, (TMTag
**) result
))
653 *tagCount
=tagMatches
;
654 ++ result
; /* Correct address for the last successful match */
657 return (TMTag
**) result
;
660 const char *tm_tag_type_name(const TMTag
*tag
)
662 g_return_val_if_fail(tag
, NULL
);
665 case tm_tag_class_t
: return "class";
666 case tm_tag_enum_t
: return "enum";
667 case tm_tag_enumerator_t
: return "enumval";
668 case tm_tag_field_t
: return "field";
669 case tm_tag_function_t
: return "function";
670 case tm_tag_interface_t
: return "interface";
671 case tm_tag_member_t
: return "member";
672 case tm_tag_method_t
: return "method";
673 case tm_tag_namespace_t
: return "namespace";
674 case tm_tag_package_t
: return "package";
675 case tm_tag_prototype_t
: return "prototype";
676 case tm_tag_struct_t
: return "struct";
677 case tm_tag_typedef_t
: return "typedef";
678 case tm_tag_union_t
: return "union";
679 case tm_tag_variable_t
: return "variable";
680 case tm_tag_externvar_t
: return "extern";
681 case tm_tag_macro_t
: return "define";
682 case tm_tag_macro_with_arg_t
: return "macro";
683 case tm_tag_file_t
: return "file";
684 default: return NULL
;
689 TMTagType
tm_tag_name_type(const char* tag_name
)
691 g_return_val_if_fail(tag_name
, tm_tag_undef_t
);
693 if (strcmp(tag_name
, "class") == 0) return tm_tag_class_t
;
694 else if (strcmp(tag_name
, "enum") == 0) return tm_tag_enum_t
;
695 else if (strcmp(tag_name
, "enumval") == 0) return tm_tag_enumerator_t
;
696 else if (strcmp(tag_name
, "field") == 0) return tm_tag_field_t
;
697 else if (strcmp(tag_name
, "function") == 0) return tm_tag_function_t
;
698 else if (strcmp(tag_name
, "interface") == 0) return tm_tag_interface_t
;
699 else if (strcmp(tag_name
, "member") == 0) return tm_tag_member_t
;
700 else if (strcmp(tag_name
, "method") == 0) return tm_tag_method_t
;
701 else if (strcmp(tag_name
, "namespace") == 0) return tm_tag_namespace_t
;
702 else if (strcmp(tag_name
, "package") == 0) return tm_tag_package_t
;
703 else if (strcmp(tag_name
, "prototype") == 0) return tm_tag_prototype_t
;
704 else if (strcmp(tag_name
, "struct") == 0) return tm_tag_struct_t
;
705 else if (strcmp(tag_name
, "typedef") == 0) return tm_tag_typedef_t
;
706 else if (strcmp(tag_name
, "union") == 0) return tm_tag_union_t
;
707 else if (strcmp(tag_name
, "variable") == 0) return tm_tag_variable_t
;
708 else if (strcmp(tag_name
, "extern") == 0) return tm_tag_externvar_t
;
709 else if (strcmp(tag_name
, "define") == 0) return tm_tag_macro_t
;
710 else if (strcmp(tag_name
, "macro") == 0) return tm_tag_macro_with_arg_t
;
711 else if (strcmp(tag_name
, "file") == 0) return tm_tag_file_t
;
712 else return tm_tag_undef_t
;
715 static const char *tm_tag_impl_name(TMTag
*tag
)
717 g_return_val_if_fail(tag
&& (tm_tag_file_t
!= tag
->type
), NULL
);
718 if (TAG_IMPL_VIRTUAL
== tag
->atts
.entry
.impl
)
724 static const char *tm_tag_access_name(TMTag
*tag
)
726 g_return_val_if_fail(tag
&& (tm_tag_file_t
!= tag
->type
), NULL
);
727 if (TAG_ACCESS_PUBLIC
== tag
->atts
.entry
.access
)
729 else if (TAG_ACCESS_PROTECTED
== tag
->atts
.entry
.access
)
731 else if (TAG_ACCESS_PRIVATE
== tag
->atts
.entry
.access
)
737 void tm_tag_print(TMTag
*tag
, FILE *fp
)
739 const char *laccess
, *impl
, *type
;
742 if (tm_tag_file_t
== tag
->type
)
744 fprintf(fp
, "%s\n", tag
->name
);
747 laccess
= tm_tag_access_name(tag
);
748 impl
= tm_tag_impl_name(tag
);
749 type
= tm_tag_type_name(tag
);
751 fprintf(fp
, "%s ", laccess
);
753 fprintf(fp
, "%s ", impl
);
755 fprintf(fp
, "%s ", type
);
756 if (tag
->atts
.entry
.var_type
)
757 fprintf(fp
, "%s ", tag
->atts
.entry
.var_type
);
758 if (tag
->atts
.entry
.scope
)
759 fprintf(fp
, "%s::", tag
->atts
.entry
.scope
);
760 fprintf(fp
, "%s", tag
->name
);
761 if (tag
->atts
.entry
.arglist
)
762 fprintf(fp
, "%s", tag
->atts
.entry
.arglist
);
763 if (tag
->atts
.entry
.inheritance
)
764 fprintf(fp
, " : from %s", tag
->atts
.entry
.inheritance
);
765 if ((tag
->atts
.entry
.file
) && (tag
->atts
.entry
.line
> 0))
766 fprintf(fp
, "[%s:%ld]", tag
->atts
.entry
.file
->work_object
.file_name
767 , tag
->atts
.entry
.line
);
771 void tm_tags_array_print(GPtrArray
*tags
, FILE *fp
)
775 if (!(tags
&& (tags
->len
> 0) && fp
))
777 for (i
= 0; i
< tags
->len
; ++i
)
779 tag
= TM_TAG(tags
->pdata
[i
]);
780 tm_tag_print(tag
, fp
);
784 gint
tm_tag_scope_depth(const TMTag
*t
)
788 if(!(t
&& t
->atts
.entry
.scope
))
790 for (s
= t
->atts
.entry
.scope
, depth
= 0; s
; s
= strstr(s
, "::"))