Skip to content

Commit

Permalink
lregex: provide the way to intercept a parser making a tag
Browse files Browse the repository at this point in the history
TODO:
- write about the new option in docs/optlib.rst.
- add --_makeTagEntryNotification-<LANG>={{...}}.

Signed-off-by: Masatake YAMATO <[email protected]>
  • Loading branch information
masatake committed May 23, 2021
1 parent dd57ded commit 8f5385f
Show file tree
Hide file tree
Showing 14 changed files with 156 additions and 6 deletions.
79 changes: 79 additions & 0 deletions Units/option-makeTagEntryReflection.d/args.ctags
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# See #3020 and #3027.

--sort=no
--extras=+q

--_extradef-Markdown=withfname,appending input filename
--extras-Markdown=+{withfname}

--_prelude-Markdown={{
% You can customize the string combining the original name
% and the basen name of input file.
/SEP (@) def

% dict<original-index:int, withfname-index:int>
/scope-remapping-table 31 dict def

% (abc/input.d) dropext => (abc/input)
% (abc.d/input) dropext => (abc.d/input)
/dropext {
(/.) _strrpbrk {
% string offset
2 copy get ?/ eq {
pop
} {
0 exch 0 string _copyinterval
} ifelse
} if
} def

% (abc/efg) basename => (efg)
/basename {
?/ _strrchr {
1 add dup 2 index length exch sub
0 string _copyinterval
} if
} def
}}

--_sequel-Markdown={{
% Fill the scope field of withfname extra tags.
scope-remapping-table {
% Make the original tag invisible
exch dup _markplaceholder
:scope dup
% withfname-index:int original-scope:int original-scope:int
0 eq {
pop pop
} {
% withfname-index:int original-scope:int
scope-remapping-table exch get
% withfname-index:int withfname-scope:int
scope:
} ifelse
} forall
}}

--_makeTagEntryReflection-Markdown={{
/Markdown.withfname _extraenabled {
. :extras {
/Markdown.withfname _amember not
} {
true
} ifelse
{
mark
. :name
SEP
. :input dropext basename
_buildstring

. :kind
. _tagloc _tag dup /Markdown.withfname _markextra
_commit
% Record the pair of original-index:int and withfname-index:int.
scope-remapping-table exch . exch put
} if

} if
}}
7 changes: 7 additions & 0 deletions Units/option-makeTagEntryReflection.d/expected.tags
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
ABC@input input.md /^# ABC$/;" c
DEF@input input.md /^## DEF$/;" s chapter:ABC@input
GHI@input input.md /^### GHI$/;" S section:ABC@input""DEF@input
HIJ@input input.md /^### HIJ$/;" S section:ABC@input""DEF@input
KLM@input input.md /^## KLM$/;" s chapter:ABC@input
OPQ@input input.md /^# OPQ$/;" c
RST@input input.md /^### RST$/;" S chapter:OPQ@input
13 changes: 13 additions & 0 deletions Units/option-makeTagEntryReflection.d/input.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# ABC

## DEF

### GHI

### HIJ

## KLM

# OPQ

### RST
13 changes: 9 additions & 4 deletions main/dependency.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include "debug.h"
#include "dependency.h"
#include "entry.h"
#include "options.h"
#include "parse_p.h"
#include "read.h"
Expand Down Expand Up @@ -184,14 +185,18 @@ extern void notifyMakeTagEntry (const tagEntryInfo *tag, int corkIndex)
{
subparser *s;

/* running optscript code attaching to --makeTagEntryReflection-<LANG> */
langType lang = tag->langType;
notifyLanguageRegexMakeTagEntry (lang, corkIndex);

foreachSubparser(s, false)
{
enterSubparser(s);
if (s->makeTagEntryNotify)
{
enterSubparser(s);
s->makeTagEntryNotify (s, tag, corkIndex);
leaveSubparser();
}
/* propagate the event recursively */
notifyMakeTagEntry (tag, corkIndex);
leaveSubparser();
}
}

Expand Down
5 changes: 5 additions & 0 deletions main/dependency.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,9 @@ struct sSlaveParser {
slaveParser *next;
};

/* These are for CPreProcessor.
* Don't use in the other parsers. */
extern void notifyInputStart (void);
extern void notifyInputEnd (void);

#endif /* CTAGS_MAIN_DEPENDENCY_H */
8 changes: 8 additions & 0 deletions main/lregex.c
Original file line number Diff line number Diff line change
Expand Up @@ -2027,6 +2027,14 @@ extern void notifyRegexInputEnd (struct lregexControlBlock *lcb)
fillEndLineFieldOfUpperScopes (lcb, endline);
}

extern void notifyRegexMakeTagEntry (struct lregexControlBlock *lcb,
int corkIndex)
{
optscriptSetup (optvm, lcb->local_dict, corkIndex);
scriptEvalHook (optvm, lcb, SCRIPT_HOOK_MAKE_TAG_ENTRY_REFLECTION);
optscriptTeardown (optvm, lcb->local_dict);
}

extern void findRegexTagsMainloop (int (* driver)(void))
{
/* merely read all lines of the file */
Expand Down
1 change: 1 addition & 0 deletions main/lregex_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ extern bool matchMultitableRegex (struct lregexControlBlock *lcb, const vString*

extern void notifyRegexInputStart (struct lregexControlBlock *lcb);
extern void notifyRegexInputEnd (struct lregexControlBlock *lcb);
extern void notifyRegexMakeTagEntry (struct lregexControlBlock *lcb, int corkIndex);

extern void addRegexTable (struct lregexControlBlock *lcb, const char *name);
extern void extendRegexTable (struct lregexControlBlock *lcb, const char *src, const char *dist);
Expand Down
4 changes: 4 additions & 0 deletions main/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,8 @@ static optionDescription LongOptionDescription [] = {
{1,1," Define new extra for <LANG>. --extras-<LANG>=+{name} enables it."},
{1,1," --_fielddef-<LANG>=<name>,<description>"},
{1,1," Define new field for <LANG>."},
{1,1," --_makeTagEnryReflection-<LANG>={{ optscript-code }}"},
{1,1," Specify code run when <LANG> parser makes a tag."},
{1,1," --_mtable-extend-<LANG>=disttable+srctable."},
{1,1," Copy patterns of a regex table to another regex table."},
{1,1," --_mtable-regex-<LANG>=<table>/<line_pattern>/<name_pattern>/[<flags>]"},
Expand Down Expand Up @@ -3337,6 +3339,8 @@ static void processLongOption (
;
else if (processSequelOption (option, parameter))
;
else if (processMakeTagEntryReflectionOption (option, parameter))
;
else if (processPretendOption (option, parameter))
;
else if (processRolesOption (option, parameter))
Expand Down
1 change: 1 addition & 0 deletions main/options_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ extern bool processRoledefOption (const char *const option, const char *const pa
extern bool processScopesepOption (const char *const option, const char *const parameter);
extern bool processPreludeOption (const char *const option, const char *const parameter);
extern bool processSequelOption (const char *const option, const char *const parameter);
extern bool processMakeTagEntryReflectionOption (const char *const option, const char *const parameter);
extern bool processPretendOption (const char *const option, const char *const parameter);
extern bool processRolesOption (const char *const option, const char *const parameter);

Expand Down
10 changes: 10 additions & 0 deletions main/parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -3785,6 +3785,11 @@ extern void notifyLanguageRegexInputEnd (langType language)
notifyRegexInputEnd((LanguageTable + language)->lregexControlBlock);
}

extern void notifyLanguageRegexMakeTagEntry (langType language, int corkIndex)
{
notifyRegexMakeTagEntry((LanguageTable + language)->lregexControlBlock, corkIndex);
}

static unsigned int parserCorkFlags (parserDefinition *parser)
{
subparser *tmp;
Expand Down Expand Up @@ -5096,6 +5101,11 @@ extern bool processSequelOption (const char *const option, const char *const par
return processHookOption (option, parameter, "_sequel-", SCRIPT_HOOK_SEQUEL);
}

extern bool processMakeTagEntryReflectionOption (const char *const option, const char *const parameter)
{
return processHookOption (option, parameter, "_makeTagEntryReflection-", SCRIPT_HOOK_MAKE_TAG_ENTRY_REFLECTION);
}

extern bool processPretendOption (const char *const option, const char *const parameter)
{
langType new_language, old_language;
Expand Down
1 change: 1 addition & 0 deletions main/parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ typedef enum {
enum scriptHook {
SCRIPT_HOOK_PRELUDE,
SCRIPT_HOOK_SEQUEL,
SCRIPT_HOOK_MAKE_TAG_ENTRY_REFLECTION,
SCRIPT_HOOK_MAX,
};

Expand Down
1 change: 1 addition & 0 deletions main/parse_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ extern void freeEncodingResources (void);
extern bool processLanguageRegexOption (langType language, enum regexParserType regptype, const char *const parameter);
extern void notifyLanguageRegexInputStart (langType language);
extern void notifyLanguageRegexInputEnd (langType language);
extern void notifyLanguageRegexMakeTagEntry (langType language, int corkIndex);

extern void matchLanguageRegex (const langType language, const vString* const line);
extern void freeRegexResources (void);
Expand Down
2 changes: 0 additions & 2 deletions main/subparser_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ extern langType getSubparserLanguage (subparser *s);

/* A base parser doesn't have to call the following three functions.
The main part calls them internally. */
extern void notifyInputStart (void);
extern void notifyInputEnd (void);
extern void notifyMakeTagEntry (const tagEntryInfo *info, int corkIndex);

extern void setupSubparsersInUse (struct slaveControlBlock *controlBlock);
Expand Down
17 changes: 17 additions & 0 deletions parsers/cpreprocessor.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <string.h>

#include "debug.h"
#include "dependency.h" /* notifyInputStart, notifyInputEnd */
#include "entry.h"
#include "htable.h"
#include "cpreprocessor.h"
Expand Down Expand Up @@ -348,6 +349,14 @@ static void cppInitCommon(langType clientLang,
: clientLang) & CORK_SYMTAB))
? makeMacroTable ()
: NULL;

if (Cpp.lang != Cpp.clientLang
&& Cpp.clientLang != LANG_IGNORE)
{
pushLanguage (Cpp.lang);
notifyInputStart ();
popLanguage ();
}
}

extern void cppInit (const bool state, const bool hasAtLiteralStrings,
Expand Down Expand Up @@ -381,6 +390,14 @@ static void cppClearMacroInUse (cppMacroInfo **pM)

extern void cppTerminate (void)
{
if (Cpp.lang != Cpp.clientLang
&& Cpp.clientLang != LANG_IGNORE)
{
pushLanguage (Cpp.lang);
notifyInputEnd ();
popLanguage ();
}

if (Cpp.directive.name != NULL)
{
vStringDelete (Cpp.directive.name);
Expand Down

0 comments on commit 8f5385f

Please sign in to comment.