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)
| 2842 | |
| 2843 | |
| 2844 | def CheckSpacingForFunctionCall(filename, clean_lines, linenum, error): |
| 2845 | """Checks for the correctness of various spacing around function calls. |
| 2846 | |
| 2847 | Args: |
| 2848 | filename: The name of the current file. |
| 2849 | clean_lines: A CleansedLines instance containing the file. |
| 2850 | linenum: The number of the line to check. |
| 2851 | error: The function to call with any errors found. |
| 2852 | """ |
| 2853 | line = clean_lines.elided[linenum] |
| 2854 | |
| 2855 | # Since function calls often occur inside if/for/while/switch |
| 2856 | # expressions - which have their own, more liberal conventions - we |
| 2857 | # first see if we should be looking inside such an expression for a |
| 2858 | # function call, to which we can apply more strict standards. |
| 2859 | fncall = line # if there's no control flow construct, look at whole line |
| 2860 | for pattern in (r'\bif\s*\((.*)\)\s*{', |
| 2861 | r'\bfor\s*\((.*)\)\s*{', |
| 2862 | r'\bwhile\s*\((.*)\)\s*[{;]', |
| 2863 | r'\bswitch\s*\((.*)\)\s*{'): |
| 2864 | match = Search(pattern, line) |
| 2865 | if match: |
| 2866 | fncall = match.group(1) # look inside the parens for function calls |
| 2867 | break |
| 2868 | |
| 2869 | # Except in if/for/while/switch, there should never be space |
| 2870 | # immediately inside parens (eg "f( 3, 4 )"). We make an exception |
| 2871 | # for nested parens ( (a+b) + c ). Likewise, there should never be |
| 2872 | # a space before a ( when it's a function argument. I assume it's a |
| 2873 | # function argument when the char before the whitespace is legal in |
| 2874 | # a function name (alnum + _) and we're not starting a macro. Also ignore |
| 2875 | # pointers and references to arrays and functions coz they're too tricky: |
| 2876 | # we use a very simple way to recognize these: |
| 2877 | # " (something)(maybe-something)" or |
| 2878 | # " (something)(maybe-something," or |
| 2879 | # " (something)[something]" |
| 2880 | # Note that we assume the contents of [] to be short enough that |
| 2881 | # they'll never need to wrap. |
| 2882 | if ( # Ignore control structures. |
| 2883 | not Search(r'\b(if|for|while|switch|return|new|delete|catch|sizeof)\b', |
| 2884 | fncall) and |
| 2885 | # Ignore pointers/references to functions. |
| 2886 | not Search(r' \([^)]+\)\([^)]*(\)|,$)', fncall) and |
| 2887 | # Ignore pointers/references to arrays. |
| 2888 | not Search(r' \([^)]+\)\[[^\]]+\]', fncall)): |
| 2889 | if Search(r'\w\s*\(\s(?!\s*\\$)', fncall): # a ( used for a fn call |
| 2890 | error(filename, linenum, 'whitespace/parens', 4, |
| 2891 | 'Extra space after ( in function call') |
| 2892 | elif Search(r'\(\s+(?!(\s*\\)|\()', fncall): |
| 2893 | error(filename, linenum, 'whitespace/parens', 2, |
| 2894 | 'Extra space after (') |
| 2895 | if (Search(r'\w\s+\(', fncall) and |
| 2896 | not Search(r'_{0,2}asm_{0,2}\s+_{0,2}volatile_{0,2}\s+\(', fncall) and |
| 2897 | not Search(r'#\s*define|typedef|using\s+\w+\s*=', fncall) and |
| 2898 | not Search(r'\w\s+\((\w+::)*\*\w+\)\(', fncall) and |
| 2899 | not Search(r'\bcase\s+\(', fncall)): |
| 2900 | # TODO(unknown): Space after an operator function seem to be a common |
| 2901 | # error, silence those for now by restricting them to highest verbosity. |
no test coverage detected