xref: /titanic_54/usr/src/tools/onbld/Checks/Cddl.py (revision cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0)
1*cdf0c1d5Smjnelson#! /usr/bin/python
2*cdf0c1d5Smjnelson
3*cdf0c1d5SmjnelsonCDDL = '''
4*cdf0c1d5SmjnelsonCDDL HEADER START
5*cdf0c1d5Smjnelson
6*cdf0c1d5SmjnelsonThe contents of this file are subject to the terms of the
7*cdf0c1d5SmjnelsonCommon Development and Distribution License (the "License").
8*cdf0c1d5SmjnelsonYou may not use this file except in compliance with the License.
9*cdf0c1d5Smjnelson
10*cdf0c1d5SmjnelsonYou can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11*cdf0c1d5Smjnelsonor http://www.opensolaris.org/os/licensing.
12*cdf0c1d5SmjnelsonSee the License for the specific language governing permissions
13*cdf0c1d5Smjnelsonand limitations under the License.
14*cdf0c1d5Smjnelson
15*cdf0c1d5SmjnelsonWhen distributing Covered Code, include this CDDL HEADER in each
16*cdf0c1d5Smjnelsonfile and include the License file at usr/src/OPENSOLARIS.LICENSE.
17*cdf0c1d5SmjnelsonIf applicable, add the following below this CDDL HEADER, with the
18*cdf0c1d5Smjnelsonfields enclosed by brackets "[]" replaced with your own identifying
19*cdf0c1d5Smjnelsoninformation: Portions Copyright [yyyy] [name of copyright owner]
20*cdf0c1d5Smjnelson
21*cdf0c1d5SmjnelsonCDDL HEADER END
22*cdf0c1d5Smjnelson'''
23*cdf0c1d5Smjnelson
24*cdf0c1d5Smjnelson#
25*cdf0c1d5Smjnelson# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
26*cdf0c1d5Smjnelson# Use is subject to license terms.
27*cdf0c1d5Smjnelson#
28*cdf0c1d5Smjnelson# ident	"%Z%%M%	%I%	%E% SMI"
29*cdf0c1d5Smjnelson#
30*cdf0c1d5Smjnelson
31*cdf0c1d5Smjnelson#
32*cdf0c1d5Smjnelson# Check source files contain a valid CDDL block
33*cdf0c1d5Smjnelson#
34*cdf0c1d5Smjnelson
35*cdf0c1d5Smjnelsonimport re, sys
36*cdf0c1d5Smjnelson
37*cdf0c1d5SmjnelsonCDDL = CDDL.splitlines()[1:]		# Don't include initial \n
38*cdf0c1d5Smjnelson
39*cdf0c1d5SmjnelsonCmntChrs = r'#*!/\\";. '
40*cdf0c1d5SmjnelsonCDDLStartRE = re.compile(r'^[%s ]*CDDL HEADER START' % CmntChrs)
41*cdf0c1d5SmjnelsonCDDLEndRE = re.compile(r'^[%s ]*CDDL HEADER END' % CmntChrs)
42*cdf0c1d5Smjnelson
43*cdf0c1d5Smjnelsonclass CddlError(Exception):
44*cdf0c1d5Smjnelson	def __init__(self, lineno, seen, shouldbe):
45*cdf0c1d5Smjnelson		Exception.__init__(self)
46*cdf0c1d5Smjnelson		self.lineno = lineno
47*cdf0c1d5Smjnelson		self.seen = seen
48*cdf0c1d5Smjnelson		self.shouldbe = shouldbe
49*cdf0c1d5Smjnelson
50*cdf0c1d5Smjnelsondef checkblock(block):
51*cdf0c1d5Smjnelson	line = block['start']
52*cdf0c1d5Smjnelson	lictxt = block['block']
53*cdf0c1d5Smjnelson
54*cdf0c1d5Smjnelson	for actual, valid in map(lambda x, y: (x and x.lstrip(CmntChrs), y),
55*cdf0c1d5Smjnelson			       lictxt, CDDL):
56*cdf0c1d5Smjnelson		if actual != valid:
57*cdf0c1d5Smjnelson			raise CddlError(line, actual, valid)
58*cdf0c1d5Smjnelson		line += 1
59*cdf0c1d5Smjnelson
60*cdf0c1d5Smjnelsondef cddlchk(fh, filename=None, lenient=False, verbose=False, output=sys.stderr):
61*cdf0c1d5Smjnelson	ret = 0
62*cdf0c1d5Smjnelson	blocks = []
63*cdf0c1d5Smjnelson	lic = []
64*cdf0c1d5Smjnelson	in_cddl = False
65*cdf0c1d5Smjnelson	start = 0
66*cdf0c1d5Smjnelson	lineno = 0
67*cdf0c1d5Smjnelson
68*cdf0c1d5Smjnelson	if not filename:
69*cdf0c1d5Smjnelson		filename = fh.name
70*cdf0c1d5Smjnelson
71*cdf0c1d5Smjnelson	for line in fh:
72*cdf0c1d5Smjnelson		line = line.rstrip('\r\n')
73*cdf0c1d5Smjnelson		lineno += 1
74*cdf0c1d5Smjnelson
75*cdf0c1d5Smjnelson		if CDDLStartRE.search(line):
76*cdf0c1d5Smjnelson			in_cddl = True
77*cdf0c1d5Smjnelson			lic.append(line)
78*cdf0c1d5Smjnelson			start = lineno
79*cdf0c1d5Smjnelson		elif in_cddl and CDDLEndRE.search(line):
80*cdf0c1d5Smjnelson			in_cddl = False
81*cdf0c1d5Smjnelson			lic.append(line)
82*cdf0c1d5Smjnelson			blocks.append({'start':start, 'block':lic})
83*cdf0c1d5Smjnelson			start = 0
84*cdf0c1d5Smjnelson			lic = []
85*cdf0c1d5Smjnelson		elif in_cddl:
86*cdf0c1d5Smjnelson			lic.append(line)
87*cdf0c1d5Smjnelson
88*cdf0c1d5Smjnelson	if in_cddl:
89*cdf0c1d5Smjnelson		output.write('Error: Incomplete CDDL block in file %s\n'
90*cdf0c1d5Smjnelson			     '    at line %s\n''' % (filename, start))
91*cdf0c1d5Smjnelson
92*cdf0c1d5Smjnelson	# Check for no CDDL, warn if we're not being lenient
93*cdf0c1d5Smjnelson	if not len(blocks) and not lenient:
94*cdf0c1d5Smjnelson		if not ret:
95*cdf0c1d5Smjnelson			ret = 2
96*cdf0c1d5Smjnelson		output.write("Warning: No CDDL block in file %s\n" % filename)
97*cdf0c1d5Smjnelson
98*cdf0c1d5Smjnelson	# Check for multiple CDDL blocks
99*cdf0c1d5Smjnelson	if len(blocks) > 1:
100*cdf0c1d5Smjnelson		ret = 1
101*cdf0c1d5Smjnelson		output.write('Error: Multiple CDDL blocks in file %s\n'
102*cdf0c1d5Smjnelson			     '    at lines %s\n''' %
103*cdf0c1d5Smjnelson			     (filename, ', '.join([str(x['start'])
104*cdf0c1d5Smjnelson						   for x in blocks])))
105*cdf0c1d5Smjnelson
106*cdf0c1d5Smjnelson	# Validate each CDDL block
107*cdf0c1d5Smjnelson	for b in blocks:
108*cdf0c1d5Smjnelson		try:
109*cdf0c1d5Smjnelson			checkblock(b)
110*cdf0c1d5Smjnelson		except CddlError, e:
111*cdf0c1d5Smjnelson			ret = 1
112*cdf0c1d5Smjnelson			output.write(
113*cdf0c1d5Smjnelson				"Error: Invalid line in CDDL block in file %s\n"
114*cdf0c1d5Smjnelson				"    at line %d, should be\n"
115*cdf0c1d5Smjnelson				"    '%s'\n"
116*cdf0c1d5Smjnelson				"    is\n"
117*cdf0c1d5Smjnelson				"    '%s'\n" % (filename, e.lineno,
118*cdf0c1d5Smjnelson						e.shouldbe, e.seen))
119*cdf0c1d5Smjnelson			break
120*cdf0c1d5Smjnelson
121*cdf0c1d5Smjnelson	if verbose and not ret:
122*cdf0c1d5Smjnelson		output.write("Message: Valid CDDL block in file %s\n" %
123*cdf0c1d5Smjnelson			     filename)
124*cdf0c1d5Smjnelson
125*cdf0c1d5Smjnelson	return ret
126