geany  1.38
About: Geany is a text editor (using GTK2) with basic features of an integrated development environment (syntax highlighting, code folding, symbol name auto-completion, ...). F: office T: editor programming GTK+ IDE
  Fossies Dox: geany-1.38.tar.bz2  ("unofficial" and yet experimental doxygen-generated source code documentation)  

tm_ctags.c
Go to the documentation of this file.
1/*
2* Copyright (c) 2016, Jiri Techet
3*
4* This source code is released for free distribution under the terms of the
5* GNU General Public License version 2 or (at your option) any later version.
6*
7* Encapsulates ctags so it is isolated from the rest of Geany.
8*/
9
10#include "tm_ctags.h"
11#include "tm_tag.h"
12
13#include "general.h" /* must always come before the rest of ctags headers */
14#include "entry_p.h"
15#include "error_p.h"
16#include "field_p.h"
17#include "options_p.h"
18#include "parse_p.h"
19#include "trashbox_p.h"
20#include "writer_p.h"
21#include "xtag_p.h"
22
23#include <string.h>
24
25
26static gint write_entry(tagWriter *writer, MIO * mio, const tagEntryInfo *const tag, void *user_data);
27static void rescan_failed(tagWriter *writer, gulong valid_tag_num, void *user_data);
28
31 .writePtagEntry = NULL, /* no pseudo-tags */
32 .preWriteEntry = NULL,
33 .postWriteEntry = NULL,
34 .rescanFailedEntry = rescan_failed,
35 .treatFieldAsFixed = NULL,
36 .defaultFileName = "geany_tags_file_which_should_never_appear_anywhere",
37 .private = NULL,
38 .type = WRITER_CUSTOM
39};
40
41
42static bool nonfatal_error_printer(const errorSelection selection,
43 const gchar *const format,
44 va_list ap, void *data CTAGS_ATTR_UNUSED)
45{
46 g_logv(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, format, ap);
47
48 return false;
49}
50
51
53{
54 TMParserType lang;
55
56 for (lang = 0; lang < countParsers(); lang++)
57 {
58 guint kind_num = countLanguageKinds(lang);
59 guint kind;
60
61 for (kind = 0; kind < kind_num; kind++)
62 {
63 kindDefinition *def = getLanguageKind(lang, kind);
64 enableKind(def, true);
65 }
66 }
67}
68
69
70/*
71 Initializes a TMTag structure with information from a ctagsTag struct
72 used by the ctags parsers. Note that the TMTag structure must be malloc()ed
73 before calling this function.
74 @param tag The TMTag structure to initialize
75 @param file Pointer to a TMSourceFile struct (it is assigned to the file member)
76 @param tag_entry Tag information gathered by the ctags parser
77 @return TRUE on success, FALSE on failure
78*/
79static gboolean init_tag(TMTag *tag, TMSourceFile *file, const tagEntryInfo *tag_entry)
80{
81 TMTagType type;
82 guchar kind_letter;
83 TMParserType lang;
84
85 if (!tag_entry)
86 return FALSE;
87
88 lang = tag_entry->langType;
89 kind_letter = getLanguageKind(tag_entry->langType, tag_entry->kindIndex)->letter;
90 type = tm_parser_get_tag_type(kind_letter, lang);
91 if (file->lang != lang) /* this is a tag from a subparser */
92 {
93 /* check for possible re-definition of subparser type */
94 type = tm_parser_get_subparser_type(file->lang, lang, type);
95 }
96
97 if (!tag_entry->name || type == tm_tag_undef_t)
98 return FALSE;
99
100 tag->name = g_strdup(tag_entry->name);
101 tag->type = type;
102 tag->local = tag_entry->isFileScope;
103 tag->pointerOrder = 0; /* backward compatibility (use var_type instead) */
104 tag->line = tag_entry->lineNumber;
105 if (NULL != tag_entry->extensionFields.signature)
106 tag->arglist = g_strdup(tag_entry->extensionFields.signature);
107 if ((NULL != tag_entry->extensionFields.scopeName) &&
108 (0 != tag_entry->extensionFields.scopeName[0]))
109 tag->scope = g_strdup(tag_entry->extensionFields.scopeName);
110 if (tag_entry->extensionFields.inheritance != NULL)
111 tag->inheritance = g_strdup(tag_entry->extensionFields.inheritance);
112 if (tag_entry->extensionFields.typeRef[1] != NULL)
113 tag->var_type = g_strdup(tag_entry->extensionFields.typeRef[1]);
114 if (tag_entry->extensionFields.access != NULL)
116 if (tag_entry->extensionFields.implementation != NULL)
118 if ((tm_tag_macro_t == tag->type) && (NULL != tag->arglist))
120 tag->file = file;
121 /* redefine lang also for subparsers because the rest of Geany assumes that
122 * tags from a single file are from a single language */
123 tag->lang = file->lang;
124 return TRUE;
125}
126
127
128/* add argument list of __init__() Python methods to the class tag */
129static void update_python_arglist(const TMTag *tag, TMSourceFile *source_file)
130{
131 guint i;
132 const gchar *parent_tag_name;
133
134 if (tag->type != tm_tag_method_t || tag->scope == NULL ||
135 g_strcmp0(tag->name, "__init__") != 0)
136 return;
137
138 parent_tag_name = strrchr(tag->scope, '.');
139 if (parent_tag_name)
140 parent_tag_name++;
141 else
142 parent_tag_name = tag->scope;
143
144 /* going in reverse order because the tag was added recently */
145 for (i = source_file->tags_array->len; i > 0; i--)
146 {
147 TMTag *prev_tag = (TMTag *) source_file->tags_array->pdata[i - 1];
148 if (g_strcmp0(prev_tag->name, parent_tag_name) == 0)
149 {
150 g_free(prev_tag->arglist);
151 prev_tag->arglist = g_strdup(tag->arglist);
152 break;
153 }
154 }
155}
156
157
158static gint write_entry(tagWriter *writer, MIO * mio, const tagEntryInfo *const tag, void *user_data)
159{
160 TMSourceFile *source_file = user_data;
161 TMTag *tm_tag = tm_tag_new();
162
164
165 if (!init_tag(tm_tag, source_file, tag))
166 {
167 tm_tag_unref(tm_tag);
168 return 0;
169 }
170
171 if (tm_tag->lang == TM_PARSER_PYTHON)
172 update_python_arglist(tm_tag, source_file);
173
174 g_ptr_array_add(source_file->tags_array, tm_tag);
175
176 /* output length - we don't write anything to the MIO */
177 return 0;
178}
179
180
181static void rescan_failed(tagWriter *writer, gulong valid_tag_num, void *user_data)
182{
183 TMSourceFile *source_file = user_data;
184 GPtrArray *tags_array = source_file->tags_array;
185
186 if (tags_array->len > valid_tag_num)
187 {
188 guint i;
189 for (i = valid_tag_num; i < tags_array->len; i++)
190 tm_tag_unref(tags_array->pdata[i]);
191 g_ptr_array_set_size(tags_array, valid_tag_num);
192 }
193}
194
195
196/* keep in sync with ctags main() - use only things interesting for us */
198{
200
203
204 checkRegex();
207
209 initOptions();
210
211 /* make sure all parsers are initialized */
213
214 /* change default values which are false */
217
218 /* some kinds we are interested in are disabled by default */
220}
221
222
223void tm_ctags_parse(guchar *buffer, gsize buffer_size,
224 const gchar *file_name, TMParserType language, TMSourceFile *source_file)
225{
226 g_return_if_fail(buffer != NULL || file_name != NULL);
227
228 parseRawBuffer(file_name, buffer, buffer_size, language, source_file);
229}
230
231
233{
234 return getLanguageName(lang);
235}
236
237
239{
240 return getNamedLanguage(name, 0);
241}
242
243
245{
246 guint kind_num = countLanguageKinds(lang);
247 static gchar kinds[257];
248 guint i;
249
250 for (i = 0; i < kind_num; i++)
251 kinds[i] = getLanguageKind(lang, i)->letter;
252 kinds[i] = '\0';
253
254 return kinds;
255}
256
257
258const gchar *tm_ctags_get_kind_name(gchar kind, TMParserType lang)
259{
260 kindDefinition *def = getLanguageKindForLetter(lang, kind);
261 return def ? def->name : "unknown";
262}
263
264
266{
268 return def ? def->letter : '-';
269}
270
271
273{
274 return countParsers();
275}
const gchar * name
Definition: document.c:3219
void getTagScopeInformation(tagEntryInfo *const tag, const char **kind, const char **name)
Definition: entry.c:803
void setErrorPrinter(errorPrintFunc printer, void *data)
Definition: error.c:27
void initFieldObjects(void)
Definition: field.c:237
#define CTAGS_ATTR_UNUSED
Definition: gcc-attr.h:22
CobolFormat format
Definition: geany_cobol.c:137
void enableKind(kindDefinition *kind, bool enable)
Definition: kind.c:70
bool checkRegex(void)
Definition: lregex.c:2768
void initOptions(void)
Definition: options.c:3804
langType getNamedLanguage(const char *const name, size_t len)
Definition: parse.c:406
unsigned int countParsers(void)
Definition: parse.c:177
kindDefinition * getLanguageKind(const langType language, int kindIndex)
Definition: parse.c:317
void initializeParsing(void)
Definition: parse.c:1907
const char * getLanguageName(const langType language)
Definition: parse.c:284
void initializeParser(langType lang)
Definition: parse.c:1850
kindDefinition * getLanguageKindForLetter(const langType language, char kindLetter)
Definition: parse.c:338
bool parseRawBuffer(const char *fileName, unsigned char *buffer, size_t bufferSize, const langType language, void *clientData)
Definition: parse.c:4158
kindDefinition * getLanguageKindForName(const langType language, const char *kindName)
Definition: parse.c:349
unsigned int countLanguageKinds(const langType language)
Definition: parse.c:307
#define LANG_AUTO
Definition: parse.h:26
#define NULL
Definition: rbtree.h:150
int errorSelection
Definition: routines.h:36
if(!stash_group_load_from_file(group, filename)) g_warning(_("Could not load keyfile %s!")
The TMSourceFile structure represents the source file and its tags in the tag manager.
TMParserType lang
GPtrArray * tags_array
Sorted tag array obtained by parsing the object.
The TMTag structure represents a single tag in the tag manager.
Definition: tm_tag.h:88
char * scope
Scope of tag.
Definition: tm_tag.h:99
char * inheritance
Parent classes.
Definition: tm_tag.h:100
char * var_type
Variable type (maps to struct for typedefs)
Definition: tm_tag.h:101
char * arglist
Argument list (functions/prototypes/macros)
Definition: tm_tag.h:98
TMSourceFile * file
These are tag attributes.
Definition: tm_tag.h:94
TMTagType type
Tag Type.
Definition: tm_tag.h:90
gulong line
Line number of the tag.
Definition: tm_tag.h:95
char * name
Name of tag.
Definition: tm_tag.h:89
char access
Access type (public/protected/private/etc.)
Definition: tm_tag.h:102
TMParserType lang
Definition: tm_tag.h:104
guint pointerOrder
Definition: tm_tag.h:97
char impl
Implementation (e.g.
Definition: tm_tag.h:103
gboolean local
Is the tag of local scope.
Definition: tm_tag.h:96
MIO:
Definition: mio.c:136
char letter
Definition: kind.h:73
char * name
Definition: kind.h:74
struct sTagEntryInfo::@3 extensionFields
const char * implementation
Definition: entry.h:71
const char * name
Definition: entry.h:63
unsigned int isFileScope
Definition: entry.h:45
const char * access
Definition: entry.h:69
unsigned long lineNumber
Definition: entry.h:56
int kindIndex
Definition: entry.h:64
langType langType
Definition: entry.h:61
const char * typeRef[2]
Definition: entry.h:88
const char * inheritance
Definition: entry.h:72
const char * signature
Definition: entry.h:85
const char * scopeName
Definition: entry.h:79
int(* writeEntry)(tagWriter *writer, MIO *mio, const tagEntryInfo *const tag, void *clientData)
Definition: writer_p.h:36
static void update_python_arglist(const TMTag *tag, TMSourceFile *source_file)
Definition: tm_ctags.c:129
static bool nonfatal_error_printer(const errorSelection selection, const gchar *const format, va_list ap, void *data)
Definition: tm_ctags.c:42
gchar tm_ctags_get_kind_from_name(const gchar *name, TMParserType lang)
Definition: tm_ctags.c:265
const gchar * tm_ctags_get_kind_name(gchar kind, TMParserType lang)
Definition: tm_ctags.c:258
void tm_ctags_init(void)
Definition: tm_ctags.c:197
static gint write_entry(tagWriter *writer, MIO *mio, const tagEntryInfo *const tag, void *user_data)
Definition: tm_ctags.c:158
tagWriter geanyWriter
Definition: tm_ctags.c:29
static void rescan_failed(tagWriter *writer, gulong valid_tag_num, void *user_data)
Definition: tm_ctags.c:181
guint tm_ctags_get_lang_count(void)
Definition: tm_ctags.c:272
void tm_ctags_parse(guchar *buffer, gsize buffer_size, const gchar *file_name, TMParserType language, TMSourceFile *source_file)
Definition: tm_ctags.c:223
const gchar * tm_ctags_get_lang_kinds(TMParserType lang)
Definition: tm_ctags.c:244
const gchar * tm_ctags_get_lang_name(TMParserType lang)
Definition: tm_ctags.c:232
static gboolean init_tag(TMTag *tag, TMSourceFile *file, const tagEntryInfo *tag_entry)
Definition: tm_ctags.c:79
static void enable_all_lang_kinds()
Definition: tm_ctags.c:52
TMParserType tm_ctags_get_named_lang(const gchar *name)
Definition: tm_ctags.c:238
TMTagType tm_parser_get_subparser_type(TMParserType lang, TMParserType sublang, TMTagType type)
Definition: tm_parser.c:673
TMTagType tm_parser_get_tag_type(gchar kind, TMParserType lang)
Definition: tm_parser.c:613
TMTagType
Types of tags.
Definition: tm_parser.h:23
@ tm_tag_undef_t
Unknown type.
Definition: tm_parser.h:24
@ tm_tag_method_t
Class method (Java only)
Definition: tm_parser.h:32
@ tm_tag_macro_with_arg_t
Parameterized macro.
Definition: tm_parser.h:42
@ tm_tag_macro_t
Macro (without arguments)
Definition: tm_parser.h:41
gint TMParserType
Definition: tm_parser.h:52
gchar tm_source_file_get_tag_access(const gchar *access)
gchar tm_source_file_get_tag_impl(const gchar *impl)
TMTag * tm_tag_new(void)
Definition: tm_tag.c:106
void tm_tag_unref(TMTag *tag)
Definition: tm_tag.c:136
void initDefaultTrashBox(void)
Definition: trashbox.c:169
static tagWriter * writer
Definition: writer.c:32
void setTagWriter(writerType wtype, tagWriter *customWriter)
Definition: writer.c:34
@ WRITER_CUSTOM
Definition: writer_p.h:29
bool enableXtag(xtagType type, bool state)
Definition: xtag.c:259
void initXtagObjects(void)
Definition: xtag.c:308
@ XTAG_REFERENCE_TAGS
Definition: xtag.h:32
@ XTAG_TAGS_GENERATED_BY_GUEST_PARSERS
Definition: xtag.h:34