@@ 4441-4565 (lines=125) @@ | ||
4438 | return len(line) |
|
4439 | ||
4440 | ||
4441 | def CheckStyle(filename, clean_lines, linenum, file_extension, nesting_state, |
|
4442 | error): |
|
4443 | """Checks rules from the 'C++ style rules' section of cppguide.html. |
|
4444 | ||
4445 | Most of these rules are hard to test (naming, comment style), but we |
|
4446 | do what we can. In particular we check for 2-space indents, line lengths, |
|
4447 | tab usage, spaces inside code, etc. |
|
4448 | ||
4449 | Args: |
|
4450 | filename: The name of the current file. |
|
4451 | clean_lines: A CleansedLines instance containing the file. |
|
4452 | linenum: The number of the line to check. |
|
4453 | file_extension: The extension (without the dot) of the filename. |
|
4454 | nesting_state: A NestingState instance which maintains information about |
|
4455 | the current stack of nested blocks being parsed. |
|
4456 | error: The function to call with any errors found. |
|
4457 | """ |
|
4458 | ||
4459 | # Don't use "elided" lines here, otherwise we can't check commented lines. |
|
4460 | # Don't want to use "raw" either, because we don't want to check inside C++11 |
|
4461 | # raw strings, |
|
4462 | raw_lines = clean_lines.lines_without_raw_strings |
|
4463 | line = raw_lines[linenum] |
|
4464 | prev = raw_lines[linenum - 1] if linenum > 0 else '' |
|
4465 | ||
4466 | if line.find('\t') != -1: |
|
4467 | error(filename, linenum, 'whitespace/tab', 1, |
|
4468 | 'Tab found; better to use spaces') |
|
4469 | ||
4470 | # One or three blank spaces at the beginning of the line is weird; it's |
|
4471 | # hard to reconcile that with 2-space indents. |
|
4472 | # NOTE: here are the conditions rob pike used for his tests. Mine aren't |
|
4473 | # as sophisticated, but it may be worth becoming so: RLENGTH==initial_spaces |
|
4474 | # if(RLENGTH > 20) complain = 0; |
|
4475 | # if(match($0, " +(error|private|public|protected):")) complain = 0; |
|
4476 | # if(match(prev, "&& *$")) complain = 0; |
|
4477 | # if(match(prev, "\\|\\| *$")) complain = 0; |
|
4478 | # if(match(prev, "[\",=><] *$")) complain = 0; |
|
4479 | # if(match($0, " <<")) complain = 0; |
|
4480 | # if(match(prev, " +for \\(")) complain = 0; |
|
4481 | # if(prevodd && match(prevprev, " +for \\(")) complain = 0; |
|
4482 | scope_or_label_pattern = r'\s*\w+\s*:\s*\\?$' |
|
4483 | classinfo = nesting_state.InnermostClass() |
|
4484 | initial_spaces = 0 |
|
4485 | cleansed_line = clean_lines.elided[linenum] |
|
4486 | while initial_spaces < len(line) and line[initial_spaces] == ' ': |
|
4487 | initial_spaces += 1 |
|
4488 | # There are certain situations we allow one space, notably for |
|
4489 | # section labels, and also lines containing multi-line raw strings. |
|
4490 | # We also don't check for lines that look like continuation lines |
|
4491 | # (of lines ending in double quotes, commas, equals, or angle brackets) |
|
4492 | # because the rules for how to indent those are non-trivial. |
|
4493 | if (not Search(r'[",=><] *$', prev) and |
|
4494 | (initial_spaces == 1 or initial_spaces == 3) and |
|
4495 | not Match(scope_or_label_pattern, cleansed_line) and |
|
4496 | not (clean_lines.raw_lines[linenum] != line and |
|
4497 | Match(r'^\s*""', line))): |
|
4498 | error(filename, linenum, 'whitespace/indent', 3, |
|
4499 | 'Weird number of spaces at line-start. ' |
|
4500 | 'Are you using a 2-space indent?') |
|
4501 | ||
4502 | if line and line[-1].isspace(): |
|
4503 | error(filename, linenum, 'whitespace/end_of_line', 4, |
|
4504 | 'Line ends in whitespace. Consider deleting these extra spaces.') |
|
4505 | ||
4506 | # Check if the line is a header guard. |
|
4507 | is_header_guard = False |
|
4508 | if file_extension in GetHeaderExtensions(): |
|
4509 | cppvar = GetHeaderGuardCPPVariable(filename) |
|
4510 | if (line.startswith('#ifndef %s' % cppvar) or |
|
4511 | line.startswith('#define %s' % cppvar) or |
|
4512 | line.startswith('#endif // %s' % cppvar)): |
|
4513 | is_header_guard = True |
|
4514 | # #include lines and header guards can be long, since there's no clean way to |
|
4515 | # split them. |
|
4516 | # |
|
4517 | # URLs can be long too. It's possible to split these, but it makes them |
|
4518 | # harder to cut&paste. |
|
4519 | # |
|
4520 | # The "$Id:...$" comment may also get very long without it being the |
|
4521 | # developers fault. |
|
4522 | # |
|
4523 | # Doxygen documentation copying can get pretty long when using an overloaded |
|
4524 | # function declaration |
|
4525 | if (not line.startswith('#include') and not is_header_guard and |
|
4526 | not Match(r'^\s*//.*http(s?)://\S*$', line) and |
|
4527 | not Match(r'^\s*//\s*[^\s]*$', line) and |
|
4528 | not Match(r'^// \$Id:.*#[0-9]+ \$$', line) and |
|
4529 | not Match(r'^\s*/// [@\\](copydoc|copydetails|copybrief) .*$', line)): |
|
4530 | line_width = GetLineWidth(line) |
|
4531 | if line_width > _line_length: |
|
4532 | error(filename, linenum, 'whitespace/line_length', 2, |
|
4533 | 'Lines should be <= %i characters long' % _line_length) |
|
4534 | ||
4535 | if (cleansed_line.count(';') > 1 and |
|
4536 | # allow simple single line lambdas |
|
4537 | not Match(r'^[^{};]*\[[^\[\]]*\][^{}]*\{[^{}\n\r]*\}', |
|
4538 | line) and |
|
4539 | # for loops are allowed two ;'s (and may run over two lines). |
|
4540 | cleansed_line.find('for') == -1 and |
|
4541 | (GetPreviousNonBlankLine(clean_lines, linenum)[0].find('for') == -1 or |
|
4542 | GetPreviousNonBlankLine(clean_lines, linenum)[0].find(';') != -1) and |
|
4543 | # It's ok to have many commands in a switch case that fits in 1 line |
|
4544 | not ((cleansed_line.find('case ') != -1 or |
|
4545 | cleansed_line.find('default:') != -1) and |
|
4546 | cleansed_line.find('break;') != -1)): |
|
4547 | error(filename, linenum, 'whitespace/newline', 0, |
|
4548 | 'More than one command on the same line') |
|
4549 | ||
4550 | # Some more style checks |
|
4551 | CheckBraces(filename, clean_lines, linenum, error) |
|
4552 | CheckTrailingSemicolon(filename, clean_lines, linenum, error) |
|
4553 | CheckEmptyBlockBody(filename, clean_lines, linenum, error) |
|
4554 | CheckAccess(filename, clean_lines, linenum, nesting_state, error) |
|
4555 | CheckSpacing(filename, clean_lines, linenum, nesting_state, error) |
|
4556 | CheckOperatorSpacing(filename, clean_lines, linenum, error) |
|
4557 | CheckParenthesisSpacing(filename, clean_lines, linenum, error) |
|
4558 | CheckCommaSpacing(filename, clean_lines, linenum, error) |
|
4559 | CheckBracesSpacing(filename, clean_lines, linenum, nesting_state, error) |
|
4560 | CheckSpacingForFunctionCall(filename, clean_lines, linenum, error) |
|
4561 | CheckCheck(filename, clean_lines, linenum, error) |
|
4562 | CheckAltTokens(filename, clean_lines, linenum, error) |
|
4563 | classinfo = nesting_state.InnermostClass() |
|
4564 | if classinfo: |
|
4565 | CheckSectionSpacing(filename, clean_lines, classinfo, linenum, error) |
|
4566 | ||
4567 | ||
4568 | _RE_PATTERN_INCLUDE = re.compile(r'^\s*#\s*include\s*([<"])([^>"]*)[>"].*$') |
@@ 4441-4565 (lines=125) @@ | ||
4438 | return len(line) |
|
4439 | ||
4440 | ||
4441 | def CheckStyle(filename, clean_lines, linenum, file_extension, nesting_state, |
|
4442 | error): |
|
4443 | """Checks rules from the 'C++ style rules' section of cppguide.html. |
|
4444 | ||
4445 | Most of these rules are hard to test (naming, comment style), but we |
|
4446 | do what we can. In particular we check for 2-space indents, line lengths, |
|
4447 | tab usage, spaces inside code, etc. |
|
4448 | ||
4449 | Args: |
|
4450 | filename: The name of the current file. |
|
4451 | clean_lines: A CleansedLines instance containing the file. |
|
4452 | linenum: The number of the line to check. |
|
4453 | file_extension: The extension (without the dot) of the filename. |
|
4454 | nesting_state: A NestingState instance which maintains information about |
|
4455 | the current stack of nested blocks being parsed. |
|
4456 | error: The function to call with any errors found. |
|
4457 | """ |
|
4458 | ||
4459 | # Don't use "elided" lines here, otherwise we can't check commented lines. |
|
4460 | # Don't want to use "raw" either, because we don't want to check inside C++11 |
|
4461 | # raw strings, |
|
4462 | raw_lines = clean_lines.lines_without_raw_strings |
|
4463 | line = raw_lines[linenum] |
|
4464 | prev = raw_lines[linenum - 1] if linenum > 0 else '' |
|
4465 | ||
4466 | if line.find('\t') != -1: |
|
4467 | error(filename, linenum, 'whitespace/tab', 1, |
|
4468 | 'Tab found; better to use spaces') |
|
4469 | ||
4470 | # One or three blank spaces at the beginning of the line is weird; it's |
|
4471 | # hard to reconcile that with 2-space indents. |
|
4472 | # NOTE: here are the conditions rob pike used for his tests. Mine aren't |
|
4473 | # as sophisticated, but it may be worth becoming so: RLENGTH==initial_spaces |
|
4474 | # if(RLENGTH > 20) complain = 0; |
|
4475 | # if(match($0, " +(error|private|public|protected):")) complain = 0; |
|
4476 | # if(match(prev, "&& *$")) complain = 0; |
|
4477 | # if(match(prev, "\\|\\| *$")) complain = 0; |
|
4478 | # if(match(prev, "[\",=><] *$")) complain = 0; |
|
4479 | # if(match($0, " <<")) complain = 0; |
|
4480 | # if(match(prev, " +for \\(")) complain = 0; |
|
4481 | # if(prevodd && match(prevprev, " +for \\(")) complain = 0; |
|
4482 | scope_or_label_pattern = r'\s*\w+\s*:\s*\\?$' |
|
4483 | classinfo = nesting_state.InnermostClass() |
|
4484 | initial_spaces = 0 |
|
4485 | cleansed_line = clean_lines.elided[linenum] |
|
4486 | while initial_spaces < len(line) and line[initial_spaces] == ' ': |
|
4487 | initial_spaces += 1 |
|
4488 | # There are certain situations we allow one space, notably for |
|
4489 | # section labels, and also lines containing multi-line raw strings. |
|
4490 | # We also don't check for lines that look like continuation lines |
|
4491 | # (of lines ending in double quotes, commas, equals, or angle brackets) |
|
4492 | # because the rules for how to indent those are non-trivial. |
|
4493 | if (not Search(r'[",=><] *$', prev) and |
|
4494 | (initial_spaces == 1 or initial_spaces == 3) and |
|
4495 | not Match(scope_or_label_pattern, cleansed_line) and |
|
4496 | not (clean_lines.raw_lines[linenum] != line and |
|
4497 | Match(r'^\s*""', line))): |
|
4498 | error(filename, linenum, 'whitespace/indent', 3, |
|
4499 | 'Weird number of spaces at line-start. ' |
|
4500 | 'Are you using a 2-space indent?') |
|
4501 | ||
4502 | if line and line[-1].isspace(): |
|
4503 | error(filename, linenum, 'whitespace/end_of_line', 4, |
|
4504 | 'Line ends in whitespace. Consider deleting these extra spaces.') |
|
4505 | ||
4506 | # Check if the line is a header guard. |
|
4507 | is_header_guard = False |
|
4508 | if file_extension in GetHeaderExtensions(): |
|
4509 | cppvar = GetHeaderGuardCPPVariable(filename) |
|
4510 | if (line.startswith('#ifndef %s' % cppvar) or |
|
4511 | line.startswith('#define %s' % cppvar) or |
|
4512 | line.startswith('#endif // %s' % cppvar)): |
|
4513 | is_header_guard = True |
|
4514 | # #include lines and header guards can be long, since there's no clean way to |
|
4515 | # split them. |
|
4516 | # |
|
4517 | # URLs can be long too. It's possible to split these, but it makes them |
|
4518 | # harder to cut&paste. |
|
4519 | # |
|
4520 | # The "$Id:...$" comment may also get very long without it being the |
|
4521 | # developers fault. |
|
4522 | # |
|
4523 | # Doxygen documentation copying can get pretty long when using an overloaded |
|
4524 | # function declaration |
|
4525 | if (not line.startswith('#include') and not is_header_guard and |
|
4526 | not Match(r'^\s*//.*http(s?)://\S*$', line) and |
|
4527 | not Match(r'^\s*//\s*[^\s]*$', line) and |
|
4528 | not Match(r'^// \$Id:.*#[0-9]+ \$$', line) and |
|
4529 | not Match(r'^\s*/// [@\\](copydoc|copydetails|copybrief) .*$', line)): |
|
4530 | line_width = GetLineWidth(line) |
|
4531 | if line_width > _line_length: |
|
4532 | error(filename, linenum, 'whitespace/line_length', 2, |
|
4533 | 'Lines should be <= %i characters long' % _line_length) |
|
4534 | ||
4535 | if (cleansed_line.count(';') > 1 and |
|
4536 | # allow simple single line lambdas |
|
4537 | not Match(r'^[^{};]*\[[^\[\]]*\][^{}]*\{[^{}\n\r]*\}', |
|
4538 | line) and |
|
4539 | # for loops are allowed two ;'s (and may run over two lines). |
|
4540 | cleansed_line.find('for') == -1 and |
|
4541 | (GetPreviousNonBlankLine(clean_lines, linenum)[0].find('for') == -1 or |
|
4542 | GetPreviousNonBlankLine(clean_lines, linenum)[0].find(';') != -1) and |
|
4543 | # It's ok to have many commands in a switch case that fits in 1 line |
|
4544 | not ((cleansed_line.find('case ') != -1 or |
|
4545 | cleansed_line.find('default:') != -1) and |
|
4546 | cleansed_line.find('break;') != -1)): |
|
4547 | error(filename, linenum, 'whitespace/newline', 0, |
|
4548 | 'More than one command on the same line') |
|
4549 | ||
4550 | # Some more style checks |
|
4551 | CheckBraces(filename, clean_lines, linenum, error) |
|
4552 | CheckTrailingSemicolon(filename, clean_lines, linenum, error) |
|
4553 | CheckEmptyBlockBody(filename, clean_lines, linenum, error) |
|
4554 | CheckAccess(filename, clean_lines, linenum, nesting_state, error) |
|
4555 | CheckSpacing(filename, clean_lines, linenum, nesting_state, error) |
|
4556 | CheckOperatorSpacing(filename, clean_lines, linenum, error) |
|
4557 | CheckParenthesisSpacing(filename, clean_lines, linenum, error) |
|
4558 | CheckCommaSpacing(filename, clean_lines, linenum, error) |
|
4559 | CheckBracesSpacing(filename, clean_lines, linenum, nesting_state, error) |
|
4560 | CheckSpacingForFunctionCall(filename, clean_lines, linenum, error) |
|
4561 | CheckCheck(filename, clean_lines, linenum, error) |
|
4562 | CheckAltTokens(filename, clean_lines, linenum, error) |
|
4563 | classinfo = nesting_state.InnermostClass() |
|
4564 | if classinfo: |
|
4565 | CheckSectionSpacing(filename, clean_lines, classinfo, linenum, error) |
|
4566 | ||
4567 | ||
4568 | _RE_PATTERN_INCLUDE = re.compile(r'^\s*#\s*include\s*([<"])([^>"]*)[>"].*$') |