]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Initial revision
authorGuido van Rossum <guido@python.org>
Wed, 26 Dec 1990 15:40:07 +0000 (15:40 +0000)
committerGuido van Rossum <guido@python.org>
Wed, 26 Dec 1990 15:40:07 +0000 (15:40 +0000)
Lib/dis.py [new file with mode: 0644]
Lib/grep.py [new file with mode: 0644]
Lib/lib-old/grep.py [new file with mode: 0644]
Lib/lib-old/packmail.py [new file with mode: 0644]
Lib/lib-old/tb.py [new file with mode: 0644]
Lib/macpath.py [new file with mode: 0644]
Lib/packmail.py [new file with mode: 0644]
Lib/sunaudio.py [new file with mode: 0644]
Lib/tb.py [new file with mode: 0644]
Lib/test/testall.py [new file with mode: 0644]
Mac/Lib/maccache.py [new file with mode: 0644]

diff --git a/Lib/dis.py b/Lib/dis.py
new file mode 100644 (file)
index 0000000..fe57fb9
--- /dev/null
@@ -0,0 +1,176 @@
+# Disassembler
+
+import sys
+import string
+
+def dis():
+       tb = sys.last_traceback
+       while tb.tb_next: tb = tb.tb_next
+       distb(tb)
+
+def distb(tb):
+       disassemble(tb.tb_frame.f_code, tb.tb_lasti)
+
+def disco(co):
+       disassemble(co, -1)
+
+def disassemble(co, lasti):
+       code = co.co_code
+       labels = findlabels(code)
+       n = len(code)
+       i = 0
+       while i < n:
+               c = code[i]
+               op = ord(c)
+               if op = SET_LINENO and i > 0: print # Extra blank line
+               if i = lasti: print '-->',
+               else: print '   ',
+               if i in labels: print '>>',
+               else: print '  ',
+               print string.rjust(`i`, 4),
+               print string.ljust(opname[op], 15),
+               i = i+1
+               if op >= HAVE_ARGUMENT:
+                       oparg = ord(code[i]) + ord(code[i+1])*256
+                       i = i+2
+                       print string.rjust(`oparg`, 5),
+                       if op in hasconst:
+                               print '(' + `co.co_consts[oparg]` + ')',
+                       elif op in hasname:
+                               print '(' + co.co_names[oparg] + ')',
+                       elif op in hasjrel:
+                               print '(to ' + `i + oparg` + ')',
+               print
+
+def findlabels(code):
+       labels = []
+       n = len(code)
+       i = 0
+       while i < n:
+               c = code[i]
+               op = ord(c)
+               i = i+1
+               if op >= HAVE_ARGUMENT:
+                       oparg = ord(code[i]) + ord(code[i+1])*256
+                       i = i+2
+                       label = -1
+                       if op in hasjrel:
+                               label = i+oparg
+                       elif op in hasjabs:
+                               label = oparg
+                       if label >= 0:
+                               if label not in labels:
+                                       labels.append(label)
+       return labels
+
+hasconst = []
+hasname = []
+hasjrel = []
+hasjabs = []
+
+opname = range(256)
+for op in opname: opname[op] = '<' + `op` + '>'
+
+def def_op(name, op):
+       opname[op] = name
+
+def name_op(name, op):
+       opname[op] = name
+       hasname.append(op)
+
+def jrel_op(name, op):
+       opname[op] = name
+       hasjrel.append(op)
+
+def jabs_op(name, op):
+       opname[op] = name
+       hasjabs.append(op)
+
+# Instruction opcodes for compiled code
+
+def_op('STOP_CODE', 0)
+def_op('POP_TOP', 1)
+def_op('ROT_TWO', 2)
+def_op('ROT_THREE', 3)
+def_op('DUP_TOP', 4)
+
+def_op('UNARY_POSITIVE', 10)
+def_op('UNARY_NEGATIVE', 11)
+def_op('UNARY_NOT', 12)
+def_op('UNARY_CONVERT', 13)
+def_op('UNARY_CALL', 14)
+
+def_op('BINARY_MULTIPLY', 20)
+def_op('BINARY_DIVIDE', 21)
+def_op('BINARY_MODULO', 22)
+def_op('BINARY_ADD', 23)
+def_op('BINARY_SUBTRACT', 24)
+def_op('BINARY_SUBSCR', 25)
+def_op('BINARY_CALL', 26)
+
+def_op('SLICE+0', 30)
+def_op('SLICE+1', 31)
+def_op('SLICE+2', 32)
+def_op('SLICE+3', 33)
+
+def_op('STORE_SLICE+0', 40)
+def_op('STORE_SLICE+1', 41)
+def_op('STORE_SLICE+2', 42)
+def_op('STORE_SLICE+3', 43)
+
+def_op('DELETE_SLICE+0', 50)
+def_op('DELETE_SLICE+1', 51)
+def_op('DELETE_SLICE+2', 52)
+def_op('DELETE_SLICE+3', 53)
+
+def_op('STORE_SUBSCR', 60)
+def_op('DELETE_SUBSCR', 61)
+
+def_op('PRINT_EXPR', 70)
+def_op('PRINT_ITEM', 71)
+def_op('PRINT_NEWLINE', 72)
+
+def_op('BREAK_LOOP', 80)
+def_op('RAISE_EXCEPTION', 81)
+def_op('LOAD_LOCALS', 82)
+def_op('RETURN_VALUE', 83)
+def_op('REQUIRE_ARGS', 84)
+def_op('REFUSE_ARGS', 85)
+def_op('BUILD_FUNCTION', 86)
+def_op('POP_BLOCK', 87)
+def_op('END_FINALLY', 88)
+def_op('BUILD_CLASS', 89)
+
+HAVE_ARGUMENT = 90             # Opcodes from here have an argument: 
+
+name_op('STORE_NAME', 90)      # Index in name list 
+name_op('DELETE_NAME', 91)     # "" 
+def_op('UNPACK_TUPLE', 92)     # Number of tuple items 
+def_op('UNPACK_LIST', 93)      # Number of list items 
+# unused:              94
+name_op('STORE_ATTR', 95)      # Index in name list 
+name_op('DELETE_ATTR', 96)     # "" 
+
+def_op('LOAD_CONST', 100)      # Index in const list 
+hasconst.append(100)
+name_op('LOAD_NAME', 101)      # Index in name list 
+def_op('BUILD_TUPLE', 102)     # Number of tuple items 
+def_op('BUILD_LIST', 103)      # Number of list items 
+def_op('BUILD_MAP', 104)       # Always zero for now 
+name_op('LOAD_ATTR', 105)      # Index in name list 
+def_op('COMPARE_OP', 106)      # Comparison operator 
+name_op('IMPORT_NAME', 107)    # Index in name list 
+name_op('IMPORT_FROM', 108)    # Index in name list 
+
+jrel_op('JUMP_FORWARD', 110)   # Number of bytes to skip 
+jrel_op('JUMP_IF_FALSE', 111)  # "" 
+jrel_op('JUMP_IF_TRUE', 112)   # "" 
+jabs_op('JUMP_ABSOLUTE', 113)  # Target byte offset from beginning of code 
+jrel_op('FOR_LOOP', 114)       # Number of bytes to skip 
+
+jrel_op('SETUP_LOOP', 120)     # Distance to target address
+jrel_op('SETUP_EXCEPT', 121)   # ""
+jrel_op('SETUP_FINALLY', 122)  # ""
+
+def_op('SET_LINENO', 127)      # Current line number
+SET_LINENO = 127
diff --git a/Lib/grep.py b/Lib/grep.py
new file mode 100644 (file)
index 0000000..210f9f0
--- /dev/null
@@ -0,0 +1,32 @@
+# 'grep'
+
+import regexp
+import string
+
+def grep(expr, filename):
+       prog = regexp.compile(expr)
+       fp = open(filename, 'r')
+       lineno = 0
+       while 1:
+               line = fp.readline()
+               if not line: break
+               lineno = lineno + 1
+               res = prog.exec(line)
+               if res:
+                       #print res
+                       start, end = res[0]
+                       if line[-1:] = '\n': line = line[:-1]
+                       prefix = string.rjust(`lineno`, 3) + ': '
+                       print prefix + line
+                       if 0:
+                               line = line[:start]
+                               if '\t' not in line:
+                                       prefix = ' ' * (len(prefix) + start)
+                               else:
+                                       prefix = ' ' * len(prefix)
+                                       for c in line:
+                                               if c <> '\t': c = ' '
+                                               prefix = prefix + c
+                               if start = end: prefix = prefix + '\\'
+                               else: prefix = prefix + '^'*(end-start)
+                               print prefix
diff --git a/Lib/lib-old/grep.py b/Lib/lib-old/grep.py
new file mode 100644 (file)
index 0000000..210f9f0
--- /dev/null
@@ -0,0 +1,32 @@
+# 'grep'
+
+import regexp
+import string
+
+def grep(expr, filename):
+       prog = regexp.compile(expr)
+       fp = open(filename, 'r')
+       lineno = 0
+       while 1:
+               line = fp.readline()
+               if not line: break
+               lineno = lineno + 1
+               res = prog.exec(line)
+               if res:
+                       #print res
+                       start, end = res[0]
+                       if line[-1:] = '\n': line = line[:-1]
+                       prefix = string.rjust(`lineno`, 3) + ': '
+                       print prefix + line
+                       if 0:
+                               line = line[:start]
+                               if '\t' not in line:
+                                       prefix = ' ' * (len(prefix) + start)
+                               else:
+                                       prefix = ' ' * len(prefix)
+                                       for c in line:
+                                               if c <> '\t': c = ' '
+                                               prefix = prefix + c
+                               if start = end: prefix = prefix + '\\'
+                               else: prefix = prefix + '^'*(end-start)
+                               print prefix
diff --git a/Lib/lib-old/packmail.py b/Lib/lib-old/packmail.py
new file mode 100644 (file)
index 0000000..c7bebe8
--- /dev/null
@@ -0,0 +1,48 @@
+# Module 'packmail' -- create a shell script out of some files.
+
+import mac
+import macpath
+from stat import ST_MTIME
+
+# Pack one file
+def pack(outfp, file, name):
+       fp = open(file, 'r')
+       outfp.write('sed "s/^X//" >' + name + ' <<"!"\n')
+       while 1:
+               line = fp.readline()
+               if not line: break
+               if line[-1:] <> '\n':
+                       line = line + '\n'
+               outfp.write('X' + line)
+       outfp.write('!\n')
+
+# Pack some files from a directory
+def packsome(outfp, dirname, names):
+       for name in names:
+               print name
+               file = macpath.cat(dirname, name)
+               pack(outfp, file, name)
+
+# Pack all files from a directory
+def packall(outfp, dirname):
+       names = mac.listdir(dirname)
+       names.sort()
+       packsome(outfp, dirname, names)
+
+# Pack all files from a directory that are not older than a give one
+def packnotolder(outfp, dirname, oldest):
+       names = mac.listdir(dirname)
+       oldest = macpath.cat(dirname, oldest)
+       st = mac.stat(oldest)
+       mtime = st[ST_MTIME]
+       todo = []
+       for name in names:
+               print name, '...',
+               st = mac.stat(macpath.cat(dirname, name))
+               if st[ST_MTIME] >= mtime:
+                       print 'Yes.'
+                       todo.append(name)
+               else:
+                       print 'No.'
+       todo.sort()
+       packsome(outfp, dirname, todo)
diff --git a/Lib/lib-old/tb.py b/Lib/lib-old/tb.py
new file mode 100644 (file)
index 0000000..e0f2748
--- /dev/null
@@ -0,0 +1,220 @@
+# Print tracebacks, with a dump of local variables.
+# Also an interactive stack trace browser.
+
+import sys
+try:
+       import mac
+       os = mac
+except NameError:
+       import posix
+       os = posix
+from stat import *
+import string
+
+def br(): browser(sys.last_traceback)
+
+def tb(): printtb(sys.last_traceback)
+
+def browser(tb):
+       if not tb:
+               print 'No traceback.'
+               return
+       tblist = []
+       while tb:
+               tblist.append(tb)
+               tb = tb.tb_next
+       ptr = len(tblist)-1
+       tb = tblist[ptr]
+       while 1:
+               if tb <> tblist[ptr]:
+                       tb = tblist[ptr]
+                       print `ptr` + ':',
+                       printtbheader(tb)
+               try:
+                       line = raw_input('TB: ')
+               except KeyboardInterrupt:
+                       print '\n[Interrupted]'
+                       break
+               except EOFError:
+                       print '\n[EOF]'
+                       break
+               cmd = string.strip(line)
+               if cmd:
+                       if cmd = 'quit':
+                               break
+                       elif cmd = 'list':
+                               browserlist(tb)
+                       elif cmd = 'up':
+                               if ptr-1 >= 0: ptr = ptr-1
+                               else: print 'Bottom of stack.'
+                       elif cmd = 'down':
+                               if ptr+1 < len(tblist): ptr = ptr+1
+                               else: print 'Top of stack.'
+                       elif cmd = 'locals':
+                               printsymbols(tb.tb_frame.f_locals)
+                       elif cmd = 'globals':
+                               printsymbols(tb.tb_frame.f_globals)
+                       elif cmd in ('?', 'help'):
+                               browserhelp()
+                       else:
+                               browserexec(tb, cmd)
+
+def browserlist(tb):
+       filename = tb.tb_frame.f_code.co_filename
+       lineno = tb.tb_lineno
+       last = lineno
+       first = max(1, last-10)
+       for i in range(first, last+1):
+               if i = lineno: prefix = '***' + string.rjust(`i`, 4) + ':'
+               else: prefix = string.rjust(`i`, 7) + ':'
+               line = readfileline(filename, i)
+               if line[-1:] = '\n': line = line[:-1]
+               print prefix + line
+
+def browserexec(tb, cmd):
+       locals = tb.tb_frame.f_locals
+       globals = tb.tb_frame.f_globals
+       try:
+               exec(cmd+'\n', globals, locals)
+       except:
+               print '*** Exception:',
+               print sys.exc_type,
+               if sys.exc_value <> None:
+                       print ':', sys.exc_value,
+               print
+               print 'Type help to get help.'
+
+def browserhelp():
+       print
+       print '    This is the traceback browser.  Commands are:'
+       print '        up      : move one level up in the call stack'
+       print '        down    : move one level down in the call stack'
+       print '        locals  : print all local variables at this level'
+       print '        globals : print all global variables at this level'
+       print '        list    : list source code around the failure'
+       print '        help    : print help (what you are reading now)'
+       print '        quit    : back to command interpreter'
+       print '    Typing any other 1-line statement will execute it'
+       print '    using the current level\'s symbol tables'
+       print
+
+def printtb(tb):
+       while tb:
+               print1tb(tb)
+               tb = tb.tb_next
+
+def print1tb(tb):
+       printtbheader(tb)
+       if tb.tb_frame.f_locals is not tb.tb_frame.f_globals:
+               printsymbols(tb.tb_frame.f_locals)
+
+def printtbheader(tb):
+       filename = tb.tb_frame.f_code.co_filename
+       lineno = tb.tb_lineno
+       info = '"' + filename + '"(' + `lineno` + ')'
+       line = readfileline(filename, lineno)
+       if line:
+               info = info + ': ' + string.strip(line)
+       print info
+
+def printsymbols(d):
+       keys = d.keys()
+       keys.sort()
+       for name in keys:
+               print '  ' + string.ljust(name, 12) + ':',
+               printobject(d[name], 4)
+               print
+
+def printobject(v, maxlevel):
+       if v = None:
+               print 'None',
+       elif type(v) in (type(0), type(0.0)):
+               print v,
+       elif type(v) = type(''):
+               if len(v) > 20:
+                       print `v[:17] + '...'`,
+               else:
+                       print `v`,
+       elif type(v) = type(()):
+               print '(',
+               printlist(v, maxlevel)
+               print ')',
+       elif type(v) = type([]):
+               print '[',
+               printlist(v, maxlevel)
+               print ']',
+       elif type(v) = type({}):
+               print '{',
+               printdict(v, maxlevel)
+               print '}',
+       else:
+               print v,
+
+def printlist(v, maxlevel):
+       n = len(v)
+       if n = 0: return
+       if maxlevel <= 0:
+               print '...',
+               return
+       for i in range(min(6, n)):
+               printobject(v[i], maxlevel-1)
+               if i+1 < n: print ',',
+       if n > 6: print '...',
+
+def printdict(v, maxlevel):
+       keys = v.keys()
+       n = len(keys)
+       if n = 0: return
+       if maxlevel <= 0:
+               print '...',
+               return
+       keys.sort()
+       for i in range(min(6, n)):
+               key = keys[i]
+               print `key` + ':',
+               printobject(v[key], maxlevel-1)
+               if i+1 < n: print ',',
+       if n > 6: print '...',
+
+_filecache = {}
+
+def readfileline(filename, lineno):
+       try:
+               stat = os.stat(filename)
+       except os.error, msg:
+               print 'Cannot stat', filename, '--', msg
+               return ''
+       cache_ok = 0
+       if _filecache.has_key(filename):
+               cached_stat, lines = _filecache[filename]
+               if stat[ST_SIZE] = cached_stat[ST_SIZE] and \
+                               stat[ST_MTIME] = cached_stat[ST_MTIME]:
+                       cache_ok = 1
+               else:
+                       print 'Stale cache entry for', filename
+                       del _filecache[filename]
+       if not cache_ok:
+               lines = readfilelines(filename)
+               if not lines:
+                       return ''
+               _filecache[filename] = stat, lines
+       if 0 <= lineno-1 < len(lines):
+               return lines[lineno-1]
+       else:
+               print 'Line number out of range, last line is', len(lines)
+               return ''
+
+def readfilelines(filename):
+       try:
+               fp = open(filename, 'r')
+       except:
+               print 'Cannot open', filename
+               return []
+       lines = []
+       while 1:
+               line = fp.readline()
+               if not line: break
+               lines.append(line)
+       if not lines:
+               print 'Empty file', filename
+       return lines
diff --git a/Lib/macpath.py b/Lib/macpath.py
new file mode 100644 (file)
index 0000000..30d2f27
--- /dev/null
@@ -0,0 +1,70 @@
+# module 'macpath'
+
+import mac
+
+import string
+
+from stat import *
+
+def isabs(s):
+       return ':' in s and s[0] <> ':'
+
+def cat(s, t):
+       if (not s) or isabs(t): return t
+       if t[:1] = ':': t = t[1:]
+       if ':' not in s:
+               s = ':' + s
+       if s[-1:] <> ':':
+               s = s + ':'
+       return s + t
+
+norm_error = 'path cannot be normalized'
+
+def norm(s):
+       if ':' not in s:
+               return ':' + s
+       f = string.splitfields(s, ':')
+       pre = []
+       post = []
+       if not f[0]:
+               pre = f[:1]
+               f = f[1:]
+       if not f[len(f)-1]:
+               post = f[-1:]
+               f = f[:-1]
+       res = []
+       for seg in f:
+               if seg:
+                       res.append(seg)
+               else:
+                       if not res: raise norm_error # starts with '::'
+                       del res[len(res)-1]
+                       if not (pre or res):
+                               raise norm_error # starts with 'vol::'
+       if pre: res = pre + res
+       if post: res = res + post
+       s = res[0]
+       for seg in res[1:]:
+               s = s + ':' + seg
+       return s
+
+def isdir(s):
+       try:
+               st = mac.stat(s)
+       except mac.error:
+               return 0
+       return S_ISDIR(st[ST_MODE])
+
+def isfile(s):
+       try:
+               st = mac.stat(s)
+       except mac.error:
+               return 0
+       return S_ISREG(st[ST_MODE])
+
+def exists(s):
+       try:
+               st = mac.stat(s)
+       except mac.error:
+               return 0
+       return 1
diff --git a/Lib/packmail.py b/Lib/packmail.py
new file mode 100644 (file)
index 0000000..c7bebe8
--- /dev/null
@@ -0,0 +1,48 @@
+# Module 'packmail' -- create a shell script out of some files.
+
+import mac
+import macpath
+from stat import ST_MTIME
+
+# Pack one file
+def pack(outfp, file, name):
+       fp = open(file, 'r')
+       outfp.write('sed "s/^X//" >' + name + ' <<"!"\n')
+       while 1:
+               line = fp.readline()
+               if not line: break
+               if line[-1:] <> '\n':
+                       line = line + '\n'
+               outfp.write('X' + line)
+       outfp.write('!\n')
+
+# Pack some files from a directory
+def packsome(outfp, dirname, names):
+       for name in names:
+               print name
+               file = macpath.cat(dirname, name)
+               pack(outfp, file, name)
+
+# Pack all files from a directory
+def packall(outfp, dirname):
+       names = mac.listdir(dirname)
+       names.sort()
+       packsome(outfp, dirname, names)
+
+# Pack all files from a directory that are not older than a give one
+def packnotolder(outfp, dirname, oldest):
+       names = mac.listdir(dirname)
+       oldest = macpath.cat(dirname, oldest)
+       st = mac.stat(oldest)
+       mtime = st[ST_MTIME]
+       todo = []
+       for name in names:
+               print name, '...',
+               st = mac.stat(macpath.cat(dirname, name))
+               if st[ST_MTIME] >= mtime:
+                       print 'Yes.'
+                       todo.append(name)
+               else:
+                       print 'No.'
+       todo.sort()
+       packsome(outfp, dirname, todo)
diff --git a/Lib/sunaudio.py b/Lib/sunaudio.py
new file mode 100644 (file)
index 0000000..92a6203
--- /dev/null
@@ -0,0 +1,54 @@
+# Module 'sunaudio' -- interpret sun audio headers
+
+import audio
+
+MAGIC = '.snd'
+
+error = 'sunaudio sound header conversion error'
+
+
+# convert a 4-char value to integer
+
+def c2i(data):
+       if type(data) <> type('') or len(data) <> 4:
+               raise error, 'c2i: bad arg (not string[4])'
+       bytes = audio.chr2num(data)
+       for i in (1, 2, 3):
+               if bytes[i] < 0:
+                       bytes[i] = bytes[i] + 256
+       return ((bytes[0]*256 + bytes[1])*256 + bytes[2])*256 + bytes[3]
+
+
+# read a sound header from an open file
+
+def gethdr(fp):
+       if fp.read(4) <> MAGIC:
+               raise error, 'gethdr: bad magic word'
+       hdr_size = c2i(fp.read(4))
+       data_size = c2i(fp.read(4))
+       encoding = c2i(fp.read(4))
+       sample_rate = c2i(fp.read(4))
+       channels = c2i(fp.read(4))
+       excess = hdr_size - 24
+       if excess < 0:
+               raise error, 'gethdr: bad hdr_size'
+       if excess > 0:
+               info = fp.read(excess)
+       else:
+               info = ''
+       return (data_size, encoding, sample_rate, channels, info)
+
+
+# read and print the sound header of a named file
+
+def printhdr(file):
+       hdr = gethdr(open(file, 'r'))
+       data_size, encoding, sample_rate, channels, info = hdr
+       while info[-1:] = '\0':
+               info = info[:-1]
+       print 'File name:  ', file
+       print 'Data size:  ', data_size
+       print 'Encoding:   ', encoding
+       print 'Sample rate:', sample_rate
+       print 'Channels:   ', channels
+       print 'Info:       ', `info`
diff --git a/Lib/tb.py b/Lib/tb.py
new file mode 100644 (file)
index 0000000..e0f2748
--- /dev/null
+++ b/Lib/tb.py
@@ -0,0 +1,220 @@
+# Print tracebacks, with a dump of local variables.
+# Also an interactive stack trace browser.
+
+import sys
+try:
+       import mac
+       os = mac
+except NameError:
+       import posix
+       os = posix
+from stat import *
+import string
+
+def br(): browser(sys.last_traceback)
+
+def tb(): printtb(sys.last_traceback)
+
+def browser(tb):
+       if not tb:
+               print 'No traceback.'
+               return
+       tblist = []
+       while tb:
+               tblist.append(tb)
+               tb = tb.tb_next
+       ptr = len(tblist)-1
+       tb = tblist[ptr]
+       while 1:
+               if tb <> tblist[ptr]:
+                       tb = tblist[ptr]
+                       print `ptr` + ':',
+                       printtbheader(tb)
+               try:
+                       line = raw_input('TB: ')
+               except KeyboardInterrupt:
+                       print '\n[Interrupted]'
+                       break
+               except EOFError:
+                       print '\n[EOF]'
+                       break
+               cmd = string.strip(line)
+               if cmd:
+                       if cmd = 'quit':
+                               break
+                       elif cmd = 'list':
+                               browserlist(tb)
+                       elif cmd = 'up':
+                               if ptr-1 >= 0: ptr = ptr-1
+                               else: print 'Bottom of stack.'
+                       elif cmd = 'down':
+                               if ptr+1 < len(tblist): ptr = ptr+1
+                               else: print 'Top of stack.'
+                       elif cmd = 'locals':
+                               printsymbols(tb.tb_frame.f_locals)
+                       elif cmd = 'globals':
+                               printsymbols(tb.tb_frame.f_globals)
+                       elif cmd in ('?', 'help'):
+                               browserhelp()
+                       else:
+                               browserexec(tb, cmd)
+
+def browserlist(tb):
+       filename = tb.tb_frame.f_code.co_filename
+       lineno = tb.tb_lineno
+       last = lineno
+       first = max(1, last-10)
+       for i in range(first, last+1):
+               if i = lineno: prefix = '***' + string.rjust(`i`, 4) + ':'
+               else: prefix = string.rjust(`i`, 7) + ':'
+               line = readfileline(filename, i)
+               if line[-1:] = '\n': line = line[:-1]
+               print prefix + line
+
+def browserexec(tb, cmd):
+       locals = tb.tb_frame.f_locals
+       globals = tb.tb_frame.f_globals
+       try:
+               exec(cmd+'\n', globals, locals)
+       except:
+               print '*** Exception:',
+               print sys.exc_type,
+               if sys.exc_value <> None:
+                       print ':', sys.exc_value,
+               print
+               print 'Type help to get help.'
+
+def browserhelp():
+       print
+       print '    This is the traceback browser.  Commands are:'
+       print '        up      : move one level up in the call stack'
+       print '        down    : move one level down in the call stack'
+       print '        locals  : print all local variables at this level'
+       print '        globals : print all global variables at this level'
+       print '        list    : list source code around the failure'
+       print '        help    : print help (what you are reading now)'
+       print '        quit    : back to command interpreter'
+       print '    Typing any other 1-line statement will execute it'
+       print '    using the current level\'s symbol tables'
+       print
+
+def printtb(tb):
+       while tb:
+               print1tb(tb)
+               tb = tb.tb_next
+
+def print1tb(tb):
+       printtbheader(tb)
+       if tb.tb_frame.f_locals is not tb.tb_frame.f_globals:
+               printsymbols(tb.tb_frame.f_locals)
+
+def printtbheader(tb):
+       filename = tb.tb_frame.f_code.co_filename
+       lineno = tb.tb_lineno
+       info = '"' + filename + '"(' + `lineno` + ')'
+       line = readfileline(filename, lineno)
+       if line:
+               info = info + ': ' + string.strip(line)
+       print info
+
+def printsymbols(d):
+       keys = d.keys()
+       keys.sort()
+       for name in keys:
+               print '  ' + string.ljust(name, 12) + ':',
+               printobject(d[name], 4)
+               print
+
+def printobject(v, maxlevel):
+       if v = None:
+               print 'None',
+       elif type(v) in (type(0), type(0.0)):
+               print v,
+       elif type(v) = type(''):
+               if len(v) > 20:
+                       print `v[:17] + '...'`,
+               else:
+                       print `v`,
+       elif type(v) = type(()):
+               print '(',
+               printlist(v, maxlevel)
+               print ')',
+       elif type(v) = type([]):
+               print '[',
+               printlist(v, maxlevel)
+               print ']',
+       elif type(v) = type({}):
+               print '{',
+               printdict(v, maxlevel)
+               print '}',
+       else:
+               print v,
+
+def printlist(v, maxlevel):
+       n = len(v)
+       if n = 0: return
+       if maxlevel <= 0:
+               print '...',
+               return
+       for i in range(min(6, n)):
+               printobject(v[i], maxlevel-1)
+               if i+1 < n: print ',',
+       if n > 6: print '...',
+
+def printdict(v, maxlevel):
+       keys = v.keys()
+       n = len(keys)
+       if n = 0: return
+       if maxlevel <= 0:
+               print '...',
+               return
+       keys.sort()
+       for i in range(min(6, n)):
+               key = keys[i]
+               print `key` + ':',
+               printobject(v[key], maxlevel-1)
+               if i+1 < n: print ',',
+       if n > 6: print '...',
+
+_filecache = {}
+
+def readfileline(filename, lineno):
+       try:
+               stat = os.stat(filename)
+       except os.error, msg:
+               print 'Cannot stat', filename, '--', msg
+               return ''
+       cache_ok = 0
+       if _filecache.has_key(filename):
+               cached_stat, lines = _filecache[filename]
+               if stat[ST_SIZE] = cached_stat[ST_SIZE] and \
+                               stat[ST_MTIME] = cached_stat[ST_MTIME]:
+                       cache_ok = 1
+               else:
+                       print 'Stale cache entry for', filename
+                       del _filecache[filename]
+       if not cache_ok:
+               lines = readfilelines(filename)
+               if not lines:
+                       return ''
+               _filecache[filename] = stat, lines
+       if 0 <= lineno-1 < len(lines):
+               return lines[lineno-1]
+       else:
+               print 'Line number out of range, last line is', len(lines)
+               return ''
+
+def readfilelines(filename):
+       try:
+               fp = open(filename, 'r')
+       except:
+               print 'Cannot open', filename
+               return []
+       lines = []
+       while 1:
+               line = fp.readline()
+               if not line: break
+               lines.append(line)
+       if not lines:
+               print 'Empty file', filename
+       return lines
diff --git a/Lib/test/testall.py b/Lib/test/testall.py
new file mode 100644 (file)
index 0000000..ef7cb13
--- /dev/null
@@ -0,0 +1,416 @@
+# Module 'testall'
+#
+# Python test set, should exercise:
+#      - all lexical and grammatical constructs
+#      - all opcodes from "opcode.h"
+#      - all operations on all object types
+#      - all builtin functions
+# Ideally also:
+#      - all possible exception situations (Thank God we've got 'try')
+#      - all boundary cases
+
+
+TestFailed = 'testall -- test failed'          # Exception
+
+
+#########################################################
+# Part 1.  Test all lexical and grammatical constructs.
+# This just tests whether the parser accepts them all.
+#########################################################
+
+print '1. Parser'
+
+print '1.1 Tokens'
+
+print '1.1.1 Backslashes'
+
+# Backslash means line continuation:
+x = 1 \
++ 1
+if x <> 2: raise TestFailed, 'backslash for line continuation'
+
+# Backslash does not means continuation in comments :\
+x = 0
+if x <> 0: raise TestFailed, 'backslash ending comment'
+
+print '1.1.2 Number formats'
+
+if 0xff <> 255: raise TestFailed, 'hex number'
+if 0377 <> 255: raise TestFailed, 'octal number'
+x = 3.14
+x = 0.314
+x = 3e14
+x = 3E14
+x = 3e-14
+
+print '1.2 Grammar'
+
+print 'single_input' # NEWLINE | simple_stmt | compound_stmt NEWLINE
+# XXX can't test in a script -- this rule is only used when interactive
+
+print 'file_input' # (NEWLINE | stmt)* ENDMARKER
+# Being tested as this very moment this very module
+
+print 'expr_input' # testlist NEWLINE
+# XXX Hard to test -- used only in calls to input()
+
+print 'eval_input' # testlist ENDMARKER
+x = eval('1, 0 or 1')
+
+print 'funcdef' # 'def' NAME parameters ':' suite
+### parameters: '(' [fplist] ')'
+### fplist: fpdef (',' fpdef)*
+### fpdef: NAME | '(' fplist ')'
+def f1(): pass
+def f2(one_argument): pass
+def f3(two, arguments): pass
+def f4(two, (compound, (arguments))): pass
+
+### stmt: simple_stmt | compound_stmt
+### simple_stmt: expr_stmt | print_stmt  | pass_stmt | del_stmt | flow_stmt | import_stmt
+# Tested below
+
+print 'expr_stmt' # (exprlist '=')* exprlist NEWLINE
+1
+1, 2, 3
+x = 1
+x = 1, 2, 3
+x = y = z = 1, 2, 3
+x, y, z = 1, 2, 3
+abc = a, b, c = x, y, z = xyz = 1, 2, (3, 4)
+# NB these variables are deleted below
+
+print 'print_stmt' # 'print' (test ',')* [test] NEWLINE
+print 1, 2, 3
+print 1, 2, 3,
+print
+print 0 or 1, 0 or 1,
+print 0 or 1
+
+print 'del_stmt' # 'del' exprlist NEWLINE
+del abc
+del x, y, (z, xyz)
+
+print 'pass_stmt' # 'pass' NEWLINE
+pass
+
+print 'flow_stmt' # break_stmt | return_stmt | raise_stmt
+# Tested below
+
+print 'break_stmt' # 'break' NEWLINE
+while 1: break
+
+print 'return_stmt' # 'return' [testlist] NEWLINE
+def g1(): return
+def g2(): return 1
+g1()
+x = g2()
+
+print 'raise_stmt' # 'raise' expr [',' expr] NEWLINE
+try: raise RuntimeError, 'just testing'
+except RuntimeError: pass
+try: raise KeyboardInterrupt
+except KeyboardInterrupt: pass
+
+print 'import_stmt' # 'import' NAME (',' NAME)* NEWLINE | 'from' NAME 'import' ('*' | NAME (',' NAME)*) NEWLINE
+[1]
+import sys
+[2]
+import time, math
+[3]
+from time import sleep
+[4]
+from math import *
+[5]
+from sys import modules, ps1, ps2
+[6]
+
+### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
+# Tested below
+
+print 'if_stmt' # 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
+if 1: pass
+if 1: pass
+else: pass
+if 0: pass
+elif 0: pass
+if 0: pass
+elif 0: pass
+elif 0: pass
+elif 0: pass
+else: pass
+
+print 'while_stmt' # 'while' test ':' suite ['else' ':' suite]
+while 0: pass
+while 0: pass
+else: pass
+
+print 'for_stmt' # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite]
+[1]
+for i in 1, 2, 3: pass
+[2]
+for i, j, k in (): pass
+else: pass
+[3]
+
+print 'try_stmt' # 'try' ':' suite (except_clause ':' suite)* ['finally' ':' suite]
+### except_clause: 'except' [expr [',' expr]]
+try: pass
+try: 1/0
+except RuntimeError: pass
+try: 1/0
+except EOFError: pass
+except TypeError, msg: pass
+except RuntimeError, msg: pass
+except: pass
+try: pass
+finally: pass
+try: 1/0
+except: pass
+finally: pass
+
+print 'suite' # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT
+if 1: pass
+if 1:
+       pass
+if 1:
+       #
+       #
+       #
+       pass
+       pass
+       #
+       pass
+       #
+
+print 'test' # and_test ('or' and_test)*
+### and_test: not_test ('and' not_test)*
+### not_test: 'not' not_test | comparison
+### comparison: expr (comp_op expr)*
+### comp_op: '<'|'>'|'='|'>' '='|'<' '='|'<' '>'|'in'|'not' 'in'|'is'|'is' 'not'
+if 1: pass
+if 1 = 1: pass
+if 1 < 1 > 1 = 1 >= 1 <= 1 <> 1 in 1 not in 1 is 1 is not 1: pass
+if not 1 = 1 = 1: pass
+if not 1 = 1 and 1 and 1: pass
+if 1 and 1 or 1 and 1 and 1 or not 1 = 1 = 1 and 1: pass
+
+print 'expr' # term (('+'|'-') term)*
+x = 1
+x = 1 + 1
+x = 1 - 1 - 1
+x = 1 - 1 + 1 - 1 + 1
+
+print 'term' # factor (('*'|'/'|'%') factor)*
+x = 1 * 1
+x = 1 / 1
+x = 1 % 1
+x = 1 / 1 * 1 % 1
+
+print 'factor' # ('+'|'-') factor | atom trailer*
+### trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME
+### subscript: expr | [expr] ':' [expr]
+x = +1
+x = -1
+x = 1
+c = sys.ps1[0]
+x = time.time()
+x = sys.modules['time'].time()
+a = '01234'
+c = a[0]
+c = a[0:5]
+c = a[:5]
+c = a[0:]
+c = a[:]
+c = a[-5:]
+c = a[:-1]
+c = a[-4:-3]
+
+print 'atom' # '(' [testlist] ')' | '[' [testlist] ']' | '{' '}' | '`' testlist '`' | NAME | NUMBER | STRING
+x = (1)
+x = (1 or 2 or 3)
+x = (1 or 2 or 3, 2, 3)
+x = []
+x = [1]
+x = [1 or 2 or 3]
+x = [1 or 2 or 3, 2, 3]
+x = []
+x = {}
+x = `x`
+x = x
+x = 'x'
+x = 123
+
+### exprlist: expr (',' expr)* [',']
+### testlist: test (',' test)* [',']
+# These have been exercised enough above
+
+print 'classdef' # 'class' NAME parameters ['=' baselist] ':' suite
+### baselist: atom arguments (',' atom arguments)*
+### arguments: '(' [testlist] ')'
+class B(): pass
+class C1() = B(): pass
+class C2() = B(): pass
+class D() = C1(), C2(), B(): pass
+class C():
+       def meth1(self): pass
+       def meth2(self, arg): pass
+       def meth3(self, (a1, a2)): pass
+
+
+#########################################################
+# Part 2.  Test all opcodes from "opcode.h"
+#########################################################
+
+print '2. Opcodes'
+print 'XXX Not yet fully implemented'
+
+print '2.1 try inside for loop'
+n = 0
+for i in range(10):
+       n = n+i
+       try: 1/0
+       except NameError: pass
+       except RuntimeError: pass
+       except TypeError: pass
+       finally: pass
+       try: pass
+       except: pass
+       try: pass
+       finally: pass
+       n = n+i
+if n <> 90:
+       raise TestFailed, 'try inside for'
+
+
+#########################################################
+# Part 3.  Test all operations on all object types
+#########################################################
+
+print '3. Object types'
+print 'XXX Not yet implemented'
+
+
+#########################################################
+# Part 4.  Test all built-in functions
+#########################################################
+
+print '4. Built-in functions'
+
+print 'abs'
+if abs(0) <> 0: raise TestFailed, 'abs(0)'
+if abs(1234) <> 1234: raise TestFailed, 'abs(1234)'
+if abs(-1234) <> 1234: raise TestFailed, 'abs(-1234)'
+if abs(0.0) <> 0.0: raise TestFailed, 'abs(0.0)'
+if abs(3.14) <> 3.14: raise TestFailed, 'abs(3.14)'
+if abs(-3.14) <> 3.14: raise TestFailed, 'abs(-3.14)'
+
+print 'dir'
+if 'x' not in dir(): raise TestFailed, 'dir()'
+if 'modules' not in dir(sys): raise TestFailed, 'dir(sys)'
+
+print 'divmod'
+if divmod(12, 7) <> (1, 5): raise TestFailed, 'divmod(12, 7)'
+if divmod(-12, 7) <> (-2, 2): raise TestFailed, 'divmod(-12, 7)'
+if divmod(12, -7) <> (-2, -2): raise TestFailed, 'divmod(12, -7)'
+if divmod(-12, -7) <> (1, -5): raise TestFailed, 'divmod(-12, -7)'
+
+print 'eval'
+if eval('1+1') <> 2: raise TestFailed, 'eval(\'1+1\')'
+
+print 'exec'
+exec('z=1+1\n')
+if z <> 2: raise TestFailed, 'exec(\'z=1+1\'\\n)'
+
+print 'float'
+if float(3.14) <> 3.14: raise TestFailed, 'float(3.14)'
+if float(314) <> 314.0: raise TestFailed, 'float(314)'
+
+print 'input'
+# Can't test in a script
+
+print 'int'
+if int(100) <> 100: raise TestFailed, 'int(100)'
+if int(3.14) <> 3: raise TestFailed, 'int(3.14)'
+
+print 'len'
+if len('123') <> 3: raise TestFailed, 'len(\'123\')'
+if len(()) <> 0: raise TestFailed, 'len(())'
+if len((1, 2, 3, 4)) <> 4: raise TestFailed, 'len((1, 2, 3, 4))'
+if len([1, 2, 3, 4]) <> 4: raise TestFailed, 'len([1, 2, 3, 4])'
+if len({}) <> 0: raise TestFailed, 'len({})'
+
+print 'min'
+if min('123123') <> '1': raise TestFailed, 'min(\'123123\')'
+if min(1, 2, 3) <> 1: raise TestFailed, 'min(1, 2, 3)'
+if min((1, 2, 3, 1, 2, 3)) <> 1: raise TestFailed, 'min((1, 2, 3, 1, 2, 3))'
+if min([1, 2, 3, 1, 2, 3]) <> 1: raise TestFailed, 'min([1, 2, 3, 1, 2, 3])'
+
+print 'max'
+if max('123123') <> '3': raise TestFailed, 'max(\'123123\')'
+if max(1, 2, 3) <> 3: raise TestFailed, 'max(1, 2, 3)'
+if max((1, 2, 3, 1, 2, 3)) <> 3: raise TestFailed, 'max((1, 2, 3, 1, 2, 3))'
+if max([1, 2, 3, 1, 2, 3]) <> 3: raise TestFailed, 'max([1, 2, 3, 1, 2, 3])'
+
+print 'open'
+print 'NB! This test creates a file named "@test" in the current directory.'
+fp = open('@test', 'w')
+fp.write('The quick brown fox jumps over the lazy dog')
+fp.write('.\n')
+fp.write('Dear John\n')
+fp.write('XXX'*100)
+fp.write('YYY'*100)
+fp.close()
+del fp
+fp = open('@test', 'r')
+if fp.readline() <> 'The quick brown fox jumps over the lazy dog.\n':
+       raise TestFailed, 'readline()'
+if fp.readline(4) <> 'Dear': raise TestFailed, 'readline(4) # short'
+if fp.readline(100) <> ' John\n': raise TestFailed, 'readline(100)'
+if fp.read(300) <> 'XXX'*100: raise TestFailed, 'read(300)'
+if fp.read(1000) <> 'YYY'*100: raise TestFailed, 'read(1000) # truncate'
+fp.close()
+del fp
+
+print 'range'
+if range(3) <> [0, 1, 2]: raise TestFailed, 'range(3)'
+if range(1, 5) <> [1, 2, 3, 4]: raise TestFailed, 'range(1, 5)'
+if range(0) <> []: raise TestFailed, 'range(0)'
+if range(-3) <> []: raise TestFailed, 'range(-3)'
+if range(1, 10, 3) <> [1, 4, 7]: raise TestFailed, 'range(1, 10, 3)'
+if range(5, -5, -3) <> [5, 2, -1, -4]: raise TestFailed, 'range(5, -5, -3)'
+
+print 'raw_input'
+savestdin = sys.stdin
+try:
+       sys.stdin = open('@test', 'r')
+       if raw_input() <> 'The quick brown fox jumps over the lazy dog.':
+               raise TestFailed, 'raw_input()'
+       if raw_input('testing\n') <> 'Dear John':
+               raise TestFailed, 'raw_input(\'testing\\n\')'
+finally:
+       sys.stdin = savestdin
+
+print 'reload'
+import string
+reload(string)
+
+print 'type'
+if type('') <> type('123') or type('') = type(()):
+       raise TestFailed, 'type()'
+
+
+print 'Passed all tests.'
+
+try:
+       import mac
+       unlink = mac.unlink
+except NameError:
+       try:
+               import posix
+               unlink = posix.unlink
+       except NameError:
+               pass
+
+unlink('@test')
+print 'Unlinked @test'
diff --git a/Mac/Lib/maccache.py b/Mac/Lib/maccache.py
new file mode 100644 (file)
index 0000000..dc6502b
--- /dev/null
@@ -0,0 +1,61 @@
+# Module 'maccache'
+#
+# Maintain a cache of listdir(), isdir(), isfile() or exists() outcomes.
+
+import mac
+import macpath
+
+
+# The cache.
+# Keys are absolute pathnames;
+# values are 0 (nothing), 1 (file) or [...] (dir).
+#
+cache = {}
+
+
+# Current working directory.
+#
+cwd = mac.getcwd()
+
+
+# Constants.
+#
+NONE = 0
+FILE = 1
+LISTTYPE = type([])
+
+def _stat(name):
+       name = macpath.cat(cwd, name)
+       if cache.has_key(name):
+               return cache[name]
+       if macpath.isfile(name):
+               cache[name] = FILE
+               return FILE
+       try:
+               list = mac.listdir(name)
+       except:
+               cache[name] = NONE
+               return NONE
+       cache[name] = list
+       if name[-1:] = ':': cache[name[:-1]] = list
+       else: cache[name+':'] = list
+       return list
+
+def isdir(name):
+       st = _stat(name)
+       return type(st) = LISTTYPE
+
+def isfile(name):
+       st = _stat(name)
+       return st = FILE
+
+def exists(name):
+       st = _stat(name)
+       return st <> NONE
+
+def listdir(name):
+       st = _stat(name)
+       if type(st) = LISTTYPE:
+               return st
+       else:
+               raise RuntimeError, 'list non-directory'