Skip to content

Commit

Permalink
main: introduce FOREIGNER dependency type
Browse files Browse the repository at this point in the history
With initForeignRefTagEntry, you can make a tag for
language X when parsing language Y.

X had no chance to initialize the parser itself when Y called
initForeignRefTagEntry (and makeTagEntry).

This change introduces a new dependency FOREIGNER gives
the chance.

With the dependency type, Y can declare it will use X
via initForeignRefTagEntry. The main part of ctags
can initialize X just after initializing Y with the
declaration as a hint.

Signed-off-by: Masatake YAMATO <[email protected]>
  • Loading branch information
masatake committed May 23, 2021
1 parent 7d6953f commit dd57ded
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 7 deletions.
10 changes: 7 additions & 3 deletions main/dependency.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ extern void linkDependencyAtInitializeParsing (depType dtype,
{
if (dtype == DEPTYPE_KIND_OWNER)
linkKindDependency (masterKCB, slaveKCB);
else if (dtype == DEPTYPE_SUBPARSER)
else if (dtype == DEPTYPE_SUBPARSER || dtype == DEPTYPE_FOREIGNER)
{
slaveParser *s = xMalloc (1, slaveParser);

Expand Down Expand Up @@ -118,8 +118,9 @@ extern void initializeDependencies (parserDefinition *parser,
for (i = 0; i < parser->dependencyCount; i++)
{
parserDependency *d = parser->dependencies + i;
if (d->type == DEPTYPE_SUBPARSER &&
((subparser *)(d->data))->direction & SUBPARSER_SUB_RUNS_BASE)
if ((d->type == DEPTYPE_SUBPARSER &&
((subparser *)(d->data))->direction & SUBPARSER_SUB_RUNS_BASE)
|| (d->type == DEPTYPE_FOREIGNER))
{
langType baseParser;
baseParser = getNamedLanguage (d->upperParser, 0);
Expand Down Expand Up @@ -320,6 +321,9 @@ extern void subparserColprintAddSubparsers (struct colprintTable *table,
pushLanguage (scb->owner);
foreachSlaveParser(tmp)
{
if (tmp->type != DEPTYPE_SUBPARSER)
continue;

struct colprintLine *line = colprintTableGetNewLine(table);

colprintLineAppendColumnCString (line, getLanguageName (tmp->id));
Expand Down
1 change: 1 addition & 0 deletions main/dependency.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
typedef enum eDepType {
DEPTYPE_KIND_OWNER,
DEPTYPE_SUBPARSER,
DEPTYPE_FOREIGNER,
COUNT_DEPTYPES,
} depType;

Expand Down
9 changes: 9 additions & 0 deletions main/entry.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,15 @@ 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 initForeignRefTagEntry (tagEntryInfo *const e, const char *const name,
langType type,
int kindIndex, int roleIndex);
Expand Down
54 changes: 50 additions & 4 deletions main/parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -1853,19 +1853,37 @@ static void linkDependenciesAtInitializeParsing (parserDefinition *const parser)
unsigned int i;
parserDependency *d;
langType upper;
parserDefinition *lowerParser;
parserObject *upperParser;

for (i = 0; i < parser->dependencyCount; i++)
{
d = parser->dependencies + i;
upper = getNamedLanguage (d->upperParser, 0);

if (d->type == DEPTYPE_FOREIGNER)
{
upper = parser->id;
langType lower = getNamedLanguage (d->upperParser, 0);
if (lower == LANG_IGNORE)
error (FATAL,
"Unknown language: \"%s\" as a foreigner for %s",
d->upperParser, parser->name);

lowerParser = LanguageTable [lower].def;
}
else
{
upper = getNamedLanguage (d->upperParser, 0);
lowerParser = parser;
}

upperParser = LanguageTable + upper;

linkDependencyAtInitializeParsing (d->type, upperParser->def,
upperParser->slaveControlBlock,
upperParser->kindControlBlock,
parser,
(LanguageTable + parser->id)->kindControlBlock,
lowerParser,
(LanguageTable + lowerParser->id)->kindControlBlock,
d->data);
}
}
Expand Down Expand Up @@ -3731,11 +3749,39 @@ static rescanReason createTagsForFile (const langType language,

extern void notifyLanguageRegexInputStart (langType language)
{
notifyRegexInputStart((LanguageTable + language)->lregexControlBlock);
parserObject *pobj = LanguageTable + language;
parserDefinition *pdef = pobj->def;

notifyRegexInputStart(pobj->lregexControlBlock);
for (unsigned int i = 0; i < pdef->dependencyCount; i++)
{
parserDependency *d = pdef->dependencies + i;
if (d->type != DEPTYPE_FOREIGNER)
continue;
langType foreigner = getNamedLanguage (d->upperParser, 0);
if (foreigner == LANG_IGNORE)
continue;

notifyLanguageRegexInputStart (foreigner);
}
}

extern void notifyLanguageRegexInputEnd (langType language)
{
parserObject *pobj = LanguageTable + language;
parserDefinition *pdef = pobj->def;

for (unsigned int i = 0; i < pdef->dependencyCount; i++)
{
parserDependency *d = pdef->dependencies + i;
if (d->type != DEPTYPE_FOREIGNER)
continue;
langType foreigner = getNamedLanguage (d->upperParser, 0);
if (foreigner == LANG_IGNORE)
continue;

notifyLanguageRegexInputEnd (foreigner);
}
notifyRegexInputEnd((LanguageTable + language)->lregexControlBlock);
}

Expand Down
8 changes: 8 additions & 0 deletions parsers/rpmspec.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "routines.h"
#include "trace.h"

#include "dependency.h"
#include "autoconf.h"

typedef enum {
Expand Down Expand Up @@ -385,10 +386,17 @@ extern parserDefinition* RpmSpecParser (void)
"rpm-spec", /* the mode name in Emacs */
NULL };
parserDefinition* const def = parserNew ("RpmSpec");

static parserDependency dependencies [] = {
[0] = { DEPTYPE_FOREIGNER, "Autoconf", NULL },
};

def->kindTable = RpmSpecKinds;
def->kindCount = ARRAY_SIZE (RpmSpecKinds);
def->extensions = extensions;
def->aliases = aliases;
def->dependencies = dependencies;
def->dependencyCount = ARRAY_SIZE (dependencies);
def->initialize = initializeRpmSpecParser;
def->parser = findRpmSpecTags;
def->method = METHOD_REGEX;
Expand Down

0 comments on commit dd57ded

Please sign in to comment.