Skip to content

Commit 24ae704

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 the glob based matching and the 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 caf6daa commit 24ae704

File tree

12 files changed

+456
-31
lines changed

12 files changed

+456
-31
lines changed

main/options.c

Lines changed: 58 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"},
@@ -1793,6 +1798,7 @@ static char* extractMapFromParameter (const langType language,
17931798
++parameter;
17941799
for (p = parameter ; *p != PATTERN_STOP && *p != '\0' ; ++p)
17951800
{
1801+
/* ??? */
17961802
if (*p == '\\' && *(p + 1) == PATTERN_STOP)
17971803
++p;
17981804
}
@@ -1808,6 +1814,26 @@ static char* extractMapFromParameter (const langType language,
18081814
return result;
18091815
}
18101816

1817+
if (first == REXPR_START)
1818+
{
1819+
*mapType = LMAP_REXPR;
1820+
1821+
++parameter;
1822+
vString *rexpr = vStringNew ();
1823+
for (p = parameter ; *p != REXPR_STOP && *p != '\0' ; ++p)
1824+
{
1825+
if (*p == '\\' && *(p + 1) == REXPR_STOP)
1826+
continue;
1827+
vStringPut (rexpr, *p);
1828+
}
1829+
if (*p == '\0')
1830+
error (FATAL, "Unterminated file name regex for %s language",
1831+
getLanguageName (language));
1832+
1833+
*tail = p + 1;
1834+
return vStringDeleteUnwrap (rexpr);
1835+
}
1836+
18111837
return NULL;
18121838
}
18131839

@@ -1823,6 +1849,13 @@ static char* addLanguageMap (const langType language, char* map_parameter,
18231849
addLanguageExtensionMap (language, map, exclusiveInAllLanguages);
18241850
else if (map && map_type == LMAP_PATTERN)
18251851
addLanguagePatternMap (language, map, exclusiveInAllLanguages);
1852+
else if (map && map_type == LMAP_REXPR)
1853+
{
1854+
bool icase = (*p == REXPR_ICASE);
1855+
addLanguageRexprMap (language, map, icase, exclusiveInAllLanguages);
1856+
if (icase)
1857+
p++;
1858+
}
18261859
else
18271860
error (FATAL, "Badly formed language map for %s language",
18281861
getLanguageName (language));
@@ -1843,6 +1876,13 @@ static char* removeLanguageMap (const langType language, char* map_parameter)
18431876
removeLanguageExtensionMap (language, map);
18441877
else if (map && map_type == LMAP_PATTERN)
18451878
removeLanguagePatternMap (language, map);
1879+
else if (map && map_type == LMAP_REXPR)
1880+
{
1881+
bool icase = (*p == REXPR_ICASE);
1882+
removeLanguageRexprMap (language, map, icase);
1883+
if (icase)
1884+
p++;
1885+
}
18461886
else
18471887
error (FATAL, "Badly formed language map for %s language",
18481888
getLanguageName (language));
@@ -2164,6 +2204,13 @@ static void processListMapPatternsOption (const char *const option,
21642204
processListMapsOptionForType (option, parameter, LMAP_PATTERN|LMAP_TABLE_OUTPUT);
21652205
}
21662206

2207+
static void processListMapRegularExpressionsOption (const char *const option,
2208+
const char *const parameter)
2209+
{
2210+
processListMapsOptionForType (option, parameter, LMAP_REXPR|LMAP_TABLE_OUTPUT);
2211+
}
2212+
2213+
21672214
static void processListMapsOption (
21682215
const char *const option CTAGS_ATTR_UNUSED,
21692216
const char *const parameter CTAGS_ATTR_UNUSED)
@@ -2327,6 +2374,13 @@ static void processDescribeLanguage(const char *const option,
23272374
getLanguageVersionCurrent (language),
23282375
getLanguageVersionAge (language));
23292376

2377+
puts("");
2378+
puts("Mappings/rexprs");
2379+
puts("-------------------------------------------------------");
2380+
printLanguageMaps (language, LMAP_REXPR|LMAP_NO_LANG_PREFIX,
2381+
localOption.withListHeader, localOption.machinable,
2382+
stdout);
2383+
23302384
puts("");
23312385
puts("Mappings/patterns");
23322386
puts("-------------------------------------------------------");
@@ -2999,6 +3053,7 @@ static parametricOption ParametricOptions [] = {
29993053
{ "list-maps", processListMapsOption, true, STAGE_ANY },
30003054
{ "list-map-extensions", processListMapExtensionsOption, true, STAGE_ANY },
30013055
{ "list-map-patterns", processListMapPatternsOption, true, STAGE_ANY },
3056+
{ "list-map-regex", processListMapRegularExpressionsOption, true, STAGE_ANY },
30023057
{ "list-mline-regex-flags", processListMultilineRegexFlagsOption, true, STAGE_ANY },
30033058
{ "list-output-formats", processListOutputFormatsOption, true, STAGE_ANY },
30043059
{ "list-params", processListParametersOption, true, STAGE_ANY },

0 commit comments

Comments
 (0)