File: entry.h

package info (click to toggle)
universal-ctags 6.2.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 37,612 kB
  • sloc: ansic: 158,498; sh: 8,621; lisp: 7,742; vhdl: 6,518; cpp: 2,583; perl: 2,578; python: 2,324; javascript: 2,054; cs: 1,193; lex: 1,015; sql: 897; makefile: 787; ruby: 764; php: 755; cobol: 741; f90: 566; ada: 559; asm: 509; yacc: 465; fortran: 412; xml: 405; objc: 289; tcl: 280; java: 173; erlang: 65; pascal: 58; ml: 49; awk: 44; haskell: 42
file content (376 lines) | stat: -rw-r--r-- 13,950 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
/*
*   Copyright (c) 1998-2002, Darren Hiebert
*
*   This source code is released for free distribution under the terms of the
*   GNU General Public License version 2 or (at your option) any later version.
*
*   External interface to entry.c
*/
#ifndef CTAGS_MAIN_ENTRY_H
#define CTAGS_MAIN_ENTRY_H

/*
*   INCLUDE FILES
*/
#include "general.h"  /* must always come first */
#include "types.h"

#include <stdint.h>
#include <time.h>

#include "field.h"
#include "xtag.h"
#include "mio.h"
#include "ptrarray.h"
#include "nestlevel.h"

/*
*   MACROS
*/

/*
*   DATA DECLARATIONS
*/
typedef struct sTagField {
	fieldType  ftype;
	const char* value;
	bool valueOwner;			/* used only in parserFieldsDynamic */
} tagField;

typedef uint64_t roleBitsType;

/*  Information about the current tag candidate.
 */
struct sTagEntryInfo {
	/*
	 * the bit fields parsers may access for setting DIRECTLY
	 */
	unsigned int lineNumberEntry:1;  /* pattern or line number entry */
	unsigned int isFileScope    :1;  /* is tag visible only within input file? */
	unsigned int truncateLineAfterTag :1;  /* truncate tag line at end of tag name? */
	unsigned int skipAutoFQEmission:1; /* If a parser makes a fq tag for the
										  current tag by itself, set this. */

	/*
	 * the bit fields parser may access for setting via accessor
	 */
	unsigned int placeholder    :1;	 /* is used only for keeping corkIndex based scope chain.
					    Put this entry to cork queue but
						the tag is not printed:
						* not printed as a tag entry,
						* never used as a part of automatically generated FQ tag, and
						* not printed as a part of scope.
						See getTagScopeInformation() and
						getFullQualifiedScopeNameFromCorkQueue. */

	/*
	 * the bit fields only the main part can access.
	 */
	unsigned int isFileEntry    :1;  /* is this just an entry for a file name? */
	unsigned int isPseudoTag:1;	/* Used only in xref output.
								   If a tag is a pseudo, set this. */
	unsigned int inCorkQueue:1;
	unsigned int isInputFileNameShared: 1; /* shares the value for inputFileName.
											* Set in the cork queue; don't touch this.*/
	unsigned int isSourceFileNameShared: 1; /* shares the value for sourceFileName.
											 * Set in the cork queue; don't touch this.*/
	unsigned int boundaryInfo: 2; /* info about the stacked input area */
	unsigned int inIntevalTab:1;
	unsigned int allowNullTag:1;	/* allow a tag with an empty string.
									 * To allow your parser to emit null tags without
									 * setting this per-entry allowNullTag,
									 * set parserDefinition::allowNullTag instead.
									 *
									 * Set this member before calling makeTagEntry.
									 */

	unsigned long lineNumber;     /* line number of tag;
									 use updateTagLine() for updating this member. */
	const char* pattern;	      /* pattern for locating input line
				       * (may be NULL if not present) *//*  */
	MIOPos      filePosition;     /* file position of line containing tag */
	langType langType;         /* language of input file */
	const char *inputFileName;   /* name of input file.
									You cannot modify the contents of buffer pointed
									by this member of the tagEntryInfo returned from
									getEntryInCorkQueue(). The buffer may be shared
									between tag entries in the cork queue.

									Further more, modifying this member of the
									tagEntryInfo returned from getEntryInCorkQueue()
									may cause a memory leak. */
	const char *name;             /* name of the tag */
	int kindIndex;	      /* kind descriptor */
	uint8_t extra[ ((XTAG_COUNT) / 8) + 1 ];
	uint8_t *extraDynamic;		/* Dynamically allocated but freed by per parser TrashBox */

	struct {
		const char* access;
		const char* implementation;
		const char* inheritance;

		/* Which scopeKindIndex belong to. If the value is LANG_AUTO,
		   the value for langType field of this structure is used as default value.
		   LANG_AUTO is set automatically in initTagEntryInfo. */
		langType    scopeLangType;
		int         scopeKindIndex;
		const char* scopeName;
		int         scopeIndex;   /* cork queue entry for upper scope tag.
					     This field is meaningful if the value
					     is not CORK_NIL, scopeKindIndex is KIND_GHOST_INDEX,
					     and scopeName is NULL.
					     CXX parser violates this rule; see the comment inside
					     cxxTagBegin(). */

		const char* signature;

		/* type (union/struct/etc.) and name for a variable or typedef. */
		const char* typeRef [2];  /* e.g., "struct" and struct name */

#define ROLE_DEFINITION_INDEX -1
#define ROLE_DEFINITION_NAME "def"
#define ROLE_MAX_COUNT (sizeof(roleBitsType) * 8)
		roleBitsType roleBits; /* for role of reference tag */

#ifdef HAVE_LIBXML
		const char* xpath;
#endif
		unsigned long _endLine;	/* Don't set directly. Use setTagEndLine() and getTagEndLine() */
		time_t epoch;
#define NO_NTH_FIELD -1
		short nth;
	} extensionFields;  /* list of extension fields*/

	/* `usedParserFields' tracks how many parser specific fields are
	   used. If it is a few (less than PRE_ALLOCATED_PARSER_FIELDS),
	   statically allocated parserFields is used. If more fields than
	   PRE_ALLOCATED_PARSER_FIELDS is defined and attached, parserFieldsDynamic
	   is used. */
	unsigned int usedParserFields;
#define PRE_ALLOCATED_PARSER_FIELDS 5
#define NO_PARSER_FIELD -1
	tagField     parserFields [PRE_ALLOCATED_PARSER_FIELDS];
	ptrArray *   parserFieldsDynamic;

	/* Following source* fields are used only when #line is found
	   in input and --line-directive is given in ctags command line. */
	langType sourceLangType;
	const char *sourceFileName;
	unsigned long sourceLineNumberDifference;
};

typedef bool (* entryForeachFunc) (int corkIndex,
								   tagEntryInfo * entry,
								   void * data);

/*
*   GLOBAL VARIABLES
*/


/*
*   FUNCTION PROTOTYPES
*/
extern int makeTagEntry (tagEntryInfo *const tag);
extern void initTagEntry (tagEntryInfo *const e, const char *const name,
			  int kindIndex);
extern void initRefTagEntry (tagEntryInfo *const e, const char *const name,
			     int kindIndex, int roleIndex);

/* initForeignRefTagEntry() is for making a tag for the language X when parsing
 * source code of Y language.
 * From the view point of the language Y, we call the language X a foreign
 * language.
 *
 * When making a tag for a foreign with this function, you must declare the
 * language X in the parser of Y with DEPTYPE_FOREIGNER dependency.
 */
extern void initForeignTagEntry (tagEntryInfo *const e, const char *const name,
								 langType type,
								 int kindIndex);
extern void initForeignRefTagEntry (tagEntryInfo *const e, const char *const name,
									langType type,
									int kindIndex, int roleIndex);
extern void assignRole(tagEntryInfo *const e, int roleIndex);
#define clearRoles(E) assignRole((E), ROLE_DEFINITION_INDEX)
extern void unassignRole(tagEntryInfo *const e, int roleIndex);
extern bool isRoleAssigned(const tagEntryInfo *const e, int roleIndex);

extern int makeQualifiedTagEntry (const tagEntryInfo *const e);

extern void setTagPositionFromTag (tagEntryInfo *const dst, const tagEntryInfo *const src);

#define CORK_NIL 0
tagEntryInfo *getEntryInCorkQueue   (int n);
tagEntryInfo *getEntryOfNestingLevel (const NestingLevel *nl);
size_t        countEntryInCorkQueue (void);

/* If a parser sets (CORK_QUEUE and )CORK_SYMTAB to useCork,
 * the parsesr can use symbol lookup tables for the current input.
 * Each scope has a symbol lookup table.
 * To register an tag to the table, use registerEntry().
 * registerEntry registers CORKINDEX to a symbol table of a parent tag
 * specified in the scopeIndex field of the tag specified with CORKINDEX.
 */
void          registerEntry (int corkIndex);
void        unregisterEntry (int corkIndex);

/* foreachEntriesInScope is for traversing the symbol table for a table
 * specified with CORKINDEX. If CORK_NIL is given, this function traverses
 * top-level entries. If name is NULL, this function traverses all entries
 * under the scope.
 *
 * If FUNC returns false, this function returns false immediately
 * even if more entires in the scope.
 * If FUNC never returns false, this function returns true.
 * If FUNC is not called because no node for NAME in the symbol table,
 * this function returns true.
 */
bool          foreachEntriesInScope (int corkIndex,
									 const char *name, /* or NULL */
									 entryForeachFunc func,
									 void *data);

unsigned int countEntriesInScope    (int corkIndex, bool onlyDefinitionTag,
									 entryForeachFunc func, void *data);

/* Return the cork index for NAME in the scope specified with CORKINDEX.
 * Even if more than one entries for NAME are in the scope, this function
 * just returns one of them. Returning CORK_NIL means there is no entry
 * for NAME.
 */
int           anyEntryInScope       (int corkIndex,
									 const char *name,
									 bool onlyDefinitionTag);

int           anyKindEntryInScope (int corkIndex,
								   const char *name, int kind,
								   bool onlyDefinitionTag);

int           anyKindsEntryInScope (int corkIndex,
									const char *name,
									const int * kinds, int count,
									bool onlyDefinitionTag);

int           anyKindsEntryInScopeRecursive (int corkIndex,
											 const char *name,
											 const int * kinds, int count,
											 bool onlyDefinitionTag);

extern void    updateTagLine(tagEntryInfo *tag, unsigned long lineNumber, MIOPos filePosition);
extern void    setTagEndLine (tagEntryInfo *tag, unsigned long endLine);
extern void    setTagEndLineToCorkEntry (int corkIndex, unsigned long endLine);
#define getTagEndLine(tag) ((tag)->extensionFields._endLine)

extern int     queryIntervalTabByLine(unsigned long lineNum);
extern int     queryIntervalTabByRange(unsigned long startLine, unsigned long endLine);
extern int     queryIntervalTabByCorkEntry(int corkIndex);
extern bool    removeFromIntervalTabMaybe(int corkIndex);

extern void    markTagExtraBit     (tagEntryInfo *const tag, xtagType extra);
extern void    unmarkTagExtraBit   (tagEntryInfo *const tag, xtagType extra);
extern bool isTagExtraBitMarked (const tagEntryInfo *const tag, xtagType extra);

/* If any extra bit is on, return true. */
extern bool isTagExtra (const tagEntryInfo *const tag);

/*
  In the following frequently used code-pattern:

     tagEntryInfo *original = getEntryInCorkQueue (index);
     tagEntryInfo xtag = *original;
	 ... customize XTAG ...
	 makeTagEntry (&xtag);

   ORIGINAL and XTAG share some memory objects through their members.
   TagEntryInfo::name is one of obvious ones.
   When updating the member in the ... customize XTAG ... stage, you will
   do:

      vStringValue *xtag_name = vStringNewInit (xtags->name);
	  ... customize XTAG_NAME with vString functions ...
	  xtag.name = vStringValue (xtag_name);
	  makeTagEntry (&xtag);
	  vStringDelete (xtag_name);

   There are some vague ones: extraDynamic and parserFieldsDynamic.
   resetTagCorkState does:

   - mark the TAG is not in cork queue: set inCorkQueue 0.
   - copy,  clear, or dont touch the extraDynamic member.
   - copy,  clear, or dont touch the parserFieldsDynamic member.

*/

enum resetTagMemberAction {
	RESET_TAG_MEMBER_COPY,
	RESET_TAG_MEMBER_CLEAR,
	RESET_TAG_MEMBER_DONTTOUCH,
};

extern void resetTagCorkState (tagEntryInfo *const tag,
							   enum resetTagMemberAction xtagAction,
							   enum resetTagMemberAction parserFieldsAction);

/* Functions for attaching parser specific fields
 *
 * Which function should I use?
 * ----------------------------
 * Case A:
 *
 * If your parser uses the Cork API, and your parser called
 * makeTagEntry () already, you can use both
 * attachParserFieldToCorkEntry () and attachParserField ().
 *
 * attachParserField () and attachParserFieldToCorkEntry () duplicates
 * the memory object specified with `value' and stores the duplicated
 * object to the entry on the cork queue. So the parser must/can free
 * the original one passed to the functions after calling. The cork
 * queue manages the life of the duplicated object. It is not the
 * parser's concern.
 *
 *
 * Case B:
 *
 * If your parser called one of initTagEntry () family but didn't call
 * makeTagEntry () for a tagEntry yet, use attachParserField ().
 *
 * The parser (== caller) must keep the memory object specified with `value'
 * till calling makeTagEntry (). The parser must free the memory object
 * after calling makeTagEntry () if it is allocated dynamically in the
 * parser side.
 *
 * Interpretation of VALUE
 * -----------------------
 * The VALUE is interpreted very differently depending on the output
 * format: ctags, xref, and json. See field.h.
 *
 * WARNING: updating the VALUE
 * ---------------------------
 * In the current implementation, there is no way to update the value
 * for a given field or detach the value from the given field.
 * For the same combination of TAG and FTYPE, you can call the
 * attachParser* function only once.
 */
extern void attachParserField (tagEntryInfo *const tag, fieldType ftype, const char* value);
extern void attachParserFieldToCorkEntry (int index, fieldType ftype, const char* value);
extern const char* getParserFieldValueForType (const tagEntryInfo *const tag, fieldType ftype);

extern int makePlaceholder (const char *const name);
extern void markTagAsPlaceholder (tagEntryInfo *e, bool placeholder);
extern void markCorkEntryAsPlaceholder (int index, bool placeholder);

/* Marking all tag entries entries under the scope specified
 * with index recursively.
 *
 * The parser calling this function enables CORK_SYMTAB.
 * Entries to be marked must be registered to the scope
 * specified with index or its descendant scopes with
 * registerEntry ().
 *
 * Call makePlaceholder () at the start of your parser for
 * making the root scope where the entries are registered.
 */
extern void markAllEntriesInScopeAsPlaceholder (int index);

#endif  /* CTAGS_MAIN_ENTRY_H */