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