Skip to content

Commit a5a3a28

Browse files
committed
main: using regex for choosing a parser for the given file name
This change extends --map-<LANG> option to support regular expression matching with the full file name. The original --map-<LANG> option supports glob based matching and extension comparison with the file basename. However, two methods are not enough if the file names are too generic. See #3287 . The regular expression passed to --map-<LANG> must be surround by % character like --map-RpmMacros='%(.*/)?macros\.d/macros\.([^/]+)$%' If you want to match in a case-insensitive way, append `i' after the second % like --map-RpmMacros='%(.*/)?macros\.d/macros\.([^/]+)$%i' If you want to use % as part of an expression, put \ before % for escaping. TODO: - [ ] reconsider name regex, rxpr, or something - [ ] update ctags.1 - [ ] add Tmain test cases - [ ] add description to --help - [X] extend optlib2c - [X] add --list-map-regex - [X] add --list-maps - [ ] add pcre backend Signed-off-by: Masatake YAMATO <[email protected]>
1 parent a9755e3 commit a5a3a28

File tree

12 files changed

+446
-28
lines changed

12 files changed

+446
-28
lines changed

main/options.c

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@
5959
/* The following separators are permitted for list options.
6060
*/
6161
#define EXTENSION_SEPARATOR '.'
62+
#define REXPR_START '%'
63+
#define REXPR_STOP '%'
64+
#define REXPR_ICASE 'i'
6265
#define PATTERN_START '('
6366
#define PATTERN_STOP ')'
6467
#define IGNORE_SEPARATORS ", \t\n"
@@ -303,10 +306,10 @@ static optionDescription LongOptionDescription [] = {
303306
{1,0," --langmap=<map>[,<map>[...]]"},
304307
{1,0," Override default mapping of language to input file extension."},
305308
{1,0," e.g. --langmap=c:.c.x,java:+.j,make:([Mm]akefile).mak"},
306-
{1,0," --map-<LANG>=[+|-]<extension>|<pattern>"},
309+
{1,0," --map-<LANG>=[+|-]<extension>|<pattern>|<regex>"},
307310
{1,0," Set, add(+) or remove(-) the map for <LANG>."},
308-
{1,0," Unlike --langmap, this doesn't take a list; only one file name <pattern>"},
309-
{1,0," or one file <extension> can be specified at once."},
311+
{1,0," Unlike --langmap, this doesn't take a list; only one file name <pattern>,"},
312+
{1,0," one file name <regex>, or one file <extension> can be specified at once."},
310313
{1,0," Unlike --langmap the change with this option affects mapping of <LANG> only."},
311314
{1,0,""},
312315
{1,0,"Tags File Contents Options"},
@@ -436,6 +439,8 @@ static optionDescription LongOptionDescription [] = {
436439
{1,0," Output list of language extensions in mapping."},
437440
{1,0," --list-map-patterns[=(<language>|all)]"},
438441
{1,0," Output list of language patterns in mapping."},
442+
{1,0," --list-map-regex[=(<language>|all)]"},
443+
{1,0," Output list of language regular expressions in mapping."},
439444
{1,0," --list-maps[=(<language>|all)]"},
440445
{1,0," Output list of language mappings (both extensions and patterns)."},
441446
{1,0," --list-mline-regex-flags"},
@@ -1787,6 +1792,7 @@ static char* extractMapFromParameter (const langType language,
17871792
++parameter;
17881793
for (p = parameter ; *p != PATTERN_STOP && *p != '\0' ; ++p)
17891794
{
1795+
/* ??? */
17901796
if (*p == '\\' && *(p + 1) == PATTERN_STOP)
17911797
++p;
17921798
}
@@ -1802,6 +1808,26 @@ static char* extractMapFromParameter (const langType language,
18021808
return result;
18031809
}
18041810

1811+
if (first == REXPR_START)
1812+
{
1813+
*mapType = LMAP_REXPR;
1814+
1815+
++parameter;
1816+
vString *rexpr = vStringNew ();
1817+
for (p = parameter ; *p != REXPR_STOP && *p != '\0' ; ++p)
1818+
{
1819+
if (*p == '\\' && *(p + 1) == REXPR_STOP)
1820+
continue;
1821+
vStringPut (rexpr, *p);
1822+
}
1823+
if (*p == '\0')
1824+
error (FATAL, "Unterminated file name regex for %s language",
1825+
getLanguageName (language));
1826+
1827+
*tail = p + 1;
1828+
return vStringDeleteUnwrap (rexpr);
1829+
}
1830+
18051831
return NULL;
18061832
}
18071833

@@ -1817,6 +1843,13 @@ static char* addLanguageMap (const langType language, char* map_parameter,
18171843
addLanguageExtensionMap (language, map, exclusiveInAllLanguages);
18181844
else if (map && map_type == LMAP_PATTERN)
18191845
addLanguagePatternMap (language, map, exclusiveInAllLanguages);
1846+
else if (map && map_type == LMAP_REXPR)
1847+
{
1848+
bool icase = (*p == REXPR_ICASE);
1849+
addLanguageRexprMap (language, map, icase, exclusiveInAllLanguages);
1850+
if (icase)
1851+
p++;
1852+
}
18201853
else
18211854
error (FATAL, "Badly formed language map for %s language",
18221855
getLanguageName (language));
@@ -1837,6 +1870,13 @@ static char* removeLanguageMap (const langType language, char* map_parameter)
18371870
removeLanguageExtensionMap (language, map);
18381871
else if (map && map_type == LMAP_PATTERN)
18391872
removeLanguagePatternMap (language, map);
1873+
else if (map && map_type == LMAP_REXPR)
1874+
{
1875+
bool icase = (*p == REXPR_ICASE);
1876+
removeLanguageRexprMap (language, map, icase);
1877+
if (icase)
1878+
p++;
1879+
}
18401880
else
18411881
error (FATAL, "Badly formed language map for %s language",
18421882
getLanguageName (language));
@@ -2158,6 +2198,13 @@ static void processListMapPatternsOption (const char *const option,
21582198
processListMapsOptionForType (option, parameter, LMAP_PATTERN|LMAP_TABLE_OUTPUT);
21592199
}
21602200

2201+
static void processListMapRegularExpressionsOption (const char *const option,
2202+
const char *const parameter)
2203+
{
2204+
processListMapsOptionForType (option, parameter, LMAP_REXPR|LMAP_TABLE_OUTPUT);
2205+
}
2206+
2207+
21612208
static void processListMapsOption (
21622209
const char *const option CTAGS_ATTR_UNUSED,
21632210
const char *const parameter CTAGS_ATTR_UNUSED)
@@ -2889,6 +2936,7 @@ static parametricOption ParametricOptions [] = {
28892936
{ "list-maps", processListMapsOption, true, STAGE_ANY },
28902937
{ "list-map-extensions", processListMapExtensionsOption, true, STAGE_ANY },
28912938
{ "list-map-patterns", processListMapPatternsOption, true, STAGE_ANY },
2939+
{ "list-map-regex", processListMapRegularExpressionsOption, true, STAGE_ANY },
28922940
{ "list-mline-regex-flags", processListMultilineRegexFlagsOption, true, STAGE_ANY },
28932941
{ "list-output-formats", processListOutputFormatsOption, true, STAGE_ANY },
28942942
{ "list-params", processListParametersOption, true, STAGE_ANY },

0 commit comments

Comments
 (0)