commit 138e695
Emilia Smólska
·
2026-08-28 17:16:14 +0000 UTC
parent ff862c1
cstyle
3 files changed,
+1407,
-0
+384,
-0
1@@ -0,0 +1,384 @@
2+Unless otherwise noted, all files in this distribution are released
3+under the Common Development and Distribution License (CDDL).
4+Exceptions are noted within the associated source files.
5+
6+--------------------------------------------------------------------
7+
8+
9+COMMON DEVELOPMENT AND DISTRIBUTION LICENSE Version 1.0
10+
11+1. Definitions.
12+
13+ 1.1. "Contributor" means each individual or entity that creates
14+ or contributes to the creation of Modifications.
15+
16+ 1.2. "Contributor Version" means the combination of the Original
17+ Software, prior Modifications used by a Contributor (if any),
18+ and the Modifications made by that particular Contributor.
19+
20+ 1.3. "Covered Software" means (a) the Original Software, or (b)
21+ Modifications, or (c) the combination of files containing
22+ Original Software with files containing Modifications, in
23+ each case including portions thereof.
24+
25+ 1.4. "Executable" means the Covered Software in any form other
26+ than Source Code.
27+
28+ 1.5. "Initial Developer" means the individual or entity that first
29+ makes Original Software available under this License.
30+
31+ 1.6. "Larger Work" means a work which combines Covered Software or
32+ portions thereof with code not governed by the terms of this
33+ License.
34+
35+ 1.7. "License" means this document.
36+
37+ 1.8. "Licensable" means having the right to grant, to the maximum
38+ extent possible, whether at the time of the initial grant or
39+ subsequently acquired, any and all of the rights conveyed
40+ herein.
41+
42+ 1.9. "Modifications" means the Source Code and Executable form of
43+ any of the following:
44+
45+ A. Any file that results from an addition to, deletion from or
46+ modification of the contents of a file containing Original
47+ Software or previous Modifications;
48+
49+ B. Any new file that contains any part of the Original
50+ Software or previous Modifications; or
51+
52+ C. Any new file that is contributed or otherwise made
53+ available under the terms of this License.
54+
55+ 1.10. "Original Software" means the Source Code and Executable
56+ form of computer software code that is originally released
57+ under this License.
58+
59+ 1.11. "Patent Claims" means any patent claim(s), now owned or
60+ hereafter acquired, including without limitation, method,
61+ process, and apparatus claims, in any patent Licensable by
62+ grantor.
63+
64+ 1.12. "Source Code" means (a) the common form of computer software
65+ code in which modifications are made and (b) associated
66+ documentation included in or with such code.
67+
68+ 1.13. "You" (or "Your") means an individual or a legal entity
69+ exercising rights under, and complying with all of the terms
70+ of, this License. For legal entities, "You" includes any
71+ entity which controls, is controlled by, or is under common
72+ control with You. For purposes of this definition,
73+ "control" means (a) the power, direct or indirect, to cause
74+ the direction or management of such entity, whether by
75+ contract or otherwise, or (b) ownership of more than fifty
76+ percent (50%) of the outstanding shares or beneficial
77+ ownership of such entity.
78+
79+2. License Grants.
80+
81+ 2.1. The Initial Developer Grant.
82+
83+ Conditioned upon Your compliance with Section 3.1 below and
84+ subject to third party intellectual property claims, the Initial
85+ Developer hereby grants You a world-wide, royalty-free,
86+ non-exclusive license:
87+
88+ (a) under intellectual property rights (other than patent or
89+ trademark) Licensable by Initial Developer, to use,
90+ reproduce, modify, display, perform, sublicense and
91+ distribute the Original Software (or portions thereof),
92+ with or without Modifications, and/or as part of a Larger
93+ Work; and
94+
95+ (b) under Patent Claims infringed by the making, using or
96+ selling of Original Software, to make, have made, use,
97+ practice, sell, and offer for sale, and/or otherwise
98+ dispose of the Original Software (or portions thereof).
99+
100+ (c) The licenses granted in Sections 2.1(a) and (b) are
101+ effective on the date Initial Developer first distributes
102+ or otherwise makes the Original Software available to a
103+ third party under the terms of this License.
104+
105+ (d) Notwithstanding Section 2.1(b) above, no patent license is
106+ granted: (1) for code that You delete from the Original
107+ Software, or (2) for infringements caused by: (i) the
108+ modification of the Original Software, or (ii) the
109+ combination of the Original Software with other software
110+ or devices.
111+
112+ 2.2. Contributor Grant.
113+
114+ Conditioned upon Your compliance with Section 3.1 below and
115+ subject to third party intellectual property claims, each
116+ Contributor hereby grants You a world-wide, royalty-free,
117+ non-exclusive license:
118+
119+ (a) under intellectual property rights (other than patent or
120+ trademark) Licensable by Contributor to use, reproduce,
121+ modify, display, perform, sublicense and distribute the
122+ Modifications created by such Contributor (or portions
123+ thereof), either on an unmodified basis, with other
124+ Modifications, as Covered Software and/or as part of a
125+ Larger Work; and
126+
127+ (b) under Patent Claims infringed by the making, using, or
128+ selling of Modifications made by that Contributor either
129+ alone and/or in combination with its Contributor Version
130+ (or portions of such combination), to make, use, sell,
131+ offer for sale, have made, and/or otherwise dispose of:
132+ (1) Modifications made by that Contributor (or portions
133+ thereof); and (2) the combination of Modifications made by
134+ that Contributor with its Contributor Version (or portions
135+ of such combination).
136+
137+ (c) The licenses granted in Sections 2.2(a) and 2.2(b) are
138+ effective on the date Contributor first distributes or
139+ otherwise makes the Modifications available to a third
140+ party.
141+
142+ (d) Notwithstanding Section 2.2(b) above, no patent license is
143+ granted: (1) for any code that Contributor has deleted
144+ from the Contributor Version; (2) for infringements caused
145+ by: (i) third party modifications of Contributor Version,
146+ or (ii) the combination of Modifications made by that
147+ Contributor with other software (except as part of the
148+ Contributor Version) or other devices; or (3) under Patent
149+ Claims infringed by Covered Software in the absence of
150+ Modifications made by that Contributor.
151+
152+3. Distribution Obligations.
153+
154+ 3.1. Availability of Source Code.
155+
156+ Any Covered Software that You distribute or otherwise make
157+ available in Executable form must also be made available in Source
158+ Code form and that Source Code form must be distributed only under
159+ the terms of this License. You must include a copy of this
160+ License with every copy of the Source Code form of the Covered
161+ Software You distribute or otherwise make available. You must
162+ inform recipients of any such Covered Software in Executable form
163+ as to how they can obtain such Covered Software in Source Code
164+ form in a reasonable manner on or through a medium customarily
165+ used for software exchange.
166+
167+ 3.2. Modifications.
168+
169+ The Modifications that You create or to which You contribute are
170+ governed by the terms of this License. You represent that You
171+ believe Your Modifications are Your original creation(s) and/or
172+ You have sufficient rights to grant the rights conveyed by this
173+ License.
174+
175+ 3.3. Required Notices.
176+
177+ You must include a notice in each of Your Modifications that
178+ identifies You as the Contributor of the Modification. You may
179+ not remove or alter any copyright, patent or trademark notices
180+ contained within the Covered Software, or any notices of licensing
181+ or any descriptive text giving attribution to any Contributor or
182+ the Initial Developer.
183+
184+ 3.4. Application of Additional Terms.
185+
186+ You may not offer or impose any terms on any Covered Software in
187+ Source Code form that alters or restricts the applicable version
188+ of this License or the recipients' rights hereunder. You may
189+ choose to offer, and to charge a fee for, warranty, support,
190+ indemnity or liability obligations to one or more recipients of
191+ Covered Software. However, you may do so only on Your own behalf,
192+ and not on behalf of the Initial Developer or any Contributor.
193+ You must make it absolutely clear that any such warranty, support,
194+ indemnity or liability obligation is offered by You alone, and You
195+ hereby agree to indemnify the Initial Developer and every
196+ Contributor for any liability incurred by the Initial Developer or
197+ such Contributor as a result of warranty, support, indemnity or
198+ liability terms You offer.
199+
200+ 3.5. Distribution of Executable Versions.
201+
202+ You may distribute the Executable form of the Covered Software
203+ under the terms of this License or under the terms of a license of
204+ Your choice, which may contain terms different from this License,
205+ provided that You are in compliance with the terms of this License
206+ and that the license for the Executable form does not attempt to
207+ limit or alter the recipient's rights in the Source Code form from
208+ the rights set forth in this License. If You distribute the
209+ Covered Software in Executable form under a different license, You
210+ must make it absolutely clear that any terms which differ from
211+ this License are offered by You alone, not by the Initial
212+ Developer or Contributor. You hereby agree to indemnify the
213+ Initial Developer and every Contributor for any liability incurred
214+ by the Initial Developer or such Contributor as a result of any
215+ such terms You offer.
216+
217+ 3.6. Larger Works.
218+
219+ You may create a Larger Work by combining Covered Software with
220+ other code not governed by the terms of this License and
221+ distribute the Larger Work as a single product. In such a case,
222+ You must make sure the requirements of this License are fulfilled
223+ for the Covered Software.
224+
225+4. Versions of the License.
226+
227+ 4.1. New Versions.
228+
229+ Sun Microsystems, Inc. is the initial license steward and may
230+ publish revised and/or new versions of this License from time to
231+ time. Each version will be given a distinguishing version number.
232+ Except as provided in Section 4.3, no one other than the license
233+ steward has the right to modify this License.
234+
235+ 4.2. Effect of New Versions.
236+
237+ You may always continue to use, distribute or otherwise make the
238+ Covered Software available under the terms of the version of the
239+ License under which You originally received the Covered Software.
240+ If the Initial Developer includes a notice in the Original
241+ Software prohibiting it from being distributed or otherwise made
242+ available under any subsequent version of the License, You must
243+ distribute and make the Covered Software available under the terms
244+ of the version of the License under which You originally received
245+ the Covered Software. Otherwise, You may also choose to use,
246+ distribute or otherwise make the Covered Software available under
247+ the terms of any subsequent version of the License published by
248+ the license steward.
249+
250+ 4.3. Modified Versions.
251+
252+ When You are an Initial Developer and You want to create a new
253+ license for Your Original Software, You may create and use a
254+ modified version of this License if You: (a) rename the license
255+ and remove any references to the name of the license steward
256+ (except to note that the license differs from this License); and
257+ (b) otherwise make it clear that the license contains terms which
258+ differ from this License.
259+
260+5. DISCLAIMER OF WARRANTY.
261+
262+ COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS"
263+ BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
264+ INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED
265+ SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR
266+ PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND
267+ PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY
268+ COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE
269+ INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY
270+ NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF
271+ WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
272+ ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS
273+ DISCLAIMER.
274+
275+6. TERMINATION.
276+
277+ 6.1. This License and the rights granted hereunder will terminate
278+ automatically if You fail to comply with terms herein and fail to
279+ cure such breach within 30 days of becoming aware of the breach.
280+ Provisions which, by their nature, must remain in effect beyond
281+ the termination of this License shall survive.
282+
283+ 6.2. If You assert a patent infringement claim (excluding
284+ declaratory judgment actions) against Initial Developer or a
285+ Contributor (the Initial Developer or Contributor against whom You
286+ assert such claim is referred to as "Participant") alleging that
287+ the Participant Software (meaning the Contributor Version where
288+ the Participant is a Contributor or the Original Software where
289+ the Participant is the Initial Developer) directly or indirectly
290+ infringes any patent, then any and all rights granted directly or
291+ indirectly to You by such Participant, the Initial Developer (if
292+ the Initial Developer is not the Participant) and all Contributors
293+ under Sections 2.1 and/or 2.2 of this License shall, upon 60 days
294+ notice from Participant terminate prospectively and automatically
295+ at the expiration of such 60 day notice period, unless if within
296+ such 60 day period You withdraw Your claim with respect to the
297+ Participant Software against such Participant either unilaterally
298+ or pursuant to a written agreement with Participant.
299+
300+ 6.3. In the event of termination under Sections 6.1 or 6.2 above,
301+ all end user licenses that have been validly granted by You or any
302+ distributor hereunder prior to termination (excluding licenses
303+ granted to You by any distributor) shall survive termination.
304+
305+7. LIMITATION OF LIABILITY.
306+
307+ UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
308+ (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE
309+ INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF
310+ COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE
311+ LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR
312+ CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT
313+ LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, WORK
314+ STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
315+ COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
316+ INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
317+ LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL
318+ INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT
319+ APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO
320+ NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
321+ CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT
322+ APPLY TO YOU.
323+
324+8. U.S. GOVERNMENT END USERS.
325+
326+ The Covered Software is a "commercial item," as that term is
327+ defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial
328+ computer software" (as that term is defined at 48
329+ C.F.R. 252.227-7014(a)(1)) and "commercial computer software
330+ documentation" as such terms are used in 48 C.F.R. 12.212
331+ (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48
332+ C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all
333+ U.S. Government End Users acquire Covered Software with only those
334+ rights set forth herein. This U.S. Government Rights clause is in
335+ lieu of, and supersedes, any other FAR, DFAR, or other clause or
336+ provision that addresses Government rights in computer software
337+ under this License.
338+
339+9. MISCELLANEOUS.
340+
341+ This License represents the complete agreement concerning subject
342+ matter hereof. If any provision of this License is held to be
343+ unenforceable, such provision shall be reformed only to the extent
344+ necessary to make it enforceable. This License shall be governed
345+ by the law of the jurisdiction specified in a notice contained
346+ within the Original Software (except to the extent applicable law,
347+ if any, provides otherwise), excluding such jurisdiction's
348+ conflict-of-law provisions. Any litigation relating to this
349+ License shall be subject to the jurisdiction of the courts located
350+ in the jurisdiction and venue specified in a notice contained
351+ within the Original Software, with the losing party responsible
352+ for costs, including, without limitation, court costs and
353+ reasonable attorneys' fees and expenses. The application of the
354+ United Nations Convention on Contracts for the International Sale
355+ of Goods is expressly excluded. Any law or regulation which
356+ provides that the language of a contract shall be construed
357+ against the drafter shall not apply to this License. You agree
358+ that You alone are responsible for compliance with the United
359+ States export administration regulations (and the export control
360+ laws and regulation of any other countries) when You use,
361+ distribute or otherwise make available any Covered Software.
362+
363+10. RESPONSIBILITY FOR CLAIMS.
364+
365+ As between Initial Developer and the Contributors, each party is
366+ responsible for claims and damages arising, directly or
367+ indirectly, out of its utilization of rights under this License
368+ and You agree to work with Initial Developer and Contributors to
369+ distribute such responsibility on an equitable basis. Nothing
370+ herein is intended or shall be deemed to constitute any admission
371+ of liability.
372+
373+--------------------------------------------------------------------
374+
375+NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND
376+DISTRIBUTION LICENSE (CDDL)
377+
378+For Covered Software in this distribution, this License shall
379+be governed by the laws of the State of California (excluding
380+conflict-of-law provisions).
381+
382+Any litigation relating to this License shall be subject to the
383+jurisdiction of the Federal Courts of the Northern District of
384+California and the state courts of the State of California, with
385+venue lying in Santa Clara County, California.
+1022,
-0
1@@ -0,0 +1,1022 @@
2+#!/usr/bin/perl -w
3+#
4+# CDDL HEADER START
5+#
6+# The contents of this file are subject to the terms of the
7+# Common Development and Distribution License (the "License").
8+# You may not use this file except in compliance with the License.
9+#
10+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11+# or http://www.opensolaris.org/os/licensing.
12+# See the License for the specific language governing permissions
13+# and limitations under the License.
14+#
15+# When distributing Covered Code, include this CDDL HEADER in each
16+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17+# If applicable, add the following below this CDDL HEADER, with the
18+# fields enclosed by brackets "[]" replaced with your own identifying
19+# information: Portions Copyright [yyyy] [name of copyright owner]
20+#
21+# CDDL HEADER END
22+#
23+# Copyright 2015 Toomas Soome <tsoome@me.com>
24+# Copyright 2016 Nexenta Systems, Inc.
25+# Copyright 2023 Oxide Computer Company
26+#
27+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
28+# Use is subject to license terms.
29+#
30+# Copyright (c) 2015 by Delphix. All rights reserved.
31+#
32+# @(#)cstyle 1.58 98/09/09 (from shannon)
33+#
34+# cstyle - check for some common stylistic errors.
35+#
36+# cstyle is a sort of "lint" for C coding style.
37+# It attempts to check for the style used in the
38+# kernel, sometimes known as "Bill Joy Normal Form".
39+#
40+# There's a lot this can't check for, like proper indentation
41+# of code blocks. There's also a lot more this could check for.
42+#
43+# A note to the non perl literate:
44+#
45+# perl regular expressions are pretty much like egrep
46+# regular expressions, with the following special symbols
47+#
48+# \s any space character
49+# \S any non-space character
50+# \w any "word" character [a-zA-Z0-9_]
51+# \W any non-word character
52+# \d a digit [0-9]
53+# \D a non-digit
54+# \b word boundary (between \w and \W)
55+# \B non-word boundary
56+#
57+
58+require 5.0;
59+use IO::File;
60+use Getopt::Std;
61+use strict;
62+
63+my $usage =
64+"usage: cstyle [-chpvCP] [-o constructs] file ...
65+ -c check continuation indentation inside functions
66+ -h perform heuristic checks that are sometimes wrong
67+ -p perform some of the more picky checks
68+ -v verbose
69+ -C don't check anything in header block comments
70+ -P check for use of non-POSIX types
71+ -o constructs
72+ allow a comma-seperated list of optional constructs:
73+ doxygen allow doxygen-style block comments (/** /*!)
74+ splint allow splint-style lint comments (/*@ ... @*/)
75+";
76+
77+my %opts;
78+
79+if (!getopts("cho:pvCP", \%opts)) {
80+ print $usage;
81+ exit 2;
82+}
83+
84+my $check_continuation = $opts{'c'};
85+my $heuristic = $opts{'h'};
86+my $picky = $opts{'p'};
87+my $verbose = $opts{'v'};
88+my $ignore_hdr_comment = $opts{'C'};
89+my $check_posix_types = $opts{'P'};
90+
91+my $doxygen_comments = 0;
92+my $splint_comments = 0;
93+
94+if (defined($opts{'o'})) {
95+ for my $x (split /,/, $opts{'o'}) {
96+ if ($x eq "doxygen") {
97+ $doxygen_comments = 1;
98+ } elsif ($x eq "splint") {
99+ $splint_comments = 1;
100+ } else {
101+ print "cstyle: unrecognized construct \"$x\"\n";
102+ print $usage;
103+ exit 2;
104+ }
105+ }
106+}
107+
108+my ($filename, $line, $prev); # shared globals
109+
110+my $fmt;
111+my $hdr_comment_start;
112+
113+if ($verbose) {
114+ $fmt = "%s: %d: %s\n%s\n";
115+} else {
116+ $fmt = "%s: %d: %s\n";
117+}
118+
119+if ($doxygen_comments) {
120+ # doxygen comments look like "/*!" or "/**"; allow them.
121+ $hdr_comment_start = qr/^\s*\/\*[\!\*]?$/;
122+} else {
123+ $hdr_comment_start = qr/^\s*\/\*$/;
124+}
125+
126+# FreeBSD uses comments styled as such for their license headers:
127+# /*-
128+# * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
129+# *
130+# ...
131+#
132+# In order to apply other cstyle checks to those files without stumbling over
133+# the license header, tolerate such comment openings as well.
134+my $fbsd_comment_start = qr/^\s*\/\*-$/;
135+
136+# Note, following must be in single quotes so that \s and \w work right.
137+my $typename = '(int|char|short|long|unsigned|float|double' .
138+ '|\w+_t|struct\s+\w+|union\s+\w+|FILE)';
139+
140+# mapping of old types to POSIX compatible types
141+my %old2posix = (
142+ 'unchar' => 'uchar_t',
143+ 'ushort' => 'ushort_t',
144+ 'uint' => 'uint_t',
145+ 'ulong' => 'ulong_t',
146+ 'u_int' => 'uint_t',
147+ 'u_short' => 'ushort_t',
148+ 'u_long' => 'ulong_t',
149+ 'u_char' => 'uchar_t',
150+ 'u_int8_t' => 'uint8_t',
151+ 'u_int16_t' => 'uint16_t',
152+ 'u_int32_t' => 'uint32_t',
153+ 'u_int64_t' => 'uint64_t',
154+ 'u_quad_t' => 'uint64_t',
155+ 'quad' => 'quad_t'
156+);
157+
158+my $lint_re = qr/\/\*(?:
159+ ARGSUSED[0-9]*|NOTREACHED|LINTLIBRARY|VARARGS[0-9]*|
160+ CONSTCOND|CONSTANTCOND|CONSTANTCONDITION|EMPTY|
161+ FALLTHRU|FALLTHROUGH|LINTED.*?|PRINTFLIKE[0-9]*|
162+ PROTOLIB[0-9]*|SCANFLIKE[0-9]*|CSTYLED.*?
163+ )\*\//x;
164+
165+my $splint_re = qr/\/\*@.*?@\*\//x;
166+
167+my $warlock_re = qr/\/\*\s*(?:
168+ VARIABLES\ PROTECTED\ BY|
169+ MEMBERS\ PROTECTED\ BY|
170+ ALL\ MEMBERS\ PROTECTED\ BY|
171+ READ-ONLY\ VARIABLES:|
172+ READ-ONLY\ MEMBERS:|
173+ VARIABLES\ READABLE\ WITHOUT\ LOCK:|
174+ MEMBERS\ READABLE\ WITHOUT\ LOCK:|
175+ LOCKS\ COVERED\ BY|
176+ LOCK\ UNNEEDED\ BECAUSE|
177+ LOCK\ NEEDED:|
178+ LOCK\ HELD\ ON\ ENTRY:|
179+ READ\ LOCK\ HELD\ ON\ ENTRY:|
180+ WRITE\ LOCK\ HELD\ ON\ ENTRY:|
181+ LOCK\ ACQUIRED\ AS\ SIDE\ EFFECT:|
182+ READ\ LOCK\ ACQUIRED\ AS\ SIDE\ EFFECT:|
183+ WRITE\ LOCK\ ACQUIRED\ AS\ SIDE\ EFFECT:|
184+ LOCK\ RELEASED\ AS\ SIDE\ EFFECT:|
185+ LOCK\ UPGRADED\ AS\ SIDE\ EFFECT:|
186+ LOCK\ DOWNGRADED\ AS\ SIDE\ EFFECT:|
187+ FUNCTIONS\ CALLED\ THROUGH\ POINTER|
188+ FUNCTIONS\ CALLED\ THROUGH\ MEMBER|
189+ LOCK\ ORDER:
190+ )/x;
191+
192+my $err_stat = 0; # exit status
193+
194+if ($#ARGV >= 0) {
195+ foreach my $arg (@ARGV) {
196+ my $fh = new IO::File $arg, "r";
197+ if (!defined($fh)) {
198+ printf "%s: can not open\n", $arg;
199+ } else {
200+ &cstyle($arg, $fh);
201+ close $fh;
202+ }
203+ }
204+} else {
205+ &cstyle("<stdin>", *STDIN);
206+}
207+exit $err_stat;
208+
209+my $no_errs = 0; # set for CSTYLED-protected lines
210+
211+sub err($) {
212+ my ($error) = @_;
213+ unless ($no_errs) {
214+ if ($verbose) {
215+ printf $fmt, $filename, $., $error, $line;
216+ } else {
217+ printf $fmt, $filename, $., $error;
218+ }
219+ $err_stat = 1;
220+ }
221+}
222+
223+sub err_prefix($$) {
224+ my ($prevline, $error) = @_;
225+ my $out = $prevline."\n".$line;
226+ unless ($no_errs) {
227+ if ($verbose) {
228+ printf $fmt, $filename, $., $error, $out;
229+ } else {
230+ printf $fmt, $filename, $., $error;
231+ }
232+ $err_stat = 1;
233+ }
234+}
235+
236+sub err_prev($) {
237+ my ($error) = @_;
238+ unless ($no_errs) {
239+ if ($verbose) {
240+ printf $fmt, $filename, $. - 1, $error, $prev;
241+ } else {
242+ printf $fmt, $filename, $. - 1, $error;
243+ }
244+ $err_stat = 1;
245+ }
246+}
247+
248+sub cstyle($$) {
249+
250+my ($fn, $filehandle) = @_;
251+$filename = $fn; # share it globally
252+
253+my $in_cpp = 0;
254+my $next_in_cpp = 0;
255+
256+my $in_comment = 0;
257+my $in_header_comment = 0;
258+my $comment_done = 0;
259+my $in_warlock_comment = 0;
260+my $in_function = 0;
261+my $in_function_header = 0;
262+my $function_header_full_indent = 0;
263+my $in_declaration = 0;
264+my $note_level = 0;
265+my $nextok = 0;
266+my $nocheck = 0;
267+
268+my $in_string = 0;
269+
270+my ($okmsg, $comment_prefix);
271+
272+$line = '';
273+$prev = '';
274+reset_indent();
275+
276+line: while (<$filehandle>) {
277+ s/\r?\n$//; # strip return and newline
278+
279+ # save the original line, then remove all text from within
280+ # double or single quotes, we do not want to check such text.
281+
282+ $line = $_;
283+
284+ #
285+ # C allows strings to be continued with a backslash at the end of
286+ # the line. We translate that into a quoted string on the previous
287+ # line followed by an initial quote on the next line.
288+ #
289+ # (we assume that no-one will use backslash-continuation with character
290+ # constants)
291+ #
292+ $_ = '"' . $_ if ($in_string && !$nocheck && !$in_comment);
293+
294+ #
295+ # normal strings and characters
296+ #
297+ s/'([^\\']|\\[^xX0]|\\0[0-9]*|\\[xX][0-9a-fA-F]*)'/''/g;
298+ s/"([^\\"]|\\.)*"/\"\"/g;
299+
300+ #
301+ # detect string continuation
302+ #
303+ if ($nocheck || $in_comment) {
304+ $in_string = 0;
305+ } else {
306+ #
307+ # Now that all full strings are replaced with "", we check
308+ # for unfinished strings continuing onto the next line.
309+ #
310+ $in_string =
311+ (s/([^"](?:"")*)"([^\\"]|\\.)*\\$/$1""/ ||
312+ s/^("")*"([^\\"]|\\.)*\\$/""/);
313+ }
314+
315+ #
316+ # figure out if we are in a cpp directive
317+ #
318+ $in_cpp = $next_in_cpp || /^\s*#/; # continued or started
319+ $next_in_cpp = $in_cpp && /\\$/; # only if continued
320+
321+ # strip off trailing backslashes, which appear in long macros
322+ s/\s*\\$//;
323+
324+ # an /* END CSTYLED */ comment ends a no-check block.
325+ if ($nocheck) {
326+ if (/\/\* *END *CSTYLED *\*\//) {
327+ $nocheck = 0;
328+ } else {
329+ reset_indent();
330+ next line;
331+ }
332+ }
333+
334+ # a /*CSTYLED*/ comment indicates that the next line is ok.
335+ if ($nextok) {
336+ if ($okmsg) {
337+ err($okmsg);
338+ }
339+ $nextok = 0;
340+ $okmsg = 0;
341+ if (/\/\* *CSTYLED.*\*\//) {
342+ /^.*\/\* *CSTYLED *(.*) *\*\/.*$/;
343+ $okmsg = $1;
344+ $nextok = 1;
345+ }
346+ $no_errs = 1;
347+ } elsif ($no_errs) {
348+ $no_errs = 0;
349+ }
350+
351+ # check length of line.
352+ # first, a quick check to see if there is any chance of being too long.
353+ if (($line =~ tr/\t/\t/) * 7 + length($line) > 80) {
354+ # yes, there is a chance.
355+ # replace tabs with spaces and check again.
356+ my $eline = $line;
357+ 1 while $eline =~
358+ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e;
359+ if (length($eline) > 80) {
360+ err("line > 80 characters");
361+ }
362+ }
363+
364+ # ignore NOTE(...) annotations (assumes NOTE is on lines by itself).
365+ if ($note_level || /\b_?NOTE\s*\(/) { # if in NOTE or this is NOTE
366+ s/[^()]//g; # eliminate all non-parens
367+ $note_level += s/\(//g - length; # update paren nest level
368+ next;
369+ }
370+
371+ # a /* BEGIN CSTYLED */ comment starts a no-check block.
372+ if (/\/\* *BEGIN *CSTYLED *\*\//) {
373+ $nocheck = 1;
374+ }
375+
376+ # a /*CSTYLED*/ comment indicates that the next line is ok.
377+ if (/\/\* *CSTYLED.*\*\//) {
378+ /^.*\/\* *CSTYLED *(.*) *\*\/.*$/;
379+ $okmsg = $1;
380+ $nextok = 1;
381+ }
382+ if (/\/\/ *CSTYLED/) {
383+ /^.*\/\/ *CSTYLED *(.*)$/;
384+ $okmsg = $1;
385+ $nextok = 1;
386+ }
387+
388+ # universal checks; apply to everything
389+ if (/\t +\t/) {
390+ err("spaces between tabs");
391+ }
392+ if (/ \t+ /) {
393+ err("tabs between spaces");
394+ }
395+ if (/\s$/) {
396+ err("space or tab at end of line");
397+ }
398+ if (/[^ \t(]\/\*/ && !/\w\(\/\*.*\*\/\);/) {
399+ err("comment preceded by non-blank");
400+ }
401+
402+ # is this the beginning or ending of a function?
403+ # (not if "struct foo\n{\n")
404+ if (/^\{$/ && $prev =~ /\)\s*(const\s*)?(\/\*.*\*\/\s*)?\\?$/) {
405+ $in_function = 1;
406+ $in_declaration = 1;
407+ $in_function_header = 0;
408+ $function_header_full_indent = 0;
409+ $prev = $line;
410+ next line;
411+ }
412+ if (/^\}\s*(\/\*.*\*\/\s*)*$/) {
413+ if ($prev =~ /^\s*return\s*;/) {
414+ err_prev("unneeded return at end of function");
415+ }
416+ $in_function = 0;
417+ reset_indent(); # we don't check between functions
418+ $prev = $line;
419+ next line;
420+ }
421+ if ($in_function_header && ! /^ (\w|\.)/ ) {
422+ if (/^\{\}$/) {
423+ $in_function_header = 0;
424+ $function_header_full_indent = 0;
425+ } elsif ($picky && ! (/^\t/ && $function_header_full_indent != 0)) {
426+ err("continuation line should be indented by 4 spaces");
427+ }
428+ }
429+
430+ #
431+ # If this matches something of form "foo(", it's probably a function
432+ # definition, unless it ends with ") bar;", in which case it's a declaration
433+ # that uses a macro to generate the type.
434+ #
435+ if (/^\w+\(/ && !/\) \w+;$/) {
436+ $in_function_header = 1;
437+ if (/\($/) {
438+ $function_header_full_indent = 1;
439+ }
440+ }
441+ if ($in_function_header && /^\{$/) {
442+ $in_function_header = 0;
443+ $function_header_full_indent = 0;
444+ $in_function = 1;
445+ }
446+ if ($in_function_header && /\);$/) {
447+ $in_function_header = 0;
448+ $function_header_full_indent = 0;
449+ }
450+ if ($in_function_header && /\{$/ ) {
451+ if ($picky) {
452+ err("opening brace on same line as function header");
453+ }
454+ $in_function_header = 0;
455+ $function_header_full_indent = 0;
456+ $in_function = 1;
457+ next line;
458+ }
459+
460+ if ($in_warlock_comment && /\*\//) {
461+ $in_warlock_comment = 0;
462+ $prev = $line;
463+ next line;
464+ }
465+
466+ # a blank line terminates the declarations within a function.
467+ # XXX - but still a problem in sub-blocks.
468+ if ($in_declaration && /^$/) {
469+ $in_declaration = 0;
470+ }
471+
472+ if ($comment_done) {
473+ $in_comment = 0;
474+ $in_header_comment = 0;
475+ $comment_done = 0;
476+ }
477+ # does this looks like the start of a block comment?
478+ if (/$hdr_comment_start/ || /$fbsd_comment_start/) {
479+ if (!/^\t*\/\*/) {
480+ err("block comment not indented by tabs");
481+ }
482+ $in_comment = 1;
483+ /^(\s*)\//;
484+ $comment_prefix = $1;
485+ if ($comment_prefix eq "") {
486+ $in_header_comment = 1;
487+ }
488+ $prev = $line;
489+ next line;
490+ }
491+ # are we still in the block comment?
492+ if ($in_comment) {
493+ if (/^$comment_prefix \*\/$/) {
494+ $comment_done = 1;
495+ } elsif (/\*\//) {
496+ $comment_done = 1;
497+ err("improper block comment close")
498+ unless ($ignore_hdr_comment && $in_header_comment);
499+ } elsif (!/^$comment_prefix \*[ \t]/ &&
500+ !/^$comment_prefix \*$/) {
501+ err("improper block comment")
502+ unless ($ignore_hdr_comment && $in_header_comment);
503+ }
504+ }
505+
506+ if ($in_header_comment && $ignore_hdr_comment) {
507+ $prev = $line;
508+ next line;
509+ }
510+
511+ # check for errors that might occur in comments and in code.
512+
513+ # allow spaces to be used to draw pictures in header comments.
514+ if (/[^ ] / && !/".* .*"/ && !$in_header_comment) {
515+ err("spaces instead of tabs");
516+ }
517+ if (/^ / && !/^ \*[ \t\/]/ && !/^ \*$/ &&
518+ (!/^ (\w|\.)/ || $in_function != 0)) {
519+ err("indent by spaces instead of tabs");
520+ }
521+ if (/^\t+ [^ \t\*]/ || /^\t+ \S/ || /^\t+ \S/) {
522+ err("continuation line not indented by 4 spaces");
523+ }
524+ if (/$warlock_re/ && !/\*\//) {
525+ $in_warlock_comment = 1;
526+ $prev = $line;
527+ next line;
528+ }
529+ if (/^\s*\/\*./ && !/^\s*\/\*.*\*\// && !/$hdr_comment_start/) {
530+ err("improper first line of block comment");
531+ }
532+
533+ if ($in_comment) { # still in comment, don't do further checks
534+ $prev = $line;
535+ next line;
536+ }
537+
538+ if ((/[^(]\/\*\S/ || /^\/\*\S/) &&
539+ !(/$lint_re/ || ($splint_comments && /$splint_re/))) {
540+ err("missing blank after open comment");
541+ }
542+ if (/\S\*\/[^)]|\S\*\/$/ &&
543+ !(/$lint_re/ || ($splint_comments && /$splint_re/))) {
544+ err("missing blank before close comment");
545+ }
546+ if (/\/\/\S/) { # C++ comments
547+ err("missing blank after start comment");
548+ }
549+ # check for unterminated single line comments, but allow them when
550+ # they are used to comment out the argument list of a function
551+ # declaration.
552+ if (/\S.*\/\*/ && !/\S.*\/\*.*\*\// && !/\(\/\*/) {
553+ err("unterminated single line comment");
554+ }
555+
556+ if (/^(#else|#endif|#include)(.*)$/) {
557+ $prev = $line;
558+ if ($picky) {
559+ my $directive = $1;
560+ my $clause = $2;
561+ # Enforce ANSI rules for #else and #endif: no noncomment
562+ # identifiers are allowed after #endif or #else. Allow
563+ # C++ comments since they seem to be a fact of life.
564+ if ((($1 eq "#endif") || ($1 eq "#else")) &&
565+ ($clause ne "") &&
566+ (!($clause =~ /^\s+\/\*.*\*\/$/)) &&
567+ (!($clause =~ /^\s+\/\/.*$/))) {
568+ err("non-comment text following " .
569+ "$directive (or malformed $directive " .
570+ "directive)");
571+ }
572+ }
573+ next line;
574+ }
575+
576+ #
577+ # delete any comments and check everything else. Note that
578+ # ".*?" is a non-greedy match, so that we don't get confused by
579+ # multiple comments on the same line.
580+ #
581+ s/\/\*.*?\*\///g;
582+ s/\/\/.*$//; # C++ comments
583+
584+ # delete any trailing whitespace; we have already checked for that.
585+ s/\s*$//;
586+
587+ # following checks do not apply to text in comments.
588+
589+ if (/[^<>\s][!<>=]=/ || /[^<>][!<>=]=[^\s,]/ ||
590+ (/[^->]>[^,=>\s]/ && !/[^->]>$/) ||
591+ (/[^<]<[^,=<\s]/ && !/[^<]<$/) ||
592+ /[^<\s]<[^<]/ || /[^->\s]>[^>]/) {
593+ err("missing space around relational operator");
594+ }
595+ if (/\S>>=/ || /\S<<=/ || />>=\S/ || /<<=\S/ || /\S[-+*\/&|^%]=/ ||
596+ (/[^-+*\/&|^%!<>=\s]=[^=]/ && !/[^-+*\/&|^%!<>=\s]=$/) ||
597+ (/[^!<>=]=[^=\s]/ && !/[^!<>=]=$/)) {
598+ # XXX - should only check this for C++ code
599+ # XXX - there are probably other forms that should be allowed
600+ if (!/\soperator=/) {
601+ err("missing space around assignment operator");
602+ }
603+ }
604+ if (/[,;]\S/ && !/\bfor \(;;\)/) {
605+ err("comma or semicolon followed by non-blank");
606+ }
607+ # allow "for" statements to have empty "while" clauses
608+ if (/\s[,;]/ && !/^[\t]+;$/ && !/^\s*for \([^;]*; ;[^;]*\)/) {
609+ err("comma or semicolon preceded by blank");
610+ }
611+ if (/^\s*(&&|\|\|)/) {
612+ err("improper boolean continuation");
613+ }
614+ if (/\S *(&&|\|\|)/ || /(&&|\|\|) *\S/) {
615+ err("more than one space around boolean operator");
616+ }
617+ if (/\b(for|if|while|switch|sizeof|alignof|return|case)\(/) {
618+ err("missing space between keyword and paren");
619+ }
620+ if (/(\b(for|if|while|switch|return)\b.*){2,}/ && !/^#define/) {
621+ # multiple "case" and "sizeof" allowed
622+ err("more than one keyword on line");
623+ }
624+ if (/\b(for|if|while|switch|sizeof|alignof|return|case)\s\s+\(/ &&
625+ !/^#if\s+\(/) {
626+ err("extra space between keyword and paren");
627+ }
628+ # try to detect "func (x)" but not "if (x)" or
629+ # "#define foo (x)" or "int (*func)();"
630+ if (/\w\s\(/) {
631+ my $s = $_;
632+ # strip off all keywords on the line
633+ s/\b(for|if|while|switch|return|case|alignof|sizeof)\s\(/XXX(/g;
634+ s/#elif\s\(/XXX(/g;
635+ s/^#define\s+\w+\s+\(/XXX(/;
636+ # do not match things like "void (*f)();"
637+ # or "typedef void (func_t)();"
638+ s/\w\s\(+\*/XXX(*/g;
639+ s/\b($typename|void)\s+\(+/XXX(/og;
640+ if (/\w\s\(/) {
641+ err("extra space between function name and left paren");
642+ }
643+ $_ = $s;
644+ }
645+ # try to detect "int foo(x)", but not "extern int foo(x);"
646+ # XXX - this still trips over too many legitimate things,
647+ # like "int foo(x,\n\ty);"
648+# if (/^(\w+(\s|\*)+)+\w+\(/ && !/\)[;,](\s|)*$/ &&
649+# !/^(extern|static)\b/) {
650+# err("return type of function not on separate line");
651+# }
652+ # this is a close approximation
653+ if (/^(\w+(\s|\*)+)+\w+\(.*\)(\s|)*$/ &&
654+ !/^(extern|static)\b/) {
655+ err("return type of function not on separate line");
656+ }
657+ if (/^#define /) {
658+ err("#define followed by space instead of tab");
659+ }
660+ if (/^\s*return\W[^;]*;/ && !/^\s*return\s*\(.*\);/) {
661+ err("unparenthesized return expression");
662+ }
663+ if (/\bsizeof\b/ && !/\bsizeof\s*\(.*\)/) {
664+ err("unparenthesized sizeof expression");
665+ }
666+ if (/\balignof\b/ && !/\balignof\s*\(.*\)/) {
667+ err("unparenthesized alignof expression");
668+ }
669+ if (/\(\s/) {
670+ err("whitespace after left paren");
671+ }
672+ # allow "for" statements to have empty "continue" clauses
673+ if (/\s\)/ && !/^\s*for \([^;]*;[^;]*; \)/) {
674+ err("whitespace before right paren");
675+ }
676+ if (/^\s*\(void\)[^ ]/) {
677+ err("missing space after (void) cast");
678+ }
679+ if (/\S\{/ && !/\{\{/) {
680+ err("missing space before left brace");
681+ }
682+ if ($in_function && /^\s+\{/ &&
683+ ($prev =~ /\)\s*$/ || $prev =~ /\bstruct\s+\w+$/)) {
684+ err("left brace starting a line");
685+ }
686+ if (/\}(else|while)/) {
687+ err("missing space after right brace");
688+ }
689+ if (/\}\s\s+(else|while)/) {
690+ err("extra space after right brace");
691+ }
692+ if (/\b_VOID\b|\bVOID\b|\bSTATIC\b/) {
693+ err("obsolete use of VOID or STATIC");
694+ }
695+ if (/\b$typename\*/o) {
696+ err("missing space between type name and *");
697+ }
698+ if (/^\s+#/) {
699+ err("preprocessor statement not in column 1");
700+ }
701+ if (/^#\s/) {
702+ err("blank after preprocessor #");
703+ }
704+ if (/!\s*(strcmp|strncmp|bcmp)\s*\(/) {
705+ err("don't use boolean ! with comparison functions");
706+ }
707+
708+ #
709+ # We completely ignore, for purposes of indentation:
710+ # * lines outside of functions
711+ # * preprocessor lines
712+ #
713+ if ($check_continuation && $in_function && !$in_cpp) {
714+ process_indent($_);
715+ }
716+ if ($picky) {
717+ # try to detect spaces after casts, but allow (e.g.)
718+ # "sizeof (int) + 1", "void (*funcptr)(int) = foo;", and
719+ # "int foo(int) __NORETURN;"
720+ if ((/^\($typename( \*+)?\)\s/o ||
721+ /\W\($typename( \*+)?\)\s/o) &&
722+ !/sizeof\s*\($typename( \*)?\)\s/o &&
723+ !/\($typename( \*+)?\)\s+=[^=]/o) {
724+ err("space after cast");
725+ }
726+ if (/\b$typename\s*\*\s/o &&
727+ !/\b$typename\s*\*\s+const\b/o) {
728+ err("unary * followed by space");
729+ }
730+ }
731+ if ($check_posix_types) {
732+ # try to detect old non-POSIX types.
733+ # POSIX requires all non-standard typedefs to end in _t,
734+ # but historically these have been used.
735+ my $types = join '|', keys %old2posix;
736+ if (/\b($types)\b/) {
737+ err("non-POSIX typedef $1 used: use $old2posix{$1} instead");
738+ }
739+ }
740+ if ($heuristic) {
741+ # cannot check this everywhere due to "struct {\n...\n} foo;"
742+ if ($in_function && !$in_declaration &&
743+ /\}./ && !/\}\s+=/ && !/\{.*\}[;,]$/ && !/\}(\s|)*$/ &&
744+ !/\} (else|while)/ && !/\}\}/) {
745+ err("possible bad text following right brace");
746+ }
747+ # cannot check this because sub-blocks in
748+ # the middle of code are ok
749+ if ($in_function && /^\s+\{/) {
750+ err("possible left brace starting a line");
751+ }
752+ }
753+ if (/^\s*else\W/) {
754+ if ($prev =~ /^\s*\}$/) {
755+ err_prefix($prev,
756+ "else and right brace should be on same line");
757+ }
758+ }
759+ $prev = $line;
760+}
761+
762+if ($prev eq "") {
763+ err("last line in file is blank");
764+}
765+
766+}
767+
768+#
769+# Continuation-line checking
770+#
771+# The rest of this file contains the code for the continuation checking
772+# engine. It's a pretty simple state machine which tracks the expression
773+# depth (unmatched '('s and '['s).
774+#
775+# Keep in mind that the argument to process_indent() has already been heavily
776+# processed; all comments have been replaced by control-A, and the contents of
777+# strings and character constants have been elided.
778+#
779+
780+my $cont_in; # currently inside of a continuation
781+my $cont_off; # skipping an initializer or definition
782+my $cont_noerr; # suppress cascading errors
783+my $cont_start; # the line being continued
784+my $cont_base; # the base indentation
785+my $cont_first; # this is the first line of a statement
786+my $cont_multiseg; # this continuation has multiple segments
787+
788+my $cont_special; # this is a C statement (if, for, etc.)
789+my $cont_macro; # this is a macro
790+my $cont_case; # this is a multi-line case
791+
792+my @cont_paren; # the stack of unmatched ( and [s we've seen
793+
794+sub
795+reset_indent()
796+{
797+ $cont_in = 0;
798+ $cont_off = 0;
799+}
800+
801+sub
802+delabel($)
803+{
804+ #
805+ # replace labels with tabs. Note that there may be multiple
806+ # labels on a line.
807+ #
808+ local $_ = $_[0];
809+
810+ while (/^(\t*)( *(?:(?:\w+\s*)|(?:case\b[^:]*)): *)(.*)$/) {
811+ my ($pre_tabs, $label, $rest) = ($1, $2, $3);
812+ $_ = $pre_tabs;
813+ while ($label =~ s/^([^\t]*)(\t+)//) {
814+ $_ .= "\t" x (length($2) + length($1) / 8);
815+ }
816+ $_ .= ("\t" x (length($label) / 8)).$rest;
817+ }
818+
819+ return ($_);
820+}
821+
822+sub
823+process_indent($)
824+{
825+ require strict;
826+ local $_ = $_[0]; # preserve the global $_
827+
828+ s///g; # No comments
829+ s/\s+$//; # Strip trailing whitespace
830+
831+ return if (/^$/); # skip empty lines
832+
833+ # regexps used below; keywords taking (), macros, and continued cases
834+ my $special = '(?:(?:\}\s*)?else\s+)?(?:if|for|while|switch)\b';
835+ my $macro = '[A-Z_][A-Z_0-9]*\(';
836+ my $case = 'case\b[^:]*$';
837+
838+ # skip over enumerations, array definitions, initializers, etc.
839+ if ($cont_off <= 0 && !/^\s*$special/ &&
840+ (/(?:(?:\b(?:enum|struct|union)\s*[^\{]*)|(?:\s+=\s*))\{/ ||
841+ (/^\s*\{/ && $prev =~ /=\s*(?:\/\*.*\*\/\s*)*$/))) {
842+ $cont_in = 0;
843+ $cont_off = tr/{/{/ - tr/}/}/;
844+ return;
845+ }
846+ if ($cont_off) {
847+ $cont_off += tr/{/{/ - tr/}/}/;
848+ return;
849+ }
850+
851+ if (!$cont_in) {
852+ $cont_start = $line;
853+
854+ if (/^\t* /) {
855+ err("non-continuation indented 4 spaces");
856+ $cont_noerr = 1; # stop reporting
857+ }
858+ $_ = delabel($_); # replace labels with tabs
859+
860+ # check if the statement is complete
861+ return if (/^\s*\}?$/);
862+ return if (/^\s*\}?\s*else\s*\{?$/);
863+ return if (/^\s*do\s*\{?$/);
864+ return if (/\{$/);
865+ return if (/\}[,;]?$/);
866+
867+ # Allow macros on their own lines
868+ return if (/^\s*[A-Z_][A-Z_0-9]*$/);
869+
870+ # cases we don't deal with, generally non-kosher
871+ if (/\{/) {
872+ err("stuff after {");
873+ return;
874+ }
875+
876+ # Get the base line, and set up the state machine
877+ /^(\t*)/;
878+ $cont_base = $1;
879+ $cont_in = 1;
880+ @cont_paren = ();
881+ $cont_first = 1;
882+ $cont_multiseg = 0;
883+
884+ # certain things need special processing
885+ $cont_special = /^\s*$special/? 1 : 0;
886+ $cont_macro = /^\s*$macro/? 1 : 0;
887+ $cont_case = /^\s*$case/? 1 : 0;
888+ } else {
889+ $cont_first = 0;
890+
891+ # Strings may be pulled back to an earlier (half-)tabstop
892+ unless ($cont_noerr || /^$cont_base / ||
893+ (/^\t*(?: )?(?:gettext\()?\"/ && !/^$cont_base\t/)) {
894+ err_prefix($cont_start,
895+ "continuation should be indented 4 spaces");
896+ }
897+ }
898+
899+ my $rest = $_; # keeps the remainder of the line
900+
901+ #
902+ # The split matches 0 characters, so that each 'special' character
903+ # is processed separately. Parens and brackets are pushed and
904+ # popped off the @cont_paren stack. For normal processing, we wait
905+ # until a ; or { terminates the statement. "special" processing
906+ # (if/for/while/switch) is allowed to stop when the stack empties,
907+ # as is macro processing. Case statements are terminated with a :
908+ # and an empty paren stack.
909+ #
910+ foreach $_ (split /[^\(\)\[\]\{\}\;\:]*/) {
911+ next if (length($_) == 0);
912+
913+ # rest contains the remainder of the line
914+ my $rxp = "[^\Q$_\E]*\Q$_\E";
915+ $rest =~ s/^$rxp//;
916+
917+ if (/\(/ || /\[/) {
918+ push @cont_paren, $_;
919+ } elsif (/\)/ || /\]/) {
920+ my $cur = $_;
921+ tr/\)\]/\(\[/;
922+
923+ my $old = (pop @cont_paren);
924+ if (!defined($old)) {
925+ err("unexpected '$cur'");
926+ $cont_in = 0;
927+ last;
928+ } elsif ($old ne $_) {
929+ err("'$cur' mismatched with '$old'");
930+ $cont_in = 0;
931+ last;
932+ }
933+
934+ #
935+ # If the stack is now empty, do special processing
936+ # for if/for/while/switch and macro statements.
937+ #
938+ next if (@cont_paren != 0);
939+ if ($cont_special) {
940+ if ($rest =~ /^\s*\{?$/) {
941+ $cont_in = 0;
942+ last;
943+ }
944+ if ($rest =~ /^\s*;$/) {
945+ err("empty if/for/while body ".
946+ "not on its own line");
947+ $cont_in = 0;
948+ last;
949+ }
950+ if (!$cont_first && $cont_multiseg == 1) {
951+ err_prefix($cont_start,
952+ "multiple statements continued ".
953+ "over multiple lines");
954+ $cont_multiseg = 2;
955+ } elsif ($cont_multiseg == 0) {
956+ $cont_multiseg = 1;
957+ }
958+ # We've finished this section, start
959+ # processing the next.
960+ goto section_ended;
961+ }
962+ if ($cont_macro) {
963+ if ($rest =~ /^$/) {
964+ $cont_in = 0;
965+ last;
966+ }
967+ }
968+ } elsif (/\;/) {
969+ if ($cont_case) {
970+ err("unexpected ;");
971+ } elsif (!$cont_special) {
972+ err("unexpected ;") if (@cont_paren != 0);
973+ if (!$cont_first && $cont_multiseg == 1) {
974+ err_prefix($cont_start,
975+ "multiple statements continued ".
976+ "over multiple lines");
977+ $cont_multiseg = 2;
978+ } elsif ($cont_multiseg == 0) {
979+ $cont_multiseg = 1;
980+ }
981+ if ($rest =~ /^$/) {
982+ $cont_in = 0;
983+ last;
984+ }
985+ if ($rest =~ /^\s*special/) {
986+ err("if/for/while/switch not started ".
987+ "on its own line");
988+ }
989+ goto section_ended;
990+ }
991+ } elsif (/\{/) {
992+ err("{ while in parens/brackets") if (@cont_paren != 0);
993+ err("stuff after {") if ($rest =~ /[^\s}]/);
994+ $cont_in = 0;
995+ last;
996+ } elsif (/\}/) {
997+ err("} while in parens/brackets") if (@cont_paren != 0);
998+ if (!$cont_special && $rest !~ /^\s*(while|else)\b/) {
999+ if ($rest =~ /^$/) {
1000+ err("unexpected }");
1001+ } else {
1002+ err("stuff after }");
1003+ }
1004+ $cont_in = 0;
1005+ last;
1006+ }
1007+ } elsif (/\:/ && $cont_case && @cont_paren == 0) {
1008+ err("stuff after multi-line case") if ($rest !~ /$^/);
1009+ $cont_in = 0;
1010+ last;
1011+ }
1012+ next;
1013+section_ended:
1014+ # End of a statement or if/while/for loop. Reset
1015+ # cont_special and cont_macro based on the rest of the
1016+ # line.
1017+ $cont_special = ($rest =~ /^\s*$special/)? 1 : 0;
1018+ $cont_macro = ($rest =~ /^\s*$macro/)? 1 : 0;
1019+ $cont_case = 0;
1020+ next;
1021+ }
1022+ $cont_noerr = 0 if (!$cont_in);
1023+}
+1,
-0
1@@ -3,6 +3,7 @@ c() { ln -sf $1 $2; }
2 c $PWD/Xdefaults ~/.Xdefaults
3 mkdir -p ~/bin
4 c $PWD/bin/amused-monitor ~/bin/amused-monitor
5+c $PWD/cddl/cstyle ~/bin/cstyle
6 c $PWD/bin/dxmessage ~/bin/dxmessage
7 c $PWD/bin/emifetch ~/bin/emifetch
8 c $PWD/bin/gcc ~/bin/gcc