5353import sys
5454import unicodedata
5555
56+ # if empty, use defaults
57+ _header_extensions = set ([])
58+
59+ # if empty, use defaults
60+ _valid_extensions = set ([])
61+
62+
5663# Files with any of these extensions are considered to be
5764# header files (and will undergo different style checks).
5865# This set can be extended by using the --headers
5966# option (also supported in CPPLINT.cfg)
60- _header_extensions = set (['h' , 'hpp' , 'hxx' , 'h++' , 'cuh' ])
61- _nonheader_extensions = set (['c' , 'cc' , 'cpp' , 'cxx' , 'c++' , 'cu' ])
62-
67+ def GetHeaderExtensions ():
68+ if not _header_extensions :
69+ return set (['h' , 'hpp' , 'hxx' , 'h++' , 'cuh' ])
70+ return _header_extensions
6371
6472# The allowed extensions for file names
65- # This is set by --extensions flag.
66- _valid_extensions = _nonheader_extensions .union (_header_extensions )
73+ # This is set by --extensions flag
74+ def GetAllExtensions ():
75+ if not _valid_extensions :
76+ return GetHeaderExtensions ().union (set (['c' , 'cc' , 'cpp' , 'cxx' , 'c++' , 'cu' ]))
77+ return _valid_extensions
78+
79+ def GetNonHeaderExtensions ():
80+ return GetAllExtensions ().difference (GetHeaderExtensions ())
81+
6782
6883# files with this suffix before the extension will be treated as test files
6984_test_suffixes = set (['_unittest' , '_test' , '_regtest' ])
7287Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
7388 [--counting=total|toplevel|detailed] [--root=subdir]
7489 [--linelength=digits]
90+ [--headers=ext1,ext2]
91+ [--extensions=ext1,ext2]
7592 <file> [file] ...
7693
7794 The style guidelines this tries to follow are those in
148165 The allowed file extensions that cpplint will check
149166
150167 Examples:
151- --extensions=hpp,cpp
168+ --extensions=%s
169+
170+ headers=extension,extension,...
171+ The allowed header extensions that cpplint will consider to be header files
172+ (by default, only files with extensions %s
173+ will be assumed to be headers)
174+
175+ Examples:
176+ --headers=%s
152177
153178 cpplint.py supports per-directory configurations specified in CPPLINT.cfg
154179 files. CPPLINT.cfg file can contain a number of key=value pairs.
184209 build/include_alpha as well as excludes all .cc from being
185210 processed by linter, in the current directory (where the .cfg
186211 file is located) and all sub-directories.
187- """ % (list (_valid_extensions ))
212+ """ % (list (GetAllExtensions ()), ',' . join ( list ( GetAllExtensions ())), GetHeaderExtensions (), ',' . join ( GetHeaderExtensions () ))
188213
189214# We categorize each error message we print. Here are the categories.
190215# We want an explicit list so we can list them all in cpplint --filter=.
@@ -536,6 +561,7 @@ def u(x):
536561 itervalues = dict .values
537562 iteritems = dict .items
538563
564+
539565def ParseNolintSuppressions (filename , raw_line , linenum , error ):
540566 """Updates the global list of error-suppressions.
541567
@@ -1094,7 +1120,7 @@ def NoExtension(self):
10941120
10951121 def IsSource (self ):
10961122 """File has a source file extension."""
1097- return self .Extension ()[1 :] in _valid_extensions
1123+ return self .Extension ()[1 :] in GetAllExtensions ()
10981124
10991125
11001126def _ShouldPrintError (category , confidence , linenum ):
@@ -1816,7 +1842,7 @@ def CheckHeaderFileIncluded(filename, include_state, error):
18161842 return
18171843
18181844 fileinfo = FileInfo (filename )
1819- for ext in _header_extensions :
1845+ for ext in GetHeaderExtensions () :
18201846 headerfile = filename [:filename .rfind ('.' ) + 1 ] + ext
18211847 if not os .path .exists (headerfile ):
18221848 continue
@@ -4472,7 +4498,7 @@ def CheckStyle(filename, clean_lines, linenum, file_extension, nesting_state,
44724498
44734499 # Check if the line is a header guard.
44744500 is_header_guard = False
4475- if file_extension in _header_extensions :
4501+ if file_extension in GetHeaderExtensions () :
44764502 cppvar = GetHeaderGuardCPPVariable (filename )
44774503 if (line .startswith ('#ifndef %s' % cppvar ) or
44784504 line .startswith ('#define %s' % cppvar ) or
@@ -4567,9 +4593,9 @@ def _DropCommonSuffixes(filename):
45674593 """
45684594 for suffix in itertools .chain (
45694595 ('%s.%s' % (test_suffix .lstrip ('_' ), ext )
4570- for test_suffix , ext in itertools .product (_test_suffixes , _nonheader_extensions )),
4596+ for test_suffix , ext in itertools .product (_test_suffixes , GetNonHeaderExtensions () )),
45714597 ('%s.%s' % (suffix , ext )
4572- for suffix , ext in itertools .product (['inl' , 'imp' , 'internal' ], _header_extensions ))):
4598+ for suffix , ext in itertools .product (['inl' , 'imp' , 'internal' ], GetHeaderExtensions () ))):
45734599 if (filename .endswith (suffix ) and len (filename ) > len (suffix ) and
45744600 filename [- len (suffix ) - 1 ] in ('-' , '_' )):
45754601 return filename [:- len (suffix ) - 1 ]
@@ -4585,7 +4611,7 @@ def _IsTestFilename(filename):
45854611 Returns:
45864612 True if 'filename' looks like a test, False otherwise.
45874613 """
4588- for test_suffix , ext in itertools .product (_test_suffixes , _nonheader_extensions ):
4614+ for test_suffix , ext in itertools .product (_test_suffixes , GetNonHeaderExtensions () ):
45894615 if filename .endswith (test_suffix + '.' + ext ):
45904616 return True
45914617 return False
@@ -4694,7 +4720,7 @@ def CheckIncludeLine(filename, clean_lines, linenum, include_state, error):
46944720 (include , filename , duplicate_line ))
46954721 return
46964722
4697- for extension in _nonheader_extensions :
4723+ for extension in GetNonHeaderExtensions () :
46984724 if (include .endswith ('.' + extension ) and
46994725 os .path .dirname (fileinfo .RepositoryName ()) != os .path .dirname (include )):
47004726 error (filename , linenum , 'build/include' , 4 ,
@@ -4851,7 +4877,7 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
48514877 CheckGlobalStatic (filename , clean_lines , linenum , error )
48524878 CheckPrintf (filename , clean_lines , linenum , error )
48534879
4854- if file_extension in _header_extensions :
4880+ if file_extension in GetHeaderExtensions () :
48554881 # TODO(unknown): check that 1-arg constructors are explicit.
48564882 # How to tell it's a constructor?
48574883 # (handled in CheckForNonStandardConstructs for now)
@@ -4958,7 +4984,7 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
49584984 # Check for use of unnamed namespaces in header files. Registration
49594985 # macros are typically OK, so we allow use of "namespace {" on lines
49604986 # that end with backslashes.
4961- if (file_extension in _header_extensions
4987+ if (file_extension in GetHeaderExtensions ()
49624988 and Search (r'\bnamespace\s*{' , line )
49634989 and line [- 1 ] != '\\ ' ):
49644990 error (filename , linenum , 'build/namespaces' , 4 ,
@@ -5600,11 +5626,11 @@ def FilesBelongToSameModule(filename_cc, filename_h):
56005626 string: the additional prefix needed to open the header file.
56015627 """
56025628 fileinfo_cc = FileInfo (filename_cc )
5603- if not fileinfo_cc .Extension ().lstrip ('.' ) in _nonheader_extensions :
5629+ if not fileinfo_cc .Extension ().lstrip ('.' ) in GetNonHeaderExtensions () :
56045630 return (False , '' )
56055631
56065632 fileinfo_h = FileInfo (filename_h )
5607- if not fileinfo_h .Extension ().lstrip ('.' ) in _header_extensions :
5633+ if not fileinfo_h .Extension ().lstrip ('.' ) in GetHeaderExtensions () :
56085634 return (False , '' )
56095635
56105636 filename_cc = filename_cc [:- (len (fileinfo_cc .Extension ()))]
@@ -5739,7 +5765,7 @@ def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error,
57395765 # TODO(unknown): Do a better job of finding .h files so we are confident that
57405766 # not having the .h file means there isn't one.
57415767 if not header_found :
5742- for extension in _nonheader_extensions :
5768+ for extension in GetNonHeaderExtensions () :
57435769 if filename .endswith ('.' + extension ):
57445770 return
57455771
@@ -6080,7 +6106,7 @@ def ProcessFileData(filename, file_extension, lines, error,
60806106 RemoveMultiLineComments (filename , lines , error )
60816107 clean_lines = CleansedLines (lines )
60826108
6083- if file_extension in _header_extensions :
6109+ if file_extension in GetHeaderExtensions () :
60846110 CheckForHeaderGuard (filename , clean_lines , error )
60856111
60866112 for line in range (clean_lines .NumLines ()):
@@ -6093,7 +6119,7 @@ def ProcessFileData(filename, file_extension, lines, error,
60936119 CheckForIncludeWhatYouUse (filename , clean_lines , include_state , error )
60946120
60956121 # Check that the .cc file has included its header if it exists.
6096- if file_extension in _nonheader_extensions :
6122+ if file_extension in GetNonHeaderExtensions () :
60976123 CheckHeaderFileIncluded (filename , include_state , error )
60986124
60996125 # We check here rather than inside ProcessLine so that we see raw
@@ -6160,6 +6186,24 @@ def ProcessConfigOverrides(filename):
61606186 _line_length = int (val )
61616187 except ValueError :
61626188 sys .stderr .write ('Line length must be numeric.' )
6189+ elif name == 'extensions' :
6190+ global _valid_extensions
6191+ try :
6192+ extensions = [ext .strip () for ext in val .split (',' )]
6193+ _valid_extensions = set (extensions )
6194+ except ValueError :
6195+ sys .stderr .write ('Extensions should be a comma-separated list of values;'
6196+ 'for example: extensions=hpp,cpp\n '
6197+ 'This could not be parsed: "%s"' % (val ,))
6198+ elif name == 'headers' :
6199+ global _header_extensions
6200+ try :
6201+ extensions = [ext .strip () for ext in val .split (',' )]
6202+ _header_extensions = set (extensions )
6203+ except ValueError :
6204+ sys .stderr .write ('Extensions should be a comma-separated list of values;'
6205+ 'for example: extensions=hpp,cpp\n '
6206+ 'This could not be parsed: "%s"' % (val ,))
61636207 else :
61646208 sys .stderr .write (
61656209 'Invalid configuration option (%s) in file %s\n ' %
@@ -6237,9 +6281,9 @@ def ProcessFile(filename, vlevel, extra_check_functions=[]):
62376281
62386282 # When reading from stdin, the extension is unknown, so no cpplint tests
62396283 # should rely on the extension.
6240- if filename != '-' and file_extension not in _valid_extensions :
6284+ if filename != '-' and file_extension not in GetAllExtensions () :
62416285 sys .stderr .write ('Ignoring %s; not a valid file name '
6242- '(%s)\n ' % (filename , ', ' .join (_valid_extensions )))
6286+ '(%s)\n ' % (filename , ', ' .join (GetAllExtensions () )))
62436287 else :
62446288 ProcessFileData (filename , file_extension , lines , Error ,
62456289 extra_check_functions )
@@ -6306,7 +6350,8 @@ def ParseArguments(args):
63066350 'filter=' ,
63076351 'root=' ,
63086352 'linelength=' ,
6309- 'extensions=' ])
6353+ 'extensions=' ,
6354+ 'headers=' ])
63106355 except getopt .GetoptError :
63116356 PrintUsage ('Invalid arguments.' )
63126357
@@ -6347,6 +6392,12 @@ def ParseArguments(args):
63476392 _valid_extensions = set (val .split (',' ))
63486393 except ValueError :
63496394 PrintUsage ('Extensions must be comma seperated list.' )
6395+ elif opt == '--headers' :
6396+ global _header_extensions
6397+ try :
6398+ _header_extensions = set (val .split (',' ))
6399+ except ValueError :
6400+ PrintUsage ('Extensions must be comma seperated list.' )
63506401
63516402 if not filenames :
63526403 PrintUsage ('No files were specified.' )
0 commit comments