@@ 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): |