Checks for the correctness of various spacing around function calls. Args: filename: The name of the current file. clean_lines: A CleansedLines instance containing the file. linenum: The number of the line to check. error: The function to call with any errors found.
(filename, clean_lines, linenum, error)
| 3448 | |
| 3449 | |
| 3450 | def CheckSpacingForFunctionCall(filename, clean_lines, linenum, error): |
| 3451 | """Checks for the correctness of various spacing around function calls. |
| 3452 | |
| 3453 | Args: |
| 3454 | filename: The name of the current file. |
| 3455 | clean_lines: A CleansedLines instance containing the file. |
| 3456 | linenum: The number of the line to check. |
| 3457 | error: The function to call with any errors found. |
| 3458 | """ |
| 3459 | line = clean_lines.elided[linenum] |
| 3460 | |
| 3461 | # Since function calls often occur inside if/for/while/switch |
| 3462 | # expressions - which have their own, more liberal conventions - we |
| 3463 | # first see if we should be looking inside such an expression for a |
| 3464 | # function call, to which we can apply more strict standards. |
| 3465 | fncall = line # if there's no control flow construct, look at whole line |
| 3466 | for pattern in (r'\bif\s*\((.*)\)\s*{', |
| 3467 | r'\bfor\s*\((.*)\)\s*{', |
| 3468 | r'\bwhile\s*\((.*)\)\s*[{;]', |
| 3469 | r'\bswitch\s*\((.*)\)\s*{'): |
| 3470 | match = Search(pattern, line) |
| 3471 | if match: |
| 3472 | fncall = match.group(1) # look inside the parens for function calls |
| 3473 | break |
| 3474 | |
| 3475 | # Except in if/for/while/switch, there should never be space |
| 3476 | # immediately inside parens (eg "f( 3, 4 )"). We make an exception |
| 3477 | # for nested parens ( (a+b) + c ). Likewise, there should never be |
| 3478 | # a space before a ( when it's a function argument. I assume it's a |
| 3479 | # function argument when the char before the whitespace is legal in |
| 3480 | # a function name (alnum + _) and we're not starting a macro. Also ignore |
| 3481 | # pointers and references to arrays and functions coz they're too tricky: |
| 3482 | # we use a very simple way to recognize these: |
| 3483 | # " (something)(maybe-something)" or |
| 3484 | # " (something)(maybe-something," or |
| 3485 | # " (something)[something]" |
| 3486 | # Note that we assume the contents of [] to be short enough that |
| 3487 | # they'll never need to wrap. |
| 3488 | if ( # Ignore control structures. |
| 3489 | not Search(r'\b(if|for|while|switch|return|new|delete|catch|sizeof)\b', |
| 3490 | fncall) and |
| 3491 | # Ignore pointers/references to functions. |
| 3492 | not Search(r' \([^)]+\)\([^)]*(\)|,$)', fncall) and |
| 3493 | # Ignore pointers/references to arrays. |
| 3494 | not Search(r' \([^)]+\)\[[^\]]+\]', fncall)): |
| 3495 | if Search(r'\w\s*\(\s(?!\s*\\$)', fncall): # a ( used for a fn call |
| 3496 | error(filename, linenum, 'whitespace/parens', 4, |
| 3497 | 'Extra space after ( in function call') |
| 3498 | elif Search(r'\(\s+(?!(\s*\\)|\()', fncall): |
| 3499 | error(filename, linenum, 'whitespace/parens', 2, |
| 3500 | 'Extra space after (') |
| 3501 | if (Search(r'\w\s+\(', fncall) and |
| 3502 | not Search(r'_{0,2}asm_{0,2}\s+_{0,2}volatile_{0,2}\s+\(', fncall) and |
| 3503 | not Search(r'#\s*define|typedef|using\s+\w+\s*=', fncall) and |
| 3504 | not Search(r'\w\s+\((\w+::)*\*\w+\)\(', fncall) and |
| 3505 | not Search(r'\bcase\s+\(', fncall)): |
| 3506 | # TODO(unknown): Space after an operator function seem to be a common |
| 3507 | # error, silence those for now by restricting them to highest verbosity. |