19512fe85Sahl#!/usr/perl5/bin/perl
29512fe85Sahl#
39512fe85Sahl# CDDL HEADER START
49512fe85Sahl#
59512fe85Sahl# The contents of this file are subject to the terms of the
69512fe85Sahl# Common Development and Distribution License (the "License").
79512fe85Sahl# You may not use this file except in compliance with the License.
89512fe85Sahl#
99512fe85Sahl# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
109512fe85Sahl# or http://www.opensolaris.org/os/licensing.
119512fe85Sahl# See the License for the specific language governing permissions
129512fe85Sahl# and limitations under the License.
139512fe85Sahl#
149512fe85Sahl# When distributing Covered Code, include this CDDL HEADER in each
159512fe85Sahl# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
169512fe85Sahl# If applicable, add the following below this CDDL HEADER, with the
179512fe85Sahl# fields enclosed by brackets "[]" replaced with your own identifying
189512fe85Sahl# information: Portions Copyright [yyyy] [name of copyright owner]
199512fe85Sahl#
209512fe85Sahl# CDDL HEADER END
219512fe85Sahl#
229512fe85Sahl
239512fe85Sahl#
24df0345f7SJohn Sonnenschein# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
259512fe85Sahl# Use is subject to license terms.
269512fe85Sahl#
279512fe85Sahl
28*c3bd3abdSMatthew Ahrens#
29*c3bd3abdSMatthew Ahrens# Copyright (c) 2014, 2016 by Delphix. All rights reserved.
30*c3bd3abdSMatthew Ahrens#
31*c3bd3abdSMatthew Ahrens
32df0345f7SJohn Sonnenscheinrequire 5.8.4;
339512fe85Sahl
349512fe85Sahl$PNAME = $0;
359512fe85Sahl$PNAME =~ s:.*/::;
369512fe85Sahl$USAGE = "Usage: $PNAME [file ...]\n";
379512fe85Sahl$errs = 0;
389512fe85Sahl
399512fe85Sahlsub err
409512fe85Sahl{
419512fe85Sahl	my($msg) = @_;
429512fe85Sahl
439512fe85Sahl	print "$file: $lineno: $msg\n";
449512fe85Sahl	$errs++;
459512fe85Sahl}
469512fe85Sahl
479512fe85Sahlsub dstyle
489512fe85Sahl{
499512fe85Sahl	open(FILE, "$file");
509512fe85Sahl	$lineno = 0;
519512fe85Sahl	$inclause = 0;
529512fe85Sahl	$skipnext = 0;
539512fe85Sahl
549512fe85Sahl	while (<FILE>) {
559512fe85Sahl		$lineno++;
569512fe85Sahl
579512fe85Sahl		chop;
589512fe85Sahl
599512fe85Sahl		if ($skipnext) {
609512fe85Sahl			$skipnext = 0;
619512fe85Sahl			next;
629512fe85Sahl		}
639512fe85Sahl
649512fe85Sahl		#
659512fe85Sahl		# Amazingly, some ident strings are longer than 80 characters!
669512fe85Sahl		#
679512fe85Sahl		if (/^#pragma ident/) {
689512fe85Sahl			next;
699512fe85Sahl		}
709512fe85Sahl
719512fe85Sahl		#
729512fe85Sahl		# The algorithm to calculate line length from cstyle.
739512fe85Sahl		#
749512fe85Sahl		$line = $_;
759512fe85Sahl		if ($line =~ tr/\t/\t/ * 7 + length($line) > 80) {
769512fe85Sahl			# yes, there is a chance.
779512fe85Sahl			# replace tabs with spaces and check again.
789512fe85Sahl			$eline = $line;
799512fe85Sahl			1 while $eline =~
809512fe85Sahl			    s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e;
819512fe85Sahl
829512fe85Sahl			if (length($eline) > 80) {
839512fe85Sahl				err "line > 80 characters";
849512fe85Sahl			}
859512fe85Sahl		}
869512fe85Sahl
879512fe85Sahl		if (/\/\*DSTYLED\*\//) {
889512fe85Sahl			$skipnext = 1;
899512fe85Sahl			next;
909512fe85Sahl		}
919512fe85Sahl
929512fe85Sahl		if (/^#pragma/) {
939512fe85Sahl			next;
949512fe85Sahl		}
959512fe85Sahl
969512fe85Sahl		if (/^#include/) {
979512fe85Sahl			next;
989512fe85Sahl		}
999512fe85Sahl
1009512fe85Sahl		#
1019512fe85Sahl		# Before we do any more analysis, we want to prune out any
1029512fe85Sahl		# quoted strings.  This is a bit tricky because we need
1039512fe85Sahl		# to be careful of backslashed quotes within quoted strings.
1049512fe85Sahl		# I'm sure there is a very crafty way to do this with a
1059512fe85Sahl		# single regular expression, but that will have to wait for
1069512fe85Sahl		# somone with better regex juju that I; we do this by first
1079512fe85Sahl		# eliminating the backslashed quotes, and then eliminating
1089512fe85Sahl		# whatever quoted strings are left.  Note that we eliminate
1099512fe85Sahl		# the string by replacing it with "quotedstr"; this is to
1109512fe85Sahl		# allow lines to end with a quoted string.  (If we simply
1119512fe85Sahl		# eliminated the quoted string, dstyle might complain about
1129512fe85Sahl		# the line ending in a space or tab.)
1139512fe85Sahl		#
1149512fe85Sahl		s/\\\"//g;
1159512fe85Sahl		s/\"[^\"]*\"/quotedstr/g;
1169512fe85Sahl
1179512fe85Sahl		if (/[ \t]$/) {
1189512fe85Sahl			err "space or tab at end of line";
1199512fe85Sahl		}
1209512fe85Sahl
1219512fe85Sahl		if (/^[\t]+[ ]+[\t]+/) {
1229512fe85Sahl			err "spaces between tabs";
1239512fe85Sahl		}
1249512fe85Sahl
1259512fe85Sahl		if (/^[\t]* \*/) {
1269512fe85Sahl			next;
1279512fe85Sahl		}
1289512fe85Sahl
1299512fe85Sahl		if (/^        /) {
1309512fe85Sahl			err "indented by spaces not tabs";
1319512fe85Sahl		}
1329512fe85Sahl
1339512fe85Sahl		if (/^{}$/) {
1349512fe85Sahl			next;
1359512fe85Sahl		}
1369512fe85Sahl
1379512fe85Sahl		if (!/^enum/ && !/^\t*struct/ && !/^\t*union/ && !/^typedef/ &&
138*c3bd3abdSMatthew Ahrens		    !/^translator/ && !/^provider/ && !/\tif / &&
139*c3bd3abdSMatthew Ahrens		    !/ else /) {
1409512fe85Sahl			if (/[\w\s]+{/) {
1419512fe85Sahl				err "left brace not on its own line";
1429512fe85Sahl			}
1439512fe85Sahl
1449512fe85Sahl			if (/{[\w\s]+/) {
1459512fe85Sahl				err "left brace not on its own line";
1469512fe85Sahl			}
1479512fe85Sahl		}
1489512fe85Sahl
149*c3bd3abdSMatthew Ahrens		if (!/;$/ && !/\t*}$/ && !/ else /) {
1509512fe85Sahl			if (/[\w\s]+}/) {
1519512fe85Sahl				err "right brace not on its own line";
1529512fe85Sahl			}
1539512fe85Sahl
1549512fe85Sahl			if (/}[\w\s]+/) {
1559512fe85Sahl				err "right brace not on its own line";
1569512fe85Sahl			}
1579512fe85Sahl		}
1589512fe85Sahl
1599512fe85Sahl		if (/^}/) {
1609512fe85Sahl			$inclause = 0;
1619512fe85Sahl		}
1629512fe85Sahl
1639512fe85Sahl		if (!$inclause && /^[\w ]+\//) {
1649512fe85Sahl			err "predicate not at beginning of line";
1659512fe85Sahl		}
1669512fe85Sahl
1679512fe85Sahl		if (!$inclause && /^\/[ \t]+\w/) {
1689512fe85Sahl			err "space between '/' and expression in predicate";
1699512fe85Sahl		}
1709512fe85Sahl
1719512fe85Sahl		if (!$inclause && /\w[ \t]+\/$/) {
1729512fe85Sahl			err "space between expression and '/' in predicate";
1739512fe85Sahl		}
1749512fe85Sahl
1759512fe85Sahl		if (!$inclause && /\s,/) {
1769512fe85Sahl			err "space before comma in probe description";
1779512fe85Sahl		}
1789512fe85Sahl
1799512fe85Sahl		if (!$inclause && /\w,[\w\s]/ && !/;$/) {
1809512fe85Sahl			if (!/extern/ && !/\(/ && !/inline/) {
1819512fe85Sahl				err "multiple probe descriptions on same line";
1829512fe85Sahl			}
1839512fe85Sahl		}
1849512fe85Sahl
1859512fe85Sahl		if ($inclause && /sizeof\(/) {
1869512fe85Sahl			err "missing space after sizeof";
1879512fe85Sahl		}
1889512fe85Sahl
1899512fe85Sahl		if ($inclause && /^[\w ]/) {
1909512fe85Sahl			err "line doesn't begin with a tab";
1919512fe85Sahl		}
1929512fe85Sahl
1939512fe85Sahl		if ($inclause && /,[\w]/) {
1949512fe85Sahl			err "comma without trailing space";
1959512fe85Sahl		}
1969512fe85Sahl
1979512fe85Sahl		if (/\w&&/ || /&&\w/ || /\w\|\|/ || /\|\|\w/) {
1989512fe85Sahl			err "logical operator not set off with spaces";
1999512fe85Sahl		}
2009512fe85Sahl
2019512fe85Sahl		#
2029512fe85Sahl		# We want to catch "i<0" variants, but we don't want to
2039512fe85Sahl		# erroneously flag translators.
2049512fe85Sahl		#
2059512fe85Sahl		if (!/\w<\w+>\(/) {
2069512fe85Sahl			if (/\w>/ || / >\w/ || /\w</ || /<\w/) {
2079512fe85Sahl				err "comparison operator not set " .
2089512fe85Sahl				    "off with spaces";
2099512fe85Sahl			}
2109512fe85Sahl		}
2119512fe85Sahl
2129512fe85Sahl		if (/\w==/ || /==\w/ || /\w<=/ || />=\w/ || /\w!=/ || /!=\w/) {
2139512fe85Sahl			err "comparison operator not set off with spaces";
2149512fe85Sahl		}
2159512fe85Sahl
2169512fe85Sahl		if (/\w=/ || /=\w/) {
2179512fe85Sahl			err "assignment operator not set off with spaces";
2189512fe85Sahl		}
2199512fe85Sahl
2209512fe85Sahl		if (/^{/) {
2219512fe85Sahl			$inclause = 1;
2229512fe85Sahl		}
2239512fe85Sahl        }
2249512fe85Sahl}
2259512fe85Sahl
2269512fe85Sahlforeach $arg (@ARGV) {
2279512fe85Sahl	if (-f $arg) {
2289512fe85Sahl		push(@files, $arg);
2299512fe85Sahl	} else {
2309512fe85Sahl		die "$PNAME: $arg is not a valid file\n";
2319512fe85Sahl	}
2329512fe85Sahl}
2339512fe85Sahl
2349512fe85Sahldie $USAGE if (scalar(@files) == 0);
2359512fe85Sahl
2369512fe85Sahlforeach $file (@files) {
2379512fe85Sahl	dstyle($file);
2389512fe85Sahl}
2399512fe85Sahl
2409512fe85Sahlexit($errs != 0);
241