hgstyle.py revision 11406
14678SN/A#! /usr/bin/env python 210293SN/A# Copyright (c) 2014 ARM Limited 310293SN/A# All rights reserved 410293SN/A# 510293SN/A# The license below extends only to copyright in the software and shall 610293SN/A# not be construed as granting a license to any other intellectual 710293SN/A# property including but not limited to intellectual property relating 810293SN/A# to a hardware implementation of the functionality of the software 910293SN/A# licensed hereunder. You may use the software subject to the license 1010293SN/A# terms below provided that you ensure that this notice is replicated 1110293SN/A# unmodified and in its entirety in all distributions of the software, 1210293SN/A# modified or unmodified, in source code or in binary form. 1310293SN/A# 145465SN/A# Copyright (c) 2006 The Regents of The University of Michigan 158227SN/A# Copyright (c) 2007,2011 The Hewlett-Packard Development Company 1611319SN/A# Copyright (c) 2016 Advanced Micro Devices, Inc. 174678SN/A# All rights reserved. 184678SN/A# 194678SN/A# Redistribution and use in source and binary forms, with or without 204678SN/A# modification, are permitted provided that the following conditions are 214678SN/A# met: redistributions of source code must retain the above copyright 224678SN/A# notice, this list of conditions and the following disclaimer; 234678SN/A# redistributions in binary form must reproduce the above copyright 244678SN/A# notice, this list of conditions and the following disclaimer in the 254678SN/A# documentation and/or other materials provided with the distribution; 264678SN/A# neither the name of the copyright holders nor the names of its 274678SN/A# contributors may be used to endorse or promote products derived from 284678SN/A# this software without specific prior written permission. 294678SN/A# 304678SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 314678SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 324678SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 334678SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 344678SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 354678SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 364678SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 374678SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 384678SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 394678SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 404678SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 414678SN/A# 424678SN/A# Authors: Nathan Binkert 4311319SN/A# Steve Reinhardt 444678SN/A 4511406Sandreas.sandberg@arm.comimport sys 468227SN/Aimport os 4711406Sandreas.sandberg@arm.comfrom os.path import join as joinpath 484678SN/A 4911406Sandreas.sandberg@arm.comcurrent_dir = os.path.dirname(__file__) 5011406Sandreas.sandberg@arm.comsys.path.insert(0, current_dir) 5111406Sandreas.sandberg@arm.com 5211406Sandreas.sandberg@arm.comfrom style.verifiers import all_verifiers 5311406Sandreas.sandberg@arm.comfrom style.style import MercurialUI, check_ignores 5411406Sandreas.sandberg@arm.comfrom style.region import * 5511406Sandreas.sandberg@arm.com 5610293SN/Afrom mercurial import bdiff, mdiff, commands 577807SN/A 588227SN/Adef modified_regions(old_data, new_data): 598227SN/A regions = Regions() 608227SN/A beg = None 618227SN/A for pbeg, pend, fbeg, fend in bdiff.blocks(old_data, new_data): 628227SN/A if beg is not None and beg != fbeg: 638227SN/A regions.append(beg, fbeg) 648227SN/A beg = fend 658227SN/A return regions 668227SN/A 678227SN/Adef modregions(wctx, fname): 688227SN/A fctx = wctx.filectx(fname) 698227SN/A pctx = fctx.parents() 708227SN/A 718227SN/A file_data = fctx.data() 728227SN/A lines = mdiff.splitnewlines(file_data) 738227SN/A if len(pctx) in (1, 2): 748227SN/A mod_regions = modified_regions(pctx[0].data(), file_data) 758227SN/A if len(pctx) == 2: 768227SN/A m2 = modified_regions(pctx[1].data(), file_data) 778227SN/A # only the lines that are new in both 788227SN/A mod_regions &= m2 798227SN/A else: 808227SN/A mod_regions = Regions() 819135SN/A mod_regions.append(0, len(lines)) 828227SN/A 838227SN/A return mod_regions 848227SN/A 8510293SN/A 8610692SN/Adef _modified_regions(repo, patterns, **kwargs): 8710692SN/A opt_all = kwargs.get('all', False) 8810692SN/A opt_no_ignore = kwargs.get('no_ignore', False) 8910692SN/A 9010692SN/A # Import the match (repository file name matching helper) 9110692SN/A # function. Different versions of Mercurial keep it in different 9210692SN/A # modules and implement them differently. 9310692SN/A try: 9410692SN/A from mercurial import scmutil 9510692SN/A m = scmutil.match(repo[None], patterns, kwargs) 9610692SN/A except ImportError: 9710692SN/A from mercurial import cmdutil 9810692SN/A m = cmdutil.match(repo, patterns, kwargs) 9910692SN/A 10010692SN/A modified, added, removed, deleted, unknown, ignore, clean = \ 10110692SN/A repo.status(match=m, clean=opt_all) 10210692SN/A 10310692SN/A if not opt_all: 10410692SN/A try: 10510692SN/A wctx = repo.workingctx() 10610692SN/A except: 10710692SN/A from mercurial import context 10810692SN/A wctx = context.workingctx(repo) 10910692SN/A 11010692SN/A files = [ (fn, all_regions) for fn in added ] + \ 11110692SN/A [ (fn, modregions(wctx, fn)) for fn in modified ] 11210692SN/A else: 11310692SN/A files = [ (fn, all_regions) for fn in added + modified + clean ] 11410692SN/A 11510692SN/A for fname, mod_regions in files: 11610692SN/A if opt_no_ignore or not check_ignores(fname): 11710692SN/A yield fname, mod_regions 11810692SN/A 11910692SN/A 12010293SN/Adef do_check_style(hgui, repo, *pats, **opts): 12110293SN/A """check files for proper m5 style guidelines 12210293SN/A 12310293SN/A Without an argument, checks all modified and added files for gem5 12410293SN/A coding style violations. A list of files can be specified to limit 12510293SN/A the checker to a subset of the repository. The style rules are 12610293SN/A normally applied on a diff of the repository state (i.e., added 12710293SN/A files are checked in their entirety while only modifications of 12810293SN/A modified files are checked). 12910293SN/A 13010293SN/A The --all option can be specified to include clean files and check 13110293SN/A modified files in their entirety. 13211319SN/A 13311319SN/A The --fix-<check>, --ignore-<check>, and --skip-<check> options 13411319SN/A can be used to control individual style checks: 13511319SN/A 13611319SN/A --fix-<check> will perform the check and automatically attempt to 13711319SN/A fix sny style error (printing a warning if unsuccessful) 13811319SN/A 13911319SN/A --ignore-<check> will perform the check but ignore any errors 14011319SN/A found (other than printing a message for each) 14111319SN/A 14211319SN/A --skip-<check> will skip performing the check entirely 14311319SN/A 14411319SN/A If none of these options are given, all checks will be performed 14511319SN/A and the user will be prompted on how to handle each error. 14611319SN/A 14711319SN/A --fix-all, --ignore-all, and --skip-all are equivalent to specifying 14811319SN/A --fix-<check>, --ignore-<check>, or --skip-<check> for all checks, 14911319SN/A respectively. However, option settings for specific checks take 15011319SN/A precedence. Thus --skip-all --fix-white can be used to skip every 15111319SN/A check other than whitespace errors, which will be checked and 15211319SN/A automatically fixed. 15311319SN/A 15411319SN/A The -v/--verbose flag will display the offending line(s) as well 15511319SN/A as their location. 15610293SN/A """ 15710691SN/A 15810691SN/A ui = MercurialUI(hgui, verbose=hgui.verbose) 1595465SN/A 16011319SN/A # instantiate varifier objects 16111406Sandreas.sandberg@arm.com verifiers = [v(ui, opts, base=repo.root) for v in all_verifiers] 1624678SN/A 16310692SN/A for fname, mod_regions in _modified_regions(repo, pats, **opts): 16411319SN/A for verifier in verifiers: 16511406Sandreas.sandberg@arm.com if verifier.apply(joinpath(repo.root, fname), mod_regions): 16610692SN/A return True 1674678SN/A 1684678SN/A return False 1694678SN/A 1707807SN/Adef check_hook(hooktype): 1717807SN/A if hooktype not in ('pretxncommit', 'pre-qrefresh'): 1727807SN/A raise AttributeError, \ 1737807SN/A "This hook is not meant for %s" % hooktype 1747807SN/A 17511319SN/A# This function provides a hook that is called before transaction 17611319SN/A# commit and on qrefresh 1777827SN/Adef check_style(ui, repo, hooktype, **kwargs): 1787807SN/A check_hook(hooktype) 1797827SN/A args = {} 1807828SN/A 1817828SN/A try: 1827828SN/A return do_check_style(ui, repo, **args) 1837828SN/A except Exception, e: 1847828SN/A import traceback 1857828SN/A traceback.print_exc() 1867828SN/A return True 1877807SN/A 1885465SN/Atry: 1895465SN/A from mercurial.i18n import _ 1905465SN/Aexcept ImportError: 1915465SN/A def _(arg): 1925465SN/A return arg 1935465SN/A 19410692SN/A_common_region_options = [ 19510692SN/A ('a', 'all', False, 19610692SN/A _("include clean files and unmodified parts of modified files")), 19710692SN/A ('', 'no-ignore', False, _("ignore the style ignore list")), 19810692SN/A ] 19910692SN/A 20011319SN/A 20111319SN/Afix_opts = [('f', 'fix-all', False, _("fix all style errors"))] + \ 20211319SN/A [('', 'fix-' + v.opt_name, False, 20311319SN/A _('fix errors in ' + v.test_name)) for v in all_verifiers] 20411319SN/Aignore_opts = [('', 'ignore-all', False, _("ignore all style errors"))] + \ 20511319SN/A [('', 'ignore-' + v.opt_name, False, 20611319SN/A _('ignore errors in ' + v.test_name)) for v in all_verifiers] 20711319SN/Askip_opts = [('', 'skip-all', False, _("skip all style error checks"))] + \ 20811319SN/A [('', 'skip-' + v.opt_name, False, 20911319SN/A _('skip checking for ' + v.test_name)) for v in all_verifiers] 21011319SN/Aall_opts = fix_opts + ignore_opts + skip_opts 21111319SN/A 21211319SN/A 2135465SN/Acmdtable = { 21410293SN/A '^m5style' : ( 21511319SN/A do_check_style, all_opts + _common_region_options + commands.walkopts, 21610293SN/A _('hg m5style [-a] [FILE]...')), 2175465SN/A} 2187807SN/A 2194678SN/Aif __name__ == '__main__': 22011406Sandreas.sandberg@arm.com print >> sys.stderr, "This file cannot be used from the command line. Use" 22111406Sandreas.sandberg@arm.com print >> sys.stderr, "style.py instead." 22211406Sandreas.sandberg@arm.com sys.exit(1) 223