Skip to content

Include what you use cout and printf #94

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
initial commit
  • Loading branch information
geoffviola committed Mar 1, 2019
commit 2e723e93f5f0a992a76540fbf7bf3f3ff734a526
67 changes: 48 additions & 19 deletions cpplint.py
Original file line number Diff line number Diff line change
Expand Up @@ -5641,7 +5641,26 @@ def ExpectingFunctionArgs(clean_lines, linenum):
('<utility>', ('forward', 'make_pair', 'move', 'swap')),
)

_RE_PATTERN_STRING = re.compile(r'\bstring\b')
# Non templated types or global objects
_HEADERS_TYPES_OR_OBJS = (
# String and others are special -- it is a non-templatized type in STL.
('<string>', ('string',)),
('<iostream>', ('cin', 'cout', 'cerr', 'clog', 'wcin', 'wcout',
'wcerr', 'wclog')),
('<cstdio>', ('FILE', 'fpos_t')))

# Non templated functions
_HEADERS_FUNCTIONS = (
('<cstdio>', ('fopen', 'freopen',
'fclose', 'fflush', 'setbuf', 'setvbuf', 'fread',
'fwrite', 'fgetc', 'getc', 'fgets', 'fputc', 'putc',
'fputs', 'getchar', 'gets', 'putchar', 'puts', 'ungetc',
'scanf', 'fscanf', 'sscanf', 'vscanf', 'vfscanf',
'vsscanf', 'printf', 'fprintf', 'sprintf', 'snprintf',
'vprintf', 'vfprintf', 'vsprintf', 'vsnprintf',
'ftell', 'fgetpos', 'fseek', 'fsetpos',
'clearerr', 'feof', 'ferror', 'perror',
'tmpfile', 'tmpnam'),),)

_re_pattern_headers_maybe_templates = []
for _header, _templates in _HEADERS_MAYBE_TEMPLATES:
Expand All @@ -5662,6 +5681,23 @@ def ExpectingFunctionArgs(clean_lines, linenum):
_template + '<>',
_header))

_re_pattern_types_or_objs = []
for _header, _types_or_objs in _HEADERS_TYPES_OR_OBJS:
for _type_or_obj in _types_or_objs:
_re_pattern_types_or_objs.append(
(re.compile(r'\b' + _type_or_obj + r'\b'),
_type_or_obj,
_header))

_re_pattern_functions = []
for _header, _functions in _HEADERS_FUNCTIONS:
for _function in _functions:
# Match printf(..., ...), but not foo->printf, foo.printf or
# 'type::printf()'.
_re_pattern_functions.append(
(re.compile(r'([^>.]|^)\b' + _function + r'\([^\)]'),
_function,
_header))

def FilesBelongToSameModule(filename_cc, filename_h):
"""Check if these two filenames belong to the same module.
Expand Down Expand Up @@ -5774,14 +5810,17 @@ def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error,
if not line or line[0] == '#':
continue

# String is special -- it is a non-templatized type in STL.
matched = _RE_PATTERN_STRING.search(line)
if matched:
# Don't warn about strings in non-STL namespaces:
# (We check only the first match per line; good enough.)
prefix = line[:matched.start()]
if prefix.endswith('std::') or not prefix.endswith('::'):
required['<string>'] = (linenum, 'string')
_re_patterns = []
_re_patterns.extend(_re_pattern_types_or_objs)
_re_patterns.extend(_re_pattern_functions)
for pattern, item, header in _re_patterns:
matched = pattern.search(line)
if matched:
# Don't warn about strings in non-STL namespaces:
# (We check only the first match per line; good enough.)
prefix = line[:matched.start()]
if prefix.endswith('std::') or not prefix.endswith('::'):
required[header] = (linenum, item)

for pattern, template, header in _re_pattern_headers_maybe_templates:
if pattern.search(line):
Expand Down Expand Up @@ -5830,16 +5869,6 @@ def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error,
if same_module and UpdateIncludeState(fullpath, include_dict, io):
header_found = True

# If we can't find the header file for a .cc, assume it's because we don't
# know where to look. In that case we'll give up as we're not sure they
# didn't include it in the .h file.
# TODO(unknown): Do a better job of finding .h files so we are confident that
# not having the .h file means there isn't one.
if not header_found:
for extension in GetNonHeaderExtensions():
if filename.endswith('.' + extension):
return

# All the lines have been processed, report the errors found.
for required_header_unstripped in sorted(required, key=required.__getitem__):
template = required[required_header_unstripped][1]
Expand Down
24 changes: 13 additions & 11 deletions cpplint_unittest.py
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,7 @@ def testErrorSuppression(self):
error_collector = ErrorCollector(self.assert_)
cpplint.ProcessFileData('test.cc', 'cc',
['// Copyright 2014 Your Company.',
'#include <iostream>',
'for (int i = 0; i != 100; ++i) {',
' std::cout << i << std::endl;',
'}; // NOLINT',
Expand Down Expand Up @@ -929,13 +930,11 @@ def testTypedefForPointerToFunction(self):

def testIncludeWhatYouUseNoImplementationFiles(self):
code = 'std::vector<int> foo;'
for extension in ['h', 'hpp', 'hxx', 'h++', 'cuh']:
for extension in ['h', 'hpp', 'hxx', 'h++', 'cuh',
'c', 'cc', 'cpp', 'cxx', 'c++', 'cu']:
self.assertEquals('Add #include <vector> for vector<>'
' [build/include_what_you_use] [4]',
self.PerformIncludeWhatYouUse(code, 'foo.' + extension))
for extension in ['c', 'cc', 'cpp', 'cxx', 'c++', 'cu']:
self.assertEquals('',
self.PerformIncludeWhatYouUse(code, 'foo.' + extension))

def testIncludeWhatYouUse(self):
self.TestIncludeWhatYouUse(
Expand Down Expand Up @@ -1022,6 +1021,12 @@ def testIncludeWhatYouUse(self):
bool foobar = min<int>(0,1);
""",
'Add #include <algorithm> for min [build/include_what_you_use] [4]')
self.TestIncludeWhatYouUse(
'cout << "hello world" << endl;',
'Add #include <iostream> for cout [build/include_what_you_use] [4]')
self.TestIncludeWhatYouUse(
'printf("hello world");',
'Add #include <cstdio> for printf [build/include_what_you_use] [4]')
self.TestIncludeWhatYouUse(
'void a(const string &foobar);',
'Add #include <string> for string [build/include_what_you_use] [4]')
Expand Down Expand Up @@ -1147,13 +1152,6 @@ def testIncludeWhatYouUse(self):
self.assertEquals(message, 'Add #include <set> for set<> '
'[build/include_what_you_use] [4]')

# If there's just a cc and the header can't be found then it's ok.
message = self.PerformIncludeWhatYouUse(
"""#include "blah/a.h"
std::set<int> foo;""",
filename='blah/a.cc')
self.assertEquals(message, '')

# Make sure we find the headers with relative paths.
mock_header_contents = ['']
message = self.PerformIncludeWhatYouUse(
Expand Down Expand Up @@ -2404,6 +2402,8 @@ def testNonConstReference(self):
cpplint.ProcessFileData(
'foo.cc', 'cc',
['// Copyright 2014 Your Company. All Rights Reserved.',
'#include <string>',
'#include <utility>',
'void swap(int &x,',
' int &y) {',
'}',
Expand Down Expand Up @@ -2996,6 +2996,7 @@ def testStaticOrGlobalSTLStrings(self):
error_collector = ErrorCollector(self.assert_)
cpplint.ProcessFileData('foo.cc', 'cc',
['// Copyright 2014 Your Company.',
'#include <string>',
'string Class',
'::MemberFunction1();',
'string Class::',
Expand Down Expand Up @@ -4767,6 +4768,7 @@ def testBuildPrintfFormat(self):
cpplint.ProcessFileData(
'foo.cc', 'cc',
['// Copyright 2014 Your Company.',
'#include <cstdio>',
r'printf("\\%%%d", value);',
r'printf(R"(\[)");',
r'printf(R"(\[%s)", R"(\])");',
Expand Down
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy