1N/A#! /usr/bin/python
1N/A
1N/A#
1N/A# CDDL HEADER START
1N/A#
1N/A# The contents of this file are subject to the terms of the
1N/A# Common Development and Distribution License (the "License").
1N/A# You may not use this file except in compliance with the License.
1N/A#
1N/A# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1N/A# or http://www.opensolaris.org/os/licensing.
1N/A# See the License for the specific language governing permissions
1N/A# and limitations under the License.
1N/A#
1N/A# When distributing Covered Code, include this CDDL HEADER in each
1N/A# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1N/A# If applicable, add the following below this CDDL HEADER, with the
1N/A# fields enclosed by brackets "[]" replaced with your own identifying
1N/A# information: Portions Copyright [yyyy] [name of copyright owner]
1N/A#
1N/A# CDDL HEADER END
1N/A#
1N/A
1N/A#
1N/A# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
1N/A#
1N/A
1N/A#
1N/A# Check that source files contain a valid comment block
1N/A#
1N/A
1N/Aimport re, sys
1N/A
1N/ACmntChrs = r'#*!/\\";. '
1N/A
1N/Aclass CmtBlkError(Exception):
1N/A def __init__(self, lineno, seen, shouldbe):
1N/A Exception.__init__(self)
1N/A self.lineno = lineno
1N/A self.seen = seen
1N/A self.shouldbe = shouldbe
1N/A
1N/Adef checkblock(block, blk_text):
1N/A line = block['start']
1N/A lictxt = block['block']
1N/A
1N/A for actual, valid in map(lambda x, y: (x and x.lstrip(CmntChrs), y),
1N/A lictxt, blk_text):
1N/A if actual != valid:
1N/A raise CmtBlkError(line, actual, valid)
1N/A line += 1
1N/A
1N/Adef cmtblkchk(fh, blk_name, blk_text, filename=None,
1N/A lenient=False, verbose=False, output=sys.stderr):
1N/A
1N/A ret = 0
1N/A blocks = []
1N/A lic = []
1N/A in_cmt = False
1N/A start = 0
1N/A lineno = 0
1N/A
1N/A StartText = '%s HEADER START' % blk_name
1N/A EndText = '%s HEADER END' % blk_name
1N/A full_text = [StartText, ''] + blk_text + ['', EndText]
1N/A
1N/A StartRE = re.compile(r'^[%s ]*%s' % (CmntChrs, StartText))
1N/A EndRE = re.compile(r'^[%s ]*%s' % (CmntChrs, EndText))
1N/A
1N/A if not filename:
1N/A filename = fh.name
1N/A
1N/A for line in fh:
1N/A line = line.rstrip('\r\n')
1N/A lineno += 1
1N/A
1N/A if StartRE.search(line):
1N/A in_cmt = True
1N/A lic.append(line)
1N/A start = lineno
1N/A elif in_cmt and EndRE.search(line):
1N/A in_cmt = False
1N/A lic.append(line)
1N/A blocks.append({'start':start, 'block':lic})
1N/A start = 0
1N/A lic = []
1N/A elif in_cmt:
1N/A lic.append(line)
1N/A
1N/A if in_cmt:
1N/A output.write('%s: %s: Error: Incomplete %s block\n''' %
1N/A (filename, start, blk_name))
1N/A
1N/A # Check for no comment block, warn if we're not being lenient
1N/A if not len(blocks) and not lenient:
1N/A if not ret:
1N/A ret = 2
1N/A output.write("%s: Warning: No %s block\n" %
1N/A (filename, blk_name))
1N/A
1N/A # Check for multiple comment blocks
1N/A if len(blocks) > 1:
1N/A ret = 1
1N/A output.write('%s: Error: Multiple %s blocks\n'
1N/A ' at lines %s\n''' %
1N/A (filename, blk_name,
1N/A ', '.join([str(x['start']) for x in blocks])))
1N/A
1N/A # Validate each comment block
1N/A for b in blocks:
1N/A try:
1N/A checkblock(b, full_text)
1N/A except CmtBlkError, e:
1N/A ret = 1
1N/A output.write(
1N/A "%s: %d: Error: Invalid line in %s block:\n"
1N/A " should be\n"
1N/A " '%s'\n"
1N/A " is\n"
1N/A " '%s'\n" % (filename, e.lineno, blk_name,
1N/A e.shouldbe, e.seen))
1N/A break
1N/A
1N/A if verbose and not ret:
1N/A output.write("%s: Valid %s block\n" %
1N/A (filename, blk_name))
1N/A
1N/A return ret