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 ()),
213+ ',' .join (list (GetAllExtensions ())),
214+ GetHeaderExtensions (),
215+ ',' .join (GetHeaderExtensions ()))
188216
189217# We categorize each error message we print. Here are the categories.
190218# We want an explicit list so we can list them all in cpplint --filter=.
@@ -536,6 +564,7 @@ def u(x):
536564 itervalues = dict .values
537565 iteritems = dict .items
538566
567+
539568def ParseNolintSuppressions (filename , raw_line , linenum , error ):
540569 """Updates the global list of error-suppressions.
541570
@@ -1094,7 +1123,7 @@ def NoExtension(self):
10941123
10951124 def IsSource (self ):
10961125 """File has a source file extension."""
1097- return self .Extension ()[1 :] in _valid_extensions
1126+ return self .Extension ()[1 :] in GetAllExtensions ()
10981127
10991128
11001129def _ShouldPrintError (category , confidence , linenum ):
@@ -1816,7 +1845,7 @@ def CheckHeaderFileIncluded(filename, include_state, error):
18161845 return
18171846
18181847 fileinfo = FileInfo (filename )
1819- for ext in _header_extensions :
1848+ for ext in GetHeaderExtensions () :
18201849 headerfile = filename [:filename .rfind ('.' ) + 1 ] + ext
18211850 if not os .path .exists (headerfile ):
18221851 continue
@@ -4472,7 +4501,7 @@ def CheckStyle(filename, clean_lines, linenum, file_extension, nesting_state,
44724501
44734502 # Check if the line is a header guard.
44744503 is_header_guard = False
4475- if file_extension in _header_extensions :
4504+ if file_extension in GetHeaderExtensions () :
44764505 cppvar = GetHeaderGuardCPPVariable (filename )
44774506 if (line .startswith ('#ifndef %s' % cppvar ) or
44784507 line .startswith ('#define %s' % cppvar ) or
@@ -4567,9 +4596,9 @@ def _DropCommonSuffixes(filename):
45674596 """
45684597 for suffix in itertools .chain (
45694598 ('%s.%s' % (test_suffix .lstrip ('_' ), ext )
4570- for test_suffix , ext in itertools .product (_test_suffixes , _nonheader_extensions )),
4599+ for test_suffix , ext in itertools .product (_test_suffixes , GetNonHeaderExtensions () )),
45714600 ('%s.%s' % (suffix , ext )
4572- for suffix , ext in itertools .product (['inl' , 'imp' , 'internal' ], _header_extensions ))):
4601+ for suffix , ext in itertools .product (['inl' , 'imp' , 'internal' ], GetHeaderExtensions () ))):
45734602 if (filename .endswith (suffix ) and len (filename ) > len (suffix ) and
45744603 filename [- len (suffix ) - 1 ] in ('-' , '_' )):
45754604 return filename [:- len (suffix ) - 1 ]
@@ -4585,7 +4614,7 @@ def _IsTestFilename(filename):
45854614 Returns:
45864615 True if 'filename' looks like a test, False otherwise.
45874616 """
4588- for test_suffix , ext in itertools .product (_test_suffixes , _nonheader_extensions ):
4617+ for test_suffix , ext in itertools .product (_test_suffixes , GetNonHeaderExtensions () ):
45894618 if filename .endswith (test_suffix + '.' + ext ):
45904619 return True
45914620 return False
@@ -4694,7 +4723,7 @@ def CheckIncludeLine(filename, clean_lines, linenum, include_state, error):
46944723 (include , filename , duplicate_line ))
46954724 return
46964725
4697- for extension in _nonheader_extensions :
4726+ for extension in GetNonHeaderExtensions () :
46984727 if (include .endswith ('.' + extension ) and
46994728 os .path .dirname (fileinfo .RepositoryName ()) != os .path .dirname (include )):
47004729 error (filename , linenum , 'build/include' , 4 ,
@@ -4851,7 +4880,7 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
48514880 CheckGlobalStatic (filename , clean_lines , linenum , error )
48524881 CheckPrintf (filename , clean_lines , linenum , error )
48534882
4854- if file_extension in _header_extensions :
4883+ if file_extension in GetHeaderExtensions () :
48554884 # TODO(unknown): check that 1-arg constructors are explicit.
48564885 # How to tell it's a constructor?
48574886 # (handled in CheckForNonStandardConstructs for now)
@@ -4958,7 +4987,7 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
49584987 # Check for use of unnamed namespaces in header files. Registration
49594988 # macros are typically OK, so we allow use of "namespace {" on lines
49604989 # that end with backslashes.
4961- if (file_extension in _header_extensions
4990+ if (file_extension in GetHeaderExtensions ()
49624991 and Search (r'\bnamespace\s*{' , line )
49634992 and line [- 1 ] != '\\ ' ):
49644993 error (filename , linenum , 'build/namespaces' , 4 ,
@@ -5600,11 +5629,11 @@ def FilesBelongToSameModule(filename_cc, filename_h):
56005629 string: the additional prefix needed to open the header file.
56015630 """
56025631 fileinfo_cc = FileInfo (filename_cc )
5603- if not fileinfo_cc .Extension ().lstrip ('.' ) in _nonheader_extensions :
5632+ if not fileinfo_cc .Extension ().lstrip ('.' ) in GetNonHeaderExtensions () :
56045633 return (False , '' )
56055634
56065635 fileinfo_h = FileInfo (filename_h )
5607- if not fileinfo_h .Extension ().lstrip ('.' ) in _header_extensions :
5636+ if not fileinfo_h .Extension ().lstrip ('.' ) in GetHeaderExtensions () :
56085637 return (False , '' )
56095638
56105639 filename_cc = filename_cc [:- (len (fileinfo_cc .Extension ()))]
@@ -5739,7 +5768,7 @@ def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error,
57395768 # TODO(unknown): Do a better job of finding .h files so we are confident that
57405769 # not having the .h file means there isn't one.
57415770 if not header_found :
5742- for extension in _nonheader_extensions :
5771+ for extension in GetNonHeaderExtensions () :
57435772 if filename .endswith ('.' + extension ):
57445773 return
57455774
@@ -6080,7 +6109,7 @@ def ProcessFileData(filename, file_extension, lines, error,
60806109 RemoveMultiLineComments (filename , lines , error )
60816110 clean_lines = CleansedLines (lines )
60826111
6083- if file_extension in _header_extensions :
6112+ if file_extension in GetHeaderExtensions () :
60846113 CheckForHeaderGuard (filename , clean_lines , error )
60856114
60866115 for line in range (clean_lines .NumLines ()):
@@ -6093,7 +6122,7 @@ def ProcessFileData(filename, file_extension, lines, error,
60936122 CheckForIncludeWhatYouUse (filename , clean_lines , include_state , error )
60946123
60956124 # Check that the .cc file has included its header if it exists.
6096- if file_extension in _nonheader_extensions :
6125+ if file_extension in GetNonHeaderExtensions () :
60976126 CheckHeaderFileIncluded (filename , include_state , error )
60986127
60996128 # We check here rather than inside ProcessLine so that we see raw
@@ -6160,6 +6189,24 @@ def ProcessConfigOverrides(filename):
61606189 _line_length = int (val )
61616190 except ValueError :
61626191 sys .stderr .write ('Line length must be numeric.' )
6192+ elif name == 'extensions' :
6193+ global _valid_extensions
6194+ try :
6195+ extensions = [ext .strip () for ext in val .split (',' )]
6196+ _valid_extensions = set (extensions )
6197+ except ValueError :
6198+ sys .stderr .write ('Extensions should be a comma-separated list of values;'
6199+ 'for example: extensions=hpp,cpp\n '
6200+ 'This could not be parsed: "%s"' % (val ,))
6201+ elif name == 'headers' :
6202+ global _header_extensions
6203+ try :
6204+ extensions = [ext .strip () for ext in val .split (',' )]
6205+ _header_extensions = set (extensions )
6206+ except ValueError :
6207+ sys .stderr .write ('Extensions should be a comma-separated list of values;'
6208+ 'for example: extensions=hpp,cpp\n '
6209+ 'This could not be parsed: "%s"' % (val ,))
61636210 else :
61646211 sys .stderr .write (
61656212 'Invalid configuration option (%s) in file %s\n ' %
@@ -6237,9 +6284,9 @@ def ProcessFile(filename, vlevel, extra_check_functions=[]):
62376284
62386285 # When reading from stdin, the extension is unknown, so no cpplint tests
62396286 # should rely on the extension.
6240- if filename != '-' and file_extension not in _valid_extensions :
6287+ if filename != '-' and file_extension not in GetAllExtensions () :
62416288 sys .stderr .write ('Ignoring %s; not a valid file name '
6242- '(%s)\n ' % (filename , ', ' .join (_valid_extensions )))
6289+ '(%s)\n ' % (filename , ', ' .join (GetAllExtensions () )))
62436290 else :
62446291 ProcessFileData (filename , file_extension , lines , Error ,
62456292 extra_check_functions )
@@ -6306,7 +6353,8 @@ def ParseArguments(args):
63066353 'filter=' ,
63076354 'root=' ,
63086355 'linelength=' ,
6309- 'extensions=' ])
6356+ 'extensions=' ,
6357+ 'headers=' ])
63106358 except getopt .GetoptError :
63116359 PrintUsage ('Invalid arguments.' )
63126360
@@ -6347,6 +6395,12 @@ def ParseArguments(args):
63476395 _valid_extensions = set (val .split (',' ))
63486396 except ValueError :
63496397 PrintUsage ('Extensions must be comma seperated list.' )
6398+ elif opt == '--headers' :
6399+ global _header_extensions
6400+ try :
6401+ _header_extensions = set (val .split (',' ))
6402+ except ValueError :
6403+ PrintUsage ('Extensions must be comma seperated list.' )
63506404
63516405 if not filenames :
63526406 PrintUsage ('No files were specified.' )
0 commit comments