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)
| 3876 | |
| 3877 | |
| 3878 | def CheckSpacingForFunctionCall(filename, clean_lines, linenum, error): |
| 3879 | """Checks for the correctness of various spacing around function calls. |
| 3880 | |
| 3881 | Args: |
| 3882 | filename: The name of the current file. |
| 3883 | clean_lines: A CleansedLines instance containing the file. |
| 3884 | linenum: The number of the line to check. |
| 3885 | error: The function to call with any errors found. |
| 3886 | """ |
| 3887 | line = clean_lines.elided[linenum] |
| 3888 | |
| 3889 | # Since function calls often occur inside if/for/while/switch |
| 3890 | # expressions - which have their own, more liberal conventions - we |
| 3891 | # first see if we should be looking inside such an expression for a |
| 3892 | # function call, to which we can apply more strict standards. |
| 3893 | fncall = line # if there's no control flow construct, look at whole line |
| 3894 | for pattern in ( |
| 3895 | r"\bif\s*\((.*)\)\s*{", |
| 3896 | r"\bfor\s*\((.*)\)\s*{", |
| 3897 | r"\bwhile\s*\((.*)\)\s*[{;]", |
| 3898 | r"\bswitch\s*\((.*)\)\s*{", |
| 3899 | ): |
| 3900 | match = re.search(pattern, line) |
| 3901 | if match: |
| 3902 | fncall = match.group(1) # look inside the parens for function calls |
| 3903 | break |
| 3904 | |
| 3905 | # Except in if/for/while/switch, there should never be space |
| 3906 | # immediately inside parens (eg "f( 3, 4 )"). We make an exception |
| 3907 | # for nested parens ( (a+b) + c ). Likewise, there should never be |
| 3908 | # a space before a ( when it's a function argument. I assume it's a |
| 3909 | # function argument when the char before the whitespace is legal in |
| 3910 | # a function name (alnum + _) and we're not starting a macro. Also ignore |
| 3911 | # pointers and references to arrays and functions coz they're too tricky: |
| 3912 | # we use a very simple way to recognize these: |
| 3913 | # " (something)(maybe-something)" or |
| 3914 | # " (something)(maybe-something," or |
| 3915 | # " (something)[something]" |
| 3916 | # Note that we assume the contents of [] to be short enough that |
| 3917 | # they'll never need to wrap. |
| 3918 | if ( # Ignore control structures. |
| 3919 | not re.search(r"\b(if|elif|for|while|switch|return|new|delete|catch|sizeof)\b", fncall) |
| 3920 | and |
| 3921 | # Ignore pointers/references to functions. |
| 3922 | not re.search(r" \([^)]+\)\([^)]*(\)|,$)", fncall) |
| 3923 | and |
| 3924 | # Ignore pointers/references to arrays. |
| 3925 | not re.search(r" \([^)]+\)\[[^\]]+\]", fncall) |
| 3926 | ): |
| 3927 | if re.search(r"\w\s*\(\s(?!\s*\\$)", fncall): # a ( used for a fn call |
| 3928 | error(filename, linenum, "whitespace/parens", 4, "Extra space after ( in function call") |
| 3929 | elif re.search(r"\(\s+(?!(\s*\\)|\()", fncall): |
| 3930 | error(filename, linenum, "whitespace/parens", 2, "Extra space after (") |
| 3931 | if ( |
| 3932 | re.search(r"\w\s+\(", fncall) |
| 3933 | and not re.search(r"_{0,2}asm_{0,2}\s+_{0,2}volatile_{0,2}\s+\(", fncall) |
| 3934 | and not re.search(r"#\s*define|typedef|using\s+\w+\s*=", fncall) |
| 3935 | and not re.search(r"\w\s+\((\w+::)*\*\w+\)\(", fncall) |