diff options
author | Andreas Sandberg <andreas.sandberg@arm.com> | 2016-03-30 15:30:32 +0100 |
---|---|---|
committer | Andreas Sandberg <andreas.sandberg@arm.com> | 2016-03-30 15:30:32 +0100 |
commit | 2580fcd9d79e2be5933c2575ce1a6eb26380f8a5 (patch) | |
tree | af2a53678e963c06f63972ddd77363d5ea55f8c0 /util/style/validators.py | |
parent | 062b6c4c9db83c91ef475b09425a1b844d93c72a (diff) | |
download | gem5-2580fcd9d79e2be5933c2575ce1a6eb26380f8a5.tar.xz |
style: Refactor the style checker as a Python package
Refactor the style checker into a Python module that can be reused by
command line tools that integrate with git. In particular:
* Create a style package in util
* Move style validators from style.py to the style/validators.py.
* Move style verifiers from style.py to the style/verifiers.py.
* Move utility functions (sort_includes, region handling,
file_types) into the style package
* Move generic code from style.py to style/style.py.
Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Curtis Dunham <curtis.dunham@arm.com>
Reviewed-by: Steve Reinhardt <steve.reinhardt@amd.com>
--HG--
rename : util/style.py => util/hgstyle.py
rename : util/sort_includes.py => util/style/sort_includes.py
extra : rebase_source : ad6cf9b9a18c48350dfc7b7c77bea6c5344fb53c
Diffstat (limited to 'util/style/validators.py')
-rw-r--r-- | util/style/validators.py | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/util/style/validators.py b/util/style/validators.py new file mode 100644 index 000000000..2c1e594c2 --- /dev/null +++ b/util/style/validators.py @@ -0,0 +1,212 @@ +#!/usr/bin/env python +# +# Copyright (c) 2014, 2016 ARM Limited +# All rights reserved +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# +# Copyright (c) 2006 The Regents of The University of Michigan +# Copyright (c) 2007,2011 The Hewlett-Packard Development Company +# Copyright (c) 2016 Advanced Micro Devices, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Nathan Binkert +# Steve Reinhardt +# Andreas Sandberg + +from abc import ABCMeta, abstractmethod +import inspect +import re +import sys + +import style + +tabsize = 8 +lead = re.compile(r'^([ \t]+)') +trail = re.compile(r'([ \t]+)$') +any_control = re.compile(r'\b(if|while|for)([ \t]*)\(') + +class Validator(object): + """Base class for style validators + + Validators analyze source files for common style violations and + produce source code style violation statistics. Unlike style + verifiers (see verifiers.py), they do not try to fix any style + violations violations. + + Deprecation warning: These classes are currently only used by the + "hg m5format" command and not by any style hooks. New style + checkers should inherit from Verifier instead of Validator. + + """ + + __metaclass__ = ABCMeta + + def __init__(self, file_name, verbose=False, language=None): + self.file_name = file_name + self.verbose = verbose + self.bad = 0 + self.language = language + + def fail_line(self, line_no, line, message): + print '%s:%d>' % (self.file_name, line_no + 1), message + if self.verbose: + print line + self.bad += 1 + + def __nonzero__(self): + return self.bad == 0 + + @classmethod + def supported_lang(cls, language): + return True + + @abstractmethod + def validate_line(self, line_no, line): + pass + + @abstractmethod + def dump(self): + pass + +class SimpleValidator(Validator): + supported_langs = set() + + def __init__(self, fail_message, dump_message, file_name, **kwargs): + super(SimpleValidator, self).__init__(file_name, **kwargs) + + self.fail_message = fail_message + self.dump_message = dump_message + + @classmethod + def supported_lang(cls, language): + return not cls.cupported_langs or language in cls.supported_langs + + def validate_line(self, line_no, line): + if not self.simple_validate_line(line): + self.fail_line(line_no, line, self.fail_message) + return False + else: + return True + + @abstractmethod + def simple_validate_line(self, line): + pass + + def dump(self): + print self.dump_message % { + "bad" : self.bad + } + +class LineLength(Validator): + def __init__(self, *args, **kwargs): + super(LineLength, self).__init__(*args, **kwargs) + + self.toolong80 = 0 + + def validate_line(self, line_no, line): + llen = style.normalized_len(line) + if llen == 80: + self.toolong80 += 1 + + if llen > 79: + self.fail_line(line_no, line, 'line too long (%d chars)' % llen) + return False + else: + return True + + def dump(self): + print "%d violations of lines over 79 chars. " \ + "%d of which are 80 chars exactly." % (self.bad, self.toolong80) + +class ControlSpacing(Validator): + supported_langs = set(('C', 'C++')) + + def validate_line(self, line_no, line): + match = any_control.search(line) + if match and match.group(2) != " ": + stats.badcontrol += 1 + self.fail_line(line_no, line, + 'improper spacing after %s' % match.group(1)) + return False + else: + return True + + def dump(self): + print "%d bad parens after if/while/for." % (self.bad, ) + +class CarriageReturn(SimpleValidator): + def __init__(self, *args, **kwargs): + super(CarriageReturn, self).__init__( + "carriage return found", + "%(bad)d carriage returns found.", + *args, **kwargs) + + def simple_validate_line(self, line): + return line.find('\r') == -1 + +class TabIndent(SimpleValidator): + lead = re.compile(r'^([ \t]+)') + + def __init__(self, *args, **kwargs): + super(TabIndent, self).__init__( + "using tabs to indent", + "%(bad)d cases of tabs to indent.", + *args, **kwargs) + + def simple_validate_line(self, line): + match = TabIndent.lead.search(line) + return not (match and match.group(1).find('\t') != -1) + +class TrailingWhitespace(SimpleValidator): + trail = re.compile(r'([ \t]+)$') + + def __init__(self, *args, **kwargs): + super(TrailingWhitespace, self).__init__( + "trailing whitespace", + "%(bad)d cases of whitespace at the end of a line.", + *args, **kwargs) + + def simple_validate_line(self, line): + return not TrailingWhitespace.trail.search(line) + +def is_validator(cls): + """Determine if a class is a Validator that can be instantiated""" + + return inspect.isclass(cls) and issubclass(cls, Validator) and \ + not inspect.isabstract(cls) + +# list of all verifier classes +all_validators = [ v for n, v in \ + inspect.getmembers(sys.modules[__name__], is_validator) ] + |