Skip to content

Commit d8f5c06

Browse files
authored
Merge pull request #3514 from masatake/lregex--warn-missing-mgroup
lregex: warn if mgroup= flag is not given in --mline-regex-<LANG>=
2 parents acbd555 + 1038f51 commit d8f5c06

File tree

7 files changed

+82
-24
lines changed

7 files changed

+82
-24
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
ctags: Notice: No options will be read from files or environment
2+
ctags: Warning: FOO: no {mgroup=N} flag given in --mline-regex-<LANG>=/(.)/\1/{_advanceTo=1start}... (addTagRegexOption)
23
ctags: Warning: a multi line regex pattern doesn't advance the input cursor: (.)
34
ctags: Warning: Language: FOO, input file: ./input.foo, pos: 0

Tmain/optlib-message-flag.d/args.ctags

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
--mline-regex-FOO=/namespace ([a-zA-Z]+) /\1/m,mlineNamespace/{mgroup=1}{warning="got namespace"}
1414
--mline-regex-FOO=/var ([a-zA-Z]+) ([a-zA-Z]+);/\2/V,mlineVariable/{warning="got variable '\2' of type \1"}{mgroup=2}
15-
--mline-regex-FOO=/bad multi-line ([a-zA-Z-]+)/\1/x,bad/{fatal="bad='\1'"}
15+
--mline-regex-FOO=/bad multi-line ([a-zA-Z-]+)/\1/x,bad/{fatal="bad='\1'"}{mgroup=1}
1616

1717

1818
--_tabledef-FOO=main

docs/man/ctags-optlib.7.rst

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Following options are for defining (or customizing) a parser:
3434
* ``--map-<LANG>=[+|-]<extension>|<pattern>``
3535
* ``--kinddef-<LANG>=<letter>,<name>,<description>``
3636
* ``--regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/[<flags>]``
37-
* ``--mline-regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/[<flags>]``
37+
* ``--mline-regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/{mgroup=<N>}[<flags>]``
3838

3939
Following options are for controlling loading parser definition:
4040

@@ -117,7 +117,7 @@ Overview for defining a parser
117117

118118
Use ``--regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/[<flags>]``
119119
option for a single-line regular expression. You can also use
120-
``--mline-regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/[<flags>]``
120+
``--mline-regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/{mgroup=<N>}[<flags>]``
121121
option for a multi-line regular expression.
122122

123123
As *<kind-spec>*, you can use the one-letter flag defined with
@@ -271,12 +271,15 @@ OPTIONS
271271
``--list-mline-regex-flags``
272272
Lists the flags that can be used in ``--mline-regex-<LANG>`` option.
273273

274-
``--mline-regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/[<flags>]``
274+
``--mline-regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/{mgroup=<N>}[<flags>]``
275275
Define a multi-line regular expression.
276276

277277
This option is similar to ``--regex-<LANG>`` option except the pattern is
278278
applied to the whole file’s contents, not line by line.
279279

280+
See "`FLAGS FOR ``--mline-regex-<LANG>`` OPTION`_" about ``{mgroup=<N>}``.
281+
``{mgroup=<N>}`` flag is a must.
282+
280283
``--_echo=<message>``
281284
Print *<message>* to the standard error stream. This is helpful to
282285
understand (and debug) optlib loading feature of Universal Ctags.
@@ -405,6 +408,20 @@ representation. ``--list-regex-flags`` lists all the flags.
405408
``fatal=<message>``
406409
print the given *<message>* and exit
407410

411+
FLAGS FOR ``--mline-regex-<LANG>`` OPTION
412+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
413+
414+
``mgroup=<N>``
415+
416+
decide the location of the tag extracted with
417+
``--mline-regex-<LANG>`` option.
418+
419+
*<N>* is the number of a capture group in the pattern, which is
420+
used to record the line number location of the tag. ``mgroup=<N>``
421+
flag is not an optional. You **must** add an ``mgroup=<N>`` flag,
422+
even if the *<N>* is ``0`` (meaning the start position of the
423+
whole regex pattern).
424+
408425
EXAMPLES
409426
-------------
410427

docs/optlib.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -917,7 +917,7 @@ Multiline pattern flags
917917

918918
.. TODO: Q: isn't the above restriction really a bug? I think it is. I should fix it.
919919
Q to @masatake-san: Do you mean that {mgroup=0} can be omitted? -> #2918 is opened
920-
920+
A. as proposed in #3514, I made {mgroup=N} be a must flag.
921921
922922
``{_advanceTo=N[start|end]}``
923923

main/debug.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@
2424
* Macros
2525
*/
2626

27+
#if defined _MSC_VER
28+
/* See https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros */
29+
# define ASSERT_FUNCTION __FUNCTION__
30+
#elif defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
31+
# define ASSERT_FUNCTION __func__
32+
#else
33+
# define ASSERT_FUNCTION ((const char*)0)
34+
#endif
35+
2736
#ifdef DEBUG
2837
# define debug(level) ((ctags_debugLevel & (long)(level)) != 0)
2938
# define DebugStatement(x) x
@@ -33,11 +42,6 @@
3342
# define AssertNotReached() do {} while(0)
3443
# else
3544
/* We expect cc supports c99 standard. */
36-
# if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
37-
# define ASSERT_FUNCTION __func__
38-
# else
39-
# define ASSERT_FUNCTION ((const char*)0)
40-
# endif
4145
# define Assert(c) ((c) ? ((void)0) : debugAssert(#c, __FILE__, __LINE__, ASSERT_FUNCTION))
4246
# define AssertNotReached() Assert(!"The control reaches unexpected place")
4347
# endif

main/lregex.c

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1926,7 +1926,6 @@ static bool matchMultilineRegexPattern (struct lregexControlBlock *lcb,
19261926
{
19271927
const char *start;
19281928
const char *current;
1929-
off_t offset = 0;
19301929
regexPattern* patbuf = entry->pattern;
19311930
struct mGroupSpec *mgroup = &patbuf->mgroup;
19321931
struct guestSpec *guest = &patbuf->guest;
@@ -1958,9 +1957,6 @@ static bool matchMultilineRegexPattern (struct lregexControlBlock *lcb,
19581957
if (hasMessage(patbuf))
19591958
printMessage(lcb->owner, patbuf, (current + pmatch[0].rm_so) - start, current, pmatch);
19601959

1961-
offset = (current + pmatch [mgroup->forLineNumberDetermination].rm_so)
1962-
- start;
1963-
19641960
entry->statistics.match++;
19651961
scriptWindow window = {
19661962
.line = current,
@@ -1983,6 +1979,9 @@ static bool matchMultilineRegexPattern (struct lregexControlBlock *lcb,
19831979

19841980
if (patbuf->type == PTRN_TAG)
19851981
{
1982+
Assert (mgroup->forLineNumberDetermination != NO_MULTILINE);
1983+
off_t offset = (current + pmatch [mgroup->forLineNumberDetermination].rm_so)
1984+
- start;
19861985
matchTagPattern (lcb, current, patbuf, pmatch, offset,
19871986
(patbuf->optscript && hasNameSlot (patbuf))? &window: NULL);
19881987
result = true;
@@ -2290,8 +2289,16 @@ extern void addTagMultiLineRegex (struct lregexControlBlock *lcb, const char* co
22902289
const char* const name, const char* const kinds, const char* const flags,
22912290
bool *disabled)
22922291
{
2293-
addTagRegexInternal (lcb, TABLE_INDEX_UNUSED,
2294-
REG_PARSER_MULTI_LINE, regex, name, kinds, flags, disabled);
2292+
regexPattern *ptrn = addTagRegexInternal (lcb, TABLE_INDEX_UNUSED,
2293+
REG_PARSER_MULTI_LINE, regex, name, kinds, flags, disabled);
2294+
if (ptrn->mgroup.forLineNumberDetermination == NO_MULTILINE)
2295+
{
2296+
if (hasNameSlot(ptrn))
2297+
error (WARNING, "%s: no {mgroup=N} flag given in --mline-regex-<LANG>=/%s/... (%s)",
2298+
regex,
2299+
getLanguageName (lcb->owner), ASSERT_FUNCTION);
2300+
ptrn->mgroup.forLineNumberDetermination = 0;
2301+
}
22952302
}
22962303

22972304
extern void addTagMultiTableRegex(struct lregexControlBlock *lcb,
@@ -2383,8 +2390,19 @@ static void addTagRegexOption (struct lregexControlBlock *lcb,
23832390
regex_pat = eStrdup (pattern);
23842391

23852392
if (parseTagRegex (regptype, regex_pat, &name, &kinds, &flags))
2386-
addTagRegexInternal (lcb, table_index, regptype, regex_pat, name, kinds, flags,
2387-
NULL);
2393+
{
2394+
regexPattern *ptrn = addTagRegexInternal (lcb, table_index, regptype, regex_pat, name, kinds, flags,
2395+
NULL);
2396+
if (regptype == REG_PARSER_MULTI_LINE
2397+
&& ptrn->mgroup.forLineNumberDetermination == NO_MULTILINE)
2398+
{
2399+
if (hasNameSlot(ptrn))
2400+
error (WARNING, "%s: no {mgroup=N} flag given in --mline-regex-<LANG>=%s... (%s)",
2401+
getLanguageName (lcb->owner),
2402+
pattern, ASSERT_FUNCTION);
2403+
ptrn->mgroup.forLineNumberDetermination = 0;
2404+
}
2405+
}
23882406

23892407
eFree (regex_pat);
23902408
}
@@ -2738,9 +2756,6 @@ static struct regexTable * matchMultitableRegexTable (struct lregexControlBlock
27382756
if (match == 0)
27392757
{
27402758
entry->statistics.match++;
2741-
off_t offset_for_tag = (current
2742-
+ pmatch [ptrn->mgroup.forLineNumberDetermination].rm_so)
2743-
- cstart;
27442759
scriptWindow window = {
27452760
.line = current,
27462761
.start = cstart,
@@ -2763,6 +2778,10 @@ static struct regexTable * matchMultitableRegexTable (struct lregexControlBlock
27632778

27642779
if (ptrn->type == PTRN_TAG)
27652780
{
2781+
Assert (ptrn->mgroup.forLineNumberDetermination != NO_MULTILINE);
2782+
off_t offset_for_tag = (current
2783+
+ pmatch [ptrn->mgroup.forLineNumberDetermination].rm_so)
2784+
- cstart;
27662785
matchTagPattern (lcb, current, ptrn, pmatch, offset_for_tag,
27672786
(ptrn->optscript && hasNameSlot (ptrn))? &window: NULL);
27682787

man/ctags-optlib.7.rst.in

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Following options are for defining (or customizing) a parser:
3434
* ``--map-<LANG>=[+|-]<extension>|<pattern>``
3535
* ``--kinddef-<LANG>=<letter>,<name>,<description>``
3636
* ``--regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/[<flags>]``
37-
* ``--mline-regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/[<flags>]``
37+
* ``--mline-regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/{mgroup=<N>}[<flags>]``
3838

3939
Following options are for controlling loading parser definition:
4040

@@ -117,7 +117,7 @@ Overview for defining a parser
117117

118118
Use ``--regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/[<flags>]``
119119
option for a single-line regular expression. You can also use
120-
``--mline-regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/[<flags>]``
120+
``--mline-regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/{mgroup=<N>}[<flags>]``
121121
option for a multi-line regular expression.
122122

123123
As *<kind-spec>*, you can use the one-letter flag defined with
@@ -271,12 +271,15 @@ OPTIONS
271271
``--list-mline-regex-flags``
272272
Lists the flags that can be used in ``--mline-regex-<LANG>`` option.
273273

274-
``--mline-regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/[<flags>]``
274+
``--mline-regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/{mgroup=<N>}[<flags>]``
275275
Define a multi-line regular expression.
276276

277277
This option is similar to ``--regex-<LANG>`` option except the pattern is
278278
applied to the whole file’s contents, not line by line.
279279

280+
See "`FLAGS FOR ``--mline-regex-<LANG>`` OPTION`_" about ``{mgroup=<N>}``.
281+
``{mgroup=<N>}`` flag is a must.
282+
280283
``--_echo=<message>``
281284
Print *<message>* to the standard error stream. This is helpful to
282285
understand (and debug) optlib loading feature of Universal Ctags.
@@ -405,6 +408,20 @@ representation. ``--list-regex-flags`` lists all the flags.
405408
``fatal=<message>``
406409
print the given *<message>* and exit
407410

411+
FLAGS FOR ``--mline-regex-<LANG>`` OPTION
412+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
413+
414+
``mgroup=<N>``
415+
416+
decide the location of the tag extracted with
417+
``--mline-regex-<LANG>`` option.
418+
419+
*<N>* is the number of a capture group in the pattern, which is
420+
used to record the line number location of the tag. ``mgroup=<N>``
421+
flag is not an optional. You **must** add an ``mgroup=<N>`` flag,
422+
even if the *<N>* is ``0`` (meaning the start position of the
423+
whole regex pattern).
424+
408425
EXAMPLES
409426
-------------
410427

0 commit comments

Comments
 (0)