| @@ 1986-2086 (lines=101) @@ | ||
| 1983 | return re.sub(r'[^a-zA-Z0-9]', '_', file_path_from_root).upper() + '_' |
|
| 1984 | ||
| 1985 | ||
| 1986 | def CheckForHeaderGuard(filename, clean_lines, error): |
|
| 1987 | """Checks that the file contains a header guard. |
|
| 1988 | ||
| 1989 | Logs an error if no #ifndef header guard is present. For other |
|
| 1990 | headers, checks that the full pathname is used. |
|
| 1991 | ||
| 1992 | Args: |
|
| 1993 | filename: The name of the C++ header file. |
|
| 1994 | clean_lines: A CleansedLines instance containing the file. |
|
| 1995 | error: The function to call with any errors found. |
|
| 1996 | """ |
|
| 1997 | ||
| 1998 | # Don't check for header guards if there are error suppression |
|
| 1999 | # comments somewhere in this file. |
|
| 2000 | # |
|
| 2001 | # Because this is silencing a warning for a nonexistent line, we |
|
| 2002 | # only support the very specific NOLINT(build/header_guard) syntax, |
|
| 2003 | # and not the general NOLINT or NOLINT(*) syntax. |
|
| 2004 | raw_lines = clean_lines.lines_without_raw_strings |
|
| 2005 | for i in raw_lines: |
|
| 2006 | if Search(r'//\s*NOLINT\(build/header_guard\)', i): |
|
| 2007 | return |
|
| 2008 | ||
| 2009 | # Allow pragma once instead of header guards |
|
| 2010 | for i in raw_lines: |
|
| 2011 | if Search(r'^\s*#pragma\s+once', i): |
|
| 2012 | return |
|
| 2013 | ||
| 2014 | cppvar = GetHeaderGuardCPPVariable(filename) |
|
| 2015 | ||
| 2016 | ifndef = '' |
|
| 2017 | ifndef_linenum = 0 |
|
| 2018 | define = '' |
|
| 2019 | endif = '' |
|
| 2020 | endif_linenum = 0 |
|
| 2021 | for linenum, line in enumerate(raw_lines): |
|
| 2022 | linesplit = line.split() |
|
| 2023 | if len(linesplit) >= 2: |
|
| 2024 | # find the first occurrence of #ifndef and #define, save arg |
|
| 2025 | if not ifndef and linesplit[0] == '#ifndef': |
|
| 2026 | # set ifndef to the header guard presented on the #ifndef line. |
|
| 2027 | ifndef = linesplit[1] |
|
| 2028 | ifndef_linenum = linenum |
|
| 2029 | if not define and linesplit[0] == '#define': |
|
| 2030 | define = linesplit[1] |
|
| 2031 | # find the last occurrence of #endif, save entire line |
|
| 2032 | if line.startswith('#endif'): |
|
| 2033 | endif = line |
|
| 2034 | endif_linenum = linenum |
|
| 2035 | ||
| 2036 | if not ifndef or not define or ifndef != define: |
|
| 2037 | error(filename, 0, 'build/header_guard', 5, |
|
| 2038 | 'No #ifndef header guard found, suggested CPP variable is: %s' % |
|
| 2039 | cppvar) |
|
| 2040 | return |
|
| 2041 | ||
| 2042 | # The guard should be PATH_FILE_H_, but we also allow PATH_FILE_H__ |
|
| 2043 | # for backward compatibility. |
|
| 2044 | if ifndef != cppvar: |
|
| 2045 | error_level = 0 |
|
| 2046 | if ifndef != cppvar + '_': |
|
| 2047 | error_level = 5 |
|
| 2048 | ||
| 2049 | ParseNolintSuppressions(filename, raw_lines[ifndef_linenum], ifndef_linenum, |
|
| 2050 | error) |
|
| 2051 | error(filename, ifndef_linenum, 'build/header_guard', error_level, |
|
| 2052 | '#ifndef header guard has wrong style, please use: %s' % cppvar) |
|
| 2053 | ||
| 2054 | # Check for "//" comments on endif line. |
|
| 2055 | ParseNolintSuppressions(filename, raw_lines[endif_linenum], endif_linenum, |
|
| 2056 | error) |
|
| 2057 | match = Match(r'#endif\s*//\s*' + cppvar + r'(_)?\b', endif) |
|
| 2058 | if match: |
|
| 2059 | if match.group(1) == '_': |
|
| 2060 | # Issue low severity warning for deprecated double trailing underscore |
|
| 2061 | error(filename, endif_linenum, 'build/header_guard', 0, |
|
| 2062 | '#endif line should be "#endif // %s"' % cppvar) |
|
| 2063 | return |
|
| 2064 | ||
| 2065 | # Didn't find the corresponding "//" comment. If this file does not |
|
| 2066 | # contain any "//" comments at all, it could be that the compiler |
|
| 2067 | # only wants "/**/" comments, look for those instead. |
|
| 2068 | no_single_line_comments = True |
|
| 2069 | for i in xrange(1, len(raw_lines) - 1): |
|
| 2070 | line = raw_lines[i] |
|
| 2071 | if Match(r'^(?:(?:\'(?:\.|[^\'])*\')|(?:"(?:\.|[^"])*")|[^\'"])*//', line): |
|
| 2072 | no_single_line_comments = False |
|
| 2073 | break |
|
| 2074 | ||
| 2075 | if no_single_line_comments: |
|
| 2076 | match = Match(r'#endif\s*/\*\s*' + cppvar + r'(_)?\s*\*/', endif) |
|
| 2077 | if match: |
|
| 2078 | if match.group(1) == '_': |
|
| 2079 | # Low severity warning for double trailing underscore |
|
| 2080 | error(filename, endif_linenum, 'build/header_guard', 0, |
|
| 2081 | '#endif line should be "#endif /* %s */"' % cppvar) |
|
| 2082 | return |
|
| 2083 | ||
| 2084 | # Didn't find anything |
|
| 2085 | error(filename, endif_linenum, 'build/header_guard', 5, |
|
| 2086 | '#endif line should be "#endif // %s"' % cppvar) |
|
| 2087 | ||
| 2088 | ||
| 2089 | def CheckHeaderFileIncluded(filename, include_state, error): |
|
| @@ 1986-2086 (lines=101) @@ | ||
| 1983 | return re.sub(r'[^a-zA-Z0-9]', '_', file_path_from_root).upper() + '_' |
|
| 1984 | ||
| 1985 | ||
| 1986 | def CheckForHeaderGuard(filename, clean_lines, error): |
|
| 1987 | """Checks that the file contains a header guard. |
|
| 1988 | ||
| 1989 | Logs an error if no #ifndef header guard is present. For other |
|
| 1990 | headers, checks that the full pathname is used. |
|
| 1991 | ||
| 1992 | Args: |
|
| 1993 | filename: The name of the C++ header file. |
|
| 1994 | clean_lines: A CleansedLines instance containing the file. |
|
| 1995 | error: The function to call with any errors found. |
|
| 1996 | """ |
|
| 1997 | ||
| 1998 | # Don't check for header guards if there are error suppression |
|
| 1999 | # comments somewhere in this file. |
|
| 2000 | # |
|
| 2001 | # Because this is silencing a warning for a nonexistent line, we |
|
| 2002 | # only support the very specific NOLINT(build/header_guard) syntax, |
|
| 2003 | # and not the general NOLINT or NOLINT(*) syntax. |
|
| 2004 | raw_lines = clean_lines.lines_without_raw_strings |
|
| 2005 | for i in raw_lines: |
|
| 2006 | if Search(r'//\s*NOLINT\(build/header_guard\)', i): |
|
| 2007 | return |
|
| 2008 | ||
| 2009 | # Allow pragma once instead of header guards |
|
| 2010 | for i in raw_lines: |
|
| 2011 | if Search(r'^\s*#pragma\s+once', i): |
|
| 2012 | return |
|
| 2013 | ||
| 2014 | cppvar = GetHeaderGuardCPPVariable(filename) |
|
| 2015 | ||
| 2016 | ifndef = '' |
|
| 2017 | ifndef_linenum = 0 |
|
| 2018 | define = '' |
|
| 2019 | endif = '' |
|
| 2020 | endif_linenum = 0 |
|
| 2021 | for linenum, line in enumerate(raw_lines): |
|
| 2022 | linesplit = line.split() |
|
| 2023 | if len(linesplit) >= 2: |
|
| 2024 | # find the first occurrence of #ifndef and #define, save arg |
|
| 2025 | if not ifndef and linesplit[0] == '#ifndef': |
|
| 2026 | # set ifndef to the header guard presented on the #ifndef line. |
|
| 2027 | ifndef = linesplit[1] |
|
| 2028 | ifndef_linenum = linenum |
|
| 2029 | if not define and linesplit[0] == '#define': |
|
| 2030 | define = linesplit[1] |
|
| 2031 | # find the last occurrence of #endif, save entire line |
|
| 2032 | if line.startswith('#endif'): |
|
| 2033 | endif = line |
|
| 2034 | endif_linenum = linenum |
|
| 2035 | ||
| 2036 | if not ifndef or not define or ifndef != define: |
|
| 2037 | error(filename, 0, 'build/header_guard', 5, |
|
| 2038 | 'No #ifndef header guard found, suggested CPP variable is: %s' % |
|
| 2039 | cppvar) |
|
| 2040 | return |
|
| 2041 | ||
| 2042 | # The guard should be PATH_FILE_H_, but we also allow PATH_FILE_H__ |
|
| 2043 | # for backward compatibility. |
|
| 2044 | if ifndef != cppvar: |
|
| 2045 | error_level = 0 |
|
| 2046 | if ifndef != cppvar + '_': |
|
| 2047 | error_level = 5 |
|
| 2048 | ||
| 2049 | ParseNolintSuppressions(filename, raw_lines[ifndef_linenum], ifndef_linenum, |
|
| 2050 | error) |
|
| 2051 | error(filename, ifndef_linenum, 'build/header_guard', error_level, |
|
| 2052 | '#ifndef header guard has wrong style, please use: %s' % cppvar) |
|
| 2053 | ||
| 2054 | # Check for "//" comments on endif line. |
|
| 2055 | ParseNolintSuppressions(filename, raw_lines[endif_linenum], endif_linenum, |
|
| 2056 | error) |
|
| 2057 | match = Match(r'#endif\s*//\s*' + cppvar + r'(_)?\b', endif) |
|
| 2058 | if match: |
|
| 2059 | if match.group(1) == '_': |
|
| 2060 | # Issue low severity warning for deprecated double trailing underscore |
|
| 2061 | error(filename, endif_linenum, 'build/header_guard', 0, |
|
| 2062 | '#endif line should be "#endif // %s"' % cppvar) |
|
| 2063 | return |
|
| 2064 | ||
| 2065 | # Didn't find the corresponding "//" comment. If this file does not |
|
| 2066 | # contain any "//" comments at all, it could be that the compiler |
|
| 2067 | # only wants "/**/" comments, look for those instead. |
|
| 2068 | no_single_line_comments = True |
|
| 2069 | for i in xrange(1, len(raw_lines) - 1): |
|
| 2070 | line = raw_lines[i] |
|
| 2071 | if Match(r'^(?:(?:\'(?:\.|[^\'])*\')|(?:"(?:\.|[^"])*")|[^\'"])*//', line): |
|
| 2072 | no_single_line_comments = False |
|
| 2073 | break |
|
| 2074 | ||
| 2075 | if no_single_line_comments: |
|
| 2076 | match = Match(r'#endif\s*/\*\s*' + cppvar + r'(_)?\s*\*/', endif) |
|
| 2077 | if match: |
|
| 2078 | if match.group(1) == '_': |
|
| 2079 | # Low severity warning for double trailing underscore |
|
| 2080 | error(filename, endif_linenum, 'build/header_guard', 0, |
|
| 2081 | '#endif line should be "#endif /* %s */"' % cppvar) |
|
| 2082 | return |
|
| 2083 | ||
| 2084 | # Didn't find anything |
|
| 2085 | error(filename, endif_linenum, 'build/header_guard', 5, |
|
| 2086 | '#endif line should be "#endif // %s"' % cppvar) |
|
| 2087 | ||
| 2088 | ||
| 2089 | def CheckHeaderFileIncluded(filename, include_state, error): |
|