ctags Internal API - cztchoice/ctags GitHub Wiki

Svg file online view: here
Ctags provides makeTagEntry to parsers as an entry point for writing tag informations to FILE. makeTagEntry calls writeTagEntry if the parser does not set useCork field. writeTagEntry calls one of three functions, writeTagsEntry, writeXrefEntry or writeCtagsEntry. One of them is chosen depending on the arguments passed to ctags.
If useCork is set, the tag informations goes to a queue on memory. The queue is flushed when useCork in unset. See cork API for more details.
cork API is introduced for recording scope information easier.
Before introducing cork, a scope information must be recorded as strings. It is flexible but memory management is required. Following code is taken from clojure.c(with modifications).
if (vStringLength (parent) > 0)
{
current.extensionFields.scope[0] = ClojureKinds[K_NAMESPACE].name;
current.extensionFields.scope[1] = vStringValue (parent);
}
makeTagEntry (¤t);parent, values stored to scope [0] and scope [1] are all something string.
cork API provides more solid way to hold scope information. cork API expects parent, which represents scope of a tag(current) currently parser dealing, is recorded to a tags file before recording the current tag via makeTagEntry function.
For passing the information about parent to makeTagEntry, tagEntryInfo object was created. It was used just for recording; and freed after recording. In cork API, it is not freed after recording; a parser can reused it as scope information.
See a commit titled with "clojure: use cork". I applied cork API to the clojure parser.
cork can be enabled and disabled per parser. cork is disabled by default. So there is no impact till you enables it in your parser.
useCork field is introduced in parserDefinition type:
typedef struct {
...
boolean useCork;
...
} parserDefinition;Set TRUE to useCork like:
extern parserDefinition *ClojureParser (void)
{
...
parserDefinition *def = parserNew ("Clojure");
...
def->useCork = TRUE;
return def;
}When ctags running a parser with useCork being TRUE, all output requested via makeTagEntry function calling is stored to an internal queue, not to tags file. When parsing an input file is done, the tag information stored automatically to the queue are flushed to tags file in batch.
When calling makeTagEntry with a tagEntryInfo object(parent), it returns an integer. The integer can be used as handle for referring the object after calling.
static int parent = SCOPE_NIL;
...
parent = makeTagEntry (&e);The handle can be used by setting to a scopeIndex field of current tag, which is in the scope of parent.
current.extensionFields.scopeIndex = parent;When passing current to makeTagEntry, the scopeIndex is refereed for emitting the scope information of current.
scopeIndex must be set to SCOPE_NIL if a tag is not in any scope. When using scopeIndex of current, NULL must be assigned to both current.extensionFields.scope[0] and current.extensionFields.scope[1]. initTagEntry function does this initialization internally, so you generally you don't have to write the initialization explicitly.