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 # Copyright 2015 Toomas Soome <tsoome@me.com>
23 # Copyright 2016 Nexenta Systems, Inc.
24 # Copyright 2020 Oxide Computer Company
25 #
26 # Copyright 2008 Sun Microsystems, Inc. All rights reserved.
27 # Use is subject to license terms.
28 #
29 # Copyright (c) 2015 by Delphix. All rights reserved.
30 #
31 # @(#)cstyle 1.58 98/09/09 (from shannon)
32 #
33 # cstyle - check for some common stylistic errors.
34 #
35 # cstyle is a sort of "lint" for C coding style.
36 # It attempts to check for the style used in the
37 # kernel, sometimes known as "Bill Joy Normal Form".
38 #
39 # There's a lot this can't check for, like proper indentation
40 # of code blocks. There's also a lot more this could check for.
41 #
42 # A note to the non perl literate:
43 #
44 # perl regular expressions are pretty much like egrep
596 (/[^!<>=]=[^=\s]/ && !/[^!<>=]=$/)) {
597 # XXX - should only check this for C++ code
598 # XXX - there are probably other forms that should be allowed
599 if (!/\soperator=/) {
600 err("missing space around assignment operator");
601 }
602 }
603 if (/[,;]\S/ && !/\bfor \(;;\)/) {
604 err("comma or semicolon followed by non-blank");
605 }
606 # allow "for" statements to have empty "while" clauses
607 if (/\s[,;]/ && !/^[\t]+;$/ && !/^\s*for \([^;]*; ;[^;]*\)/) {
608 err("comma or semicolon preceded by blank");
609 }
610 if (/^\s*(&&|\|\|)/) {
611 err("improper boolean continuation");
612 }
613 if (/\S *(&&|\|\|)/ || /(&&|\|\|) *\S/) {
614 err("more than one space around boolean operator");
615 }
616 if (/\b(for|if|while|switch|sizeof|return|case)\(/) {
617 err("missing space between keyword and paren");
618 }
619 if (/(\b(for|if|while|switch|return)\b.*){2,}/ && !/^#define/) {
620 # multiple "case" and "sizeof" allowed
621 err("more than one keyword on line");
622 }
623 if (/\b(for|if|while|switch|sizeof|return|case)\s\s+\(/ &&
624 !/^#if\s+\(/) {
625 err("extra space between keyword and paren");
626 }
627 # try to detect "func (x)" but not "if (x)" or
628 # "#define foo (x)" or "int (*func)();"
629 if (/\w\s\(/) {
630 my $s = $_;
631 # strip off all keywords on the line
632 s/\b(for|if|while|switch|return|case|sizeof)\s\(/XXX(/g;
633 s/#elif\s\(/XXX(/g;
634 s/^#define\s+\w+\s+\(/XXX(/;
635 # do not match things like "void (*f)();"
636 # or "typedef void (func_t)();"
637 s/\w\s\(+\*/XXX(*/g;
638 s/\b($typename|void)\s+\(+/XXX(/og;
639 if (/\w\s\(/) {
640 err("extra space between function name and left paren");
641 }
642 $_ = $s;
643 }
644 # try to detect "int foo(x)", but not "extern int foo(x);"
645 # XXX - this still trips over too many legitimate things,
646 # like "int foo(x,\n\ty);"
647 # if (/^(\w+(\s|\*)+)+\w+\(/ && !/\)[;,](\s|)*$/ &&
648 # !/^(extern|static)\b/) {
649 # err("return type of function not on separate line");
650 # }
651 # this is a close approximation
652 if (/^(\w+(\s|\*)+)+\w+\(.*\)(\s|)*$/ &&
653 !/^(extern|static)\b/) {
654 err("return type of function not on separate line");
655 }
656 if (/^#define /) {
657 err("#define followed by space instead of tab");
658 }
659 if (/^\s*return\W[^;]*;/ && !/^\s*return\s*\(.*\);/) {
660 err("unparenthesized return expression");
661 }
662 if (/\bsizeof\b/ && !/\bsizeof\s*\(.*\)/) {
663 err("unparenthesized sizeof expression");
664 }
665 if (/\(\s/) {
666 err("whitespace after left paren");
667 }
668 # allow "for" statements to have empty "continue" clauses
669 if (/\s\)/ && !/^\s*for \([^;]*;[^;]*; \)/) {
670 err("whitespace before right paren");
671 }
672 if (/^\s*\(void\)[^ ]/) {
673 err("missing space after (void) cast");
674 }
675 if (/\S\{/ && !/\{\{/) {
676 err("missing space before left brace");
677 }
678 if ($in_function && /^\s+\{/ &&
679 ($prev =~ /\)\s*$/ || $prev =~ /\bstruct\s+\w+$/)) {
680 err("left brace starting a line");
681 }
682 if (/\}(else|while)/) {
683 err("missing space after right brace");
684 }
|
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 # Copyright 2015 Toomas Soome <tsoome@me.com>
23 # Copyright 2016 Nexenta Systems, Inc.
24 # Copyright 2023 Oxide Computer Company
25 #
26 # Copyright 2008 Sun Microsystems, Inc. All rights reserved.
27 # Use is subject to license terms.
28 #
29 # Copyright (c) 2015 by Delphix. All rights reserved.
30 #
31 # @(#)cstyle 1.58 98/09/09 (from shannon)
32 #
33 # cstyle - check for some common stylistic errors.
34 #
35 # cstyle is a sort of "lint" for C coding style.
36 # It attempts to check for the style used in the
37 # kernel, sometimes known as "Bill Joy Normal Form".
38 #
39 # There's a lot this can't check for, like proper indentation
40 # of code blocks. There's also a lot more this could check for.
41 #
42 # A note to the non perl literate:
43 #
44 # perl regular expressions are pretty much like egrep
596 (/[^!<>=]=[^=\s]/ && !/[^!<>=]=$/)) {
597 # XXX - should only check this for C++ code
598 # XXX - there are probably other forms that should be allowed
599 if (!/\soperator=/) {
600 err("missing space around assignment operator");
601 }
602 }
603 if (/[,;]\S/ && !/\bfor \(;;\)/) {
604 err("comma or semicolon followed by non-blank");
605 }
606 # allow "for" statements to have empty "while" clauses
607 if (/\s[,;]/ && !/^[\t]+;$/ && !/^\s*for \([^;]*; ;[^;]*\)/) {
608 err("comma or semicolon preceded by blank");
609 }
610 if (/^\s*(&&|\|\|)/) {
611 err("improper boolean continuation");
612 }
613 if (/\S *(&&|\|\|)/ || /(&&|\|\|) *\S/) {
614 err("more than one space around boolean operator");
615 }
616 if (/\b(for|if|while|switch|sizeof|alignof|return|case)\(/) {
617 err("missing space between keyword and paren");
618 }
619 if (/(\b(for|if|while|switch|return)\b.*){2,}/ && !/^#define/) {
620 # multiple "case" and "sizeof" allowed
621 err("more than one keyword on line");
622 }
623 if (/\b(for|if|while|switch|sizeof|alignof|return|case)\s\s+\(/ &&
624 !/^#if\s+\(/) {
625 err("extra space between keyword and paren");
626 }
627 # try to detect "func (x)" but not "if (x)" or
628 # "#define foo (x)" or "int (*func)();"
629 if (/\w\s\(/) {
630 my $s = $_;
631 # strip off all keywords on the line
632 s/\b(for|if|while|switch|return|case|alignof|sizeof)\s\(/XXX(/g;
633 s/#elif\s\(/XXX(/g;
634 s/^#define\s+\w+\s+\(/XXX(/;
635 # do not match things like "void (*f)();"
636 # or "typedef void (func_t)();"
637 s/\w\s\(+\*/XXX(*/g;
638 s/\b($typename|void)\s+\(+/XXX(/og;
639 if (/\w\s\(/) {
640 err("extra space between function name and left paren");
641 }
642 $_ = $s;
643 }
644 # try to detect "int foo(x)", but not "extern int foo(x);"
645 # XXX - this still trips over too many legitimate things,
646 # like "int foo(x,\n\ty);"
647 # if (/^(\w+(\s|\*)+)+\w+\(/ && !/\)[;,](\s|)*$/ &&
648 # !/^(extern|static)\b/) {
649 # err("return type of function not on separate line");
650 # }
651 # this is a close approximation
652 if (/^(\w+(\s|\*)+)+\w+\(.*\)(\s|)*$/ &&
653 !/^(extern|static)\b/) {
654 err("return type of function not on separate line");
655 }
656 if (/^#define /) {
657 err("#define followed by space instead of tab");
658 }
659 if (/^\s*return\W[^;]*;/ && !/^\s*return\s*\(.*\);/) {
660 err("unparenthesized return expression");
661 }
662 if (/\bsizeof\b/ && !/\bsizeof\s*\(.*\)/) {
663 err("unparenthesized sizeof expression");
664 }
665 if (/\balignof\b/ && !/\balignof\s*\(.*\)/) {
666 err("unparenthesized alignof expression");
667 }
668 if (/\(\s/) {
669 err("whitespace after left paren");
670 }
671 # allow "for" statements to have empty "continue" clauses
672 if (/\s\)/ && !/^\s*for \([^;]*;[^;]*; \)/) {
673 err("whitespace before right paren");
674 }
675 if (/^\s*\(void\)[^ ]/) {
676 err("missing space after (void) cast");
677 }
678 if (/\S\{/ && !/\{\{/) {
679 err("missing space before left brace");
680 }
681 if ($in_function && /^\s+\{/ &&
682 ($prev =~ /\)\s*$/ || $prev =~ /\bstruct\s+\w+$/)) {
683 err("left brace starting a line");
684 }
685 if (/\}(else|while)/) {
686 err("missing space after right brace");
687 }
|