123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- #!/bin/sh
- # Checks some of the GNU style formatting rules in a set of patches.
- # Copyright (C) 2010, 2012, 2016 Free Software Foundation, Inc.
- # Contributed by Sebastian Pop <sebastian.pop@amd.com>
- # This program is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation; either version 3 of the License, or
- # (at your option) any later version.
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- # You should have received a copy of the GNU General Public License
- # along with this program; if not, see the file COPYING3. If not,
- # see <http://www.gnu.org/licenses/>.
- # Set to empty in the environment to override.
- : ${color:---color=always}
- usage() {
- cat <<EOF
- check_GNU_style.sh [patch]...
- Checks the patches for some of the GNU style formatting problems.
- When FILE is -, read standard input.
- Please note that these checks are not always accurate, and
- complete. The reference documentation of the GNU Coding Standards
- can be found here: http://www.gnu.org/prep/standards_toc.html
- and there are also some additional coding conventions for GCC:
- http://gcc.gnu.org/codingconventions.html
- EOF
- exit 1
- }
- test $# -eq 0 && usage
- nfiles=$#
- files="$*"
- stdin=false
- stdin_tmp=""
- if [ $nfiles -eq 1 ] && [ "$files" = "-" ]; then
- stdin=true
- # By putting stdin into a temp file, we can handle it just like any other
- # file. F.i., we can cat it twice, which we can't do with stdin.
- stdin_tmp=check_GNU_style.stdin
- cat - > $stdin_tmp
- files=$stdin_tmp
- else
- for f in $files; do
- if [ "$f" = "-" ]; then
- # Let's keep things simple. Either we read from stdin, or we read
- # from files specified on the command line, not both.
- usage
- fi
- if [ ! -f "$f" ]; then
- echo "error: could not read file: $f"
- exit 1
- fi
- done
- fi
- inp=check_GNU_style.inp
- tmp=check_GNU_style.tmp
- tmp2=check_GNU_style.2.tmp
- tmp3=check_GNU_style.3.tmp
- # Remove $tmp on exit and various signals.
- trap "rm -f $inp $tmp $tmp2 $tmp3 $stdin_tmp" 0
- trap "rm -f $inp $tmp $tmp2 $tmp3 $stdin_tmp; exit 1" 1 2 3 5 9 13 15
- if [ $nfiles -eq 1 ]; then
- # There's no need for the file prefix if we're dealing only with one file.
- format="-n"
- else
- format="-nH"
- fi
- # Remove the testsuite part of the diff. We don't care about GNU style
- # in testcases and the dg-* directives give too many false positives.
- remove_testsuite ()
- {
- awk 'BEGIN{testsuite=0} /^(.*:)?([1-9][0-9]*:)?\+\+\+ / && ! /testsuite\//{testsuite=0} \
- {if (!testsuite) print} /^(.*:)?([1-9][0-9]*:)?\+\+\+ (.*\/)?testsuite\//{testsuite=1}'
- }
- grep $format '^+' $files \
- | remove_testsuite \
- | grep -v ':+++' \
- > $inp
- cat_with_prefix ()
- {
- local f="$1"
- if [ "$prefix" = "" ]; then
- cat "$f"
- else
- awk "{printf \"%s%s\n\", \"$prefix\", \$0}" $f
- fi
- }
- # Grep
- g (){
- local msg="$1"
- local arg="$2"
- local found=false
- cat $inp \
- | egrep $color -- "$arg" \
- > "$tmp" && found=true
- if $found; then
- printf "\n$msg\n"
- cat "$tmp"
- fi
- }
- # And Grep
- ag (){
- local msg="$1"
- local arg1="$2"
- local arg2="$3"
- local found=false
- cat $inp \
- | egrep $color -- "$arg1" \
- | egrep $color -- "$arg2" \
- > "$tmp" && found=true
- if $found; then
- printf "\n$msg\n"
- cat "$tmp"
- fi
- }
- # reVerse Grep
- vg (){
- local msg="$1"
- local varg="$2"
- local arg="$3"
- local found=false
- cat $inp \
- | egrep -v -- "$varg" \
- | egrep $color -- "$arg" \
- > "$tmp" && found=true
- if $found; then
- printf "\n$msg\n"
- cat "$tmp"
- fi
- }
- col (){
- local msg="$1"
- local first=true
- local f
- for f in $files; do
- prefix=""
- if [ $nfiles -ne 1 ]; then
- prefix="$f:"
- fi
- # Don't reuse $inp, which may be generated using -H and thus contain a
- # file prefix. Re-remove the testsuite since we're not using $inp.
- cat $f | remove_testsuite \
- | grep -n '^+' \
- | grep -v ':+++' \
- > $tmp
- # Keep only line number prefix and patch modifier '+'.
- cat "$tmp" \
- | sed 's/\(^[0-9][0-9]*:+\).*/\1/' \
- > "$tmp2"
- # Remove line number prefix and patch modifier '+'.
- # Expand tabs to spaces according to tab positions.
- # Keep long lines, make short lines empty. Print the part past 80 chars
- # in red.
- cat "$tmp" \
- | sed 's/^[0-9]*:+//' \
- | expand \
- | awk '{ \
- if (length($0) > 80) \
- printf "%s\033[1;31m%s\033[0m\n", \
- substr($0,1,80), \
- substr($0,81); \
- else \
- print "" \
- }' \
- > "$tmp3"
- # Combine prefix back with long lines.
- # Filter out empty lines.
- local found=false
- paste -d '\0' "$tmp2" "$tmp3" \
- | grep -v '^[0-9][0-9]*:+$' \
- > "$tmp" && found=true
- if $found; then
- if $first; then
- printf "\n$msg\n"
- first=false
- fi
- cat_with_prefix "$tmp"
- fi
- done
- }
- col 'Lines should not exceed 80 characters.'
- g 'Blocks of 8 spaces should be replaced with tabs.' \
- ' {8}'
- g 'Trailing whitespace.' \
- '[[:space:]]$'
- g 'Space before dot.' \
- '[[:alnum:]][[:blank:]]+\.'
- g 'Dot, space, space, new sentence.' \
- '[[:alnum:]]\.([[:blank:]]|[[:blank:]]{3,})[A-Z0-9]'
- g 'Dot, space, space, end of comment.' \
- '[[:alnum:]]\.([[:blank:]]{0,1}|[[:blank:]]{3,})\*/'
- g 'Sentences should end with a dot. Dot, space, space, end of the comment.' \
- '[[:alnum:]][[:blank:]]*\*/'
- vg 'There should be exactly one space between function name and parenthesis.' \
- '\#define' \
- '[[:alnum:]]([[:blank:]]{2,})?\('
- g 'There should be no space before a left square bracket.' \
- '[[:alnum:]][[:blank:]]+\['
- g 'There should be no space before closing parenthesis.' \
- '[[:graph:]][[:blank:]]+\)'
- # This will give false positives for C99 compound literals.
- g 'Braces should be on a separate line.' \
- '(\)|else)[[:blank:]]*{'
- # Does this apply to definitions of aggregate objects?
- ag 'Trailing operator.' \
- '^[1-9][0-9]*:\+[[:space:]]' \
- '(([^a-zA-Z_]\*)|([-%<=&|^?])|([^*]/)|([^:][+]))$'
|