2015-11-22 Jerry DeLisle <jvdelisle@gcc.gnu.org>
[official-gcc.git] / contrib / check_GNU_style.sh
blobac54ed070e73a2b931d348c216faa21b2070ecd9
1 #!/bin/sh
3 # Checks some of the GNU style formatting rules in a set of patches.
4 # Copyright (C) 2010, 2012 Free Software Foundation, Inc.
5 # Contributed by Sebastian Pop <sebastian.pop@amd.com>
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.
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.
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 usage() {
22 cat <<EOF
23 check_GNU_style.sh [patch]...
25 Checks the patches for some of the GNU style formatting problems.
26 When FILE is -, read standard input.
28 Please note that these checks are not always accurate, and
29 complete. The reference documentation of the GNU Coding Standards
30 can be found here: http://www.gnu.org/prep/standards_toc.html
31 and there are also some additional coding conventions for GCC:
32 http://gcc.gnu.org/codingconventions.html
34 EOF
35 exit 1
38 test $# -eq 0 && usage
39 nfiles=$#
40 files="$*"
42 stdin=false
43 stdin_tmp=""
44 if [ $nfiles -eq 1 ] && [ "$files" = "-" ]; then
45 stdin=true
47 # By putting stdin into a temp file, we can handle it just like any other
48 # file. F.i., we can cat it twice, which we can't do with stdin.
49 stdin_tmp=check_GNU_style.stdin
50 cat - > $stdin_tmp
51 files=$stdin_tmp
52 else
53 for f in $files; do
54 if [ "$f" = "-" ]; then
55 # Let's keep things simple. Either we read from stdin, or we read
56 # from files specified on the command line, not both.
57 usage
59 if [ ! -f "$f" ]; then
60 echo "error: could not read file: $f"
61 exit 1
63 done
66 inp=check_GNU_style.inp
67 tmp=check_GNU_style.tmp
68 tmp2=check_GNU_style.2.tmp
69 tmp3=check_GNU_style.3.tmp
71 # Remove $tmp on exit and various signals.
72 trap "rm -f $inp $tmp $tmp2 $tmp3 $stdin_tmp" 0
73 trap "rm -f $inp $tmp $tmp2 $tmp3 $stdin_tmp; exit 1" 1 2 3 5 9 13 15
75 if [ $nfiles -eq 1 ]; then
76 # There's no need for the file prefix if we're dealing only with one file.
77 format="-n"
78 else
79 format="-nH"
81 grep $format '^+' $files \
82 | grep -v ':+++' \
83 > $inp
85 cat_with_prefix ()
87 local f="$1"
89 if [ "$prefix" = "" ]; then
90 cat "$f"
91 else
92 awk "{printf \"%s%s\n\", \"$prefix\", \$0}" $f
96 # Grep
97 g (){
98 local msg="$1"
99 local arg="$2"
101 local found=false
102 cat $inp \
103 | egrep --color=always -- "$arg" \
104 > "$tmp" && found=true
106 if $found; then
107 printf "\n$msg\n"
108 cat "$tmp"
112 # And Grep
113 ag (){
114 local msg="$1"
115 local arg1="$2"
116 local arg2="$3"
118 local found=false
119 cat $inp \
120 | egrep --color=always -- "$arg1" \
121 | egrep --color=always -- "$arg2" \
122 > "$tmp" && found=true
124 if $found; then
125 printf "\n$msg\n"
126 cat "$tmp"
130 # reVerse Grep
131 vg (){
132 local msg="$1"
133 local varg="$2"
134 local arg="$3"
136 local found=false
137 cat $inp \
138 | egrep -v -- "$varg" \
139 | egrep --color=always -- "$arg" \
140 > "$tmp" && found=true
142 if $found; then
143 printf "\n$msg\n"
144 cat "$tmp"
148 col (){
149 local msg="$1"
151 local first=true
152 local f
153 for f in $files; do
154 prefix=""
155 if [ $nfiles -ne 1 ]; then
156 prefix="$f:"
159 # Don't reuse $inp, which may be generated using -H and thus contain a
160 # file prefix.
161 grep -n '^+' $f \
162 | grep -v ':+++' \
163 > $tmp
165 # Keep only line number prefix and patch modifier '+'.
166 cat "$tmp" \
167 | sed 's/\(^[0-9][0-9]*:+\).*/\1/' \
168 > "$tmp2"
170 # Remove line number prefix and patch modifier '+'.
171 # Expand tabs to spaces according to tab positions.
172 # Keep long lines, make short lines empty. Print the part past 80 chars
173 # in red.
174 cat "$tmp" \
175 | sed 's/^[0-9]*:+//' \
176 | expand \
177 | awk '{ \
178 if (length($0) > 80) \
179 printf "%s\033[1;31m%s\033[0m\n", \
180 substr($0,1,80), \
181 substr($0,81); \
182 else \
183 print "" \
184 }' \
185 > "$tmp3"
187 # Combine prefix back with long lines.
188 # Filter out empty lines.
189 local found=false
190 paste -d '' "$tmp2" "$tmp3" \
191 | grep -v '^[0-9][0-9]*:+$' \
192 > "$tmp" && found=true
194 if $found; then
195 if $first; then
196 printf "\n$msg\n"
197 first=false
199 cat_with_prefix "$tmp"
201 done
204 col 'Lines should not exceed 80 characters.'
206 g 'Blocks of 8 spaces should be replaced with tabs.' \
207 ' {8}'
209 g 'Trailing whitespace.' \
210 '[[:space:]]$'
212 g 'Space before dot.' \
213 '[[:alnum:]][[:blank:]]+\.'
215 g 'Dot, space, space, new sentence.' \
216 '[[:alnum:]]\.([[:blank:]]|[[:blank:]]{3,})[A-Z0-9]'
218 g 'Dot, space, space, end of comment.' \
219 '[[:alnum:]]\.([[:blank:]]{0,1}|[[:blank:]]{3,})\*/'
221 g 'Sentences should end with a dot. Dot, space, space, end of the comment.' \
222 '[[:alnum:]][[:blank:]]*\*/'
224 vg 'There should be exactly one space between function name and parentheses.' \
225 '\#define' \
226 '[[:alnum:]]([[:blank:]]{2,})?\('
228 g 'There should be no space before closing parentheses.' \
229 '[[:graph:]][[:blank:]]+\)'
231 ag 'Braces should be on a separate line.' \
232 '\{' \
233 'if[[:blank:]]\(|while[[:blank:]]\(|switch[[:blank:]]\('