hgstyle.py revision 11410
111409Sandreas.sandberg@arm.com#! /usr/bin/env python 211410Sandreas.sandberg@arm.com# Copyright (c) 2014 ARM Limited 311409Sandreas.sandberg@arm.com# All rights reserved 411409Sandreas.sandberg@arm.com# 511409Sandreas.sandberg@arm.com# The license below extends only to copyright in the software and shall 611409Sandreas.sandberg@arm.com# not be construed as granting a license to any other intellectual 711409Sandreas.sandberg@arm.com# property including but not limited to intellectual property relating 811409Sandreas.sandberg@arm.com# to a hardware implementation of the functionality of the software 911409Sandreas.sandberg@arm.com# licensed hereunder. You may use the software subject to the license 1011409Sandreas.sandberg@arm.com# terms below provided that you ensure that this notice is replicated 1111409Sandreas.sandberg@arm.com# unmodified and in its entirety in all distributions of the software, 1211409Sandreas.sandberg@arm.com# modified or unmodified, in source code or in binary form. 1311409Sandreas.sandberg@arm.com# 1411410Sandreas.sandberg@arm.com# Copyright (c) 2006 The Regents of The University of Michigan 1511410Sandreas.sandberg@arm.com# Copyright (c) 2007,2011 The Hewlett-Packard Development Company 1611410Sandreas.sandberg@arm.com# Copyright (c) 2016 Advanced Micro Devices, Inc. 1711410Sandreas.sandberg@arm.com# All rights reserved. 1811410Sandreas.sandberg@arm.com# 1911409Sandreas.sandberg@arm.com# Redistribution and use in source and binary forms, with or without 2011409Sandreas.sandberg@arm.com# modification, are permitted provided that the following conditions are 2111409Sandreas.sandberg@arm.com# met: redistributions of source code must retain the above copyright 2211409Sandreas.sandberg@arm.com# notice, this list of conditions and the following disclaimer; 2311409Sandreas.sandberg@arm.com# redistributions in binary form must reproduce the above copyright 2411409Sandreas.sandberg@arm.com# notice, this list of conditions and the following disclaimer in the 2511409Sandreas.sandberg@arm.com# documentation and/or other materials provided with the distribution; 2611409Sandreas.sandberg@arm.com# neither the name of the copyright holders nor the names of its 2711409Sandreas.sandberg@arm.com# contributors may be used to endorse or promote products derived from 2811409Sandreas.sandberg@arm.com# this software without specific prior written permission. 2911409Sandreas.sandberg@arm.com# 3011409Sandreas.sandberg@arm.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3111409Sandreas.sandberg@arm.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3211409Sandreas.sandberg@arm.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3311409Sandreas.sandberg@arm.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3411409Sandreas.sandberg@arm.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3511409Sandreas.sandberg@arm.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3611409Sandreas.sandberg@arm.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3711409Sandreas.sandberg@arm.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3811409Sandreas.sandberg@arm.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3911409Sandreas.sandberg@arm.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 4011409Sandreas.sandberg@arm.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 4111409Sandreas.sandberg@arm.com# 4211410Sandreas.sandberg@arm.com# Authors: Nathan Binkert 4311410Sandreas.sandberg@arm.com# Steve Reinhardt 4411409Sandreas.sandberg@arm.com 4511410Sandreas.sandberg@arm.comimport sys 4611409Sandreas.sandberg@arm.comimport os 4711410Sandreas.sandberg@arm.comfrom os.path import join as joinpath 4811409Sandreas.sandberg@arm.com 4911410Sandreas.sandberg@arm.comcurrent_dir = os.path.dirname(__file__) 5011410Sandreas.sandberg@arm.comsys.path.insert(0, current_dir) 5111410Sandreas.sandberg@arm.com 5211409Sandreas.sandberg@arm.comfrom style.verifiers import all_verifiers 5311410Sandreas.sandberg@arm.comfrom style.style import MercurialUI, check_ignores 5411410Sandreas.sandberg@arm.comfrom style.region import * 5511409Sandreas.sandberg@arm.com 5611410Sandreas.sandberg@arm.comfrom mercurial import bdiff, mdiff, commands 5711409Sandreas.sandberg@arm.com 5811410Sandreas.sandberg@arm.comdef modified_regions(old_data, new_data): 5911410Sandreas.sandberg@arm.com regions = Regions() 6011410Sandreas.sandberg@arm.com beg = None 6111410Sandreas.sandberg@arm.com for pbeg, pend, fbeg, fend in bdiff.blocks(old_data, new_data): 6211410Sandreas.sandberg@arm.com if beg is not None and beg != fbeg: 6311410Sandreas.sandberg@arm.com regions.append(beg, fbeg) 6411410Sandreas.sandberg@arm.com beg = fend 6511410Sandreas.sandberg@arm.com return regions 6611409Sandreas.sandberg@arm.com 6711410Sandreas.sandberg@arm.comdef modregions(wctx, fname): 6811410Sandreas.sandberg@arm.com fctx = wctx.filectx(fname) 6911410Sandreas.sandberg@arm.com pctx = fctx.parents() 7011409Sandreas.sandberg@arm.com 7111410Sandreas.sandberg@arm.com file_data = fctx.data() 7211410Sandreas.sandberg@arm.com lines = mdiff.splitnewlines(file_data) 7311410Sandreas.sandberg@arm.com if len(pctx) in (1, 2): 7411410Sandreas.sandberg@arm.com mod_regions = modified_regions(pctx[0].data(), file_data) 7511410Sandreas.sandberg@arm.com if len(pctx) == 2: 7611410Sandreas.sandberg@arm.com m2 = modified_regions(pctx[1].data(), file_data) 7711410Sandreas.sandberg@arm.com # only the lines that are new in both 7811410Sandreas.sandberg@arm.com mod_regions &= m2 7911409Sandreas.sandberg@arm.com else: 8011410Sandreas.sandberg@arm.com mod_regions = Regions() 8111410Sandreas.sandberg@arm.com mod_regions.append(0, len(lines)) 8211409Sandreas.sandberg@arm.com 8311410Sandreas.sandberg@arm.com return mod_regions 8411410Sandreas.sandberg@arm.com 8511410Sandreas.sandberg@arm.com 8611410Sandreas.sandberg@arm.comdef _modified_regions(repo, patterns, **kwargs): 8711410Sandreas.sandberg@arm.com opt_all = kwargs.get('all', False) 8811410Sandreas.sandberg@arm.com opt_no_ignore = kwargs.get('no_ignore', False) 8911410Sandreas.sandberg@arm.com 9011410Sandreas.sandberg@arm.com # Import the match (repository file name matching helper) 9111410Sandreas.sandberg@arm.com # function. Different versions of Mercurial keep it in different 9211410Sandreas.sandberg@arm.com # modules and implement them differently. 9311410Sandreas.sandberg@arm.com try: 9411410Sandreas.sandberg@arm.com from mercurial import scmutil 9511410Sandreas.sandberg@arm.com m = scmutil.match(repo[None], patterns, kwargs) 9611410Sandreas.sandberg@arm.com except ImportError: 9711410Sandreas.sandberg@arm.com from mercurial import cmdutil 9811410Sandreas.sandberg@arm.com m = cmdutil.match(repo, patterns, kwargs) 9911410Sandreas.sandberg@arm.com 10011410Sandreas.sandberg@arm.com modified, added, removed, deleted, unknown, ignore, clean = \ 10111410Sandreas.sandberg@arm.com repo.status(match=m, clean=opt_all) 10211410Sandreas.sandberg@arm.com 10311410Sandreas.sandberg@arm.com if not opt_all: 10411410Sandreas.sandberg@arm.com try: 10511410Sandreas.sandberg@arm.com wctx = repo.workingctx() 10611410Sandreas.sandberg@arm.com except: 10711410Sandreas.sandberg@arm.com from mercurial import context 10811410Sandreas.sandberg@arm.com wctx = context.workingctx(repo) 10911410Sandreas.sandberg@arm.com 11011410Sandreas.sandberg@arm.com files = [ (fn, all_regions) for fn in added ] + \ 11111410Sandreas.sandberg@arm.com [ (fn, modregions(wctx, fn)) for fn in modified ] 11211410Sandreas.sandberg@arm.com else: 11311410Sandreas.sandberg@arm.com files = [ (fn, all_regions) for fn in added + modified + clean ] 11411410Sandreas.sandberg@arm.com 11511410Sandreas.sandberg@arm.com for fname, mod_regions in files: 11611410Sandreas.sandberg@arm.com if opt_no_ignore or not check_ignores(fname): 11711410Sandreas.sandberg@arm.com yield fname, mod_regions 11811410Sandreas.sandberg@arm.com 11911410Sandreas.sandberg@arm.com 12011410Sandreas.sandberg@arm.comdef do_check_style(hgui, repo, *pats, **opts): 12111410Sandreas.sandberg@arm.com """check files for proper m5 style guidelines 12211410Sandreas.sandberg@arm.com 12311410Sandreas.sandberg@arm.com Without an argument, checks all modified and added files for gem5 12411410Sandreas.sandberg@arm.com coding style violations. A list of files can be specified to limit 12511410Sandreas.sandberg@arm.com the checker to a subset of the repository. The style rules are 12611410Sandreas.sandberg@arm.com normally applied on a diff of the repository state (i.e., added 12711410Sandreas.sandberg@arm.com files are checked in their entirety while only modifications of 12811410Sandreas.sandberg@arm.com modified files are checked). 12911410Sandreas.sandberg@arm.com 13011410Sandreas.sandberg@arm.com The --all option can be specified to include clean files and check 13111410Sandreas.sandberg@arm.com modified files in their entirety. 13211410Sandreas.sandberg@arm.com 13311410Sandreas.sandberg@arm.com The --fix-<check>, --ignore-<check>, and --skip-<check> options 13411410Sandreas.sandberg@arm.com can be used to control individual style checks: 13511410Sandreas.sandberg@arm.com 13611410Sandreas.sandberg@arm.com --fix-<check> will perform the check and automatically attempt to 13711410Sandreas.sandberg@arm.com fix sny style error (printing a warning if unsuccessful) 13811410Sandreas.sandberg@arm.com 13911410Sandreas.sandberg@arm.com --ignore-<check> will perform the check but ignore any errors 14011410Sandreas.sandberg@arm.com found (other than printing a message for each) 14111410Sandreas.sandberg@arm.com 14211410Sandreas.sandberg@arm.com --skip-<check> will skip performing the check entirely 14311410Sandreas.sandberg@arm.com 14411410Sandreas.sandberg@arm.com If none of these options are given, all checks will be performed 14511410Sandreas.sandberg@arm.com and the user will be prompted on how to handle each error. 14611410Sandreas.sandberg@arm.com 14711410Sandreas.sandberg@arm.com --fix-all, --ignore-all, and --skip-all are equivalent to specifying 14811410Sandreas.sandberg@arm.com --fix-<check>, --ignore-<check>, or --skip-<check> for all checks, 14911410Sandreas.sandberg@arm.com respectively. However, option settings for specific checks take 15011410Sandreas.sandberg@arm.com precedence. Thus --skip-all --fix-white can be used to skip every 15111410Sandreas.sandberg@arm.com check other than whitespace errors, which will be checked and 15211410Sandreas.sandberg@arm.com automatically fixed. 15311410Sandreas.sandberg@arm.com 15411410Sandreas.sandberg@arm.com The -v/--verbose flag will display the offending line(s) as well 15511410Sandreas.sandberg@arm.com as their location. 15611410Sandreas.sandberg@arm.com """ 15711410Sandreas.sandberg@arm.com 15811410Sandreas.sandberg@arm.com ui = MercurialUI(hgui, verbose=hgui.verbose) 15911410Sandreas.sandberg@arm.com 16011410Sandreas.sandberg@arm.com # instantiate varifier objects 16111410Sandreas.sandberg@arm.com verifiers = [v(ui, opts, base=repo.root) for v in all_verifiers] 16211410Sandreas.sandberg@arm.com 16311410Sandreas.sandberg@arm.com for fname, mod_regions in _modified_regions(repo, pats, **opts): 16411410Sandreas.sandberg@arm.com for verifier in verifiers: 16511410Sandreas.sandberg@arm.com if verifier.apply(joinpath(repo.root, fname), mod_regions): 16611410Sandreas.sandberg@arm.com return True 16711410Sandreas.sandberg@arm.com 16811410Sandreas.sandberg@arm.com return False 16911410Sandreas.sandberg@arm.com 17011410Sandreas.sandberg@arm.comdef check_hook(hooktype): 17111410Sandreas.sandberg@arm.com if hooktype not in ('pretxncommit', 'pre-qrefresh'): 17211410Sandreas.sandberg@arm.com raise AttributeError, \ 17311410Sandreas.sandberg@arm.com "This hook is not meant for %s" % hooktype 17411410Sandreas.sandberg@arm.com 17511410Sandreas.sandberg@arm.com# This function provides a hook that is called before transaction 17611410Sandreas.sandberg@arm.com# commit and on qrefresh 17711410Sandreas.sandberg@arm.comdef check_style(ui, repo, hooktype, **kwargs): 17811410Sandreas.sandberg@arm.com check_hook(hooktype) 17911410Sandreas.sandberg@arm.com args = {} 18011410Sandreas.sandberg@arm.com 18111410Sandreas.sandberg@arm.com try: 18211410Sandreas.sandberg@arm.com return do_check_style(ui, repo, **args) 18311410Sandreas.sandberg@arm.com except Exception, e: 18411410Sandreas.sandberg@arm.com import traceback 18511410Sandreas.sandberg@arm.com traceback.print_exc() 18611410Sandreas.sandberg@arm.com return True 18711410Sandreas.sandberg@arm.com 18811410Sandreas.sandberg@arm.comtry: 18911410Sandreas.sandberg@arm.com from mercurial.i18n import _ 19011410Sandreas.sandberg@arm.comexcept ImportError: 19111410Sandreas.sandberg@arm.com def _(arg): 19211410Sandreas.sandberg@arm.com return arg 19311410Sandreas.sandberg@arm.com 19411410Sandreas.sandberg@arm.com_common_region_options = [ 19511410Sandreas.sandberg@arm.com ('a', 'all', False, 19611410Sandreas.sandberg@arm.com _("include clean files and unmodified parts of modified files")), 19711410Sandreas.sandberg@arm.com ('', 'no-ignore', False, _("ignore the style ignore list")), 19811410Sandreas.sandberg@arm.com ] 19911410Sandreas.sandberg@arm.com 20011410Sandreas.sandberg@arm.com 20111410Sandreas.sandberg@arm.comfix_opts = [('f', 'fix-all', False, _("fix all style errors"))] + \ 20211410Sandreas.sandberg@arm.com [('', 'fix-' + v.opt_name, False, 20311410Sandreas.sandberg@arm.com _('fix errors in ' + v.test_name)) for v in all_verifiers] 20411410Sandreas.sandberg@arm.comignore_opts = [('', 'ignore-all', False, _("ignore all style errors"))] + \ 20511410Sandreas.sandberg@arm.com [('', 'ignore-' + v.opt_name, False, 20611410Sandreas.sandberg@arm.com _('ignore errors in ' + v.test_name)) for v in all_verifiers] 20711410Sandreas.sandberg@arm.comskip_opts = [('', 'skip-all', False, _("skip all style error checks"))] + \ 20811410Sandreas.sandberg@arm.com [('', 'skip-' + v.opt_name, False, 20911410Sandreas.sandberg@arm.com _('skip checking for ' + v.test_name)) for v in all_verifiers] 21011410Sandreas.sandberg@arm.comall_opts = fix_opts + ignore_opts + skip_opts 21111410Sandreas.sandberg@arm.com 21211410Sandreas.sandberg@arm.com 21311410Sandreas.sandberg@arm.comcmdtable = { 21411410Sandreas.sandberg@arm.com '^m5style' : ( 21511410Sandreas.sandberg@arm.com do_check_style, all_opts + _common_region_options + commands.walkopts, 21611410Sandreas.sandberg@arm.com _('hg m5style [-a] [FILE]...')), 21711409Sandreas.sandberg@arm.com} 21811409Sandreas.sandberg@arm.com 21911409Sandreas.sandberg@arm.comif __name__ == '__main__': 22011410Sandreas.sandberg@arm.com print >> sys.stderr, "This file cannot be used from the command line. Use" 22111410Sandreas.sandberg@arm.com print >> sys.stderr, "style.py instead." 22211410Sandreas.sandberg@arm.com sys.exit(1) 223