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