aboutsummaryrefslogtreecommitdiff
path: root/shar/python-0.9.1-15-21.shar
diff options
context:
space:
mode:
Diffstat (limited to 'shar/python-0.9.1-15-21.shar')
-rw-r--r--shar/python-0.9.1-15-21.shar2539
1 files changed, 2539 insertions, 0 deletions
diff --git a/shar/python-0.9.1-15-21.shar b/shar/python-0.9.1-15-21.shar
new file mode 100644
index 0000000..3cc3c78
--- /dev/null
+++ b/shar/python-0.9.1-15-21.shar
@@ -0,0 +1,2539 @@
+: This is a shell archive.
+: Extract with 'sh this_file'.
+:
+: Extract part 01 first since it makes all directories
+echo 'Start of pack.out, part 15 out of 21:'
+if test -s 'demo/sgi/gl/kites.py'
+then echo '*** I will not over-write existing file demo/sgi/gl/kites.py'
+else
+echo 'x - demo/sgi/gl/kites.py'
+sed 's/^X//' > 'demo/sgi/gl/kites.py' << 'EOF'
+X#! /ufs/guido/bin/sgi/python
+X
+X# *** This only works correctly on a 24 bit-plane machine. ***
+X#
+X# A simple Python program that tests the some parts of the
+X# GL library. It shows the speed that can be obtained when
+X# doing simple graphics.
+X#
+X# The bottleneck in this program is NOT Python but the graphics
+X# engine; i.e Python can feed the graphics pipeline fast enough
+X# on the 4D/25G.
+X#
+X# This program show 3 kites flying around the screen. It uses
+X#
+X# * bgnpolygon, endpolygon
+X# * v3, n3
+X# * lmdef, lmbind
+X#
+X# Usage :
+X#
+X# ESC -> exit program
+X# MOUSE3 -> freeze toggle
+X# MOUSE2 -> one step (use this in freeze state)
+X
+Xfrom GL import *
+Xfrom gl import *
+Ximport DEVICE
+Xfrom math import *
+X
+X#
+X# viewobj : sets the rotation, translation and scaling
+X# set appropiate material, call drawobject()
+X#
+Xdef viewobj (r, s, t, mat) :
+X pushmatrix()
+X rot (r * 10.0, 'X')
+X rot (r * 10.0, 'Y')
+X rot (r * 10.0, 'Z')
+X scale (s[0], s[1], s[2])
+X translate (t[0], t[1], t[2])
+X lmbind(MATERIAL, mat)
+X drawobject()
+X popmatrix()
+X
+X#
+X# makeobj : the contructor of the object
+X#
+Xdef mkobj () :
+X v0 = (-5.0 ,0.0, 0.0)
+X v1 = (0.0 ,5.0, 0.0)
+X v2 = (5.0 ,0.0, 0.0)
+X v3 = (0.0 ,2.0, 0.0)
+X n0 = (sqrt(2.0)/2.0, sqrt(2.0)/2.0, 0.0)
+X vn = ((v0, n0), (v1, n0), (v2, n0), (v3, n0))
+X #
+X return vn
+X
+X#
+X# the object itself as an array of vertices and normals
+X#
+Xkite = mkobj ()
+X
+X#
+X# drawobject : draw a triangle. with bgnpolygon
+X#
+Xdef drawobject () :
+X #
+X bgnpolygon()
+X vnarray (kite)
+X endpolygon()
+X
+X#
+X# identity matrix
+X#
+Xidmat=[1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
+X
+X#
+X# the rgb-value of light-blue
+X#
+XLightBlue = (43,169,255)
+X
+X#
+X# the different materials.
+X#
+Xm1=[SPECULAR,0.0,0.0,0.6,DIFFUSE,0.0,0.0,0.8,SHININESS,20.0,LMNULL]
+Xm2=[SPECULAR,0.8,0.0,0.1,DIFFUSE,0.8,0.0,0.3,SHININESS,120.0,LMNULL]
+Xm3=[SPECULAR,0.0,1.0,0.0,DIFFUSE,0.0,0.6,0.0,SHININESS,120.0,LMNULL]
+X
+X#
+X# lightsources
+X#
+Xlight1 = [LCOLOR,1.0,1.0,1.0,POSITION,15.0,15.0,0.0,1.0,LMNULL]
+Xlight2 = [LCOLOR,1.0,1.0,1.0,POSITION,-15.0,15.0,0.0,1.0,LMNULL]
+X
+X#
+X# the lightmodel
+X#
+Xmodel = [AMBIENT,0.2,0.2,0.2,LMNULL]
+X
+X#
+X# initgl : opens the window, configures the pipeline to 2buf and zbuf,
+X# sets the viewing, defines and binds the materials
+X#
+Xdef initgl () :
+X #
+X # open window
+X #
+X foreground ()
+X keepaspect (1, 1)
+X prefposition (100, 500, 100, 500)
+X w = winopen ('PYTHON lights')
+X keepaspect (1, 1)
+X winconstraints()
+X #
+X # configure pipeline (zbuf, 2buf, GOURAUD and RGBmode)
+X #
+X zbuffer (1)
+X doublebuffer ()
+X shademodel (GOURAUD)
+X RGBmode ()
+X gconfig ()
+X #
+X # define and bind materials (set perspective BEFORE loadmat !)
+X #
+X mmode(MVIEWING)
+X perspective (900, 1.0, 1.0, 20.0)
+X loadmatrix(idmat)
+X lmdef(DEFMATERIAL, 1, m1)
+X lmdef(DEFMATERIAL, 2, m2)
+X lmdef(DEFMATERIAL, 3, m3)
+X lmdef(DEFLIGHT, 1, light1)
+X lmdef(DEFLIGHT, 2, light2)
+X lmdef(DEFLMODEL, 1, model)
+X lmbind(LIGHT0,1)
+X lmbind(LIGHT1,2)
+X lmbind(LMODEL,1)
+X #
+X # set viewing
+X #
+X lookat (0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0)
+X #
+X # ask for the REDRAW and ESCKEY events
+X #
+X qdevice(DEVICE.MOUSE3)
+X qdevice(DEVICE.MOUSE2)
+X qdevice(DEVICE.REDRAW)
+X qdevice(DEVICE.ESCKEY)
+X
+X#
+X# GoForIT : use 2buf to redraw the object 2n times. index i is used as
+X# the (smoothly changing) rotation angle
+X#
+Xdef GoForIt(i) :
+X freeze = 1
+X while 1 :
+X if freeze <> 0 :
+X i = i + 1
+X #
+X # clear z-buffer and clear background to light-blue
+X #
+X zclear()
+X c3i (LightBlue)
+X clear()
+X #
+X # draw the 3 traiangles scaled above each other.
+X #
+X viewobj(float(i),[1.0,1.0,1.0],[1.0,1.0,1.0],1)
+X viewobj(float(i),[0.75,0.75,0.75],[0.0,2.0,2.0],2)
+X viewobj(float(i),[0.5,0.5,0.5],[0.0,4.0,4.0],3)
+X #
+X swapbuffers()
+X #
+X if qtest() <> 0 :
+X dev, val = qread()
+X if dev = DEVICE.ESCKEY :
+X break
+X elif dev = DEVICE.REDRAW :
+X reshapeviewport ()
+X elif dev = DEVICE.MOUSE3 and val <> 0 :
+X freeze = 1 - freeze
+X elif dev = DEVICE.MOUSE2 and val <> 0 :
+X i = i + 1
+X
+X
+X# the main program
+X#
+Xdef main () :
+X initgl ()
+X GoForIt (0)
+X
+X#
+X# exec main
+X#
+Xmain ()
+EOF
+chmod +x 'demo/sgi/gl/kites.py'
+fi
+if test -s 'demo/sgi/gl_panel/nurbs/nurbs.s'
+then echo '*** I will not over-write existing file demo/sgi/gl_panel/nurbs/nurbs.s'
+else
+echo 'x - demo/sgi/gl_panel/nurbs/nurbs.s'
+sed 's/^X//' > 'demo/sgi/gl_panel/nurbs/nurbs.s' << 'EOF'
+X;;; This file was automatically generated by the panel editor.
+X;;; If you read it into gnu emacs, it will automagically format itself.
+X
+X(panel (prop help creator:user-panel-help)
+X(prop user-panel #t)
+X(label "NURB controls")
+X(x 815)
+X(y 22)
+X(al (pnl_toggle_button (name "trim")
+X(prop help creator:user-act-help)
+X(label "trim on/off")
+X(x 4)
+X(y 4.5)
+X(w 0.45)
+X(h 0.4)
+X(downfunc move-then-resize)
+X)
+X(pnl_toggle_button (name "motion")
+X(prop help creator:user-act-help)
+X(label "motion on/off")
+X(y 1)
+X(downfunc move-then-resize)
+X)
+X(pnl_toggle_button (name "xyzaxis")
+X(prop help creator:user-act-help)
+X(label "xyz-axis")
+X(y 3)
+X(downfunc move-then-resize)
+X)
+X(pnl_toggle_button (name "trimpnts")
+X(prop help creator:user-act-help)
+X(label "trimming pnts")
+X(y 3.5)
+X(downfunc move-then-resize)
+X)
+X(pnl_toggle_button (name "cntlpnts")
+X(prop help creator:user-act-help)
+X(label "control pnts")
+X(y 4)
+X(downfunc move-then-resize)
+X)
+X(pnl_toggle_button (name "nurb")
+X(prop help creator:user-act-help)
+X(label "nurb")
+X(y 4.5)
+X(val 1)
+X(downfunc move-then-resize)
+X)
+X(pnl_button (name "quit")
+X(prop help creator:user-act-help)
+X(label "quit")
+X(x 4)
+X(y 1)
+X(labeltype 1)
+X(downfunc move-then-resize)
+X)
+X(pnl_label (prop help creator:user-act-help)
+X(label "TRIMMING")
+X(x 4)
+X(y 5)
+X(downfunc move-then-resize)
+X)
+X(pnl_label (prop help creator:user-act-help)
+X(label "MOTION")
+X(y 1.5)
+X(downfunc move-then-resize)
+X)
+X(pnl_label (prop help creator:user-act-help)
+X(label "VISIBILITY")
+X(y 5)
+X(downfunc move-then-resize)
+X)
+X)
+X)
+X;;; Local Variables:
+X;;; mode: scheme
+X;;; eval: (save-excursion (goto-char (point-min)) (kill-line 3))
+X;;; eval: (save-excursion (goto-char (point-min)) (replace-regexp "[ \n]*)" ")"))
+X;;; eval: (indent-region (point-min) (point-max) nil)
+X;;; eval: (progn (kill-line -3) (delete-backward-char 1) (save-buffer))
+X;;; End:
+EOF
+fi
+if test -s 'lib/Sliders.py'
+then echo '*** I will not over-write existing file lib/Sliders.py'
+else
+echo 'x - lib/Sliders.py'
+sed 's/^X//' > 'lib/Sliders.py' << 'EOF'
+X# Module 'Sliders'
+X
+X
+Ximport stdwin
+Xfrom stdwinevents import *
+Ximport rect
+Xfrom Buttons import *
+Xfrom HVSplit import HSplit
+X
+X
+X# Field indices in event detail
+X#
+X_HV = 0
+X_CLICKS = 1
+X_BUTTON = 2
+X_MASK = 3
+X
+X
+X# DragSlider is the simplest possible slider.
+X# It looks like a button but dragging the mouse left or right
+X# changes the controlled value.
+X# It does not support any of the triggers or hooks defined by Buttons,
+X# but defines its own setval_trigger and setval_hook.
+X#
+Xclass DragSliderReactivity() = BaseReactivity():
+X #
+X def mouse_down(self, detail):
+X h, v = hv = detail[_HV]
+X if self.enabled and self.mousetest(hv):
+X self.anchor = h
+X self.oldval = self.val
+X self.active = 1
+X #
+X def mouse_move(self, detail):
+X if self.active:
+X h, v = detail[_HV]
+X self.setval(self.oldval + (h - self.anchor))
+X #
+X def mouse_up(self, detail):
+X if self.active:
+X h, v = detail[_HV]
+X self.setval(self.oldval + (h - self.anchor))
+X self.active = 0
+X #
+X
+Xclass DragSliderAppearance() = ButtonAppearance():
+X #
+X # INVARIANTS maintained by the setval method:
+X #
+X # self.min <= self.val <= self.max
+X # self.text = self.pretext + `self.val` + self.postext
+X #
+X # (Notice that unlike Python ranges, the end point belongs
+X # to the range.)
+X #
+X def init_appearance(self):
+X ButtonAppearance.init_appearance(self)
+X self.min = 0
+X self.val = 0
+X self.max = 100
+X self.hook = 0
+X self.pretext = self.postext = ''
+X self.recalctext()
+X #
+X # The 'get*' and 'set*' methods belong to the generic slider interface
+X #
+X def getval(self): return self.val
+X #
+X def sethook(self, hook):
+X self.hook = hook
+X #
+X def setminvalmax(self, (min, val, max)):
+X self.min = min
+X self.max = max
+X self.setval(val)
+X #
+X def settexts(self, (pretext, postext)):
+X self.pretext = pretext
+X self.postext = postext
+X self.recalctext()
+X #
+X def setval(self, val):
+X val = min(self.max, max(self.min, val))
+X if val <> self.val:
+X self.val = val
+X self.recalctext()
+X self.trigger()
+X #
+X def trigger(self):
+X if self.hook:
+X self.hook(self)
+X #
+X def recalctext(self):
+X self.settext(self.pretext + `self.val` + self.postext)
+X #
+X
+Xclass DragSlider() = DragSliderReactivity(), DragSliderAppearance(), Define():
+X def definetext(self, (parent, text)):
+X raise RuntimeError, 'DragSlider.definetext() not supported'
+X
+X
+X# Auxiliary class for PushButton incorporated in ComplexSlider
+X#
+Xclass _StepButton() = PushButton():
+X def define(self, parent):
+X self = PushButton.define(self, parent)
+X self.step = 0
+X return self
+X def setstep(self, step):
+X self.step = step
+X def definetextstep(self, (parent, text, step)):
+X self = self.definetext(parent, text)
+X self.setstep(step)
+X return self
+X def init_reactivity(self):
+X PushButton.init_reactivity(self)
+X self.parent.need_timer(self)
+X def step_trigger(self):
+X self.parent.setval(self.parent.getval() + self.step)
+X def down_trigger(self):
+X self.step_trigger()
+X self.parent.settimer(5)
+X def timer(self):
+X if self.hilited:
+X self.step_trigger()
+X if self.active:
+X self.parent.settimer(1)
+X
+X
+X# A complex slider is an HSplit initialized to three buttons:
+X# one to step down, a dragslider, and one to step up.
+X#
+Xclass ComplexSlider() = HSplit():
+X #
+X # Override Slider define() method
+X #
+X def define(self, parent):
+X self = self.create(parent) # HSplit
+X #
+X self.downbutton = _StepButton().definetextstep(self, '-', -1)
+X self.dragbutton = DragSlider().define(self)
+X self.upbutton = _StepButton().definetextstep(self, '+', 1)
+X #
+X return self
+X #
+X # Override HSplit methods
+X #
+X def minsize(self, m):
+X w1, h1 = self.downbutton.minsize(m)
+X w2, h2 = self.dragbutton.minsize(m)
+X w3, h3 = self.upbutton.minsize(m)
+X height = max(h1, h2, h3)
+X w1 = max(w1, height)
+X w3 = max(w3, height)
+X return w1+w2+w3, height
+X #
+X def setbounds(self, bounds):
+X (left, top), (right, bottom) = self.bounds = bounds
+X size = bottom - top
+X self.downbutton.setbounds((left, top), (left+size, bottom))
+X self.dragbutton.setbounds((left+size, top), \
+X (right-size, bottom))
+X self.upbutton.setbounds((right-size, top), (right, bottom))
+X #
+X # Pass other Slider methods on to dragbutton
+X #
+X def getval(self): return self.dragbutton.getval()
+X def sethook(self, hook): self.dragbutton.sethook(hook)
+X def setminvalmax(self, args): self.dragbutton.setminvalmax(args)
+X def settexts(self, args): self.dragbutton.settexts(args)
+X def setval(self, val): self.dragbutton.setval(val)
+X def enable(self, flag):
+X self.downbutton.enable(flag)
+X self.dragbutton.enable(flag)
+X self.upbutton.enable(flag)
+EOF
+fi
+if test -s 'lib/clock.py'
+then echo '*** I will not over-write existing file lib/clock.py'
+else
+echo 'x - lib/clock.py'
+sed 's/^X//' > 'lib/clock.py' << 'EOF'
+X# 'klok' -- A simple alarm clock
+X
+X# The alarm can be set at 5 minute intervals on a 12 hour basis.
+X# It is controlled with the mouse:
+X# - Click and drag around the circle to set the alarm.
+X# - Click far outside the circle to clear the alarm.
+X# - Click near the center to set the alarm at the last time set.
+X# The alarm time is indicated by a small triangle just outside the circle,
+X# and also by a digital time at the bottom.
+X# The indicators disappear when the alarm is not set.
+X# When the alarm goes off, it beeps every minute for five minutes,
+X# and the clock turns into inverse video.
+X# Click or activate the window to turn the ringing off.
+X
+Ximport stdwin
+Xfrom stdwinevents import WE_MOUSE_DOWN, WE_MOUSE_MOVE, WE_MOUSE_UP, \
+X WE_TIMER, WE_DRAW, WE_SIZE, WE_CLOSE, WE_ACTIVATE
+Ximport time
+Xfrom math import sin, cos, atan2, pi, sqrt
+X
+XDEFWIDTH, DEFHEIGHT = 200, 200
+X
+Xmouse_events = (WE_MOUSE_DOWN, WE_MOUSE_MOVE, WE_MOUSE_UP)
+Xorigin = 0, 0
+Xfaraway = 2000, 2000
+Xeverywhere = origin, faraway
+X
+Xclass struct(): pass # A class to declare featureless objects
+X
+XG = struct() # Global variables (most set in setdimensions())
+XG.tzdiff = 5*3600 # THINK computes UCT from local time assuming EST!
+X
+XA = struct() # Globals used by the alarm
+XA.set = 1 # True when alarm is set
+XA.time = 11*60 + 40 # Time when alarm must go off
+XA.ring = 0 # True when alarm is ringing
+X
+Xdef main():
+X try:
+X realmain()
+X except KeyboardInterrupt:
+X print 'KeyboardInterrupt'
+X finally:
+X G.w = 0
+X
+Xdef realmain():
+X setdimensions(DEFWIDTH, DEFHEIGHT)
+X stdwin.setdefwinsize(G.farcorner)
+X G.w = stdwin.open('klok')
+X settimer()
+X while 1:
+X type, window, detail = stdwin.getevent()
+X if type = WE_DRAW:
+X drawproc(detail)
+X elif type = WE_TIMER:
+X settimer()
+X drawproc(everywhere)
+X elif type in mouse_events:
+X mouseclick(type, detail)
+X elif type = WE_ACTIVATE:
+X if A.ring:
+X # Turn the ringing off
+X A.ring = 0
+X G.w.begindrawing().invert(G.mainarea)
+X elif type = WE_SIZE:
+X G.w.change(everywhere)
+X width, height = G.w.getwinsize()
+X height = height - stdwin.lineheight()
+X setdimensions(width, height)
+X elif type = WE_CLOSE:
+X break
+X
+Xdef setdimensions(width, height):
+X if width < height: size = width
+X else: size = height
+X halfwidth = width/2
+X halfheight = height/2
+X G.center = halfwidth, halfheight
+X G.radius = size*45/100
+X G.width = width
+X G.height = height
+X G.corner = width, height
+X G.mainarea = origin, G.corner
+X G.lineheight = stdwin.lineheight()
+X G.farcorner = width, height + G.lineheight
+X G.statusarea = (0, height), G.farcorner
+X G.fullarea = origin, G.farcorner
+X
+Xdef settimer():
+X now = getlocaltime()
+X G.times = calctime(now)
+X delay = 61 - now % 60
+X G.w.settimer(10 * delay)
+X minutes = (now/60) % 720
+X if A.ring:
+X # Is it time to stop the alarm ringing?
+X since = (minutes - A.time + 720) % 720
+X if since >= 5:
+X # Stop it now
+X A.ring = 0
+X else:
+X # Ring again, once every minute
+X stdwin.fleep()
+X elif A.set and minutes = A.time:
+X # Start the alarm ringing
+X A.ring = 1
+X stdwin.fleep()
+X
+Xdef drawproc(area):
+X hours, minutes, seconds = G.times
+X d = G.w.begindrawing()
+X d.cliprect(area)
+X d.erase(everywhere)
+X d.circle(G.center, G.radius)
+X d.line(G.center, calcpoint(hours*30 + minutes/2, 0.6))
+X d.line(G.center, calcpoint(minutes*6, 1.0))
+X str = dd(hours) + ':' + dd(minutes)
+X p = (G.width - d.textwidth(str))/2, G.height * 3 / 4
+X d.text(p, str)
+X if A.set:
+X drawalarm(d)
+X drawalarmtime(d)
+X if A.ring:
+X d.invert(G.mainarea)
+X
+Xdef mouseclick(type, detail):
+X d = G.w.begindrawing()
+X if A.ring:
+X # First turn the ringing off
+X A.ring = 0
+X d.invert(G.mainarea)
+X h, v = detail[0]
+X ch, cv = G.center
+X x, y = h-ch, cv-v
+X dist = sqrt(x*x + y*y) / float(G.radius)
+X if dist > 1.2:
+X if A.set:
+X drawalarm(d)
+X erasealarmtime(d)
+X A.set = 0
+X elif dist < 0.8:
+X if not A.set:
+X A.set = 1
+X drawalarm(d)
+X drawalarmtime(d)
+X else:
+X # Convert to half-degrees (range 0..720)
+X alpha = atan2(y, x)
+X hdeg = alpha*360.0/pi
+X hdeg = 180.0 - hdeg
+X hdeg = (hdeg + 720.0) % 720.0
+X atime = 5*int(hdeg/5.0 + 0.5)
+X if atime <> A.time or not A.set:
+X if A.set:
+X drawalarm(d)
+X erasealarmtime(d)
+X A.set = 1
+X A.time = atime
+X drawalarm(d)
+X drawalarmtime(d)
+X
+Xdef drawalarm(d):
+X p1 = calcpoint(float(A.time)/2.0, 1.02)
+X p2 = calcpoint(float(A.time)/2.0 - 4.0, 1.1)
+X p3 = calcpoint(float(A.time)/2.0 + 4.0, 1.1)
+X d.xorline(p1, p2)
+X d.xorline(p2, p3)
+X d.xorline(p3, p1)
+X
+Xdef erasealarmtime(d):
+X d.erase(G.statusarea)
+X
+Xdef drawalarmtime(d):
+X # A.time is in the range 0..720 with origin at 12 o'clock
+X # Convert to hours (0..12) and minutes (12*(0..60))
+X hh = A.time/60
+X mm = A.time%60
+X str = 'Alarm@' + dd(hh) + ':' + dd(mm)
+X p1 = (G.width - d.textwidth(str))/2, G.height
+X d.text(p1, str)
+X
+Xdef calctime(now):
+X seconds = now % 60
+X minutes = (now/60) % 60
+X hours = (now/3600) % 12
+X return hours, minutes, seconds
+X
+Xdef calcpoint(degrees, size):
+X alpha = pi/2.0 - float(degrees) * pi/180.0
+X x, y = cos(alpha), sin(alpha)
+X h, v = G.center
+X r = float(G.radius)
+X return h + int(x*size*r), v - int(y*size*r)
+X
+Xdef dd(n):
+X s = `n`
+X return '0'*(2-len(s)) + s
+X
+Xdef getlocaltime():
+X return time.time() - G.tzdiff
+X
+X#main()
+EOF
+fi
+if test -s 'lib/dircmp.py'
+then echo '*** I will not over-write existing file lib/dircmp.py'
+else
+echo 'x - lib/dircmp.py'
+sed 's/^X//' > 'lib/dircmp.py' << 'EOF'
+X# Module 'dirmp'
+X#
+X# Defines a class to build directory diff tools on.
+X
+Ximport posix
+X
+Ximport path
+X
+Ximport dircache
+Ximport cmpcache
+Ximport statcache
+Xfrom stat import *
+X
+X# Directory comparison class.
+X#
+Xclass dircmp():
+X #
+X def new(dd, (a, b)): # Initialize
+X dd.a = a
+X dd.b = b
+X # Properties that caller may change before callingdd. run():
+X dd.hide = ['.', '..'] # Names never to be shown
+X dd.ignore = ['RCS', 'tags'] # Names ignored in comparison
+X #
+X return dd
+X #
+X def run(dd): # Compare everything except common subdirectories
+X dd.a_list = filter(dircache.listdir(dd.a), dd.hide)
+X dd.b_list = filter(dircache.listdir(dd.b), dd.hide)
+X dd.a_list.sort()
+X dd.b_list.sort()
+X dd.phase1()
+X dd.phase2()
+X dd.phase3()
+X #
+X def phase1(dd): # Compute common names
+X dd.a_only = []
+X dd.common = []
+X for x in dd.a_list:
+X if x in dd.b_list:
+X dd.common.append(x)
+X else:
+X dd.a_only.append(x)
+X #
+X dd.b_only = []
+X for x in dd.b_list:
+X if x not in dd.common:
+X dd.b_only.append(x)
+X #
+X def phase2(dd): # Distinguish files, directories, funnies
+X dd.common_dirs = []
+X dd.common_files = []
+X dd.common_funny = []
+X #
+X for x in dd.common:
+X a_path = path.cat(dd.a, x)
+X b_path = path.cat(dd.b, x)
+X #
+X ok = 1
+X try:
+X a_stat = statcache.stat(a_path)
+X except posix.error, why:
+X # print 'Can\'t stat', a_path, ':', why[1]
+X ok = 0
+X try:
+X b_stat = statcache.stat(b_path)
+X except posix.error, why:
+X # print 'Can\'t stat', b_path, ':', why[1]
+X ok = 0
+X #
+X if ok:
+X a_type = S_IFMT(a_stat[ST_MODE])
+X b_type = S_IFMT(b_stat[ST_MODE])
+X if a_type <> b_type:
+X dd.common_funny.append(x)
+X elif S_ISDIR(a_type):
+X dd.common_dirs.append(x)
+X elif S_ISREG(a_type):
+X dd.common_files.append(x)
+X else:
+X dd.common_funny.append(x)
+X else:
+X dd.common_funny.append(x)
+X #
+X def phase3(dd): # Find out differences between common files
+X xx = cmpfiles(dd.a, dd.b, dd.common_files)
+X dd.same_files, dd.diff_files, dd.funny_files = xx
+X #
+X def phase4(dd): # Find out differences between common subdirectories
+X # A new dircmp object is created for each common subdirectory,
+X # these are stored in a dictionary indexed by filename.
+X # The hide and ignore properties are inherited from the parent
+X dd.subdirs = {}
+X for x in dd.common_dirs:
+X a_x = path.cat(dd.a, x)
+X b_x = path.cat(dd.b, x)
+X dd.subdirs[x] = newdd = dircmp().new(a_x, b_x)
+X newdd.hide = dd.hide
+X newdd.ignore = dd.ignore
+X newdd.run()
+X #
+X def phase4_closure(dd): # Recursively call phase4() on subdirectories
+X dd.phase4()
+X for x in dd.subdirs.keys():
+X dd.subdirs[x].phase4_closure()
+X #
+X def report(dd): # Print a report on the differences between a and b
+X # Assume that phases 1 to 3 have been executed
+X # Output format is purposely lousy
+X print 'diff', dd.a, dd.b
+X if dd.a_only:
+X print 'Only in', dd.a, ':', dd.a_only
+X if dd.b_only:
+X print 'Only in', dd.b, ':', dd.b_only
+X if dd.same_files:
+X print 'Identical files :', dd.same_files
+X if dd.diff_files:
+X print 'Differing files :', dd.diff_files
+X if dd.funny_files:
+X print 'Trouble with common files :', dd.funny_files
+X if dd.common_dirs:
+X print 'Common subdirectories :', dd.common_dirs
+X if dd.common_funny:
+X print 'Common funny cases :', dd.common_funny
+X #
+X def report_closure(dd): # Print reports on dd and on subdirs
+X # If phase 4 hasn't been done, no subdir reports are printed
+X dd.report()
+X try:
+X x = dd.subdirs
+X except NameError:
+X return # No subdirectories computed
+X for x in dd.subdirs.keys():
+X print
+X dd.subdirs[x].report_closure()
+X #
+X def report_phase4_closure(dd): # Report and do phase 4 recursively
+X dd.report()
+X dd.phase4()
+X for x in dd.subdirs.keys():
+X print
+X dd.subdirs[x].report_phase4_closure()
+X
+X
+X# Compare common files in two directories.
+X# Return:
+X# - files that compare equal
+X# - files that compare different
+X# - funny cases (can't stat etc.)
+X#
+Xdef cmpfiles(a, b, common):
+X res = ([], [], [])
+X for x in common:
+X res[cmp(path.cat(a, x), path.cat(b, x))].append(x)
+X return res
+X
+X
+X# Compare two files.
+X# Return:
+X# 0 for equal
+X# 1 for different
+X# 2 for funny cases (can't stat, etc.)
+X#
+Xdef cmp(a, b):
+X try:
+X if cmpcache.cmp(a, b): return 0
+X return 1
+X except posix.error:
+X return 2
+X
+X
+X# Remove a list item.
+X# NB: This modifies the list argument.
+X#
+Xdef remove(list, item):
+X for i in range(len(list)):
+X if list[i] = item:
+X del list[i]
+X break
+X
+X
+X# Return a copy with items that occur in skip removed.
+X#
+Xdef filter(list, skip):
+X result = []
+X for item in list:
+X if item not in skip: result.append(item)
+X return result
+X
+X
+X# Demonstration and testing.
+X#
+Xdef demo():
+X import sys
+X import getopt
+X options, args = getopt.getopt(sys.argv[1:], 'r')
+X if len(args) <> 2: raise getopt.error, 'need exactly two args'
+X dd = dircmp().new(args[0], args[1])
+X dd.run()
+X if ('-r', '') in options:
+X dd.report_phase4_closure()
+X else:
+X dd.report()
+X
+X# demo()
+EOF
+fi
+if test -s 'lib/dis.py'
+then echo '*** I will not over-write existing file lib/dis.py'
+else
+echo 'x - lib/dis.py'
+sed 's/^X//' > 'lib/dis.py' << 'EOF'
+X# Disassembler
+X
+Ximport sys
+Ximport string
+X
+Xdef dis():
+X tb = sys.last_traceback
+X while tb.tb_next: tb = tb.tb_next
+X distb(tb)
+X
+Xdef distb(tb):
+X disassemble(tb.tb_frame.f_code, tb.tb_lasti)
+X
+Xdef disco(co):
+X disassemble(co, -1)
+X
+Xdef disassemble(co, lasti):
+X code = co.co_code
+X labels = findlabels(code)
+X n = len(code)
+X i = 0
+X while i < n:
+X c = code[i]
+X op = ord(c)
+X if op = SET_LINENO and i > 0: print # Extra blank line
+X if i = lasti: print '-->',
+X else: print ' ',
+X if i in labels: print '>>',
+X else: print ' ',
+X print string.rjust(`i`, 4),
+X print string.ljust(opname[op], 15),
+X i = i+1
+X if op >= HAVE_ARGUMENT:
+X oparg = ord(code[i]) + ord(code[i+1])*256
+X i = i+2
+X print string.rjust(`oparg`, 5),
+X if op in hasconst:
+X print '(' + `co.co_consts[oparg]` + ')',
+X elif op in hasname:
+X print '(' + co.co_names[oparg] + ')',
+X elif op in hasjrel:
+X print '(to ' + `i + oparg` + ')',
+X print
+X
+Xdef findlabels(code):
+X labels = []
+X n = len(code)
+X i = 0
+X while i < n:
+X c = code[i]
+X op = ord(c)
+X i = i+1
+X if op >= HAVE_ARGUMENT:
+X oparg = ord(code[i]) + ord(code[i+1])*256
+X i = i+2
+X label = -1
+X if op in hasjrel:
+X label = i+oparg
+X elif op in hasjabs:
+X label = oparg
+X if label >= 0:
+X if label not in labels:
+X labels.append(label)
+X return labels
+X
+Xhasconst = []
+Xhasname = []
+Xhasjrel = []
+Xhasjabs = []
+X
+Xopname = range(256)
+Xfor op in opname: opname[op] = '<' + `op` + '>'
+X
+Xdef def_op(name, op):
+X opname[op] = name
+X
+Xdef name_op(name, op):
+X opname[op] = name
+X hasname.append(op)
+X
+Xdef jrel_op(name, op):
+X opname[op] = name
+X hasjrel.append(op)
+X
+Xdef jabs_op(name, op):
+X opname[op] = name
+X hasjabs.append(op)
+X
+X# Instruction opcodes for compiled code
+X
+Xdef_op('STOP_CODE', 0)
+Xdef_op('POP_TOP', 1)
+Xdef_op('ROT_TWO', 2)
+Xdef_op('ROT_THREE', 3)
+Xdef_op('DUP_TOP', 4)
+X
+Xdef_op('UNARY_POSITIVE', 10)
+Xdef_op('UNARY_NEGATIVE', 11)
+Xdef_op('UNARY_NOT', 12)
+Xdef_op('UNARY_CONVERT', 13)
+Xdef_op('UNARY_CALL', 14)
+X
+Xdef_op('BINARY_MULTIPLY', 20)
+Xdef_op('BINARY_DIVIDE', 21)
+Xdef_op('BINARY_MODULO', 22)
+Xdef_op('BINARY_ADD', 23)
+Xdef_op('BINARY_SUBTRACT', 24)
+Xdef_op('BINARY_SUBSCR', 25)
+Xdef_op('BINARY_CALL', 26)
+X
+Xdef_op('SLICE+0', 30)
+Xdef_op('SLICE+1', 31)
+Xdef_op('SLICE+2', 32)
+Xdef_op('SLICE+3', 33)
+X
+Xdef_op('STORE_SLICE+0', 40)
+Xdef_op('STORE_SLICE+1', 41)
+Xdef_op('STORE_SLICE+2', 42)
+Xdef_op('STORE_SLICE+3', 43)
+X
+Xdef_op('DELETE_SLICE+0', 50)
+Xdef_op('DELETE_SLICE+1', 51)
+Xdef_op('DELETE_SLICE+2', 52)
+Xdef_op('DELETE_SLICE+3', 53)
+X
+Xdef_op('STORE_SUBSCR', 60)
+Xdef_op('DELETE_SUBSCR', 61)
+X
+Xdef_op('PRINT_EXPR', 70)
+Xdef_op('PRINT_ITEM', 71)
+Xdef_op('PRINT_NEWLINE', 72)
+X
+Xdef_op('BREAK_LOOP', 80)
+Xdef_op('RAISE_EXCEPTION', 81)
+Xdef_op('LOAD_LOCALS', 82)
+Xdef_op('RETURN_VALUE', 83)
+Xdef_op('REQUIRE_ARGS', 84)
+Xdef_op('REFUSE_ARGS', 85)
+Xdef_op('BUILD_FUNCTION', 86)
+Xdef_op('POP_BLOCK', 87)
+Xdef_op('END_FINALLY', 88)
+Xdef_op('BUILD_CLASS', 89)
+X
+XHAVE_ARGUMENT = 90 # Opcodes from here have an argument:
+X
+Xname_op('STORE_NAME', 90) # Index in name list
+Xname_op('DELETE_NAME', 91) # ""
+Xdef_op('UNPACK_TUPLE', 92) # Number of tuple items
+Xdef_op('UNPACK_LIST', 93) # Number of list items
+X# unused: 94
+Xname_op('STORE_ATTR', 95) # Index in name list
+Xname_op('DELETE_ATTR', 96) # ""
+X
+Xdef_op('LOAD_CONST', 100) # Index in const list
+Xhasconst.append(100)
+Xname_op('LOAD_NAME', 101) # Index in name list
+Xdef_op('BUILD_TUPLE', 102) # Number of tuple items
+Xdef_op('BUILD_LIST', 103) # Number of list items
+Xdef_op('BUILD_MAP', 104) # Always zero for now
+Xname_op('LOAD_ATTR', 105) # Index in name list
+Xdef_op('COMPARE_OP', 106) # Comparison operator
+Xname_op('IMPORT_NAME', 107) # Index in name list
+Xname_op('IMPORT_FROM', 108) # Index in name list
+X
+Xjrel_op('JUMP_FORWARD', 110) # Number of bytes to skip
+Xjrel_op('JUMP_IF_FALSE', 111) # ""
+Xjrel_op('JUMP_IF_TRUE', 112) # ""
+Xjabs_op('JUMP_ABSOLUTE', 113) # Target byte offset from beginning of code
+Xjrel_op('FOR_LOOP', 114) # Number of bytes to skip
+X
+Xjrel_op('SETUP_LOOP', 120) # Distance to target address
+Xjrel_op('SETUP_EXCEPT', 121) # ""
+Xjrel_op('SETUP_FINALLY', 122) # ""
+X
+Xdef_op('SET_LINENO', 127) # Current line number
+XSET_LINENO = 127
+EOF
+fi
+if test -s 'lib/lambda.py'
+then echo '*** I will not over-write existing file lib/lambda.py'
+else
+echo 'x - lib/lambda.py'
+sed 's/^X//' > 'lib/lambda.py' << 'EOF'
+X# A bit of Lambda Calculus illustrated in Python.
+X#
+X# This does not use Python's built-in 'eval' or 'exec' functions!
+X
+X
+X# Currying
+X#
+X# From a function with 2 args, f(x, y), and a value for the 1st arg,
+X# we can create a new function with one argument fx(y) = f(x, y).
+X# This is called "Currying" (after the idea's inventor, a Mr. Curry).
+X#
+X# To implement this we create a class member, of which fx is a method;
+X# f and x are stored as data attributes of the member.
+X
+Xclass _CurryClass():
+X def new(self, (f, x)):
+X self.f = f
+X self.x = x
+X return self
+X def fx(self, y):
+X return self.f(self.x, y)
+X
+Xdef CURRY(f, x):
+X # NB: f is not "simple": it has 2 arguments
+X return _CurryClass().new(f, x).fx
+X
+X
+X# Numbers in Lambda Calculus
+X#
+X# In the lambda calculus, natural numbers are represented by
+X# higher-order functions Ntimes(f, x) that yield f applied N
+X# times to x, e.g., Twice(f, x) = f(f(x)).
+X# As far as I understand, there is no difference in real lambda
+X# calculus between
+X# lambda f x : f(f(x))
+X# and
+X# lambda f : f o f # 'o' means function composition
+X# but in Python we have to write the first as Twice(f, x) and
+X# the second as twice(f).
+X
+Xdef Never(f, x): return x
+Xdef Once(f, x): return f(x)
+Xdef Twice(f, x): return f(f(x))
+Xdef Thrice(f, x): return f(f(f(x)))
+Xdef Fourfold(f, x): return f(f(f(f(x))))
+X# (etc.)
+X
+Xdef never(f): return CURRY(Never, f)
+Xdef once(f): return CURRY(Once, f)
+Xdef twice(f): return CURRY(Twice, f)
+Xdef thrice(f): return CURRY(Thrice, f)
+Xdef fourfold(f): return CURRY(Fourfold, f)
+X# (etc.)
+X
+X
+X# NB: actually 'ntimes' is less concrete than 'Ntimes', as
+X# 'ntimes' returns a function, while 'Ntimes' returns a value
+X# similar to what f(x) returns. 'Ntimes' can be derived
+X# from 'ntimes', as follows:
+X# def Ntimes(f, x): return ntimes(f)(x)
+X# but this doesn't help us since 'ntimes' can only be defined
+X# using Ntimes (or a trick like the one used by CURRY).
+X
+X
+X# Arithmetic in Lambda Calculus
+X#
+X# We can perform simple arithmetic on the un-curried versions, e.g.,
+X# Successor(Twice) = Thrice (2+1)
+X# Sum(Thrice, Twice) = Fivefold (3+2)
+X# Product(Thrice, Twice) = Sixfold (3*2)
+X# Power(Thrice, Twice) = Ninefold (3**2)
+X#
+X# First we define versions that need f and x arguments.
+X# They have funny argument forms so the final functions can
+X# use CURRY, which only works on functions of exactly 2 arguments.
+X
+Xdef SUCCESSOR(Ntimes, (f, x)): return f(Ntimes(f, x))
+Xdef SUCCESSOR(Ntimes, (f, x)): return Ntimes(f, f(x)) # Same effect
+Xdef SUM(Ntimes, (Mtimes, (f, x))): return Ntimes(f, Mtimes(f, x))
+Xdef PRODUCT(Ntimes, (Mtimes, (f, x))): return Ntimes(CURRY(Mtimes, f), x)
+Xdef POWER(Ntimes, (Mtimes, (f, x))):
+X return Mtimes(CURRY(CURRY, Ntimes), f)(x)
+X
+Xdef Successor(Ntimes): return CURRY(SUCCESSOR, Ntimes)
+Xdef Sum(Ntimes, Mtimes): return CURRY(CURRY(SUM, Ntimes), Mtimes)
+Xdef Product(Ntimes, Mtimes): return CURRY(CURRY(PRODUCT, Ntimes), Mtimes)
+Xdef Power(Ntimes, Mtimes): return CURRY(CURRY(POWER, Ntimes), Mtimes)
+X
+X
+X# Sorry, I don't have a clue on how to do subtraction or division...
+X
+X
+X# References
+X#
+X# All I know about lambda calculus is from Roger Penrose's
+X# The Emperor's New Mind, Chapter 2.
+X
+X
+X# P.S.: Here is a Lambda function in Python.
+X# It uses 'exec' and expects two strings to describe the arguments
+X# and the function expression. Example:
+X# lambda('x', 'x+1')
+X# defines the successor function.
+X
+Xdef lambda(args, expr):
+X if '\n' in args or '\n' in expr:
+X raise RuntimeError, 'lambda: no cheating!'
+X stmt = 'def func(' + args + '): return ' + expr + '\n'
+X print 'lambda:', stmt,
+X exec(stmt)
+X return func
+X
+X
+X# P.P.S.S.: Here is a way to construct Ntimes and ntimes directly.
+X# Example:
+X# GenericNtimes(4)
+X# is equivalent to Fourfold.
+X
+Xclass _GenericNtimesClass():
+X def new(self, n):
+X self.n = n
+X return self
+X def Ntimes(self, (f, x)):
+X n = self.n
+X while n > 0: x, n = f(x), n-1
+X return x
+X
+Xdef GenericNtimes(n):
+X return _GenericNtimesClass().new(n).Ntimes
+X
+X
+X# To construct any 'ntimes' function from the corresponding 'Ntimes',
+X# we use a trick as used by CURRY. For example,
+X# Ntimes2ntimes(Fourfold)
+X# yields a function equivalent to fourfold.
+X
+Xclass _Ntimes2ntimesClass():
+X def new(self, Ntimes):
+X self.Ntimes = Ntimes
+X return self
+X def ntimes(self, f):
+X return CURRY(self.Ntimes, f)
+X
+Xdef Ntimes2ntimes(Ntimes): return _Ntimes2ntimesClass().new(Ntimes).ntimes
+X
+X
+X# This allows us to construct generic 'ntimes' functions. Example:
+X# generic_ntimes(3)
+X# is the same as thrice.
+X
+Xdef generic_ntimes(n): return Ntimes2ntimes(GenericNtimes(n))
+EOF
+fi
+if test -s 'lib/tb.py'
+then echo '*** I will not over-write existing file lib/tb.py'
+else
+echo 'x - lib/tb.py'
+sed 's/^X//' > 'lib/tb.py' << 'EOF'
+X# Print tracebacks, with a dump of local variables.
+X# Also an interactive stack trace browser.
+X
+Ximport sys
+Xtry:
+X import mac
+X os = mac
+Xexcept NameError:
+X import posix
+X os = posix
+Xfrom stat import *
+Ximport string
+X
+Xdef br(): browser(sys.last_traceback)
+X
+Xdef tb(): printtb(sys.last_traceback)
+X
+Xdef browser(tb):
+X if not tb:
+X print 'No traceback.'
+X return
+X tblist = []
+X while tb:
+X tblist.append(tb)
+X tb = tb.tb_next
+X ptr = len(tblist)-1
+X tb = tblist[ptr]
+X while 1:
+X if tb <> tblist[ptr]:
+X tb = tblist[ptr]
+X print `ptr` + ':',
+X printtbheader(tb)
+X try:
+X line = raw_input('TB: ')
+X except KeyboardInterrupt:
+X print '\n[Interrupted]'
+X break
+X except EOFError:
+X print '\n[EOF]'
+X break
+X cmd = string.strip(line)
+X if cmd:
+X if cmd = 'quit':
+X break
+X elif cmd = 'list':
+X browserlist(tb)
+X elif cmd = 'up':
+X if ptr-1 >= 0: ptr = ptr-1
+X else: print 'Bottom of stack.'
+X elif cmd = 'down':
+X if ptr+1 < len(tblist): ptr = ptr+1
+X else: print 'Top of stack.'
+X elif cmd = 'locals':
+X printsymbols(tb.tb_frame.f_locals)
+X elif cmd = 'globals':
+X printsymbols(tb.tb_frame.f_globals)
+X elif cmd in ('?', 'help'):
+X browserhelp()
+X else:
+X browserexec(tb, cmd)
+X
+Xdef browserlist(tb):
+X filename = tb.tb_frame.f_code.co_filename
+X lineno = tb.tb_lineno
+X last = lineno
+X first = max(1, last-10)
+X for i in range(first, last+1):
+X if i = lineno: prefix = '***' + string.rjust(`i`, 4) + ':'
+X else: prefix = string.rjust(`i`, 7) + ':'
+X line = readfileline(filename, i)
+X if line[-1:] = '\n': line = line[:-1]
+X print prefix + line
+X
+Xdef browserexec(tb, cmd):
+X locals = tb.tb_frame.f_locals
+X globals = tb.tb_frame.f_globals
+X try:
+X exec(cmd+'\n', globals, locals)
+X except:
+X print '*** Exception:',
+X print sys.exc_type,
+X if sys.exc_value <> None:
+X print ':', sys.exc_value,
+X print
+X print 'Type help to get help.'
+X
+Xdef browserhelp():
+X print
+X print ' This is the traceback browser. Commands are:'
+X print ' up : move one level up in the call stack'
+X print ' down : move one level down in the call stack'
+X print ' locals : print all local variables at this level'
+X print ' globals : print all global variables at this level'
+X print ' list : list source code around the failure'
+X print ' help : print help (what you are reading now)'
+X print ' quit : back to command interpreter'
+X print ' Typing any other 1-line statement will execute it'
+X print ' using the current level\'s symbol tables'
+X print
+X
+Xdef printtb(tb):
+X while tb:
+X print1tb(tb)
+X tb = tb.tb_next
+X
+Xdef print1tb(tb):
+X printtbheader(tb)
+X if tb.tb_frame.f_locals is not tb.tb_frame.f_globals:
+X printsymbols(tb.tb_frame.f_locals)
+X
+Xdef printtbheader(tb):
+X filename = tb.tb_frame.f_code.co_filename
+X lineno = tb.tb_lineno
+X info = '"' + filename + '"(' + `lineno` + ')'
+X line = readfileline(filename, lineno)
+X if line:
+X info = info + ': ' + string.strip(line)
+X print info
+X
+Xdef printsymbols(d):
+X keys = d.keys()
+X keys.sort()
+X for name in keys:
+X print ' ' + string.ljust(name, 12) + ':',
+X printobject(d[name], 4)
+X print
+X
+Xdef printobject(v, maxlevel):
+X if v = None:
+X print 'None',
+X elif type(v) in (type(0), type(0.0)):
+X print v,
+X elif type(v) = type(''):
+X if len(v) > 20:
+X print `v[:17] + '...'`,
+X else:
+X print `v`,
+X elif type(v) = type(()):
+X print '(',
+X printlist(v, maxlevel)
+X print ')',
+X elif type(v) = type([]):
+X print '[',
+X printlist(v, maxlevel)
+X print ']',
+X elif type(v) = type({}):
+X print '{',
+X printdict(v, maxlevel)
+X print '}',
+X else:
+X print v,
+X
+Xdef printlist(v, maxlevel):
+X n = len(v)
+X if n = 0: return
+X if maxlevel <= 0:
+X print '...',
+X return
+X for i in range(min(6, n)):
+X printobject(v[i], maxlevel-1)
+X if i+1 < n: print ',',
+X if n > 6: print '...',
+X
+Xdef printdict(v, maxlevel):
+X keys = v.keys()
+X n = len(keys)
+X if n = 0: return
+X if maxlevel <= 0:
+X print '...',
+X return
+X keys.sort()
+X for i in range(min(6, n)):
+X key = keys[i]
+X print `key` + ':',
+X printobject(v[key], maxlevel-1)
+X if i+1 < n: print ',',
+X if n > 6: print '...',
+X
+X_filecache = {}
+X
+Xdef readfileline(filename, lineno):
+X try:
+X stat = os.stat(filename)
+X except os.error, msg:
+X print 'Cannot stat', filename, '--', msg
+X return ''
+X cache_ok = 0
+X if _filecache.has_key(filename):
+X cached_stat, lines = _filecache[filename]
+X if stat[ST_SIZE] = cached_stat[ST_SIZE] and \
+X stat[ST_MTIME] = cached_stat[ST_MTIME]:
+X cache_ok = 1
+X else:
+X print 'Stale cache entry for', filename
+X del _filecache[filename]
+X if not cache_ok:
+X lines = readfilelines(filename)
+X if not lines:
+X return ''
+X _filecache[filename] = stat, lines
+X if 0 <= lineno-1 < len(lines):
+X return lines[lineno-1]
+X else:
+X print 'Line number out of range, last line is', len(lines)
+X return ''
+X
+Xdef readfilelines(filename):
+X try:
+X fp = open(filename, 'r')
+X except:
+X print 'Cannot open', filename
+X return []
+X lines = []
+X while 1:
+X line = fp.readline()
+X if not line: break
+X lines.append(line)
+X if not lines:
+X print 'Empty file', filename
+X return lines
+EOF
+fi
+if test -s 'src/errors.c'
+then echo '*** I will not over-write existing file src/errors.c'
+else
+echo 'x - src/errors.c'
+sed 's/^X//' > 'src/errors.c' << 'EOF'
+X/***********************************************************
+XCopyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
+XNetherlands.
+X
+X All Rights Reserved
+X
+XPermission to use, copy, modify, and distribute this software and its
+Xdocumentation for any purpose and without fee is hereby granted,
+Xprovided that the above copyright notice appear in all copies and that
+Xboth that copyright notice and this permission notice appear in
+Xsupporting documentation, and that the names of Stichting Mathematisch
+XCentrum or CWI not be used in advertising or publicity pertaining to
+Xdistribution of the software without specific, written prior permission.
+X
+XSTICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+XTHIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+XWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+XACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+XOF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+X
+X******************************************************************/
+X
+X/* Error handling -- see also run.c */
+X
+X/* New error handling interface.
+X
+X The following problem exists (existed): methods of built-in modules
+X are called with 'self' and 'args' arguments, but without a context
+X argument, so they have no way to raise a specific exception.
+X The same is true for the object implementations: no context argument.
+X The old convention was to set 'errno' and to return NULL.
+X The caller (usually call_function() in eval.c) detects the NULL
+X return value and then calls puterrno(ctx) to turn the errno value
+X into a true exception. Problems with this approach are:
+X - it used standard errno values to indicate Python-specific errors,
+X but this means that when such an error code is reported by a system
+X call (e.g., in module posix), the user gets a confusing message
+X - errno is a global variable, which makes extensions to a multi-
+X threading environment difficult; e.g., in IRIX, multi-threaded
+X programs must use the function oserror() instead of looking in errno
+X - there is no portable way to add new error numbers for specic
+X situations -- the value space for errno is reserved to the OS, yet
+X the way to turn module-specific errors into a module-specific
+X exception requires module-specific values for errno
+X - there is no way to add a more situation-specific message to an
+X error.
+X
+X The new interface solves all these problems. To return an error, a
+X built-in function calls err_set(exception), err_setval(exception,
+X value) or err_setstr(exception, string), and returns NULL. These
+X functions save the value for later use by puterrno(). To adapt this
+X scheme to a multi-threaded environment, only the implementation of
+X err_setval() has to be changed.
+X*/
+X
+X#include "allobjects.h"
+X
+X#include <errno.h>
+X#ifndef errno
+Xextern int errno;
+X#endif
+X
+X#include "errcode.h"
+X
+Xextern char *strerror PROTO((int));
+X
+X/* Last exception stored by err_setval() */
+X
+Xstatic object *last_exception;
+Xstatic object *last_exc_val;
+X
+Xvoid
+Xerr_setval(exception, value)
+X object *exception;
+X object *value;
+X{
+X XDECREF(last_exception);
+X XINCREF(exception);
+X last_exception = exception;
+X
+X XDECREF(last_exc_val);
+X XINCREF(value);
+X last_exc_val = value;
+X}
+X
+Xvoid
+Xerr_set(exception)
+X object *exception;
+X{
+X err_setval(exception, (object *)NULL);
+X}
+X
+Xvoid
+Xerr_setstr(exception, string)
+X object *exception;
+X char *string;
+X{
+X object *value = newstringobject(string);
+X err_setval(exception, value);
+X XDECREF(value);
+X}
+X
+Xint
+Xerr_occurred()
+X{
+X return last_exception != NULL;
+X}
+X
+Xvoid
+Xerr_get(p_exc, p_val)
+X object **p_exc;
+X object **p_val;
+X{
+X *p_exc = last_exception;
+X last_exception = NULL;
+X *p_val = last_exc_val;
+X last_exc_val = NULL;
+X}
+X
+Xvoid
+Xerr_clear()
+X{
+X XDECREF(last_exception);
+X last_exception = NULL;
+X XDECREF(last_exc_val);
+X last_exc_val = NULL;
+X}
+X
+X/* Convenience functions to set a type error exception and return 0 */
+X
+Xint
+Xerr_badarg()
+X{
+X err_setstr(TypeError, "illegal argument type for built-in operation");
+X return 0;
+X}
+X
+Xobject *
+Xerr_nomem()
+X{
+X err_set(MemoryError);
+X return NULL;
+X}
+X
+Xobject *
+Xerr_errno(exc)
+X object *exc;
+X{
+X object *v = newtupleobject(2);
+X if (v != NULL) {
+X settupleitem(v, 0, newintobject((long)errno));
+X settupleitem(v, 1, newstringobject(strerror(errno)));
+X }
+X err_setval(exc, v);
+X XDECREF(v);
+X return NULL;
+X}
+X
+Xvoid
+Xerr_badcall()
+X{
+X err_setstr(SystemError, "bad argument to internal function");
+X}
+X
+X/* Set the error appropriate to the given input error code (see errcode.h) */
+X
+Xvoid
+Xerr_input(err)
+X int err;
+X{
+X switch (err) {
+X case E_DONE:
+X case E_OK:
+X break;
+X case E_SYNTAX:
+X err_setstr(RuntimeError, "syntax error");
+X break;
+X case E_TOKEN:
+X err_setstr(RuntimeError, "illegal token");
+X break;
+X case E_INTR:
+X err_set(KeyboardInterrupt);
+X break;
+X case E_NOMEM:
+X err_nomem();
+X break;
+X case E_EOF:
+X err_set(EOFError);
+X break;
+X default:
+X err_setstr(RuntimeError, "unknown input error");
+X break;
+X }
+X}
+EOF
+fi
+if test -s 'src/mathmodule.c'
+then echo '*** I will not over-write existing file src/mathmodule.c'
+else
+echo 'x - src/mathmodule.c'
+sed 's/^X//' > 'src/mathmodule.c' << 'EOF'
+X/***********************************************************
+XCopyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
+XNetherlands.
+X
+X All Rights Reserved
+X
+XPermission to use, copy, modify, and distribute this software and its
+Xdocumentation for any purpose and without fee is hereby granted,
+Xprovided that the above copyright notice appear in all copies and that
+Xboth that copyright notice and this permission notice appear in
+Xsupporting documentation, and that the names of Stichting Mathematisch
+XCentrum or CWI not be used in advertising or publicity pertaining to
+Xdistribution of the software without specific, written prior permission.
+X
+XSTICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+XTHIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+XWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+XACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+XOF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+X
+X******************************************************************/
+X
+X/* Math module -- standard C math library functions, pi and e */
+X
+X#include "allobjects.h"
+X
+X#include <errno.h>
+X#ifndef errno
+Xextern int errno;
+X#endif
+X
+X#include "modsupport.h"
+X
+X#include <math.h>
+X
+Xstatic int
+Xgetdoublearg(args, px)
+X register object *args;
+X double *px;
+X{
+X if (args == NULL)
+X return err_badarg();
+X if (is_floatobject(args)) {
+X *px = getfloatvalue(args);
+X return 1;
+X }
+X if (is_intobject(args)) {
+X *px = getintvalue(args);
+X return 1;
+X }
+X return err_badarg();
+X}
+X
+Xstatic int
+Xget2doublearg(args, px, py)
+X register object *args;
+X double *px, *py;
+X{
+X if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2)
+X return err_badarg();
+X return getdoublearg(gettupleitem(args, 0), px) &&
+X getdoublearg(gettupleitem(args, 1), py);
+X}
+X
+Xstatic object *
+Xmath_1(args, func)
+X object *args;
+X double (*func) FPROTO((double));
+X{
+X double x;
+X if (!getdoublearg(args, &x))
+X return NULL;
+X errno = 0;
+X x = (*func)(x);
+X if (errno != 0)
+X return NULL;
+X else
+X return newfloatobject(x);
+X}
+X
+Xstatic object *
+Xmath_2(args, func)
+X object *args;
+X double (*func) FPROTO((double, double));
+X{
+X double x, y;
+X if (!get2doublearg(args, &x, &y))
+X return NULL;
+X errno = 0;
+X x = (*func)(x, y);
+X if (errno != 0)
+X return NULL;
+X else
+X return newfloatobject(x);
+X}
+X
+X#define FUNC1(stubname, func) \
+X static object * stubname(self, args) object *self, *args; { \
+X return math_1(args, func); \
+X }
+X
+X#define FUNC2(stubname, func) \
+X static object * stubname(self, args) object *self, *args; { \
+X return math_2(args, func); \
+X }
+X
+XFUNC1(math_acos, acos)
+XFUNC1(math_asin, asin)
+XFUNC1(math_atan, atan)
+XFUNC2(math_atan2, atan2)
+XFUNC1(math_ceil, ceil)
+XFUNC1(math_cos, cos)
+XFUNC1(math_cosh, cosh)
+XFUNC1(math_exp, exp)
+XFUNC1(math_fabs, fabs)
+XFUNC1(math_floor, floor)
+X#if 0
+X/* XXX This one is not in the Amoeba library yet, so what the heck... */
+XFUNC2(math_fmod, fmod)
+X#endif
+XFUNC1(math_log, log)
+XFUNC1(math_log10, log10)
+XFUNC2(math_pow, pow)
+XFUNC1(math_sin, sin)
+XFUNC1(math_sinh, sinh)
+XFUNC1(math_sqrt, sqrt)
+XFUNC1(math_tan, tan)
+XFUNC1(math_tanh, tanh)
+X
+X#if 0
+X/* What about these? */
+Xdouble frexp(double x, int *i);
+Xdouble ldexp(double x, int n);
+Xdouble modf(double x, double *i);
+X#endif
+X
+Xstatic struct methodlist math_methods[] = {
+X {"acos", math_acos},
+X {"asin", math_asin},
+X {"atan", math_atan},
+X {"atan2", math_atan2},
+X {"ceil", math_ceil},
+X {"cos", math_cos},
+X {"cosh", math_cosh},
+X {"exp", math_exp},
+X {"fabs", math_fabs},
+X {"floor", math_floor},
+X#if 0
+X {"fmod", math_fmod},
+X {"frexp", math_freqp},
+X {"ldexp", math_ldexp},
+X#endif
+X {"log", math_log},
+X {"log10", math_log10},
+X#if 0
+X {"modf", math_modf},
+X#endif
+X {"pow", math_pow},
+X {"sin", math_sin},
+X {"sinh", math_sinh},
+X {"sqrt", math_sqrt},
+X {"tan", math_tan},
+X {"tanh", math_tanh},
+X {NULL, NULL} /* sentinel */
+X};
+X
+Xvoid
+Xinitmath()
+X{
+X object *m, *d, *v;
+X
+X m = initmodule("math", math_methods);
+X d = getmoduledict(m);
+X dictinsert(d, "pi", v = newfloatobject(atan(1.0) * 4.0));
+X DECREF(v);
+X dictinsert(d, "e", v = newfloatobject(exp(1.0)));
+X DECREF(v);
+X}
+EOF
+fi
+if test -s 'src/sysmodule.c'
+then echo '*** I will not over-write existing file src/sysmodule.c'
+else
+echo 'x - src/sysmodule.c'
+sed 's/^X//' > 'src/sysmodule.c' << 'EOF'
+X/***********************************************************
+XCopyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
+XNetherlands.
+X
+X All Rights Reserved
+X
+XPermission to use, copy, modify, and distribute this software and its
+Xdocumentation for any purpose and without fee is hereby granted,
+Xprovided that the above copyright notice appear in all copies and that
+Xboth that copyright notice and this permission notice appear in
+Xsupporting documentation, and that the names of Stichting Mathematisch
+XCentrum or CWI not be used in advertising or publicity pertaining to
+Xdistribution of the software without specific, written prior permission.
+X
+XSTICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+XTHIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+XWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+XACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+XOF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+X
+X******************************************************************/
+X
+X/* System module */
+X
+X/*
+XVarious bits of information used by the interpreter are collected in
+Xmodule 'sys'.
+XFunction member:
+X- exit(sts): call (C, POSIX) exit(sts)
+XData members:
+X- stdin, stdout, stderr: standard file objects
+X- modules: the table of modules (dictionary)
+X- path: module search path (list of strings)
+X- argv: script arguments (list of strings)
+X- ps1, ps2: optional primary and secondary prompts (strings)
+X*/
+X
+X#include "allobjects.h"
+X
+X#include "sysmodule.h"
+X#include "import.h"
+X#include "modsupport.h"
+X
+X/* Define delimiter used in $PYTHONPATH */
+X
+X#ifdef THINK_C
+X#define DELIM ' '
+X#endif
+X
+X#ifndef DELIM
+X#define DELIM ':'
+X#endif
+X
+Xstatic object *sysdict;
+X
+Xobject *
+Xsysget(name)
+X char *name;
+X{
+X return dictlookup(sysdict, name);
+X}
+X
+XFILE *
+Xsysgetfile(name, def)
+X char *name;
+X FILE *def;
+X{
+X FILE *fp = NULL;
+X object *v = sysget(name);
+X if (v != NULL)
+X fp = getfilefile(v);
+X if (fp == NULL)
+X fp = def;
+X return fp;
+X}
+X
+Xint
+Xsysset(name, v)
+X char *name;
+X object *v;
+X{
+X if (v == NULL)
+X return dictremove(sysdict, name);
+X else
+X return dictinsert(sysdict, name, v);
+X}
+X
+Xstatic object *
+Xsys_exit(self, args)
+X object *self;
+X object *args;
+X{
+X int sts;
+X if (!getintarg(args, &sts))
+X return NULL;
+X goaway(sts);
+X exit(sts); /* Just in case */
+X /* NOTREACHED */
+X}
+X
+Xstatic struct methodlist sys_methods[] = {
+X {"exit", sys_exit},
+X {NULL, NULL} /* sentinel */
+X};
+X
+Xstatic object *sysin, *sysout, *syserr;
+X
+Xvoid
+Xinitsys()
+X{
+X object *m = initmodule("sys", sys_methods);
+X sysdict = getmoduledict(m);
+X INCREF(sysdict);
+X /* NB keep an extra ref to the std files to avoid closing them
+X when the user deletes them */
+X /* XXX File objects should have a "don't close" flag instead */
+X sysin = newopenfileobject(stdin, "<stdin>", "r");
+X sysout = newopenfileobject(stdout, "<stdout>", "w");
+X syserr = newopenfileobject(stderr, "<stderr>", "w");
+X if (err_occurred())
+X fatal("can't create sys.std* file objects");
+X dictinsert(sysdict, "stdin", sysin);
+X dictinsert(sysdict, "stdout", sysout);
+X dictinsert(sysdict, "stderr", syserr);
+X dictinsert(sysdict, "modules", get_modules());
+X if (err_occurred())
+X fatal("can't insert sys.* objects in sys dict");
+X}
+X
+Xstatic object *
+Xmakepathobject(path, delim)
+X char *path;
+X int delim;
+X{
+X int i, n;
+X char *p;
+X object *v, *w;
+X
+X n = 1;
+X p = path;
+X while ((p = strchr(p, delim)) != NULL) {
+X n++;
+X p++;
+X }
+X v = newlistobject(n);
+X if (v == NULL)
+X return NULL;
+X for (i = 0; ; i++) {
+X p = strchr(path, delim);
+X if (p == NULL)
+X p = strchr(path, '\0'); /* End of string */
+X w = newsizedstringobject(path, (int) (p - path));
+X if (w == NULL) {
+X DECREF(v);
+X return NULL;
+X }
+X setlistitem(v, i, w);
+X if (*p == '\0')
+X break;
+X path = p+1;
+X }
+X return v;
+X}
+X
+Xvoid
+Xsetpythonpath(path)
+X char *path;
+X{
+X object *v;
+X if ((v = makepathobject(path, DELIM)) == NULL)
+X fatal("can't create sys.path");
+X if (sysset("path", v) != 0)
+X fatal("can't assign sys.path");
+X DECREF(v);
+X}
+X
+Xstatic object *
+Xmakeargvobject(argc, argv)
+X int argc;
+X char **argv;
+X{
+X object *av;
+X if (argc < 0 || argv == NULL)
+X argc = 0;
+X av = newlistobject(argc);
+X if (av != NULL) {
+X int i;
+X for (i = 0; i < argc; i++) {
+X object *v = newstringobject(argv[i]);
+X if (v == NULL) {
+X DECREF(av);
+X av = NULL;
+X break;
+X }
+X setlistitem(av, i, v);
+X }
+X }
+X return av;
+X}
+X
+Xvoid
+Xsetpythonargv(argc, argv)
+X int argc;
+X char **argv;
+X{
+X object *av = makeargvobject(argc, argv);
+X if (av == NULL)
+X fatal("no mem for sys.argv");
+X if (sysset("argv", av) != 0)
+X fatal("can't assign sys.argv");
+X DECREF(av);
+X}
+EOF
+fi
+if test -s 'src/timemodule.c'
+then echo '*** I will not over-write existing file src/timemodule.c'
+else
+echo 'x - src/timemodule.c'
+sed 's/^X//' > 'src/timemodule.c' << 'EOF'
+X/***********************************************************
+XCopyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
+XNetherlands.
+X
+X All Rights Reserved
+X
+XPermission to use, copy, modify, and distribute this software and its
+Xdocumentation for any purpose and without fee is hereby granted,
+Xprovided that the above copyright notice appear in all copies and that
+Xboth that copyright notice and this permission notice appear in
+Xsupporting documentation, and that the names of Stichting Mathematisch
+XCentrum or CWI not be used in advertising or publicity pertaining to
+Xdistribution of the software without specific, written prior permission.
+X
+XSTICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+XTHIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+XWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+XACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+XOF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+X
+X******************************************************************/
+X
+X/* Time module */
+X
+X#include "allobjects.h"
+X
+X#include "modsupport.h"
+X
+X#include "sigtype.h"
+X
+X#include <signal.h>
+X#include <setjmp.h>
+X
+X#ifdef __STDC__
+X#include <time.h>
+X#else /* !__STDC__ */
+Xtypedef unsigned long time_t;
+Xextern time_t time();
+X#endif /* !__STDC__ */
+X
+X
+X/* Time methods */
+X
+Xstatic object *
+Xtime_time(self, args)
+X object *self;
+X object *args;
+X{
+X long secs;
+X if (!getnoarg(args))
+X return NULL;
+X secs = time((time_t *)NULL);
+X return newintobject(secs);
+X}
+X
+Xstatic jmp_buf sleep_intr;
+X
+Xstatic void
+Xsleep_catcher(sig)
+X int sig;
+X{
+X longjmp(sleep_intr, 1);
+X}
+X
+Xstatic object *
+Xtime_sleep(self, args)
+X object *self;
+X object *args;
+X{
+X int secs;
+X SIGTYPE (*sigsave)();
+X if (!getintarg(args, &secs))
+X return NULL;
+X if (setjmp(sleep_intr)) {
+X signal(SIGINT, sigsave);
+X err_set(KeyboardInterrupt);
+X return NULL;
+X }
+X sigsave = signal(SIGINT, SIG_IGN);
+X if (sigsave != (SIGTYPE (*)()) SIG_IGN)
+X signal(SIGINT, sleep_catcher);
+X sleep(secs);
+X signal(SIGINT, sigsave);
+X INCREF(None);
+X return None;
+X}
+X
+X#ifdef THINK_C
+X#define DO_MILLI
+X#endif /* THINK_C */
+X
+X#ifdef AMOEBA
+X#define DO_MILLI
+Xextern long sys_milli();
+X#define millitimer sys_milli
+X#endif /* AMOEBA */
+X
+X#ifdef BSD_TIME
+X#define DO_MILLI
+X#endif /* BSD_TIME */
+X
+X#ifdef DO_MILLI
+X
+Xstatic object *
+Xtime_millisleep(self, args)
+X object *self;
+X object *args;
+X{
+X long msecs;
+X SIGTYPE (*sigsave)();
+X if (!getlongarg(args, &msecs))
+X return NULL;
+X if (setjmp(sleep_intr)) {
+X signal(SIGINT, sigsave);
+X err_set(KeyboardInterrupt);
+X return NULL;
+X }
+X sigsave = signal(SIGINT, SIG_IGN);
+X if (sigsave != (SIGTYPE (*)()) SIG_IGN)
+X signal(SIGINT, sleep_catcher);
+X millisleep(msecs);
+X signal(SIGINT, sigsave);
+X INCREF(None);
+X return None;
+X}
+X
+Xstatic object *
+Xtime_millitimer(self, args)
+X object *self;
+X object *args;
+X{
+X long msecs;
+X extern long millitimer();
+X if (!getnoarg(args))
+X return NULL;
+X msecs = millitimer();
+X return newintobject(msecs);
+X}
+X
+X#endif /* DO_MILLI */
+X
+X
+Xstatic struct methodlist time_methods[] = {
+X#ifdef DO_MILLI
+X {"millisleep", time_millisleep},
+X {"millitimer", time_millitimer},
+X#endif /* DO_MILLI */
+X {"sleep", time_sleep},
+X {"time", time_time},
+X {NULL, NULL} /* sentinel */
+X};
+X
+X
+Xvoid
+Xinittime()
+X{
+X initmodule("time", time_methods);
+X}
+X
+X
+X#ifdef THINK_C
+X
+X#define MacTicks (* (long *)0x16A)
+X
+Xstatic
+Xsleep(msecs)
+X int msecs;
+X{
+X register long deadline;
+X
+X deadline = MacTicks + msecs * 60;
+X while (MacTicks < deadline) {
+X if (intrcheck())
+X sleep_catcher(SIGINT);
+X }
+X}
+X
+Xstatic
+Xmillisleep(msecs)
+X long msecs;
+X{
+X register long deadline;
+X
+X deadline = MacTicks + msecs * 3 / 50; /* msecs * 60 / 1000 */
+X while (MacTicks < deadline) {
+X if (intrcheck())
+X sleep_catcher(SIGINT);
+X }
+X}
+X
+Xstatic long
+Xmillitimer()
+X{
+X return MacTicks * 50 / 3; /* MacTicks * 1000 / 60 */
+X}
+X
+X#endif /* THINK_C */
+X
+X
+X#ifdef BSD_TIME
+X
+X#include <sys/types.h>
+X#include <sys/time.h>
+X
+Xstatic long
+Xmillitimer()
+X{
+X struct timeval t;
+X struct timezone tz;
+X if (gettimeofday(&t, &tz) != 0)
+X return -1;
+X return t.tv_sec*1000 + t.tv_usec/1000;
+X
+X}
+X
+Xstatic
+Xmillisleep(msecs)
+X long msecs;
+X{
+X struct timeval t;
+X t.tv_sec = msecs/1000;
+X t.tv_usec = (msecs%1000)*1000;
+X (void) select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
+X}
+X
+X#endif /* BSD_TIME */
+X
+EOF
+fi
+if test -s 'src/traceback.c'
+then echo '*** I will not over-write existing file src/traceback.c'
+else
+echo 'x - src/traceback.c'
+sed 's/^X//' > 'src/traceback.c' << 'EOF'
+X/***********************************************************
+XCopyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
+XNetherlands.
+X
+X All Rights Reserved
+X
+XPermission to use, copy, modify, and distribute this software and its
+Xdocumentation for any purpose and without fee is hereby granted,
+Xprovided that the above copyright notice appear in all copies and that
+Xboth that copyright notice and this permission notice appear in
+Xsupporting documentation, and that the names of Stichting Mathematisch
+XCentrum or CWI not be used in advertising or publicity pertaining to
+Xdistribution of the software without specific, written prior permission.
+X
+XSTICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+XTHIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+XWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+XACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+XOF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+X
+X******************************************************************/
+X
+X/* Traceback implementation */
+X
+X#include "allobjects.h"
+X
+X#include "compile.h"
+X#include "frameobject.h"
+X#include "traceback.h"
+X#include "structmember.h"
+X
+Xtypedef struct _tracebackobject {
+X OB_HEAD
+X struct _tracebackobject *tb_next;
+X frameobject *tb_frame;
+X int tb_lasti;
+X int tb_lineno;
+X} tracebackobject;
+X
+X#define OFF(x) offsetof(tracebackobject, x)
+X
+Xstatic struct memberlist tb_memberlist[] = {
+X {"tb_next", T_OBJECT, OFF(tb_next)},
+X {"tb_frame", T_OBJECT, OFF(tb_frame)},
+X {"tb_lasti", T_INT, OFF(tb_lasti)},
+X {"tb_lineno", T_INT, OFF(tb_lineno)},
+X {NULL} /* Sentinel */
+X};
+X
+Xstatic object *
+Xtb_getattr(tb, name)
+X tracebackobject *tb;
+X char *name;
+X{
+X return getmember((char *)tb, tb_memberlist, name);
+X}
+X
+Xstatic void
+Xtb_dealloc(tb)
+X tracebackobject *tb;
+X{
+X XDECREF(tb->tb_next);
+X XDECREF(tb->tb_frame);
+X DEL(tb);
+X}
+X
+Xstatic typeobject Tracebacktype = {
+X OB_HEAD_INIT(&Typetype)
+X 0,
+X "traceback",
+X sizeof(tracebackobject),
+X 0,
+X tb_dealloc, /*tp_dealloc*/
+X 0, /*tp_print*/
+X tb_getattr, /*tp_getattr*/
+X 0, /*tp_setattr*/
+X 0, /*tp_compare*/
+X 0, /*tp_repr*/
+X 0, /*tp_as_number*/
+X 0, /*tp_as_sequence*/
+X 0, /*tp_as_mapping*/
+X};
+X
+X#define is_tracebackobject(v) ((v)->ob_type == &Tracebacktype)
+X
+Xstatic tracebackobject *
+Xnewtracebackobject(next, frame, lasti, lineno)
+X tracebackobject *next;
+X frameobject *frame;
+X int lasti, lineno;
+X{
+X tracebackobject *tb;
+X if ((next != NULL && !is_tracebackobject(next)) ||
+X frame == NULL || !is_frameobject(frame)) {
+X err_badcall();
+X return NULL;
+X }
+X tb = NEWOBJ(tracebackobject, &Tracebacktype);
+X if (tb != NULL) {
+X XINCREF(next);
+X tb->tb_next = next;
+X XINCREF(frame);
+X tb->tb_frame = frame;
+X tb->tb_lasti = lasti;
+X tb->tb_lineno = lineno;
+X }
+X return tb;
+X}
+X
+Xstatic tracebackobject *tb_current = NULL;
+X
+Xint
+Xtb_here(frame, lasti, lineno)
+X frameobject *frame;
+X int lasti;
+X int lineno;
+X{
+X tracebackobject *tb;
+X tb = newtracebackobject(tb_current, frame, lasti, lineno);
+X if (tb == NULL)
+X return -1;
+X XDECREF(tb_current);
+X tb_current = tb;
+X return 0;
+X}
+X
+Xobject *
+Xtb_fetch()
+X{
+X object *v;
+X v = (object *)tb_current;
+X tb_current = NULL;
+X return v;
+X}
+X
+Xint
+Xtb_store(v)
+X object *v;
+X{
+X if (v != NULL && !is_tracebackobject(v)) {
+X err_badcall();
+X return -1;
+X }
+X XDECREF(tb_current);
+X XINCREF(v);
+X tb_current = (tracebackobject *)v;
+X return 0;
+X}
+X
+Xstatic void
+Xtb_displayline(fp, filename, lineno)
+X FILE *fp;
+X char *filename;
+X int lineno;
+X{
+X FILE *xfp;
+X char buf[1000];
+X int i;
+X if (filename[0] == '<' && filename[strlen(filename)-1] == '>')
+X return;
+X xfp = fopen(filename, "r");
+X if (xfp == NULL) {
+X fprintf(fp, " (cannot open \"%s\")\n", filename);
+X return;
+X }
+X for (i = 0; i < lineno; i++) {
+X if (fgets(buf, sizeof buf, xfp) == NULL)
+X break;
+X }
+X if (i == lineno) {
+X char *p = buf;
+X while (*p == ' ' || *p == '\t')
+X p++;
+X fprintf(fp, " %s", p);
+X if (strchr(p, '\n') == NULL)
+X fprintf(fp, "\n");
+X }
+X fclose(xfp);
+X}
+X
+Xstatic void
+Xtb_printinternal(tb, fp)
+X tracebackobject *tb;
+X FILE *fp;
+X{
+X while (tb != NULL) {
+X if (intrcheck()) {
+X fprintf(fp, "[interrupted]\n");
+X break;
+X }
+X fprintf(fp, " File \"");
+X printobject(tb->tb_frame->f_code->co_filename, fp, PRINT_RAW);
+X fprintf(fp, "\", line %d\n", tb->tb_lineno);
+X tb_displayline(fp,
+X getstringvalue(tb->tb_frame->f_code->co_filename),
+X tb->tb_lineno);
+X tb = tb->tb_next;
+X }
+X}
+X
+Xint
+Xtb_print(v, fp)
+X object *v;
+X FILE *fp;
+X{
+X if (v == NULL)
+X return 0;
+X if (!is_tracebackobject(v)) {
+X err_badcall();
+X return -1;
+X }
+X sysset("last_traceback", v);
+X tb_printinternal((tracebackobject *)v, fp);
+X return 0;
+X}
+EOF
+fi
+echo 'Part 15 out of 21 of pack.out complete.'
+exit 0