+# List of source file extensions which require preprocessing.
+my @source_preprocess_compile_cpp = (
+ # C++
+ qw( cc cp cxx cpp CPP c++ C ),
+ # Objective-C++
+ qw( mm Mr),
+);
+my @source_preprocess_compile = (
+ # C
+ qw( c ),
+ # Objective-C
+ qw( m ),
+ # (Objective-)C++
+ @source_preprocess_compile_cpp,
+ # Fortran
+ qw( F FOR fpp FPP FTN F90 F95 F03 F08 ),
+);
+my @source_preprocess_no_compile = (
+ # Assembly
+ qw( s ),
+);
+my @source_preprocess = (
+ @source_preprocess_compile,
+ @source_preprocess_no_compile,
+);
+# List of source file extensions which don't require preprocessing.
+my @source_no_preprocess_compile_cpp = (
+ # C++
+ qw( ii ),
+ # Objective-C++
+ qw( mii ),
+);
+my @source_no_preprocess_compile = (
+ # C
+ qw( i ),
+ # (Objective-)C++
+ @source_no_preprocess_compile_cpp,
+ # Objective-C
+ qw( mi ),
+ # Fortran
+ qw( f for ftn f90 f95 f03 f08 ),
+);
+my @source_no_preprocess_no_compile = (
+ # Assembly
+ qw( S sx ),
+);
+my @source_no_preprocess = (
+ @source_no_preprocess_compile,
+ @source_no_preprocess_no_compile,
+);
+# List of header file extensions which require preprocessing.
+my @header_preprocess = (
+ # C, C++, Objective-C, Objective-C++
+ qw( h ),
+ # C++
+ qw( hh H hp hxx hpp HPP h++ tcc ),
+);
+
+# Hashes for fast extensions lookup to check if a file falls in one of these
+# categories.
+my %extensions_no_preprocess = map { $_ => 1 } (
+ @source_no_preprocess,
+);
+my %extensions_preprocess = map { $_ => 1 } (
+ @header_preprocess,
+ @source_preprocess,
+);
+my %extensions_compile_link = map { $_ => 1 } (
+ @source_preprocess,
+ @source_no_preprocess,
+);
+my %extensions_compile = map { $_ => 1 } (
+ @source_preprocess_compile,
+ @source_no_preprocess_compile,
+);
+my %extensions_no_compile = map { $_ => 1 } (
+ @source_preprocess_no_compile,
+ @source_no_preprocess_no_compile,
+);
+my %extensions_compile_cpp = map { $_ => 1 } (
+ @source_preprocess_compile_cpp,
+ @source_no_preprocess_compile_cpp,
+);
+my %extension = map { $_ => 1 } (
+ @source_no_preprocess,
+ @source_no_preprocess_compile,
+ @source_no_preprocess_compile_cpp,
+ @source_no_preprocess_no_compile,
+ @header_preprocess,
+ @source_preprocess,
+ @source_preprocess_compile,
+ @source_preprocess_compile_cpp,
+ @source_preprocess_no_compile,
+);
+
+# Regexp to match file extensions.
+my $file_extension_regex = qr/
+ \s
+ \S+ # Filename without extension.
+ \.
+ ([^\\.\s]+) # File extension.
+ (?=\s|\\) # At end of word. Can't use \b because some files have non
+ # word characters at the end and because \b matches double
+ # extensions (like .cpp.o). Works always as all lines are
+ # terminated with "\n".
+ /x;
+