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