xref: /Universal-ctags/main/entry.h (revision aaaac7eeac8399141aa8e6d9e6ec0379931848b2)
1 /*
2 *   Copyright (c) 1998-2002, Darren Hiebert
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 *   External interface to entry.c
8 */
9 #ifndef CTAGS_MAIN_ENTRY_H
10 #define CTAGS_MAIN_ENTRY_H
11 
12 /*
13 *   INCLUDE FILES
14 */
15 #include "general.h"  /* must always come first */
16 #include "types.h"
17 
18 #include <stdint.h>
19 #include <time.h>
20 
21 #include "field.h"
22 #include "xtag.h"
23 #include "mio.h"
24 #include "ptrarray.h"
25 #include "nestlevel.h"
26 
27 /*
28 *   MACROS
29 */
30 
31 /*
32 *   DATA DECLARATIONS
33 */
34 typedef struct sTagField {
35 	fieldType  ftype;
36 	const char* value;
37 	bool valueOwner;			/* used only in parserFieldsDynamic */
38 } tagField;
39 
40 typedef uint64_t roleBitsType;
41 
42 /*  Information about the current tag candidate.
43  */
44 struct sTagEntryInfo {
45 	unsigned int lineNumberEntry:1;  /* pattern or line number entry */
46 	unsigned int isFileScope    :1;  /* is tag visible only within input file? */
47 	unsigned int isFileEntry    :1;  /* is this just an entry for a file name? */
48 	unsigned int truncateLineAfterTag :1;  /* truncate tag line at end of tag name? */
49 	unsigned int placeholder    :1;	 /* is used only for keeping corkIndex based scope chain.
50 					    Put this entry to cork queue but
51 					    don't print it to tags file. */
52 	unsigned int skipAutoFQEmission:1; /* If a parser makes a fq tag for the
53 										  current tag by itself, set this. */
54 	unsigned int isPseudoTag:1;	/* Used only in xref output.
55 								   If a tag is a pseudo, set this. */
56 	unsigned int inCorkQueue:1;
57 
58 	unsigned long lineNumber;     /* line number of tag */
59 	const char* pattern;	      /* pattern for locating input line
60 				       * (may be NULL if not present) *//*  */
61 	unsigned int boundaryInfo;    /* info about nested input stream */
62 	MIOPos      filePosition;     /* file position of line containing tag */
63 	langType langType;         /* language of input file */
64 	const char *inputFileName;   /* name of input file */
65 	const char *name;             /* name of the tag */
66 	int kindIndex;	      /* kind descriptor */
67 	uint8_t extra[ ((XTAG_COUNT) / 8) + 1 ];
68 	uint8_t *extraDynamic;		/* Dynamically allocated but freed by per parser TrashBox */
69 
70 	struct {
71 		const char* access;
72 		const char* implementation;
73 		const char* inheritance;
74 
75 		/* Which scopeKindIndex belong to. If the value is LANG_AUTO,
76 		   the value for langType field of this structure is used as default value.
77 		   LANG_AUTO is set automatically in initTagEntryInfo. */
78 		langType    scopeLangType;
79 		int         scopeKindIndex;
80 		const char* scopeName;
81 		int         scopeIndex;   /* cork queue entry for upper scope tag.
82 					     This field is meaningful if the value
83 					     is not CORK_NIL and scope[0]  and scope[1] are
84 					     NULL. */
85 
86 		const char* signature;
87 
88 		/* type (union/struct/etc.) and name for a variable or typedef. */
89 		const char* typeRef [2];  /* e.g., "struct" and struct name */
90 
91 #define ROLE_DEFINITION_INDEX -1
92 #define ROLE_DEFINITION_NAME "def"
93 #define ROLE_MAX_COUNT (sizeof(roleBitsType) * 8)
94 		roleBitsType roleBits; /* for role of reference tag */
95 
96 #ifdef HAVE_LIBXML
97 		const char* xpath;
98 #endif
99 		unsigned long endLine;
100 		time_t epoch;
101 #define NO_NTH_FIELD -1
102 		short nth;
103 	} extensionFields;  /* list of extension fields*/
104 
105 	/* `usedParserFields' tracks how many parser own fields are
106 	   used. If it is a few (less than PRE_ALLOCATED_PARSER_FIELDS),
107 	   statically allocated parserFields is used. If more fields than
108 	   PRE_ALLOCATED_PARSER_FIELDS is defined and attached, parserFieldsDynamic
109 	   is used. */
110 	unsigned int usedParserFields;
111 #define PRE_ALLOCATED_PARSER_FIELDS 5
112 #define NO_PARSER_FIELD -1
113 	tagField     parserFields [PRE_ALLOCATED_PARSER_FIELDS];
114 	ptrArray *   parserFieldsDynamic;
115 
116 	/* Following source* fields are used only when #line is found
117 	   in input and --line-directive is given in ctags command line. */
118 	langType sourceLangType;
119 	const char *sourceFileName;
120 	unsigned long sourceLineNumberDifference;
121 };
122 
123 typedef bool (* entryForeachFunc) (int corkIndex,
124 								   tagEntryInfo * entry,
125 								   void * data);
126 
127 /*
128 *   GLOBAL VARIABLES
129 */
130 
131 
132 /*
133 *   FUNCTION PROTOTYPES
134 */
135 extern int makeTagEntry (const tagEntryInfo *const tag);
136 extern void initTagEntry (tagEntryInfo *const e, const char *const name,
137 			  int kindIndex);
138 extern void initRefTagEntry (tagEntryInfo *const e, const char *const name,
139 			     int kindIndex, int roleIndex);
140 
141 /* initForeignRefTagEntry() is for making a tag for the language X when parsing
142  * source code of Y language.
143  * From the view point of the language Y, we call the language X a foreign
144  * language.
145  *
146  * When making a tag for a foreign with this function, you must declare the
147  * language X in the parser of Y with DEPTYPE_FOREIGNER dependency.
148  */
149 extern void initForeignTagEntry (tagEntryInfo *const e, const char *const name,
150 								 langType type,
151 								 int kindIndex);
152 extern void initForeignRefTagEntry (tagEntryInfo *const e, const char *const name,
153 									langType type,
154 									int kindIndex, int roleIndex);
155 extern void assignRole(tagEntryInfo *const e, int roleIndex);
156 extern bool isRoleAssigned(const tagEntryInfo *const e, int roleIndex);
157 
158 extern int makeQualifiedTagEntry (const tagEntryInfo *const e);
159 
160 extern void setTagPositionFromTag (tagEntryInfo *const dst, const tagEntryInfo *const src);
161 
162 #define CORK_NIL 0
163 tagEntryInfo *getEntryInCorkQueue   (int n);
164 tagEntryInfo *getEntryOfNestingLevel (const NestingLevel *nl);
165 size_t        countEntryInCorkQueue (void);
166 
167 /* If a parser sets (CORK_QUEUE and )CORK_SYMTAB to useCork,
168  * the parsesr can use symbol lookup tables for the current input.
169  * Each scope has a symbol lookup table.
170  * To register an tag to the table, use registerEntry().
171  * registerEntry registers CORKINDEX to a symbol table of a parent tag
172  * specified in the scopeIndex field of the tag specified with CORKINDEX.
173  */
174 void          registerEntry (int corkIndex);
175 void        unregisterEntry (int corkIndex);
176 
177 /* foreachEntriesInScope is for traversing the symbol table for a table
178  * specified with CORKINDEX. If CORK_NIL is given, this function traverses
179  * top-level entries. If name is NULL, this function traverses all entries
180  * under the scope.
181  *
182  * If FUNC returns false, this function returns false immediately
183  * even if more entires in the scope.
184  * If FUNC never returns false, this function returns true.
185  * If FUNC is not called because no node for NAME in the symbol table,
186  * this function returns true.
187  */
188 bool          foreachEntriesInScope (int corkIndex,
189 									 const char *name, /* or NULL */
190 									 entryForeachFunc func,
191 									 void *data);
192 
193 /* Return the cork index for NAME in the scope specified with CORKINDEX.
194  * Even if more than one entries for NAME are in the scope, this function
195  * just returns one of them. Returning CORK_NIL means there is no entry
196  * for NAME.
197  */
198 int           anyEntryInScope       (int corkIndex,
199 									 const char *name,
200 									 bool onlyDefinitionTag);
201 
202 int           anyKindEntryInScope (int corkIndex,
203 								   const char *name, int kind,
204 								   bool onlyDefinitionTag);
205 
206 int           anyKindsEntryInScope (int corkIndex,
207 									const char *name,
208 									const int * kinds, int count,
209 									bool onlyDefinitionTag);
210 
211 int           anyKindsEntryInScopeRecursive (int corkIndex,
212 											 const char *name,
213 											 const int * kinds, int count,
214 											 bool onlyDefinitionTag);
215 
216 extern void    markTagExtraBit     (tagEntryInfo *const tag, xtagType extra);
217 extern void    unmarkTagExtraBit   (tagEntryInfo *const tag, xtagType extra);
218 extern bool isTagExtraBitMarked (const tagEntryInfo *const tag, xtagType extra);
219 
220 /* If any extra bit is on, return true. */
221 extern bool isTagExtra (const tagEntryInfo *const tag);
222 
223 /* Functions for attaching parser specific fields
224  *
225  * Which function you should use?
226  * ------------------------------
227  * Case A:
228  *
229  * If your parser uses the Cork API, and your parser called
230  * makeTagEntry () already, you can use both
231  * attachParserFieldToCorkEntry () and attachParserField ().  Your
232  * parser has the cork index returned from makeTagEntry ().  With the
233  * cork index, your parser can call attachParserFieldToCorkEntry ().
234  * If your parser already call getEntryInCorkQueue () to get the tag
235  * entry for the cork index, your parser can call attachParserField ()
236  * with passing true for `inCorkQueue' parameter. attachParserField ()
237  * is a bit faster than attachParserFieldToCorkEntry ().
238  *
239  * attachParserField () and attachParserFieldToCorkEntry () duplicates
240  * the memory object specified with `value' and stores the duplicated
241  * object to the entry on the cork queue. So the parser must/can free
242  * the original one passed to the functions after calling. The cork
243  * queue manages the life of the duplicated object. It is not the
244  * parser's concern.
245  *
246  *
247  * Case B:
248  *
249  * If your parser called one of initTagEntry () family but didn't call
250  * makeTagEntry () for a tagEntry yet, use attachParserField () with
251  * false for `inCorkQueue' whether your parser uses the Cork API or
252  * not.
253  *
254  * The parser (== caller) keeps the memory object specified with `value'
255  * till calling makeTagEntry (). The parser must free the memory object
256  * after calling makeTagEntry () if it is allocated dynamically in the
257  * parser side.
258  *
259  * Interpretation of VALUE
260  * -----------------------
261  * For FIELDTYPE_STRING:
262  * Both json writer and xref writer prints it as-is.
263  *
264  * For FIELDTYPE_STRING|FIELDTYPE_BOOL:
265  * If VALUE points "" (empty C string), the json writer prints it as
266  * false, and the xref writer prints it as -.
267  * If VALUE points a non-empty C string, Both json writer and xref
268  * writer print it as-is.
269  *
270  * For FIELDTYPE_BOOL
271  * The json writer always prints true.
272  * The xref writer always prints the name of field.
273  * Set "" explicitly though the value pointed by VALUE is not referred,
274  *
275  *
276  * The other data type and the combination of types are not implemented yet.
277  *
278  */
279 extern void attachParserField (tagEntryInfo *const tag, bool inCorkQueue, fieldType ftype, const char* value);
280 extern void attachParserFieldToCorkEntry (int index, fieldType ftype, const char* value);
281 extern const char* getParserFieldValueForType (tagEntryInfo *const tag, fieldType ftype);
282 
283 extern int makePlaceholder (const char *const name);
284 extern void markTagPlaceholder (tagEntryInfo *e, bool placeholder);
285 
286 /* Marking all tag entries entries under the scope specified
287  * with index recursively.
288  *
289  * The parser calling this function enables CORK_SYMTAB.
290  * Entries to be marked must be registered to the scope
291  * specified with index or its descendant scopes with
292  * registerEntry ().
293  *
294  * Call makePlaceholder () at the start of your parser for
295  * making the root scope where the entries are registered.
296  */
297 extern void markAllEntriesInScopeAsPlaceholder (int index);
298 
299 #endif  /* CTAGS_MAIN_ENTRY_H */
300