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+
21612208static 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