jstyle.sh revision 7c478bd95313f5f23a4c958a745db2134aa03244
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License, Version 1.0 only
# (the "License"). You may not use this file except in compliance
# with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
eval 'exec perl -S $0 "$@"'
if 0;
#
#ident "%Z%%M% %I% %E% SMI"
#
# Copyright (c) 1991-1997 by Sun Microsystems, Inc.
# All rights reserved.
#
# jstyle - check for some common stylistic errors.
#
# jstyle is a sort of "lint" for Java coding style.
#
# There's a lot this can't check for, like proper
# indentation of continuation lines. There's also
# a lot more this could check for.
#
# A note to the non perl literate:
#
# perl regular expressions are pretty much like egrep
# regular expressions, with the following special symbols
#
# \s any space character
# \S any non-space character
# \w any "word" character [a-zA-Z0-9_]
# \W any non-word character
# \d a digit [0-9]
# \D a non-digit
# \b word boundary (between \w and \W)
# \B non-word boundary
#
#require "getopts.pl";
# XXX - because some versions of perl can not find the lib directory,
# we just include this here.
;# getopts.pl - a better getopt.pl
;# Usage:
;# do Getopts("a:bc"); # -a takes arg. -b & -c not. Sets opt_* as a
;# # side effect.
sub Getopts {
local($[) = 0;
}
}
else {
}
else {
}
}
}
else {
++$errs;
}
else {
}
}
}
$errs == 0;
}
1;
# end of getopts.pl
$usage =
"usage: jstyle [-c] [-h] [-p] [-s] [-t] [-v] [-C] file ...
-c check continuation line indenting
-h perform heuristic checks that are sometimes wrong
-p perform some of the more picky checks
-s check for spaces vs. tabs
-t insist on indenting by tabs
-v verbose
-C don't check anything in header block comments
";
print $usage;
exit 1;
}
$heuristic = $opt_h;
if ($verbose) {
} else {
}
# Note, following must be in single quotes so that \s and \w work right.
$typename = '(int|char|boolean|byte|short|long|float|double)';
if ($#ARGV >= 0) {
} else {
}
}
} else {
}
sub err {
}
sub jstyle {
$in_comment = 0;
$in_header_comment = 0;
$in_continuation = 0;
$in_class = 0;
$in_declaration = 0;
$note_level = 0;
$nextok = 0;
$nocheck = 0;
$expect_continuation = 0;
$filename = $_[0];
s/\r?\n$//; # strip return and newline
# save the original line, then remove all text from within
# double or single quotes, we do not want to check such text.
$line = $_;
s/"[^"]*"/\"\"/g;
s/'.'/''/g;
# an /* END JSTYLED */ comment ends a no-check block.
if ($nocheck) {
if (/\/\* *END *JSTYLED *\*\//) {
$nocheck = 0;
} else {
next line;
}
}
# a /*JSTYLED*/ comment indicates that the next line is ok.
if ($nextok) {
if ($okmsg) {
do err($okmsg);
}
$nextok = 0;
$okmsg = 0;
if (/\/\* *JSTYLED.*\*\//) {
/^.*\/\* *JSTYLED *(.*) *\*\/.*$/;
$okmsg = $1;
$nextok = 1;
}
next line;
}
# remember whether we expect to be inside a continuation line.
# check for proper continuation line. blank lines
# in the middle of the
# continuation do not count.
# XXX - only check within functions.
if ($check_continuation && $expect_continuation && $in_class &&
!/^\s*$/) {
# continuation line must start with whitespace of
# previous line, plus either 4 spaces or a tab, but
# do not check lines that start with a string constant
# since they are often shifted to the left to make them
# fit on the line.
if (!/^$continuation_indent \S/ &&
}
$expect_continuation = 0;
}
# a /* BEGIN JSTYLED */ comment starts a no-check block.
$nocheck = 1;
}
# a /*JSTYLED*/ comment indicates that the next line is ok.
$okmsg = $1;
$nextok = 1;
}
$okmsg = $1;
$nextok = 1;
}
# is this the beginning or ending of a class?
$in_class = 1;
$in_declaration = 1;
next line;
}
if (/^}\s*(\/\*.*\*\/\s*)*$/) {
$in_class = 0;
next line;
}
# strip trailing spaces
s/\s*$//;
}
# does this looks like the start of a block comment?
if (/^\s*\/\*(\*|)$/) {
if (!/^(\t| )*\/\*(\*|)$/) {
}
$in_comment = 1;
s/\/\*(\*|)/ /;
$comment_prefix = $_;
$in_header_comment = 1;
}
next line;
}
if (/^\s*\/\*./ && !/^\s*\/\*\*$/ && !/^\s*\/\*.*\*\//) {
# it's a bad one, but it still is one.
# avoid ripple effect of not recognizing this.
if (!/^(\t| )*\/\*(\*|)/) {
}
$in_comment = 1;
s/\/\*.*/ /;
$comment_prefix = $_;
$in_header_comment = 1;
}
next line;
}
# are we still in the block comment?
# assume out of comment
$in_comment = 0;
$in_header_comment = 0;
}
next line;
}
# check for errors that might occur in comments and in code.
# check length of line.
# first, a quick check to see if there is any chance of being too long.
# yes, there is a chance.
# replace tabs with spaces and check again.
1 while $eline =~
}
}
# this is the fastest way to check line length,
# but it doesnt work with perl 3.0.
# if ($line =~ tr/\t/\t/ * 7 + length($line) > 80) {
# $pos = $oldp = $p = 0;
# while (($p = index($line, "\t", $p)) >= 0) {
# $pos = ($pos + $p - $oldp + 8) & ~7;
# $oldp = ++$p;
# }
# $pos += length($line) - $oldp;
# if ($pos > 80) {
# do err("line > 80 characters");
# }
# }
# allow spaces to be used to draw pictures in header comments.
}
if ($tabs && /^ / && !/^ \*[ \t\/]/ && !/^ \*$/ &&
}
}
}
if (0) {
if (/^[\t]+ [^ \t\*]/ || /^[\t]+ \S/ || /^[\t]+ \S/) {
}
}
if (/[^ \t(]\/\*/ && !/\w\(\/\*.*\*\/\);/) {
}
}
}
next line;
}
if ((/\/\*\S/ && !/\/\*\*/) || /\/\*\*\S/) {
}
if (/\S\*\//) {
}
# allow // at beginnging of line, often used to comment out code
if (/.\/\/\S/) { # C++ comments
}
# check for unterminated single line comments.
if (/\S.*\/\*/ && !/\S.*\/\*.*\*\//) {
}
# delete any comments and check everything else.
s/\/\*.*\*\///g;
s/\/\/.*$//; # C++ comments
# delete any trailing whitespace; we have already checked for that.
s/\s*$//;
# following checks do not apply to text in comments.
# if it looks like an operator at the end of the line, and it is
# not really the end of a comment (...*/), and it is not really
# a label (done:), and it is not a case label (case FOO:),
# or we are not in a function definition (ANSI C style) and the
# operator is a "," (to avoid hitting "int\nfoo(\n\tint i,\n\tint j)"),
# or we are in a function and the operator is a
# "*" (to avoid hitting on "char*\nfunc()").
if ((/[-+|&\/?:=]$/ && !/\*\/$/ && !/^\s*\w*:$/ &&
!/^\s\s*case\s\s*\w*:$/) ||
/,$/ ||
$expect_continuation = 1;
/^(\s*)\S/;
$continuation_indent = $1;
}
}
if (/[^<>\s][!<>=]=/ || /[^<>][!<>=]=\S/ ||
(/[^->]>[^=>\s]/ && !/[^->]>$/) || (/[^<]<[^=<\s]/ && !/[^<]<$/) ||
/[^<\s]<[^<]/ || /[^->\s]>[^>]/) {
}
if (/\S>>=/ || /\S<<=/ || />>=\S/ || /<<=\S/ || /\S[-+*\/&|^%]=/ ||
(/[^-+*\/&|^%!<>=\s]=[^=]/ && !/[^-+*\/&|^%!<>=\s]=$/) ||
(/[^!<>=]=[^=\s]/ && !/[^!<>=]=$/)) {
}
}
# allow "for" statements to have empty "while" clauses
if (/\s[,;]/ && !/^[\t]+;$/ && !/^\s*for \([^;]*; ;[^;]*\)/) {
}
if (0) {
if (/^\s*(&&|\|\|)/) {
}
}
}
}
# multiple "case" allowed
}
!/^#if\s+\(/) {
}
# try to detect "func (x)" but not "if (x)" or
# "int (*func)();"
if (/\w\s\(/) {
$s = $_;
# strip off all keywords on the line
#s/\b($typename|void)\s+\(+/XXX(/og;
if (/\w\s\(/) {
}
$_ = $s;
}
if (/\(\s/) {
}
# allow "for" statements to have empty "continue" clauses
if (/\s\)/ && !/^\s*for \([^;]*;[^;]*; \)/) {
}
if (/^\s*\(void\)[^ ]/) {
}
if (/\S{/ && !/{{/) {
}
}
if (/}(else|while)/) {
}
if (/}\s\s+(else|while)/) {
}
}
# cannot check this everywhere due to "struct {\n...\n} foo;"
if ($in_class && !$in_declaration &&
/}./ && !/}\s+=/ && !/{.*}[;,]$/ && !/}(\s|)*$/ &&
!/} (else|while)/ && !/}}/) {
}
# cannot check this because sub-blocks in
# the middle of code are ok
}
}
if (/^\s*else\W/) {
}
}
}
}
}
}