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
@@ -1093,7 +1119,7 @@ def NoExtension(self):
10931119
10941120 def IsSource (self ):
10951121 """File has a source file extension."""
1096- return self .Extension ()[1 :] in _valid_extensions
1122+ return self .Extension ()[1 :] in GetAllExtensions ()
10971123
10981124
10991125def _ShouldPrintError (category , confidence , linenum ):
@@ -1815,7 +1841,7 @@ def CheckHeaderFileIncluded(filename, include_state, error):
18151841 return
18161842
18171843 fileinfo = FileInfo (filename )
1818- for ext in _header_extensions :
1844+ for ext in GetHeaderExtensions () :
18191845 headerfile = filename [:filename .rfind ('.' ) + 1 ] + ext
18201846 if not os .path .exists (headerfile ):
18211847 continue
@@ -4471,7 +4497,7 @@ def CheckStyle(filename, clean_lines, linenum, file_extension, nesting_state,
44714497
44724498 # Check if the line is a header guard.
44734499 is_header_guard = False
4474- if file_extension in _header_extensions :
4500+ if file_extension in GetHeaderExtensions () :
44754501 cppvar = GetHeaderGuardCPPVariable (filename )
44764502 if (line .startswith ('#ifndef %s' % cppvar ) or
44774503 line .startswith ('#define %s' % cppvar ) or
@@ -4562,9 +4588,9 @@ def _DropCommonSuffixes(filename):
45624588 """
45634589 for suffix in itertools .chain (
45644590 ('%s.%s' % (test_suffix .lstrip ('_' ), ext )
4565- for test_suffix , ext in itertools .product (_test_suffixes , _nonheader_extensions )),
4591+ for test_suffix , ext in itertools .product (_test_suffixes , GetNonHeaderExtensions () )),
45664592 ('%s.%s' % (suffix , ext )
4567- for suffix , ext in itertools .product (['inl' , 'imp' , 'internal' ], _header_extensions ))):
4593+ for suffix , ext in itertools .product (['inl' , 'imp' , 'internal' ], GetHeaderExtensions () ))):
45684594 if (filename .endswith (suffix ) and len (filename ) > len (suffix ) and
45694595 filename [- len (suffix ) - 1 ] in ('-' , '_' )):
45704596 return filename [:- len (suffix ) - 1 ]
@@ -4580,7 +4606,7 @@ def _IsTestFilename(filename):
45804606 Returns:
45814607 True if 'filename' looks like a test, False otherwise.
45824608 """
4583- for test_suffix , ext in itertools .product (_test_suffixes , _nonheader_extensions ):
4609+ for test_suffix , ext in itertools .product (_test_suffixes , GetNonHeaderExtensions () ):
45844610 if filename .endswith (test_suffix + '.' + ext ):
45854611 return True
45864612 return False
@@ -4689,7 +4715,7 @@ def CheckIncludeLine(filename, clean_lines, linenum, include_state, error):
46894715 (include , filename , duplicate_line ))
46904716 return
46914717
4692- for extension in _nonheader_extensions :
4718+ for extension in GetNonHeaderExtensions () :
46934719 if (include .endswith ('.' + extension ) and
46944720 os .path .dirname (fileinfo .RepositoryName ()) != os .path .dirname (include )):
46954721 error (filename , linenum , 'build/include' , 4 ,
@@ -4846,7 +4872,7 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
48464872 CheckGlobalStatic (filename , clean_lines , linenum , error )
48474873 CheckPrintf (filename , clean_lines , linenum , error )
48484874
4849- if file_extension in _header_extensions :
4875+ if file_extension in GetHeaderExtensions () :
48504876 # TODO(unknown): check that 1-arg constructors are explicit.
48514877 # How to tell it's a constructor?
48524878 # (handled in CheckForNonStandardConstructs for now)
@@ -4953,7 +4979,7 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
49534979 # Check for use of unnamed namespaces in header files. Registration
49544980 # macros are typically OK, so we allow use of "namespace {" on lines
49554981 # that end with backslashes.
4956- if (file_extension in _header_extensions
4982+ if (file_extension in GetHeaderExtensions ()
49574983 and Search (r'\bnamespace\s*{' , line )
49584984 and line [- 1 ] != '\\ ' ):
49594985 error (filename , linenum , 'build/namespaces' , 4 ,
@@ -5595,11 +5621,11 @@ def FilesBelongToSameModule(filename_cc, filename_h):
55955621 string: the additional prefix needed to open the header file.
55965622 """
55975623 fileinfo_cc = FileInfo (filename_cc )
5598- if not fileinfo_cc .Extension ().lstrip ('.' ) in _nonheader_extensions :
5624+ if not fileinfo_cc .Extension ().lstrip ('.' ) in GetNonHeaderExtensions () :
55995625 return (False , '' )
56005626
56015627 fileinfo_h = FileInfo (filename_h )
5602- if not fileinfo_h .Extension ().lstrip ('.' ) in _header_extensions :
5628+ if not fileinfo_h .Extension ().lstrip ('.' ) in GetHeaderExtensions () :
56035629 return (False , '' )
56045630
56055631 filename_cc = filename_cc [:- (len (fileinfo_cc .Extension ()))]
@@ -5734,7 +5760,7 @@ def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error,
57345760 # TODO(unknown): Do a better job of finding .h files so we are confident that
57355761 # not having the .h file means there isn't one.
57365762 if not header_found :
5737- for extension in _nonheader_extensions :
5763+ for extension in GetNonHeaderExtensions () :
57385764 if filename .endswith ('.' + extension ):
57395765 return
57405766
@@ -6075,7 +6101,7 @@ def ProcessFileData(filename, file_extension, lines, error,
60756101 RemoveMultiLineComments (filename , lines , error )
60766102 clean_lines = CleansedLines (lines )
60776103
6078- if file_extension in _header_extensions :
6104+ if file_extension in GetHeaderExtensions () :
60796105 CheckForHeaderGuard (filename , clean_lines , error )
60806106
60816107 for line in range (clean_lines .NumLines ()):
@@ -6088,7 +6114,7 @@ def ProcessFileData(filename, file_extension, lines, error,
60886114 CheckForIncludeWhatYouUse (filename , clean_lines , include_state , error )
60896115
60906116 # Check that the .cc file has included its header if it exists.
6091- if file_extension in _nonheader_extensions :
6117+ if file_extension in GetNonHeaderExtensions () :
60926118 CheckHeaderFileIncluded (filename , include_state , error )
60936119
60946120 # We check here rather than inside ProcessLine so that we see raw
@@ -6155,6 +6181,24 @@ def ProcessConfigOverrides(filename):
61556181 _line_length = int (val )
61566182 except ValueError :
61576183 sys .stderr .write ('Line length must be numeric.' )
6184+ elif name == 'extensions' :
6185+ global _valid_extensions
6186+ try :
6187+ extensions = [ext .strip () for ext in val .split (',' )]
6188+ _valid_extensions = set (extensions )
6189+ except ValueError :
6190+ sys .stderr .write ('Extensions should be a comma-separated list of values;'
6191+ 'for example: extensions=hpp,cpp\n '
6192+ 'This could not be parsed: "%s"' % (val ,))
6193+ elif name == 'headers' :
6194+ global _header_extensions
6195+ try :
6196+ extensions = [ext .strip () for ext in val .split (',' )]
6197+ _header_extensions = set (extensions )
6198+ except ValueError :
6199+ sys .stderr .write ('Extensions should be a comma-separated list of values;'
6200+ 'for example: extensions=hpp,cpp\n '
6201+ 'This could not be parsed: "%s"' % (val ,))
61586202 else :
61596203 sys .stderr .write (
61606204 'Invalid configuration option (%s) in file %s\n ' %
@@ -6301,7 +6345,8 @@ def ParseArguments(args):
63016345 'filter=' ,
63026346 'root=' ,
63036347 'linelength=' ,
6304- 'extensions=' ])
6348+ 'extensions=' ,
6349+ 'headers=' ])
63056350 except getopt .GetoptError :
63066351 PrintUsage ('Invalid arguments.' )
63076352
@@ -6342,6 +6387,12 @@ def ParseArguments(args):
63426387 _valid_extensions = set (val .split (',' ))
63436388 except ValueError :
63446389 PrintUsage ('Extensions must be comma seperated list.' )
6390+ elif opt == '--headers' :
6391+ global _header_extensions
6392+ try :
6393+ _header_extensions = set (val .split (',' ))
6394+ except ValueError :
6395+ PrintUsage ('Extensions must be comma seperated list.' )
63456396
63466397 if not filenames :
63476398 PrintUsage ('No files were specified.' )
0 commit comments