diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 9eed3683ad76ca..0e7684d2f0cf30 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -77,6 +77,8 @@ my %maybe_linker_symbol; # for externs in c exceptions, when seen in *vmlinux.lds.h +my $pending_log = undef; + sub help { my ($exitcode) = @_; @@ -3888,6 +3890,91 @@ sub process { } } +# check for pr_* and dev_* logs without a newline for C and Rust files to avoid missing log messages + my $pr_cont_pattern = qr{ + \b + pr_cont!? + \s* + \( + \s* + "([^"]*)" + [^)]* + \) + }x; + my $log_macro_pattern = qr{ + \b + ( + pr_(?:emerg|alert|crit|err|warn|notice|info|debug) + | dev_(?:emerg|alert|crit|err|warn|notice|info|dbg) + ) + (!?) + \s* + \( + \s* + "([^"]*)" + }x; + + if ($realfile =~ /\.(?:c|h|rs)$/) { + if ($rawline =~ /^\+/) { + my $cleanline = $rawline; + $cleanline =~ s/^[+\s]+//; + $cleanline =~ s/\r?$//; + $cleanline =~ s{/\*.*?\*/}{}g; + $cleanline =~ s{//.*}{}g; + + if ($pending_log) { + if ($cleanline =~ /$pr_cont_pattern/) { + my $cont_string_arg = $1; + if ($cont_string_arg =~ /\\n$/) { + $pending_log = undef; + } + } elsif ($cleanline =~ /$log_macro_pattern/) { + WARN($pending_log->{lang} . "_LOG_NO_NEWLINE", + "Possible usage of $pending_log->{macro_call} without a trailing newline.\n" . + $pending_log->{herecurr}); + + $pending_log = undef; + + my $macro_call = $1; + my $maybe_excl = $2; + my $string_arg = $3; + $string_arg =~ s/\s+$//; + + if ($realfile =~ /\.rs$/ && $maybe_excl ne '!') { + return; + } + + if ($string_arg !~ /\\n$/ && $string_arg !~ /\n$/) { + $pending_log = { + macro_call => $macro_call, + herecurr => $herecurr, + lang => ($realfile =~ /\.rs$/) ? "Rust" : "C", + }; + } + } + } else { + if ($cleanline =~ /$log_macro_pattern/) { + my $macro_call = $1; + my $maybe_excl = $2; + my $string_arg = $3; + $string_arg =~ s/\s+$//; + + if ($realfile =~ /\.rs$/ && $maybe_excl ne '!') { + return; + } + + if ($string_arg !~ /\\n$/ && $string_arg !~ /\n$/) { + $pending_log = { + macro_call => $macro_call, + herecurr => $herecurr, + lang => ($realfile =~ /\.rs$/) ? "Rust" : "C", + }; + } + } + } + } + } + # check for .L prefix local symbols in .S files if ($realfile =~ /\.S$/ && $line =~ /^\+\s*(?:[A-Z]+_)?SYM_[A-Z]+_(?:START|END)(?:_[A-Z_]+)?\s*\(\s*\.L/) { @@ -7678,6 +7765,15 @@ sub process { } } +# pending log means a pr_* without an ending newline has not +# been followed by a pr_cont call with a newline at the end + if ($pending_log) { + WARN($pending_log->{lang} . "_LOG_NO_NEWLINE", + "Usage of $pending_log->{macro_call} without a trailing newline.\n" . + $pending_log->{herecurr}); + $pending_log = undef; + } + # If we have no input at all, then there is nothing to report on # so just keep quiet. if ($#rawlines == -1) {