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 */
|