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