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