Skip to content

Commit e2d3723

Browse files
authored
Merge pull request #4059 from masatake/main--extras-and-fields-in-foreign-language
Main: use extras and fields in the foreign language specified in {_language=...} flag
2 parents a7b07d7 + 1d0be58 commit e2d3723

File tree

22 files changed

+151
-12
lines changed

22 files changed

+151
-12
lines changed

Tmain/list-mline-regex-flags.d/stdout-expected.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ p pcre2 use pcre2 regex engine
99
- warning="MESSAGE" print the given MESSAGE at WARNING level
1010
- _advanceTo=N[start|end] a group in pattern from where the next scan starts [0end]
1111
- _anonymous=PREFIX make an anonymous tag with PREFIX
12-
- _extra=EXTRA record the tag only when the extra is enabled
13-
- _field=FIELD:VALUE record the matched string(VALUE) to parser own FIELD of the tag
12+
- _extra=EXTRA record the tag only when the (foreign) extra is enabled
13+
- _field=FIELD:VALUE record the matched string(VALUE) to the (foreign) language specific FIELD of the tag
1414
- _guest=PARSERSPEC,N0[start|end],N1[start|end] run guest parser on the area
1515
- _language=LANG make a foreign tag for LANG
1616
- _role=ROLE set the given ROLE to the roles field

Tmain/list-mtable-regex-flags.d/stdout-expected.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ p pcre2 use pcre2 regex engine
1515
- warning="MESSAGE" print the given MESSAGE at WARNING level
1616
- _advanceTo=N[start|end] a group in pattern from where the next scan starts [0end]
1717
- _anonymous=PREFIX make an anonymous tag with PREFIX
18-
- _extra=EXTRA record the tag only when the extra is enabled
19-
- _field=FIELD:VALUE record the matched string(VALUE) to parser own FIELD of the tag
18+
- _extra=EXTRA record the tag only when the (foreign) extra is enabled
19+
- _field=FIELD:VALUE record the matched string(VALUE) to the (foreign) language specific FIELD of the tag
2020
- _guest=PARSERSPEC,N0[start|end],N1[start|end] run guest parser on the area
2121
- _language=LANG make a foreign tag for LANG
2222
- _role=ROLE set the given ROLE to the roles field

Tmain/list-regex-flags.d/stdout-expected.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ x exclusive skip testing the other pat
1010
- scope=ACTION use scope stack: ACTION = ref|push|pop|clear|set|replace|intervaltab
1111
- warning="MESSAGE" print the given MESSAGE at WARNING level
1212
- _anonymous=PREFIX make an anonymous tag with PREFIX
13-
- _extra=EXTRA record the tag only when the extra is enabled
14-
- _field=FIELD:VALUE record the matched string(VALUE) to parser own FIELD of the tag
13+
- _extra=EXTRA record the tag only when the (foreign) extra is enabled
14+
- _field=FIELD:VALUE record the matched string(VALUE) to the (foreign) language specific FIELD of the tag
1515
- _guest=PARSERSPEC,N0[start|end],N1[start|end] run guest parser on the area
1616
- _language=LANG make a foreign tag for LANG
1717
- _role=ROLE set the given ROLE to the roles field
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Copyright: 2024 Masatake YAMATO
2+
# License: GPL-2
3+
4+
. ../utils.sh
5+
6+
CTAGS=$1
7+
8+
V=
9+
# V=valgrind
10+
11+
${V} ${CTAGS} --quiet --options=NONE \
12+
\
13+
--langdef=NOSUCHLANG'{_foreignLanguage=Kconfig}' \
14+
--_extradef-NOSUCHLANG='NOSUCHEXTRA,but this is not the part of Kconfig' \
15+
--regex-NOSUCHLANG='/^\# (CONFIG_[^ ]+) is not set/\1/c/{_language=Kconfig}{_extra=NOSUCHEXTRA}{exclusive}' \
16+
\
17+
--_force-quit=0
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ctags: Warning: no such extra "NOSUCHEXTRA" in Kconfig
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Copyright: 2024 Masatake YAMATO
2+
# License: GPL-2
3+
4+
. ../utils.sh
5+
6+
CTAGS=$1
7+
8+
V=
9+
# V=valgrind
10+
11+
${V} ${CTAGS} --quiet --options=NONE \
12+
\
13+
--langdef=NOSUCHLANG'{_foreignLanguage=Kconfig}' \
14+
--_fielddef-NOSUCHLANG='NOSUCHFIELD,but this is not the part of Kconfig' \
15+
--regex-NOSUCHLANG='/^\# (CONFIG_[^ ]+) is (not set)/\1/c/{_language=Kconfig}{_field=NOSUCHFIELD:\1}{exclusive}' \
16+
\
17+
--_force-quit=0
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ctags: Warning: no such field "NOSUCHFIELD" in Kconfig
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
D:def00
2+
d:def01
3+
v:var0
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
D:def10
2+
d:def11
3+
v:var1
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Copyright: 2024 Masatake YAMATO
2+
# License: GPL-2
3+
4+
. ../utils.sh
5+
6+
CTAGS=$1
7+
8+
V=
9+
# V=valgrind
10+
11+
printf "# %s\n" --extras-X0=+'{iname}'
12+
${V} ${CTAGS} --quiet --options=NONE --options=./x0.ctags --options=./x1.ctags \
13+
--extras-X0=+'{iname}' --fields=+'{extras}{language}' -o - input-0.x1
14+
15+
printf "# %s\n" --extras-X0=-'{iname}'
16+
${V} ${CTAGS} --quiet --options=NONE --options=./x0.ctags --options=./x1.ctags \
17+
--extras-X0=-'{iname}' --fields=+'{extras}{language}' -o - input-1.x1

Tmain/parser-own-extras-for-foreign-lang.d/stderr-expected.txt

Whitespace-only changes.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# --extras-X0=+{iname}
2+
__def01__ input-0.x1 /^d:def01$/;" d language:X0 extras:iname
3+
def00 input-0.x1 /^D:def00$/;" d language:X0
4+
var0 input-0.x1 /^v:var0$/;" v language:X1
5+
# --extras-X0=-{iname}
6+
def10 input-1.x1 /^D:def10$/;" d language:X0
7+
var1 input-1.x1 /^v:var1$/;" v language:X1
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
--langdef=X0
2+
--kinddef-X0=d,def,definitions
3+
--_extradef-X0=iname,internal name like __x__
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
--langdef=X1{_foreignLanguage=X0}
2+
--map-X1=+.x1
3+
--kinddef-X1=v,var,variables
4+
--regex-X1=/D:([a-z0-9]+)$/\1/d/{_language=X0}
5+
--regex-X1=/d:([a-z0-9]+)$/__\1__/d/{_language=X0}{_extra=iname}
6+
--regex-X1=/v:([a-z0-9]+)$/\1/v/
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
public func foo(n, m);
2+
protected func bar(n);
3+
private func baz(n,...);
4+
X:tagme@iamowner
5+
Y:iamowner2=tagme2
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
--langdef=knownz
2+
--kinddef-knownz=m,mark,makers
3+
4+
--_fielddef-knownz=owner,the owner of the markers
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Copyright: 2024 Masatake YAMATO
2+
# License: GPL-2
3+
4+
. ../utils.sh
5+
6+
CTAGS=$1
7+
8+
V=
9+
# V=valgrind
10+
11+
${V} ${CTAGS} --options=NONE --options=./knownz.ctags --options=./unknownx.ctags \
12+
--fields=+l \
13+
--fields-unknownx=+'{protection}{signature}' \
14+
--fields-knownz=+'{owner}' \
15+
-o - input.unknownx
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ctags: Notice: No options will be read from files or environment
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
bar input.unknownx /^protected func bar(n);$/;" f language:unknownx protection:protected signature:(n)
2+
baz input.unknownx /^private func baz(n,...);$/;" f language:unknownx protection:private signature:(n,...)
3+
foo input.unknownx /^public func foo(n, m);$/;" f language:unknownx protection:public signature:(n, m)
4+
tagme input.unknownx /^X:tagme@iamowner$/;" m language:knownz owner:iamowner
5+
tagme2 input.unknownx /^Y:iamowner2=tagme2$/;" m language:knownz owner:iamowner2
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--langdef=unknownx{_foreignLanguage=knownz}
2+
--kinddef-unknownx=f,func,functions
3+
--map-unknownx=+.unknownx
4+
5+
--_fielddef-unknownx=protection,protections
6+
--_fielddef-unknownx=signature,signatures
7+
8+
--regex-unknownx=/^((public|protected|private) +)?func ([^\(]+)\((.*)\)/\3/f/{_field=protection:\1}{_field=signature:(\4)}
9+
--regex-unknownx=/^X:([a-z]+)@([a-z]+)/\1/m/{_language=knownz}{_field=owner:\2}
10+
--regex-unknownx=/^Y:([a-z0-9]+)=([a-z0-9]+)/\2/m/{_field=owner:\1}{_language=knownz}

docs/optlib.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,10 @@ The pattern matching is done only when the ``main`` is enabled.
371371
$ ctags --options=python-main.ctags -o - --extras-Python='+{main}' input.py
372372
__main__ input.py /^if __name__ == '__main__':$/;" f
373373
374+
By default, ctags assumes the extra is a part of the language specified
375+
with `<LANG>` in ``--regex-<LANG>``. Together with ``{_language=<LANG>}``
376+
flag, you can switch the language of the extra. See ":ref:`foreigntag`".
377+
The combination of these flags is new in version 6.2.0.
374378

375379
.. TODO: this "fields" section should probably be moved up this document, as a
376380
subsection in the "Regex option argument flags" section
@@ -463,6 +467,10 @@ about ``--fields-<LANG>`` option.
463467

464468
`passwd` parser is a simple example that uses ``--fields-<LANG>`` option.
465469

470+
By default, ctags assumes the field is a part of the language specified
471+
with `<LANG>` in ``--regex-<LANG>``. Together with ``{_language=<LANG>}``
472+
flag, you can switch the language of the field. See ":ref:`foreigntag`".
473+
The combination of these flags is new in version 6.2.0.
466474

467475
.. _roles:
468476

@@ -1961,6 +1969,15 @@ the output for input.docc:
19611969
compress input.docc /^- function: compress(const char *plain_text, enum algorithm alg) => char *$/;" function language:C roles:documented
19621970
decompress input.docc /^- function: decompress(const char *compressed_byteseq) => char *$/;" function language:C roles:documented
19631971
1972+
1973+
.. TESTCASE: Tmain/parser-own-fields-for-foreign-lang.d
1974+
1975+
``{_language=<LANG>}`` flag affects ``{_field=FIELDNAME:GROUP}`` flag; ctags looks up
1976+
the field defintion in `<LANG>`.
1977+
1978+
``{_language=<LANG>}`` flag affects ``{_extra=XNAME}`` flag; ctags looks up
1979+
the extra defintion in `<LANG>`.
1980+
19641981
.. END: NOT REVIEWED YET
19651982
19661983
.. _optlib2c:

main/lregex.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,9 +1084,12 @@ static void common_flag_extra_long (const char* const s, const char* const v, vo
10841084
return;
10851085
}
10861086

1087-
cdata->ptrn->xtagType = getXtagTypeForNameAndLanguage (v, cdata->owner);
1087+
langType lang = (cdata->ptrn->foreign_lang == LANG_IGNORE)
1088+
? cdata->owner
1089+
: cdata->ptrn->foreign_lang;
1090+
cdata->ptrn->xtagType = getXtagTypeForNameAndLanguage (v, lang);
10881091
if (cdata->ptrn->xtagType == XTAG_UNKNOWN)
1089-
error (WARNING, "no such extra \"%s\" in %s", v, getLanguageName(cdata->owner));
1092+
error (WARNING, "no such extra \"%s\" in %s", v, getLanguageName(lang));
10901093
}
10911094

10921095

@@ -1134,10 +1137,14 @@ static void common_flag_field_long (const char* const s, const char* const v, vo
11341137
}
11351138

11361139
fname = eStrndup (v, tmp - v);
1137-
ftype = getFieldTypeForNameAndLanguage (fname, cdata->owner);
1140+
1141+
langType lang = (ptrn->foreign_lang == LANG_IGNORE)
1142+
? cdata->owner
1143+
: ptrn->foreign_lang;
1144+
ftype = getFieldTypeForNameAndLanguage (fname, lang);
11381145
if (ftype == FIELD_UNKNOWN)
11391146
{
1140-
error (WARNING, "no such field \"%s\" in %s", fname, getLanguageName(cdata->owner));
1147+
error (WARNING, "no such field \"%s\" in %s", fname, getLanguageName(lang));
11411148
eFree (fname);
11421149
return;
11431150
}
@@ -1267,9 +1274,9 @@ static flagDefinition commonSpecFlagDef[] = {
12671274
"\"MESSAGE\"", "print the given MESSAGE at WARNING level"},
12681275
#define EXPERIMENTAL "_"
12691276
{ '\0', EXPERIMENTAL "extra", NULL, common_flag_extra_long ,
1270-
"EXTRA", "record the tag only when the extra is enabled"},
1277+
"EXTRA", "record the tag only when the (foreign) extra is enabled"},
12711278
{ '\0', EXPERIMENTAL "field", NULL, common_flag_field_long ,
1272-
"FIELD:VALUE", "record the matched string(VALUE) to parser own FIELD of the tag"},
1279+
"FIELD:VALUE", "record the matched string(VALUE) to the (foreign) language specific FIELD of the tag"},
12731280
{ '\0', EXPERIMENTAL "role", NULL, common_flag_role_long,
12741281
"ROLE", "set the given ROLE to the roles field"},
12751282
{ '\0', EXPERIMENTAL "anonymous", NULL, common_flag_anonymous_long,

0 commit comments

Comments
 (0)