1 #!/usr/perl5/bin/perl
2 #
3 # CDDL HEADER START
4 #
5 # The contents of this file are subject to the terms of the
6 # Common Development and Distribution License (the "License").
7 # You may not use this file except in compliance with the License.
8 #
9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 # or http://www.opensolaris.org/os/licensing.
11 # See the License for the specific language governing permissions
12 # and limitations under the License.
13 #
14 # When distributing Covered Code, include this CDDL HEADER in each
15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 # If applicable, add the following below this CDDL HEADER, with the
17 # fields enclosed by brackets "[]" replaced with your own identifying
18 # information: Portions Copyright [yyyy] [name of copyright owner]
19 #
20 # CDDL HEADER END
21 #
22
23 #
24 # Copyright 2008 Sun Microsystems, Inc. All rights reserved.
25 # Use is subject to license terms.
26 #
27
28 require 5.8.4;
29
30 $PNAME = $0;
31 $PNAME =~ s:.*/::;
32 $USAGE = "Usage: $PNAME [file ...]\n";
33 $errs = 0;
34
35 sub err
36 {
37 my($msg) = @_;
38
39 print "$file: $lineno: $msg\n";
40 $errs++;
41 }
42
43 sub dstyle
44 {
45 open(FILE, "$file");
46 $lineno = 0;
47 $inclause = 0;
48 $skipnext = 0;
49
50 while (<FILE>) {
51 $lineno++;
52
53 chop;
54
55 if ($skipnext) {
56 $skipnext = 0;
57 next;
58 }
59
60 #
61 # Amazingly, some ident strings are longer than 80 characters!
62 #
63 if (/^#pragma ident/) {
64 next;
65 }
66
67 #
68 # The algorithm to calculate line length from cstyle.
69 #
70 $line = $_;
71 if ($line =~ tr/\t/\t/ * 7 + length($line) > 80) {
72 # yes, there is a chance.
73 # replace tabs with spaces and check again.
74 $eline = $line;
75 1 while $eline =~
76 s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e;
77
78 if (length($eline) > 80) {
79 err "line > 80 characters";
80 }
81 }
82
83 if (/\/\*DSTYLED\*\//) {
84 $skipnext = 1;
85 next;
86 }
87
88 if (/^#pragma/) {
89 next;
90 }
91
92 if (/^#include/) {
93 next;
94 }
95
96 #
97 # Before we do any more analysis, we want to prune out any
98 # quoted strings. This is a bit tricky because we need
99 # to be careful of backslashed quotes within quoted strings.
100 # I'm sure there is a very crafty way to do this with a
101 # single regular expression, but that will have to wait for
102 # somone with better regex juju that I; we do this by first
103 # eliminating the backslashed quotes, and then eliminating
104 # whatever quoted strings are left. Note that we eliminate
105 # the string by replacing it with "quotedstr"; this is to
106 # allow lines to end with a quoted string. (If we simply
107 # eliminated the quoted string, dstyle might complain about
108 # the line ending in a space or tab.)
109 #
110 s/\\\"//g;
111 s/\"[^\"]*\"/quotedstr/g;
112
113 if (/[ \t]$/) {
114 err "space or tab at end of line";
115 }
116
117 if (/^[\t]+[ ]+[\t]+/) {
118 err "spaces between tabs";
119 }
120
121 if (/^[\t]* \*/) {
122 next;
123 }
124
125 if (/^ /) {
126 err "indented by spaces not tabs";
127 }
128
129 if (/^{}$/) {
130 next;
131 }
132
133 if (!/^enum/ && !/^\t*struct/ && !/^\t*union/ && !/^typedef/ &&
134 !/^translator/ && !/^provider/) {
135 if (/[\w\s]+{/) {
136 err "left brace not on its own line";
137 }
138
139 if (/{[\w\s]+/) {
140 err "left brace not on its own line";
141 }
142 }
143
144 if (!/;$/) {
145 if (/[\w\s]+}/) {
146 err "right brace not on its own line";
147 }
148
149 if (/}[\w\s]+/) {
150 err "right brace not on its own line";
151 }
152 }
153
154 if (/^}/) {
155 $inclause = 0;
156 }
157
158 if (!$inclause && /^[\w ]+\//) {
159 err "predicate not at beginning of line";
160 }
161
162 if (!$inclause && /^\/[ \t]+\w/) {
163 err "space between '/' and expression in predicate";
164 }
165
166 if (!$inclause && /\w[ \t]+\/$/) {
167 err "space between expression and '/' in predicate";
168 }
169
170 if (!$inclause && /\s,/) {
171 err "space before comma in probe description";
172 }
173
174 if (!$inclause && /\w,[\w\s]/ && !/;$/) {
175 if (!/extern/ && !/\(/ && !/inline/) {
176 err "multiple probe descriptions on same line";
177 }
178 }
179
180 if ($inclause && /sizeof\(/) {
181 err "missing space after sizeof";
182 }
183
184 if ($inclause && /^[\w ]/) {
185 err "line doesn't begin with a tab";
186 }
187
188 if ($inclause && /,[\w]/) {
189 err "comma without trailing space";
190 }
191
192 if (/\w&&/ || /&&\w/ || /\w\|\|/ || /\|\|\w/) {
193 err "logical operator not set off with spaces";
194 }
195
196 #
197 # We want to catch "i<0" variants, but we don't want to
198 # erroneously flag translators.
199 #
200 if (!/\w<\w+>\(/) {
201 if (/\w>/ || / >\w/ || /\w</ || /<\w/) {
202 err "comparison operator not set " .
203 "off with spaces";
204 }
205 }
206
207 if (/\w==/ || /==\w/ || /\w<=/ || />=\w/ || /\w!=/ || /!=\w/) {
208 err "comparison operator not set off with spaces";
209 }
210
211 if (/\w=/ || /=\w/) {
212 err "assignment operator not set off with spaces";
213 }
214
215 if (/^{/) {
216 $inclause = 1;
217 }
218 }
219 }
220
221 foreach $arg (@ARGV) {
222 if (-f $arg) {
223 push(@files, $arg);
224 } else {
225 die "$PNAME: $arg is not a valid file\n";
226 }
227 }
228
229 die $USAGE if (scalar(@files) == 0);
230
231 foreach $file (@files) {
232 dstyle($file);
233 }
234
235 exit($errs != 0);