Update to version p5.9.20211031.0 of ctags
[geany-mirror.git] / ctags / main / xtag.c
blob4e3e60cc8000af300e8006900e1b9641355c3491
1 /*
3 * Copyright (c) 2015, Red Hat, Inc.
4 * Copyright (c) 2015, Masatake YAMATO
6 * Author: Masatake YAMATO <yamato@redhat.com>
8 * This source code is released for free distribution under the terms of the
9 * GNU General Public License version 2 or (at your option) any later version.
13 #include "general.h" /* must always come first */
14 #include "ctags.h"
15 #include "debug.h"
16 #include "options.h"
17 #include "options_p.h"
18 #include "parse_p.h"
19 #include "routines.h"
20 #include "trashbox.h"
21 #include "writer_p.h"
22 #include "xtag.h"
23 #include "xtag_p.h"
25 #include <string.h>
26 #include <ctype.h>
28 typedef struct sXtagObject {
29 xtagDefinition *def;
30 langType language;
31 xtagType sibling;
32 } xtagObject;
34 static bool isPseudoTagsEnabled (xtagDefinition *pdef CTAGS_ATTR_UNUSED)
36 if (!writerCanPrintPtag())
37 return false;
38 if (!writerPrintPtagByDefault())
39 return false;
41 return ! isDestinationStdout ();
44 static bool isPseudoTagsFixed (xtagDefinition *pdef CTAGS_ATTR_UNUSED)
46 if (!writerCanPrintPtag())
47 return true;
48 else
49 return false;
52 static void enableFileKind (xtagDefinition *pdef, bool state)
54 enableDefaultFileKind(state);
55 pdef->enabled = state;
58 static xtagDefinition xtagDefinitions [] = {
59 { true, 'F', "fileScope",
60 "Include tags of file scope" },
61 { false, 'f', "inputFile",
62 "Include an entry for the base file name of every input file",
63 NULL,
64 NULL,
65 enableFileKind},
66 { false, 'p', "pseudo",
67 "Include pseudo tags",
68 isPseudoTagsEnabled,
69 isPseudoTagsFixed},
70 { false, 'q', "qualified",
71 "Include an extra class-qualified tag entry for each tag"},
72 { false, 'r', "reference",
73 "Include reference tags"},
74 { false, 'g', "guest",
75 "Include tags generated by guest parsers"},
76 { true, 's', "subparser",
77 "Include tags generated by subparsers"},
78 { true, '\0', "anonymous",
79 "Include tags for non-named objects like lambda"},
82 static unsigned int xtagObjectUsed;
83 static unsigned int xtagObjectAllocated;
84 static xtagObject* xtagObjects;
86 static xtagObject* getXtagObject (xtagType type)
88 Assert ((0 <= type) && ((unsigned int)type < xtagObjectUsed));
89 return (xtagObjects + type);
92 extern xtagDefinition* getXtagDefinition (xtagType type)
94 Assert ((0 <= type) && ((unsigned int)type < xtagObjectUsed));
96 return getXtagObject (type)->def;
99 typedef bool (* xtagPredicate) (xtagObject *pobj, langType language, const void *user_data);
100 static xtagType getXtagTypeGeneric (xtagPredicate predicate, langType language, const void *user_data)
102 static bool initialized = false;
103 unsigned int i;
105 if (language == LANG_AUTO && (initialized == false))
107 initialized = true;
108 initializeParser (LANG_AUTO);
110 else if (language != LANG_IGNORE && (initialized == false))
111 initializeParser (language);
113 for (i = 0; i < xtagObjectUsed; i++)
115 if (predicate (xtagObjects + i, language, user_data))
116 return i;
118 return XTAG_UNKNOWN;
121 static bool xtagEqualByLetter (xtagObject *pobj, langType language CTAGS_ATTR_UNUSED,
122 const void *user_data)
124 return (pobj->def->letter == *((char *)user_data))? true: false;
127 extern xtagType getXtagTypeForLetter (char letter)
129 return getXtagTypeGeneric (xtagEqualByLetter, LANG_IGNORE, &letter);
132 static bool xtagEqualByNameAndLanguage (xtagObject *pobj, langType language, const void *user_data)
134 const char* name = user_data;
136 if ((language == LANG_AUTO || pobj->language == language)
137 && (strcmp (pobj->def->name, name) == 0))
138 return true;
139 else
140 return false;
143 extern xtagType getXtagTypeForNameAndLanguage (const char *name, langType language)
145 return getXtagTypeGeneric (xtagEqualByNameAndLanguage, language, name);
148 extern struct colprintTable * xtagColprintTableNew (void)
150 return colprintTableNew ("L:LETTER", "L:NAME", "L:ENABLED",
151 "L:LANGUAGE", "L:FIXED", "L:DESCRIPTION", NULL);
154 static void xtagColprintAddLine (struct colprintTable *table, int xtype)
156 xtagObject* xobj = getXtagObject (xtype);
157 xtagDefinition *xdef = xobj->def;
159 struct colprintLine *line = colprintTableGetNewLine(table);
161 colprintLineAppendColumnChar (line,
162 (xdef->letter == NUL_XTAG_LETTER)
163 ? '-'
164 : xdef->letter);
165 colprintLineAppendColumnCString (line, xdef->name);
166 colprintLineAppendColumnBool (line, isXtagEnabled(xdef->xtype));
167 colprintLineAppendColumnCString (line,
168 xobj->language == LANG_IGNORE
169 ? RSV_NONE
170 : getLanguageName (xobj->language));
171 colprintLineAppendColumnBool (line, isXtagFixed(xdef->xtype));
172 colprintLineAppendColumnCString (line, xdef->description);
175 extern void xtagColprintAddCommonLines (struct colprintTable *table)
177 for (int i = 0; i < XTAG_COUNT; i++)
178 xtagColprintAddLine (table, i);
181 extern void xtagColprintAddLanguageLines (struct colprintTable *table, langType language)
183 for (unsigned int i = XTAG_COUNT; i < xtagObjectUsed; i++)
185 xtagObject* xobj = getXtagObject (i);
187 if (xobj->language == language)
188 xtagColprintAddLine (table, i);
192 static int xtagColprintCompareLines (struct colprintLine *a , struct colprintLine *b)
194 const char *a_parser = colprintLineGetColumn (a, 3);
195 const char *b_parser = colprintLineGetColumn (b, 3);
197 if (strcmp (a_parser, RSV_NONE) == 0
198 && strcmp (b_parser, RSV_NONE) != 0)
199 return -1;
200 else if (strcmp (a_parser, RSV_NONE) != 0
201 && strcmp (b_parser, RSV_NONE) == 0)
202 return 1;
203 else if (strcmp (a_parser, RSV_NONE) != 0
204 && strcmp (b_parser, RSV_NONE) != 0)
206 int r;
207 r = strcmp (a_parser, b_parser);
208 if (r != 0)
209 return r;
211 else
213 int r;
215 const char *a_letter = colprintLineGetColumn (a, 0);
216 const char *b_letter = colprintLineGetColumn (b, 0);
217 r = strcmp(a_letter, b_letter);
218 if (r != 0)
219 return r;
222 const char *a_name = colprintLineGetColumn (a, 1);
223 const char *b_name = colprintLineGetColumn (b, 1);
225 return strcmp(a_name, b_name);
228 extern void xtagColprintTablePrint (struct colprintTable *table,
229 bool withListHeader, bool machinable, FILE *fp)
231 colprintTableSort (table, xtagColprintCompareLines);
232 colprintTablePrint (table, 0, withListHeader, machinable, fp);
235 extern bool isXtagEnabled (xtagType type)
237 xtagDefinition* def = getXtagDefinition (type);
239 Assert (def);
241 if (def->isEnabled)
242 return def->isEnabled (def);
243 else
244 return def->enabled;
247 extern bool isXtagFixed (xtagType type)
249 xtagDefinition* def = getXtagDefinition (type);
251 Assert (def);
253 if (def->isFixed)
254 return def->isFixed (def);
256 return false;
259 extern bool enableXtag (xtagType type, bool state)
261 bool old;
262 xtagDefinition* def = getXtagDefinition (type);
264 Assert (def);
266 old = isXtagEnabled (type);
268 if (isXtagFixed(type))
269 def->enabled = old;
270 else if (def->enable)
271 def->enable (def, state);
272 else
273 def->enabled = state;
275 def->isEnabled = NULL;
277 return old;
280 extern bool isCommonXtag (xtagType type)
282 return (type < XTAG_COUNT)? true: false;
285 extern langType getXtagOwner (xtagType type)
287 return getXtagObject (type)->language;
290 extern const char* getXtagName (xtagType type)
292 xtagDefinition* def = getXtagDefinition (type);
293 if (def)
294 return def->name;
295 else
296 return NULL;
299 extern const char* getXtagDescription (xtagType type)
301 xtagDefinition* def = getXtagDefinition (type);
302 if (def)
303 return def->description;
304 else
305 return NULL;
308 extern void initXtagObjects (void)
310 xtagObject *xobj;
312 xtagObjectAllocated = ARRAY_SIZE (xtagDefinitions);
313 xtagObjects = xMalloc (xtagObjectAllocated, xtagObject);
314 DEFAULT_TRASH_BOX(&xtagObjects, eFreeIndirect);
316 for (unsigned int i = 0; i < ARRAY_SIZE (xtagDefinitions); i++)
318 xobj = xtagObjects + i;
319 xobj->def = xtagDefinitions + i;
320 xobj->def->xtype = i;
321 xobj->language = LANG_IGNORE;
322 xobj->sibling = XTAG_UNKNOWN;
323 xtagObjectUsed++;
327 extern int countXtags (void)
329 return xtagObjectUsed;
332 static void updateSiblingXtag (xtagType type, const char* name)
334 int i;
335 xtagObject *xobj;
337 for (i = type; i > 0; i--)
339 xobj = xtagObjects + i - 1;
340 if (xobj->def->name && (strcmp (xobj->def->name, name) == 0))
342 Assert (xobj->sibling == XTAG_UNKNOWN);
343 xobj->sibling = type;
344 break;
349 extern int defineXtag (xtagDefinition *def, langType language)
351 xtagObject *xobj;
352 size_t i;
354 Assert (def);
355 Assert (def->name);
356 for (i = 0; i < strlen (def->name); i++)
358 Assert ( isalnum (def->name [i]) );
360 def->letter = NUL_XTAG_LETTER;
362 if (xtagObjectUsed == xtagObjectAllocated)
364 xtagObjectAllocated *= 2;
365 xtagObjects = xRealloc (xtagObjects, xtagObjectAllocated, xtagObject);
367 xobj = xtagObjects + (xtagObjectUsed);
368 def->xtype = xtagObjectUsed++;
369 xobj->def = def;
370 xobj->language = language;
371 xobj->sibling = XTAG_UNKNOWN;
373 updateSiblingXtag (def->xtype, def->name);
375 verbose ("Add extra[%d]: %s,%s in %s\n",
376 def->xtype,
377 def->name, def->description,
378 getLanguageName (language));
380 return def->xtype;
383 extern xtagType nextSiblingXtag (xtagType type)
385 xtagObject *xobj;
387 xobj = xtagObjects + type;
388 return xobj->sibling;