[libvirt] [PATCH 0/2] syntax-check: revert expensive cosmetic checks

Also do not bother taking C++ style comments into account. Ján Tomko (2): syntax-check: revert indentation checks check-spacing: do not kill C++-style comments build-aux/check-spacing.pl | 459 ++++++++++++++------------------------------- src/libvirt.c | 4 +- 2 files changed, 142 insertions(+), 321 deletions(-) -- 2.16.4

Recent patches added indentation checks that discovered some cosmetic issues at the cost of making this check last as long as the rest of syntax-check combined on my system. Also, they're moving closer to us implementing yet another C parser (docs/apibuild.py being the other one). Revert the following commits: commit 11e1f11dd34f2688169c63c13ea8d99a64724369 syntax-check: Check for incorrect indentation in function body commit 2585a79e32e8b0d994ab35fd7c641eb9b96632e3 build-aux:check-spacing: Introduce a new rule to check misaligned stuff in parenthesises commit a033182f042a07ffbd4b9a50418670778ceddbf3 build-aux:check-spacing: Add wrapper function of CheckCurlyBrackets commit 6225626b6f0a4817d1f17de0bc5200c5d7986a3e build-aux:check-spacing: Add wrapper function of CheckWhiteSpaces commit c3875129d9bd094ffe90d54fbec86624ae88c40b build-aux:check-spacing: Add wrapper function of KillComments commit e995904c5691be3c21f4c6dbc1f067fe0c8e8515 build-aux:check-spacing: Add wrapper function of CheckFunctionBody commit 11e1f11dd34f2688169c63c13ea8d99a64724369 syntax-check: Check for incorrect indentation in function body This brings the speed of the script to a tolerable level and lets it focus on the more visible issues. Signed-off-by: Ján Tomko <jtomko@redhat.com> --- build-aux/check-spacing.pl | 460 ++++++++++++++------------------------------- 1 file changed, 142 insertions(+), 318 deletions(-) diff --git a/build-aux/check-spacing.pl b/build-aux/check-spacing.pl index d36b004abf..ca8b434916 100755 --- a/build-aux/check-spacing.pl +++ b/build-aux/check-spacing.pl @@ -23,356 +23,180 @@ use strict; use warnings; -# -# CheckFunctionBody: -# $_[0]: $data(in) -# $_[1]: $location(in), which format is file-path:line-num:line-code -# $_[2]: $fn_linenum(inout), maintains start line-num of function body -# Returns 0 in case of success or 1 on failure -# -# Check incorrect indentation and blank first line in function body. -# For efficiency, it only checks the first line of function body. -# But it's enough for most cases. -# (It could be better that we use *state* to declare @fn_linenum and -# move it into this subroutine. But *state* requires version >= v5.10.) -# -sub CheckFunctionBody { - my $ret = 0; - my ($data, $location, $fn_linenum) = @_; +my $ret = 0; +my $incomment = 0; - # Check first line of function block - if ($$fn_linenum) { - if ($$data =~ /^\s*$/) { - print "Blank line before content in function body:\n$$location"; - $ret = 1; - } elsif ($$data !~ /^[ ]{4}\S/) { - unless ($$data =~ /^[ ]\w+:$/ || $$data =~ /^}/) { - print "Incorrect indentation in function body:\n$$location"; - $ret = 1; - } - } - $$fn_linenum = 0; - } +foreach my $file (@ARGV) { + # Per-file variables for multiline Curly Bracket (cb_) check + my $cb_linenum = 0; + my $cb_code = ""; + my $cb_scolon = 0; - # Detect start of function block - if ($$data =~ /^{$/) { - $$fn_linenum = $.; - } + open FILE, $file; - return $ret; -} + while (defined (my $line = <FILE>)) { + my $data = $line; + # For temporary modifications + my $tmpdata; -# -# KillComments: -# $_[0]: $data(inout) -# $_[1]: $incomment(inout) -# -# Remove all content of comments -# (Also, the @incomment could be declared with *state* and move it in.) -# -sub KillComments { - my ($data, $incomment) = @_; + # Kill any quoted , ; = or " + $data =~ s/'[";,=]'/'X'/g; - # Kill contents of multi-line comments - # and detect end of multi-line comments - if ($$incomment) { - if ($$data =~ m,\*/,) { - $$incomment = 0; - $$data =~ s,^.*\*/,*/,; - } else { - $$data = ""; - } - } + # Kill any quoted strings + $data =~ s,"(?:[^\\\"]|\\.)*","XXX",g; - # Kill single line comments, and detect - # start of multi-line comments - if ($$data =~ m,/\*.*\*/,) { - $$data =~ s,/\*.*\*/,/* */,; - } elsif ($$data =~ m,/\*,) { - $$incomment = 1; - $$data =~ s,/\*.*,/*,; - } + # Kill any C++ style comments + $data =~ s,//.*$,//,; - return; -} + next if $data =~ /^#/; -# -# CheckWhiteSpaces: -# $_[0]: $data(in) -# $_[1]: $location(in), which format is file-path:line-num:line-code -# Returns 0 in case of success or 1 on failure -# -# Check whitespaces according to code spec of libvirt. -# -sub CheckWhiteSpaces { - my $ret = 0; - my ($data, $location) = @_; + # Kill contents of multi-line comments + # and detect end of multi-line comments + if ($incomment) { + if ($data =~ m,\*/,) { + $incomment = 0; + $data =~ s,^.*\*/,*/,; + } else { + $data = ""; + } + } - # We need to match things like - # - # int foo (int bar, bool wizz); - # foo (bar, wizz); - # - # but not match things like: - # - # typedef int (*foo)(bar wizz) - # - # we can't do this (efficiently) without - # missing things like - # - # foo (*bar, wizz); - # - # We also don't want to spoil the $data so it can be used - # later on. + # Kill single line comments, and detect + # start of multi-line comments + if ($data =~ m,/\*.*\*/,) { + $data =~ s,/\*.*\*/,/* */,; + } elsif ($data =~ m,/\*,) { + $incomment = 1; + $data =~ s,/\*.*,/*,; + } - # For temporary modifications - my $tmpdata = $$data; - while ($tmpdata =~ /(\w+)\s\((?!\*)/) { - my $kw = $1; + # We need to match things like + # + # int foo (int bar, bool wizz); + # foo (bar, wizz); + # + # but not match things like: + # + # typedef int (*foo)(bar wizz) + # + # we can't do this (efficiently) without + # missing things like + # + # foo (*bar, wizz); + # + # We also don't want to spoil the $data so it can be used + # later on. + $tmpdata = $data; + while ($tmpdata =~ /(\w+)\s\((?!\*)/) { + my $kw = $1; + + # Allow space after keywords only + if ($kw =~ /^(?:if|for|while|switch|return)$/) { + $tmpdata =~ s/(?:$kw\s\()/XXX(/; + } else { + print "Whitespace after non-keyword:\n"; + print "$file:$.: $line"; + $ret = 1; + last; + } + } - # Allow space after keywords only - if ($kw =~ /^(?:if|for|while|switch|return)$/) { - $tmpdata =~ s/(?:$kw\s\()/XXX(/; - } else { - print "Whitespace after non-keyword:\n$$location"; + # Require whitespace immediately after keywords + if ($data =~ /\b(?:if|for|while|switch|return)\(/) { + print "No whitespace after keyword:\n"; + print "$file:$.: $line"; $ret = 1; - last; } - } - # Require whitespace immediately after keywords - if ($$data =~ /\b(?:if|for|while|switch|return)\(/) { - print "No whitespace after keyword:\n$$location"; - $ret = 1; - } - - # Forbid whitespace between )( of a function typedef - if ($$data =~ /\(\*\w+\)\s+\(/) { - print "Whitespace between ')' and '(':\n$$location"; - $ret = 1; - } - - # Forbid whitespace following ( or prior to ) - # but allow whitespace before ) on a single line - # (optionally followed by a semicolon) - if (($$data =~ /\s\)/ && not $$data =~ /^\s+\);?$/) || - $$data =~ /\((?!$)\s/) { - print "Whitespace after '(' or before ')':\n$$location"; - $ret = 1; - } - - # Forbid whitespace before ";" or ",". Things like below are allowed: - # - # 1) The expression is empty for "for" loop. E.g. - # for (i = 0; ; i++) - # - # 2) An empty statement. E.g. - # while (write(statuswrite, &status, 1) == -1 && - # errno == EINTR) - # ; - # - if ($$data =~ /\s[;,]/) { - unless ($$data =~ /\S; ; / || - $$data =~ /^\s+;/) { - print "Whitespace before semicolon or comma:\n$$location"; + # Forbid whitespace between )( of a function typedef + if ($data =~ /\(\*\w+\)\s+\(/) { + print "Whitespace between ')' and '(':\n"; + print "$file:$.: $line"; $ret = 1; } - } - - # Require EOL, macro line continuation, or whitespace after ";". - # Allow "for (;;)" as an exception. - if ($$data =~ /;[^ \\\n;)]/) { - print "Invalid character after semicolon:\n$$location"; - $ret = 1; - } - - # Require EOL, space, or enum/struct end after comma. - if ($$data =~ /,[^ \\\n)}]/) { - print "Invalid character after comma:\n$$location"; - $ret = 1; - } - - # Require spaces around assignment '=', compounds and '==' - if ($$data =~ /[^ ]\b[!<>&|\-+*\/%\^=]?=/ || - $$data =~ /=[^= \\\n]/) { - print "Spacing around '=' or '==':\n$$location"; - $ret = 1; - } - - return $ret; -} -# -# CheckCurlyBrackets: -# $_[0]: $data(in) -# $_[1]: $file(in) -# $_[2]: $line(in) -# $_[3]: $cb_linenum(inout) -# $_[4]: $cb_code(inout) -# $_[5]: $cb_scolon(inout) -# Returns 0 in case of success or 1 on failure -# -# Check whitespaces according to code spec of libvirt. -# -sub CheckCurlyBrackets { - my $ret = 0; - my ($data, $file, $line, $cb_linenum, $cb_code, $cb_scolon) = @_; - - # One line conditional statements with one line bodies should - # not use curly brackets. - if ($$data =~ /^\s*(if|while|for)\b.*\{$/) { - $$cb_linenum = $.; - $$cb_code = $$line; - $$cb_scolon = 0; - } - - # We need to check for exactly one semicolon inside the body, - # because empty statements (e.g. with comment only) are - # allowed - if ($$cb_linenum == $. - 1 && $$data =~ /^[^;]*;[^;]*$/) { - $$cb_code .= $$line; - $$cb_scolon = 1; - } - - if ($$data =~ /^\s*}\s*$/ && - $$cb_linenum == $. - 2 && - $$cb_scolon) { - - print "Curly brackets around single-line body:\n"; - print "$$file:$$cb_linenum-$.:\n$$cb_code$$line"; - $ret = 1; - - # There _should_ be no need to reset the values; but to - # keep my inner peace... - $$cb_linenum = 0; - $$cb_scolon = 0; - $$cb_code = ""; - } - - return $ret; -} - -# -# CheckMisalignment: -# $_[0]: $data(in) -# $_[1]: $file(in) -# $_[2]: $line(in) -# $_[3]: @paren_stack(inout), which maintains information -# of the parenthesis -# Returns 0 in case of success or 1 on failure -# -# Check misaligned stuff in parenthesis: -# 1. For misaligned arguments of function -# 2. For misaligned conditions of [if|while|switch|...] -# -sub CheckMisalignment { - my $ret = 0; - my ($data, $file, $line, $paren_stack) = @_; - - # Check alignment based on @paren_stack - if (@$paren_stack) { - if ($$data =~ /(\S+.*$)/) { - my $pos = $$paren_stack[-1][0]; - my $linenum = $$paren_stack[-1][1]; - my $code = $$paren_stack[-1][2]; - if ($pos + 1 != length($`)) { - my $pad = ""; - if ($. > $linenum + 1) { - $pad = " " x $pos . " ...\n"; - } - print "Misaligned line in parenthesis:\n"; - print "$$file:$linenum-$.:\n$code$pad$$line\n"; - $ret = 1; - } + # Forbid whitespace following ( or prior to ) + # but allow whitespace before ) on a single line + # (optionally followed by a semicolon) + if (($data =~ /\s\)/ && not $data =~ /^\s+\);?$/) || + $data =~ /\((?!$)\s/) { + print "Whitespace after '(' or before ')':\n"; + print "$file:$.: $line"; + $ret = 1; } - } - # Maintain @paren_stack - if ($$data =~ /.*[()]/) { - my $pos = 0; - my $temp = $$data; - - # Kill the content between matched parenthesis and themselves - # within the current line. - $temp =~ s,(\((?:[^()]++|(?R))*+\)),"X" x (length $&),ge; - - # Pop a item for the open-paren when finding close-paren - while (($pos = index($temp, "\)", $pos)) >= 0) { - if (@$paren_stack) { - pop(@$paren_stack); - $pos++; - } else { - print "Warning: found unbalanced parenthesis:\n"; - print "$$file:$.:\n$$line\n"; + # Forbid whitespace before ";" or ",". Things like below are allowed: + # + # 1) The expression is empty for "for" loop. E.g. + # for (i = 0; ; i++) + # + # 2) An empty statement. E.g. + # while (write(statuswrite, &status, 1) == -1 && + # errno == EINTR) + # ; + # + if ($data =~ /\s[;,]/) { + unless ($data =~ /\S; ; / || + $data =~ /^\s+;/) { + print "Whitespace before semicolon or comma:\n"; + print "$file:$.: $line"; $ret = 1; - last; } } - # Push the item for open-paren on @paren_stack - # @item = [ position of the open-paren, linenum, code-line ] - while (($pos = index($temp, "\(", $pos)) >= 0) { - push @$paren_stack, [$pos, $., $$line]; - $pos++; + # Require EOL, macro line continuation, or whitespace after ";". + # Allow "for (;;)" as an exception. + if ($data =~ /;[^ \\\n;)]/) { + print "Invalid character after semicolon:\n"; + print "$file:$.: $line"; + $ret = 1; } - } - return $ret; -} - -my $ret = 0; - -foreach my $file (@ARGV) { - # Per-file variables for multiline Curly Bracket (cb_) check - my $cb_linenum = 0; - my $cb_code = ""; - my $cb_scolon = 0; - my $fn_linenum = 0; - my $incomment = 0; - my @paren_stack; - - open FILE, $file; - - while (defined (my $line = <FILE>)) { - my $has_define = 0; - my $data = $line; - my $location = "$file:$.:\n$line"; - - # Kill any quoted , ; = or " - $data =~ s/'[";,=]'/'X'/g; - - # Kill any quoted strings. Replace with equal-length "XXXX..." - $data =~ s,"(([^\\\"]|\\.)*)","\"".'X'x(length $1)."\"",ge; - $data =~ s,'(([^\\\']|\\.)*)',"\'".'X'x(length $1)."\'",ge; + # Require EOL, space, or enum/struct end after comma. + if ($data =~ /,[^ \\\n)}]/) { + print "Invalid character after comma:\n"; + print "$file:$.: $line"; + $ret = 1; + } - # Kill any C++ style comments - $data =~ s,//.*$,//,; + # Require spaces around assignment '=', compounds and '==' + if ($data =~ /[^ ]\b[!<>&|\-+*\/%\^=]?=/ || + $data =~ /=[^= \\\n]/) { + print "Spacing around '=' or '==':\n"; + print "$file:$.: $line"; + $ret = 1; + } - $has_define = 1 if $data =~ /(?:^#\s*define\b)/; - if (not $has_define) { - # Ignore all macros except for #define - next if $data =~ /^#/; + # One line conditional statements with one line bodies should + # not use curly brackets. + if ($data =~ /^\s*(if|while|for)\b.*\{$/) { + $cb_linenum = $.; + $cb_code = $line; + $cb_scolon = 0; + } - $ret = 1 if CheckFunctionBody(\$data, \$location, \$fn_linenum); + # We need to check for exactly one semicolon inside the body, + # because empty statements (e.g. with comment only) are + # allowed + if ($cb_linenum == $. - 1 && $data =~ /^[^;]*;[^;]*$/) { + $cb_code .= $line; + $cb_scolon = 1; + } - KillComments(\$data, \$incomment); + if ($data =~ /^\s*}\s*$/ && + $cb_linenum == $. - 2 && + $cb_scolon) { - $ret = 1 if CheckWhiteSpaces(\$data, \$location); + print "Curly brackets around single-line body:\n"; + print "$file:$cb_linenum-$.:\n$cb_code$line"; + $ret = 1; - $ret = 1 if CheckCurlyBrackets(\$data, \$file, \$line, - \$cb_linenum, \$cb_code, \$cb_scolon); + # There _should_ be no need to reset the values; but to + # keep my inner peace... + $cb_linenum = 0; + $cb_scolon = 0; + $cb_code = ""; } - - ##################################################################### - # Temporary Filter for CheckMisalignment: - # Here we introduce a white-list of path, since there're - # too much misalignment. - # We _need_ fix these misalignment in batches. - # We _should_ remove it as soon as fixing all. - ##################################################################### - next unless $file =~ /^src\/util\//; - - $ret = 1 if CheckMisalignment(\$data, \$file, \$line, \@paren_stack); } close FILE; } -- 2.16.4

On Fri, Oct 05, 2018 at 01:48:06PM +0200, Ján Tomko wrote:
Recent patches added indentation checks that discovered some cosmetic issues at the cost of making this check last as long as the rest of syntax-check combined on my system. Also, they're moving closer to us implementing yet another C parser (docs/apibuild.py being the other one).
Revert the following commits: commit 11e1f11dd34f2688169c63c13ea8d99a64724369 syntax-check: Check for incorrect indentation in function body commit 2585a79e32e8b0d994ab35fd7c641eb9b96632e3 build-aux:check-spacing: Introduce a new rule to check misaligned stuff in parenthesises commit a033182f042a07ffbd4b9a50418670778ceddbf3 build-aux:check-spacing: Add wrapper function of CheckCurlyBrackets commit 6225626b6f0a4817d1f17de0bc5200c5d7986a3e build-aux:check-spacing: Add wrapper function of CheckWhiteSpaces commit c3875129d9bd094ffe90d54fbec86624ae88c40b build-aux:check-spacing: Add wrapper function of KillComments commit e995904c5691be3c21f4c6dbc1f067fe0c8e8515 build-aux:check-spacing: Add wrapper function of CheckFunctionBody commit 11e1f11dd34f2688169c63c13ea8d99a64724369 syntax-check: Check for incorrect indentation in function body
This brings the speed of the script to a tolerable level and lets it focus on the more visible issues.
Signed-off-by: Ján Tomko <jtomko@redhat.com> Reviewed-by: Erik Skultety <eskultet@redhat.com>

On 10/19/2018 10:03 AM, Erik Skultety wrote:
On Fri, Oct 05, 2018 at 01:48:06PM +0200, Ján Tomko wrote:
Recent patches added indentation checks that discovered some cosmetic issues at the cost of making this check last as long as the rest of syntax-check combined on my system. Also, they're moving closer to us implementing yet another C parser (docs/apibuild.py being the other one).
Revert the following commits: commit 11e1f11dd34f2688169c63c13ea8d99a64724369 syntax-check: Check for incorrect indentation in function body commit 2585a79e32e8b0d994ab35fd7c641eb9b96632e3 build-aux:check-spacing: Introduce a new rule to check misaligned stuff in parenthesises commit a033182f042a07ffbd4b9a50418670778ceddbf3 build-aux:check-spacing: Add wrapper function of CheckCurlyBrackets commit 6225626b6f0a4817d1f17de0bc5200c5d7986a3e build-aux:check-spacing: Add wrapper function of CheckWhiteSpaces commit c3875129d9bd094ffe90d54fbec86624ae88c40b build-aux:check-spacing: Add wrapper function of KillComments commit e995904c5691be3c21f4c6dbc1f067fe0c8e8515 build-aux:check-spacing: Add wrapper function of CheckFunctionBody commit 11e1f11dd34f2688169c63c13ea8d99a64724369 syntax-check: Check for incorrect indentation in function body
This brings the speed of the script to a tolerable level and lets it focus on the more visible issues.
Signed-off-by: Ján Tomko <jtomko@redhat.com> Reviewed-by: Erik Skultety <eskultet@redhat.com>
So what alternative do we have? Obviously, we fail at honoring our formatting rules. Having a check that would fail at `synax-check' time would help us. Okay, implementing new C parser might not be the best solution, but it's at least something. Michal

Our HACKING guide forbids these. There's no point in exempting these from the spacing check if their existence is against our coding style. Note that the non-usage of these comments itself is not enforced by syntax check, probably because of the need to implement a C parser. Signed-off-by: Ján Tomko <jtomko@redhat.com> --- build-aux/check-spacing.pl | 3 --- src/libvirt.c | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/build-aux/check-spacing.pl b/build-aux/check-spacing.pl index ca8b434916..a32e355be6 100755 --- a/build-aux/check-spacing.pl +++ b/build-aux/check-spacing.pl @@ -45,9 +45,6 @@ foreach my $file (@ARGV) { # Kill any quoted strings $data =~ s,"(?:[^\\\"]|\\.)*","XXX",g; - # Kill any C++ style comments - $data =~ s,//.*$,//,; - next if $data =~ /^#/; # Kill contents of multi-line comments diff --git a/src/libvirt.c b/src/libvirt.c index 0a738aefb1..7c379495ad 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -230,8 +230,8 @@ virWinsockInit(void) WSADATA winsock_data; /* http://msdn2.microsoft.com/en-us/library/ms742213.aspx */ - winsock_version = MAKEWORD (2, 2); - err = WSAStartup (winsock_version, &winsock_data); + winsock_version = MAKEWORD(2, 2); + err = WSAStartup(winsock_version, &winsock_data); return err == 0 ? 0 : -1; } #endif -- 2.16.4

On Fri, Oct 05, 2018 at 01:48:05PM +0200, Ján Tomko wrote:
Also do not bother taking C++ style comments into account.
Ján Tomko (2): syntax-check: revert indentation checks check-spacing: do not kill C++-style comments
Reviewed-by: Erik Skultety <eskultet@redhat.com>
participants (3)
-
Erik Skultety
-
Ján Tomko
-
Michal Prívozník