- def __nonzero__(self):
- return self.toolong or self.toolong80 or self.leadtabs or \
- self.trailwhite or self.badcontrol or self.cret
-
-def validate(filename, stats, verbose, exit_code):
- if lang_type(filename) not in format_types:
- return
-
- def msg(lineno, line, message):
- print '%s:%d>' % (filename, lineno + 1), message
- if verbose > 2:
- print line
-
- def bad():
- if exit_code is not None:
- sys.exit(exit_code)
-
- try:
- f = file(filename, 'r')
- except OSError:
- if verbose > 0:
- print 'could not open file %s' % filename
- bad()
- return
-
- for i,line in enumerate(f):
- line = line.rstrip('\n')
-
- # no carriage returns
- if line.find('\r') != -1:
- self.cret += 1
- if verbose > 1:
- msg(i, line, 'carriage return found')
- bad()
-
- # lines max out at 79 chars
- llen = linelen(line)
- if llen > 79:
- stats.toolong += 1
- if llen == 80:
- stats.toolong80 += 1
- if verbose > 1:
- msg(i, line, 'line too long (%d chars)' % llen)
- bad()
-
- # no tabs used to indent
- match = lead.search(line)
- if match and match.group(1).find('\t') != -1:
- stats.leadtabs += 1
- if verbose > 1:
- msg(i, line, 'using tabs to indent')
- bad()
-
- # no trailing whitespace
- if trail.search(line):
- stats.trailwhite +=1
- if verbose > 1:
- msg(i, line, 'trailing whitespace')
- bad()
-
- # for c++, exactly one space betwen if/while/for and (
- if cpp:
- match = any_control.search(line)
- if match and not good_control.search(line):
- stats.badcontrol += 1
- if verbose > 1:
- msg(i, line, 'improper spacing after %s' % match.group(1))
- bad()
-
-def do_check_style(hgui, repo, *files, **args):
- """check files for proper m5 style guidelines"""
- from mercurial import mdiff, util
-
- auto = args.get('auto', False)
- if auto:
- auto = 'f'
- ui = MercurialUI(hgui, hgui.verbose, auto)
-
- if files:
- files = frozenset(files)
-
- def skip(name):
- return files and name in files
-
- def prompt(name, func, regions=all_regions):
- result = ui.prompt("(a)bort, (i)gnore, or (f)ix?", 'aif', 'a')
- if result == 'a':
- return True
- elif result == 'f':
- func(repo.wjoin(name), regions)
-
- return False
-
- modified, added, removed, deleted, unknown, ignore, clean = repo.status()
-
- whitespace = Whitespace(ui)
- sorted_includes = SortedIncludes(ui)
- for fname in added:
- if skip(fname):
- continue
-
- if whitespace.apply(fname, prompt):
- return True
-
- if sorted_includes.apply(fname, prompt):
- return True
-
- try:
- wctx = repo.workingctx()
- except:
- from mercurial import context
- wctx = context.workingctx(repo)
-
- for fname in modified:
- if skip(fname):
- continue
-
- regions = modregions(wctx, fname)
-
- if whitespace.apply(fname, prompt, regions):
- return True
-
- if sorted_includes.apply(fname, prompt, regions):
- return True
-
- return False
-
-def do_check_format(hgui, repo, **args):
- ui = MercurialUI(hgui, hgui.verbose, auto)
-
- modified, added, removed, deleted, unknown, ignore, clean = repo.status()
-
- verbose = 0
- stats = ValidationStats()
- for f in modified + added:
- validate(f, stats, verbose, None)
-
- if stats:
- stats.dump()
- result = ui.prompt("invalid formatting\n(i)gnore or (a)bort?",
- 'ai', 'a')
- if result == 'a':
- return True
-
- return False
-
-def check_hook(hooktype):
- if hooktype not in ('pretxncommit', 'pre-qrefresh'):
- raise AttributeError, \
- "This hook is not meant for %s" % hooktype
-
-def check_style(ui, repo, hooktype, **kwargs):
- check_hook(hooktype)
- args = {}
-
- try:
- return do_check_style(ui, repo, **args)
- except Exception, e:
- import traceback
- traceback.print_exc()
- return True
-
-def check_format(ui, repo, hooktype, **kwargs):
- check_hook(hooktype)
- args = {}
-
- try:
- return do_check_format(ui, repo, **args)
- except Exception, e:
- import traceback
- traceback.print_exc()
- return True
-
-try:
- from mercurial.i18n import _
-except ImportError:
- def _(arg):
- return arg
-
-cmdtable = {
- '^m5style' :
- ( do_check_style,
- [ ('a', 'auto', False, _("automatically fix whitespace")) ],
- _('hg m5style [-a] [FILE]...')),
- '^m5format' :
- ( do_check_format,
- [ ],
- _('hg m5format [FILE]...')),
-}
-
-if __name__ == '__main__':
- import getopt
-
- progname = sys.argv[0]
- if len(sys.argv) < 2:
- sys.exit('usage: %s <command> [<command args>]' % progname)
-
- fixwhite_usage = '%s fixwhite [-t <tabsize> ] <path> [...] \n' % progname
- chkformat_usage = '%s chkformat <path> [...] \n' % progname
- chkwhite_usage = '%s chkwhite <path> [...] \n' % progname
-
- command = sys.argv[1]
- if command == 'fixwhite':
- flags = 't:'
- usage = fixwhite_usage
- elif command == 'chkwhite':
- flags = 'nv'
- usage = chkwhite_usage
- elif command == 'chkformat':
- flags = 'nv'
- usage = chkformat_usage
- else:
- sys.exit(fixwhite_usage + chkwhite_usage + chkformat_usage)
-
- opts, args = getopt.getopt(sys.argv[2:], flags)
-
- code = 1
- verbose = 1
- for opt,arg in opts:
- if opt == '-n':
- code = None
- if opt == '-t':
- tabsize = int(arg)
- if opt == '-v':
- verbose += 1
-
- if command == 'fixwhite':
- for filename in args:
- fixwhite(filename, tabsize)
- elif command == 'chkwhite':
- for filename in args:
- for line,num in checkwhite(filename):
- print 'invalid whitespace: %s:%d' % (filename, num)
- if verbose:
- print '>>%s<<' % line[:-1]
- elif command == 'chkformat':
- stats = ValidationStats()
- for filename in args:
- validate(filename, stats=stats, verbose=verbose, exit_code=code)
-
- if verbose > 0:
- stats.dump()
- else:
- sys.exit("command '%s' not found" % command)