113540Sandrea.mondelli@ucf.edu#! /usr/bin/env python2.7
211403Sandreas.sandberg@arm.com# Copyright (c) 2014, 2016 ARM Limited
311403Sandreas.sandberg@arm.com# All rights reserved
411403Sandreas.sandberg@arm.com#
511403Sandreas.sandberg@arm.com# The license below extends only to copyright in the software and shall
611403Sandreas.sandberg@arm.com# not be construed as granting a license to any other intellectual
711403Sandreas.sandberg@arm.com# property including but not limited to intellectual property relating
811403Sandreas.sandberg@arm.com# to a hardware implementation of the functionality of the software
911403Sandreas.sandberg@arm.com# licensed hereunder.  You may use the software subject to the license
1011403Sandreas.sandberg@arm.com# terms below provided that you ensure that this notice is replicated
1111403Sandreas.sandberg@arm.com# unmodified and in its entirety in all distributions of the software,
1211403Sandreas.sandberg@arm.com# modified or unmodified, in source code or in binary form.
1311403Sandreas.sandberg@arm.com#
1411403Sandreas.sandberg@arm.com# Copyright (c) 2006 The Regents of The University of Michigan
1511403Sandreas.sandberg@arm.com# Copyright (c) 2007,2011 The Hewlett-Packard Development Company
1611403Sandreas.sandberg@arm.com# Copyright (c) 2016 Advanced Micro Devices, Inc.
1711403Sandreas.sandberg@arm.com# All rights reserved.
1811403Sandreas.sandberg@arm.com#
1911403Sandreas.sandberg@arm.com# Redistribution and use in source and binary forms, with or without
2011403Sandreas.sandberg@arm.com# modification, are permitted provided that the following conditions are
2111403Sandreas.sandberg@arm.com# met: redistributions of source code must retain the above copyright
2211403Sandreas.sandberg@arm.com# notice, this list of conditions and the following disclaimer;
2311403Sandreas.sandberg@arm.com# redistributions in binary form must reproduce the above copyright
2411403Sandreas.sandberg@arm.com# notice, this list of conditions and the following disclaimer in the
2511403Sandreas.sandberg@arm.com# documentation and/or other materials provided with the distribution;
2611403Sandreas.sandberg@arm.com# neither the name of the copyright holders nor the names of its
2711403Sandreas.sandberg@arm.com# contributors may be used to endorse or promote products derived from
2811403Sandreas.sandberg@arm.com# this software without specific prior written permission.
2911403Sandreas.sandberg@arm.com#
3011403Sandreas.sandberg@arm.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3111403Sandreas.sandberg@arm.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3211403Sandreas.sandberg@arm.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3311403Sandreas.sandberg@arm.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3411403Sandreas.sandberg@arm.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3511403Sandreas.sandberg@arm.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3611403Sandreas.sandberg@arm.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3711403Sandreas.sandberg@arm.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3811403Sandreas.sandberg@arm.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3911403Sandreas.sandberg@arm.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
4011403Sandreas.sandberg@arm.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4111403Sandreas.sandberg@arm.com#
4211403Sandreas.sandberg@arm.com# Authors: Nathan Binkert
4311403Sandreas.sandberg@arm.com#          Steve Reinhardt
4411403Sandreas.sandberg@arm.com#          Andreas Sandberg
4511403Sandreas.sandberg@arm.com
4611403Sandreas.sandberg@arm.comfrom abc import ABCMeta, abstractmethod
4711403Sandreas.sandberg@arm.comimport difflib
4811403Sandreas.sandberg@arm.comimport re
4911403Sandreas.sandberg@arm.comimport sys
5011403Sandreas.sandberg@arm.com
5111403Sandreas.sandberg@arm.comfrom region import *
5211403Sandreas.sandberg@arm.com
5311403Sandreas.sandberg@arm.comtabsize = 8
5411403Sandreas.sandberg@arm.comlead = re.compile(r'^([ \t]+)')
5511403Sandreas.sandberg@arm.comtrail = re.compile(r'([ \t]+)$')
5611403Sandreas.sandberg@arm.comany_control = re.compile(r'\b(if|while|for)([ \t]*)\(')
5711403Sandreas.sandberg@arm.com
5811403Sandreas.sandberg@arm.com
5911403Sandreas.sandberg@arm.comclass UserInterface(object):
6011403Sandreas.sandberg@arm.com    __metaclass__ = ABCMeta
6111403Sandreas.sandberg@arm.com
6211403Sandreas.sandberg@arm.com    def __init__(self, verbose=False):
6311403Sandreas.sandberg@arm.com        self.verbose = verbose
6411403Sandreas.sandberg@arm.com
6511403Sandreas.sandberg@arm.com    def prompt(self, prompt, results, default):
6611403Sandreas.sandberg@arm.com        while True:
6711403Sandreas.sandberg@arm.com            result = self._prompt(prompt, results, default)
6811403Sandreas.sandberg@arm.com            if result in results:
6911403Sandreas.sandberg@arm.com                return result
7011403Sandreas.sandberg@arm.com
7111403Sandreas.sandberg@arm.com    @abstractmethod
7211403Sandreas.sandberg@arm.com    def _prompt(self, prompt, results, default):
7311403Sandreas.sandberg@arm.com        pass
7411403Sandreas.sandberg@arm.com
7511403Sandreas.sandberg@arm.com    @abstractmethod
7611403Sandreas.sandberg@arm.com    def write(self, string):
7711403Sandreas.sandberg@arm.com        pass
7811403Sandreas.sandberg@arm.com
7911403Sandreas.sandberg@arm.comclass StdioUI(UserInterface):
8011403Sandreas.sandberg@arm.com    def _prompt(self, prompt, results, default):
8111403Sandreas.sandberg@arm.com        return raw_input(prompt) or default
8211403Sandreas.sandberg@arm.com
8311403Sandreas.sandberg@arm.com    def write(self, string):
8411403Sandreas.sandberg@arm.com        sys.stdout.write(string)
8511403Sandreas.sandberg@arm.com
8611403Sandreas.sandberg@arm.comclass MercurialUI(UserInterface):
8711403Sandreas.sandberg@arm.com    def __init__(self, ui, *args, **kwargs):
8811403Sandreas.sandberg@arm.com        super(MercurialUI, self).__init__(*args, **kwargs)
8911403Sandreas.sandberg@arm.com        self.hg_ui = ui
9011403Sandreas.sandberg@arm.com
9111403Sandreas.sandberg@arm.com    def _prompt(self, prompt, results, default):
9211403Sandreas.sandberg@arm.com        return self.hg_ui.prompt(prompt, default=default)
9311403Sandreas.sandberg@arm.com
9411403Sandreas.sandberg@arm.com    def write(self, string):
9511403Sandreas.sandberg@arm.com        self.hg_ui.write(string)
9611403Sandreas.sandberg@arm.com
9711403Sandreas.sandberg@arm.com
9811403Sandreas.sandberg@arm.comdef _re_ignore(expr):
9911403Sandreas.sandberg@arm.com    """Helper function to create regular expression ignore file
10011403Sandreas.sandberg@arm.com    matcher functions"""
10111403Sandreas.sandberg@arm.com
10211403Sandreas.sandberg@arm.com    rex = re.compile(expr)
10311403Sandreas.sandberg@arm.com    def match_re(fname):
10411403Sandreas.sandberg@arm.com        return rex.match(fname)
10511403Sandreas.sandberg@arm.com    return match_re
10611403Sandreas.sandberg@arm.com
10711403Sandreas.sandberg@arm.com# This list contains a list of functions that are called to determine
10811403Sandreas.sandberg@arm.com# if a file should be excluded from the style matching rules or
10911403Sandreas.sandberg@arm.com# not. The functions are called with the file name relative to the
11011403Sandreas.sandberg@arm.com# repository root (without a leading slash) as their argument. A file
11111403Sandreas.sandberg@arm.com# is excluded if any function in the list returns true.
11211403Sandreas.sandberg@arm.comstyle_ignores = [
11311403Sandreas.sandberg@arm.com    # Ignore external projects as they are unlikely to follow the gem5
11411403Sandreas.sandberg@arm.com    # coding convention.
11511403Sandreas.sandberg@arm.com    _re_ignore("^ext/"),
11611468SCurtis.Dunham@arm.com    # Ignore test data, as they are not code
11711468SCurtis.Dunham@arm.com    _re_ignore("^tests/(?:quick|long)/"),
11812771Sqtt2@cornell.edu    # Ignore RISC-V assembly tests as they are maintained in an external
11912771Sqtt2@cornell.edu    # project that does not follow the gem5 coding convention
12012771Sqtt2@cornell.edu    _re_ignore("tests/test-progs/asmtest/src/riscv/"),
12112771Sqtt2@cornell.edu    # Ignore RISC-V assembly dump files
12212771Sqtt2@cornell.edu    _re_ignore("tests/test-progs/asmtest/dump/riscv/")
12311403Sandreas.sandberg@arm.com]
12411403Sandreas.sandberg@arm.com
12511403Sandreas.sandberg@arm.comdef check_ignores(fname):
12611403Sandreas.sandberg@arm.com    """Check if a file name matches any of the ignore rules"""
12711403Sandreas.sandberg@arm.com
12811403Sandreas.sandberg@arm.com    for rule in style_ignores:
12911403Sandreas.sandberg@arm.com        if rule(fname):
13011403Sandreas.sandberg@arm.com            return True
13111403Sandreas.sandberg@arm.com
13211403Sandreas.sandberg@arm.com    return False
13311403Sandreas.sandberg@arm.com
13411403Sandreas.sandberg@arm.com
13511403Sandreas.sandberg@arm.comdef normalized_len(line):
13611403Sandreas.sandberg@arm.com    """Return a normalized line length with expanded tabs"""
13711403Sandreas.sandberg@arm.com
13811403Sandreas.sandberg@arm.com    count = 0
13911403Sandreas.sandberg@arm.com    for c in line:
14011403Sandreas.sandberg@arm.com        if c == '\t':
14111403Sandreas.sandberg@arm.com            count += tabsize - count % tabsize
14211403Sandreas.sandberg@arm.com        else:
14311403Sandreas.sandberg@arm.com            count += 1
14411403Sandreas.sandberg@arm.com
14511403Sandreas.sandberg@arm.com    return count
14611403Sandreas.sandberg@arm.com
14711403Sandreas.sandberg@arm.comdef modified_regions(old, new, context=0):
14811403Sandreas.sandberg@arm.com    regions = Regions()
14911403Sandreas.sandberg@arm.com    m = difflib.SequenceMatcher(a=old, b=new, autojunk=False)
15011403Sandreas.sandberg@arm.com    for group in m.get_grouped_opcodes(context):
15111403Sandreas.sandberg@arm.com        first = group[0]
15211403Sandreas.sandberg@arm.com        last = group[-1]
15311403Sandreas.sandberg@arm.com
15411403Sandreas.sandberg@arm.com        regions.extend(Region(first[3], last[4] + 1))
15511403Sandreas.sandberg@arm.com
15611403Sandreas.sandberg@arm.com    return regions
157