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