home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2807 < prev    next >
Internet Message Format  |  1991-02-19  |  62KB

  1. From: guido@cwi.nl (Guido van Rossum)
  2. Newsgroups: alt.sources
  3. Subject: Python 0.9.1 part 15/21
  4. Message-ID: <2977@charon.cwi.nl>
  5. Date: 19 Feb 91 17:42:25 GMT
  6.  
  7. : This is a shell archive.
  8. : Extract with 'sh this_file'.
  9. :
  10. : Extract part 01 first since it makes all directories
  11. echo 'Start of pack.out, part 15 out of 21:'
  12. if test -s 'demo/sgi/gl/kites.py'
  13. then echo '*** I will not over-write existing file demo/sgi/gl/kites.py'
  14. else
  15. echo 'x - demo/sgi/gl/kites.py'
  16. sed 's/^X//' > 'demo/sgi/gl/kites.py' << 'EOF'
  17. X#! /ufs/guido/bin/sgi/python
  18. X
  19. X# *** This only works correctly on a 24 bit-plane machine. ***
  20. X#
  21. X# A simple Python program that tests the some parts of the
  22. X# GL library. It shows the speed that can be obtained when
  23. X# doing simple graphics.
  24. X#
  25. X# The bottleneck in this program is NOT Python but the graphics
  26. X# engine; i.e Python can feed the graphics pipeline fast enough
  27. X# on the 4D/25G.
  28. X#
  29. X# This program show 3 kites flying around the screen. It uses
  30. X#
  31. X#     * bgnpolygon, endpolygon
  32. X#     * v3, n3
  33. X#     * lmdef, lmbind
  34. X#
  35. X# Usage :
  36. X# 
  37. X#     ESC     -> exit program
  38. X#     MOUSE3     -> freeze toggle
  39. X#     MOUSE2     -> one step (use this in freeze state)
  40. X
  41. Xfrom GL import *
  42. Xfrom gl import *
  43. Ximport DEVICE
  44. Xfrom math import *
  45. X
  46. X#
  47. X# viewobj : sets the rotation, translation and scaling
  48. X# set appropiate material, call drawobject()
  49. X#
  50. Xdef viewobj (r, s, t, mat) :
  51. X    pushmatrix()
  52. X    rot (r * 10.0, 'X')
  53. X    rot (r * 10.0, 'Y')
  54. X    rot (r * 10.0, 'Z')
  55. X    scale (s[0], s[1], s[2])
  56. X    translate (t[0], t[1], t[2])
  57. X    lmbind(MATERIAL, mat)
  58. X    drawobject()
  59. X    popmatrix()
  60. X
  61. X#
  62. X# makeobj : the contructor of the object
  63. X#
  64. Xdef mkobj () :
  65. X    v0 = (-5.0 ,0.0, 0.0)
  66. X    v1 = (0.0 ,5.0, 0.0)
  67. X    v2 = (5.0 ,0.0, 0.0)
  68. X    v3 = (0.0 ,2.0, 0.0)
  69. X    n0 = (sqrt(2.0)/2.0, sqrt(2.0)/2.0, 0.0)
  70. X    vn = ((v0, n0), (v1, n0), (v2, n0), (v3, n0))
  71. X    #
  72. X    return vn
  73. X
  74. X#
  75. X# the object itself as an array of vertices and normals
  76. X#
  77. Xkite = mkobj ()
  78. X
  79. X#
  80. X# drawobject : draw a triangle. with bgnpolygon
  81. X#
  82. Xdef drawobject () :
  83. X    #
  84. X    bgnpolygon()
  85. X    vnarray (kite)
  86. X    endpolygon()
  87. X
  88. X#
  89. X# identity matrix
  90. X#
  91. 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]
  92. X
  93. X#
  94. X# the rgb-value of light-blue 
  95. X#
  96. XLightBlue = (43,169,255)
  97. X
  98. X#
  99. X# the different materials.
  100. X#
  101. Xm1=[SPECULAR,0.0,0.0,0.6,DIFFUSE,0.0,0.0,0.8,SHININESS,20.0,LMNULL]
  102. Xm2=[SPECULAR,0.8,0.0,0.1,DIFFUSE,0.8,0.0,0.3,SHININESS,120.0,LMNULL]
  103. Xm3=[SPECULAR,0.0,1.0,0.0,DIFFUSE,0.0,0.6,0.0,SHININESS,120.0,LMNULL]
  104. X
  105. X#
  106. X# lightsources
  107. X#
  108. Xlight1 = [LCOLOR,1.0,1.0,1.0,POSITION,15.0,15.0,0.0,1.0,LMNULL]
  109. Xlight2 = [LCOLOR,1.0,1.0,1.0,POSITION,-15.0,15.0,0.0,1.0,LMNULL]
  110. X
  111. X#
  112. X# the lightmodel
  113. X#
  114. Xmodel = [AMBIENT,0.2,0.2,0.2,LMNULL]
  115. X
  116. X#
  117. X# initgl : opens the window, configures the pipeline to 2buf and zbuf,
  118. X# sets the viewing, defines and binds the materials
  119. X#
  120. Xdef initgl () :
  121. X    #
  122. X    # open window
  123. X    #
  124. X    foreground ()
  125. X    keepaspect (1, 1)
  126. X    prefposition (100, 500, 100, 500)
  127. X    w = winopen ('PYTHON lights')
  128. X    keepaspect (1, 1)
  129. X    winconstraints()
  130. X    #
  131. X    # configure pipeline (zbuf, 2buf, GOURAUD and RGBmode)
  132. X    #
  133. X    zbuffer (1)
  134. X    doublebuffer ()
  135. X    shademodel (GOURAUD)
  136. X    RGBmode ()
  137. X    gconfig ()
  138. X    #
  139. X    # define and bind materials (set perspective BEFORE loadmat !)
  140. X    #
  141. X    mmode(MVIEWING)
  142. X    perspective (900, 1.0, 1.0, 20.0)
  143. X    loadmatrix(idmat)
  144. X    lmdef(DEFMATERIAL, 1, m1)
  145. X    lmdef(DEFMATERIAL, 2, m2)
  146. X    lmdef(DEFMATERIAL, 3, m3)
  147. X    lmdef(DEFLIGHT, 1, light1)
  148. X    lmdef(DEFLIGHT, 2, light2)
  149. X    lmdef(DEFLMODEL, 1, model)
  150. X    lmbind(LIGHT0,1)
  151. X    lmbind(LIGHT1,2)
  152. X    lmbind(LMODEL,1)
  153. X    #
  154. X    # set viewing
  155. X    #
  156. X    lookat (0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0)
  157. X    #
  158. X    # ask for the REDRAW and ESCKEY events
  159. X    #
  160. X    qdevice(DEVICE.MOUSE3)
  161. X    qdevice(DEVICE.MOUSE2)
  162. X    qdevice(DEVICE.REDRAW)
  163. X    qdevice(DEVICE.ESCKEY)
  164. X
  165. X#
  166. X# GoForIT : use 2buf to redraw the object 2n times. index i is used as 
  167. X# the (smoothly changing) rotation angle
  168. X#
  169. Xdef GoForIt(i) :
  170. X    freeze = 1
  171. X    while 1 :
  172. X        if freeze <> 0 :
  173. X            i = i + 1
  174. X        #
  175. X        # clear z-buffer and clear background to light-blue
  176. X        #
  177. X        zclear()
  178. X        c3i (LightBlue)
  179. X        clear()
  180. X        #
  181. X        # draw the 3 traiangles scaled above each other.
  182. X        #
  183. X        viewobj(float(i),[1.0,1.0,1.0],[1.0,1.0,1.0],1)
  184. X        viewobj(float(i),[0.75,0.75,0.75],[0.0,2.0,2.0],2)
  185. X        viewobj(float(i),[0.5,0.5,0.5],[0.0,4.0,4.0],3)
  186. X        #
  187. X        swapbuffers()
  188. X        #
  189. X        if qtest() <> 0 :
  190. X            dev, val = qread()
  191. X            if dev = DEVICE.ESCKEY :
  192. X                break
  193. X            elif dev = DEVICE.REDRAW :
  194. X                reshapeviewport ()
  195. X            elif dev = DEVICE.MOUSE3 and val <> 0 :
  196. X                freeze = 1 - freeze
  197. X            elif dev = DEVICE.MOUSE2 and val <> 0 :
  198. X                i = i + 1
  199. X
  200. X
  201. X# the main program
  202. X#
  203. Xdef main () :
  204. X    initgl ()
  205. X    GoForIt (0)
  206. X
  207. X#
  208. X# exec main
  209. X#
  210. Xmain  ()
  211. EOF
  212. chmod +x 'demo/sgi/gl/kites.py'
  213. fi
  214. if test -s 'demo/sgi/gl_panel/nurbs/nurbs.s'
  215. then echo '*** I will not over-write existing file demo/sgi/gl_panel/nurbs/nurbs.s'
  216. else
  217. echo 'x - demo/sgi/gl_panel/nurbs/nurbs.s'
  218. sed 's/^X//' > 'demo/sgi/gl_panel/nurbs/nurbs.s' << 'EOF'
  219. X;;; This file was automatically generated by the panel editor.
  220. X;;; If you read it into gnu emacs, it will automagically format itself.
  221. X
  222. X(panel (prop help creator:user-panel-help)
  223. X(prop user-panel #t)
  224. X(label "NURB controls")
  225. X(x 815)
  226. X(y 22)
  227. X(al (pnl_toggle_button (name "trim")
  228. X(prop help creator:user-act-help)
  229. X(label "trim on/off")
  230. X(x 4)
  231. X(y 4.5)
  232. X(w 0.45)
  233. X(h 0.4)
  234. X(downfunc move-then-resize)
  235. X)
  236. X(pnl_toggle_button (name "motion")
  237. X(prop help creator:user-act-help)
  238. X(label "motion on/off")
  239. X(y 1)
  240. X(downfunc move-then-resize)
  241. X)
  242. X(pnl_toggle_button (name "xyzaxis")
  243. X(prop help creator:user-act-help)
  244. X(label "xyz-axis")
  245. X(y 3)
  246. X(downfunc move-then-resize)
  247. X)
  248. X(pnl_toggle_button (name "trimpnts")
  249. X(prop help creator:user-act-help)
  250. X(label "trimming pnts")
  251. X(y 3.5)
  252. X(downfunc move-then-resize)
  253. X)
  254. X(pnl_toggle_button (name "cntlpnts")
  255. X(prop help creator:user-act-help)
  256. X(label "control pnts")
  257. X(y 4)
  258. X(downfunc move-then-resize)
  259. X)
  260. X(pnl_toggle_button (name "nurb")
  261. X(prop help creator:user-act-help)
  262. X(label "nurb")
  263. X(y 4.5)
  264. X(val 1)
  265. X(downfunc move-then-resize)
  266. X)
  267. X(pnl_button (name "quit")
  268. X(prop help creator:user-act-help)
  269. X(label "quit")
  270. X(x 4)
  271. X(y 1)
  272. X(labeltype 1)
  273. X(downfunc move-then-resize)
  274. X)
  275. X(pnl_label (prop help creator:user-act-help)
  276. X(label "TRIMMING")
  277. X(x 4)
  278. X(y 5)
  279. X(downfunc move-then-resize)
  280. X)
  281. X(pnl_label (prop help creator:user-act-help)
  282. X(label "MOTION")
  283. X(y 1.5)
  284. X(downfunc move-then-resize)
  285. X)
  286. X(pnl_label (prop help creator:user-act-help)
  287. X(label "VISIBILITY")
  288. X(y 5)
  289. X(downfunc move-then-resize)
  290. X)
  291. X)
  292. X)
  293. X;;; Local Variables:
  294. X;;; mode: scheme
  295. X;;; eval: (save-excursion (goto-char (point-min)) (kill-line 3))
  296. X;;; eval: (save-excursion (goto-char (point-min)) (replace-regexp "[ \n]*)" ")"))
  297. X;;; eval: (indent-region (point-min) (point-max) nil)
  298. X;;; eval: (progn (kill-line -3) (delete-backward-char 1) (save-buffer))
  299. X;;; End:
  300. EOF
  301. fi
  302. if test -s 'lib/Sliders.py'
  303. then echo '*** I will not over-write existing file lib/Sliders.py'
  304. else
  305. echo 'x - lib/Sliders.py'
  306. sed 's/^X//' > 'lib/Sliders.py' << 'EOF'
  307. X# Module 'Sliders'
  308. X
  309. X
  310. Ximport stdwin
  311. Xfrom stdwinevents import *
  312. Ximport rect
  313. Xfrom Buttons import *
  314. Xfrom HVSplit import HSplit
  315. X
  316. X
  317. X# Field indices in event detail
  318. X#
  319. X_HV = 0
  320. X_CLICKS = 1
  321. X_BUTTON = 2
  322. X_MASK = 3
  323. X
  324. X
  325. X# DragSlider is the simplest possible slider.
  326. X# It looks like a button but dragging the mouse left or right
  327. X# changes the controlled value.
  328. X# It does not support any of the triggers or hooks defined by Buttons,
  329. X# but defines its own setval_trigger and setval_hook.
  330. X#
  331. Xclass DragSliderReactivity() = BaseReactivity():
  332. X    #
  333. X    def mouse_down(self, detail):
  334. X        h, v = hv = detail[_HV]
  335. X        if self.enabled and self.mousetest(hv):
  336. X            self.anchor = h
  337. X            self.oldval = self.val
  338. X            self.active = 1
  339. X    #
  340. X    def mouse_move(self, detail):
  341. X        if self.active:
  342. X            h, v = detail[_HV]
  343. X            self.setval(self.oldval + (h - self.anchor))
  344. X    #
  345. X    def mouse_up(self, detail):
  346. X        if self.active:
  347. X            h, v = detail[_HV]
  348. X            self.setval(self.oldval + (h - self.anchor))
  349. X            self.active = 0
  350. X    #
  351. X
  352. Xclass DragSliderAppearance() = ButtonAppearance():
  353. X    #
  354. X    # INVARIANTS maintained by the setval method:
  355. X    #
  356. X    #    self.min <= self.val <= self.max
  357. X    #    self.text = self.pretext + `self.val` + self.postext
  358. X    #
  359. X    # (Notice that unlike Python ranges, the end point belongs
  360. X    # to the range.)
  361. X    #
  362. X    def init_appearance(self):
  363. X        ButtonAppearance.init_appearance(self)
  364. X        self.min = 0
  365. X        self.val = 0
  366. X        self.max = 100
  367. X        self.hook = 0
  368. X        self.pretext = self.postext = ''
  369. X        self.recalctext()
  370. X    #
  371. X    # The 'get*' and 'set*' methods belong to the generic slider interface
  372. X    #
  373. X    def getval(self): return self.val
  374. X    #
  375. X    def sethook(self, hook):
  376. X        self.hook = hook
  377. X    #
  378. X    def setminvalmax(self, (min, val, max)):
  379. X        self.min = min
  380. X        self.max = max
  381. X        self.setval(val)
  382. X    #
  383. X    def settexts(self, (pretext, postext)):
  384. X        self.pretext = pretext
  385. X        self.postext = postext
  386. X        self.recalctext()
  387. X    #
  388. X    def setval(self, val):
  389. X        val = min(self.max, max(self.min, val))
  390. X        if val <> self.val:
  391. X            self.val = val
  392. X            self.recalctext()
  393. X            self.trigger()
  394. X    #
  395. X    def trigger(self):
  396. X        if self.hook:
  397. X            self.hook(self)
  398. X    #
  399. X    def recalctext(self):
  400. X        self.settext(self.pretext + `self.val` + self.postext)
  401. X    #
  402. X
  403. Xclass DragSlider() = DragSliderReactivity(), DragSliderAppearance(), Define():
  404. X    def definetext(self, (parent, text)):
  405. X        raise RuntimeError, 'DragSlider.definetext() not supported'
  406. X
  407. X
  408. X# Auxiliary class for PushButton incorporated in ComplexSlider
  409. X#
  410. Xclass _StepButton() = PushButton():
  411. X    def define(self, parent):
  412. X        self = PushButton.define(self, parent)
  413. X        self.step = 0
  414. X        return self
  415. X    def setstep(self, step):
  416. X        self.step = step
  417. X    def definetextstep(self, (parent, text, step)):
  418. X        self = self.definetext(parent, text)
  419. X        self.setstep(step)
  420. X        return self
  421. X    def init_reactivity(self):
  422. X        PushButton.init_reactivity(self)
  423. X        self.parent.need_timer(self)
  424. X    def step_trigger(self):
  425. X        self.parent.setval(self.parent.getval() + self.step)
  426. X    def down_trigger(self):
  427. X        self.step_trigger()
  428. X        self.parent.settimer(5)
  429. X    def timer(self):
  430. X        if self.hilited:
  431. X            self.step_trigger()
  432. X        if self.active:
  433. X            self.parent.settimer(1)
  434. X
  435. X
  436. X# A complex slider is an HSplit initialized to three buttons:
  437. X# one to step down, a dragslider, and one to step up.
  438. X#
  439. Xclass ComplexSlider() = HSplit():
  440. X    #
  441. X    # Override Slider define() method
  442. X    #
  443. X    def define(self, parent):
  444. X        self = self.create(parent) # HSplit
  445. X        #
  446. X        self.downbutton = _StepButton().definetextstep(self, '-', -1)
  447. X        self.dragbutton = DragSlider().define(self)
  448. X        self.upbutton = _StepButton().definetextstep(self, '+', 1)
  449. X        #
  450. X        return self
  451. X    #
  452. X    # Override HSplit methods
  453. X    #
  454. X    def minsize(self, m):
  455. X        w1, h1 = self.downbutton.minsize(m)
  456. X        w2, h2 = self.dragbutton.minsize(m)
  457. X        w3, h3 = self.upbutton.minsize(m)
  458. X        height = max(h1, h2, h3)
  459. X        w1 = max(w1, height)
  460. X        w3 = max(w3, height)
  461. X        return w1+w2+w3, height
  462. X    #
  463. X    def setbounds(self, bounds):
  464. X        (left, top), (right, bottom) = self.bounds = bounds
  465. X        size = bottom - top
  466. X        self.downbutton.setbounds((left, top), (left+size, bottom))
  467. X        self.dragbutton.setbounds((left+size, top), \
  468. X                        (right-size, bottom))
  469. X        self.upbutton.setbounds((right-size, top), (right, bottom))
  470. X    #
  471. X    # Pass other Slider methods on to dragbutton
  472. X    #
  473. X    def getval(self): return self.dragbutton.getval()
  474. X    def sethook(self, hook): self.dragbutton.sethook(hook)
  475. X    def setminvalmax(self, args): self.dragbutton.setminvalmax(args)
  476. X    def settexts(self, args): self.dragbutton.settexts(args)
  477. X    def setval(self, val): self.dragbutton.setval(val)
  478. X    def enable(self, flag):
  479. X        self.downbutton.enable(flag)
  480. X        self.dragbutton.enable(flag)
  481. X        self.upbutton.enable(flag)
  482. EOF
  483. fi
  484. if test -s 'lib/clock.py'
  485. then echo '*** I will not over-write existing file lib/clock.py'
  486. else
  487. echo 'x - lib/clock.py'
  488. sed 's/^X//' > 'lib/clock.py' << 'EOF'
  489. X# 'klok' -- A simple alarm clock
  490. X
  491. X# The alarm can be set at 5 minute intervals on a 12 hour basis.
  492. X# It is controlled with the mouse:
  493. X# - Click and drag around the circle to set the alarm.
  494. X# - Click far outside the circle to clear the alarm.
  495. X# - Click near the center to set the alarm at the last time set.
  496. X# The alarm time is indicated by a small triangle just outside the circle,
  497. X# and also by a digital time at the bottom.
  498. X# The indicators disappear when the alarm is not set.
  499. X# When the alarm goes off, it beeps every minute for five minutes,
  500. X# and the clock turns into inverse video.
  501. X# Click or activate the window to turn the ringing off.
  502. X
  503. Ximport stdwin
  504. Xfrom stdwinevents import WE_MOUSE_DOWN, WE_MOUSE_MOVE, WE_MOUSE_UP, \
  505. X    WE_TIMER, WE_DRAW, WE_SIZE, WE_CLOSE, WE_ACTIVATE
  506. Ximport time
  507. Xfrom math import sin, cos, atan2, pi, sqrt
  508. X
  509. XDEFWIDTH, DEFHEIGHT = 200, 200
  510. X
  511. Xmouse_events = (WE_MOUSE_DOWN, WE_MOUSE_MOVE, WE_MOUSE_UP)
  512. Xorigin = 0, 0
  513. Xfaraway = 2000, 2000
  514. Xeverywhere = origin, faraway
  515. X
  516. Xclass struct(): pass    # A class to declare featureless objects
  517. X
  518. XG = struct()        # Global variables (most set in setdimensions())
  519. XG.tzdiff = 5*3600    # THINK computes UCT from local time assuming EST!
  520. X
  521. XA = struct()        # Globals used by the alarm
  522. XA.set = 1        # True when alarm is set
  523. XA.time = 11*60 + 40    # Time when alarm must go off
  524. XA.ring = 0        # True when alarm is ringing
  525. X
  526. Xdef main():
  527. X    try:
  528. X        realmain()
  529. X    except KeyboardInterrupt:
  530. X        print 'KeyboardInterrupt'
  531. X    finally:
  532. X        G.w = 0
  533. X
  534. Xdef realmain():
  535. X    setdimensions(DEFWIDTH, DEFHEIGHT)
  536. X    stdwin.setdefwinsize(G.farcorner)
  537. X    G.w = stdwin.open('klok')
  538. X    settimer()
  539. X    while 1:
  540. X        type, window, detail = stdwin.getevent()
  541. X        if type = WE_DRAW:
  542. X            drawproc(detail)
  543. X        elif type = WE_TIMER:
  544. X            settimer()
  545. X            drawproc(everywhere)
  546. X        elif type in mouse_events:
  547. X            mouseclick(type, detail)
  548. X        elif type = WE_ACTIVATE:
  549. X            if A.ring:
  550. X                # Turn the ringing off
  551. X                A.ring = 0
  552. X                G.w.begindrawing().invert(G.mainarea)
  553. X        elif type = WE_SIZE:
  554. X            G.w.change(everywhere)
  555. X            width, height = G.w.getwinsize()
  556. X            height = height - stdwin.lineheight()
  557. X            setdimensions(width, height)
  558. X        elif type = WE_CLOSE:
  559. X            break
  560. X
  561. Xdef setdimensions(width, height):
  562. X    if width < height: size = width
  563. X    else: size = height
  564. X    halfwidth = width/2
  565. X    halfheight = height/2
  566. X    G.center = halfwidth, halfheight
  567. X    G.radius = size*45/100
  568. X    G.width = width
  569. X    G.height = height
  570. X    G.corner = width, height
  571. X    G.mainarea = origin, G.corner
  572. X    G.lineheight = stdwin.lineheight()
  573. X    G.farcorner = width, height + G.lineheight
  574. X    G.statusarea = (0, height), G.farcorner
  575. X    G.fullarea = origin, G.farcorner
  576. X
  577. Xdef settimer():
  578. X    now = getlocaltime()
  579. X    G.times = calctime(now)
  580. X    delay = 61 - now % 60
  581. X    G.w.settimer(10 * delay)
  582. X    minutes = (now/60) % 720
  583. X    if A.ring:
  584. X        # Is it time to stop the alarm ringing?
  585. X        since = (minutes - A.time + 720) % 720
  586. X        if since >= 5:
  587. X            # Stop it now
  588. X            A.ring = 0
  589. X        else:
  590. X            # Ring again, once every minute
  591. X            stdwin.fleep()
  592. X    elif A.set and minutes = A.time:
  593. X        # Start the alarm ringing
  594. X        A.ring = 1
  595. X        stdwin.fleep()
  596. X
  597. Xdef drawproc(area):
  598. X    hours, minutes, seconds = G.times
  599. X    d = G.w.begindrawing()
  600. X    d.cliprect(area)
  601. X    d.erase(everywhere)
  602. X    d.circle(G.center, G.radius)
  603. X    d.line(G.center, calcpoint(hours*30 + minutes/2, 0.6))
  604. X    d.line(G.center, calcpoint(minutes*6, 1.0))
  605. X    str = dd(hours) + ':' + dd(minutes)
  606. X    p = (G.width - d.textwidth(str))/2, G.height * 3 / 4
  607. X    d.text(p, str)
  608. X    if A.set:
  609. X        drawalarm(d)
  610. X        drawalarmtime(d)
  611. X    if A.ring:
  612. X        d.invert(G.mainarea)
  613. X
  614. Xdef mouseclick(type, detail):
  615. X    d = G.w.begindrawing()
  616. X    if A.ring:
  617. X        # First turn the ringing off
  618. X        A.ring = 0
  619. X        d.invert(G.mainarea)
  620. X    h, v = detail[0]
  621. X    ch, cv = G.center
  622. X    x, y = h-ch, cv-v
  623. X    dist = sqrt(x*x + y*y) / float(G.radius)
  624. X    if dist > 1.2:
  625. X        if A.set:
  626. X            drawalarm(d)
  627. X            erasealarmtime(d)
  628. X            A.set = 0
  629. X    elif dist < 0.8:
  630. X        if not A.set:
  631. X            A.set = 1
  632. X            drawalarm(d)
  633. X            drawalarmtime(d)
  634. X    else:
  635. X        # Convert to half-degrees (range 0..720)
  636. X        alpha = atan2(y, x)
  637. X        hdeg = alpha*360.0/pi
  638. X        hdeg = 180.0 - hdeg
  639. X        hdeg = (hdeg + 720.0) % 720.0
  640. X        atime = 5*int(hdeg/5.0 + 0.5)
  641. X        if atime <> A.time or not A.set:
  642. X            if A.set:
  643. X                drawalarm(d)
  644. X                erasealarmtime(d)
  645. X            A.set = 1
  646. X            A.time = atime
  647. X            drawalarm(d)
  648. X            drawalarmtime(d)
  649. X
  650. Xdef drawalarm(d):
  651. X    p1 = calcpoint(float(A.time)/2.0, 1.02)
  652. X    p2 = calcpoint(float(A.time)/2.0 - 4.0, 1.1)
  653. X    p3 = calcpoint(float(A.time)/2.0 + 4.0, 1.1)
  654. X    d.xorline(p1, p2)
  655. X    d.xorline(p2, p3)
  656. X    d.xorline(p3, p1)
  657. X
  658. Xdef erasealarmtime(d):
  659. X    d.erase(G.statusarea)
  660. X
  661. Xdef drawalarmtime(d):
  662. X    # A.time is in the range 0..720 with origin at 12 o'clock
  663. X    # Convert to hours (0..12) and minutes (12*(0..60))
  664. X    hh = A.time/60
  665. X    mm = A.time%60
  666. X    str = 'Alarm@' + dd(hh) + ':' + dd(mm)
  667. X    p1 = (G.width - d.textwidth(str))/2, G.height
  668. X    d.text(p1, str)
  669. X
  670. Xdef calctime(now):
  671. X    seconds = now % 60
  672. X    minutes = (now/60) % 60
  673. X    hours = (now/3600) % 12
  674. X    return hours, minutes, seconds
  675. X
  676. Xdef calcpoint(degrees, size):
  677. X    alpha = pi/2.0 - float(degrees) * pi/180.0
  678. X    x, y = cos(alpha), sin(alpha)
  679. X    h, v = G.center
  680. X    r = float(G.radius)
  681. X    return h + int(x*size*r), v - int(y*size*r)
  682. X
  683. Xdef dd(n):
  684. X    s = `n`
  685. X    return '0'*(2-len(s)) + s
  686. X
  687. Xdef getlocaltime():
  688. X    return time.time() - G.tzdiff
  689. X
  690. X#main()
  691. EOF
  692. fi
  693. if test -s 'lib/dircmp.py'
  694. then echo '*** I will not over-write existing file lib/dircmp.py'
  695. else
  696. echo 'x - lib/dircmp.py'
  697. sed 's/^X//' > 'lib/dircmp.py' << 'EOF'
  698. X# Module 'dirmp'
  699. X#
  700. X# Defines a class to build directory diff tools on.
  701. X
  702. Ximport posix
  703. X
  704. Ximport path
  705. X
  706. Ximport dircache
  707. Ximport cmpcache
  708. Ximport statcache
  709. Xfrom stat import *
  710. X
  711. X# Directory comparison class.
  712. X#
  713. Xclass dircmp():
  714. X    #
  715. X    def new(dd, (a, b)): # Initialize
  716. X        dd.a = a
  717. X        dd.b = b
  718. X        # Properties that caller may change before callingdd. run():
  719. X        dd.hide = ['.', '..'] # Names never to be shown
  720. X        dd.ignore = ['RCS', 'tags'] # Names ignored in comparison
  721. X        #
  722. X        return dd
  723. X    #
  724. X    def run(dd): # Compare everything except common subdirectories
  725. X        dd.a_list = filter(dircache.listdir(dd.a), dd.hide)
  726. X        dd.b_list = filter(dircache.listdir(dd.b), dd.hide)
  727. X        dd.a_list.sort()
  728. X        dd.b_list.sort()
  729. X        dd.phase1()
  730. X        dd.phase2()
  731. X        dd.phase3()
  732. X    #
  733. X    def phase1(dd): # Compute common names
  734. X        dd.a_only = []
  735. X        dd.common = []
  736. X        for x in dd.a_list:
  737. X            if x in dd.b_list:
  738. X                dd.common.append(x)
  739. X            else:
  740. X                dd.a_only.append(x)
  741. X        #
  742. X        dd.b_only = []
  743. X        for x in dd.b_list:
  744. X            if x not in dd.common:
  745. X                dd.b_only.append(x)
  746. X    #
  747. X    def phase2(dd): # Distinguish files, directories, funnies
  748. X        dd.common_dirs = []
  749. X        dd.common_files = []
  750. X        dd.common_funny = []
  751. X        #
  752. X        for x in dd.common:
  753. X            a_path = path.cat(dd.a, x)
  754. X            b_path = path.cat(dd.b, x)
  755. X            #
  756. X            ok = 1
  757. X            try:
  758. X                a_stat = statcache.stat(a_path)
  759. X            except posix.error, why:
  760. X                # print 'Can\'t stat', a_path, ':', why[1]
  761. X                ok = 0
  762. X            try:
  763. X                b_stat = statcache.stat(b_path)
  764. X            except posix.error, why:
  765. X                # print 'Can\'t stat', b_path, ':', why[1]
  766. X                ok = 0
  767. X            #
  768. X            if ok:
  769. X                a_type = S_IFMT(a_stat[ST_MODE])
  770. X                b_type = S_IFMT(b_stat[ST_MODE])
  771. X                if a_type <> b_type:
  772. X                    dd.common_funny.append(x)
  773. X                elif S_ISDIR(a_type):
  774. X                    dd.common_dirs.append(x)
  775. X                elif S_ISREG(a_type):
  776. X                    dd.common_files.append(x)
  777. X                else:
  778. X                    dd.common_funny.append(x)
  779. X            else:
  780. X                dd.common_funny.append(x)
  781. X    #
  782. X    def phase3(dd): # Find out differences between common files
  783. X        xx = cmpfiles(dd.a, dd.b, dd.common_files)
  784. X        dd.same_files, dd.diff_files, dd.funny_files = xx
  785. X    #
  786. X    def phase4(dd): # Find out differences between common subdirectories
  787. X        # A new dircmp object is created for each common subdirectory,
  788. X        # these are stored in a dictionary indexed by filename.
  789. X        # The hide and ignore properties are inherited from the parent
  790. X        dd.subdirs = {}
  791. X        for x in dd.common_dirs:
  792. X            a_x = path.cat(dd.a, x)
  793. X            b_x = path.cat(dd.b, x)
  794. X            dd.subdirs[x] = newdd = dircmp().new(a_x, b_x)
  795. X            newdd.hide = dd.hide
  796. X            newdd.ignore = dd.ignore
  797. X            newdd.run()
  798. X    #
  799. X    def phase4_closure(dd): # Recursively call phase4() on subdirectories
  800. X        dd.phase4()
  801. X        for x in dd.subdirs.keys():
  802. X            dd.subdirs[x].phase4_closure()
  803. X    #
  804. X    def report(dd): # Print a report on the differences between a and b
  805. X        # Assume that phases 1 to 3 have been executed
  806. X        # Output format is purposely lousy
  807. X        print 'diff', dd.a, dd.b
  808. X        if dd.a_only:
  809. X            print 'Only in', dd.a, ':', dd.a_only
  810. X        if dd.b_only:
  811. X            print 'Only in', dd.b, ':', dd.b_only
  812. X        if dd.same_files:
  813. X            print 'Identical files :', dd.same_files
  814. X        if dd.diff_files:
  815. X            print 'Differing files :', dd.diff_files
  816. X        if dd.funny_files:
  817. X            print 'Trouble with common files :', dd.funny_files
  818. X        if dd.common_dirs:
  819. X            print 'Common subdirectories :', dd.common_dirs
  820. X        if dd.common_funny:
  821. X            print 'Common funny cases :', dd.common_funny
  822. X    #
  823. X    def report_closure(dd): # Print reports on dd and on subdirs
  824. X        # If phase 4 hasn't been done, no subdir reports are printed
  825. X        dd.report()
  826. X        try:
  827. X            x = dd.subdirs
  828. X        except NameError:
  829. X            return # No subdirectories computed
  830. X        for x in dd.subdirs.keys():
  831. X            print
  832. X            dd.subdirs[x].report_closure()
  833. X    #
  834. X    def report_phase4_closure(dd): # Report and do phase 4 recursively
  835. X        dd.report()
  836. X        dd.phase4()
  837. X        for x in dd.subdirs.keys():
  838. X            print
  839. X            dd.subdirs[x].report_phase4_closure()
  840. X
  841. X
  842. X# Compare common files in two directories.
  843. X# Return:
  844. X#    - files that compare equal
  845. X#    - files that compare different
  846. X#    - funny cases (can't stat etc.)
  847. X#
  848. Xdef cmpfiles(a, b, common):
  849. X    res = ([], [], [])
  850. X    for x in common:
  851. X        res[cmp(path.cat(a, x), path.cat(b, x))].append(x)
  852. X    return res
  853. X
  854. X
  855. X# Compare two files.
  856. X# Return:
  857. X#    0 for equal
  858. X#    1 for different
  859. X#    2 for funny cases (can't stat, etc.)
  860. X#
  861. Xdef cmp(a, b):
  862. X    try:
  863. X        if cmpcache.cmp(a, b): return 0
  864. X        return 1
  865. X    except posix.error:
  866. X        return 2
  867. X
  868. X
  869. X# Remove a list item.
  870. X# NB: This modifies the list argument.
  871. X#
  872. Xdef remove(list, item):
  873. X    for i in range(len(list)):
  874. X        if list[i] = item:
  875. X            del list[i]
  876. X            break
  877. X
  878. X
  879. X# Return a copy with items that occur in skip removed.
  880. X#
  881. Xdef filter(list, skip):
  882. X    result = []
  883. X    for item in list:
  884. X        if item not in skip: result.append(item)
  885. X    return result
  886. X
  887. X
  888. X# Demonstration and testing.
  889. X#
  890. Xdef demo():
  891. X    import sys
  892. X    import getopt
  893. X    options, args = getopt.getopt(sys.argv[1:], 'r')
  894. X    if len(args) <> 2: raise getopt.error, 'need exactly two args'
  895. X    dd = dircmp().new(args[0], args[1])
  896. X    dd.run()
  897. X    if ('-r', '') in options:
  898. X        dd.report_phase4_closure()
  899. X    else:
  900. X        dd.report()
  901. X
  902. X# demo()
  903. EOF
  904. fi
  905. if test -s 'lib/dis.py'
  906. then echo '*** I will not over-write existing file lib/dis.py'
  907. else
  908. echo 'x - lib/dis.py'
  909. sed 's/^X//' > 'lib/dis.py' << 'EOF'
  910. X# Disassembler
  911. X
  912. Ximport sys
  913. Ximport string
  914. X
  915. Xdef dis():
  916. X    tb = sys.last_traceback
  917. X    while tb.tb_next: tb = tb.tb_next
  918. X    distb(tb)
  919. X
  920. Xdef distb(tb):
  921. X    disassemble(tb.tb_frame.f_code, tb.tb_lasti)
  922. X
  923. Xdef disco(co):
  924. X    disassemble(co, -1)
  925. X
  926. Xdef disassemble(co, lasti):
  927. X    code = co.co_code
  928. X    labels = findlabels(code)
  929. X    n = len(code)
  930. X    i = 0
  931. X    while i < n:
  932. X        c = code[i]
  933. X        op = ord(c)
  934. X        if op = SET_LINENO and i > 0: print # Extra blank line
  935. X        if i = lasti: print '-->',
  936. X        else: print '   ',
  937. X        if i in labels: print '>>',
  938. X        else: print '  ',
  939. X        print string.rjust(`i`, 4),
  940. X        print string.ljust(opname[op], 15),
  941. X        i = i+1
  942. X        if op >= HAVE_ARGUMENT:
  943. X            oparg = ord(code[i]) + ord(code[i+1])*256
  944. X            i = i+2
  945. X            print string.rjust(`oparg`, 5),
  946. X            if op in hasconst:
  947. X                print '(' + `co.co_consts[oparg]` + ')',
  948. X            elif op in hasname:
  949. X                print '(' + co.co_names[oparg] + ')',
  950. X            elif op in hasjrel:
  951. X                print '(to ' + `i + oparg` + ')',
  952. X        print
  953. X
  954. Xdef findlabels(code):
  955. X    labels = []
  956. X    n = len(code)
  957. X    i = 0
  958. X    while i < n:
  959. X        c = code[i]
  960. X        op = ord(c)
  961. X        i = i+1
  962. X        if op >= HAVE_ARGUMENT:
  963. X            oparg = ord(code[i]) + ord(code[i+1])*256
  964. X            i = i+2
  965. X            label = -1
  966. X            if op in hasjrel:
  967. X                label = i+oparg
  968. X            elif op in hasjabs:
  969. X                label = oparg
  970. X            if label >= 0:
  971. X                if label not in labels:
  972. X                    labels.append(label)
  973. X    return labels
  974. X
  975. Xhasconst = []
  976. Xhasname = []
  977. Xhasjrel = []
  978. Xhasjabs = []
  979. X
  980. Xopname = range(256)
  981. Xfor op in opname: opname[op] = '<' + `op` + '>'
  982. X
  983. Xdef def_op(name, op):
  984. X    opname[op] = name
  985. X
  986. Xdef name_op(name, op):
  987. X    opname[op] = name
  988. X    hasname.append(op)
  989. X
  990. Xdef jrel_op(name, op):
  991. X    opname[op] = name
  992. X    hasjrel.append(op)
  993. X
  994. Xdef jabs_op(name, op):
  995. X    opname[op] = name
  996. X    hasjabs.append(op)
  997. X
  998. X# Instruction opcodes for compiled code
  999. X
  1000. Xdef_op('STOP_CODE', 0)
  1001. Xdef_op('POP_TOP', 1)
  1002. Xdef_op('ROT_TWO', 2)
  1003. Xdef_op('ROT_THREE', 3)
  1004. Xdef_op('DUP_TOP', 4)
  1005. X
  1006. Xdef_op('UNARY_POSITIVE', 10)
  1007. Xdef_op('UNARY_NEGATIVE', 11)
  1008. Xdef_op('UNARY_NOT', 12)
  1009. Xdef_op('UNARY_CONVERT', 13)
  1010. Xdef_op('UNARY_CALL', 14)
  1011. X
  1012. Xdef_op('BINARY_MULTIPLY', 20)
  1013. Xdef_op('BINARY_DIVIDE', 21)
  1014. Xdef_op('BINARY_MODULO', 22)
  1015. Xdef_op('BINARY_ADD', 23)
  1016. Xdef_op('BINARY_SUBTRACT', 24)
  1017. Xdef_op('BINARY_SUBSCR', 25)
  1018. Xdef_op('BINARY_CALL', 26)
  1019. X
  1020. Xdef_op('SLICE+0', 30)
  1021. Xdef_op('SLICE+1', 31)
  1022. Xdef_op('SLICE+2', 32)
  1023. Xdef_op('SLICE+3', 33)
  1024. X
  1025. Xdef_op('STORE_SLICE+0', 40)
  1026. Xdef_op('STORE_SLICE+1', 41)
  1027. Xdef_op('STORE_SLICE+2', 42)
  1028. Xdef_op('STORE_SLICE+3', 43)
  1029. X
  1030. Xdef_op('DELETE_SLICE+0', 50)
  1031. Xdef_op('DELETE_SLICE+1', 51)
  1032. Xdef_op('DELETE_SLICE+2', 52)
  1033. Xdef_op('DELETE_SLICE+3', 53)
  1034. X
  1035. Xdef_op('STORE_SUBSCR', 60)
  1036. Xdef_op('DELETE_SUBSCR', 61)
  1037. X
  1038. Xdef_op('PRINT_EXPR', 70)
  1039. Xdef_op('PRINT_ITEM', 71)
  1040. Xdef_op('PRINT_NEWLINE', 72)
  1041. X
  1042. Xdef_op('BREAK_LOOP', 80)
  1043. Xdef_op('RAISE_EXCEPTION', 81)
  1044. Xdef_op('LOAD_LOCALS', 82)
  1045. Xdef_op('RETURN_VALUE', 83)
  1046. Xdef_op('REQUIRE_ARGS', 84)
  1047. Xdef_op('REFUSE_ARGS', 85)
  1048. Xdef_op('BUILD_FUNCTION', 86)
  1049. Xdef_op('POP_BLOCK', 87)
  1050. Xdef_op('END_FINALLY', 88)
  1051. Xdef_op('BUILD_CLASS', 89)
  1052. X
  1053. XHAVE_ARGUMENT = 90        # Opcodes from here have an argument: 
  1054. X
  1055. Xname_op('STORE_NAME', 90)    # Index in name list 
  1056. Xname_op('DELETE_NAME', 91)    # "" 
  1057. Xdef_op('UNPACK_TUPLE', 92)    # Number of tuple items 
  1058. Xdef_op('UNPACK_LIST', 93)    # Number of list items 
  1059. X# unused:        94
  1060. Xname_op('STORE_ATTR', 95)    # Index in name list 
  1061. Xname_op('DELETE_ATTR', 96)    # "" 
  1062. X
  1063. Xdef_op('LOAD_CONST', 100)    # Index in const list 
  1064. Xhasconst.append(100)
  1065. Xname_op('LOAD_NAME', 101)    # Index in name list 
  1066. Xdef_op('BUILD_TUPLE', 102)    # Number of tuple items 
  1067. Xdef_op('BUILD_LIST', 103)    # Number of list items 
  1068. Xdef_op('BUILD_MAP', 104)    # Always zero for now 
  1069. Xname_op('LOAD_ATTR', 105)    # Index in name list 
  1070. Xdef_op('COMPARE_OP', 106)    # Comparison operator 
  1071. Xname_op('IMPORT_NAME', 107)    # Index in name list 
  1072. Xname_op('IMPORT_FROM', 108)    # Index in name list 
  1073. X
  1074. Xjrel_op('JUMP_FORWARD', 110)    # Number of bytes to skip 
  1075. Xjrel_op('JUMP_IF_FALSE', 111)    # "" 
  1076. Xjrel_op('JUMP_IF_TRUE', 112)    # "" 
  1077. Xjabs_op('JUMP_ABSOLUTE', 113)    # Target byte offset from beginning of code 
  1078. Xjrel_op('FOR_LOOP', 114)    # Number of bytes to skip 
  1079. X
  1080. Xjrel_op('SETUP_LOOP', 120)    # Distance to target address
  1081. Xjrel_op('SETUP_EXCEPT', 121)    # ""
  1082. Xjrel_op('SETUP_FINALLY', 122)    # ""
  1083. X
  1084. Xdef_op('SET_LINENO', 127)    # Current line number
  1085. XSET_LINENO = 127
  1086. EOF
  1087. fi
  1088. if test -s 'lib/lambda.py'
  1089. then echo '*** I will not over-write existing file lib/lambda.py'
  1090. else
  1091. echo 'x - lib/lambda.py'
  1092. sed 's/^X//' > 'lib/lambda.py' << 'EOF'
  1093. X# A bit of Lambda Calculus illustrated in Python.
  1094. X#
  1095. X# This does not use Python's built-in 'eval' or 'exec' functions!
  1096. X
  1097. X
  1098. X# Currying
  1099. X#
  1100. X# From a function with 2 args, f(x, y), and a value for the 1st arg,
  1101. X# we can create a new function with one argument fx(y) = f(x, y).
  1102. X# This is called "Currying" (after the idea's inventor, a Mr. Curry).
  1103. X#
  1104. X# To implement this we create a class member, of which fx is a method;
  1105. X# f and x are stored as data attributes of the member.
  1106. X
  1107. Xclass _CurryClass():
  1108. X    def new(self, (f, x)):
  1109. X        self.f = f
  1110. X        self.x = x
  1111. X        return self
  1112. X    def fx(self, y):
  1113. X        return self.f(self.x, y)
  1114. X
  1115. Xdef CURRY(f, x):
  1116. X    # NB: f is not "simple": it has 2 arguments
  1117. X    return _CurryClass().new(f, x).fx
  1118. X
  1119. X
  1120. X# Numbers in Lambda Calculus
  1121. X#
  1122. X# In the lambda calculus, natural numbers are represented by
  1123. X# higher-order functions Ntimes(f, x) that yield f applied N
  1124. X# times to x, e.g., Twice(f, x) = f(f(x)).
  1125. X# As far as I understand, there is no difference in real lambda
  1126. X# calculus between
  1127. X#    lambda f x : f(f(x))
  1128. X# and
  1129. X#    lambda f : f o f    # 'o' means function composition
  1130. X# but in Python we have to write the first as Twice(f, x) and
  1131. X# the second as twice(f).
  1132. X
  1133. Xdef Never(f, x): return x
  1134. Xdef Once(f, x): return f(x)
  1135. Xdef Twice(f, x): return f(f(x))
  1136. Xdef Thrice(f, x): return f(f(f(x)))
  1137. Xdef Fourfold(f, x): return f(f(f(f(x))))
  1138. X# (etc.)
  1139. X
  1140. Xdef never(f): return CURRY(Never, f)
  1141. Xdef once(f): return CURRY(Once, f)
  1142. Xdef twice(f): return CURRY(Twice, f)
  1143. Xdef thrice(f): return CURRY(Thrice, f)
  1144. Xdef fourfold(f): return CURRY(Fourfold, f)
  1145. X# (etc.)
  1146. X
  1147. X
  1148. X# NB: actually 'ntimes' is less concrete than 'Ntimes', as
  1149. X# 'ntimes' returns a function, while 'Ntimes' returns a value
  1150. X# similar to what f(x) returns.  'Ntimes' can be derived
  1151. X# from 'ntimes', as follows:
  1152. X#    def Ntimes(f, x): return ntimes(f)(x)
  1153. X# but this doesn't help us since 'ntimes' can only be defined
  1154. X# using Ntimes (or a trick like the one used by CURRY).
  1155. X
  1156. X
  1157. X# Arithmetic in Lambda Calculus
  1158. X#
  1159. X# We can perform simple arithmetic on the un-curried versions, e.g.,
  1160. X#    Successor(Twice)    = Thrice    (2+1)
  1161. X#    Sum(Thrice, Twice)    = Fivefold    (3+2)
  1162. X#    Product(Thrice, Twice)    = Sixfold    (3*2)
  1163. X#    Power(Thrice, Twice)    = Ninefold    (3**2)
  1164. X#
  1165. X# First we define versions that need f and x arguments.
  1166. X# They have funny argument forms so the final functions can
  1167. X# use CURRY, which only works on functions of exactly 2 arguments.
  1168. X
  1169. Xdef SUCCESSOR(Ntimes, (f, x)): return f(Ntimes(f, x))
  1170. Xdef SUCCESSOR(Ntimes, (f, x)): return Ntimes(f, f(x))    # Same effect
  1171. Xdef SUM(Ntimes, (Mtimes, (f, x))): return Ntimes(f, Mtimes(f, x))
  1172. Xdef PRODUCT(Ntimes, (Mtimes, (f, x))): return Ntimes(CURRY(Mtimes, f), x)
  1173. Xdef POWER(Ntimes, (Mtimes, (f, x))):
  1174. X    return Mtimes(CURRY(CURRY, Ntimes), f)(x)
  1175. X
  1176. Xdef Successor(Ntimes): return CURRY(SUCCESSOR, Ntimes)
  1177. Xdef Sum(Ntimes, Mtimes): return CURRY(CURRY(SUM, Ntimes), Mtimes)
  1178. Xdef Product(Ntimes, Mtimes): return CURRY(CURRY(PRODUCT, Ntimes), Mtimes)
  1179. Xdef Power(Ntimes, Mtimes): return CURRY(CURRY(POWER, Ntimes), Mtimes)
  1180. X
  1181. X
  1182. X# Sorry, I don't have a clue on how to do subtraction or division...
  1183. X
  1184. X
  1185. X# References
  1186. X#
  1187. X# All I know about lambda calculus is from Roger Penrose's
  1188. X# The Emperor's New Mind, Chapter 2.
  1189. X
  1190. X
  1191. X# P.S.: Here is a Lambda function in Python.
  1192. X# It uses 'exec' and expects two strings to describe the arguments
  1193. X# and the function expression.  Example:
  1194. X#    lambda('x', 'x+1')
  1195. X# defines the successor function.
  1196. X
  1197. Xdef lambda(args, expr):
  1198. X    if '\n' in args or '\n' in expr:
  1199. X        raise RuntimeError, 'lambda: no cheating!'
  1200. X    stmt = 'def func(' + args + '): return ' + expr + '\n'
  1201. X    print 'lambda:', stmt,
  1202. X    exec(stmt)
  1203. X    return func
  1204. X
  1205. X
  1206. X# P.P.S.S.: Here is a way to construct Ntimes and ntimes directly.
  1207. X# Example:
  1208. X#    GenericNtimes(4)
  1209. X# is equivalent to Fourfold.
  1210. X
  1211. Xclass _GenericNtimesClass():
  1212. X    def new(self, n):
  1213. X        self.n = n
  1214. X        return self
  1215. X    def Ntimes(self, (f, x)):
  1216. X        n = self.n
  1217. X        while n > 0: x, n = f(x), n-1
  1218. X        return x
  1219. X
  1220. Xdef GenericNtimes(n):
  1221. X    return _GenericNtimesClass().new(n).Ntimes
  1222. X
  1223. X
  1224. X# To construct any 'ntimes' function from the corresponding 'Ntimes',
  1225. X# we use a trick as used by CURRY.  For example,
  1226. X#    Ntimes2ntimes(Fourfold)
  1227. X# yields a function equivalent to fourfold.
  1228. X
  1229. Xclass _Ntimes2ntimesClass():
  1230. X    def new(self, Ntimes):
  1231. X        self.Ntimes = Ntimes
  1232. X        return self
  1233. X    def ntimes(self, f):
  1234. X        return CURRY(self.Ntimes, f)
  1235. X
  1236. Xdef Ntimes2ntimes(Ntimes): return _Ntimes2ntimesClass().new(Ntimes).ntimes
  1237. X
  1238. X
  1239. X# This allows us to construct generic 'ntimes' functions.  Example:
  1240. X#    generic_ntimes(3)
  1241. X# is the same as thrice.
  1242. X
  1243. Xdef generic_ntimes(n): return Ntimes2ntimes(GenericNtimes(n))
  1244. EOF
  1245. fi
  1246. if test -s 'lib/tb.py'
  1247. then echo '*** I will not over-write existing file lib/tb.py'
  1248. else
  1249. echo 'x - lib/tb.py'
  1250. sed 's/^X//' > 'lib/tb.py' << 'EOF'
  1251. X# Print tracebacks, with a dump of local variables.
  1252. X# Also an interactive stack trace browser.
  1253. X
  1254. Ximport sys
  1255. Xtry:
  1256. X    import mac
  1257. X    os = mac
  1258. Xexcept NameError:
  1259. X    import posix
  1260. X    os = posix
  1261. Xfrom stat import *
  1262. Ximport string
  1263. X
  1264. Xdef br(): browser(sys.last_traceback)
  1265. X
  1266. Xdef tb(): printtb(sys.last_traceback)
  1267. X
  1268. Xdef browser(tb):
  1269. X    if not tb:
  1270. X        print 'No traceback.'
  1271. X        return
  1272. X    tblist = []
  1273. X    while tb:
  1274. X        tblist.append(tb)
  1275. X        tb = tb.tb_next
  1276. X    ptr = len(tblist)-1
  1277. X    tb = tblist[ptr]
  1278. X    while 1:
  1279. X        if tb <> tblist[ptr]:
  1280. X            tb = tblist[ptr]
  1281. X            print `ptr` + ':',
  1282. X            printtbheader(tb)
  1283. X        try:
  1284. X            line = raw_input('TB: ')
  1285. X        except KeyboardInterrupt:
  1286. X            print '\n[Interrupted]'
  1287. X            break
  1288. X        except EOFError:
  1289. X            print '\n[EOF]'
  1290. X            break
  1291. X        cmd = string.strip(line)
  1292. X        if cmd:
  1293. X            if cmd = 'quit':
  1294. X                break
  1295. X            elif cmd = 'list':
  1296. X                browserlist(tb)
  1297. X            elif cmd = 'up':
  1298. X                if ptr-1 >= 0: ptr = ptr-1
  1299. X                else: print 'Bottom of stack.'
  1300. X            elif cmd = 'down':
  1301. X                if ptr+1 < len(tblist): ptr = ptr+1
  1302. X                else: print 'Top of stack.'
  1303. X            elif cmd = 'locals':
  1304. X                printsymbols(tb.tb_frame.f_locals)
  1305. X            elif cmd = 'globals':
  1306. X                printsymbols(tb.tb_frame.f_globals)
  1307. X            elif cmd in ('?', 'help'):
  1308. X                browserhelp()
  1309. X            else:
  1310. X                browserexec(tb, cmd)
  1311. X
  1312. Xdef browserlist(tb):
  1313. X    filename = tb.tb_frame.f_code.co_filename
  1314. X    lineno = tb.tb_lineno
  1315. X    last = lineno
  1316. X    first = max(1, last-10)
  1317. X    for i in range(first, last+1):
  1318. X        if i = lineno: prefix = '***' + string.rjust(`i`, 4) + ':'
  1319. X        else: prefix = string.rjust(`i`, 7) + ':'
  1320. X        line = readfileline(filename, i)
  1321. X        if line[-1:] = '\n': line = line[:-1]
  1322. X        print prefix + line
  1323. X
  1324. Xdef browserexec(tb, cmd):
  1325. X    locals = tb.tb_frame.f_locals
  1326. X    globals = tb.tb_frame.f_globals
  1327. X    try:
  1328. X        exec(cmd+'\n', globals, locals)
  1329. X    except:
  1330. X        print '*** Exception:',
  1331. X        print sys.exc_type,
  1332. X        if sys.exc_value <> None:
  1333. X            print ':', sys.exc_value,
  1334. X        print
  1335. X        print 'Type help to get help.'
  1336. X
  1337. Xdef browserhelp():
  1338. X    print
  1339. X    print '    This is the traceback browser.  Commands are:'
  1340. X    print '        up      : move one level up in the call stack'
  1341. X    print '        down    : move one level down in the call stack'
  1342. X    print '        locals  : print all local variables at this level'
  1343. X    print '        globals : print all global variables at this level'
  1344. X    print '        list    : list source code around the failure'
  1345. X    print '        help    : print help (what you are reading now)'
  1346. X    print '        quit    : back to command interpreter'
  1347. X    print '    Typing any other 1-line statement will execute it'
  1348. X    print '    using the current level\'s symbol tables'
  1349. X    print
  1350. X
  1351. Xdef printtb(tb):
  1352. X    while tb:
  1353. X        print1tb(tb)
  1354. X        tb = tb.tb_next
  1355. X
  1356. Xdef print1tb(tb):
  1357. X    printtbheader(tb)
  1358. X    if tb.tb_frame.f_locals is not tb.tb_frame.f_globals:
  1359. X        printsymbols(tb.tb_frame.f_locals)
  1360. X
  1361. Xdef printtbheader(tb):
  1362. X    filename = tb.tb_frame.f_code.co_filename
  1363. X    lineno = tb.tb_lineno
  1364. X    info = '"' + filename + '"(' + `lineno` + ')'
  1365. X    line = readfileline(filename, lineno)
  1366. X    if line:
  1367. X        info = info + ': ' + string.strip(line)
  1368. X    print info
  1369. X
  1370. Xdef printsymbols(d):
  1371. X    keys = d.keys()
  1372. X    keys.sort()
  1373. X    for name in keys:
  1374. X        print '  ' + string.ljust(name, 12) + ':',
  1375. X        printobject(d[name], 4)
  1376. X        print
  1377. X
  1378. Xdef printobject(v, maxlevel):
  1379. X    if v = None:
  1380. X        print 'None',
  1381. X    elif type(v) in (type(0), type(0.0)):
  1382. X        print v,
  1383. X    elif type(v) = type(''):
  1384. X        if len(v) > 20:
  1385. X            print `v[:17] + '...'`,
  1386. X        else:
  1387. X            print `v`,
  1388. X    elif type(v) = type(()):
  1389. X        print '(',
  1390. X        printlist(v, maxlevel)
  1391. X        print ')',
  1392. X    elif type(v) = type([]):
  1393. X        print '[',
  1394. X        printlist(v, maxlevel)
  1395. X        print ']',
  1396. X    elif type(v) = type({}):
  1397. X        print '{',
  1398. X        printdict(v, maxlevel)
  1399. X        print '}',
  1400. X    else:
  1401. X        print v,
  1402. X
  1403. Xdef printlist(v, maxlevel):
  1404. X    n = len(v)
  1405. X    if n = 0: return
  1406. X    if maxlevel <= 0:
  1407. X        print '...',
  1408. X        return
  1409. X    for i in range(min(6, n)):
  1410. X        printobject(v[i], maxlevel-1)
  1411. X        if i+1 < n: print ',',
  1412. X    if n > 6: print '...',
  1413. X
  1414. Xdef printdict(v, maxlevel):
  1415. X    keys = v.keys()
  1416. X    n = len(keys)
  1417. X    if n = 0: return
  1418. X    if maxlevel <= 0:
  1419. X        print '...',
  1420. X        return
  1421. X    keys.sort()
  1422. X    for i in range(min(6, n)):
  1423. X        key = keys[i]
  1424. X        print `key` + ':',
  1425. X        printobject(v[key], maxlevel-1)
  1426. X        if i+1 < n: print ',',
  1427. X    if n > 6: print '...',
  1428. X
  1429. X_filecache = {}
  1430. X
  1431. Xdef readfileline(filename, lineno):
  1432. X    try:
  1433. X        stat = os.stat(filename)
  1434. X    except os.error, msg:
  1435. X        print 'Cannot stat', filename, '--', msg
  1436. X        return ''
  1437. X    cache_ok = 0
  1438. X    if _filecache.has_key(filename):
  1439. X        cached_stat, lines = _filecache[filename]
  1440. X        if stat[ST_SIZE] = cached_stat[ST_SIZE] and \
  1441. X                stat[ST_MTIME] = cached_stat[ST_MTIME]:
  1442. X            cache_ok = 1
  1443. X        else:
  1444. X            print 'Stale cache entry for', filename
  1445. X            del _filecache[filename]
  1446. X    if not cache_ok:
  1447. X        lines = readfilelines(filename)
  1448. X        if not lines:
  1449. X            return ''
  1450. X        _filecache[filename] = stat, lines
  1451. X    if 0 <= lineno-1 < len(lines):
  1452. X        return lines[lineno-1]
  1453. X    else:
  1454. X        print 'Line number out of range, last line is', len(lines)
  1455. X        return ''
  1456. X
  1457. Xdef readfilelines(filename):
  1458. X    try:
  1459. X        fp = open(filename, 'r')
  1460. X    except:
  1461. X        print 'Cannot open', filename
  1462. X        return []
  1463. X    lines = []
  1464. X    while 1:
  1465. X        line = fp.readline()
  1466. X        if not line: break
  1467. X        lines.append(line)
  1468. X    if not lines:
  1469. X        print 'Empty file', filename
  1470. X    return lines
  1471. EOF
  1472. fi
  1473. if test -s 'src/errors.c'
  1474. then echo '*** I will not over-write existing file src/errors.c'
  1475. else
  1476. echo 'x - src/errors.c'
  1477. sed 's/^X//' > 'src/errors.c' << 'EOF'
  1478. X/***********************************************************
  1479. XCopyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
  1480. XNetherlands.
  1481. X
  1482. X                        All Rights Reserved
  1483. X
  1484. XPermission to use, copy, modify, and distribute this software and its 
  1485. Xdocumentation for any purpose and without fee is hereby granted, 
  1486. Xprovided that the above copyright notice appear in all copies and that
  1487. Xboth that copyright notice and this permission notice appear in 
  1488. Xsupporting documentation, and that the names of Stichting Mathematisch
  1489. XCentrum or CWI not be used in advertising or publicity pertaining to
  1490. Xdistribution of the software without specific, written prior permission.
  1491. X
  1492. XSTICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  1493. XTHIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  1494. XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  1495. XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  1496. XWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  1497. XACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  1498. XOF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  1499. X
  1500. X******************************************************************/
  1501. X
  1502. X/* Error handling -- see also run.c */
  1503. X
  1504. X/* New error handling interface.
  1505. X
  1506. X   The following problem exists (existed): methods of built-in modules
  1507. X   are called with 'self' and 'args' arguments, but without a context
  1508. X   argument, so they have no way to raise a specific exception.
  1509. X   The same is true for the object implementations: no context argument.
  1510. X   The old convention was to set 'errno' and to return NULL.
  1511. X   The caller (usually call_function() in eval.c) detects the NULL
  1512. X   return value and then calls puterrno(ctx) to turn the errno value
  1513. X   into a true exception.  Problems with this approach are:
  1514. X   - it used standard errno values to indicate Python-specific errors,
  1515. X     but this means that when such an error code is reported by a system
  1516. X     call (e.g., in module posix), the user gets a confusing message
  1517. X   - errno is a global variable, which makes extensions to a multi-
  1518. X     threading environment difficult; e.g., in IRIX, multi-threaded
  1519. X     programs must use the function oserror() instead of looking in errno
  1520. X   - there is no portable way to add new error numbers for specic
  1521. X     situations -- the value space for errno is reserved to the OS, yet
  1522. X     the way to turn module-specific errors into a module-specific
  1523. X     exception requires module-specific values for errno
  1524. X   - there is no way to add a more situation-specific message to an
  1525. X     error.
  1526. X  
  1527. X  The new interface solves all these problems.  To return an error, a
  1528. X  built-in function calls err_set(exception), err_setval(exception,
  1529. X  value) or err_setstr(exception, string), and returns NULL.  These
  1530. X  functions save the value for later use by puterrno().  To adapt this
  1531. X  scheme to a multi-threaded environment, only the implementation of
  1532. X  err_setval() has to be changed.
  1533. X*/
  1534. X
  1535. X#include "allobjects.h"
  1536. X
  1537. X#include <errno.h>
  1538. X#ifndef errno
  1539. Xextern int errno;
  1540. X#endif
  1541. X
  1542. X#include "errcode.h"
  1543. X
  1544. Xextern char *strerror PROTO((int));
  1545. X
  1546. X/* Last exception stored by err_setval() */
  1547. X
  1548. Xstatic object *last_exception;
  1549. Xstatic object *last_exc_val;
  1550. X
  1551. Xvoid
  1552. Xerr_setval(exception, value)
  1553. X    object *exception;
  1554. X    object *value;
  1555. X{
  1556. X    XDECREF(last_exception);
  1557. X    XINCREF(exception);
  1558. X    last_exception = exception;
  1559. X    
  1560. X    XDECREF(last_exc_val);
  1561. X    XINCREF(value);
  1562. X    last_exc_val = value;
  1563. X}
  1564. X
  1565. Xvoid
  1566. Xerr_set(exception)
  1567. X    object *exception;
  1568. X{
  1569. X    err_setval(exception, (object *)NULL);
  1570. X}
  1571. X
  1572. Xvoid
  1573. Xerr_setstr(exception, string)
  1574. X    object *exception;
  1575. X    char *string;
  1576. X{
  1577. X    object *value = newstringobject(string);
  1578. X    err_setval(exception, value);
  1579. X    XDECREF(value);
  1580. X}
  1581. X
  1582. Xint
  1583. Xerr_occurred()
  1584. X{
  1585. X    return last_exception != NULL;
  1586. X}
  1587. X
  1588. Xvoid
  1589. Xerr_get(p_exc, p_val)
  1590. X    object **p_exc;
  1591. X    object **p_val;
  1592. X{
  1593. X    *p_exc = last_exception;
  1594. X    last_exception = NULL;
  1595. X    *p_val = last_exc_val;
  1596. X    last_exc_val = NULL;
  1597. X}
  1598. X
  1599. Xvoid
  1600. Xerr_clear()
  1601. X{
  1602. X    XDECREF(last_exception);
  1603. X    last_exception = NULL;
  1604. X    XDECREF(last_exc_val);
  1605. X    last_exc_val = NULL;
  1606. X}
  1607. X
  1608. X/* Convenience functions to set a type error exception and return 0 */
  1609. X
  1610. Xint
  1611. Xerr_badarg()
  1612. X{
  1613. X    err_setstr(TypeError, "illegal argument type for built-in operation");
  1614. X    return 0;
  1615. X}
  1616. X
  1617. Xobject *
  1618. Xerr_nomem()
  1619. X{
  1620. X    err_set(MemoryError);
  1621. X    return NULL;
  1622. X}
  1623. X
  1624. Xobject *
  1625. Xerr_errno(exc)
  1626. X    object *exc;
  1627. X{
  1628. X    object *v = newtupleobject(2);
  1629. X    if (v != NULL) {
  1630. X        settupleitem(v, 0, newintobject((long)errno));
  1631. X        settupleitem(v, 1, newstringobject(strerror(errno)));
  1632. X    }
  1633. X    err_setval(exc, v);
  1634. X    XDECREF(v);
  1635. X    return NULL;
  1636. X}
  1637. X
  1638. Xvoid
  1639. Xerr_badcall()
  1640. X{
  1641. X    err_setstr(SystemError, "bad argument to internal function");
  1642. X}
  1643. X
  1644. X/* Set the error appropriate to the given input error code (see errcode.h) */
  1645. X
  1646. Xvoid
  1647. Xerr_input(err)
  1648. X    int err;
  1649. X{
  1650. X    switch (err) {
  1651. X    case E_DONE:
  1652. X    case E_OK:
  1653. X        break;
  1654. X    case E_SYNTAX:
  1655. X        err_setstr(RuntimeError, "syntax error");
  1656. X        break;
  1657. X    case E_TOKEN:
  1658. X        err_setstr(RuntimeError, "illegal token");
  1659. X        break;
  1660. X    case E_INTR:
  1661. X        err_set(KeyboardInterrupt);
  1662. X        break;
  1663. X    case E_NOMEM:
  1664. X        err_nomem();
  1665. X        break;
  1666. X    case E_EOF:
  1667. X        err_set(EOFError);
  1668. X        break;
  1669. X    default:
  1670. X        err_setstr(RuntimeError, "unknown input error");
  1671. X        break;
  1672. X    }
  1673. X}
  1674. EOF
  1675. fi
  1676. if test -s 'src/mathmodule.c'
  1677. then echo '*** I will not over-write existing file src/mathmodule.c'
  1678. else
  1679. echo 'x - src/mathmodule.c'
  1680. sed 's/^X//' > 'src/mathmodule.c' << 'EOF'
  1681. X/***********************************************************
  1682. XCopyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
  1683. XNetherlands.
  1684. X
  1685. X                        All Rights Reserved
  1686. X
  1687. XPermission to use, copy, modify, and distribute this software and its 
  1688. Xdocumentation for any purpose and without fee is hereby granted, 
  1689. Xprovided that the above copyright notice appear in all copies and that
  1690. Xboth that copyright notice and this permission notice appear in 
  1691. Xsupporting documentation, and that the names of Stichting Mathematisch
  1692. XCentrum or CWI not be used in advertising or publicity pertaining to
  1693. Xdistribution of the software without specific, written prior permission.
  1694. X
  1695. XSTICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  1696. XTHIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  1697. XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  1698. XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  1699. XWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  1700. XACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  1701. XOF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  1702. X
  1703. X******************************************************************/
  1704. X
  1705. X/* Math module -- standard C math library functions, pi and e */
  1706. X
  1707. X#include "allobjects.h"
  1708. X
  1709. X#include <errno.h>
  1710. X#ifndef errno
  1711. Xextern int errno;
  1712. X#endif
  1713. X
  1714. X#include "modsupport.h"
  1715. X
  1716. X#include <math.h>
  1717. X
  1718. Xstatic int
  1719. Xgetdoublearg(args, px)
  1720. X    register object *args;
  1721. X    double *px;
  1722. X{
  1723. X    if (args == NULL)
  1724. X        return err_badarg();
  1725. X    if (is_floatobject(args)) {
  1726. X        *px = getfloatvalue(args);
  1727. X        return 1;
  1728. X    }
  1729. X    if (is_intobject(args)) {
  1730. X        *px = getintvalue(args);
  1731. X        return 1;
  1732. X    }
  1733. X    return err_badarg();
  1734. X}
  1735. X
  1736. Xstatic int
  1737. Xget2doublearg(args, px, py)
  1738. X    register object *args;
  1739. X    double *px, *py;
  1740. X{
  1741. X    if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2)
  1742. X        return err_badarg();
  1743. X    return getdoublearg(gettupleitem(args, 0), px) &&
  1744. X        getdoublearg(gettupleitem(args, 1), py);
  1745. X}
  1746. X
  1747. Xstatic object *
  1748. Xmath_1(args, func)
  1749. X    object *args;
  1750. X    double (*func) FPROTO((double));
  1751. X{
  1752. X    double x;
  1753. X    if (!getdoublearg(args, &x))
  1754. X        return NULL;
  1755. X    errno = 0;
  1756. X    x = (*func)(x);
  1757. X    if (errno != 0)
  1758. X        return NULL;
  1759. X    else
  1760. X        return newfloatobject(x);
  1761. X}
  1762. X
  1763. Xstatic object *
  1764. Xmath_2(args, func)
  1765. X    object *args;
  1766. X    double (*func) FPROTO((double, double));
  1767. X{
  1768. X    double x, y;
  1769. X    if (!get2doublearg(args, &x, &y))
  1770. X        return NULL;
  1771. X    errno = 0;
  1772. X    x = (*func)(x, y);
  1773. X    if (errno != 0)
  1774. X        return NULL;
  1775. X    else
  1776. X        return newfloatobject(x);
  1777. X}
  1778. X
  1779. X#define FUNC1(stubname, func) \
  1780. X    static object * stubname(self, args) object *self, *args; { \
  1781. X        return math_1(args, func); \
  1782. X    }
  1783. X
  1784. X#define FUNC2(stubname, func) \
  1785. X    static object * stubname(self, args) object *self, *args; { \
  1786. X        return math_2(args, func); \
  1787. X    }
  1788. X
  1789. XFUNC1(math_acos, acos)
  1790. XFUNC1(math_asin, asin)
  1791. XFUNC1(math_atan, atan)
  1792. XFUNC2(math_atan2, atan2)
  1793. XFUNC1(math_ceil, ceil)
  1794. XFUNC1(math_cos, cos)
  1795. XFUNC1(math_cosh, cosh)
  1796. XFUNC1(math_exp, exp)
  1797. XFUNC1(math_fabs, fabs)
  1798. XFUNC1(math_floor, floor)
  1799. X#if 0
  1800. X/* XXX This one is not in the Amoeba library yet, so what the heck... */
  1801. XFUNC2(math_fmod, fmod)
  1802. X#endif
  1803. XFUNC1(math_log, log)
  1804. XFUNC1(math_log10, log10)
  1805. XFUNC2(math_pow, pow)
  1806. XFUNC1(math_sin, sin)
  1807. XFUNC1(math_sinh, sinh)
  1808. XFUNC1(math_sqrt, sqrt)
  1809. XFUNC1(math_tan, tan)
  1810. XFUNC1(math_tanh, tanh)
  1811. X
  1812. X#if 0
  1813. X/* What about these? */
  1814. Xdouble    frexp(double x, int *i);
  1815. Xdouble    ldexp(double x, int n);
  1816. Xdouble    modf(double x, double *i);
  1817. X#endif
  1818. X
  1819. Xstatic struct methodlist math_methods[] = {
  1820. X    {"acos", math_acos},
  1821. X    {"asin", math_asin},
  1822. X    {"atan", math_atan},
  1823. X    {"atan2", math_atan2},
  1824. X    {"ceil", math_ceil},
  1825. X    {"cos", math_cos},
  1826. X    {"cosh", math_cosh},
  1827. X    {"exp", math_exp},
  1828. X    {"fabs", math_fabs},
  1829. X    {"floor", math_floor},
  1830. X#if 0
  1831. X    {"fmod", math_fmod},
  1832. X    {"frexp", math_freqp},
  1833. X    {"ldexp", math_ldexp},
  1834. X#endif
  1835. X    {"log", math_log},
  1836. X    {"log10", math_log10},
  1837. X#if 0
  1838. X    {"modf", math_modf},
  1839. X#endif
  1840. X    {"pow", math_pow},
  1841. X    {"sin", math_sin},
  1842. X    {"sinh", math_sinh},
  1843. X    {"sqrt", math_sqrt},
  1844. X    {"tan", math_tan},
  1845. X    {"tanh", math_tanh},
  1846. X    {NULL,        NULL}        /* sentinel */
  1847. X};
  1848. X
  1849. Xvoid
  1850. Xinitmath()
  1851. X{
  1852. X    object *m, *d, *v;
  1853. X    
  1854. X    m = initmodule("math", math_methods);
  1855. X    d = getmoduledict(m);
  1856. X    dictinsert(d, "pi", v = newfloatobject(atan(1.0) * 4.0));
  1857. X    DECREF(v);
  1858. X    dictinsert(d, "e", v = newfloatobject(exp(1.0)));
  1859. X    DECREF(v);
  1860. X}
  1861. EOF
  1862. fi
  1863. if test -s 'src/sysmodule.c'
  1864. then echo '*** I will not over-write existing file src/sysmodule.c'
  1865. else
  1866. echo 'x - src/sysmodule.c'
  1867. sed 's/^X//' > 'src/sysmodule.c' << 'EOF'
  1868. X/***********************************************************
  1869. XCopyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
  1870. XNetherlands.
  1871. X
  1872. X                        All Rights Reserved
  1873. X
  1874. XPermission to use, copy, modify, and distribute this software and its 
  1875. Xdocumentation for any purpose and without fee is hereby granted, 
  1876. Xprovided that the above copyright notice appear in all copies and that
  1877. Xboth that copyright notice and this permission notice appear in 
  1878. Xsupporting documentation, and that the names of Stichting Mathematisch
  1879. XCentrum or CWI not be used in advertising or publicity pertaining to
  1880. Xdistribution of the software without specific, written prior permission.
  1881. X
  1882. XSTICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  1883. XTHIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  1884. XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  1885. XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  1886. XWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  1887. XACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  1888. XOF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  1889. X
  1890. X******************************************************************/
  1891. X
  1892. X/* System module */
  1893. X
  1894. X/*
  1895. XVarious bits of information used by the interpreter are collected in
  1896. Xmodule 'sys'.
  1897. XFunction member:
  1898. X- exit(sts): call (C, POSIX) exit(sts)
  1899. XData members:
  1900. X- stdin, stdout, stderr: standard file objects
  1901. X- modules: the table of modules (dictionary)
  1902. X- path: module search path (list of strings)
  1903. X- argv: script arguments (list of strings)
  1904. X- ps1, ps2: optional primary and secondary prompts (strings)
  1905. X*/
  1906. X
  1907. X#include "allobjects.h"
  1908. X
  1909. X#include "sysmodule.h"
  1910. X#include "import.h"
  1911. X#include "modsupport.h"
  1912. X
  1913. X/* Define delimiter used in $PYTHONPATH */
  1914. X
  1915. X#ifdef THINK_C
  1916. X#define DELIM ' '
  1917. X#endif
  1918. X
  1919. X#ifndef DELIM
  1920. X#define DELIM ':'
  1921. X#endif
  1922. X
  1923. Xstatic object *sysdict;
  1924. X
  1925. Xobject *
  1926. Xsysget(name)
  1927. X    char *name;
  1928. X{
  1929. X    return dictlookup(sysdict, name);
  1930. X}
  1931. X
  1932. XFILE *
  1933. Xsysgetfile(name, def)
  1934. X    char *name;
  1935. X    FILE *def;
  1936. X{
  1937. X    FILE *fp = NULL;
  1938. X    object *v = sysget(name);
  1939. X    if (v != NULL)
  1940. X        fp = getfilefile(v);
  1941. X    if (fp == NULL)
  1942. X        fp = def;
  1943. X    return fp;
  1944. X}
  1945. X
  1946. Xint
  1947. Xsysset(name, v)
  1948. X    char *name;
  1949. X    object *v;
  1950. X{
  1951. X    if (v == NULL)
  1952. X        return dictremove(sysdict, name);
  1953. X    else
  1954. X        return dictinsert(sysdict, name, v);
  1955. X}
  1956. X
  1957. Xstatic object *
  1958. Xsys_exit(self, args)
  1959. X    object *self;
  1960. X    object *args;
  1961. X{
  1962. X    int sts;
  1963. X    if (!getintarg(args, &sts))
  1964. X        return NULL;
  1965. X    goaway(sts);
  1966. X    exit(sts); /* Just in case */
  1967. X    /* NOTREACHED */
  1968. X}
  1969. X
  1970. Xstatic struct methodlist sys_methods[] = {
  1971. X    {"exit",    sys_exit},
  1972. X    {NULL,        NULL}        /* sentinel */
  1973. X};
  1974. X
  1975. Xstatic object *sysin, *sysout, *syserr;
  1976. X
  1977. Xvoid
  1978. Xinitsys()
  1979. X{
  1980. X    object *m = initmodule("sys", sys_methods);
  1981. X    sysdict = getmoduledict(m);
  1982. X    INCREF(sysdict);
  1983. X    /* NB keep an extra ref to the std files to avoid closing them
  1984. X       when the user deletes them */
  1985. X    /* XXX File objects should have a "don't close" flag instead */
  1986. X    sysin = newopenfileobject(stdin, "<stdin>", "r");
  1987. X    sysout = newopenfileobject(stdout, "<stdout>", "w");
  1988. X    syserr = newopenfileobject(stderr, "<stderr>", "w");
  1989. X    if (err_occurred())
  1990. X        fatal("can't create sys.std* file objects");
  1991. X    dictinsert(sysdict, "stdin", sysin);
  1992. X    dictinsert(sysdict, "stdout", sysout);
  1993. X    dictinsert(sysdict, "stderr", syserr);
  1994. X    dictinsert(sysdict, "modules", get_modules());
  1995. X    if (err_occurred())
  1996. X        fatal("can't insert sys.* objects in sys dict");
  1997. X}
  1998. X
  1999. Xstatic object *
  2000. Xmakepathobject(path, delim)
  2001. X    char *path;
  2002. X    int delim;
  2003. X{
  2004. X    int i, n;
  2005. X    char *p;
  2006. X    object *v, *w;
  2007. X    
  2008. X    n = 1;
  2009. X    p = path;
  2010. X    while ((p = strchr(p, delim)) != NULL) {
  2011. X        n++;
  2012. X        p++;
  2013. X    }
  2014. X    v = newlistobject(n);
  2015. X    if (v == NULL)
  2016. X        return NULL;
  2017. X    for (i = 0; ; i++) {
  2018. X        p = strchr(path, delim);
  2019. X        if (p == NULL)
  2020. X            p = strchr(path, '\0'); /* End of string */
  2021. X        w = newsizedstringobject(path, (int) (p - path));
  2022. X        if (w == NULL) {
  2023. X            DECREF(v);
  2024. X            return NULL;
  2025. X        }
  2026. X        setlistitem(v, i, w);
  2027. X        if (*p == '\0')
  2028. X            break;
  2029. X        path = p+1;
  2030. X    }
  2031. X    return v;
  2032. X}
  2033. X
  2034. Xvoid
  2035. Xsetpythonpath(path)
  2036. X    char *path;
  2037. X{
  2038. X    object *v;
  2039. X    if ((v = makepathobject(path, DELIM)) == NULL)
  2040. X        fatal("can't create sys.path");
  2041. X    if (sysset("path", v) != 0)
  2042. X        fatal("can't assign sys.path");
  2043. X    DECREF(v);
  2044. X}
  2045. X
  2046. Xstatic object *
  2047. Xmakeargvobject(argc, argv)
  2048. X    int argc;
  2049. X    char **argv;
  2050. X{
  2051. X    object *av;
  2052. X    if (argc < 0 || argv == NULL)
  2053. X        argc = 0;
  2054. X    av = newlistobject(argc);
  2055. X    if (av != NULL) {
  2056. X        int i;
  2057. X        for (i = 0; i < argc; i++) {
  2058. X            object *v = newstringobject(argv[i]);
  2059. X            if (v == NULL) {
  2060. X                DECREF(av);
  2061. X                av = NULL;
  2062. X                break;
  2063. X            }
  2064. X            setlistitem(av, i, v);
  2065. X        }
  2066. X    }
  2067. X    return av;
  2068. X}
  2069. X
  2070. Xvoid
  2071. Xsetpythonargv(argc, argv)
  2072. X    int argc;
  2073. X    char **argv;
  2074. X{
  2075. X    object *av = makeargvobject(argc, argv);
  2076. X    if (av == NULL)
  2077. X        fatal("no mem for sys.argv");
  2078. X    if (sysset("argv", av) != 0)
  2079. X        fatal("can't assign sys.argv");
  2080. X    DECREF(av);
  2081. X}
  2082. EOF
  2083. fi
  2084. if test -s 'src/timemodule.c'
  2085. then echo '*** I will not over-write existing file src/timemodule.c'
  2086. else
  2087. echo 'x - src/timemodule.c'
  2088. sed 's/^X//' > 'src/timemodule.c' << 'EOF'
  2089. X/***********************************************************
  2090. XCopyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
  2091. XNetherlands.
  2092. X
  2093. X                        All Rights Reserved
  2094. X
  2095. XPermission to use, copy, modify, and distribute this software and its 
  2096. Xdocumentation for any purpose and without fee is hereby granted, 
  2097. Xprovided that the above copyright notice appear in all copies and that
  2098. Xboth that copyright notice and this permission notice appear in 
  2099. Xsupporting documentation, and that the names of Stichting Mathematisch
  2100. XCentrum or CWI not be used in advertising or publicity pertaining to
  2101. Xdistribution of the software without specific, written prior permission.
  2102. X
  2103. XSTICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  2104. XTHIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  2105. XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  2106. XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  2107. XWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  2108. XACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  2109. XOF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  2110. X
  2111. X******************************************************************/
  2112. X
  2113. X/* Time module */
  2114. X
  2115. X#include "allobjects.h"
  2116. X
  2117. X#include "modsupport.h"
  2118. X
  2119. X#include "sigtype.h"
  2120. X
  2121. X#include <signal.h>
  2122. X#include <setjmp.h>
  2123. X
  2124. X#ifdef __STDC__
  2125. X#include <time.h>
  2126. X#else /* !__STDC__ */
  2127. Xtypedef unsigned long time_t;
  2128. Xextern time_t time();
  2129. X#endif /* !__STDC__ */
  2130. X
  2131. X
  2132. X/* Time methods */
  2133. X
  2134. Xstatic object *
  2135. Xtime_time(self, args)
  2136. X    object *self;
  2137. X    object *args;
  2138. X{
  2139. X    long secs;
  2140. X    if (!getnoarg(args))
  2141. X        return NULL;
  2142. X    secs = time((time_t *)NULL);
  2143. X    return newintobject(secs);
  2144. X}
  2145. X
  2146. Xstatic jmp_buf sleep_intr;
  2147. X
  2148. Xstatic void
  2149. Xsleep_catcher(sig)
  2150. X    int sig;
  2151. X{
  2152. X    longjmp(sleep_intr, 1);
  2153. X}
  2154. X
  2155. Xstatic object *
  2156. Xtime_sleep(self, args)
  2157. X    object *self;
  2158. X    object *args;
  2159. X{
  2160. X    int secs;
  2161. X    SIGTYPE (*sigsave)();
  2162. X    if (!getintarg(args, &secs))
  2163. X        return NULL;
  2164. X    if (setjmp(sleep_intr)) {
  2165. X        signal(SIGINT, sigsave);
  2166. X        err_set(KeyboardInterrupt);
  2167. X        return NULL;
  2168. X    }
  2169. X    sigsave = signal(SIGINT, SIG_IGN);
  2170. X    if (sigsave != (SIGTYPE (*)()) SIG_IGN)
  2171. X        signal(SIGINT, sleep_catcher);
  2172. X    sleep(secs);
  2173. X    signal(SIGINT, sigsave);
  2174. X    INCREF(None);
  2175. X    return None;
  2176. X}
  2177. X
  2178. X#ifdef THINK_C
  2179. X#define DO_MILLI
  2180. X#endif /* THINK_C */
  2181. X
  2182. X#ifdef AMOEBA
  2183. X#define DO_MILLI
  2184. Xextern long sys_milli();
  2185. X#define millitimer sys_milli
  2186. X#endif /* AMOEBA */
  2187. X
  2188. X#ifdef BSD_TIME
  2189. X#define DO_MILLI
  2190. X#endif /* BSD_TIME */
  2191. X
  2192. X#ifdef DO_MILLI
  2193. X
  2194. Xstatic object *
  2195. Xtime_millisleep(self, args)
  2196. X    object *self;
  2197. X    object *args;
  2198. X{
  2199. X    long msecs;
  2200. X    SIGTYPE (*sigsave)();
  2201. X    if (!getlongarg(args, &msecs))
  2202. X        return NULL;
  2203. X    if (setjmp(sleep_intr)) {
  2204. X        signal(SIGINT, sigsave);
  2205. X        err_set(KeyboardInterrupt);
  2206. X        return NULL;
  2207. X    }
  2208. X    sigsave = signal(SIGINT, SIG_IGN);
  2209. X    if (sigsave != (SIGTYPE (*)()) SIG_IGN)
  2210. X        signal(SIGINT, sleep_catcher);
  2211. X    millisleep(msecs);
  2212. X    signal(SIGINT, sigsave);
  2213. X    INCREF(None);
  2214. X    return None;
  2215. X}
  2216. X
  2217. Xstatic object *
  2218. Xtime_millitimer(self, args)
  2219. X    object *self;
  2220. X    object *args;
  2221. X{
  2222. X    long msecs;
  2223. X    extern long millitimer();
  2224. X    if (!getnoarg(args))
  2225. X        return NULL;
  2226. X    msecs = millitimer();
  2227. X    return newintobject(msecs);
  2228. X}
  2229. X
  2230. X#endif /* DO_MILLI */
  2231. X
  2232. X
  2233. Xstatic struct methodlist time_methods[] = {
  2234. X#ifdef DO_MILLI
  2235. X    {"millisleep",    time_millisleep},
  2236. X    {"millitimer",    time_millitimer},
  2237. X#endif /* DO_MILLI */
  2238. X    {"sleep",    time_sleep},
  2239. X    {"time",    time_time},
  2240. X    {NULL,        NULL}        /* sentinel */
  2241. X};
  2242. X
  2243. X
  2244. Xvoid
  2245. Xinittime()
  2246. X{
  2247. X    initmodule("time", time_methods);
  2248. X}
  2249. X
  2250. X
  2251. X#ifdef THINK_C
  2252. X
  2253. X#define MacTicks    (* (long *)0x16A)
  2254. X
  2255. Xstatic
  2256. Xsleep(msecs)
  2257. X    int msecs;
  2258. X{
  2259. X    register long deadline;
  2260. X    
  2261. X    deadline = MacTicks + msecs * 60;
  2262. X    while (MacTicks < deadline) {
  2263. X        if (intrcheck())
  2264. X            sleep_catcher(SIGINT);
  2265. X    }
  2266. X}
  2267. X
  2268. Xstatic
  2269. Xmillisleep(msecs)
  2270. X    long msecs;
  2271. X{
  2272. X    register long deadline;
  2273. X    
  2274. X    deadline = MacTicks + msecs * 3 / 50; /* msecs * 60 / 1000 */
  2275. X    while (MacTicks < deadline) {
  2276. X        if (intrcheck())
  2277. X            sleep_catcher(SIGINT);
  2278. X    }
  2279. X}
  2280. X
  2281. Xstatic long
  2282. Xmillitimer()
  2283. X{
  2284. X    return MacTicks * 50 / 3; /* MacTicks * 1000 / 60 */
  2285. X}
  2286. X
  2287. X#endif /* THINK_C */
  2288. X
  2289. X
  2290. X#ifdef BSD_TIME
  2291. X
  2292. X#include <sys/types.h>
  2293. X#include <sys/time.h>
  2294. X
  2295. Xstatic long
  2296. Xmillitimer()
  2297. X{
  2298. X    struct timeval t;
  2299. X    struct timezone tz;
  2300. X    if (gettimeofday(&t, &tz) != 0)
  2301. X        return -1;
  2302. X    return t.tv_sec*1000 + t.tv_usec/1000;
  2303. X    
  2304. X}
  2305. X
  2306. Xstatic
  2307. Xmillisleep(msecs)
  2308. X    long msecs;
  2309. X{
  2310. X    struct timeval t;
  2311. X    t.tv_sec = msecs/1000;
  2312. X    t.tv_usec = (msecs%1000)*1000;
  2313. X    (void) select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
  2314. X}
  2315. X
  2316. X#endif /* BSD_TIME */
  2317. X
  2318. EOF
  2319. fi
  2320. if test -s 'src/traceback.c'
  2321. then echo '*** I will not over-write existing file src/traceback.c'
  2322. else
  2323. echo 'x - src/traceback.c'
  2324. sed 's/^X//' > 'src/traceback.c' << 'EOF'
  2325. X/***********************************************************
  2326. XCopyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
  2327. XNetherlands.
  2328. X
  2329. X                        All Rights Reserved
  2330. X
  2331. XPermission to use, copy, modify, and distribute this software and its 
  2332. Xdocumentation for any purpose and without fee is hereby granted, 
  2333. Xprovided that the above copyright notice appear in all copies and that
  2334. Xboth that copyright notice and this permission notice appear in 
  2335. Xsupporting documentation, and that the names of Stichting Mathematisch
  2336. XCentrum or CWI not be used in advertising or publicity pertaining to
  2337. Xdistribution of the software without specific, written prior permission.
  2338. X
  2339. XSTICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  2340. XTHIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  2341. XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  2342. XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  2343. XWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  2344. XACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  2345. XOF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  2346. X
  2347. X******************************************************************/
  2348. X
  2349. X/* Traceback implementation */
  2350. X
  2351. X#include "allobjects.h"
  2352. X
  2353. X#include "compile.h"
  2354. X#include "frameobject.h"
  2355. X#include "traceback.h"
  2356. X#include "structmember.h"
  2357. X
  2358. Xtypedef struct _tracebackobject {
  2359. X    OB_HEAD
  2360. X    struct _tracebackobject *tb_next;
  2361. X    frameobject *tb_frame;
  2362. X    int tb_lasti;
  2363. X    int tb_lineno;
  2364. X} tracebackobject;
  2365. X
  2366. X#define OFF(x) offsetof(tracebackobject, x)
  2367. X
  2368. Xstatic struct memberlist tb_memberlist[] = {
  2369. X    {"tb_next",    T_OBJECT,    OFF(tb_next)},
  2370. X    {"tb_frame",    T_OBJECT,    OFF(tb_frame)},
  2371. X    {"tb_lasti",    T_INT,        OFF(tb_lasti)},
  2372. X    {"tb_lineno",    T_INT,        OFF(tb_lineno)},
  2373. X    {NULL}    /* Sentinel */
  2374. X};
  2375. X
  2376. Xstatic object *
  2377. Xtb_getattr(tb, name)
  2378. X    tracebackobject *tb;
  2379. X    char *name;
  2380. X{
  2381. X    return getmember((char *)tb, tb_memberlist, name);
  2382. X}
  2383. X
  2384. Xstatic void
  2385. Xtb_dealloc(tb)
  2386. X    tracebackobject *tb;
  2387. X{
  2388. X    XDECREF(tb->tb_next);
  2389. X    XDECREF(tb->tb_frame);
  2390. X    DEL(tb);
  2391. X}
  2392. X
  2393. Xstatic typeobject Tracebacktype = {
  2394. X    OB_HEAD_INIT(&Typetype)
  2395. X    0,
  2396. X    "traceback",
  2397. X    sizeof(tracebackobject),
  2398. X    0,
  2399. X    tb_dealloc,    /*tp_dealloc*/
  2400. X    0,        /*tp_print*/
  2401. X    tb_getattr,    /*tp_getattr*/
  2402. X    0,        /*tp_setattr*/
  2403. X    0,        /*tp_compare*/
  2404. X    0,        /*tp_repr*/
  2405. X    0,        /*tp_as_number*/
  2406. X    0,        /*tp_as_sequence*/
  2407. X    0,        /*tp_as_mapping*/
  2408. X};
  2409. X
  2410. X#define is_tracebackobject(v) ((v)->ob_type == &Tracebacktype)
  2411. X
  2412. Xstatic tracebackobject *
  2413. Xnewtracebackobject(next, frame, lasti, lineno)
  2414. X    tracebackobject *next;
  2415. X    frameobject *frame;
  2416. X    int lasti, lineno;
  2417. X{
  2418. X    tracebackobject *tb;
  2419. X    if ((next != NULL && !is_tracebackobject(next)) ||
  2420. X            frame == NULL || !is_frameobject(frame)) {
  2421. X        err_badcall();
  2422. X        return NULL;
  2423. X    }
  2424. X    tb = NEWOBJ(tracebackobject, &Tracebacktype);
  2425. X    if (tb != NULL) {
  2426. X        XINCREF(next);
  2427. X        tb->tb_next = next;
  2428. X        XINCREF(frame);
  2429. X        tb->tb_frame = frame;
  2430. X        tb->tb_lasti = lasti;
  2431. X        tb->tb_lineno = lineno;
  2432. X    }
  2433. X    return tb;
  2434. X}
  2435. X
  2436. Xstatic tracebackobject *tb_current = NULL;
  2437. X
  2438. Xint
  2439. Xtb_here(frame, lasti, lineno)
  2440. X    frameobject *frame;
  2441. X    int lasti;
  2442. X    int lineno;
  2443. X{
  2444. X    tracebackobject *tb;
  2445. X    tb = newtracebackobject(tb_current, frame, lasti, lineno);
  2446. X    if (tb == NULL)
  2447. X        return -1;
  2448. X    XDECREF(tb_current);
  2449. X    tb_current = tb;
  2450. X    return 0;
  2451. X}
  2452. X
  2453. Xobject *
  2454. Xtb_fetch()
  2455. X{
  2456. X    object *v;
  2457. X    v = (object *)tb_current;
  2458. X    tb_current = NULL;
  2459. X    return v;
  2460. X}
  2461. X
  2462. Xint
  2463. Xtb_store(v)
  2464. X    object *v;
  2465. X{
  2466. X    if (v != NULL && !is_tracebackobject(v)) {
  2467. X        err_badcall();
  2468. X        return -1;
  2469. X    }
  2470. X    XDECREF(tb_current);
  2471. X    XINCREF(v);
  2472. X    tb_current = (tracebackobject *)v;
  2473. X    return 0;
  2474. X}
  2475. X
  2476. Xstatic void
  2477. Xtb_displayline(fp, filename, lineno)
  2478. X    FILE *fp;
  2479. X    char *filename;
  2480. X    int lineno;
  2481. X{
  2482. X    FILE *xfp;
  2483. X    char buf[1000];
  2484. X    int i;
  2485. X    if (filename[0] == '<' && filename[strlen(filename)-1] == '>')
  2486. X        return;
  2487. X    xfp = fopen(filename, "r");
  2488. X    if (xfp == NULL) {
  2489. X        fprintf(fp, "    (cannot open \"%s\")\n", filename);
  2490. X        return;
  2491. X    }
  2492. X    for (i = 0; i < lineno; i++) {
  2493. X        if (fgets(buf, sizeof buf, xfp) == NULL)
  2494. X            break;
  2495. X    }
  2496. X    if (i == lineno) {
  2497. X        char *p = buf;
  2498. X        while (*p == ' ' || *p == '\t')
  2499. X            p++;
  2500. X        fprintf(fp, "    %s", p);
  2501. X        if (strchr(p, '\n') == NULL)
  2502. X            fprintf(fp, "\n");
  2503. X    }
  2504. X    fclose(xfp);
  2505. X}
  2506. X
  2507. Xstatic void
  2508. Xtb_printinternal(tb, fp)
  2509. X    tracebackobject *tb;
  2510. X    FILE *fp;
  2511. X{
  2512. X    while (tb != NULL) {
  2513. X        if (intrcheck()) {
  2514. X            fprintf(fp, "[interrupted]\n");
  2515. X            break;
  2516. X        }
  2517. X        fprintf(fp, "  File \"");
  2518. X        printobject(tb->tb_frame->f_code->co_filename, fp, PRINT_RAW);
  2519. X        fprintf(fp, "\", line %d\n", tb->tb_lineno);
  2520. X        tb_displayline(fp,
  2521. X             getstringvalue(tb->tb_frame->f_code->co_filename),
  2522. X                            tb->tb_lineno);
  2523. X        tb = tb->tb_next;
  2524. X    }
  2525. X}
  2526. X
  2527. Xint
  2528. Xtb_print(v, fp)
  2529. X    object *v;
  2530. X    FILE *fp;
  2531. X{
  2532. X    if (v == NULL)
  2533. X        return 0;
  2534. X    if (!is_tracebackobject(v)) {
  2535. X        err_badcall();
  2536. X        return -1;
  2537. X    }
  2538. X    sysset("last_traceback", v);
  2539. X    tb_printinternal((tracebackobject *)v, fp);
  2540. X    return 0;
  2541. X}
  2542. EOF
  2543. fi
  2544. echo 'Part 15 out of 21 of pack.out complete.'
  2545. exit 0
  2546.