1ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#!/usr/bin/python 2ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# 3ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# Copyright (c) 2009 Google Inc. All rights reserved. 4ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# 5ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# Redistribution and use in source and binary forms, with or without 6ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# modification, are permitted provided that the following conditions are 7ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# met: 8ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# 9ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# * Redistributions of source code must retain the above copyright 10ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# notice, this list of conditions and the following disclaimer. 11ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# * Redistributions in binary form must reproduce the above 12ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# copyright notice, this list of conditions and the following disclaimer 13ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# in the documentation and/or other materials provided with the 14ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# distribution. 15ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# * Neither the name of Google Inc. nor the names of its 16ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# contributors may be used to endorse or promote products derived from 17ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# this software without specific prior written permission. 18ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# 19ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 31ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang"""Does google-lint on c++ files. 32ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 33ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangThe goal of this script is to identify places in the code that *may* 34ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangbe in non-compliance with google style. It does not attempt to fix 35ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangup these problems -- the point is to educate. It does also not 36ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangattempt to find all problems, or to ensure that everything it does 37ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangfind is legitimately a problem. 38ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 39ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangIn particular, we can get very confused by /* and // inside strings! 40ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangWe do a small hack, which is to ignore //'s with "'s after them on the 41ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangsame line, but it is far from perfect (in either direction). 42ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang""" 43ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 44ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangimport codecs 45ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangimport copy 46ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangimport getopt 47ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangimport math # for log 48ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangimport os 49ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangimport re 50ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangimport sre_compile 51ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangimport string 52ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangimport sys 53ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangimport unicodedata 54ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 55ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 56ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_USAGE = """ 57ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangSyntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...] 58b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian [--counting=total|toplevel|detailed] [--root=subdir] 59b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian [--linelength=digits] 60ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang <file> [file] ... 61ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 62ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang The style guidelines this tries to follow are those in 63ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml 64ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 65ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Every problem is given a confidence score from 1-5, with 5 meaning we are 66ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang certain of the problem, and 1 meaning it could be a legitimate construct. 67ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang This will miss some errors, and is not a substitute for a code review. 68ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 69ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang To suppress false-positive errors of a certain category, add a 70ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'NOLINT(category)' comment to the line. NOLINT or NOLINT(*) 71ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang suppresses errors of all categories on that line. 72ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 73ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang The files passed in will be linted; at least one file must be provided. 74b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian Default linted extensions are .cc, .cpp, .cu, .cuh and .h. Change the 75b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian extensions with the --extensions flag. 76ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 77ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Flags: 78ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 79ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang output=vs7 80ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang By default, the output is formatted to ease emacs parsing. Visual Studio 81ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang compatible output (vs7) may also be used. Other formats are unsupported. 82ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 83ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang verbose=# 84ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Specify a number 0-5 to restrict errors to certain verbosity levels. 85ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 86ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filter=-x,+y,... 87ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Specify a comma-separated list of category-filters to apply: only 88ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error messages whose category names pass the filters will be printed. 89ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (Category names are printed with the message and look like 90ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang "[whitespace/indent]".) Filters are evaluated left to right. 91ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang "-FOO" and "FOO" means "do not print categories that start with FOO". 92ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang "+FOO" means "do print categories that start with FOO". 93ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 94ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Examples: --filter=-whitespace,+whitespace/braces 95ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang --filter=whitespace,runtime/printf,+runtime/printf_format 96ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang --filter=-,+build/include_what_you_use 97ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 98ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang To see a list of all the categories used in cpplint, pass no arg: 99ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang --filter= 100ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 101ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang counting=total|toplevel|detailed 102ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang The total number of errors found is always printed. If 103ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'toplevel' is provided, then the count of errors in each of 104ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang the top-level categories like 'build' and 'whitespace' will 105ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang also be printed. If 'detailed' is provided, then a count 106ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang is provided for each category like 'build/class'. 107ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 108ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang root=subdir 109ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang The root directory used for deriving header guard CPP variable. 110ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang By default, the header guard CPP variable is calculated as the relative 111ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang path to the directory that contains .git, .hg, or .svn. When this flag 112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang is specified, the relative path is calculated from the specified 113ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang directory. If the specified directory does not exist, this flag is 114ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ignored. 115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Examples: 117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Assuing that src/.git exists, the header guard CPP variables for 118ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang src/chrome/browser/ui/browser.h are: 119ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 120ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang No flag => CHROME_BROWSER_UI_BROWSER_H_ 121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang --root=chrome => BROWSER_UI_BROWSER_H_ 122ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang --root=chrome/browser => UI_BROWSER_H_ 123b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 124b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian linelength=digits 125b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian This is the allowed line length for the project. The default value is 126b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 80 characters. 127b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 128b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian Examples: 129b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian --linelength=120 130b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 131b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian extensions=extension,extension,... 132b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian The allowed file extensions that cpplint will check 133b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 134b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian Examples: 135b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian --extensions=hpp,cpp 136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang""" 137ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# We categorize each error message we print. Here are the categories. 139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# We want an explicit list so we can list them all in cpplint --filter=. 140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# If you add a new error message with a new category, add it to the list 141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# here! cpplint_unittest.py should tell you if you forget to do this. 142ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_ERROR_CATEGORIES = [ 143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'build/class', 144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'build/deprecated', 145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'build/endif_comment', 146ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'build/explicit_make_pair', 147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'build/forward_decl', 148ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'build/header_guard', 149ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'build/include', 150ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'build/include_alpha', 151ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'build/include_order', 152ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'build/include_what_you_use', 153ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'build/namespaces', 154ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'build/printf_format', 155ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'build/storage_class', 156ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'legal/copyright', 157ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'readability/alt_tokens', 158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'readability/braces', 159ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'readability/casting', 160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'readability/check', 161ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'readability/constructors', 162ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'readability/fn_size', 163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'readability/function', 164ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'readability/multiline_comment', 165ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'readability/multiline_string', 166ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'readability/namespace', 167ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'readability/nolint', 168b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'readability/nul', 169ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'readability/streams', 170ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'readability/todo', 171ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'readability/utf8', 172ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'runtime/arrays', 173ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'runtime/casting', 174ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'runtime/explicit', 175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'runtime/int', 176ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'runtime/init', 177ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'runtime/invalid_increment', 178ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'runtime/member_string_references', 179ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'runtime/memset', 180ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'runtime/operator', 181ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'runtime/printf', 182ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'runtime/printf_format', 183ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'runtime/references', 184ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'runtime/sizeof', 185ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'runtime/string', 186ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'runtime/threadsafe_fn', 187b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'runtime/vlog', 188ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'whitespace/blank_line', 189ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'whitespace/braces', 190ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'whitespace/comma', 191ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'whitespace/comments', 192b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'whitespace/empty_conditional_body', 193ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'whitespace/empty_loop_body', 194ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'whitespace/end_of_line', 195ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'whitespace/ending_newline', 196ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'whitespace/forcolon', 197ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'whitespace/indent', 198ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'whitespace/line_length', 199ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'whitespace/newline', 200ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'whitespace/operators', 201ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'whitespace/parens', 202ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'whitespace/semicolon', 203ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'whitespace/tab', 204ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'whitespace/todo' 205ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ] 206ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 207ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# The default state of the category filter. This is overrided by the --filter= 208ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# flag. By default all errors are on, so only add here categories that should be 209ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# off by default (i.e., categories that must be enabled by the --filter= flags). 210ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# All entries here should start with a '-' or '+', as in the --filter= flag. 211ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_DEFAULT_FILTERS = ['-build/include_alpha'] 212ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 213ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# We used to check for high-bit characters, but after much discussion we 214ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# decided those were OK, as long as they were in UTF-8 and didn't represent 215ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# hard-coded international strings, which belong in a separate i18n file. 216ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 217ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 218b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian# C++ headers 219ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_CPP_HEADERS = frozenset([ 220b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Legacy 221b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'algobase.h', 222b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'algo.h', 223b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'alloc.h', 224b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'builtinbuf.h', 225b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'bvector.h', 226b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'complex.h', 227b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'defalloc.h', 228b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'deque.h', 229b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'editbuf.h', 230b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'fstream.h', 231b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'function.h', 232b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'hash_map', 233b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'hash_map.h', 234b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'hash_set', 235b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'hash_set.h', 236b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'hashtable.h', 237b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'heap.h', 238b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'indstream.h', 239b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'iomanip.h', 240b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'iostream.h', 241b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'istream.h', 242b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'iterator.h', 243b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'list.h', 244b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'map.h', 245b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'multimap.h', 246b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'multiset.h', 247b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'ostream.h', 248b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'pair.h', 249b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'parsestream.h', 250b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'pfstream.h', 251b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'procbuf.h', 252b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'pthread_alloc', 253b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'pthread_alloc.h', 254b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'rope', 255b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'rope.h', 256b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'ropeimpl.h', 257b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'set.h', 258b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'slist', 259b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'slist.h', 260b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'stack.h', 261b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'stdiostream.h', 262b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'stl_alloc.h', 263b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'stl_relops.h', 264b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'streambuf.h', 265b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'stream.h', 266b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'strfile.h', 267b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'strstream.h', 268b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'tempbuf.h', 269b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'tree.h', 270b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'type_traits.h', 271b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'vector.h', 272b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 17.6.1.2 C++ library headers 273b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'algorithm', 274b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'array', 275b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'atomic', 276b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'bitset', 277b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'chrono', 278b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'codecvt', 279b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'complex', 280b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'condition_variable', 281b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'deque', 282b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'exception', 283b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'forward_list', 284b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'fstream', 285b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'functional', 286b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'future', 287b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'initializer_list', 288b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'iomanip', 289b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'ios', 290b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'iosfwd', 291b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'iostream', 292b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'istream', 293b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'iterator', 294b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'limits', 295b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'list', 296b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'locale', 297b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'map', 298b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'memory', 299b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'mutex', 300b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'new', 301b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'numeric', 302b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'ostream', 303b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'queue', 304b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'random', 305b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'ratio', 306b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'regex', 307b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'set', 308b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'sstream', 309b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'stack', 310b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'stdexcept', 311b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'streambuf', 312b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'string', 313b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'strstream', 314b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'system_error', 315b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'thread', 316b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'tuple', 317b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'typeindex', 318b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'typeinfo', 319b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'type_traits', 320b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'unordered_map', 321b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'unordered_set', 322b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'utility', 323b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'valarray', 324b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'vector', 325b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 17.6.1.2 C++ headers for C library facilities 326b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'cassert', 327b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'ccomplex', 328b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'cctype', 329b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'cerrno', 330b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'cfenv', 331b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'cfloat', 332b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'cinttypes', 333b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'ciso646', 334b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'climits', 335b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'clocale', 336b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'cmath', 337b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'csetjmp', 338b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'csignal', 339b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'cstdalign', 340b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'cstdarg', 341b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'cstdbool', 342b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'cstddef', 343b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'cstdint', 344b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'cstdio', 345b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'cstdlib', 346b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'cstring', 347b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'ctgmath', 348b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'ctime', 349b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'cuchar', 350b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'cwchar', 351b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'cwctype', 352ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ]) 353ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 354ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# Assertion macros. These are defined in base/logging.h and 355ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# testing/base/gunit.h. Note that the _M versions need to come first 356ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# for substring matching to work. 357ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_CHECK_MACROS = [ 358ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'DCHECK', 'CHECK', 359ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'EXPECT_TRUE_M', 'EXPECT_TRUE', 360ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'ASSERT_TRUE_M', 'ASSERT_TRUE', 361ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'EXPECT_FALSE_M', 'EXPECT_FALSE', 362ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'ASSERT_FALSE_M', 'ASSERT_FALSE', 363ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ] 364ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 365ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# Replacement macros for CHECK/DCHECK/EXPECT_TRUE/EXPECT_FALSE 366ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_CHECK_REPLACEMENT = dict([(m, {}) for m in _CHECK_MACROS]) 367ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 368ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangfor op, replacement in [('==', 'EQ'), ('!=', 'NE'), 369ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('>=', 'GE'), ('>', 'GT'), 370ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('<=', 'LE'), ('<', 'LT')]: 371ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _CHECK_REPLACEMENT['DCHECK'][op] = 'DCHECK_%s' % replacement 372ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _CHECK_REPLACEMENT['CHECK'][op] = 'CHECK_%s' % replacement 373ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _CHECK_REPLACEMENT['EXPECT_TRUE'][op] = 'EXPECT_%s' % replacement 374ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _CHECK_REPLACEMENT['ASSERT_TRUE'][op] = 'ASSERT_%s' % replacement 375ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _CHECK_REPLACEMENT['EXPECT_TRUE_M'][op] = 'EXPECT_%s_M' % replacement 376ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _CHECK_REPLACEMENT['ASSERT_TRUE_M'][op] = 'ASSERT_%s_M' % replacement 377ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 378ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangfor op, inv_replacement in [('==', 'NE'), ('!=', 'EQ'), 379ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('>=', 'LT'), ('>', 'LE'), 380ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('<=', 'GT'), ('<', 'GE')]: 381ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _CHECK_REPLACEMENT['EXPECT_FALSE'][op] = 'EXPECT_%s' % inv_replacement 382ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _CHECK_REPLACEMENT['ASSERT_FALSE'][op] = 'ASSERT_%s' % inv_replacement 383ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _CHECK_REPLACEMENT['EXPECT_FALSE_M'][op] = 'EXPECT_%s_M' % inv_replacement 384ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _CHECK_REPLACEMENT['ASSERT_FALSE_M'][op] = 'ASSERT_%s_M' % inv_replacement 385ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 386ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# Alternative tokens and their replacements. For full list, see section 2.5 387ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# Alternative tokens [lex.digraph] in the C++ standard. 388ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# 389ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# Digraphs (such as '%:') are not included here since it's a mess to 390ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# match those on a word boundary. 391ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_ALT_TOKEN_REPLACEMENT = { 392ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'and': '&&', 393ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'bitor': '|', 394ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'or': '||', 395ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'xor': '^', 396ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'compl': '~', 397ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'bitand': '&', 398ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'and_eq': '&=', 399ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'or_eq': '|=', 400ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'xor_eq': '^=', 401ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'not': '!', 402ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'not_eq': '!=' 403ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 404ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 405ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# Compile regular expression that matches all the above keywords. The "[ =()]" 406ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# bit is meant to avoid matching these keywords outside of boolean expressions. 407ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# 408b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian# False positives include C-style multi-line comments and multi-line strings 409b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian# but those have always been troublesome for cpplint. 410ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_ALT_TOKEN_REPLACEMENT_PATTERN = re.compile( 411ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang r'[ =()](' + ('|'.join(_ALT_TOKEN_REPLACEMENT.keys())) + r')(?=[ (]|$)') 412ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 413ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 414ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# These constants define types of headers for use with 415ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# _IncludeState.CheckNextIncludeOrder(). 416ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_C_SYS_HEADER = 1 417ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_CPP_SYS_HEADER = 2 418ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_LIKELY_MY_HEADER = 3 419ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_POSSIBLE_MY_HEADER = 4 420ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_OTHER_HEADER = 5 421ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 422ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# These constants define the current inline assembly state 423ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_NO_ASM = 0 # Outside of inline assembly block 424ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_INSIDE_ASM = 1 # Inside inline assembly block 425ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_END_ASM = 2 # Last line of inline assembly block 426ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_BLOCK_ASM = 3 # The whole block is an inline assembly block 427ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 428ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# Match start of assembly blocks 429ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_MATCH_ASM = re.compile(r'^\s*(?:asm|_asm|__asm|__asm__)' 430ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang r'(?:\s+(volatile|__volatile__))?' 431ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang r'\s*[{(]') 432ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 433ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 434ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_regexp_compile_cache = {} 435ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 436ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# Finds occurrences of NOLINT or NOLINT(...). 437ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_RE_SUPPRESSION = re.compile(r'\bNOLINT\b(\([^)]*\))?') 438ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 439ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# {str, set(int)}: a map from error categories to sets of linenumbers 440ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# on which those errors are expected and should be suppressed. 441ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_error_suppressions = {} 442ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 443ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# The root directory used for deriving header guard CPP variable. 444ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# This is set by --root flag. 445ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_root = None 446ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 447b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian# The allowed line length of files. 448b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian# This is set by --linelength flag. 449b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian_line_length = 80 450b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 451b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian# The allowed extensions for file names 452b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian# This is set by --extensions flag. 453b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian_valid_extensions = set(['cc', 'h', 'cpp', 'cu', 'cuh']) 454b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 455ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef ParseNolintSuppressions(filename, raw_line, linenum, error): 456ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Updates the global list of error-suppressions. 457ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 458ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Parses any NOLINT comments on the current line, updating the global 459ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error_suppressions store. Reports an error if the NOLINT comment 460ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang was malformed. 461ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 462ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 463ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: str, the name of the input file. 464ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang raw_line: str, the line of input text, with comments. 465ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: int, the number of the current line. 466ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: function, an error handler. 467ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 468ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # FIXME(adonovan): "NOLINT(" is misparsed as NOLINT(*). 469ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang matched = _RE_SUPPRESSION.search(raw_line) 470ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if matched: 471ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang category = matched.group(1) 472ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if category in (None, '(*)'): # => "suppress all" 473ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _error_suppressions.setdefault(None, set()).add(linenum) 474ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 475ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if category.startswith('(') and category.endswith(')'): 476ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang category = category[1:-1] 477ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if category in _ERROR_CATEGORIES: 478ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _error_suppressions.setdefault(category, set()).add(linenum) 479ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 480ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'readability/nolint', 5, 481ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Unknown NOLINT error category: %s' % category) 482ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 483ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 484ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef ResetNolintSuppressions(): 485ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang "Resets the set of NOLINT suppressions to empty." 486ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _error_suppressions.clear() 487ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 488ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 489ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef IsErrorSuppressedByNolint(category, linenum): 490ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Returns true if the specified error category is suppressed on this line. 491ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 492ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Consults the global error_suppressions map populated by 493ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ParseNolintSuppressions/ResetNolintSuppressions. 494ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 495ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 496ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang category: str, the category of the error. 497ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: int, the current line number. 498ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Returns: 499ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang bool, True iff the error should be suppressed due to a NOLINT comment. 500ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 501ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return (linenum in _error_suppressions.get(category, set()) or 502ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum in _error_suppressions.get(None, set())) 503ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 504ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef Match(pattern, s): 505ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Matches the string with the pattern, caching the compiled regexp.""" 506ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # The regexp compilation caching is inlined in both Match and Search for 507ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # performance reasons; factoring it out into a separate function turns out 508ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # to be noticeably expensive. 509b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if pattern not in _regexp_compile_cache: 510ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _regexp_compile_cache[pattern] = sre_compile.compile(pattern) 511ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return _regexp_compile_cache[pattern].match(s) 512ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 513ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 514b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramaniandef ReplaceAll(pattern, rep, s): 515b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian """Replaces instances of pattern in a string with a replacement. 516b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 517b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian The compiled regex is kept in a cache shared by Match and Search. 518b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 519b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian Args: 520b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian pattern: regex pattern 521b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian rep: replacement text 522b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian s: search string 523b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 524b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian Returns: 525b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian string with replacements made (or original string if no replacements) 526b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian """ 527b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if pattern not in _regexp_compile_cache: 528b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian _regexp_compile_cache[pattern] = sre_compile.compile(pattern) 529b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return _regexp_compile_cache[pattern].sub(rep, s) 530b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 531b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 532ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef Search(pattern, s): 533ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Searches the string for the pattern, caching the compiled regexp.""" 534b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if pattern not in _regexp_compile_cache: 535ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _regexp_compile_cache[pattern] = sre_compile.compile(pattern) 536ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return _regexp_compile_cache[pattern].search(s) 537ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 538ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 539ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangclass _IncludeState(dict): 540ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Tracks line numbers for includes, and the order in which includes appear. 541ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 542ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang As a dict, an _IncludeState object serves as a mapping between include 543ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename and line number on which that file was included. 544ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 545ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Call CheckNextIncludeOrder() once for each header in the file, passing 546ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang in the type constants defined above. Calls in an illegal order will 547ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang raise an _IncludeError with an appropriate error message. 548ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 549ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 550ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # self._section will move monotonically through this set. If it ever 551ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # needs to move backwards, CheckNextIncludeOrder will raise an error. 552ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _INITIAL_SECTION = 0 553ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _MY_H_SECTION = 1 554ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _C_SECTION = 2 555ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _CPP_SECTION = 3 556ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _OTHER_H_SECTION = 4 557ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 558ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _TYPE_NAMES = { 559ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _C_SYS_HEADER: 'C system header', 560ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _CPP_SYS_HEADER: 'C++ system header', 561ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _LIKELY_MY_HEADER: 'header this file implements', 562ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _POSSIBLE_MY_HEADER: 'header this file may implement', 563ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _OTHER_HEADER: 'other header', 564ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 565ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _SECTION_NAMES = { 566ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _INITIAL_SECTION: "... nothing. (This can't be an error.)", 567ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _MY_H_SECTION: 'a header this file implements', 568ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _C_SECTION: 'C system header', 569ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _CPP_SECTION: 'C++ system header', 570ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _OTHER_H_SECTION: 'other header', 571ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 572ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 573ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def __init__(self): 574ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang dict.__init__(self) 575b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian self.ResetSection() 576b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 577b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian def ResetSection(self): 578ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # The name of the current section. 579ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self._section = self._INITIAL_SECTION 580ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # The path of last found header. 581ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self._last_header = '' 582ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 583b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian def SetLastHeader(self, header_path): 584b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian self._last_header = header_path 585b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 586ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def CanonicalizeAlphabeticalOrder(self, header_path): 587ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Returns a path canonicalized for alphabetical comparison. 588ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 589ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang - replaces "-" with "_" so they both cmp the same. 590ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang - removes '-inl' since we don't require them to be after the main header. 591ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang - lowercase everything, just in case. 592ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 593ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 594ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang header_path: Path to be canonicalized. 595ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 596ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Returns: 597ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Canonicalized path. 598ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 599ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return header_path.replace('-inl.h', '.h').replace('-', '_').lower() 600ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 601b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian def IsInAlphabeticalOrder(self, clean_lines, linenum, header_path): 602ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Check if a header is in alphabetical order with the previous header. 603ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 604ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 605b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian clean_lines: A CleansedLines instance containing the file. 606b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian linenum: The number of the line to check. 607b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian header_path: Canonicalized header to be checked. 608ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 609ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Returns: 610ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Returns true if the header is in alphabetical order. 611ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 612b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # If previous section is different from current section, _last_header will 613b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # be reset to empty string, so it's always less than current header. 614b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 615b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # If previous line was a blank line, assume that the headers are 616b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # intentionally sorted the way they are. 617b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (self._last_header > header_path and 618b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian not Match(r'^\s*$', clean_lines.elided[linenum - 1])): 619ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return False 620ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return True 621ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 622ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def CheckNextIncludeOrder(self, header_type): 623ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Returns a non-empty error message if the next header is out of order. 624ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 625ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang This function also updates the internal state to be ready to check 626ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang the next include. 627ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 628ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 629ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang header_type: One of the _XXX_HEADER constants defined above. 630ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 631ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Returns: 632ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang The empty string if the header is in the right order, or an 633ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error message describing what's wrong. 634ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 635ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 636ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error_message = ('Found %s after %s' % 637ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (self._TYPE_NAMES[header_type], 638ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self._SECTION_NAMES[self._section])) 639ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 640ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang last_section = self._section 641ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 642ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if header_type == _C_SYS_HEADER: 643ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if self._section <= self._C_SECTION: 644ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self._section = self._C_SECTION 645ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 646ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self._last_header = '' 647ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return error_message 648ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif header_type == _CPP_SYS_HEADER: 649ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if self._section <= self._CPP_SECTION: 650ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self._section = self._CPP_SECTION 651ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 652ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self._last_header = '' 653ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return error_message 654ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif header_type == _LIKELY_MY_HEADER: 655ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if self._section <= self._MY_H_SECTION: 656ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self._section = self._MY_H_SECTION 657ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 658ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self._section = self._OTHER_H_SECTION 659ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif header_type == _POSSIBLE_MY_HEADER: 660ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if self._section <= self._MY_H_SECTION: 661ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self._section = self._MY_H_SECTION 662ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 663ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # This will always be the fallback because we're not sure 664ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # enough that the header is associated with this file. 665ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self._section = self._OTHER_H_SECTION 666ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 667ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang assert header_type == _OTHER_HEADER 668ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self._section = self._OTHER_H_SECTION 669ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 670ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if last_section != self._section: 671ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self._last_header = '' 672ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 673ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return '' 674ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 675ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 676ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangclass _CppLintState(object): 677ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Maintains module-wide state..""" 678ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 679ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def __init__(self): 680ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.verbose_level = 1 # global setting. 681ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.error_count = 0 # global count of reported errors 682ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # filters to apply when emitting error messages 683ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.filters = _DEFAULT_FILTERS[:] 684ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.counting = 'total' # In what way are we counting errors? 685ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.errors_by_category = {} # string to int dict storing error counts 686ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 687ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # output format: 688ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # "emacs" - format that emacs can parse (default) 689ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # "vs7" - format that Microsoft Visual Studio 7 can parse 690ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.output_format = 'emacs' 691ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 692ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def SetOutputFormat(self, output_format): 693ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Sets the output format for errors.""" 694ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.output_format = output_format 695ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 696ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def SetVerboseLevel(self, level): 697ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Sets the module's verbosity, and returns the previous setting.""" 698ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang last_verbose_level = self.verbose_level 699ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.verbose_level = level 700ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return last_verbose_level 701ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 702ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def SetCountingStyle(self, counting_style): 703ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Sets the module's counting options.""" 704ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.counting = counting_style 705ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 706ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def SetFilters(self, filters): 707ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Sets the error-message filters. 708ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 709ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang These filters are applied when deciding whether to emit a given 710ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error message. 711ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 712ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 713ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filters: A string of comma-separated filters (eg "+whitespace/indent"). 714ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Each filter should start with + or -; else we die. 715ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 716ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Raises: 717ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ValueError: The comma-separated filters did not all start with '+' or '-'. 718ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang E.g. "-,+whitespace,-whitespace/indent,whitespace/badfilter" 719ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 720ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Default filters always have less priority than the flag ones. 721ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.filters = _DEFAULT_FILTERS[:] 722ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for filt in filters.split(','): 723ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_filt = filt.strip() 724ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if clean_filt: 725ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.filters.append(clean_filt) 726ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for filt in self.filters: 727ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not (filt.startswith('+') or filt.startswith('-')): 728ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang raise ValueError('Every filter in --filters must start with + or -' 729ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ' (%s does not)' % filt) 730ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 731ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def ResetErrorCounts(self): 732ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Sets the module's error statistic back to zero.""" 733ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.error_count = 0 734ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.errors_by_category = {} 735ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 736ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def IncrementErrorCount(self, category): 737ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Bumps the module's error statistic.""" 738ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.error_count += 1 739ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if self.counting in ('toplevel', 'detailed'): 740ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if self.counting != 'detailed': 741ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang category = category.split('/')[0] 742ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if category not in self.errors_by_category: 743ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.errors_by_category[category] = 0 744ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.errors_by_category[category] += 1 745ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 746ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def PrintErrorCounts(self): 747ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Print a summary of errors by category, and the total.""" 748ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for category, count in self.errors_by_category.iteritems(): 749ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang sys.stderr.write('Category \'%s\' errors found: %d\n' % 750ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (category, count)) 751ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang sys.stderr.write('Total errors found: %d\n' % self.error_count) 752ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 753ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_cpplint_state = _CppLintState() 754ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 755ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 756ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef _OutputFormat(): 757ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Gets the module's output format.""" 758ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return _cpplint_state.output_format 759ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 760ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 761ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef _SetOutputFormat(output_format): 762ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Sets the module's output format.""" 763ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _cpplint_state.SetOutputFormat(output_format) 764ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 765ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 766ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef _VerboseLevel(): 767ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Returns the module's verbosity setting.""" 768ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return _cpplint_state.verbose_level 769ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 770ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 771ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef _SetVerboseLevel(level): 772ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Sets the module's verbosity, and returns the previous setting.""" 773ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return _cpplint_state.SetVerboseLevel(level) 774ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 775ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 776ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef _SetCountingStyle(level): 777ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Sets the module's counting options.""" 778ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _cpplint_state.SetCountingStyle(level) 779ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 780ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 781ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef _Filters(): 782ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Returns the module's list of output filters, as a list.""" 783ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return _cpplint_state.filters 784ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 785ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 786ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef _SetFilters(filters): 787ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Sets the module's error-message filters. 788ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 789ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang These filters are applied when deciding whether to emit a given 790ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error message. 791ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 792ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 793ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filters: A string of comma-separated filters (eg "whitespace/indent"). 794ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Each filter should start with + or -; else we die. 795ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 796ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _cpplint_state.SetFilters(filters) 797ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 798ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 799ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangclass _FunctionState(object): 800ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Tracks current function name and the number of lines in its body.""" 801ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 802ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _NORMAL_TRIGGER = 250 # for --v=0, 500 for --v=1, etc. 803ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _TEST_TRIGGER = 400 # about 50% more than _NORMAL_TRIGGER. 804ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 805ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def __init__(self): 806ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.in_a_function = False 807ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.lines_in_function = 0 808ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.current_function = '' 809ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 810ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def Begin(self, function_name): 811ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Start analyzing function body. 812ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 813ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 814ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang function_name: The name of the function being tracked. 815ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 816ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.in_a_function = True 817ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.lines_in_function = 0 818ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.current_function = function_name 819ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 820ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def Count(self): 821ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Count line in current function body.""" 822ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if self.in_a_function: 823ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.lines_in_function += 1 824ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 825ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def Check(self, error, filename, linenum): 826ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Report if too many lines in function body. 827ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 828ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 829ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: The function to call with any errors found. 830ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the current file. 831ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: The number of the line to check. 832ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 833ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Match(r'T(EST|est)', self.current_function): 834ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang base_trigger = self._TEST_TRIGGER 835ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 836ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang base_trigger = self._NORMAL_TRIGGER 837ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang trigger = base_trigger * 2**_VerboseLevel() 838ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 839ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if self.lines_in_function > trigger: 840ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error_level = int(math.log(self.lines_in_function / base_trigger, 2)) 841ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 50 => 0, 100 => 1, 200 => 2, 400 => 3, 800 => 4, 1600 => 5, ... 842ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if error_level > 5: 843ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error_level = 5 844ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'readability/fn_size', error_level, 845ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Small and focused functions are preferred:' 846ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ' %s has %d non-comment lines' 847ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ' (error triggered by exceeding %d lines).' % ( 848ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.current_function, self.lines_in_function, trigger)) 849ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 850ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def End(self): 851ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Stop analyzing function body.""" 852ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.in_a_function = False 853ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 854ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 855ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangclass _IncludeError(Exception): 856ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Indicates a problem with the include order in a file.""" 857ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang pass 858ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 859ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 860ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangclass FileInfo: 861ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Provides utility functions for filenames. 862ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 863ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang FileInfo provides easy access to the components of a file's path 864ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang relative to the project root. 865ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 866ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 867ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def __init__(self, filename): 868ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self._filename = filename 869ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 870ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def FullName(self): 871ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Make Windows paths like Unix.""" 872ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return os.path.abspath(self._filename).replace('\\', '/') 873ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 874ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def RepositoryName(self): 875ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """FullName after removing the local path to the repository. 876ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 877ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang If we have a real absolute path name here we can try to do something smart: 878ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang detecting the root of the checkout and truncating /path/to/checkout from 879ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang the name so that we get header guards that don't include things like 880ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang "C:\Documents and Settings\..." or "/home/username/..." in them and thus 881ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang people on different computers who have checked the source out to different 882ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang locations won't see bogus errors. 883ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 884ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang fullname = self.FullName() 885ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 886ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if os.path.exists(fullname): 887ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang project_dir = os.path.dirname(fullname) 888ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 889ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if os.path.exists(os.path.join(project_dir, ".svn")): 890ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # If there's a .svn file in the current directory, we recursively look 891ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # up the directory tree for the top of the SVN checkout 892ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang root_dir = project_dir 893ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang one_up_dir = os.path.dirname(root_dir) 894ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang while os.path.exists(os.path.join(one_up_dir, ".svn")): 895ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang root_dir = os.path.dirname(root_dir) 896ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang one_up_dir = os.path.dirname(one_up_dir) 897ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 898ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang prefix = os.path.commonprefix([root_dir, project_dir]) 899ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return fullname[len(prefix) + 1:] 900ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 901ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Not SVN <= 1.6? Try to find a git, hg, or svn top level directory by 902ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # searching up from the current path. 903ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang root_dir = os.path.dirname(fullname) 904ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang while (root_dir != os.path.dirname(root_dir) and 905ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang not os.path.exists(os.path.join(root_dir, ".git")) and 906ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang not os.path.exists(os.path.join(root_dir, ".hg")) and 907ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang not os.path.exists(os.path.join(root_dir, ".svn"))): 908ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang root_dir = os.path.dirname(root_dir) 909ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 910ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (os.path.exists(os.path.join(root_dir, ".git")) or 911ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang os.path.exists(os.path.join(root_dir, ".hg")) or 912ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang os.path.exists(os.path.join(root_dir, ".svn"))): 913ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang prefix = os.path.commonprefix([root_dir, project_dir]) 914ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return fullname[len(prefix) + 1:] 915ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 916ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Don't know what to do; header guard warnings may be wrong... 917ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return fullname 918ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 919ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def Split(self): 920ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Splits the file into the directory, basename, and extension. 921ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 922ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang For 'chrome/browser/browser.cc', Split() would 923ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return ('chrome/browser', 'browser', '.cc') 924ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 925ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Returns: 926ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang A tuple of (directory, basename, extension). 927ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 928ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 929ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang googlename = self.RepositoryName() 930ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang project, rest = os.path.split(googlename) 931ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return (project,) + os.path.splitext(rest) 932ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 933ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def BaseName(self): 934ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """File base name - text after the final slash, before the final period.""" 935ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return self.Split()[1] 936ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 937ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def Extension(self): 938ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """File extension - text following the final period.""" 939ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return self.Split()[2] 940ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 941ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def NoExtension(self): 942ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """File has no source file extension.""" 943ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return '/'.join(self.Split()[0:2]) 944ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 945ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def IsSource(self): 946ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """File has a source file extension.""" 947ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return self.Extension()[1:] in ('c', 'cc', 'cpp', 'cxx') 948ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 949ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 950ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef _ShouldPrintError(category, confidence, linenum): 951ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """If confidence >= verbose, category passes filter and is not suppressed.""" 952ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 953ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # There are three ways we might decide not to print an error message: 954ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # a "NOLINT(category)" comment appears in the source, 955ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # the verbosity level isn't high enough, or the filters filter it out. 956ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if IsErrorSuppressedByNolint(category, linenum): 957ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return False 958ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if confidence < _cpplint_state.verbose_level: 959ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return False 960ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 961ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang is_filtered = False 962ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for one_filter in _Filters(): 963ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if one_filter.startswith('-'): 964ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if category.startswith(one_filter[1:]): 965ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang is_filtered = True 966ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif one_filter.startswith('+'): 967ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if category.startswith(one_filter[1:]): 968ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang is_filtered = False 969ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 970ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang assert False # should have been checked for in SetFilter. 971ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if is_filtered: 972ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return False 973ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 974ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return True 975ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 976ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 977ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef Error(filename, linenum, category, confidence, message): 978ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Logs the fact we've found a lint error. 979ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 980ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang We log where the error was found, and also our confidence in the error, 981ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang that is, how certain we are this is a legitimate style regression, and 982ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang not a misidentification or a use that's sometimes justified. 983ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 984ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang False positives can be suppressed by the use of 985ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang "cpplint(category)" comments on the offending line. These are 986ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang parsed into _error_suppressions. 987ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 988ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 989ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the file containing the error. 990ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: The number of the line containing the error. 991ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang category: A string used to describe the "category" this bug 992ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang falls under: "whitespace", say, or "runtime". Categories 993ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang may have a hierarchy separated by slashes: "whitespace/indent". 994ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang confidence: A number from 1-5 representing a confidence score for 995ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang the error, with 5 meaning that we are certain of the problem, 996ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang and 1 meaning that it could be a legitimate construct. 997ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang message: The error message. 998ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 999ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if _ShouldPrintError(category, confidence, linenum): 1000ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _cpplint_state.IncrementErrorCount(category) 1001ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if _cpplint_state.output_format == 'vs7': 1002ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang sys.stderr.write('%s(%s): %s [%s] [%d]\n' % ( 1003ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename, linenum, message, category, confidence)) 1004b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian elif _cpplint_state.output_format == 'eclipse': 1005b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian sys.stderr.write('%s:%s: warning: %s [%s] [%d]\n' % ( 1006b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian filename, linenum, message, category, confidence)) 1007ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 1008ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang sys.stderr.write('%s:%s: %s [%s] [%d]\n' % ( 1009ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename, linenum, message, category, confidence)) 1010ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1011ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1012b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian# Matches standard C++ escape sequences per 2.13.2.3 of the C++ standard. 1013ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_RE_PATTERN_CLEANSE_LINE_ESCAPES = re.compile( 1014ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang r'\\([abfnrtv?"\\\']|\d+|x[0-9a-fA-F]+)') 1015ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# Matches strings. Escape codes should already be removed by ESCAPES. 1016ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES = re.compile(r'"[^"]*"') 1017ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# Matches characters. Escape codes should already be removed by ESCAPES. 1018ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES = re.compile(r"'.'") 1019ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# Matches multi-line C++ comments. 1020ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# This RE is a little bit more complicated than one might expect, because we 1021ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# have to take care of space removals tools so we can handle comments inside 1022ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# statements better. 1023ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# The current rule is: We only clear spaces from both sides when we're at the 1024ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# end of the line. Otherwise, we try to remove spaces from the right side, 1025ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# if this doesn't work we try on left side but only if there's a non-character 1026ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# on the right. 1027ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_RE_PATTERN_CLEANSE_LINE_C_COMMENTS = re.compile( 1028ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang r"""(\s*/\*.*\*/\s*$| 1029ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /\*.*\*/\s+| 1030ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang \s+/\*.*\*/(?=\W)| 1031ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /\*.*\*/)""", re.VERBOSE) 1032ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1033ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1034ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef IsCppString(line): 1035ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Does line terminate so, that the next symbol is in string constant. 1036ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1037ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang This function does not consider single-line nor multi-line comments. 1038ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1039ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 1040ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line: is a partial line of code starting from the 0..n. 1041ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1042ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Returns: 1043ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang True, if next character appended to 'line' is inside a 1044ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang string constant. 1045ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 1046ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1047ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = line.replace(r'\\', 'XX') # after this, \\" does not match to \" 1048ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return ((line.count('"') - line.count(r'\"') - line.count("'\"'")) & 1) == 1 1049ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1050ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1051b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramaniandef CleanseRawStrings(raw_lines): 1052b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian """Removes C++11 raw strings from lines. 1053b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1054b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian Before: 1055b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian static const char kData[] = R"( 1056b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian multi-line string 1057b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian )"; 1058b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1059b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian After: 1060b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian static const char kData[] = "" 1061b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian (replaced by blank line) 1062b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ""; 1063b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1064b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian Args: 1065b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian raw_lines: list of raw lines. 1066b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1067b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian Returns: 1068b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian list of lines with C++11 raw strings replaced by empty strings. 1069b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian """ 1070b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1071b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian delimiter = None 1072b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian lines_without_raw_strings = [] 1073b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian for line in raw_lines: 1074b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if delimiter: 1075b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Inside a raw string, look for the end 1076b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian end = line.find(delimiter) 1077b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if end >= 0: 1078b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Found the end of the string, match leading space for this 1079b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # line and resume copying the original lines, and also insert 1080b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # a "" on the last line. 1081b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian leading_space = Match(r'^(\s*)\S', line) 1082b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian line = leading_space.group(1) + '""' + line[end + len(delimiter):] 1083b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian delimiter = None 1084b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian else: 1085b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Haven't found the end yet, append a blank line. 1086b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian line = '' 1087b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1088b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian else: 1089b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Look for beginning of a raw string. 1090b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # See 2.14.15 [lex.string] for syntax. 1091b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian matched = Match(r'^(.*)\b(?:R|u8R|uR|UR|LR)"([^\s\\()]*)\((.*)$', line) 1092b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if matched: 1093b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian delimiter = ')' + matched.group(2) + '"' 1094b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1095b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian end = matched.group(3).find(delimiter) 1096b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if end >= 0: 1097b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Raw string ended on same line 1098b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian line = (matched.group(1) + '""' + 1099b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian matched.group(3)[end + len(delimiter):]) 1100b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian delimiter = None 1101b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian else: 1102b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Start of a multi-line raw string 1103b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian line = matched.group(1) + '""' 1104b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1105b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian lines_without_raw_strings.append(line) 1106b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1107b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # TODO(unknown): if delimiter is not None here, we might want to 1108b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # emit a warning for unterminated string. 1109b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return lines_without_raw_strings 1110b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1111b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef FindNextMultiLineCommentStart(lines, lineix): 1113ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Find the beginning marker for a multiline comment.""" 1114ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang while lineix < len(lines): 1115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if lines[lineix].strip().startswith('/*'): 1116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Only return this marker if the comment goes beyond this line 1117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if lines[lineix].strip().find('*/', 2) < 0: 1118ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return lineix 1119ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang lineix += 1 1120ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return len(lines) 1121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1122ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1123ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef FindNextMultiLineCommentEnd(lines, lineix): 1124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """We are inside a comment, find the end marker.""" 1125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang while lineix < len(lines): 1126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if lines[lineix].strip().endswith('*/'): 1127ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return lineix 1128ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang lineix += 1 1129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return len(lines) 1130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1131ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1132ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef RemoveMultiLineCommentsFromRange(lines, begin, end): 1133ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Clears a range of lines for multi-line comments.""" 1134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Having // dummy comments makes the lines non-empty, so we will not get 1135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # unnecessary blank line warnings later in the code. 1136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for i in range(begin, end): 1137ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang lines[i] = '// dummy' 1138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef RemoveMultiLineComments(filename, lines, error): 1141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Removes multiline (c-style) comments from lines.""" 1142ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang lineix = 0 1143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang while lineix < len(lines): 1144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang lineix_begin = FindNextMultiLineCommentStart(lines, lineix) 1145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if lineix_begin >= len(lines): 1146ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 1147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang lineix_end = FindNextMultiLineCommentEnd(lines, lineix_begin) 1148ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if lineix_end >= len(lines): 1149ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, lineix_begin + 1, 'readability/multiline_comment', 5, 1150ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Could not find end of multi-line comment') 1151ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 1152ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang RemoveMultiLineCommentsFromRange(lines, lineix_begin, lineix_end + 1) 1153ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang lineix = lineix_end + 1 1154ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1155ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1156ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef CleanseComments(line): 1157ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Removes //-comments and single-line C-style /* */ comments. 1158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1159ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 1160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line: A line of C++ source. 1161ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1162ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Returns: 1163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang The line with single-line comments removed. 1164ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 1165ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang commentpos = line.find('//') 1166ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if commentpos != -1 and not IsCppString(line[:commentpos]): 1167ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = line[:commentpos].rstrip() 1168ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # get rid of /* ... */ 1169ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return _RE_PATTERN_CLEANSE_LINE_C_COMMENTS.sub('', line) 1170ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1171ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1172ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangclass CleansedLines(object): 1173ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Holds 3 copies of all lines with different preprocessing applied to them. 1174ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1) elided member contains lines without strings and comments, 1176ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2) lines member contains lines without comments, and 1177ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3) raw_lines member contains all the lines without processing. 1178ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang All these three members are of <type 'list'>, and of the same length. 1179ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 1180ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1181ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def __init__(self, lines): 1182ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.elided = [] 1183ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.lines = [] 1184ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.raw_lines = lines 1185ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.num_lines = len(lines) 1186b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian self.lines_without_raw_strings = CleanseRawStrings(lines) 1187b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian for linenum in range(len(self.lines_without_raw_strings)): 1188b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian self.lines.append(CleanseComments( 1189b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian self.lines_without_raw_strings[linenum])) 1190b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian elided = self._CollapseStrings(self.lines_without_raw_strings[linenum]) 1191ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.elided.append(CleanseComments(elided)) 1192ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1193ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def NumLines(self): 1194ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Returns the number of lines represented.""" 1195ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return self.num_lines 1196ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1197ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang @staticmethod 1198ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def _CollapseStrings(elided): 1199ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Collapses strings and chars on a line to simple "" or '' blocks. 1200ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1201ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang We nix strings first so we're not fooled by text like '"http://"' 1202ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1203ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 1204ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elided: The line being processed. 1205ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1206ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Returns: 1207ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang The line with collapsed strings. 1208ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 1209ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not _RE_PATTERN_INCLUDE.match(elided): 1210ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Remove escaped characters first to make quote/single quote collapsing 1211ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # basic. Things that look like escaped characters shouldn't occur 1212ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # outside of strings and chars. 1213ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elided = _RE_PATTERN_CLEANSE_LINE_ESCAPES.sub('', elided) 1214ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elided = _RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES.sub("''", elided) 1215ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elided = _RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES.sub('""', elided) 1216ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return elided 1217ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1218ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1219ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef FindEndOfExpressionInLine(line, startpos, depth, startchar, endchar): 1220ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Find the position just after the matching endchar. 1221ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1222ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 1223ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line: a CleansedLines line. 1224ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang startpos: start searching at this position. 1225ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang depth: nesting level at startpos. 1226ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang startchar: expression opening character. 1227ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang endchar: expression closing character. 1228ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1229ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Returns: 1230b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian On finding matching endchar: (index just after matching endchar, 0) 1231b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian Otherwise: (-1, new depth at end of this line) 1232ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 1233ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for i in xrange(startpos, len(line)): 1234ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if line[i] == startchar: 1235ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang depth += 1 1236ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif line[i] == endchar: 1237ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang depth -= 1 1238ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if depth == 0: 1239b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return (i + 1, 0) 1240b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return (-1, depth) 1241ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1242ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1243ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef CloseExpression(clean_lines, linenum, pos): 1244b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian """If input points to ( or { or [ or <, finds the position that closes it. 1245ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1246b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian If lines[linenum][pos] points to a '(' or '{' or '[' or '<', finds the 1247ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum/pos that correspond to the closing of the expression. 1248ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1249ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 1250ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_lines: A CleansedLines instance containing the file. 1251ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: The number of the line to check. 1252ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang pos: A position on the line. 1253ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1254ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Returns: 1255ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang A tuple (line, linenum, pos) pointer *past* the closing brace, or 1256ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (line, len(lines), -1) if we never find a close. Note we ignore 1257ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang strings and comments when matching; and the line we return is the 1258ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'cleansed' line at linenum. 1259ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 1260ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1261ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = clean_lines.elided[linenum] 1262ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang startchar = line[pos] 1263b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if startchar not in '({[<': 1264ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return (line, clean_lines.NumLines(), -1) 1265ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if startchar == '(': endchar = ')' 1266ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if startchar == '[': endchar = ']' 1267ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if startchar == '{': endchar = '}' 1268b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if startchar == '<': endchar = '>' 1269ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1270ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Check first line 1271b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian (end_pos, num_open) = FindEndOfExpressionInLine( 1272b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian line, pos, 0, startchar, endchar) 1273ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if end_pos > -1: 1274ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return (line, linenum, end_pos) 1275b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1276b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Continue scanning forward 1277ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang while linenum < clean_lines.NumLines() - 1: 1278ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum += 1 1279ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = clean_lines.elided[linenum] 1280b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian (end_pos, num_open) = FindEndOfExpressionInLine( 1281b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian line, 0, num_open, startchar, endchar) 1282b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if end_pos > -1: 1283b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return (line, linenum, end_pos) 1284ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1285ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Did not find endchar before end of file, give up 1286ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return (line, clean_lines.NumLines(), -1) 1287ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1288b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1289b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramaniandef FindStartOfExpressionInLine(line, endpos, depth, startchar, endchar): 1290b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian """Find position at the matching startchar. 1291b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1292b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian This is almost the reverse of FindEndOfExpressionInLine, but note 1293b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian that the input position and returned position differs by 1. 1294b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1295b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian Args: 1296b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian line: a CleansedLines line. 1297b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian endpos: start searching at this position. 1298b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian depth: nesting level at endpos. 1299b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian startchar: expression opening character. 1300b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian endchar: expression closing character. 1301b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1302b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian Returns: 1303b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian On finding matching startchar: (index at matching startchar, 0) 1304b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian Otherwise: (-1, new depth at beginning of this line) 1305b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian """ 1306b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian for i in xrange(endpos, -1, -1): 1307b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if line[i] == endchar: 1308b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian depth += 1 1309b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian elif line[i] == startchar: 1310b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian depth -= 1 1311b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if depth == 0: 1312b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return (i, 0) 1313b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return (-1, depth) 1314b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1315b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1316b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramaniandef ReverseCloseExpression(clean_lines, linenum, pos): 1317b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian """If input points to ) or } or ] or >, finds the position that opens it. 1318b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1319b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian If lines[linenum][pos] points to a ')' or '}' or ']' or '>', finds the 1320b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian linenum/pos that correspond to the opening of the expression. 1321b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1322b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian Args: 1323b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian clean_lines: A CleansedLines instance containing the file. 1324b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian linenum: The number of the line to check. 1325b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian pos: A position on the line. 1326b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1327b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian Returns: 1328b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian A tuple (line, linenum, pos) pointer *at* the opening brace, or 1329b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian (line, 0, -1) if we never find the matching opening brace. Note 1330b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian we ignore strings and comments when matching; and the line we 1331b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return is the 'cleansed' line at linenum. 1332b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian """ 1333b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian line = clean_lines.elided[linenum] 1334b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian endchar = line[pos] 1335b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if endchar not in ')}]>': 1336b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return (line, 0, -1) 1337b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if endchar == ')': startchar = '(' 1338b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if endchar == ']': startchar = '[' 1339b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if endchar == '}': startchar = '{' 1340b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if endchar == '>': startchar = '<' 1341b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1342b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Check last line 1343b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian (start_pos, num_open) = FindStartOfExpressionInLine( 1344b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian line, pos, 0, startchar, endchar) 1345b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if start_pos > -1: 1346b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return (line, linenum, start_pos) 1347b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1348b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Continue scanning backward 1349b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian while linenum > 0: 1350b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian linenum -= 1 1351b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian line = clean_lines.elided[linenum] 1352b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian (start_pos, num_open) = FindStartOfExpressionInLine( 1353b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian line, len(line) - 1, num_open, startchar, endchar) 1354b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if start_pos > -1: 1355b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return (line, linenum, start_pos) 1356b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1357b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Did not find startchar before beginning of file, give up 1358b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return (line, 0, -1) 1359b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1360b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1361ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef CheckForCopyright(filename, lines, error): 1362ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Logs an error if no Copyright message appears at the top of the file.""" 1363ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1364ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # We'll say it should occur by line 10. Don't forget there's a 1365ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # dummy line at the front. 1366ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for line in xrange(1, min(len(lines), 11)): 1367ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if re.search(r'Copyright', lines[line], re.I): break 1368ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: # means no copyright line was found 1369ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, 0, 'legal/copyright', 5, 1370ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'No copyright message found. ' 1371ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'You should have a line: "Copyright [year] <Copyright Owner>"') 1372ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1373ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1374ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef GetHeaderGuardCPPVariable(filename): 1375ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Returns the CPP variable that should be used as a header guard. 1376ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1377ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 1378ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of a C++ header file. 1379ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1380ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Returns: 1381ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang The CPP variable that should be used as a header guard in the 1382ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang named file. 1383ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1384ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 1385ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1386ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Restores original filename in case that cpplint is invoked from Emacs's 1387ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # flymake. 1388ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename = re.sub(r'_flymake\.h$', '.h', filename) 1389ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename = re.sub(r'/\.flymake/([^/]*)$', r'/\1', filename) 1390ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1391ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang fileinfo = FileInfo(filename) 1392ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang file_path_from_root = fileinfo.RepositoryName() 1393ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if _root: 1394ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang file_path_from_root = re.sub('^' + _root + os.sep, '', file_path_from_root) 1395ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return re.sub(r'[-./\s]', '_', file_path_from_root).upper() + '_' 1396ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1397ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1398ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef CheckForHeaderGuard(filename, lines, error): 1399ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Checks that the file contains a header guard. 1400ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1401ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Logs an error if no #ifndef header guard is present. For other 1402ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang headers, checks that the full pathname is used. 1403ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1404ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 1405ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the C++ header file. 1406ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang lines: An array of strings, each representing a line of the file. 1407ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: The function to call with any errors found. 1408ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 1409ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1410ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang cppvar = GetHeaderGuardCPPVariable(filename) 1411ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1412ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ifndef = None 1413ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ifndef_linenum = 0 1414ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang define = None 1415ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang endif = None 1416ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang endif_linenum = 0 1417ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for linenum, line in enumerate(lines): 1418ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linesplit = line.split() 1419ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if len(linesplit) >= 2: 1420ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # find the first occurrence of #ifndef and #define, save arg 1421ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not ifndef and linesplit[0] == '#ifndef': 1422ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # set ifndef to the header guard presented on the #ifndef line. 1423ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ifndef = linesplit[1] 1424ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ifndef_linenum = linenum 1425ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not define and linesplit[0] == '#define': 1426ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang define = linesplit[1] 1427ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # find the last occurrence of #endif, save entire line 1428ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if line.startswith('#endif'): 1429ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang endif = line 1430ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang endif_linenum = linenum 1431ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1432ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not ifndef: 1433ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, 0, 'build/header_guard', 5, 1434ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'No #ifndef header guard found, suggested CPP variable is: %s' % 1435ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang cppvar) 1436ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 1437ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1438ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not define: 1439ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, 0, 'build/header_guard', 5, 1440ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'No #define header guard found, suggested CPP variable is: %s' % 1441ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang cppvar) 1442ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 1443ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1444ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # The guard should be PATH_FILE_H_, but we also allow PATH_FILE_H__ 1445ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # for backward compatibility. 1446ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if ifndef != cppvar: 1447ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error_level = 0 1448ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if ifndef != cppvar + '_': 1449ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error_level = 5 1450ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1451ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ParseNolintSuppressions(filename, lines[ifndef_linenum], ifndef_linenum, 1452ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error) 1453ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, ifndef_linenum, 'build/header_guard', error_level, 1454ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang '#ifndef header guard has wrong style, please use: %s' % cppvar) 1455ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1456ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if define != ifndef: 1457ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, 0, 'build/header_guard', 5, 1458ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang '#ifndef and #define don\'t match, suggested CPP variable is: %s' % 1459ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang cppvar) 1460ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 1461ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1462ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if endif != ('#endif // %s' % cppvar): 1463ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error_level = 0 1464ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if endif != ('#endif // %s' % (cppvar + '_')): 1465ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error_level = 5 1466ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1467ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ParseNolintSuppressions(filename, lines[endif_linenum], endif_linenum, 1468ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error) 1469ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, endif_linenum, 'build/header_guard', error_level, 1470ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang '#endif line should be "#endif // %s"' % cppvar) 1471ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1472ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1473b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramaniandef CheckForBadCharacters(filename, lines, error): 1474b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian """Logs an error for each line containing bad characters. 1475b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1476b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian Two kinds of bad characters: 1477ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1478b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1. Unicode replacement characters: These indicate that either the file 1479b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian contained invalid UTF-8 (likely) or Unicode replacement characters (which 1480b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian it shouldn't). Note that it's possible for this to throw off line 1481b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian numbering if the invalid UTF-8 occurred adjacent to a newline. 1482b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1483b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 2. NUL bytes. These are problematic for some tools. 1484ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1485ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 1486ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the current file. 1487ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang lines: An array of strings, each representing a line of the file. 1488ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: The function to call with any errors found. 1489ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 1490ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for linenum, line in enumerate(lines): 1491ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if u'\ufffd' in line: 1492ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'readability/utf8', 5, 1493ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Line contains invalid UTF-8 (or Unicode replacement character).') 1494b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if '\0' in line: 1495b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian error(filename, linenum, 'readability/nul', 5, 'Line contains NUL byte.') 1496ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1497ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1498ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef CheckForNewlineAtEOF(filename, lines, error): 1499ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Logs an error if there is no newline char at the end of the file. 1500ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1501ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 1502ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the current file. 1503ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang lines: An array of strings, each representing a line of the file. 1504ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: The function to call with any errors found. 1505ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 1506ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1507ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # The array lines() was created by adding two newlines to the 1508ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # original file (go figure), then splitting on \n. 1509ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # To verify that the file ends in \n, we just have to make sure the 1510ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # last-but-two element of lines() exists and is empty. 1511ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if len(lines) < 3 or lines[-2]: 1512ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, len(lines) - 2, 'whitespace/ending_newline', 5, 1513ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Could not find a newline character at the end of the file.') 1514ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1515ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1516ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef CheckForMultilineCommentsAndStrings(filename, clean_lines, linenum, error): 1517ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Logs an error if we see /* ... */ or "..." that extend past one line. 1518ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1519ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* ... */ comments are legit inside macros, for one line. 1520ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Otherwise, we prefer // comments, so it's ok to warn about the 1521ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang other. Likewise, it's ok for strings to extend across multiple 1522ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang lines, as long as a line continuation character (backslash) 1523ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang terminates each line. Although not currently prohibited by the C++ 1524ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang style guide, it's ugly and unnecessary. We don't do well with either 1525ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang in this lint program, so we warn about both. 1526ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1527ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 1528ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the current file. 1529ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_lines: A CleansedLines instance containing the file. 1530ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: The number of the line to check. 1531ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: The function to call with any errors found. 1532ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 1533ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = clean_lines.elided[linenum] 1534ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1535ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Remove all \\ (escaped backslashes) from the line. They are OK, and the 1536ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # second (escaped) slash may trigger later \" detection erroneously. 1537ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = line.replace('\\\\', '') 1538ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1539ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if line.count('/*') > line.count('*/'): 1540ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'readability/multiline_comment', 5, 1541ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Complex multi-line /*...*/-style comment found. ' 1542ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Lint may give bogus warnings. ' 1543ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Consider replacing these with //-style comments, ' 1544ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'with #if 0...#endif, ' 1545ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'or with more clearly structured multi-line comments.') 1546ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1547ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (line.count('"') - line.count('\\"')) % 2: 1548ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'readability/multiline_string', 5, 1549ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Multi-line string ("...") found. This lint script doesn\'t ' 1550b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'do well with such strings, and may give bogus warnings. ' 1551b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'Use C++11 raw strings or concatenation instead.') 1552ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1553ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1554ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangthreading_list = ( 1555ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('asctime(', 'asctime_r('), 1556ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('ctime(', 'ctime_r('), 1557ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('getgrgid(', 'getgrgid_r('), 1558ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('getgrnam(', 'getgrnam_r('), 1559ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('getlogin(', 'getlogin_r('), 1560ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('getpwnam(', 'getpwnam_r('), 1561ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('getpwuid(', 'getpwuid_r('), 1562ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('gmtime(', 'gmtime_r('), 1563ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('localtime(', 'localtime_r('), 1564ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('rand(', 'rand_r('), 1565ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('strtok(', 'strtok_r('), 1566ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('ttyname(', 'ttyname_r('), 1567ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ) 1568ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1569ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1570ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef CheckPosixThreading(filename, clean_lines, linenum, error): 1571ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Checks for calls to thread-unsafe functions. 1572ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1573ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Much code has been originally written without consideration of 1574ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang multi-threading. Also, engineers are relying on their old experience; 1575ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang they have learned posix before threading extensions were added. These 1576ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang tests guide the engineers to use thread-safe functions (when using 1577ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang posix directly). 1578ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1579ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 1580ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the current file. 1581ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_lines: A CleansedLines instance containing the file. 1582ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: The number of the line to check. 1583ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: The function to call with any errors found. 1584ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 1585ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = clean_lines.elided[linenum] 1586ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for single_thread_function, multithread_safe_function in threading_list: 1587ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ix = line.find(single_thread_function) 1588b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Comparisons made explicit for clarity -- pylint: disable=g-explicit-bool-comparison 1589ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if ix >= 0 and (ix == 0 or (not line[ix - 1].isalnum() and 1590ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line[ix - 1] not in ('_', '.', '>'))): 1591ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'runtime/threadsafe_fn', 2, 1592ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Consider using ' + multithread_safe_function + 1593ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang '...) instead of ' + single_thread_function + 1594ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang '...) for improved thread safety.') 1595ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1596ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1597b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramaniandef CheckVlogArguments(filename, clean_lines, linenum, error): 1598b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian """Checks that VLOG() is only used for defining a logging level. 1599b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1600b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian For example, VLOG(2) is correct. VLOG(INFO), VLOG(WARNING), VLOG(ERROR), and 1601b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VLOG(FATAL) are not. 1602b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1603b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian Args: 1604b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian filename: The name of the current file. 1605b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian clean_lines: A CleansedLines instance containing the file. 1606b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian linenum: The number of the line to check. 1607b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian error: The function to call with any errors found. 1608b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian """ 1609b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian line = clean_lines.elided[linenum] 1610b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if Search(r'\bVLOG\((INFO|ERROR|WARNING|DFATAL|FATAL)\)', line): 1611b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian error(filename, linenum, 'runtime/vlog', 5, 1612b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'VLOG() should be used with numeric verbosity level. ' 1613b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'Use LOG() if you want symbolic severity levels.') 1614b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1615b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1616ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# Matches invalid increment: *count++, which moves pointer instead of 1617ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# incrementing a value. 1618ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_RE_PATTERN_INVALID_INCREMENT = re.compile( 1619ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang r'^\s*\*\w+(\+\+|--);') 1620ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1621ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1622ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef CheckInvalidIncrement(filename, clean_lines, linenum, error): 1623ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Checks for invalid increment *count++. 1624ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1625ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang For example following function: 1626ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang void increment_counter(int* count) { 1627ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *count++; 1628ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 1629ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang is invalid, because it effectively does count++, moving pointer, and should 1630ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang be replaced with ++*count, (*count)++ or *count += 1. 1631ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1632ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 1633ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the current file. 1634ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_lines: A CleansedLines instance containing the file. 1635ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: The number of the line to check. 1636ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: The function to call with any errors found. 1637ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 1638ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = clean_lines.elided[linenum] 1639ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if _RE_PATTERN_INVALID_INCREMENT.match(line): 1640ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'runtime/invalid_increment', 5, 1641ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Changing pointer instead of value (or unused value of operator*).') 1642ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1643ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1644ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangclass _BlockInfo(object): 1645ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Stores information about a generic block of code.""" 1646ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1647ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def __init__(self, seen_open_brace): 1648ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.seen_open_brace = seen_open_brace 1649ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.open_parentheses = 0 1650ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.inline_asm = _NO_ASM 1651ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1652ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def CheckBegin(self, filename, clean_lines, linenum, error): 1653ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Run checks that applies to text up to the opening brace. 1654ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1655ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang This is mostly for checking the text after the class identifier 1656ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang and the "{", usually where the base class is specified. For other 1657ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang blocks, there isn't much to check, so we always pass. 1658ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1659ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 1660ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the current file. 1661ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_lines: A CleansedLines instance containing the file. 1662ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: The number of the line to check. 1663ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: The function to call with any errors found. 1664ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 1665ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang pass 1666ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1667ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def CheckEnd(self, filename, clean_lines, linenum, error): 1668ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Run checks that applies to text after the closing brace. 1669ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1670ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang This is mostly used for checking end of namespace comments. 1671ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1672ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 1673ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the current file. 1674ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_lines: A CleansedLines instance containing the file. 1675ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: The number of the line to check. 1676ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: The function to call with any errors found. 1677ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 1678ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang pass 1679ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1680ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1681ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangclass _ClassInfo(_BlockInfo): 1682ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Stores information about a class.""" 1683ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1684ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def __init__(self, name, class_or_struct, clean_lines, linenum): 1685ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _BlockInfo.__init__(self, False) 1686ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.name = name 1687ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.starting_linenum = linenum 1688ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.is_derived = False 1689ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if class_or_struct == 'struct': 1690ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.access = 'public' 1691b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian self.is_struct = True 1692ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 1693ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.access = 'private' 1694b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian self.is_struct = False 1695b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1696b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Remember initial indentation level for this class. Using raw_lines here 1697b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # instead of elided to account for leading comments. 1698b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian initial_indent = Match(r'^( *)\S', clean_lines.raw_lines[linenum]) 1699b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if initial_indent: 1700b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian self.class_indent = len(initial_indent.group(1)) 1701b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian else: 1702b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian self.class_indent = 0 1703ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1704ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Try to find the end of the class. This will be confused by things like: 1705ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # class A { 1706ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # } *x = { ... 1707ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 1708ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # But it's still good enough for CheckSectionSpacing. 1709ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.last_line = 0 1710ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang depth = 0 1711ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for i in range(linenum, clean_lines.NumLines()): 1712ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = clean_lines.elided[i] 1713ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang depth += line.count('{') - line.count('}') 1714ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not depth: 1715ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.last_line = i 1716ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break 1717ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1718ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def CheckBegin(self, filename, clean_lines, linenum, error): 1719ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Look for a bare ':' 1720ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Search('(^|[^:]):($|[^:])', clean_lines.elided[linenum]): 1721ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.is_derived = True 1722ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1723b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian def CheckEnd(self, filename, clean_lines, linenum, error): 1724b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Check that closing brace is aligned with beginning of the class. 1725b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Only do this if the closing brace is indented by only whitespaces. 1726b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # This means we will not check single-line class definitions. 1727b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian indent = Match(r'^( *)\}', clean_lines.elided[linenum]) 1728b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if indent and len(indent.group(1)) != self.class_indent: 1729b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if self.is_struct: 1730b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian parent = 'struct ' + self.name 1731b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian else: 1732b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian parent = 'class ' + self.name 1733b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian error(filename, linenum, 'whitespace/indent', 3, 1734b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'Closing brace should be aligned with beginning of %s' % parent) 1735b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1736ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1737ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangclass _NamespaceInfo(_BlockInfo): 1738ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Stores information about a namespace.""" 1739ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1740ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def __init__(self, name, linenum): 1741ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _BlockInfo.__init__(self, False) 1742ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.name = name or '' 1743ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.starting_linenum = linenum 1744ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1745ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def CheckEnd(self, filename, clean_lines, linenum, error): 1746ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Check end of namespace comments.""" 1747ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = clean_lines.raw_lines[linenum] 1748ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1749ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Check how many lines is enclosed in this namespace. Don't issue 1750ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # warning for missing namespace comments if there aren't enough 1751ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # lines. However, do apply checks if there is already an end of 1752ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # namespace comment and it's incorrect. 1753ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 1754ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # TODO(unknown): We always want to check end of namespace comments 1755ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # if a namespace is large, but sometimes we also want to apply the 1756ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # check if a short namespace contained nontrivial things (something 1757ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # other than forward declarations). There is currently no logic on 1758ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # deciding what these nontrivial things are, so this check is 1759ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # triggered by namespace size only, which works most of the time. 1760ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (linenum - self.starting_linenum < 10 1761ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang and not Match(r'};*\s*(//|/\*).*\bnamespace\b', line)): 1762ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 1763ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1764ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Look for matching comment at end of namespace. 1765ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 1766ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Note that we accept C style "/* */" comments for terminating 1767ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # namespaces, so that code that terminate namespaces inside 1768b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # preprocessor macros can be cpplint clean. 1769ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 1770ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # We also accept stuff like "// end of namespace <name>." with the 1771ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # period at the end. 1772ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 1773ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Besides these, we don't accept anything else, otherwise we might 1774ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # get false negatives when existing comment is a substring of the 1775b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # expected namespace. 1776ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if self.name: 1777ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Named namespace 1778ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not Match((r'};*\s*(//|/\*).*\bnamespace\s+' + re.escape(self.name) + 1779ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang r'[\*/\.\\\s]*$'), 1780ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line): 1781ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'readability/namespace', 5, 1782ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Namespace should be terminated with "// namespace %s"' % 1783ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.name) 1784ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 1785ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Anonymous namespace 1786ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not Match(r'};*\s*(//|/\*).*\bnamespace[\*/\.\\\s]*$', line): 1787ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'readability/namespace', 5, 1788ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Namespace should be terminated with "// namespace"') 1789ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1790ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1791ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangclass _PreprocessorInfo(object): 1792ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Stores checkpoints of nesting stacks when #if/#else is seen.""" 1793ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1794ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def __init__(self, stack_before_if): 1795ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # The entire nesting stack before #if 1796ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.stack_before_if = stack_before_if 1797ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1798ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # The entire nesting stack up to #else 1799ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.stack_before_else = [] 1800ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1801ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Whether we have already seen #else or #elif 1802ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.seen_else = False 1803ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1804ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1805ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangclass _NestingState(object): 1806ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Holds states related to parsing braces.""" 1807ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1808ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def __init__(self): 1809ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Stack for tracking all braces. An object is pushed whenever we 1810ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # see a "{", and popped when we see a "}". Only 3 types of 1811ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # objects are possible: 1812ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # - _ClassInfo: a class or struct. 1813ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # - _NamespaceInfo: a namespace. 1814ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # - _BlockInfo: some other type of block. 1815ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.stack = [] 1816ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1817ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Stack of _PreprocessorInfo objects. 1818ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.pp_stack = [] 1819ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1820ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def SeenOpenBrace(self): 1821ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Check if we have seen the opening brace for the innermost block. 1822ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1823ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Returns: 1824ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang True if we have seen the opening brace, False if the innermost 1825ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang block is still expecting an opening brace. 1826ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 1827ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return (not self.stack) or self.stack[-1].seen_open_brace 1828ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1829ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def InNamespaceBody(self): 1830ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Check if we are currently one level inside a namespace body. 1831ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1832ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Returns: 1833ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang True if top of the stack is a namespace block, False otherwise. 1834ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 1835ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return self.stack and isinstance(self.stack[-1], _NamespaceInfo) 1836ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1837ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def UpdatePreprocessor(self, line): 1838ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Update preprocessor stack. 1839ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1840ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang We need to handle preprocessors due to classes like this: 1841ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang #ifdef SWIG 1842ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct ResultDetailsPageElementExtensionPoint { 1843ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang #else 1844ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct ResultDetailsPageElementExtensionPoint : public Extension { 1845ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang #endif 1846ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1847ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang We make the following assumptions (good enough for most files): 1848ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang - Preprocessor condition evaluates to true from #if up to first 1849ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang #else/#elif/#endif. 1850ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1851ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang - Preprocessor condition evaluates to false from #else/#elif up 1852ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang to #endif. We still perform lint checks on these lines, but 1853ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang these do not affect nesting stack. 1854ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1855ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 1856ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line: current line to check. 1857ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 1858ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Match(r'^\s*#\s*(if|ifdef|ifndef)\b', line): 1859ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Beginning of #if block, save the nesting stack here. The saved 1860ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # stack will allow us to restore the parsing state in the #else case. 1861ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.pp_stack.append(_PreprocessorInfo(copy.deepcopy(self.stack))) 1862ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif Match(r'^\s*#\s*(else|elif)\b', line): 1863ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Beginning of #else block 1864ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if self.pp_stack: 1865ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not self.pp_stack[-1].seen_else: 1866ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # This is the first #else or #elif block. Remember the 1867ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # whole nesting stack up to this point. This is what we 1868ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # keep after the #endif. 1869ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.pp_stack[-1].seen_else = True 1870ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.pp_stack[-1].stack_before_else = copy.deepcopy(self.stack) 1871ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1872ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Restore the stack to how it was before the #if 1873ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.stack = copy.deepcopy(self.pp_stack[-1].stack_before_if) 1874ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 1875ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # TODO(unknown): unexpected #else, issue warning? 1876ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang pass 1877ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif Match(r'^\s*#\s*endif\b', line): 1878ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # End of #if or #else blocks. 1879ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if self.pp_stack: 1880ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # If we saw an #else, we will need to restore the nesting 1881ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # stack to its former state before the #else, otherwise we 1882ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # will just continue from where we left off. 1883ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if self.pp_stack[-1].seen_else: 1884ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Here we can just use a shallow copy since we are the last 1885ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # reference to it. 1886ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.stack = self.pp_stack[-1].stack_before_else 1887ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Drop the corresponding #if 1888ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.pp_stack.pop() 1889ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 1890ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # TODO(unknown): unexpected #endif, issue warning? 1891ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang pass 1892ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1893ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def Update(self, filename, clean_lines, linenum, error): 1894ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Update nesting state with current line. 1895ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1896ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 1897ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the current file. 1898ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_lines: A CleansedLines instance containing the file. 1899ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: The number of the line to check. 1900ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: The function to call with any errors found. 1901ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 1902ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = clean_lines.elided[linenum] 1903ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1904ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Update pp_stack first 1905ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.UpdatePreprocessor(line) 1906ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1907ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Count parentheses. This is to avoid adding struct arguments to 1908ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # the nesting stack. 1909ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if self.stack: 1910ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang inner_block = self.stack[-1] 1911ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang depth_change = line.count('(') - line.count(')') 1912ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang inner_block.open_parentheses += depth_change 1913ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1914ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Also check if we are starting or ending an inline assembly block. 1915ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if inner_block.inline_asm in (_NO_ASM, _END_ASM): 1916ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (depth_change != 0 and 1917ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang inner_block.open_parentheses == 1 and 1918ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _MATCH_ASM.match(line)): 1919ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Enter assembly block 1920ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang inner_block.inline_asm = _INSIDE_ASM 1921ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 1922ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Not entering assembly block. If previous line was _END_ASM, 1923ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # we will now shift to _NO_ASM state. 1924ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang inner_block.inline_asm = _NO_ASM 1925ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif (inner_block.inline_asm == _INSIDE_ASM and 1926ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang inner_block.open_parentheses == 0): 1927ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Exit assembly block 1928ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang inner_block.inline_asm = _END_ASM 1929ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1930ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Consume namespace declaration at the beginning of the line. Do 1931ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # this in a loop so that we catch same line declarations like this: 1932ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # namespace proto2 { namespace bridge { class MessageSet; } } 1933ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang while True: 1934ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Match start of namespace. The "\b\s*" below catches namespace 1935ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # declarations even if it weren't followed by a whitespace, this 1936ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # is so that we don't confuse our namespace checker. The 1937ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # missing spaces will be flagged by CheckSpacing. 1938ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang namespace_decl_match = Match(r'^\s*namespace\b\s*([:\w]+)?(.*)$', line) 1939ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not namespace_decl_match: 1940ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break 1941ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1942ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang new_namespace = _NamespaceInfo(namespace_decl_match.group(1), linenum) 1943ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.stack.append(new_namespace) 1944ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1945ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = namespace_decl_match.group(2) 1946ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if line.find('{') != -1: 1947ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang new_namespace.seen_open_brace = True 1948ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = line[line.find('{') + 1:] 1949ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1950ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Look for a class declaration in whatever is left of the line 1951ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # after parsing namespaces. The regexp accounts for decorated classes 1952ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # such as in: 1953ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # class LOCKABLE API Object { 1954ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # }; 1955ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 1956ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Templates with class arguments may confuse the parser, for example: 1957ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # template <class T 1958ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # class Comparator = less<T>, 1959ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # class Vector = vector<T> > 1960ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # class HeapQueue { 1961ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 1962ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Because this parser has no nesting state about templates, by the 1963ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # time it saw "class Comparator", it may think that it's a new class. 1964ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Nested templates have a similar problem: 1965ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # template < 1966ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # typename ExportedType, 1967ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # typename TupleType, 1968ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # template <typename, typename> class ImplTemplate> 1969ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 1970ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # To avoid these cases, we ignore classes that are followed by '=' or '>' 1971ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang class_decl_match = Match( 1972ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang r'\s*(template\s*<[\w\s<>,:]*>\s*)?' 1973b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r'(class|struct)\s+([A-Z_]+\s+)*(\w+(?:::\w+)*)' 1974b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r'(([^=>]|<[^<>]*>|<[^<>]*<[^<>]*>\s*>)*)$', line) 1975ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (class_decl_match and 1976ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (not self.stack or self.stack[-1].open_parentheses == 0)): 1977ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.stack.append(_ClassInfo( 1978ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang class_decl_match.group(4), class_decl_match.group(2), 1979ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_lines, linenum)) 1980ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = class_decl_match.group(5) 1981ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1982ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # If we have not yet seen the opening brace for the innermost block, 1983ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # run checks here. 1984ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not self.SeenOpenBrace(): 1985ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.stack[-1].CheckBegin(filename, clean_lines, linenum, error) 1986ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1987ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Update access control if we are inside a class/struct 1988ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if self.stack and isinstance(self.stack[-1], _ClassInfo): 1989b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian classinfo = self.stack[-1] 1990b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian access_match = Match( 1991b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r'^(.*)\b(public|private|protected|signals)(\s+(?:slots\s*)?)?' 1992b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r':(?:[^:]|$)', 1993b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian line) 1994ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if access_match: 1995b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian classinfo.access = access_match.group(2) 1996b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1997b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Check that access keywords are indented +1 space. Skip this 1998b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # check if the keywords are not preceded by whitespaces. 1999b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian indent = access_match.group(1) 2000b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (len(indent) != classinfo.class_indent + 1 and 2001b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian Match(r'^\s*$', indent)): 2002b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if classinfo.is_struct: 2003b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian parent = 'struct ' + classinfo.name 2004b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian else: 2005b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian parent = 'class ' + classinfo.name 2006b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian slots = '' 2007b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if access_match.group(3): 2008b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian slots = access_match.group(3) 2009b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian error(filename, linenum, 'whitespace/indent', 3, 2010b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian '%s%s: should be indented +1 space inside %s' % ( 2011b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian access_match.group(2), slots, parent)) 2012ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2013ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Consume braces or semicolons from what's left of the line 2014ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang while True: 2015ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Match first brace, semicolon, or closed parenthesis. 2016ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang matched = Match(r'^[^{;)}]*([{;)}])(.*)$', line) 2017ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not matched: 2018ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break 2019ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2020ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang token = matched.group(1) 2021ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if token == '{': 2022ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # If namespace or class hasn't seen a opening brace yet, mark 2023ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # namespace/class head as complete. Push a new block onto the 2024ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # stack otherwise. 2025ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not self.SeenOpenBrace(): 2026ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.stack[-1].seen_open_brace = True 2027ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 2028ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.stack.append(_BlockInfo(True)) 2029ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if _MATCH_ASM.match(line): 2030ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.stack[-1].inline_asm = _BLOCK_ASM 2031ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif token == ';' or token == ')': 2032ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # If we haven't seen an opening brace yet, but we already saw 2033ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # a semicolon, this is probably a forward declaration. Pop 2034ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # the stack for these. 2035ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 2036ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Similarly, if we haven't seen an opening brace yet, but we 2037ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # already saw a closing parenthesis, then these are probably 2038ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # function arguments with extra "class" or "struct" keywords. 2039ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Also pop these stack for these. 2040ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not self.SeenOpenBrace(): 2041ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.stack.pop() 2042ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: # token == '}' 2043ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Perform end of block checks and pop the stack. 2044ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if self.stack: 2045ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.stack[-1].CheckEnd(filename, clean_lines, linenum, error) 2046ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang self.stack.pop() 2047ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = matched.group(2) 2048ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2049ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang def InnermostClass(self): 2050ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Get class info on the top of the stack. 2051ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2052ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Returns: 2053ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang A _ClassInfo object if we are inside a class, or None otherwise. 2054ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 2055ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for i in range(len(self.stack), 0, -1): 2056ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang classinfo = self.stack[i - 1] 2057ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if isinstance(classinfo, _ClassInfo): 2058ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return classinfo 2059ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return None 2060ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2061b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian def CheckCompletedBlocks(self, filename, error): 2062b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian """Checks that all classes and namespaces have been completely parsed. 2063ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2064ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Call this when all lines in a file have been processed. 2065ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 2066ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the current file. 2067ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: The function to call with any errors found. 2068ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 2069ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Note: This test can result in false positives if #ifdef constructs 2070ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # get in the way of brace matching. See the testBuildClass test in 2071ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # cpplint_unittest.py for an example of this. 2072ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for obj in self.stack: 2073ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if isinstance(obj, _ClassInfo): 2074ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, obj.starting_linenum, 'build/class', 5, 2075ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Failed to find complete declaration of class %s' % 2076ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang obj.name) 2077b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian elif isinstance(obj, _NamespaceInfo): 2078b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian error(filename, obj.starting_linenum, 'build/namespaces', 5, 2079b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'Failed to find complete declaration of namespace %s' % 2080b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian obj.name) 2081ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2082ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2083ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef CheckForNonStandardConstructs(filename, clean_lines, linenum, 2084ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nesting_state, error): 2085b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r"""Logs an error if we see certain non-ANSI constructs ignored by gcc-2. 2086ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2087ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Complain about several constructs which gcc-2 accepts, but which are 2088ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang not standard C++. Warning about these in lint is one way to ease the 2089ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang transition to new compilers. 2090ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang - put storage class first (e.g. "static const" instead of "const static"). 2091ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang - "%lld" instead of %qd" in printf-type functions. 2092ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang - "%1$d" is non-standard in printf-type functions. 2093ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang - "\%" is an undefined character escape sequence. 2094ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang - text after #endif is not allowed. 2095ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang - invalid inner-style forward declaration. 2096ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang - >? and <? operators, and their >?= and <?= cousins. 2097ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2098ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Additionally, check for constructor/destructor style violations and reference 2099ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang members, as it is very convenient to do so while checking for 2100ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang gcc-2 compliance. 2101ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2102ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 2103ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the current file. 2104ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_lines: A CleansedLines instance containing the file. 2105ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: The number of the line to check. 2106ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nesting_state: A _NestingState instance which maintains information about 2107ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang the current stack of nested blocks being parsed. 2108ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: A callable to which errors are reported, which takes 4 arguments: 2109ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename, line number, error level, and message 2110ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 2111ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Remove comments from the line, but leave in strings for now. 2113ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = clean_lines.lines[linenum] 2114ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Search(r'printf\s*\(.*".*%[-+ ]?\d*q', line): 2116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'runtime/printf_format', 3, 2117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang '%q in format strings is deprecated. Use %ll instead.') 2118ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2119ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Search(r'printf\s*\(.*".*%\d+\$', line): 2120ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'runtime/printf_format', 2, 2121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang '%N$ formats are unconventional. Try rewriting to avoid them.') 2122ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2123ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Remove escaped backslashes before looking for undefined escapes. 2124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = line.replace('\\\\', '') 2125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Search(r'("|\').*\\(%|\[|\(|{)', line): 2127ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'build/printf_format', 3, 2128ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang '%, [, (, and { are undefined character escapes. Unescape them.') 2129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # For the rest, work with both comments and strings removed. 2131ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = clean_lines.elided[linenum] 2132ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2133ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Search(r'\b(const|volatile|void|char|short|int|long' 2134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang r'|float|double|signed|unsigned' 2135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang r'|schar|u?int8|u?int16|u?int32|u?int64)' 2136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang r'\s+(register|static|extern|typedef)\b', 2137ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line): 2138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'build/storage_class', 5, 2139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Storage class (static, extern, typedef, etc) should be first.') 2140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Match(r'\s*#\s*endif\s*[^/\s]+', line): 2142ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'build/endif_comment', 5, 2143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Uncommented text after #endif is non-standard. Use a comment.') 2144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Match(r'\s*class\s+(\w+\s*::\s*)+\w+\s*;', line): 2146ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'build/forward_decl', 5, 2147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Inner-style forward declarations are invalid. Remove this line.') 2148ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2149ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Search(r'(\w+|[+-]?\d+(\.\d*)?)\s*(<|>)\?=?\s*(\w+|[+-]?\d+)(\.\d*)?', 2150ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line): 2151ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'build/deprecated', 3, 2152ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang '>? and <? (max and min) operators are non-standard and deprecated.') 2153ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2154ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Search(r'^\s*const\s*string\s*&\s*\w+\s*;', line): 2155ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # TODO(unknown): Could it be expanded safely to arbitrary references, 2156ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # without triggering too many false positives? The first 2157ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # attempt triggered 5 warnings for mostly benign code in the regtest, hence 2158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # the restriction. 2159ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Here's the original regexp, for the reference: 2160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # type_name = r'\w+((\s*::\s*\w+)|(\s*<\s*\w+?\s*>))?' 2161ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # r'\s*const\s*' + type_name + '\s*&\s*\w+\s*;' 2162ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'runtime/member_string_references', 2, 2163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'const string& members are dangerous. It is much better to use ' 2164ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'alternatives, such as pointers or simple constants.') 2165ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2166ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Everything else in this function operates on class declarations. 2167ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Return early if the top of the nesting stack is not a class, or if 2168ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # the class head is not completed yet. 2169ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang classinfo = nesting_state.InnermostClass() 2170ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not classinfo or not classinfo.seen_open_brace: 2171ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 2172ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2173ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # The class may have been declared with namespace or classname qualifiers. 2174ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # The constructor and destructor will not have those qualifiers. 2175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang base_classname = classinfo.name.split('::')[-1] 2176ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2177ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Look for single-argument constructors that aren't marked explicit. 2178ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Technically a valid construct, but against style. 2179ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang args = Match(r'\s+(?:inline\s+)?%s\s*\(([^,()]+)\)' 2180ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang % re.escape(base_classname), 2181ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line) 2182ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (args and 2183ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang args.group(1) != 'void' and 2184b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian not Match(r'(const\s+)?%s(\s+const)?\s*(?:<\w+>\s*)?&' 2185b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian % re.escape(base_classname), args.group(1).strip())): 2186ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'runtime/explicit', 5, 2187ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Single-argument constructors should be marked explicit.') 2188ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2189ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2190ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef CheckSpacingForFunctionCall(filename, line, linenum, error): 2191ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Checks for the correctness of various spacing around function calls. 2192ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2193ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 2194ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the current file. 2195ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line: The text of the line to check. 2196ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: The number of the line to check. 2197ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: The function to call with any errors found. 2198ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 2199ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2200ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Since function calls often occur inside if/for/while/switch 2201ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # expressions - which have their own, more liberal conventions - we 2202ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # first see if we should be looking inside such an expression for a 2203ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # function call, to which we can apply more strict standards. 2204ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang fncall = line # if there's no control flow construct, look at whole line 2205ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for pattern in (r'\bif\s*\((.*)\)\s*{', 2206ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang r'\bfor\s*\((.*)\)\s*{', 2207ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang r'\bwhile\s*\((.*)\)\s*[{;]', 2208ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang r'\bswitch\s*\((.*)\)\s*{'): 2209ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match = Search(pattern, line) 2210ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if match: 2211ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang fncall = match.group(1) # look inside the parens for function calls 2212ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break 2213ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2214ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Except in if/for/while/switch, there should never be space 2215ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # immediately inside parens (eg "f( 3, 4 )"). We make an exception 2216ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # for nested parens ( (a+b) + c ). Likewise, there should never be 2217ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # a space before a ( when it's a function argument. I assume it's a 2218ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # function argument when the char before the whitespace is legal in 2219ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # a function name (alnum + _) and we're not starting a macro. Also ignore 2220ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # pointers and references to arrays and functions coz they're too tricky: 2221ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # we use a very simple way to recognize these: 2222ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # " (something)(maybe-something)" or 2223ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # " (something)(maybe-something," or 2224ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # " (something)[something]" 2225ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Note that we assume the contents of [] to be short enough that 2226ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # they'll never need to wrap. 2227ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if ( # Ignore control structures. 2228b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian not Search(r'\b(if|for|while|switch|return|new|delete|catch|sizeof)\b', 2229b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian fncall) and 2230ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Ignore pointers/references to functions. 2231ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang not Search(r' \([^)]+\)\([^)]*(\)|,$)', fncall) and 2232ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Ignore pointers/references to arrays. 2233ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang not Search(r' \([^)]+\)\[[^\]]+\]', fncall)): 2234ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Search(r'\w\s*\(\s(?!\s*\\$)', fncall): # a ( used for a fn call 2235ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/parens', 4, 2236ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Extra space after ( in function call') 2237ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif Search(r'\(\s+(?!(\s*\\)|\()', fncall): 2238ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/parens', 2, 2239ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Extra space after (') 2240ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (Search(r'\w\s+\(', fncall) and 2241ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang not Search(r'#\s*define|typedef', fncall) and 2242b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian not Search(r'\w\s+\((\w+::)*\*\w+\)\(', fncall)): 2243ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/parens', 4, 2244ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Extra space before ( in function call') 2245ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # If the ) is followed only by a newline or a { + newline, assume it's 2246ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # part of a control statement (if/while/etc), and don't complain 2247ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Search(r'[^)]\s+\)\s*[^{\s]', fncall): 2248ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # If the closing parenthesis is preceded by only whitespaces, 2249ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # try to give a more descriptive error message. 2250ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Search(r'^\s+\)', fncall): 2251ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/parens', 2, 2252ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Closing ) should be moved to the previous line') 2253ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 2254ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/parens', 2, 2255ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Extra space before )') 2256ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2257ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2258ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef IsBlankLine(line): 2259ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Returns true if the given line is blank. 2260ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2261ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang We consider a line to be blank if the line is empty or consists of 2262ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang only white spaces. 2263ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2264ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 2265ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line: A line of a string. 2266ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2267ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Returns: 2268ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang True, if the given line is blank. 2269ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 2270ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return not line or line.isspace() 2271ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2272ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2273ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef CheckForFunctionLengths(filename, clean_lines, linenum, 2274ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang function_state, error): 2275ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Reports for long function bodies. 2276ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2277ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang For an overview why this is done, see: 2278ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Write_Short_Functions 2279ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2280ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Uses a simplistic algorithm assuming other style guidelines 2281ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (especially spacing) are followed. 2282ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Only checks unindented functions, so class members are unchecked. 2283ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Trivial bodies are unchecked, so constructors with huge initializer lists 2284ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang may be missed. 2285ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Blank/comment lines are not counted so as to avoid encouraging the removal 2286ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang of vertical space and comments just to get through a lint check. 2287ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang NOLINT *on the last line of a function* disables this check. 2288ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2289ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 2290ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the current file. 2291ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_lines: A CleansedLines instance containing the file. 2292ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: The number of the line to check. 2293ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang function_state: Current function name and lines in body so far. 2294ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: The function to call with any errors found. 2295ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 2296ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang lines = clean_lines.lines 2297ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = lines[linenum] 2298ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang raw = clean_lines.raw_lines 2299ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang raw_line = raw[linenum] 2300ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang joined_line = '' 2301ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2302ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang starting_func = False 2303ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang regexp = r'(\w(\w|::|\*|\&|\s)*)\(' # decls * & space::name( ... 2304ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match_result = Match(regexp, line) 2305ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if match_result: 2306ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # If the name is all caps and underscores, figure it's a macro and 2307ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # ignore it, unless it's TEST or TEST_F. 2308ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang function_name = match_result.group(1).split()[-1] 2309ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if function_name == 'TEST' or function_name == 'TEST_F' or ( 2310ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang not Match(r'[A-Z_]+$', function_name)): 2311ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang starting_func = True 2312ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2313ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if starting_func: 2314ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang body_found = False 2315ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for start_linenum in xrange(linenum, clean_lines.NumLines()): 2316ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang start_line = lines[start_linenum] 2317ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang joined_line += ' ' + start_line.lstrip() 2318ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Search(r'(;|})', start_line): # Declarations and trivial functions 2319ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang body_found = True 2320ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break # ... ignore 2321ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif Search(r'{', start_line): 2322ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang body_found = True 2323ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang function = Search(r'((\w|:)*)\(', line).group(1) 2324ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Match(r'TEST', function): # Handle TEST... macros 2325ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang parameter_regexp = Search(r'(\(.*\))', joined_line) 2326ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if parameter_regexp: # Ignore bad syntax 2327ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang function += parameter_regexp.group(1) 2328ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 2329ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang function += '()' 2330ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang function_state.Begin(function) 2331ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break 2332ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not body_found: 2333ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # No body for the function (or evidence of a non-function) was found. 2334ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'readability/fn_size', 5, 2335ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Lint failed to find start of function body.') 2336ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif Match(r'^\}\s*$', line): # function end 2337ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang function_state.Check(error, filename, linenum) 2338ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang function_state.End() 2339ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif not Match(r'^\s*$', line): 2340ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang function_state.Count() # Count non-blank/non-comment lines. 2341ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2342ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2343ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_RE_PATTERN_TODO = re.compile(r'^//(\s*)TODO(\(.+?\))?:?(\s|$)?') 2344ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2345ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2346ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef CheckComment(comment, filename, linenum, error): 2347ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Checks for common mistakes in TODO comments. 2348ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2349ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 2350ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang comment: The text of the comment from the line in question. 2351ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the current file. 2352ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: The number of the line to check. 2353ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: The function to call with any errors found. 2354ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 2355ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match = _RE_PATTERN_TODO.match(comment) 2356ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if match: 2357ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # One whitespace is correct; zero whitespace is handled elsewhere. 2358ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang leading_whitespace = match.group(1) 2359ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if len(leading_whitespace) > 1: 2360ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/todo', 2, 2361ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Too many spaces before TODO') 2362ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2363ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang username = match.group(2) 2364ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not username: 2365ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'readability/todo', 2, 2366ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Missing username in TODO; it should look like ' 2367ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang '"// TODO(my_username): Stuff."') 2368ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2369ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang middle_whitespace = match.group(3) 2370b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Comparisons made explicit for correctness -- pylint: disable=g-explicit-bool-comparison 2371ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if middle_whitespace != ' ' and middle_whitespace != '': 2372ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/todo', 2, 2373ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'TODO(my_username) should be followed by a space') 2374ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2375ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef CheckAccess(filename, clean_lines, linenum, nesting_state, error): 2376ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Checks for improper use of DISALLOW* macros. 2377ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2378ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 2379ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the current file. 2380ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_lines: A CleansedLines instance containing the file. 2381ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: The number of the line to check. 2382ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nesting_state: A _NestingState instance which maintains information about 2383ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang the current stack of nested blocks being parsed. 2384ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: The function to call with any errors found. 2385ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 2386ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = clean_lines.elided[linenum] # get rid of comments and strings 2387ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2388ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang matched = Match((r'\s*(DISALLOW_COPY_AND_ASSIGN|' 2389ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang r'DISALLOW_EVIL_CONSTRUCTORS|' 2390ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang r'DISALLOW_IMPLICIT_CONSTRUCTORS)'), line) 2391ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not matched: 2392ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 2393ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if nesting_state.stack and isinstance(nesting_state.stack[-1], _ClassInfo): 2394ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if nesting_state.stack[-1].access != 'private': 2395ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'readability/constructors', 3, 2396ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang '%s must be in the private: section' % matched.group(1)) 2397ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2398ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 2399ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Found DISALLOW* macro outside a class declaration, or perhaps it 2400ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # was used inside a function when it should have been part of the 2401ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # class declaration. We could issue a warning here, but it 2402ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # probably resulted in a compiler error already. 2403ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang pass 2404ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2405ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2406ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef FindNextMatchingAngleBracket(clean_lines, linenum, init_suffix): 2407ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Find the corresponding > to close a template. 2408ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2409ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 2410ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_lines: A CleansedLines instance containing the file. 2411ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: Current line number. 2412ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang init_suffix: Remainder of the current line after the initial <. 2413ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2414ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Returns: 2415ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang True if a matching bracket exists. 2416ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 2417ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = init_suffix 2418ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nesting_stack = ['<'] 2419ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang while True: 2420ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Find the next operator that can tell us whether < is used as an 2421ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # opening bracket or as a less-than operator. We only want to 2422ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # warn on the latter case. 2423ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 2424ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # We could also check all other operators and terminate the search 2425ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # early, e.g. if we got something like this "a<b+c", the "<" is 2426ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # most likely a less-than operator, but then we will get false 2427b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # positives for default arguments and other template expressions. 2428ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match = Search(r'^[^<>(),;\[\]]*([<>(),;\[\]])(.*)$', line) 2429ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if match: 2430ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Found an operator, update nesting stack 2431ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang operator = match.group(1) 2432ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = match.group(2) 2433ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2434ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if nesting_stack[-1] == '<': 2435ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Expecting closing angle bracket 2436ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if operator in ('<', '(', '['): 2437ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nesting_stack.append(operator) 2438ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif operator == '>': 2439ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nesting_stack.pop() 2440ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not nesting_stack: 2441ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Found matching angle bracket 2442ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return True 2443ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif operator == ',': 2444ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Got a comma after a bracket, this is most likely a template 2445ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # argument. We have not seen a closing angle bracket yet, but 2446ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # it's probably a few lines later if we look for it, so just 2447ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # return early here. 2448ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return True 2449ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 2450ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Got some other operator. 2451ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return False 2452ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2453ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 2454ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Expecting closing parenthesis or closing bracket 2455ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if operator in ('<', '(', '['): 2456ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nesting_stack.append(operator) 2457ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif operator in (')', ']'): 2458ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # We don't bother checking for matching () or []. If we got 2459ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # something like (] or [), it would have been a syntax error. 2460ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nesting_stack.pop() 2461ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2462ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 2463ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Scan the next line 2464ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum += 1 2465ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if linenum >= len(clean_lines.elided): 2466ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break 2467ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = clean_lines.elided[linenum] 2468ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2469ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Exhausted all remaining lines and still no matching angle bracket. 2470ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Most likely the input was incomplete, otherwise we should have 2471ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # seen a semicolon and returned early. 2472ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return True 2473ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2474ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2475ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef FindPreviousMatchingAngleBracket(clean_lines, linenum, init_prefix): 2476ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Find the corresponding < that started a template. 2477ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2478ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 2479ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_lines: A CleansedLines instance containing the file. 2480ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: Current line number. 2481ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang init_prefix: Part of the current line before the initial >. 2482ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2483ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Returns: 2484ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang True if a matching bracket exists. 2485ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 2486ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = init_prefix 2487ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nesting_stack = ['>'] 2488ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang while True: 2489ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Find the previous operator 2490ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match = Search(r'^(.*)([<>(),;\[\]])[^<>(),;\[\]]*$', line) 2491ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if match: 2492ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Found an operator, update nesting stack 2493ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang operator = match.group(2) 2494ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = match.group(1) 2495ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2496ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if nesting_stack[-1] == '>': 2497ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Expecting opening angle bracket 2498ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if operator in ('>', ')', ']'): 2499ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nesting_stack.append(operator) 2500ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif operator == '<': 2501ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nesting_stack.pop() 2502ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not nesting_stack: 2503ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Found matching angle bracket 2504ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return True 2505ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif operator == ',': 2506ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Got a comma before a bracket, this is most likely a 2507ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # template argument. The opening angle bracket is probably 2508ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # there if we look for it, so just return early here. 2509ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return True 2510ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 2511ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Got some other operator. 2512ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return False 2513ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2514ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 2515ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Expecting opening parenthesis or opening bracket 2516ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if operator in ('>', ')', ']'): 2517ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nesting_stack.append(operator) 2518ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif operator in ('(', '['): 2519ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nesting_stack.pop() 2520ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2521ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 2522ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Scan the previous line 2523ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum -= 1 2524ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if linenum < 0: 2525ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break 2526ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = clean_lines.elided[linenum] 2527ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2528ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Exhausted all earlier lines and still no matching angle bracket. 2529ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return False 2530ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2531ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2532ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef CheckSpacing(filename, clean_lines, linenum, nesting_state, error): 2533ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Checks for the correctness of various spacing issues in the code. 2534ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2535ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Things we check for: spaces around operators, spaces after 2536ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if/for/while/switch, no spaces around parens in function calls, two 2537ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang spaces between code and comment, don't start a block with a blank 2538ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line, don't end a function with a blank line, don't add a blank line 2539ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang after public/protected/private, don't have too many blank lines in a row. 2540ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2541ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 2542ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the current file. 2543ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_lines: A CleansedLines instance containing the file. 2544ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: The number of the line to check. 2545ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nesting_state: A _NestingState instance which maintains information about 2546ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang the current stack of nested blocks being parsed. 2547ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: The function to call with any errors found. 2548ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 2549ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2550b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Don't use "elided" lines here, otherwise we can't check commented lines. 2551b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Don't want to use "raw" either, because we don't want to check inside C++11 2552b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # raw strings, 2553b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian raw = clean_lines.lines_without_raw_strings 2554ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = raw[linenum] 2555ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2556ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Before nixing comments, check if the line is blank for no good 2557ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # reason. This includes the first line after a block is opened, and 2558ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # blank lines at the end of a function (ie, right before a line like '}' 2559ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 2560ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Skip all the blank line checks if we are immediately inside a 2561ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # namespace body. In other words, don't issue blank line warnings 2562ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # for this block: 2563ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # namespace { 2564ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 2565ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # } 2566ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 2567ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # A warning about missing end of namespace comments will be issued instead. 2568ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if IsBlankLine(line) and not nesting_state.InNamespaceBody(): 2569ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elided = clean_lines.elided 2570ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang prev_line = elided[linenum - 1] 2571ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang prevbrace = prev_line.rfind('{') 2572ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # TODO(unknown): Don't complain if line before blank line, and line after, 2573ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # both start with alnums and are indented the same amount. 2574ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # This ignores whitespace at the start of a namespace block 2575ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # because those are not usually indented. 2576ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if prevbrace != -1 and prev_line[prevbrace:].find('}') == -1: 2577ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # OK, we have a blank line at the start of a code block. Before we 2578ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # complain, we check if it is an exception to the rule: The previous 2579ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # non-empty line has the parameters of a function header that are indented 2580ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 4 spaces (because they did not fit in a 80 column line when placed on 2581ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # the same line as the function name). We also check for the case where 2582ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # the previous line is indented 6 spaces, which may happen when the 2583ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # initializers of a constructor do not fit into a 80 column line. 2584ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang exception = False 2585ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Match(r' {6}\w', prev_line): # Initializer list? 2586ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # We are looking for the opening column of initializer list, which 2587ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # should be indented 4 spaces to cause 6 space indentation afterwards. 2588ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang search_position = linenum-2 2589ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang while (search_position >= 0 2590ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang and Match(r' {6}\w', elided[search_position])): 2591ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang search_position -= 1 2592ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang exception = (search_position >= 0 2593ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang and elided[search_position][:5] == ' :') 2594ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 2595ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Search for the function arguments or an initializer list. We use a 2596ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # simple heuristic here: If the line is indented 4 spaces; and we have a 2597ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # closing paren, without the opening paren, followed by an opening brace 2598ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # or colon (for initializer lists) we assume that it is the last line of 2599ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # a function header. If we have a colon indented 4 spaces, it is an 2600ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # initializer list. 2601ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang exception = (Match(r' {4}\w[^\(]*\)\s*(const\s*)?(\{\s*$|:)', 2602ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang prev_line) 2603ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang or Match(r' {4}:', prev_line)) 2604ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2605ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not exception: 2606ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/blank_line', 2, 2607b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'Redundant blank line at the start of a code block ' 2608b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'should be deleted.') 2609ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Ignore blank lines at the end of a block in a long if-else 2610ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # chain, like this: 2611ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # if (condition1) { 2612ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # // Something followed by a blank line 2613ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 2614ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # } else if (condition2) { 2615ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # // Something else 2616ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # } 2617ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if linenum + 1 < clean_lines.NumLines(): 2618ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang next_line = raw[linenum + 1] 2619ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (next_line 2620ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang and Match(r'\s*}', next_line) 2621ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang and next_line.find('} else ') == -1): 2622ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/blank_line', 3, 2623b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'Redundant blank line at the end of a code block ' 2624b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'should be deleted.') 2625ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2626ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang matched = Match(r'\s*(public|protected|private):', prev_line) 2627ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if matched: 2628ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/blank_line', 3, 2629ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Do not leave a blank line after "%s:"' % matched.group(1)) 2630ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2631ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Next, we complain if there's a comment too near the text 2632ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang commentpos = line.find('//') 2633ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if commentpos != -1: 2634ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Check if the // may be in quotes. If so, ignore it 2635b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Comparisons made explicit for clarity -- pylint: disable=g-explicit-bool-comparison 2636ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (line.count('"', 0, commentpos) - 2637ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line.count('\\"', 0, commentpos)) % 2 == 0: # not in quotes 2638ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Allow one space for new scopes, two spaces otherwise: 2639ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (not Match(r'^\s*{ //', line) and 2640ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ((commentpos >= 1 and 2641ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line[commentpos-1] not in string.whitespace) or 2642ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (commentpos >= 2 and 2643ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line[commentpos-2] not in string.whitespace))): 2644ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/comments', 2, 2645ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'At least two spaces is best between code and comments') 2646ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # There should always be a space between the // and the comment 2647ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang commentend = commentpos + 2 2648ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if commentend < len(line) and not line[commentend] == ' ': 2649ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # but some lines are exceptions -- e.g. if they're big 2650ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # comment delimiters like: 2651ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # //---------------------------------------------------------- 2652ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # or are an empty C++ style Doxygen comment, like: 2653ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # /// 2654b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # or C++ style Doxygen comments placed after the variable: 2655b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # ///< Header comment 2656b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # //!< Header comment 2657ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # or they begin with multiple slashes followed by a space: 2658ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # //////// Header comment 2659ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match = (Search(r'[=/-]{4,}\s*$', line[commentend:]) or 2660ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Search(r'^/$', line[commentend:]) or 2661b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian Search(r'^!< ', line[commentend:]) or 2662b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian Search(r'^/< ', line[commentend:]) or 2663ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Search(r'^/+ ', line[commentend:])) 2664ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not match: 2665ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/comments', 4, 2666ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Should have a space between // and comment') 2667ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang CheckComment(line[commentpos:], filename, linenum, error) 2668ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2669ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = clean_lines.elided[linenum] # get rid of comments and strings 2670ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2671ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Don't try to do spacing checks for operator methods 2672ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = re.sub(r'operator(==|!=|<|<<|<=|>=|>>|>)\(', 'operator\(', line) 2673ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2674ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # We allow no-spaces around = within an if: "if ( (a=Foo()) == 0 )". 2675ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Otherwise not. Note we only check for non-spaces on *both* sides; 2676ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # sometimes people put non-spaces on one side when aligning ='s among 2677ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # many lines (not that this is behavior that I approve of...) 2678ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Search(r'[\w.]=[\w.]', line) and not Search(r'\b(if|while) ', line): 2679ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/operators', 4, 2680ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Missing spaces around =') 2681ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2682ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # It's ok not to have spaces around binary operators like + - * /, but if 2683ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # there's too little whitespace, we get concerned. It's hard to tell, 2684ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # though, so we punt on this one for now. TODO. 2685ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2686ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # You should always have whitespace around binary operators. 2687ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 2688ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Check <= and >= first to avoid false positives with < and >, then 2689ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # check non-include lines for spacing around < and >. 2690ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match = Search(r'[^<>=!\s](==|!=|<=|>=)[^<>=!\s]', line) 2691ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if match: 2692ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/operators', 3, 2693ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Missing spaces around %s' % match.group(1)) 2694ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # We allow no-spaces around << when used like this: 10<<20, but 2695ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # not otherwise (particularly, not when used as streams) 2696b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Also ignore using ns::operator<<; 2697b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian match = Search(r'(operator|\S)(?:L|UL|ULL|l|ul|ull)?<<(\S)', line) 2698b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (match and 2699b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian not (match.group(1).isdigit() and match.group(2).isdigit()) and 2700b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian not (match.group(1) == 'operator' and match.group(2) == ';')): 2701ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/operators', 3, 2702ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Missing spaces around <<') 2703ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif not Match(r'#.*include', line): 2704ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Avoid false positives on -> 2705ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang reduced_line = line.replace('->', '') 2706ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2707ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Look for < that is not surrounded by spaces. This is only 2708ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # triggered if both sides are missing spaces, even though 2709ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # technically should should flag if at least one side is missing a 2710ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # space. This is done to avoid some false positives with shifts. 2711ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match = Search(r'[^\s<]<([^\s=<].*)', reduced_line) 2712ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (match and 2713ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang not FindNextMatchingAngleBracket(clean_lines, linenum, match.group(1))): 2714ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/operators', 3, 2715ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Missing spaces around <') 2716ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2717ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Look for > that is not surrounded by spaces. Similar to the 2718ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # above, we only trigger if both sides are missing spaces to avoid 2719ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # false positives with shifts. 2720ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match = Search(r'^(.*[^\s>])>[^\s=>]', reduced_line) 2721ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (match and 2722ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang not FindPreviousMatchingAngleBracket(clean_lines, linenum, 2723ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match.group(1))): 2724ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/operators', 3, 2725ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Missing spaces around >') 2726ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2727ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # We allow no-spaces around >> for almost anything. This is because 2728ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # C++11 allows ">>" to close nested templates, which accounts for 2729ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # most cases when ">>" is not followed by a space. 2730ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 2731ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # We still warn on ">>" followed by alpha character, because that is 2732ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # likely due to ">>" being used for right shifts, e.g.: 2733ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # value >> alpha 2734ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 2735ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # When ">>" is used to close templates, the alphanumeric letter that 2736ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # follows would be part of an identifier, and there should still be 2737ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # a space separating the template type and the identifier. 2738ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # type<type<type>> alpha 2739ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match = Search(r'>>[a-zA-Z_]', line) 2740ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if match: 2741ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/operators', 3, 2742ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Missing spaces around >>') 2743ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2744ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # There shouldn't be space around unary operators 2745ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match = Search(r'(!\s|~\s|[\s]--[\s;]|[\s]\+\+[\s;])', line) 2746ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if match: 2747ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/operators', 4, 2748ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Extra space for operator %s' % match.group(1)) 2749ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2750ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # A pet peeve of mine: no spaces after an if, while, switch, or for 2751ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match = Search(r' (if\(|for\(|while\(|switch\()', line) 2752ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if match: 2753ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/parens', 5, 2754ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Missing space before ( in %s' % match.group(1)) 2755ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2756ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # For if/for/while/switch, the left and right parens should be 2757ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # consistent about how many spaces are inside the parens, and 2758ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # there should either be zero or one spaces inside the parens. 2759ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # We don't want: "if ( foo)" or "if ( foo )". 2760ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Exception: "for ( ; foo; bar)" and "for (foo; bar; )" are allowed. 2761ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match = Search(r'\b(if|for|while|switch)\s*' 2762ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang r'\(([ ]*)(.).*[^ ]+([ ]*)\)\s*{\s*$', 2763ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line) 2764ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if match: 2765ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if len(match.group(2)) != len(match.group(4)): 2766ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not (match.group(3) == ';' and 2767ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang len(match.group(2)) == 1 + len(match.group(4)) or 2768ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang not match.group(2) and Search(r'\bfor\s*\(.*; \)', line)): 2769ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/parens', 5, 2770ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Mismatching spaces inside () in %s' % match.group(1)) 2771b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if len(match.group(2)) not in [0, 1]: 2772ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/parens', 5, 2773ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Should have zero or one spaces inside ( and ) in %s' % 2774ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match.group(1)) 2775ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2776ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # You should always have a space after a comma (either as fn arg or operator) 2777b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 2778b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # This does not apply when the non-space character following the 2779b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # comma is another comma, since the only time when that happens is 2780b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # for empty macro arguments. 2781b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 2782b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # We run this check in two passes: first pass on elided lines to 2783b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # verify that lines contain missing whitespaces, second pass on raw 2784b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # lines to confirm that those missing whitespaces are not due to 2785b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # elided comments. 2786b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if Search(r',[^,\s]', line) and Search(r',[^,\s]', raw[linenum]): 2787ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/comma', 3, 2788ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Missing space after ,') 2789ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2790ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # You should always have a space after a semicolon 2791ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # except for few corner cases 2792ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # TODO(unknown): clarify if 'if (1) { return 1;}' is requires one more 2793ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # space after ; 2794ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Search(r';[^\s};\\)/]', line): 2795ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/semicolon', 3, 2796ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Missing space after ;') 2797ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2798ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Next we will look for issues with function calls. 2799ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang CheckSpacingForFunctionCall(filename, line, linenum, error) 2800ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2801ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Except after an opening paren, or after another opening brace (in case of 2802ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # an initializer list, for instance), you should have spaces before your 2803ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # braces. And since you should never have braces at the beginning of a line, 2804ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # this is an easy test. 2805b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian match = Match(r'^(.*[^ ({]){', line) 2806b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if match: 2807b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Try a bit harder to check for brace initialization. This 2808b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # happens in one of the following forms: 2809b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Constructor() : initializer_list_{} { ... } 2810b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Constructor{}.MemberFunction() 2811b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Type variable{}; 2812b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # FunctionCall(type{}, ...); 2813b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # LastArgument(..., type{}); 2814b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # LOG(INFO) << type{} << " ..."; 2815b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # map_of_type[{...}] = ...; 2816b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 2817b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # We check for the character following the closing brace, and 2818b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # silence the warning if it's one of those listed above, i.e. 2819b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # "{.;,)<]". 2820b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 2821b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # To account for nested initializer list, we allow any number of 2822b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # closing braces up to "{;,)<". We can't simply silence the 2823b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # warning on first sight of closing brace, because that would 2824b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # cause false negatives for things that are not initializer lists. 2825b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Silence this: But not this: 2826b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Outer{ if (...) { 2827b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Inner{...} if (...){ // Missing space before { 2828b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # }; } 2829b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 2830b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # There is a false negative with this approach if people inserted 2831b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # spurious semicolons, e.g. "if (cond){};", but we will catch the 2832b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # spurious semicolon with a separate check. 2833b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian (endline, endlinenum, endpos) = CloseExpression( 2834b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian clean_lines, linenum, len(match.group(1))) 2835b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian trailing_text = '' 2836b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if endpos > -1: 2837b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian trailing_text = endline[endpos:] 2838b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian for offset in xrange(endlinenum + 1, 2839b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian min(endlinenum + 3, clean_lines.NumLines() - 1)): 2840b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian trailing_text += clean_lines.elided[offset] 2841b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if not Match(r'^[\s}]*[{.;,)<\]]', trailing_text): 2842b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian error(filename, linenum, 'whitespace/braces', 5, 2843b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'Missing space before {') 2844ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2845ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Make sure '} else {' has spaces. 2846ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Search(r'}else', line): 2847ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/braces', 5, 2848ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Missing space before else') 2849ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2850ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # You shouldn't have spaces before your brackets, except maybe after 2851ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 'delete []' or 'new char * []'. 2852ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Search(r'\w\s+\[', line) and not Search(r'delete\s+\[', line): 2853ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/braces', 5, 2854ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Extra space before [') 2855ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2856ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # You shouldn't have a space before a semicolon at the end of the line. 2857ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # There's a special case for "for" since the style guide allows space before 2858ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # the semicolon there. 2859ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Search(r':\s*;\s*$', line): 2860ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/semicolon', 5, 2861ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Semicolon defining empty statement. Use {} instead.') 2862ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif Search(r'^\s*;\s*$', line): 2863ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/semicolon', 5, 2864ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Line contains only semicolon. If this should be an empty statement, ' 2865ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'use {} instead.') 2866ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif (Search(r'\s+;\s*$', line) and 2867ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang not Search(r'\bfor\b', line)): 2868ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/semicolon', 5, 2869ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Extra space before last semicolon. If this should be an empty ' 2870ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'statement, use {} instead.') 2871ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2872ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # In range-based for, we wanted spaces before and after the colon, but 2873ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # not around "::" tokens that might appear. 2874ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (Search('for *\(.*[^:]:[^: ]', line) or 2875ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Search('for *\(.*[^: ]:[^:]', line)): 2876ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/forcolon', 2, 2877ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Missing space around colon in range-based for loop') 2878ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2879ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2880ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef CheckSectionSpacing(filename, clean_lines, class_info, linenum, error): 2881ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Checks for additional blank line issues related to sections. 2882ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2883ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Currently the only thing checked here is blank line before protected/private. 2884ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2885ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 2886ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the current file. 2887ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_lines: A CleansedLines instance containing the file. 2888ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang class_info: A _ClassInfo objects. 2889ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: The number of the line to check. 2890ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: The function to call with any errors found. 2891ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 2892ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Skip checks if the class is small, where small means 25 lines or less. 2893ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 25 lines seems like a good cutoff since that's the usual height of 2894ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # terminals, and any class that can't fit in one screen can't really 2895ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # be considered "small". 2896ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 2897ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Also skip checks if we are on the first line. This accounts for 2898ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # classes that look like 2899ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # class Foo { public: ... }; 2900ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 2901ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # If we didn't find the end of the class, last_line would be zero, 2902ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # and the check will be skipped by the first condition. 2903ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (class_info.last_line - class_info.starting_linenum <= 24 or 2904ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum <= class_info.starting_linenum): 2905ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 2906ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2907ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang matched = Match(r'\s*(public|protected|private):', clean_lines.lines[linenum]) 2908ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if matched: 2909ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Issue warning if the line before public/protected/private was 2910ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # not a blank line, but don't do this if the previous line contains 2911ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # "class" or "struct". This can happen two ways: 2912ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # - We are at the beginning of the class. 2913ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # - We are forward-declaring an inner class that is semantically 2914ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # private, but needed to be public for implementation reasons. 2915ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Also ignores cases where the previous line ends with a backslash as can be 2916ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # common when defining classes in C macros. 2917ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang prev_line = clean_lines.lines[linenum - 1] 2918ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (not IsBlankLine(prev_line) and 2919ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang not Search(r'\b(class|struct)\b', prev_line) and 2920ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang not Search(r'\\$', prev_line)): 2921ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Try a bit harder to find the beginning of the class. This is to 2922ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # account for multi-line base-specifier lists, e.g.: 2923ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # class Derived 2924ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # : public Base { 2925ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang end_class_head = class_info.starting_linenum 2926ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for i in range(class_info.starting_linenum, linenum): 2927ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Search(r'\{\s*$', clean_lines.lines[i]): 2928ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang end_class_head = i 2929ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break 2930ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if end_class_head < linenum - 1: 2931ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/blank_line', 3, 2932ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang '"%s:" should be preceded by a blank line' % matched.group(1)) 2933ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2934ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2935ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef GetPreviousNonBlankLine(clean_lines, linenum): 2936ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Return the most recent non-blank line and its line number. 2937ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2938ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 2939ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_lines: A CleansedLines instance containing the file contents. 2940ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: The number of the line to check. 2941ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2942ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Returns: 2943ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang A tuple with two elements. The first element is the contents of the last 2944ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang non-blank line before the current line, or the empty string if this is the 2945ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang first non-blank line. The second is the line number of that line, or -1 2946ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if this is the first non-blank line. 2947ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 2948ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2949ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang prevlinenum = linenum - 1 2950ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang while prevlinenum >= 0: 2951ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang prevline = clean_lines.elided[prevlinenum] 2952ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not IsBlankLine(prevline): # if not a blank line... 2953ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return (prevline, prevlinenum) 2954ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang prevlinenum -= 1 2955ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return ('', -1) 2956ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2957ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2958ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef CheckBraces(filename, clean_lines, linenum, error): 2959ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Looks for misplaced braces (e.g. at the end of line). 2960ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2961ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 2962ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the current file. 2963ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_lines: A CleansedLines instance containing the file. 2964ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: The number of the line to check. 2965ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: The function to call with any errors found. 2966ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 2967ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2968ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = clean_lines.elided[linenum] # get rid of comments and strings 2969ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2970ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Match(r'\s*{\s*$', line): 2971b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # We allow an open brace to start a line in the case where someone is using 2972b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # braces in a block to explicitly create a new scope, which is commonly used 2973b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # to control the lifetime of stack-allocated variables. Braces are also 2974b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # used for brace initializers inside function calls. We don't detect this 2975b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # perfectly: we just don't complain if the last non-whitespace character on 2976b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # the previous non-blank line is ',', ';', ':', '(', '{', or '}', or if the 2977b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # previous line starts a preprocessor block. 2978ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0] 2979b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (not Search(r'[,;:}{(]\s*$', prevline) and 2980ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang not Match(r'\s*#', prevline)): 2981ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/braces', 4, 2982ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang '{ should almost always be at the end of the previous line') 2983ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2984ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # An else clause should be on the same line as the preceding closing brace. 2985ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Match(r'\s*else\s*', line): 2986ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0] 2987ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Match(r'\s*}\s*$', prevline): 2988ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/newline', 4, 2989ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'An else should appear on the same line as the preceding }') 2990ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2991ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # If braces come on one side of an else, they should be on both. 2992ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # However, we have to worry about "else if" that spans multiple lines! 2993ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Search(r'}\s*else[^{]*$', line) or Match(r'[^}]*else\s*{', line): 2994ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Search(r'}\s*else if([^{]*)$', line): # could be multi-line if 2995ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # find the ( after the if 2996ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang pos = line.find('else if') 2997ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang pos = line.find('(', pos) 2998ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if pos > 0: 2999ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (endline, _, endpos) = CloseExpression(clean_lines, linenum, pos) 3000ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if endline[endpos:].find('{') == -1: # must be brace after if 3001ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'readability/braces', 5, 3002ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'If an else has a brace on one side, it should have it on both') 3003ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: # common case: else not followed by a multi-line if 3004ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'readability/braces', 5, 3005ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'If an else has a brace on one side, it should have it on both') 3006ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3007ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Likewise, an else should never have the else clause on the same line 3008ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Search(r'\belse [^\s{]', line) and not Search(r'\belse if\b', line): 3009ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/newline', 4, 3010ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Else clause should never be on same line as else (use 2 lines)') 3011ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3012ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # In the same way, a do/while should never be on one line 3013ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Match(r'\s*do [^\s{]', line): 3014ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/newline', 4, 3015ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'do/while clauses should not be on a single line') 3016ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3017b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Block bodies should not be followed by a semicolon. Due to C++11 3018b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # brace initialization, there are more places where semicolons are 3019b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # required than not, so we use a whitelist approach to check these 3020b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # rather than a blacklist. These are the places where "};" should 3021b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # be replaced by just "}": 3022b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 1. Some flavor of block following closing parenthesis: 3023b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # for (;;) {}; 3024b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # while (...) {}; 3025b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # switch (...) {}; 3026b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Function(...) {}; 3027b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # if (...) {}; 3028b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # if (...) else if (...) {}; 3029b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 3030b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 2. else block: 3031b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # if (...) else {}; 3032b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 3033b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 3. const member function: 3034b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Function(...) const {}; 3035b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 3036b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 4. Block following some statement: 3037b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # x = 42; 3038b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # {}; 3039b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 3040b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 5. Block at the beginning of a function: 3041b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Function(...) { 3042b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # {}; 3043b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # } 3044b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 3045b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Note that naively checking for the preceding "{" will also match 3046b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # braces inside multi-dimensional arrays, but this is fine since 3047b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # that expression will not contain semicolons. 3048b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 3049b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 6. Block following another block: 3050b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # while (true) {} 3051b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # {}; 3052b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 3053b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 7. End of namespaces: 3054b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # namespace {}; 3055b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 3056b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # These semicolons seems far more common than other kinds of 3057b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # redundant semicolons, possibly due to people converting classes 3058b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # to namespaces. For now we do not warn for this case. 3059b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 3060b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Try matching case 1 first. 3061b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian match = Match(r'^(.*\)\s*)\{', line) 3062b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if match: 3063b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Matched closing parenthesis (case 1). Check the token before the 3064b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # matching opening parenthesis, and don't warn if it looks like a 3065b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # macro. This avoids these false positives: 3066b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # - macro that defines a base class 3067b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # - multi-line macro that defines a base class 3068b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # - macro that defines the whole class-head 3069b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 3070b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # But we still issue warnings for macros that we know are safe to 3071b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # warn, specifically: 3072b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # - TEST, TEST_F, TEST_P, MATCHER, MATCHER_P 3073b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # - TYPED_TEST 3074b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # - INTERFACE_DEF 3075b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # - EXCLUSIVE_LOCKS_REQUIRED, SHARED_LOCKS_REQUIRED, LOCKS_EXCLUDED: 3076b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 3077b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # We implement a whitelist of safe macros instead of a blacklist of 3078b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # unsafe macros, even though the latter appears less frequently in 3079b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # google code and would have been easier to implement. This is because 3080b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # the downside for getting the whitelist wrong means some extra 3081b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # semicolons, while the downside for getting the blacklist wrong 3082b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # would result in compile errors. 3083b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 3084b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # In addition to macros, we also don't want to warn on compound 3085b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # literals. 3086b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian closing_brace_pos = match.group(1).rfind(')') 3087b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian opening_parenthesis = ReverseCloseExpression( 3088b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian clean_lines, linenum, closing_brace_pos) 3089b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if opening_parenthesis[2] > -1: 3090b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian line_prefix = opening_parenthesis[0][0:opening_parenthesis[2]] 3091b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian macro = Search(r'\b([A-Z_]+)\s*$', line_prefix) 3092b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if ((macro and 3093b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian macro.group(1) not in ( 3094b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'TEST', 'TEST_F', 'MATCHER', 'MATCHER_P', 'TYPED_TEST', 3095b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'EXCLUSIVE_LOCKS_REQUIRED', 'SHARED_LOCKS_REQUIRED', 3096b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'LOCKS_EXCLUDED', 'INTERFACE_DEF')) or 3097b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian Search(r'\s+=\s*$', line_prefix)): 3098b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian match = None 3099b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 3100b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian else: 3101b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Try matching cases 2-3. 3102b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian match = Match(r'^(.*(?:else|\)\s*const)\s*)\{', line) 3103b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if not match: 3104b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Try matching cases 4-6. These are always matched on separate lines. 3105b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 3106b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Note that we can't simply concatenate the previous line to the 3107b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # current line and do a single match, otherwise we may output 3108b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # duplicate warnings for the blank line case: 3109b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # if (cond) { 3110b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # // blank line 3111b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # } 3112b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0] 3113b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if prevline and Search(r'[;{}]\s*$', prevline): 3114b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian match = Match(r'^(\s*)\{', line) 3115b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 3116b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Check matching closing brace 3117b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if match: 3118b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian (endline, endlinenum, endpos) = CloseExpression( 3119b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian clean_lines, linenum, len(match.group(1))) 3120b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if endpos > -1 and Match(r'^\s*;', endline[endpos:]): 3121b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Current {} pair is eligible for semicolon check, and we have found 3122b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # the redundant semicolon, output warning here. 3123b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 3124b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Note: because we are scanning forward for opening braces, and 3125b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # outputting warnings for the matching closing brace, if there are 3126b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # nested blocks with trailing semicolons, we will get the error 3127b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # messages in reversed order. 3128b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian error(filename, endlinenum, 'readability/braces', 4, 3129b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian "You don't need a ; after a }") 3130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3131ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3132b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramaniandef CheckEmptyBlockBody(filename, clean_lines, linenum, error): 3133b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian """Look for empty loop/conditional body with only a single semicolon. 3134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 3136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the current file. 3137ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_lines: A CleansedLines instance containing the file. 3138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: The number of the line to check. 3139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: The function to call with any errors found. 3140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 3141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3142ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Search for loop keywords at the beginning of the line. Because only 3143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # whitespaces are allowed before the keywords, this will also ignore most 3144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # do-while-loops, since those lines should start with closing brace. 3145b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 3146b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # We also check "if" blocks here, since an empty conditional block 3147b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # is likely an error. 3148ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = clean_lines.elided[linenum] 3149b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian matched = Match(r'\s*(for|while|if)\s*\(', line) 3150b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if matched: 3151ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Find the end of the conditional expression 3152ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (end_line, end_linenum, end_pos) = CloseExpression( 3153ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_lines, linenum, line.find('(')) 3154ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3155ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Output warning if what follows the condition expression is a semicolon. 3156ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # No warning for all other cases, including whitespace or newline, since we 3157ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # have a separate check for semicolons preceded by whitespace. 3158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if end_pos >= 0 and Match(r';', end_line[end_pos:]): 3159b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if matched.group(1) == 'if': 3160b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian error(filename, end_linenum, 'whitespace/empty_conditional_body', 5, 3161b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'Empty conditional bodies should use {}') 3162b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian else: 3163b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian error(filename, end_linenum, 'whitespace/empty_loop_body', 5, 3164b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'Empty loop bodies should use {} or continue') 3165ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3166ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3167ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef CheckCheck(filename, clean_lines, linenum, error): 3168ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Checks the use of CHECK and EXPECT macros. 3169ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3170ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 3171ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the current file. 3172ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_lines: A CleansedLines instance containing the file. 3173ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: The number of the line to check. 3174ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: The function to call with any errors found. 3175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 3176ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3177ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Decide the set of replacement macros that should be suggested 3178b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian lines = clean_lines.elided 3179b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian check_macro = None 3180b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian start_pos = -1 3181ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for macro in _CHECK_MACROS: 3182b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian i = lines[linenum].find(macro) 3183b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if i >= 0: 3184b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian check_macro = macro 3185b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 3186b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Find opening parenthesis. Do a regular expression match here 3187b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # to make sure that we are matching the expected CHECK macro, as 3188b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # opposed to some other macro that happens to contain the CHECK 3189b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # substring. 3190b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian matched = Match(r'^(.*\b' + check_macro + r'\s*)\(', lines[linenum]) 3191b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if not matched: 3192b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian continue 3193b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian start_pos = len(matched.group(1)) 3194ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break 3195b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if not check_macro or start_pos < 0: 3196ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Don't waste time here if line doesn't contain 'CHECK' or 'EXPECT' 3197ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 3198ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3199b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Find end of the boolean expression by matching parentheses 3200b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian (last_line, end_line, end_pos) = CloseExpression( 3201b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian clean_lines, linenum, start_pos) 3202b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if end_pos < 0: 3203b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return 3204b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if linenum == end_line: 3205b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian expression = lines[linenum][start_pos + 1:end_pos - 1] 3206b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian else: 3207b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian expression = lines[linenum][start_pos + 1:] 3208b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian for i in xrange(linenum + 1, end_line): 3209b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian expression += lines[i] 3210b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian expression += last_line[0:end_pos - 1] 3211b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 3212b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Parse expression so that we can take parentheses into account. 3213b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # This avoids false positives for inputs like "CHECK((a < 4) == b)", 3214b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # which is not replaceable by CHECK_LE. 3215b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian lhs = '' 3216b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian rhs = '' 3217b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian operator = None 3218b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian while expression: 3219b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian matched = Match(r'^\s*(<<|<<=|>>|>>=|->\*|->|&&|\|\||' 3220b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r'==|!=|>=|>|<=|<|\()(.*)$', expression) 3221b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if matched: 3222b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian token = matched.group(1) 3223b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if token == '(': 3224b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Parenthesized operand 3225b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian expression = matched.group(2) 3226b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian (end, _) = FindEndOfExpressionInLine(expression, 0, 1, '(', ')') 3227b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if end < 0: 3228b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return # Unmatched parenthesis 3229b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian lhs += '(' + expression[0:end] 3230b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian expression = expression[end:] 3231b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian elif token in ('&&', '||'): 3232b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Logical and/or operators. This means the expression 3233b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # contains more than one term, for example: 3234b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # CHECK(42 < a && a < b); 3235b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 3236b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # These are not replaceable with CHECK_LE, so bail out early. 3237b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return 3238b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian elif token in ('<<', '<<=', '>>', '>>=', '->*', '->'): 3239b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Non-relational operator 3240b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian lhs += token 3241b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian expression = matched.group(2) 3242b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian else: 3243b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Relational operator 3244b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian operator = token 3245b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian rhs = matched.group(2) 3246b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break 3247b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian else: 3248b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Unparenthesized operand. Instead of appending to lhs one character 3249b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # at a time, we do another regular expression match to consume several 3250b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # characters at once if possible. Trivial benchmark shows that this 3251b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # is more efficient when the operands are longer than a single 3252b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # character, which is generally the case. 3253b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian matched = Match(r'^([^-=!<>()&|]+)(.*)$', expression) 3254b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if not matched: 3255b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian matched = Match(r'^(\s*\S)(.*)$', expression) 3256b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if not matched: 3257b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break 3258b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian lhs += matched.group(1) 3259b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian expression = matched.group(2) 3260ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3261b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Only apply checks if we got all parts of the boolean expression 3262b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if not (lhs and operator and rhs): 3263b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return 3264b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 3265b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Check that rhs do not contain logical operators. We already know 3266b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # that lhs is fine since the loop above parses out && and ||. 3267b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if rhs.find('&&') > -1 or rhs.find('||') > -1: 3268b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return 3269b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 3270b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # At least one of the operands must be a constant literal. This is 3271b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # to avoid suggesting replacements for unprintable things like 3272b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # CHECK(variable != iterator) 3273b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 3274b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # The following pattern matches decimal, hex integers, strings, and 3275b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # characters (in that order). 3276b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian lhs = lhs.strip() 3277b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian rhs = rhs.strip() 3278b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian match_constant = r'^([-+]?(\d+|0[xX][0-9a-fA-F]+)[lLuU]{0,3}|".*"|\'.*\')$' 3279b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if Match(match_constant, lhs) or Match(match_constant, rhs): 3280b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Note: since we know both lhs and rhs, we can provide a more 3281b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # descriptive error message like: 3282b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Consider using CHECK_EQ(x, 42) instead of CHECK(x == 42) 3283b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Instead of: 3284b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Consider using CHECK_EQ instead of CHECK(a == b) 3285b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 3286b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # We are still keeping the less descriptive message because if lhs 3287b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # or rhs gets long, the error message might become unreadable. 3288b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian error(filename, linenum, 'readability/check', 2, 3289b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'Consider using %s instead of %s(a %s b)' % ( 3290b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian _CHECK_REPLACEMENT[check_macro][operator], 3291b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian check_macro, operator)) 3292ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3293ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3294ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef CheckAltTokens(filename, clean_lines, linenum, error): 3295ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Check alternative keywords being used in boolean expressions. 3296ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3297ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 3298ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the current file. 3299ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_lines: A CleansedLines instance containing the file. 3300ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: The number of the line to check. 3301ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: The function to call with any errors found. 3302ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 3303ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = clean_lines.elided[linenum] 3304ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3305ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Avoid preprocessor lines 3306ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Match(r'^\s*#', line): 3307ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 3308ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3309ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Last ditch effort to avoid multi-line comments. This will not help 3310ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # if the comment started before the current line or ended after the 3311ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # current line, but it catches most of the false positives. At least, 3312ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # it provides a way to workaround this warning for people who use 3313ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # multi-line comments in preprocessor macros. 3314ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 3315ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # TODO(unknown): remove this once cpplint has better support for 3316ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # multi-line comments. 3317ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if line.find('/*') >= 0 or line.find('*/') >= 0: 3318ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 3319ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3320ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for match in _ALT_TOKEN_REPLACEMENT_PATTERN.finditer(line): 3321ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'readability/alt_tokens', 2, 3322ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Use operator %s instead of %s' % ( 3323ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _ALT_TOKEN_REPLACEMENT[match.group(1)], match.group(1))) 3324ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3325ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3326ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef GetLineWidth(line): 3327ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Determines the width of the line in column positions. 3328ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3329ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 3330ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line: A string, which may be a Unicode string. 3331ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3332ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Returns: 3333ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang The width of the line in column positions, accounting for Unicode 3334ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang combining characters and wide characters. 3335ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 3336ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if isinstance(line, unicode): 3337ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang width = 0 3338ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for uc in unicodedata.normalize('NFC', line): 3339ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if unicodedata.east_asian_width(uc) in ('W', 'F'): 3340ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang width += 2 3341ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif not unicodedata.combining(uc): 3342ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang width += 1 3343ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return width 3344ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 3345ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return len(line) 3346ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3347ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3348ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef CheckStyle(filename, clean_lines, linenum, file_extension, nesting_state, 3349ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error): 3350ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Checks rules from the 'C++ style rules' section of cppguide.html. 3351ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3352ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Most of these rules are hard to test (naming, comment style), but we 3353ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang do what we can. In particular we check for 2-space indents, line lengths, 3354ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang tab usage, spaces inside code, etc. 3355ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3356ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 3357ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the current file. 3358ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_lines: A CleansedLines instance containing the file. 3359ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: The number of the line to check. 3360ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang file_extension: The extension (without the dot) of the filename. 3361ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nesting_state: A _NestingState instance which maintains information about 3362ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang the current stack of nested blocks being parsed. 3363ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: The function to call with any errors found. 3364ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 3365ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3366b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Don't use "elided" lines here, otherwise we can't check commented lines. 3367b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Don't want to use "raw" either, because we don't want to check inside C++11 3368b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # raw strings, 3369b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian raw_lines = clean_lines.lines_without_raw_strings 3370ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = raw_lines[linenum] 3371ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3372ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if line.find('\t') != -1: 3373ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/tab', 1, 3374ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Tab found; better to use spaces') 3375ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3376ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # One or three blank spaces at the beginning of the line is weird; it's 3377ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # hard to reconcile that with 2-space indents. 3378ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # NOTE: here are the conditions rob pike used for his tests. Mine aren't 3379ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # as sophisticated, but it may be worth becoming so: RLENGTH==initial_spaces 3380ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # if(RLENGTH > 20) complain = 0; 3381ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # if(match($0, " +(error|private|public|protected):")) complain = 0; 3382ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # if(match(prev, "&& *$")) complain = 0; 3383ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # if(match(prev, "\\|\\| *$")) complain = 0; 3384ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # if(match(prev, "[\",=><] *$")) complain = 0; 3385ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # if(match($0, " <<")) complain = 0; 3386ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # if(match(prev, " +for \\(")) complain = 0; 3387ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # if(prevodd && match(prevprev, " +for \\(")) complain = 0; 3388ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang initial_spaces = 0 3389ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang cleansed_line = clean_lines.elided[linenum] 3390ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang while initial_spaces < len(line) and line[initial_spaces] == ' ': 3391ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang initial_spaces += 1 3392ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if line and line[-1].isspace(): 3393ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/end_of_line', 4, 3394ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Line ends in whitespace. Consider deleting these extra spaces.') 3395b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # There are certain situations we allow one space, notably for section labels 3396ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif ((initial_spaces == 1 or initial_spaces == 3) and 3397ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang not Match(r'\s*\w+\s*:\s*$', cleansed_line)): 3398ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/indent', 3, 3399ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Weird number of spaces at line-start. ' 3400ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Are you using a 2-space indent?') 3401ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3402ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Check if the line is a header guard. 3403ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang is_header_guard = False 3404ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if file_extension == 'h': 3405ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang cppvar = GetHeaderGuardCPPVariable(filename) 3406ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (line.startswith('#ifndef %s' % cppvar) or 3407ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line.startswith('#define %s' % cppvar) or 3408ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line.startswith('#endif // %s' % cppvar)): 3409ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang is_header_guard = True 3410ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # #include lines and header guards can be long, since there's no clean way to 3411ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # split them. 3412ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 3413ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # URLs can be long too. It's possible to split these, but it makes them 3414ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # harder to cut&paste. 3415ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 3416ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # The "$Id:...$" comment may also get very long without it being the 3417ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # developers fault. 3418ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (not line.startswith('#include') and not is_header_guard and 3419ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang not Match(r'^\s*//.*http(s?)://\S*$', line) and 3420ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang not Match(r'^// \$Id:.*#[0-9]+ \$$', line)): 3421ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line_width = GetLineWidth(line) 3422b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian extended_length = int((_line_length * 1.25)) 3423b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if line_width > extended_length: 3424ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/line_length', 4, 3425b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'Lines should very rarely be longer than %i characters' % 3426b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian extended_length) 3427b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian elif line_width > _line_length: 3428ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/line_length', 2, 3429b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'Lines should be <= %i characters long' % _line_length) 3430ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3431ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (cleansed_line.count(';') > 1 and 3432ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # for loops are allowed two ;'s (and may run over two lines). 3433ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang cleansed_line.find('for') == -1 and 3434ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (GetPreviousNonBlankLine(clean_lines, linenum)[0].find('for') == -1 or 3435ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang GetPreviousNonBlankLine(clean_lines, linenum)[0].find(';') != -1) and 3436ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # It's ok to have many commands in a switch case that fits in 1 line 3437ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang not ((cleansed_line.find('case ') != -1 or 3438ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang cleansed_line.find('default:') != -1) and 3439ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang cleansed_line.find('break;') != -1)): 3440ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'whitespace/newline', 0, 3441ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'More than one command on the same line') 3442ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3443ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Some more style checks 3444ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang CheckBraces(filename, clean_lines, linenum, error) 3445b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian CheckEmptyBlockBody(filename, clean_lines, linenum, error) 3446ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang CheckAccess(filename, clean_lines, linenum, nesting_state, error) 3447ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang CheckSpacing(filename, clean_lines, linenum, nesting_state, error) 3448ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang CheckCheck(filename, clean_lines, linenum, error) 3449ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang CheckAltTokens(filename, clean_lines, linenum, error) 3450ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang classinfo = nesting_state.InnermostClass() 3451ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if classinfo: 3452ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang CheckSectionSpacing(filename, clean_lines, classinfo, linenum, error) 3453ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3454ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3455ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_RE_PATTERN_INCLUDE_NEW_STYLE = re.compile(r'#include +"[^/]+\.h"') 3456ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_RE_PATTERN_INCLUDE = re.compile(r'^\s*#\s*include\s*([<"])([^>"]*)[>"].*$') 3457ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# Matches the first component of a filename delimited by -s and _s. That is: 3458ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# _RE_FIRST_COMPONENT.match('foo').group(0) == 'foo' 3459ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# _RE_FIRST_COMPONENT.match('foo.cc').group(0) == 'foo' 3460ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# _RE_FIRST_COMPONENT.match('foo-bar_baz.cc').group(0) == 'foo' 3461ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang# _RE_FIRST_COMPONENT.match('foo_bar-baz.cc').group(0) == 'foo' 3462ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_RE_FIRST_COMPONENT = re.compile(r'^[^-_.]+') 3463ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3464ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3465ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef _DropCommonSuffixes(filename): 3466ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Drops common suffixes like _test.cc or -inl.h from filename. 3467ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3468ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang For example: 3469ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang >>> _DropCommonSuffixes('foo/foo-inl.h') 3470ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'foo/foo' 3471ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang >>> _DropCommonSuffixes('foo/bar/foo.cc') 3472ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'foo/bar/foo' 3473ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang >>> _DropCommonSuffixes('foo/foo_internal.h') 3474ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'foo/foo' 3475ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang >>> _DropCommonSuffixes('foo/foo_unusualinternal.h') 3476ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'foo/foo_unusualinternal' 3477ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3478ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 3479ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The input filename. 3480ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3481ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Returns: 3482ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang The filename with the common suffix removed. 3483ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 3484ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for suffix in ('test.cc', 'regtest.cc', 'unittest.cc', 3485ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'inl.h', 'impl.h', 'internal.h'): 3486ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (filename.endswith(suffix) and len(filename) > len(suffix) and 3487ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename[-len(suffix) - 1] in ('-', '_')): 3488ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return filename[:-len(suffix) - 1] 3489ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return os.path.splitext(filename)[0] 3490ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3491ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3492ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef _IsTestFilename(filename): 3493ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Determines if the given filename has a suffix that identifies it as a test. 3494ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3495ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 3496ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The input filename. 3497ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3498ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Returns: 3499ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang True if 'filename' looks like a test, False otherwise. 3500ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 3501ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (filename.endswith('_test.cc') or 3502ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename.endswith('_unittest.cc') or 3503ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename.endswith('_regtest.cc')): 3504ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return True 3505ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 3506ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return False 3507ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3508ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3509ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef _ClassifyInclude(fileinfo, include, is_system): 3510ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Figures out what kind of header 'include' is. 3511ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3512ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 3513ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang fileinfo: The current file cpplint is running over. A FileInfo instance. 3514ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang include: The path to a #included file. 3515ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang is_system: True if the #include used <> rather than "". 3516ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3517ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Returns: 3518ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang One of the _XXX_HEADER constants. 3519ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3520ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang For example: 3521ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'stdio.h', True) 3522ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _C_SYS_HEADER 3523ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'string', True) 3524ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _CPP_SYS_HEADER 3525ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/foo.h', False) 3526ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _LIKELY_MY_HEADER 3527ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang >>> _ClassifyInclude(FileInfo('foo/foo_unknown_extension.cc'), 3528ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ... 'bar/foo_other_ext.h', False) 3529ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _POSSIBLE_MY_HEADER 3530ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/bar.h', False) 3531ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _OTHER_HEADER 3532ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 3533ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # This is a list of all standard c++ header files, except 3534ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # those already checked for above. 3535b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian is_cpp_h = include in _CPP_HEADERS 3536ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3537ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if is_system: 3538ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if is_cpp_h: 3539ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return _CPP_SYS_HEADER 3540ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 3541ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return _C_SYS_HEADER 3542ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3543ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # If the target file and the include we're checking share a 3544ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # basename when we drop common extensions, and the include 3545ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # lives in . , then it's likely to be owned by the target file. 3546ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang target_dir, target_base = ( 3547ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang os.path.split(_DropCommonSuffixes(fileinfo.RepositoryName()))) 3548ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang include_dir, include_base = os.path.split(_DropCommonSuffixes(include)) 3549ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if target_base == include_base and ( 3550ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang include_dir == target_dir or 3551ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang include_dir == os.path.normpath(target_dir + '/../public')): 3552ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return _LIKELY_MY_HEADER 3553ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3554ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # If the target and include share some initial basename 3555ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # component, it's possible the target is implementing the 3556ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # include, so it's allowed to be first, but we'll never 3557ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # complain if it's not there. 3558ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang target_first_component = _RE_FIRST_COMPONENT.match(target_base) 3559ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang include_first_component = _RE_FIRST_COMPONENT.match(include_base) 3560ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (target_first_component and include_first_component and 3561ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang target_first_component.group(0) == 3562ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang include_first_component.group(0)): 3563ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return _POSSIBLE_MY_HEADER 3564ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3565ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return _OTHER_HEADER 3566ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3567ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3568ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3569ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef CheckIncludeLine(filename, clean_lines, linenum, include_state, error): 3570ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Check rules that are applicable to #include lines. 3571ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3572ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Strings on #include lines are NOT removed from elided line, to make 3573ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang certain tasks easier. However, to prevent false positives, checks 3574ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang applicable to #include lines in CheckLanguage must be put here. 3575ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3576ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 3577ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the current file. 3578ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_lines: A CleansedLines instance containing the file. 3579ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: The number of the line to check. 3580ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang include_state: An _IncludeState instance in which the headers are inserted. 3581ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: The function to call with any errors found. 3582ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 3583ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang fileinfo = FileInfo(filename) 3584ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3585ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = clean_lines.lines[linenum] 3586ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3587ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # "include" should use the new style "foo/bar.h" instead of just "bar.h" 3588ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if _RE_PATTERN_INCLUDE_NEW_STYLE.search(line): 3589ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'build/include', 4, 3590ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Include the directory when naming .h files') 3591ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3592ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # we shouldn't include a file more than once. actually, there are a 3593ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # handful of instances where doing so is okay, but in general it's 3594ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # not. 3595ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match = _RE_PATTERN_INCLUDE.search(line) 3596ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if match: 3597ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang include = match.group(2) 3598ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang is_system = (match.group(1) == '<') 3599ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if include in include_state: 3600ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'build/include', 4, 3601ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang '"%s" already included at %s:%s' % 3602ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (include, filename, include_state[include])) 3603ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 3604ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang include_state[include] = linenum 3605ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3606ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # We want to ensure that headers appear in the right order: 3607ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 1) for foo.cc, foo.h (preferred location) 3608ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 2) c system files 3609ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 3) cpp system files 3610ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 4) for foo.cc, foo.h (deprecated location) 3611ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 5) other google headers 3612ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 3613ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # We classify each include statement as one of those 5 types 3614ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # using a number of techniques. The include_state object keeps 3615ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # track of the highest type seen, and complains if we see a 3616ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # lower type after that. 3617ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error_message = include_state.CheckNextIncludeOrder( 3618ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _ClassifyInclude(fileinfo, include, is_system)) 3619ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if error_message: 3620ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'build/include_order', 4, 3621ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang '%s. Should be: %s.h, c system, c++ system, other.' % 3622ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (error_message, fileinfo.BaseName())) 3623b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian canonical_include = include_state.CanonicalizeAlphabeticalOrder(include) 3624b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if not include_state.IsInAlphabeticalOrder( 3625b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian clean_lines, linenum, canonical_include): 3626ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'build/include_alpha', 4, 3627ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Include "%s" not in alphabetical order' % include) 3628b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian include_state.SetLastHeader(canonical_include) 3629ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3630ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Look for any of the stream classes that are part of standard C++. 3631ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match = _RE_PATTERN_INCLUDE.match(line) 3632ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if match: 3633ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang include = match.group(2) 3634ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Match(r'(f|ind|io|i|o|parse|pf|stdio|str|)?stream$', include): 3635ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Many unit tests use cout, so we exempt them. 3636ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not _IsTestFilename(filename): 3637ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'readability/streams', 3, 3638ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Streams are highly discouraged.') 3639ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3640ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3641ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef _GetTextInside(text, start_pattern): 3642b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r"""Retrieves all the text between matching open and close parentheses. 3643ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3644ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Given a string of lines and a regular expression string, retrieve all the text 3645ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang following the expression and between opening punctuation symbols like 3646ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (, [, or {, and the matching close-punctuation symbol. This properly nested 3647ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang occurrences of the punctuations, so for the text like 3648ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang printf(a(), b(c())); 3649ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang a call to _GetTextInside(text, r'printf\(') will return 'a(), b(c())'. 3650ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang start_pattern must match string having an open punctuation symbol at the end. 3651ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3652ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 3653ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang text: The lines to extract text. Its comments and strings must be elided. 3654ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang It can be single line and can span multiple lines. 3655ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang start_pattern: The regexp string indicating where to start extracting 3656ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang the text. 3657ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Returns: 3658ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang The extracted text. 3659ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang None if either the opening string or ending punctuation could not be found. 3660ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 3661ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # TODO(sugawarayu): Audit cpplint.py to see what places could be profitably 3662ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # rewritten to use _GetTextInside (and use inferior regexp matching today). 3663ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3664ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Give opening punctuations to get the matching close-punctuations. 3665ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang matching_punctuation = {'(': ')', '{': '}', '[': ']'} 3666ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang closing_punctuation = set(matching_punctuation.itervalues()) 3667ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3668ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Find the position to start extracting text. 3669ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match = re.search(start_pattern, text, re.M) 3670ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not match: # start_pattern not found in text. 3671ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return None 3672ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang start_position = match.end(0) 3673ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3674ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang assert start_position > 0, ( 3675ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'start_pattern must ends with an opening punctuation.') 3676ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang assert text[start_position - 1] in matching_punctuation, ( 3677ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'start_pattern must ends with an opening punctuation.') 3678ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Stack of closing punctuations we expect to have in text after position. 3679ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang punctuation_stack = [matching_punctuation[text[start_position - 1]]] 3680ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang position = start_position 3681ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang while punctuation_stack and position < len(text): 3682ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if text[position] == punctuation_stack[-1]: 3683ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang punctuation_stack.pop() 3684ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif text[position] in closing_punctuation: 3685ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # A closing punctuation without matching opening punctuations. 3686ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return None 3687ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif text[position] in matching_punctuation: 3688ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang punctuation_stack.append(matching_punctuation[text[position]]) 3689ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang position += 1 3690ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if punctuation_stack: 3691ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Opening punctuations left without matching close-punctuations. 3692ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return None 3693ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # punctuations match. 3694ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return text[start_position:position - 1] 3695ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3696ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3697b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian# Patterns for matching call-by-reference parameters. 3698b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian# 3699b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian# Supports nested templates up to 2 levels deep using this messy pattern: 3700b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian# < (?: < (?: < [^<>]* 3701b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian# > 3702b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian# | [^<>] )* 3703b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian# > 3704b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian# | [^<>] )* 3705b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian# > 3706b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian_RE_PATTERN_IDENT = r'[_a-zA-Z]\w*' # =~ [[:alpha:]][[:alnum:]]* 3707b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian_RE_PATTERN_TYPE = ( 3708b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r'(?:const\s+)?(?:typename\s+|class\s+|struct\s+|union\s+|enum\s+)?' 3709b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r'(?:\w|' 3710b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r'\s*<(?:<(?:<[^<>]*>|[^<>])*>|[^<>])*>|' 3711b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r'::)+') 3712b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian# A call-by-reference parameter ends with '& identifier'. 3713b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian_RE_PATTERN_REF_PARAM = re.compile( 3714b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r'(' + _RE_PATTERN_TYPE + r'(?:\s*(?:\bconst\b|[*]))*\s*' 3715b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r'&\s*' + _RE_PATTERN_IDENT + r')\s*(?:=[^,()]+)?[,)]') 3716b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian# A call-by-const-reference parameter either ends with 'const& identifier' 3717b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian# or looks like 'const type& identifier' when 'type' is atomic. 3718b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian_RE_PATTERN_CONST_REF_PARAM = ( 3719b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r'(?:.*\s*\bconst\s*&\s*' + _RE_PATTERN_IDENT + 3720b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r'|const\s+' + _RE_PATTERN_TYPE + r'\s*&\s*' + _RE_PATTERN_IDENT + r')') 3721b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 3722b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 3723b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramaniandef CheckLanguage(filename, clean_lines, linenum, file_extension, 3724b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian include_state, nesting_state, error): 3725ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Checks rules from the 'C++ language rules' section of cppguide.html. 3726ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3727ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Some of these rules are hard to test (function overloading, using 3728ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang uint32 inappropriately), but we do the best we can. 3729ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3730ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 3731ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the current file. 3732ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_lines: A CleansedLines instance containing the file. 3733ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: The number of the line to check. 3734ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang file_extension: The extension (without the dot) of the filename. 3735ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang include_state: An _IncludeState instance in which the headers are inserted. 3736b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian nesting_state: A _NestingState instance which maintains information about 3737b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian the current stack of nested blocks being parsed. 3738ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: The function to call with any errors found. 3739ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 3740ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # If the line is empty or consists of entirely a comment, no need to 3741ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # check it. 3742ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = clean_lines.elided[linenum] 3743ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not line: 3744ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 3745ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3746ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match = _RE_PATTERN_INCLUDE.search(line) 3747ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if match: 3748ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang CheckIncludeLine(filename, clean_lines, linenum, include_state, error) 3749ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 3750ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3751b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Reset include state across preprocessor directives. This is meant 3752b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # to silence warnings for conditional includes. 3753b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if Match(r'^\s*#\s*(?:ifdef|elif|else|endif)\b', line): 3754b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian include_state.ResetSection() 3755ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3756ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Make Windows paths like Unix. 3757ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang fullname = os.path.abspath(filename).replace('\\', '/') 3758ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3759ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # TODO(unknown): figure out if they're using default arguments in fn proto. 3760ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3761ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Check to see if they're using an conversion function cast. 3762ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # I just try to capture the most common basic types, though there are more. 3763ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Parameterless conversion functions, such as bool(), are allowed as they are 3764ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # probably a member operator declaration or default constructor. 3765ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match = Search( 3766ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang r'(\bnew\s+)?\b' # Grab 'new' operator, if it's there 3767b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r'(int|float|double|bool|char|int32|uint32|int64|uint64)' 3768b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r'(\([^)].*)', line) 3769ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if match: 3770b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian matched_new = match.group(1) 3771b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian matched_type = match.group(2) 3772b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian matched_funcptr = match.group(3) 3773b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 3774ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # gMock methods are defined using some variant of MOCK_METHODx(name, type) 3775ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # where type may be float(), int(string), etc. Without context they are 3776ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # virtually indistinguishable from int(x) casts. Likewise, gMock's 3777ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # MockCallback takes a template parameter of the form return_type(arg_type), 3778ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # which looks much like the cast we're trying to detect. 3779b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 3780b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # std::function<> wrapper has a similar problem. 3781b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 3782b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Return types for function pointers also look like casts if they 3783b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # don't have an extra space. 3784b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (matched_new is None and # If new operator, then this isn't a cast 3785ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang not (Match(r'^\s*MOCK_(CONST_)?METHOD\d+(_T)?\(', line) or 3786b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian Search(r'\bMockCallback<.*>', line) or 3787b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian Search(r'\bstd::function<.*>', line)) and 3788b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian not (matched_funcptr and 3789b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian Match(r'\((?:[^() ]+::\s*\*\s*)?[^() ]+\)\s*\(', 3790b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian matched_funcptr))): 3791ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Try a bit harder to catch gmock lines: the only place where 3792ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # something looks like an old-style cast is where we declare the 3793ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # return type of the mocked method, and the only time when we 3794ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # are missing context is if MOCK_METHOD was split across 3795b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # multiple lines. The missing MOCK_METHOD is usually one or two 3796b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # lines back, so scan back one or two lines. 3797b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 3798b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # It's not possible for gmock macros to appear in the first 2 3799b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # lines, since the class head + section name takes up 2 lines. 3800b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (linenum < 2 or 3801b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian not (Match(r'^\s*MOCK_(?:CONST_)?METHOD\d+(?:_T)?\((?:\S+,)?\s*$', 3802b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian clean_lines.elided[linenum - 1]) or 3803b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian Match(r'^\s*MOCK_(?:CONST_)?METHOD\d+(?:_T)?\(\s*$', 3804b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian clean_lines.elided[linenum - 2]))): 3805ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'readability/casting', 4, 3806ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Using deprecated casting style. ' 3807ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Use static_cast<%s>(...) instead' % 3808b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian matched_type) 3809ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3810ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum], 3811ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'static_cast', 3812ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang r'\((int|float|double|bool|char|u?int(16|32|64))\)', error) 3813ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3814ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # This doesn't catch all cases. Consider (const char * const)"hello". 3815ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 3816ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # (char *) "foo" should always be a const_cast (reinterpret_cast won't 3817ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # compile). 3818ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum], 3819ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'const_cast', r'\((char\s?\*+\s?)\)\s*"', error): 3820ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang pass 3821ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 3822ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Check pointer casts for other than string constants 3823ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum], 3824ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'reinterpret_cast', r'\((\w+\s?\*+\s?)\)', error) 3825ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3826ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # In addition, we look for people taking the address of a cast. This 3827ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # is dangerous -- casts can assign to temporaries, so the pointer doesn't 3828ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # point where you think. 3829b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian match = Search( 3830b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r'(?:&\(([^)]+)\)[\w(])|' 3831b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r'(?:&(static|dynamic|down|reinterpret)_cast\b)', line) 3832b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if match and match.group(1) != '*': 3833ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'runtime/casting', 4, 3834ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('Are you taking an address of a cast? ' 3835ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'This is dangerous: could be a temp var. ' 3836ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Take the address before doing the cast, rather than after')) 3837ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3838b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Create an extended_line, which is the concatenation of the current and 3839b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # next lines, for more effective checking of code that may span more than one 3840b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # line. 3841b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if linenum + 1 < clean_lines.NumLines(): 3842b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian extended_line = line + clean_lines.elided[linenum + 1] 3843b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian else: 3844b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian extended_line = line 3845b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 3846ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Check for people declaring static/global STL strings at the top level. 3847ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # This is dangerous because the C++ language does not guarantee that 3848ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # globals with constructors are initialized before the first access. 3849ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match = Match( 3850ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang r'((?:|static +)(?:|const +))string +([a-zA-Z0-9_:]+)\b(.*)', 3851ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line) 3852ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Make sure it's not a function. 3853ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Function template specialization looks like: "string foo<Type>(...". 3854ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Class template definitions look like: "string Foo<Type>::Method(...". 3855b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 3856b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Also ignore things that look like operators. These are matched separately 3857b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # because operator names cross non-word boundaries. If we change the pattern 3858b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # above, we would decrease the accuracy of matching identifiers. 3859b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (match and 3860b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian not Search(r'\boperator\W', line) and 3861b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian not Match(r'\s*(<.*>)?(::[a-zA-Z0-9_]+)?\s*\(([^"]|$)', match.group(3))): 3862ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'runtime/string', 4, 3863ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'For a static/global string constant, use a C style string instead: ' 3864ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang '"%schar %s[]".' % 3865ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (match.group(1), match.group(2))) 3866ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3867ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Search(r'\b([A-Za-z0-9_]*_)\(\1\)', line): 3868ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'runtime/init', 4, 3869ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'You seem to be initializing a member variable with itself.') 3870ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3871ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if file_extension == 'h': 3872ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # TODO(unknown): check that 1-arg constructors are explicit. 3873ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # How to tell it's a constructor? 3874ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # (handled in CheckForNonStandardConstructs for now) 3875ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # TODO(unknown): check that classes have DISALLOW_EVIL_CONSTRUCTORS 3876ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # (level 1 error) 3877ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang pass 3878ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3879ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Check if people are using the verboten C basic types. The only exception 3880ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # we regularly allow is "unsigned short port" for port. 3881ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Search(r'\bshort port\b', line): 3882ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not Search(r'\bunsigned short port\b', line): 3883ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'runtime/int', 4, 3884ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Use "unsigned short" for ports, not "short"') 3885ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 3886ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match = Search(r'\b(short|long(?! +double)|long long)\b', line) 3887ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if match: 3888ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'runtime/int', 4, 3889ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Use int16/int64/etc, rather than the C type %s' % match.group(1)) 3890ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3891ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # When snprintf is used, the second argument shouldn't be a literal. 3892ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match = Search(r'snprintf\s*\(([^,]*),\s*([0-9]*)\s*,', line) 3893ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if match and match.group(2) != '0': 3894ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # If 2nd arg is zero, snprintf is used to calculate size. 3895ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'runtime/printf', 3, 3896ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'If you can, use sizeof(%s) instead of %s as the 2nd arg ' 3897ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'to snprintf.' % (match.group(1), match.group(2))) 3898ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3899ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Check if some verboten C functions are being used. 3900ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Search(r'\bsprintf\b', line): 3901ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'runtime/printf', 5, 3902ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Never use sprintf. Use snprintf instead.') 3903ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match = Search(r'\b(strcpy|strcat)\b', line) 3904ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if match: 3905ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'runtime/printf', 4, 3906ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Almost always, snprintf is better than %s' % match.group(1)) 3907ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3908ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Check if some verboten operator overloading is going on 3909ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # TODO(unknown): catch out-of-line unary operator&: 3910ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # class X {}; 3911ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # int operator&(const X& x) { return 42; } // unary operator& 3912ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # The trick is it's hard to tell apart from binary operator&: 3913ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # class Y { int operator&(const Y& x) { return 23; } }; // binary operator& 3914ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Search(r'\boperator\s*&\s*\(\s*\)', line): 3915ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'runtime/operator', 4, 3916ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Unary operator& is dangerous. Do not use it.') 3917ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3918ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Check for suspicious usage of "if" like 3919ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # } if (a == b) { 3920ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Search(r'\}\s*if\s*\(', line): 3921ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'readability/braces', 4, 3922ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Did you mean "else if"? If not, start a new line for "if".') 3923ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3924ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Check for potential format string bugs like printf(foo). 3925ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # We constrain the pattern not to pick things like DocidForPrintf(foo). 3926ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Not perfect but it can catch printf(foo.c_str()) and printf(foo->c_str()) 3927ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # TODO(sugawarayu): Catch the following case. Need to change the calling 3928ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # convention of the whole function to process multiple line to handle it. 3929ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # printf( 3930ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # boy_this_is_a_really_long_variable_that_cannot_fit_on_the_prev_line); 3931ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang printf_args = _GetTextInside(line, r'(?i)\b(string)?printf\s*\(') 3932ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if printf_args: 3933ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match = Match(r'([\w.\->()]+)$', printf_args) 3934ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if match and match.group(1) != '__VA_ARGS__': 3935ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang function_name = re.search(r'\b((?:string)?printf)\s*\(', 3936ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line, re.I).group(1) 3937ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'runtime/printf', 4, 3938ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Potential format string bug. Do %s("%%s", %s) instead.' 3939ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang % (function_name, match.group(1))) 3940ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3941ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Check for potential memset bugs like memset(buf, sizeof(buf), 0). 3942ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match = Search(r'memset\s*\(([^,]*),\s*([^,]*),\s*0\s*\)', line) 3943ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if match and not Match(r"^''|-?[0-9]+|0x[0-9A-Fa-f]$", match.group(2)): 3944ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'runtime/memset', 4, 3945ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Did you mean "memset(%s, 0, %s)"?' 3946ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang % (match.group(1), match.group(2))) 3947ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3948ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Search(r'\busing namespace\b', line): 3949ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'build/namespaces', 5, 3950ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Do not use namespace using-directives. ' 3951ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Use using-declarations instead.') 3952ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3953ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Detect variable-length arrays. 3954ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match = Match(r'\s*(.+::)?(\w+) [a-z]\w*\[(.+)];', line) 3955ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (match and match.group(2) != 'return' and match.group(2) != 'delete' and 3956ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match.group(3).find(']') == -1): 3957ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Split the size using space and arithmetic operators as delimiters. 3958ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # If any of the resulting tokens are not compile time constants then 3959ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # report the error. 3960ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang tokens = re.split(r'\s|\+|\-|\*|\/|<<|>>]', match.group(3)) 3961ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang is_const = True 3962ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang skip_next = False 3963ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for tok in tokens: 3964ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if skip_next: 3965ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang skip_next = False 3966ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang continue 3967ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3968ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Search(r'sizeof\(.+\)', tok): continue 3969ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Search(r'arraysize\(\w+\)', tok): continue 3970ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3971ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang tok = tok.lstrip('(') 3972ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang tok = tok.rstrip(')') 3973ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not tok: continue 3974ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Match(r'\d+', tok): continue 3975ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Match(r'0[xX][0-9a-fA-F]+', tok): continue 3976ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Match(r'k[A-Z0-9]\w*', tok): continue 3977ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Match(r'(.+::)?k[A-Z0-9]\w*', tok): continue 3978ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if Match(r'(.+::)?[A-Z][A-Z0-9_]*', tok): continue 3979ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # A catch all for tricky sizeof cases, including 'sizeof expression', 3980ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # 'sizeof(*type)', 'sizeof(const type)', 'sizeof(struct StructName)' 3981ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # requires skipping the next token because we split on ' ' and '*'. 3982ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if tok.startswith('sizeof'): 3983ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang skip_next = True 3984ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang continue 3985ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang is_const = False 3986ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break 3987ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not is_const: 3988ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'runtime/arrays', 1, 3989ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Do not use variable-length arrays. Use an appropriately named ' 3990ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang "('k' followed by CamelCase) compile-time constant for the size.") 3991ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3992ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # If DISALLOW_EVIL_CONSTRUCTORS, DISALLOW_COPY_AND_ASSIGN, or 3993ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # DISALLOW_IMPLICIT_CONSTRUCTORS is present, then it should be the last thing 3994ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # in the class declaration. 3995ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match = Match( 3996ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (r'\s*' 3997ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang r'(DISALLOW_(EVIL_CONSTRUCTORS|COPY_AND_ASSIGN|IMPLICIT_CONSTRUCTORS))' 3998ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang r'\(.*\);$'), 3999ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line) 4000ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if match and linenum + 1 < clean_lines.NumLines(): 4001ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang next_line = clean_lines.elided[linenum + 1] 4002ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # We allow some, but not all, declarations of variables to be present 4003ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # in the statement that defines the class. The [\w\*,\s]* fragment of 4004ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # the regular expression below allows users to declare instances of 4005ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # the class or pointers to instances, but not less common types such 4006ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # as function pointers or arrays. It's a tradeoff between allowing 4007ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # reasonable code and avoiding trying to parse more C++ using regexps. 4008ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not Search(r'^\s*}[\w\*,\s]*;', next_line): 4009ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'readability/constructors', 3, 4010ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match.group(1) + ' should be the last thing in the class') 4011ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4012ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Check for use of unnamed namespaces in header files. Registration 4013ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # macros are typically OK, so we allow use of "namespace {" on lines 4014ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # that end with backslashes. 4015ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (file_extension == 'h' 4016ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang and Search(r'\bnamespace\s*{', line) 4017ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang and line[-1] != '\\'): 4018ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'build/namespaces', 4, 4019ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Do not use unnamed namespaces in header files. See ' 4020ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces' 4021ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ' for more information.') 4022ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4023b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramaniandef CheckForNonConstReference(filename, clean_lines, linenum, 4024b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian nesting_state, error): 4025b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian """Check for non-const references. 4026b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 4027b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian Separate from CheckLanguage since it scans backwards from current 4028b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian line, instead of scanning forward. 4029b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 4030b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian Args: 4031b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian filename: The name of the current file. 4032b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian clean_lines: A CleansedLines instance containing the file. 4033b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian linenum: The number of the line to check. 4034b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian nesting_state: A _NestingState instance which maintains information about 4035b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian the current stack of nested blocks being parsed. 4036b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian error: The function to call with any errors found. 4037b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian """ 4038b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Do nothing if there is no '&' on current line. 4039b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian line = clean_lines.elided[linenum] 4040b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if '&' not in line: 4041b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return 4042b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 4043b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Long type names may be broken across multiple lines, usually in one 4044b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # of these forms: 4045b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # LongType 4046b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # ::LongTypeContinued &identifier 4047b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # LongType:: 4048b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # LongTypeContinued &identifier 4049b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # LongType< 4050b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # ...>::LongTypeContinued &identifier 4051b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 4052b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # If we detected a type split across two lines, join the previous 4053b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # line to current line so that we can match const references 4054b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # accordingly. 4055b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 4056b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Note that this only scans back one line, since scanning back 4057b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # arbitrary number of lines would be expensive. If you have a type 4058b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # that spans more than 2 lines, please use a typedef. 4059b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if linenum > 1: 4060b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian previous = None 4061b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if Match(r'\s*::(?:[\w<>]|::)+\s*&\s*\S', line): 4062b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # previous_line\n + ::current_line 4063b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian previous = Search(r'\b((?:const\s*)?(?:[\w<>]|::)+[\w<>])\s*$', 4064b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian clean_lines.elided[linenum - 1]) 4065b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian elif Match(r'\s*[a-zA-Z_]([\w<>]|::)+\s*&\s*\S', line): 4066b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # previous_line::\n + current_line 4067b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian previous = Search(r'\b((?:const\s*)?(?:[\w<>]|::)+::)\s*$', 4068b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian clean_lines.elided[linenum - 1]) 4069b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if previous: 4070b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian line = previous.group(1) + line.lstrip() 4071b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian else: 4072b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Check for templated parameter that is split across multiple lines 4073b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian endpos = line.rfind('>') 4074b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if endpos > -1: 4075b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian (_, startline, startpos) = ReverseCloseExpression( 4076b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian clean_lines, linenum, endpos) 4077b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if startpos > -1 and startline < linenum: 4078b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Found the matching < on an earlier line, collect all 4079b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # pieces up to current line. 4080b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian line = '' 4081b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian for i in xrange(startline, linenum + 1): 4082b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian line += clean_lines.elided[i].strip() 4083b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 4084b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Check for non-const references in function parameters. A single '&' may 4085b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # found in the following places: 4086b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # inside expression: binary & for bitwise AND 4087b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # inside expression: unary & for taking the address of something 4088b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # inside declarators: reference parameter 4089b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # We will exclude the first two cases by checking that we are not inside a 4090b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # function body, including one that was just introduced by a trailing '{'. 4091b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # TODO(unknwon): Doesn't account for preprocessor directives. 4092b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # TODO(unknown): Doesn't account for 'catch(Exception& e)' [rare]. 4093b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian check_params = False 4094b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if not nesting_state.stack: 4095b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian check_params = True # top level 4096b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian elif (isinstance(nesting_state.stack[-1], _ClassInfo) or 4097b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian isinstance(nesting_state.stack[-1], _NamespaceInfo)): 4098b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian check_params = True # within class or namespace 4099b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian elif Match(r'.*{\s*$', line): 4100b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (len(nesting_state.stack) == 1 or 4101b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian isinstance(nesting_state.stack[-2], _ClassInfo) or 4102b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian isinstance(nesting_state.stack[-2], _NamespaceInfo)): 4103b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian check_params = True # just opened global/class/namespace block 4104b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # We allow non-const references in a few standard places, like functions 4105b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # called "swap()" or iostream operators like "<<" or ">>". Do not check 4106b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # those function parameters. 4107b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 4108b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # We also accept & in static_assert, which looks like a function but 4109b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # it's actually a declaration expression. 4110b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian whitelisted_functions = (r'(?:[sS]wap(?:<\w:+>)?|' 4111b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r'operator\s*[<>][<>]|' 4112b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r'static_assert|COMPILE_ASSERT' 4113b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r')\s*\(') 4114b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if Search(whitelisted_functions, line): 4115b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian check_params = False 4116b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian elif not Search(r'\S+\([^)]*$', line): 4117b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Don't see a whitelisted function on this line. Actually we 4118b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # didn't see any function name on this line, so this is likely a 4119b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # multi-line parameter list. Try a bit harder to catch this case. 4120b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian for i in xrange(2): 4121b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (linenum > i and 4122b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian Search(whitelisted_functions, clean_lines.elided[linenum - i - 1])): 4123b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian check_params = False 4124b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break 4125b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 4126b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if check_params: 4127b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian decls = ReplaceAll(r'{[^}]*}', ' ', line) # exclude function body 4128b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian for parameter in re.findall(_RE_PATTERN_REF_PARAM, decls): 4129b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if not Match(_RE_PATTERN_CONST_REF_PARAM, parameter): 4130b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian error(filename, linenum, 'runtime/references', 2, 4131b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'Is this a non-const reference? ' 4132b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'If so, make const or use a pointer: ' + 4133b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ReplaceAll(' *<', '<', parameter)) 4134b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 4135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef CheckCStyleCast(filename, linenum, line, raw_line, cast_type, pattern, 4137ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error): 4138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Checks for a C-style cast by looking for the pattern. 4139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 4141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the current file. 4142ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: The number of the line to check. 4143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line: The line of code to check. 4144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang raw_line: The raw line of code to check, with comments. 4145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang cast_type: The string for the C++ cast to recommend. This is either 4146ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang reinterpret_cast, static_cast, or const_cast, depending. 4147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang pattern: The regular expression used to find C-style casts. 4148ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: The function to call with any errors found. 4149ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4150ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Returns: 4151ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang True if an error was emitted. 4152ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang False otherwise. 4153ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 4154ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match = Search(pattern, line) 4155ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not match: 4156ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return False 4157ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # e.g., sizeof(int) 4159ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang sizeof_match = Match(r'.*sizeof\s*$', line[0:match.start(1) - 1]) 4160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if sizeof_match: 4161ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'runtime/sizeof', 1, 4162ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Using sizeof(type). Use sizeof(varname) instead if possible') 4163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return True 4164ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4165ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # operator++(int) and operator--(int) 4166ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (line[0:match.start(1) - 1].endswith(' operator++') or 4167ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line[0:match.start(1) - 1].endswith(' operator--')): 4168ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return False 4169ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4170b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # A single unnamed argument for a function tends to look like old 4171b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # style cast. If we see those, don't issue warnings for deprecated 4172b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # casts, instead issue warnings for unnamed arguments where 4173b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # appropriate. 4174b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 4175b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # These are things that we want warnings for, since the style guide 4176b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # explicitly require all parameters to be named: 4177b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Function(int); 4178b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Function(int) { 4179b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # ConstMember(int) const; 4180b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # ConstMember(int) const { 4181b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # ExceptionMember(int) throw (...); 4182b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # ExceptionMember(int) throw (...) { 4183b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # PureVirtual(int) = 0; 4184b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # 4185b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # These are functions of some sort, where the compiler would be fine 4186b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # if they had named parameters, but people often omit those 4187b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # identifiers to reduce clutter: 4188b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # (FunctionPointer)(int); 4189b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # (FunctionPointer)(int) = value; 4190b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Function((function_pointer_arg)(int)) 4191b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # <TemplateArgument(int)>; 4192b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # <(FunctionPointerTemplateArgument)(int)>; 4193ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang remainder = line[match.end(0):] 4194b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if Match(r'^\s*(?:;|const\b|throw\b|=|>|\{|\))', remainder): 4195b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Looks like an unnamed parameter. 4196ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4197b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Don't warn on any kind of template arguments. 4198b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if Match(r'^\s*>', remainder): 4199b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return False 4200b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 4201b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Don't warn on assignments to function pointers, but keep warnings for 4202b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # unnamed parameters to pure virtual functions. Note that this pattern 4203b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # will also pass on assignments of "0" to function pointers, but the 4204b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # preferred values for those would be "nullptr" or "NULL". 4205b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian matched_zero = Match(r'^\s=\s*(\S+)\s*;', remainder) 4206b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if matched_zero and matched_zero.group(1) != '0': 4207b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return False 4208b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 4209b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Don't warn on function pointer declarations. For this we need 4210b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # to check what came before the "(type)" string. 4211b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if Match(r'.*\)\s*$', line[0:match.start(0)]): 4212b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return False 4213b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 4214b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Don't warn if the parameter is named with block comments, e.g.: 4215b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Function(int /*unused_param*/); 4216b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if '/*' in raw_line: 4217b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return False 4218b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 4219b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian # Passed all filters, issue warning here. 4220b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian error(filename, linenum, 'readability/function', 3, 4221b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'All parameters should be named in a function') 4222ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return True 4223ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4224ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # At this point, all that should be left is actual casts. 4225ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'readability/casting', 4, 4226ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Using C-style cast. Use %s<%s>(...) instead' % 4227ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (cast_type, match.group(1))) 4228ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4229ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return True 4230ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4231ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4232ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_HEADERS_CONTAINING_TEMPLATES = ( 4233ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('<deque>', ('deque',)), 4234ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('<functional>', ('unary_function', 'binary_function', 4235ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'plus', 'minus', 'multiplies', 'divides', 'modulus', 4236ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'negate', 4237ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'equal_to', 'not_equal_to', 'greater', 'less', 4238ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'greater_equal', 'less_equal', 4239ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'logical_and', 'logical_or', 'logical_not', 4240ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'unary_negate', 'not1', 'binary_negate', 'not2', 4241ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'bind1st', 'bind2nd', 4242ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'pointer_to_unary_function', 4243ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'pointer_to_binary_function', 4244ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'ptr_fun', 4245ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'mem_fun_t', 'mem_fun', 'mem_fun1_t', 'mem_fun1_ref_t', 4246ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'mem_fun_ref_t', 4247ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'const_mem_fun_t', 'const_mem_fun1_t', 4248ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'const_mem_fun_ref_t', 'const_mem_fun1_ref_t', 4249ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'mem_fun_ref', 4250ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang )), 4251ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('<limits>', ('numeric_limits',)), 4252ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('<list>', ('list',)), 4253ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('<map>', ('map', 'multimap',)), 4254ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('<memory>', ('allocator',)), 4255ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('<queue>', ('queue', 'priority_queue',)), 4256ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('<set>', ('set', 'multiset',)), 4257ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('<stack>', ('stack',)), 4258ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('<string>', ('char_traits', 'basic_string',)), 4259ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('<utility>', ('pair',)), 4260ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('<vector>', ('vector',)), 4261ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4262ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # gcc extensions. 4263ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Note: std::hash is their hash, ::hash is our hash 4264ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('<hash_map>', ('hash_map', 'hash_multimap',)), 4265ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('<hash_set>', ('hash_set', 'hash_multiset',)), 4266ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ('<slist>', ('slist',)), 4267ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ) 4268ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4269ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_RE_PATTERN_STRING = re.compile(r'\bstring\b') 4270ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4271ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_re_pattern_algorithm_header = [] 4272ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangfor _template in ('copy', 'max', 'min', 'min_element', 'sort', 'swap', 4273ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'transform'): 4274ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Match max<type>(..., ...), max(..., ...), but not foo->max, foo.max or 4275ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # type::max(). 4276ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _re_pattern_algorithm_header.append( 4277ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (re.compile(r'[^>.]\b' + _template + r'(<.*?>)?\([^\)]'), 4278ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _template, 4279ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang '<algorithm>')) 4280ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4281ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_re_pattern_templates = [] 4282ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangfor _header, _templates in _HEADERS_CONTAINING_TEMPLATES: 4283ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for _template in _templates: 4284ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _re_pattern_templates.append( 4285ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (re.compile(r'(\<|\b)' + _template + r'\s*\<'), 4286ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _template + '<>', 4287ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _header)) 4288ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4289ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4290ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef FilesBelongToSameModule(filename_cc, filename_h): 4291ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Check if these two filenames belong to the same module. 4292ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4293ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang The concept of a 'module' here is a as follows: 4294ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang foo.h, foo-inl.h, foo.cc, foo_test.cc and foo_unittest.cc belong to the 4295ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang same 'module' if they are in the same directory. 4296ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang some/path/public/xyzzy and some/path/internal/xyzzy are also considered 4297ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang to belong to the same module here. 4298ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4299ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang If the filename_cc contains a longer path than the filename_h, for example, 4300ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang '/absolute/path/to/base/sysinfo.cc', and this file would include 4301ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'base/sysinfo.h', this function also produces the prefix needed to open the 4302ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang header. This is used by the caller of this function to more robustly open the 4303ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang header file. We don't have access to the real include paths in this context, 4304ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang so we need this guesswork here. 4305ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4306ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Known bugs: tools/base/bar.cc and base/bar.h belong to the same module 4307ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang according to this implementation. Because of this, this function gives 4308ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang some false positives. This should be sufficiently rare in practice. 4309ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4310ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 4311ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename_cc: is the path for the .cc file 4312ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename_h: is the path for the header path 4313ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4314ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Returns: 4315ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Tuple with a bool and a string: 4316ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang bool: True if filename_cc and filename_h belong to the same module. 4317ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang string: the additional prefix needed to open the header file. 4318ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 4319ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4320ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not filename_cc.endswith('.cc'): 4321ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return (False, '') 4322ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename_cc = filename_cc[:-len('.cc')] 4323ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if filename_cc.endswith('_unittest'): 4324ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename_cc = filename_cc[:-len('_unittest')] 4325ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif filename_cc.endswith('_test'): 4326ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename_cc = filename_cc[:-len('_test')] 4327ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename_cc = filename_cc.replace('/public/', '/') 4328ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename_cc = filename_cc.replace('/internal/', '/') 4329ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4330ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not filename_h.endswith('.h'): 4331ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return (False, '') 4332ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename_h = filename_h[:-len('.h')] 4333ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if filename_h.endswith('-inl'): 4334ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename_h = filename_h[:-len('-inl')] 4335ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename_h = filename_h.replace('/public/', '/') 4336ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename_h = filename_h.replace('/internal/', '/') 4337ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4338ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang files_belong_to_same_module = filename_cc.endswith(filename_h) 4339ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang common_path = '' 4340ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if files_belong_to_same_module: 4341ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang common_path = filename_cc[:-len(filename_h)] 4342ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return files_belong_to_same_module, common_path 4343ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4344ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4345ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef UpdateIncludeState(filename, include_state, io=codecs): 4346ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Fill up the include_state with new includes found from the file. 4347ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4348ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 4349ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: the name of the header to read. 4350ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang include_state: an _IncludeState instance in which the headers are inserted. 4351ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang io: The io factory to use to read the file. Provided for testability. 4352ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4353ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Returns: 4354ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang True if a header was succesfully added. False otherwise. 4355ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 4356ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang headerfile = None 4357ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang try: 4358ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang headerfile = io.open(filename, 'r', 'utf8', 'replace') 4359ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang except IOError: 4360ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return False 4361ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum = 0 4362ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for line in headerfile: 4363ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum += 1 4364ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_line = CleanseComments(line) 4365ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match = _RE_PATTERN_INCLUDE.search(clean_line) 4366ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if match: 4367ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang include = match.group(2) 4368ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # The value formatting is cute, but not really used right now. 4369ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # What matters here is that the key is in include_state. 4370ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang include_state.setdefault(include, '%s:%d' % (filename, linenum)) 4371ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return True 4372ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4373ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4374ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error, 4375ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang io=codecs): 4376ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Reports for missing stl includes. 4377ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4378ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang This function will output warnings to make sure you are including the headers 4379ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang necessary for the stl containers and functions that you use. We only give one 4380ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang reason to include a header. For example, if you use both equal_to<> and 4381ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang less<> in a .h file, only one (the latter in the file) of these will be 4382ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang reported as a reason to include the <functional>. 4383ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4384ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 4385ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the current file. 4386ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_lines: A CleansedLines instance containing the file. 4387ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang include_state: An _IncludeState instance. 4388ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: The function to call with any errors found. 4389ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang io: The IO factory to use to read the header file. Provided for unittest 4390ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang injection. 4391ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 4392ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang required = {} # A map of header name to linenumber and the template entity. 4393ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Example of required: { '<functional>': (1219, 'less<>') } 4394ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4395ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for linenum in xrange(clean_lines.NumLines()): 4396ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line = clean_lines.elided[linenum] 4397ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not line or line[0] == '#': 4398ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang continue 4399ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4400ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # String is special -- it is a non-templatized type in STL. 4401ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang matched = _RE_PATTERN_STRING.search(line) 4402ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if matched: 4403ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Don't warn about strings in non-STL namespaces: 4404ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # (We check only the first match per line; good enough.) 4405ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang prefix = line[:matched.start()] 4406ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if prefix.endswith('std::') or not prefix.endswith('::'): 4407ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang required['<string>'] = (linenum, 'string') 4408ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4409ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for pattern, template, header in _re_pattern_algorithm_header: 4410ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if pattern.search(line): 4411ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang required[header] = (linenum, template) 4412ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4413ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # The following function is just a speed up, no semantics are changed. 4414ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not '<' in line: # Reduces the cpu time usage by skipping lines. 4415ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang continue 4416ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4417ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for pattern, template, header in _re_pattern_templates: 4418ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if pattern.search(line): 4419ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang required[header] = (linenum, template) 4420ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4421ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # The policy is that if you #include something in foo.h you don't need to 4422ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # include it again in foo.cc. Here, we will look at possible includes. 4423ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Let's copy the include_state so it is only messed up within this function. 4424ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang include_state = include_state.copy() 4425ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4426ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Did we find the header for this file (if any) and succesfully load it? 4427ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang header_found = False 4428ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4429ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Use the absolute path so that matching works properly. 4430ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang abs_filename = FileInfo(filename).FullName() 4431ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4432ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # For Emacs's flymake. 4433ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # If cpplint is invoked from Emacs's flymake, a temporary file is generated 4434ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # by flymake and that file name might end with '_flymake.cc'. In that case, 4435ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # restore original file name here so that the corresponding header file can be 4436ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # found. 4437ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # e.g. If the file name is 'foo_flymake.cc', we should search for 'foo.h' 4438ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # instead of 'foo_flymake.h' 4439ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang abs_filename = re.sub(r'_flymake\.cc$', '.cc', abs_filename) 4440ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4441ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # include_state is modified during iteration, so we iterate over a copy of 4442ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # the keys. 4443ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang header_keys = include_state.keys() 4444ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for header in header_keys: 4445ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (same_module, common_path) = FilesBelongToSameModule(abs_filename, header) 4446ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang fullpath = common_path + header 4447ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if same_module and UpdateIncludeState(fullpath, include_state, io): 4448ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang header_found = True 4449ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4450ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # If we can't find the header file for a .cc, assume it's because we don't 4451ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # know where to look. In that case we'll give up as we're not sure they 4452ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # didn't include it in the .h file. 4453ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # TODO(unknown): Do a better job of finding .h files so we are confident that 4454ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # not having the .h file means there isn't one. 4455ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if filename.endswith('.cc') and not header_found: 4456ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 4457ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4458ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # All the lines have been processed, report the errors found. 4459ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for required_header_unstripped in required: 4460ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang template = required[required_header_unstripped][1] 4461ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if required_header_unstripped.strip('<>"') not in include_state: 4462ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, required[required_header_unstripped][0], 4463ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'build/include_what_you_use', 4, 4464ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'Add #include ' + required_header_unstripped + ' for ' + template) 4465ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4466ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4467ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang_RE_PATTERN_EXPLICIT_MAKEPAIR = re.compile(r'\bmake_pair\s*<') 4468ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4469ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4470ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef CheckMakePairUsesDeduction(filename, clean_lines, linenum, error): 4471ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Check that make_pair's template arguments are deduced. 4472ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4473ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang G++ 4.6 in C++0x mode fails badly if make_pair's template arguments are 4474ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang specified explicitly, and such use isn't intended in any case. 4475ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4476ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 4477ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the current file. 4478ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_lines: A CleansedLines instance containing the file. 4479ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang linenum: The number of the line to check. 4480ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: The function to call with any errors found. 4481ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 4482b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian line = clean_lines.elided[linenum] 4483ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang match = _RE_PATTERN_EXPLICIT_MAKEPAIR.search(line) 4484ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if match: 4485ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error(filename, linenum, 'build/explicit_make_pair', 4486ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4, # 4 = high confidence 4487ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'For C++11-compatibility, omit template arguments from make_pair' 4488ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ' OR use pair directly OR if appropriate, construct a pair directly') 4489ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4490ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4491ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef ProcessLine(filename, file_extension, clean_lines, line, 4492ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang include_state, function_state, nesting_state, error, 4493ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang extra_check_functions=[]): 4494ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Processes a single line in the file. 4495ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4496ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 4497ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: Filename of the file that is being processed. 4498ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang file_extension: The extension (dot not included) of the file. 4499ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_lines: An array of strings, each representing a line of the file, 4500ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang with comments stripped. 4501ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang line: Number of line being processed. 4502ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang include_state: An _IncludeState instance in which the headers are inserted. 4503ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang function_state: A _FunctionState instance which counts function lines, etc. 4504ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nesting_state: A _NestingState instance which maintains information about 4505ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang the current stack of nested blocks being parsed. 4506ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: A callable to which errors are reported, which takes 4 arguments: 4507ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename, line number, error level, and message 4508ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang extra_check_functions: An array of additional check functions that will be 4509ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang run on each source line. Each function takes 4 4510ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang arguments: filename, clean_lines, line, error 4511ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 4512ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang raw_lines = clean_lines.raw_lines 4513ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ParseNolintSuppressions(filename, raw_lines[line], line, error) 4514ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nesting_state.Update(filename, clean_lines, line, error) 4515ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if nesting_state.stack and nesting_state.stack[-1].inline_asm != _NO_ASM: 4516ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 4517ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang CheckForFunctionLengths(filename, clean_lines, line, function_state, error) 4518ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error) 4519ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang CheckStyle(filename, clean_lines, line, file_extension, nesting_state, error) 4520ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang CheckLanguage(filename, clean_lines, line, file_extension, include_state, 4521b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian nesting_state, error) 4522b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian CheckForNonConstReference(filename, clean_lines, line, nesting_state, error) 4523ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang CheckForNonStandardConstructs(filename, clean_lines, line, 4524ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nesting_state, error) 4525b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian CheckVlogArguments(filename, clean_lines, line, error) 4526ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang CheckPosixThreading(filename, clean_lines, line, error) 4527ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang CheckInvalidIncrement(filename, clean_lines, line, error) 4528ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang CheckMakePairUsesDeduction(filename, clean_lines, line, error) 4529ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for check_fn in extra_check_functions: 4530ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang check_fn(filename, clean_lines, line, error) 4531ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4532ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef ProcessFileData(filename, file_extension, lines, error, 4533ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang extra_check_functions=[]): 4534ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Performs lint checks and reports any errors to the given error function. 4535ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4536ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 4537ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: Filename of the file that is being processed. 4538ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang file_extension: The extension (dot not included) of the file. 4539ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang lines: An array of strings, each representing a line of the file, with the 4540ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang last element being empty if the file is terminated with a newline. 4541ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang error: A callable to which errors are reported, which takes 4 arguments: 4542ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename, line number, error level, and message 4543ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang extra_check_functions: An array of additional check functions that will be 4544ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang run on each source line. Each function takes 4 4545ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang arguments: filename, clean_lines, line, error 4546ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 4547ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang lines = (['// marker so line numbers and indices both start at 1'] + lines + 4548ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ['// marker so line numbers end in a known way']) 4549ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4550ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang include_state = _IncludeState() 4551ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang function_state = _FunctionState() 4552ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nesting_state = _NestingState() 4553ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4554ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ResetNolintSuppressions() 4555ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4556ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang CheckForCopyright(filename, lines, error) 4557ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4558ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if file_extension == 'h': 4559ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang CheckForHeaderGuard(filename, lines, error) 4560ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4561ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang RemoveMultiLineComments(filename, lines, error) 4562ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang clean_lines = CleansedLines(lines) 4563ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for line in xrange(clean_lines.NumLines()): 4564ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ProcessLine(filename, file_extension, clean_lines, line, 4565ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang include_state, function_state, nesting_state, error, 4566ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang extra_check_functions) 4567b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian nesting_state.CheckCompletedBlocks(filename, error) 4568ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4569ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error) 4570ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4571ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # We check here rather than inside ProcessLine so that we see raw 4572ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # lines rather than "cleaned" lines. 4573b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian CheckForBadCharacters(filename, lines, error) 4574ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4575ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang CheckForNewlineAtEOF(filename, lines, error) 4576ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4577ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef ProcessFile(filename, vlevel, extra_check_functions=[]): 4578ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Does google-lint on a single file. 4579ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4580ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 4581ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filename: The name of the file to parse. 4582ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4583ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang vlevel: The level of errors to report. Every error of confidence 4584ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang >= verbose_level will be reported. 0 is a good default. 4585ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4586ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang extra_check_functions: An array of additional check functions that will be 4587ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang run on each source line. Each function takes 4 4588ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang arguments: filename, clean_lines, line, error 4589ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 4590ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4591ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _SetVerboseLevel(vlevel) 4592ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4593ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang try: 4594ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Support the UNIX convention of using "-" for stdin. Note that 4595ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # we are not opening the file with universal newline support 4596ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # (which codecs doesn't support anyway), so the resulting lines do 4597ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # contain trailing '\r' characters if we are reading a file that 4598ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # has CRLF endings. 4599ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # If after the split a trailing '\r' is present, it is removed 4600ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # below. If it is not expected to be present (i.e. os.linesep != 4601ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # '\r\n' as in Windows), a warning is issued below if this file 4602ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # is processed. 4603ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4604ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if filename == '-': 4605ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang lines = codecs.StreamReaderWriter(sys.stdin, 4606ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang codecs.getreader('utf8'), 4607ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang codecs.getwriter('utf8'), 4608ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'replace').read().split('\n') 4609ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 4610ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang lines = codecs.open(filename, 'r', 'utf8', 'replace').read().split('\n') 4611ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4612ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang carriage_return_found = False 4613ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Remove trailing '\r'. 4614ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for linenum in range(len(lines)): 4615ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if lines[linenum].endswith('\r'): 4616ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang lines[linenum] = lines[linenum].rstrip('\r') 4617ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang carriage_return_found = True 4618ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4619ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang except IOError: 4620ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang sys.stderr.write( 4621ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang "Skipping input '%s': Can't open for reading\n" % filename) 4622ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 4623ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4624ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Note, if no dot is found, this will give the entire filename as the ext. 4625ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang file_extension = filename[filename.rfind('.') + 1:] 4626ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4627ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # When reading from stdin, the extension is unknown, so no cpplint tests 4628ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # should rely on the extension. 4629b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if filename != '-' and file_extension not in _valid_extensions: 4630b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian sys.stderr.write('Ignoring %s; not a valid file name ' 4631b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian '(%s)\n' % (filename, ', '.join(_valid_extensions))) 4632ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 4633ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ProcessFileData(filename, file_extension, lines, Error, 4634ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang extra_check_functions) 4635ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if carriage_return_found and os.linesep != '\r\n': 4636ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Use 0 for linenum since outputting only one error for potentially 4637ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # several lines. 4638ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Error(filename, 0, 'whitespace/newline', 1, 4639ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'One or more unexpected \\r (^M) found;' 4640ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'better to use only a \\n') 4641ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4642ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang sys.stderr.write('Done processing %s\n' % filename) 4643ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4644ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4645ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef PrintUsage(message): 4646ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Prints a brief usage string and exits, optionally with an error message. 4647ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4648ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 4649ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang message: The optional error message. 4650ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 4651ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang sys.stderr.write(_USAGE) 4652ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if message: 4653ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang sys.exit('\nFATAL ERROR: ' + message) 4654ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang else: 4655ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang sys.exit(1) 4656ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4657ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4658ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef PrintCategories(): 4659ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Prints a list of all the error-categories used by error messages. 4660ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4661ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang These are the categories used to filter messages via --filter. 4662ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 4663ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang sys.stderr.write(''.join(' %s\n' % cat for cat in _ERROR_CATEGORIES)) 4664ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang sys.exit(0) 4665ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4666ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4667ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef ParseArguments(args): 4668ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """Parses the command line arguments. 4669ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4670ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang This may set the output format and verbosity level as side-effects. 4671ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4672ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Args: 4673ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang args: The command line arguments: 4674ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4675ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang Returns: 4676ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang The list of filenames to lint. 4677ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang """ 4678ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang try: 4679ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (opts, filenames) = getopt.getopt(args, '', ['help', 'output=', 'verbose=', 4680ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'counting=', 4681ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'filter=', 4682b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'root=', 4683b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'linelength=', 4684b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 'extensions=']) 4685ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang except getopt.GetoptError: 4686ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang PrintUsage('Invalid arguments.') 4687ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4688ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang verbosity = _VerboseLevel() 4689ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang output_format = _OutputFormat() 4690ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filters = '' 4691ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang counting_style = '' 4692ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4693ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (opt, val) in opts: 4694ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if opt == '--help': 4695ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang PrintUsage(None) 4696ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif opt == '--output': 4697b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if val not in ('emacs', 'vs7', 'eclipse'): 4698b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian PrintUsage('The only allowed output formats are emacs, vs7 and eclipse.') 4699ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang output_format = val 4700ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif opt == '--verbose': 4701ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang verbosity = int(val) 4702ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif opt == '--filter': 4703ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filters = val 4704ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not filters: 4705ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang PrintCategories() 4706ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif opt == '--counting': 4707ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if val not in ('total', 'toplevel', 'detailed'): 4708ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang PrintUsage('Valid counting options are total, toplevel, and detailed') 4709ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang counting_style = val 4710ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang elif opt == '--root': 4711ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang global _root 4712ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _root = val 4713b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian elif opt == '--linelength': 4714b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian global _line_length 4715b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian try: 4716b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian _line_length = int(val) 4717b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian except ValueError: 4718b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian PrintUsage('Line length must be digits.') 4719b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian elif opt == '--extensions': 4720b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian global _valid_extensions 4721b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian try: 4722b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian _valid_extensions = set(val.split(',')) 4723b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian except ValueError: 4724b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian PrintUsage('Extensions must be comma seperated list.') 4725ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4726ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if not filenames: 4727ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang PrintUsage('No files were specified.') 4728ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4729ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _SetOutputFormat(output_format) 4730ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _SetVerboseLevel(verbosity) 4731ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _SetFilters(filters) 4732ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _SetCountingStyle(counting_style) 4733ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4734ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return filenames 4735ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4736ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4737ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangdef main(): 4738ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang filenames = ParseArguments(sys.argv[1:]) 4739ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4740ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # Change stderr to write with replacement characters so we don't die 4741ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang # if we try to print something containing non-ASCII characters. 4742ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang sys.stderr = codecs.StreamReaderWriter(sys.stderr, 4743ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang codecs.getreader('utf8'), 4744ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang codecs.getwriter('utf8'), 4745ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 'replace') 4746ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4747ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _cpplint_state.ResetErrorCounts() 4748ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for filename in filenames: 4749ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ProcessFile(filename, _cpplint_state.verbose_level) 4750ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang _cpplint_state.PrintErrorCounts() 4751ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4752ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang sys.exit(_cpplint_state.error_count > 0) 4753ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4754ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4755ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangif __name__ == '__main__': 4756ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang main() 4757