home *** CD-ROM | disk | FTP | other *** search
/ PC Extra 07 & 08 / pca1507.iso / Software / psp8 / Data1.cab / tabnanny.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2003-04-22  |  9.1 KB  |  263 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.2)
  3.  
  4. '''The Tab Nanny despises ambiguous indentation.  She knows no mercy.'''
  5. __version__ = '6'
  6. import os
  7. import sys
  8. import getopt
  9. import tokenize
  10. if not hasattr(tokenize, 'NL'):
  11.     raise ValueError("tokenize.NL doesn't exist -- tokenize module too old")
  12.  
  13. __all__ = [
  14.     'check',
  15.     'NannyNag',
  16.     'process_tokens']
  17. verbose = 0
  18. filename_only = 0
  19.  
  20. def errprint(*args):
  21.     sep = ''
  22.     for arg in args:
  23.         sys.stderr.write(sep + str(arg))
  24.         sep = ' '
  25.     
  26.     sys.stderr.write('\n')
  27.  
  28.  
  29. def main():
  30.     global filename_only, verbose
  31.     
  32.     try:
  33.         (opts, args) = getopt.getopt(sys.argv[1:], 'qv')
  34.     except getopt.error:
  35.         msg = None
  36.         errprint(msg)
  37.         return None
  38.  
  39.     for o, a in opts:
  40.         if o == '-q':
  41.             filename_only = filename_only + 1
  42.         
  43.         if o == '-v':
  44.             verbose = verbose + 1
  45.         
  46.     
  47.     if not args:
  48.         errprint('Usage:', sys.argv[0], '[-v] file_or_directory ...')
  49.         return None
  50.     
  51.     for arg in args:
  52.         check(arg)
  53.     
  54.  
  55.  
  56. class NannyNag:
  57.     
  58.     def __init__(self, lineno, msg, line):
  59.         (self.lineno, self.msg, self.line) = (lineno, msg, line)
  60.  
  61.     
  62.     def get_lineno(self):
  63.         return self.lineno
  64.  
  65.     
  66.     def get_msg(self):
  67.         return self.msg
  68.  
  69.     
  70.     def get_line(self):
  71.         return self.line
  72.  
  73.  
  74.  
  75. def check(file):
  76.     if os.path.isdir(file) and not os.path.islink(file):
  77.         if verbose:
  78.             print '%s: listing directory' % `file`
  79.         
  80.         names = os.listdir(file)
  81.         for name in names:
  82.             fullname = os.path.join(file, name)
  83.             if os.path.isdir(fullname) and not os.path.islink(fullname) or os.path.normcase(name[-3:]) == '.py':
  84.                 check(fullname)
  85.             
  86.         
  87.         return None
  88.     
  89.     
  90.     try:
  91.         f = open(file)
  92.     except IOError:
  93.         msg = None
  94.         errprint('%s: I/O Error: %s' % (`file`, str(msg)))
  95.         return None
  96.  
  97.     if verbose > 1:
  98.         print 'checking', `file`, '...'
  99.     
  100.     
  101.     try:
  102.         process_tokens(tokenize.generate_tokens(f.readline))
  103.     except tokenize.TokenError:
  104.         msg = None
  105.         errprint('%s: Token Error: %s' % (`file`, str(msg)))
  106.         return None
  107.     except NannyNag:
  108.         nag = None
  109.         badline = nag.get_lineno()
  110.         line = nag.get_line()
  111.         if verbose:
  112.             print '%s: *** Line %d: trouble in tab city! ***' % (`file`, badline)
  113.             print 'offending line:', `line`
  114.             print nag.get_msg()
  115.         elif ' ' in file:
  116.             file = '"' + file + '"'
  117.         
  118.         if filename_only:
  119.             print file
  120.         else:
  121.             print file, badline, `line`
  122.         return None
  123.  
  124.     if verbose:
  125.         print '%s: Clean bill of health.' % `file`
  126.     
  127.  
  128.  
  129. class Whitespace:
  130.     (S, T) = ' \t'
  131.     
  132.     def __init__(self, ws):
  133.         self.raw = ws
  134.         (S, T) = (Whitespace.S, Whitespace.T)
  135.         count = []
  136.         b = n = nt = 0
  137.         for ch in self.raw:
  138.             if ch == S:
  139.                 n = n + 1
  140.                 b = b + 1
  141.             elif ch == T:
  142.                 n = n + 1
  143.                 nt = nt + 1
  144.                 if b >= len(count):
  145.                     count = count + [
  146.                         0] * ((b - len(count)) + 1)
  147.                 
  148.                 count[b] = count[b] + 1
  149.                 b = 0
  150.             else:
  151.                 break
  152.         
  153.         self.n = n
  154.         self.nt = nt
  155.         self.norm = (tuple(count), b)
  156.         self.is_simple = len(count) <= 1
  157.  
  158.     
  159.     def longest_run_of_spaces(self):
  160.         (count, trailing) = self.norm
  161.         return max(len(count) - 1, trailing)
  162.  
  163.     
  164.     def indent_level(self, tabsize):
  165.         (count, trailing) = self.norm
  166.         il = 0
  167.         for i in range(tabsize, len(count)):
  168.             il = il + (i / tabsize) * count[i]
  169.         
  170.         return trailing + tabsize * (il + self.nt)
  171.  
  172.     
  173.     def equal(self, other):
  174.         return self.norm == other.norm
  175.  
  176.     
  177.     def not_equal_witness(self, other):
  178.         n = max(self.longest_run_of_spaces(), other.longest_run_of_spaces()) + 1
  179.         a = []
  180.         for ts in range(1, n + 1):
  181.             if self.indent_level(ts) != other.indent_level(ts):
  182.                 a.append((ts, self.indent_level(ts), other.indent_level(ts)))
  183.             
  184.         
  185.         return a
  186.  
  187.     
  188.     def less(self, other):
  189.         if self.n >= other.n:
  190.             return 0
  191.         
  192.         if self.is_simple and other.is_simple:
  193.             return self.nt <= other.nt
  194.         
  195.         n = max(self.longest_run_of_spaces(), other.longest_run_of_spaces()) + 1
  196.         for ts in range(2, n + 1):
  197.             if self.indent_level(ts) >= other.indent_level(ts):
  198.                 return 0
  199.             
  200.         
  201.         return 1
  202.  
  203.     
  204.     def not_less_witness(self, other):
  205.         n = max(self.longest_run_of_spaces(), other.longest_run_of_spaces()) + 1
  206.         a = []
  207.         for ts in range(1, n + 1):
  208.             if self.indent_level(ts) >= other.indent_level(ts):
  209.                 a.append((ts, self.indent_level(ts), other.indent_level(ts)))
  210.             
  211.         
  212.         return a
  213.  
  214.  
  215.  
  216. def format_witnesses(w):
  217.     import string
  218.     firsts = map((lambda tup: str(tup[0])), w)
  219.     prefix = 'at tab size'
  220.     if len(w) > 1:
  221.         prefix = prefix + 's'
  222.     
  223.     return prefix + ' ' + string.join(firsts, ', ')
  224.  
  225.  
  226. def process_tokens(tokens):
  227.     INDENT = tokenize.INDENT
  228.     DEDENT = tokenize.DEDENT
  229.     NEWLINE = tokenize.NEWLINE
  230.     JUNK = (tokenize.COMMENT, tokenize.NL)
  231.     indents = [
  232.         Whitespace('')]
  233.     check_equal = 0
  234.     for type, token, start, end, line in tokens:
  235.         if type == NEWLINE:
  236.             check_equal = 1
  237.         elif type == INDENT:
  238.             check_equal = 0
  239.             thisguy = Whitespace(token)
  240.             if not indents[-1].less(thisguy):
  241.                 witness = indents[-1].not_less_witness(thisguy)
  242.                 msg = 'indent not greater e.g. ' + format_witnesses(witness)
  243.                 raise NannyNag(start[0], msg, line)
  244.             
  245.             indents.append(thisguy)
  246.         elif type == DEDENT:
  247.             check_equal = 1
  248.             del indents[-1]
  249.         elif check_equal and type not in JUNK:
  250.             check_equal = 0
  251.             thisguy = Whitespace(line)
  252.             if not indents[-1].equal(thisguy):
  253.                 witness = indents[-1].not_equal_witness(thisguy)
  254.                 msg = 'indent not equal e.g. ' + format_witnesses(witness)
  255.                 raise NannyNag(start[0], msg, line)
  256.             
  257.         
  258.     
  259.  
  260. if __name__ == '__main__':
  261.     main()
  262.  
  263.