]>
Commit | Line | Data |
---|---|---|
f3e3b476 SP |
1 | #!/bin/sh |
2 | ||
3 | # Checks some of the GNU style formatting rules in a set of patches. | |
55a82b66 | 4 | # Copyright (C) 2010, 2012, 2016 Free Software Foundation, Inc. |
f3e3b476 SP |
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 | |
55a82b66 MS |
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} | |
f3e3b476 SP |
23 | |
24 | usage() { | |
25 | cat <<EOF | |
26 | check_GNU_style.sh [patch]... | |
27 | ||
28 | Checks the patches for some of the GNU style formatting problems. | |
6e7bdfac YG |
29 | When FILE is -, read standard input. |
30 | ||
f3e3b476 SP |
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 | ||
37 | EOF | |
38 | exit 1 | |
39 | } | |
40 | ||
41 | test $# -eq 0 && usage | |
4171ffe9 TV |
42 | nfiles=$# |
43 | files="$*" | |
f3e3b476 | 44 | |
7f167be6 | 45 | stdin=false |
a22e33d0 | 46 | stdin_tmp="" |
7f167be6 TV |
47 | if [ $nfiles -eq 1 ] && [ "$files" = "-" ]; then |
48 | stdin=true | |
a22e33d0 TV |
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 | |
7f167be6 TV |
55 | else |
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 | |
67 | fi | |
0648b807 | 68 | |
6e7bdfac | 69 | inp=check_GNU_style.inp |
f3e3b476 | 70 | tmp=check_GNU_style.tmp |
323eb6e3 TV |
71 | tmp2=check_GNU_style.2.tmp |
72 | tmp3=check_GNU_style.3.tmp | |
f3e3b476 | 73 | |
c8ae7abf | 74 | # Remove $tmp on exit and various signals. |
323eb6e3 TV |
75 | trap "rm -f $inp $tmp $tmp2 $tmp3 $stdin_tmp" 0 |
76 | trap "rm -f $inp $tmp $tmp2 $tmp3 $stdin_tmp; exit 1" 1 2 3 5 9 13 15 | |
6e7bdfac | 77 | |
4171ffe9 TV |
78 | if [ $nfiles -eq 1 ]; then |
79 | # There's no need for the file prefix if we're dealing only with one file. | |
80 | format="-n" | |
81 | else | |
82 | format="-nH" | |
83 | fi | |
e77cf8c6 KT |
84 | |
85 | # Remove the testsuite part of the diff. We don't care about GNU style | |
86 | # in testcases and the dg-* directives give too many false positives. | |
87 | remove_testsuite () | |
88 | { | |
89 | awk 'BEGIN{testsuite=0} /^(.*:)?([1-9][0-9]*:)?\+\+\+ / && ! /testsuite\//{testsuite=0} \ | |
90 | {if (!testsuite) print} /^(.*:)?([1-9][0-9]*:)?\+\+\+ (.*\/)?testsuite\//{testsuite=1}' | |
91 | } | |
92 | ||
4171ffe9 | 93 | grep $format '^+' $files \ |
e77cf8c6 | 94 | | remove_testsuite \ |
4171ffe9 TV |
95 | | grep -v ':+++' \ |
96 | > $inp | |
c8ae7abf | 97 | |
323eb6e3 TV |
98 | cat_with_prefix () |
99 | { | |
100 | local f="$1" | |
101 | ||
102 | if [ "$prefix" = "" ]; then | |
103 | cat "$f" | |
104 | else | |
7392b090 | 105 | awk "{printf \"%s%s\n\", \"$prefix\", \$0}" $f |
323eb6e3 TV |
106 | fi |
107 | } | |
108 | ||
f3e3b476 SP |
109 | # Grep |
110 | g (){ | |
847b6e15 TV |
111 | local msg="$1" |
112 | local arg="$2" | |
ad7f0dfe TV |
113 | |
114 | local found=false | |
6e7bdfac | 115 | cat $inp \ |
55a82b66 | 116 | | egrep $color -- "$arg" \ |
ad7f0dfe TV |
117 | > "$tmp" && found=true |
118 | ||
119 | if $found; then | |
120 | printf "\n$msg\n" | |
121 | cat "$tmp" | |
122 | fi | |
f3e3b476 SP |
123 | } |
124 | ||
125 | # And Grep | |
126 | ag (){ | |
847b6e15 TV |
127 | local msg="$1" |
128 | local arg1="$2" | |
129 | local arg2="$3" | |
ad7f0dfe TV |
130 | |
131 | local found=false | |
6e7bdfac | 132 | cat $inp \ |
55a82b66 MS |
133 | | egrep $color -- "$arg1" \ |
134 | | egrep $color -- "$arg2" \ | |
ad7f0dfe TV |
135 | > "$tmp" && found=true |
136 | ||
137 | if $found; then | |
138 | printf "\n$msg\n" | |
139 | cat "$tmp" | |
140 | fi | |
f3e3b476 SP |
141 | } |
142 | ||
143 | # reVerse Grep | |
144 | vg (){ | |
847b6e15 TV |
145 | local msg="$1" |
146 | local varg="$2" | |
147 | local arg="$3" | |
ad7f0dfe TV |
148 | |
149 | local found=false | |
6e7bdfac | 150 | cat $inp \ |
f3e3b476 | 151 | | egrep -v -- "$varg" \ |
55a82b66 | 152 | | egrep $color -- "$arg" \ |
ad7f0dfe TV |
153 | > "$tmp" && found=true |
154 | ||
155 | if $found; then | |
156 | printf "\n$msg\n" | |
157 | cat "$tmp" | |
158 | fi | |
f3e3b476 SP |
159 | } |
160 | ||
161 | col (){ | |
847b6e15 | 162 | local msg="$1" |
323eb6e3 | 163 | |
cc1e0483 TV |
164 | local first=true |
165 | local f | |
166 | for f in $files; do | |
323eb6e3 | 167 | prefix="" |
cc1e0483 TV |
168 | if [ $nfiles -ne 1 ]; then |
169 | prefix="$f:" | |
170 | fi | |
171 | ||
172 | # Don't reuse $inp, which may be generated using -H and thus contain a | |
e77cf8c6 KT |
173 | # file prefix. Re-remove the testsuite since we're not using $inp. |
174 | cat $f | remove_testsuite \ | |
175 | | grep -n '^+' \ | |
cc1e0483 TV |
176 | | grep -v ':+++' \ |
177 | > $tmp | |
178 | ||
323eb6e3 TV |
179 | # Keep only line number prefix and patch modifier '+'. |
180 | cat "$tmp" \ | |
181 | | sed 's/\(^[0-9][0-9]*:+\).*/\1/' \ | |
182 | > "$tmp2" | |
183 | ||
184 | # Remove line number prefix and patch modifier '+'. | |
185 | # Expand tabs to spaces according to tab positions. | |
186 | # Keep long lines, make short lines empty. Print the part past 80 chars | |
187 | # in red. | |
188 | cat "$tmp" \ | |
189 | | sed 's/^[0-9]*:+//' \ | |
190 | | expand \ | |
e77cf8c6 | 191 | | awk '{ \ |
323eb6e3 TV |
192 | if (length($0) > 80) \ |
193 | printf "%s\033[1;31m%s\033[0m\n", \ | |
194 | substr($0,1,80), \ | |
195 | substr($0,81); \ | |
196 | else \ | |
197 | print "" \ | |
198 | }' \ | |
199 | > "$tmp3" | |
200 | ||
201 | # Combine prefix back with long lines. | |
202 | # Filter out empty lines. | |
203 | local found=false | |
22d222d2 | 204 | paste -d '\0' "$tmp2" "$tmp3" \ |
323eb6e3 TV |
205 | | grep -v '^[0-9][0-9]*:+$' \ |
206 | > "$tmp" && found=true | |
207 | ||
208 | if $found; then | |
209 | if $first; then | |
210 | printf "\n$msg\n" | |
211 | first=false | |
cc1e0483 | 212 | fi |
323eb6e3 TV |
213 | cat_with_prefix "$tmp" |
214 | fi | |
cc1e0483 | 215 | done |
f3e3b476 SP |
216 | } |
217 | ||
55a82b66 | 218 | |
6e7bdfac YG |
219 | col 'Lines should not exceed 80 characters.' |
220 | ||
221 | g 'Blocks of 8 spaces should be replaced with tabs.' \ | |
222 | ' {8}' | |
f3e3b476 SP |
223 | |
224 | g 'Trailing whitespace.' \ | |
6e7bdfac | 225 | '[[:space:]]$' |
f3e3b476 SP |
226 | |
227 | g 'Space before dot.' \ | |
6e7bdfac | 228 | '[[:alnum:]][[:blank:]]+\.' |
f3e3b476 SP |
229 | |
230 | g 'Dot, space, space, new sentence.' \ | |
6e7bdfac | 231 | '[[:alnum:]]\.([[:blank:]]|[[:blank:]]{3,})[A-Z0-9]' |
f3e3b476 SP |
232 | |
233 | g 'Dot, space, space, end of comment.' \ | |
6e7bdfac | 234 | '[[:alnum:]]\.([[:blank:]]{0,1}|[[:blank:]]{3,})\*/' |
f3e3b476 SP |
235 | |
236 | g 'Sentences should end with a dot. Dot, space, space, end of the comment.' \ | |
6e7bdfac | 237 | '[[:alnum:]][[:blank:]]*\*/' |
f3e3b476 | 238 | |
55a82b66 | 239 | vg 'There should be exactly one space between function name and parenthesis.' \ |
7e425ad6 TV |
240 | '\#define' \ |
241 | '[[:alnum:]]([[:blank:]]{2,})?\(' | |
f3e3b476 | 242 | |
55a82b66 MS |
243 | g 'There should be no space before a left square bracket.' \ |
244 | '[[:alnum:]][[:blank:]]+\[' | |
245 | ||
246 | g 'There should be no space before closing parenthesis.' \ | |
6e7bdfac | 247 | '[[:graph:]][[:blank:]]+\)' |
f3e3b476 | 248 | |
55a82b66 MS |
249 | # This will give false positives for C99 compound literals. |
250 | g 'Braces should be on a separate line.' \ | |
251 | '(\)|else)[[:blank:]]*{' | |
252 | ||
2ecc0c83 MS |
253 | # Does this apply to definitions of aggregate objects? |
254 | ag 'Trailing operator.' \ | |
255 | '^[1-9][0-9]*:\+[[:space:]]' \ | |
55a82b66 | 256 | '(([^a-zA-Z_]\*)|([-%<=&|^?])|([^*]/)|([^:][+]))$' |