1#!/bin/sh 2 3# Checks some of the GNU style formatting rules in a set of patches. 4# Copyright (C) 2010, 2012, 2016 Free Software Foundation, Inc. 5# Contributed by Sebastian Pop <sebastian.pop@amd.com> 6 7# This program is free software; you can redistribute it and/or modify 8# it under the terms of the GNU General Public License as published by 9# the Free Software Foundation; either version 3 of the License, or 10# (at your option) any later version. 11 12# This program is distributed in the hope that it will be useful, 13# but WITHOUT ANY WARRANTY; without even the implied warranty of 14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15# GNU General Public License for more details. 16 17# You should have received a copy of the GNU General Public License 18# along with this program; if not, see the file COPYING3. If not, 19# see <http://www.gnu.org/licenses/>. 20 21# Set to empty in the environment to override. 22: ${color:---color=always} 23 24usage() { 25 cat <<EOF 26check_GNU_style.sh [patch]... 27 28 Checks the patches for some of the GNU style formatting problems. 29 When FILE is -, read standard input. 30 31 Please note that these checks are not always accurate, and 32 complete. The reference documentation of the GNU Coding Standards 33 can be found here: http://www.gnu.org/prep/standards_toc.html 34 and there are also some additional coding conventions for GCC: 35 http://gcc.gnu.org/codingconventions.html 36 37EOF 38 exit 1 39} 40 41test $# -eq 0 && usage 42nfiles=$# 43files="$*" 44 45stdin=false 46stdin_tmp="" 47if [ $nfiles -eq 1 ] && [ "$files" = "-" ]; then 48 stdin=true 49 50 # By putting stdin into a temp file, we can handle it just like any other 51 # file. F.i., we can cat it twice, which we can't do with stdin. 52 stdin_tmp=check_GNU_style.stdin 53 cat - > $stdin_tmp 54 files=$stdin_tmp 55else 56 for f in $files; do 57 if [ "$f" = "-" ]; then 58 # Let's keep things simple. Either we read from stdin, or we read 59 # from files specified on the command line, not both. 60 usage 61 fi 62 if [ ! -f "$f" ]; then 63 echo "error: could not read file: $f" 64 exit 1 65 fi 66 done 67fi 68 69inp=check_GNU_style.inp 70tmp=check_GNU_style.tmp 71tmp2=check_GNU_style.2.tmp 72tmp3=check_GNU_style.3.tmp 73 74# Remove $tmp on exit and various signals. 75trap "rm -f $inp $tmp $tmp2 $tmp3 $stdin_tmp" 0 76trap "rm -f $inp $tmp $tmp2 $tmp3 $stdin_tmp; exit 1" 1 2 3 5 9 13 15 77 78if [ $nfiles -eq 1 ]; then 79 # There's no need for the file prefix if we're dealing only with one file. 80 format="-n" 81else 82 format="-nH" 83fi 84grep $format '^+' $files \ 85 | grep -v ':+++' \ 86 > $inp 87 88cat_with_prefix () 89{ 90 local f="$1" 91 92 if [ "$prefix" = "" ]; then 93 cat "$f" 94 else 95 awk "{printf \"%s%s\n\", \"$prefix\", \$0}" $f 96 fi 97} 98 99# Grep 100g (){ 101 local msg="$1" 102 local arg="$2" 103 104 local found=false 105 cat $inp \ 106 | egrep $color -- "$arg" \ 107 > "$tmp" && found=true 108 109 if $found; then 110 printf "\n$msg\n" 111 cat "$tmp" 112 fi 113} 114 115# And Grep 116ag (){ 117 local msg="$1" 118 local arg1="$2" 119 local arg2="$3" 120 121 local found=false 122 cat $inp \ 123 | egrep $color -- "$arg1" \ 124 | egrep $color -- "$arg2" \ 125 > "$tmp" && found=true 126 127 if $found; then 128 printf "\n$msg\n" 129 cat "$tmp" 130 fi 131} 132 133# reVerse Grep 134vg (){ 135 local msg="$1" 136 local varg="$2" 137 local arg="$3" 138 139 local found=false 140 cat $inp \ 141 | egrep -v -- "$varg" \ 142 | egrep $color -- "$arg" \ 143 > "$tmp" && found=true 144 145 if $found; then 146 printf "\n$msg\n" 147 cat "$tmp" 148 fi 149} 150 151col (){ 152 local msg="$1" 153 154 local first=true 155 local f 156 for f in $files; do 157 prefix="" 158 if [ $nfiles -ne 1 ]; then 159 prefix="$f:" 160 fi 161 162 # Don't reuse $inp, which may be generated using -H and thus contain a 163 # file prefix. 164 grep -n '^+' $f \ 165 | grep -v ':+++' \ 166 > $tmp 167 168 # Keep only line number prefix and patch modifier '+'. 169 cat "$tmp" \ 170 | sed 's/\(^[0-9][0-9]*:+\).*/\1/' \ 171 > "$tmp2" 172 173 # Remove line number prefix and patch modifier '+'. 174 # Expand tabs to spaces according to tab positions. 175 # Keep long lines, make short lines empty. Print the part past 80 chars 176 # in red. 177 # Don't complain about dg-xxx directives in tests. 178 cat "$tmp" \ 179 | sed 's/^[0-9]*:+//' \ 180 | expand \ 181 | awk '$0 !~ /{[[:space:]]*dg-(error|warning|message)[[:space:]]/ { \ 182 if (length($0) > 80) \ 183 printf "%s\033[1;31m%s\033[0m\n", \ 184 substr($0,1,80), \ 185 substr($0,81); \ 186 else \ 187 print "" \ 188 }' \ 189 > "$tmp3" 190 191 # Combine prefix back with long lines. 192 # Filter out empty lines. 193 local found=false 194 paste -d '' "$tmp2" "$tmp3" \ 195 | grep -v '^[0-9][0-9]*:+$' \ 196 > "$tmp" && found=true 197 198 if $found; then 199 if $first; then 200 printf "\n$msg\n" 201 first=false 202 fi 203 cat_with_prefix "$tmp" 204 fi 205 done 206} 207 208 209col 'Lines should not exceed 80 characters.' 210 211g 'Blocks of 8 spaces should be replaced with tabs.' \ 212 ' {8}' 213 214g 'Trailing whitespace.' \ 215 '[[:space:]]$' 216 217g 'Space before dot.' \ 218 '[[:alnum:]][[:blank:]]+\.' 219 220g 'Dot, space, space, new sentence.' \ 221 '[[:alnum:]]\.([[:blank:]]|[[:blank:]]{3,})[A-Z0-9]' 222 223g 'Dot, space, space, end of comment.' \ 224 '[[:alnum:]]\.([[:blank:]]{0,1}|[[:blank:]]{3,})\*/' 225 226g 'Sentences should end with a dot. Dot, space, space, end of the comment.' \ 227 '[[:alnum:]][[:blank:]]*\*/' 228 229vg 'There should be exactly one space between function name and parenthesis.' \ 230 '\#define' \ 231 '[[:alnum:]]([[:blank:]]{2,})?\(' 232 233g 'There should be no space before a left square bracket.' \ 234 '[[:alnum:]][[:blank:]]+\[' 235 236g 'There should be no space before closing parenthesis.' \ 237 '[[:graph:]][[:blank:]]+\)' 238 239# This will give false positives for C99 compound literals. 240g 'Braces should be on a separate line.' \ 241 '(\)|else)[[:blank:]]*{' 242 243# Does this apply to definitions of aggregate objects? 244ag 'Trailing operator.' \ 245 '^[1-9][0-9]*:\+[[:space:]]' \ 246 '(([^a-zA-Z_]\*)|([-%<=&|^?])|([^*]/)|([^:][+]))$' 247