changeset 15553b536bd6 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=15553b536bd6
description:
        style: make style hook work with pre-qrefresh and update to use new code
        clean up the code a little bit while we're at it.

        I recommend that everyone adds the pre-qrefresh hook below since it
        will make qref run the style hook and not just commit/qpush

        [extensions]
        style = <m5 path>/util/style.py

        [hooks]
        pretxncommit.style = python:style.check_whitespace
        pre-qrefresh.style = python:style.check_whitespace

diffstat:

 SConstruct         |   1 +
 util/file_types.py |  89 +++++++++++++++++++++++++++++++++++++++++++++++++++
 util/style.py      |  93 ++++++++++++++++++-----------------------------------
 3 files changed, 122 insertions(+), 61 deletions(-)

diffs (269 lines):

diff -r fbf4b1b18202 -r 15553b536bd6 SConstruct
--- a/SConstruct        Thu Dec 23 13:36:18 2010 -0600
+++ b/SConstruct        Thu Dec 30 12:53:56 2010 -0500
@@ -165,6 +165,7 @@
 
 [hooks]
 pretxncommit.style = python:style.check_whitespace
+pre-qrefresh.style = python:style.check_whitespace
 """ % (main.root)
 
 mercurial_bin_not_found = """
diff -r fbf4b1b18202 -r 15553b536bd6 util/file_types.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/util/file_types.py        Thu Dec 30 12:53:56 2010 -0500
@@ -0,0 +1,89 @@
+import os
+
+# lanuage type for each file extension
+lang_types = {
+    '.c'     : "C",
+    '.h'     : "C",
+    '.cc'    : "C++",
+    '.hh'    : "C++",
+    '.cxx'   : "C++",
+    '.hxx'   : "C++",
+    '.cpp'   : "C++",
+    '.hpp'   : "C++",
+    '.C'     : "C++",
+    '.H'     : "C++",
+    '.i'     : "swig",
+    '.py'    : "python",
+    '.pl'    : "perl",
+    '.pm'    : "perl",
+    '.s'     : "asm",
+    '.S'     : "asm",
+    '.l'     : "lex",
+    '.ll'    : "lex",
+    '.y'     : "yacc",
+    '.yy'    : "yacc",
+    '.isa'   : "isa",
+    '.sh'    : "shell",
+    '.slicc' : "slicc",
+    '.sm'    : "slicc",
+    '.awk'   : "awk",
+    '.el'    : "lisp",
+    '.txt'   : "text",
+    '.tex'   : "tex",
+    }
+
+# languages based on file prefix
+lang_prefixes = (
+    ('SCons',    'scons'),
+    ('Make',     'make'),
+    ('make',     'make'),
+    ('Doxyfile', 'doxygen'),
+    )
+
+# languages based on #! line of first file
+hash_bang = (
+    ('python', 'python'),
+    ('perl',   'perl'),
+    ('sh',     'shell'),
+    )
+
+# the list of all languages that we detect
+all_languages = frozenset(lang_types.itervalues())
+all_languages |= frozenset(lang for start,lang in lang_prefixes)
+all_languages |= frozenset(lang for start,lang in hash_bang)
+
+def lang_type(filename, firstline=None, openok=True):
+    '''identify the language of a given filename and potentially the
+    firstline of the file.  If the firstline of the file is not
+    provided and openok is True, open the file and read the first line
+    if necessary'''
+
+    basename = os.path.basename(filename)
+    name,extension = os.path.splitext(basename)
+
+    # first try to detect language based on file extension
+    try:
+        return lang_types[extension]
+    except KeyError:
+        pass
+
+    # now try to detect language based on file prefix
+    for start,lang in lang_prefixes:
+        if basename.startswith(start):
+            return start
+
+    # if a first line was not provided but the file is ok to open,
+    # grab the first line of the file.
+    if firstline is None and openok:
+        handle = file(filename, 'r')
+        firstline = handle.readline()
+        handle.close()
+
+    # try to detect language based on #! in first line
+    if firstline and firstline.startswith('#!'):
+        for string,lang in hash_bang:
+            if firstline.find(string) > 0:
+                return lang
+
+    # sorry, we couldn't detect the language
+    return None
diff -r fbf4b1b18202 -r 15553b536bd6 util/style.py
--- a/util/style.py     Thu Dec 23 13:36:18 2010 -0600
+++ b/util/style.py     Thu Dec 30 12:53:56 2010 -0500
@@ -32,47 +32,17 @@
 import os
 import sys
 
+sys.path.insert(0, os.path.dirname(__file__))
+
+from file_types import lang_type
+
 lead = re.compile(r'^([ \t]+)')
 trail = re.compile(r'([ \t]+)$')
 any_control = re.compile(r'\b(if|while|for)[ \t]*[(]')
 good_control = re.compile(r'\b(if|while|for) [(]')
 
-lang_types = { 'c'   : "C",
-               'h'   : "C",
-               'cc'  : "C++",
-               'hh'  : "C++",
-               'cxx' : "C++",
-               'hxx' : "C++",
-               'cpp' : "C++",
-               'hpp' : "C++",
-               'C'   : "C++",
-               'H'   : "C++",
-               'i'   : "swig",
-               'py'  : "python",
-               's'   : "asm",
-               'S'   : "asm",
-               'isa' : "isa" }
-def file_type(filename):
-    extension = filename.split('.')
-    extension = len(extension) > 1 and extension[-1]
-    return lang_types.get(extension, None)
-
-whitespace_types = ('C', 'C++', 'swig', 'python', 'asm', 'isa')
-def whitespace_file(filename):
-    if file_type(filename) in whitespace_types:
-        return True
-
-    if filename.startswith("SCons"):
-        return True
-
-    return False
-
-format_types = ( 'C', 'C++' )
-def format_file(filename):
-    if file_type(filename) in format_types:
-        return True
-
-    return True 
+whitespace_types = set(('C', 'C++', 'swig', 'python', 'asm', 'isa', 'scons'))
+format_types = set(('C', 'C++'))
 
 def checkwhite_line(line):
     match = lead.search(line)
@@ -86,7 +56,7 @@
     return True
 
 def checkwhite(filename):
-    if not whitespace_file(filename):
+    if lang_type(filename) not in whitespace_types:
         return
 
     try:
@@ -116,7 +86,7 @@
     return line.rstrip() + '\n'
 
 def fixwhite(filename, tabsize, fixonly=None):
-    if not whitespace_file(filename):
+    if lang_type(filename) not in whitespace_types:
         return
 
     try:
@@ -174,7 +144,7 @@
                self.trailwhite or self.badcontrol or self.cret
 
 def validate(filename, stats, verbose, exit_code):
-    if not format_file(filename):
+    if lang_type(filename) not in format_types:
         return
 
     def msg(lineno, line, message):
@@ -186,13 +156,6 @@
         if exit_code is not None:
             sys.exit(exit_code)
 
-    cpp = filename.endswith('.cc') or filename.endswith('.hh')
-    py = filename.endswith('.py')
-
-    if py + cpp != 1:
-        raise AttributeError, \
-              "I don't know how to deal with the file %s" % filename
-
     try:
         f = file(filename, 'r')
     except OSError:
@@ -314,7 +277,7 @@
         if skip(fname):
             continue
 
-        if not whitespace_file(fname):
+        if lang_type(fname) not in whitespace_types:
             continue
 
         fctx = wctx.filectx(fname)
@@ -348,19 +311,7 @@
             if prompt(fname, fixonly):
                 return True
 
-def check_whitespace(ui, repo, hooktype, node, parent1, parent2, **kwargs):
-    if hooktype != 'pretxncommit':
-        raise AttributeError, \
-              "This hook is only meant for pretxncommit, not %s" % hooktype
-
-    args = { 'tabsize' : 8 }
-    return do_check_whitespace(ui, repo, **args)
-
-def check_format(ui, repo, hooktype, node, parent1, parent2, **kwargs):
-    if hooktype != 'pretxncommit':
-        raise AttributeError, \
-              "This hook is only meant for pretxncommit, not %s" % hooktype
-
+def do_check_format(ui, repo, **args):
     modified, added, removed, deleted, unknown, ignore, clean = repo.status()
 
     verbose = 0
@@ -381,6 +332,21 @@
 
     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_whitespace(ui, repo, hooktype, **kwargs):
+    check_hook(hooktype)
+    args = { 'tabsize' : 8 }
+    return do_check_whitespace(ui, repo, **args)
+
+def check_format(ui, repo, hooktype, **kwargs):
+    check_hook(hooktype)
+    args = {}
+    return do_check_format(ui, repo, **args)
+
 try:
     from mercurial.i18n import _
 except ImportError:
@@ -392,8 +358,13 @@
     ( do_check_whitespace,
       [ ('a', 'auto', False, _("automatically fix whitespace")),
         ('t', 'tabsize', 8, _("Number of spaces TAB indents")) ],
-      _('hg m5check [-t <tabsize>] [FILE]...')),
+      _('hg m5style [-a] [-t <tabsize>] [FILE]...')),
+    '^m5format' :
+    ( do_check_format,
+      [ ],
+      _('hg m5format [FILE]...')),
 }
+
 if __name__ == '__main__':
     import getopt
 
_______________________________________________
m5-dev mailing list
m5-dev@m5sim.org
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to