diff options
| author | Skip Montanaro <[email protected]> | 2021-02-16 14:40:46 -0600 |
|---|---|---|
| committer | Skip Montanaro <[email protected]> | 2021-02-16 14:40:46 -0600 |
| commit | a19a216bc60160c162e616145ef091dd18ce4e61 (patch) | |
| tree | fa4bdff21f9b04a125c84a2bfab8a1c738359e15 /shar/python-0.9.1-15-21.shar | |
| download | python-0.9.1-patched-QoL-a19a216bc60160c162e616145ef091dd18ce4e61.tar.xz python-0.9.1-patched-QoL-a19a216bc60160c162e616145ef091dd18ce4e61.zip | |
Python 0.9.1 as posted in alt.sources
Diffstat (limited to 'shar/python-0.9.1-15-21.shar')
| -rw-r--r-- | shar/python-0.9.1-15-21.shar | 2539 |
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 |
