home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2804 < 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 12/21
  4. Message-ID: <2974@charon.cwi.nl>
  5. Date: 19 Feb 91 17:42:10 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 12 out of 21:'
  12. if test -s 'demo/sgi/gl_panel/flying/flying.py'
  13. then echo '*** I will not over-write existing file demo/sgi/gl_panel/flying/flying.py'
  14. else
  15. echo 'x - demo/sgi/gl_panel/flying/flying.py'
  16. sed 's/^X//' > 'demo/sgi/gl_panel/flying/flying.py' << 'EOF'
  17. X#! /ufs/guido/bin/sgi/python
  18. X
  19. Xfrom gl import *
  20. Xfrom objdict import *
  21. Xfrom GL import *
  22. Ximport DEVICE, time
  23. Ximport objectdef, light, panel, material
  24. X
  25. Xdef fixmatact (p) :
  26. X    p.diffR.fixact ()
  27. X    p.diffG.fixact ()
  28. X    p.diffB.fixact ()
  29. X    p.specR.fixact ()
  30. X    p.specG.fixact ()
  31. X    p.specB.fixact ()
  32. X    p.shine.fixact ()
  33. X
  34. Xdef fixlichtact (p) :
  35. X    p.R.fixact ()
  36. X    p.G.fixact ()
  37. X    p.B.fixact ()
  38. X    p.X.fixact ()
  39. X    p.Y.fixact ()
  40. X    p.Z.fixact ()
  41. X    p.local.fixact ()
  42. X
  43. Xdef cbsetlight (a) :
  44. X    p = a.back
  45. X    setlight (p, a.label)
  46. X
  47. Xdef cbsetmaterial (a) :
  48. X    p = a.back
  49. X    setmaterial (p, a.label)
  50. X
  51. Xmater = [0]
  52. Xlicht = [0]
  53. X
  54. Xdef setmaterial (p, mname) :
  55. X    #
  56. X    mater [0:1] = [material.materdict [mname]]
  57. X    #
  58. X    p.diffR.val = mater [0][1]
  59. X    p.diffG.val = mater [0][2]
  60. X    p.diffB.val = mater [0][3]
  61. X    #
  62. X    p.specR.val = mater [0][5]
  63. X    p.specG.val = mater [0][6]
  64. X    p.specB.val = mater [0][7]
  65. X    #
  66. X    p.shine.val = mater [0][9] / 128.0
  67. X    fixmatact (p)
  68. X
  69. Xdef setlight (p, mname) :
  70. X    #
  71. X    licht [0:1] = [material.lichtdict [mname]]
  72. X    #
  73. X    p.R.val = licht [0][1]
  74. X    p.G.val = licht [0][2]
  75. X    p.B.val = licht [0][3]
  76. X    #
  77. X    p.X.val = (licht [0][5] + 10.0) / 20.0 
  78. X    p.Y.val = (licht [0][6] + 10.0) / 20.0
  79. X    p.Z.val = (licht [0][7] + 10.0) / 20.0
  80. X    #
  81. X    p.local.val = licht [0][8]
  82. X    #
  83. X    fixlichtact (p)
  84. X
  85. Xdef cbmaterial (a) :
  86. X    #
  87. X    if mater[0] = 0 : return
  88. X    #
  89. X    p = a.back
  90. X    mater [0][5:8] = [p.diffR.val, p.diffG.val, p.diffB.val]
  91. X    mater [0][1:4] = [p.specR.val, p.specG.val, p.specB.val]
  92. X    mater [0][9:10] = [128.0 * p.shine.val]
  93. X    light.bindlight (0)
  94. X
  95. Xdef cblight (a) :
  96. X    #
  97. X    if licht[0] = 0 : return
  98. X    #
  99. X    p = a.back
  100. X    licht [0][1:4] = [p.R.val, p.G.val, p.B.val]
  101. X    licht [0][5:8] = [20.0 * p.X.val - 10.0, 20.0 * p.Y.val - 10.0, 20.0 * p.Z.val - 10.0]
  102. X    if p.local.val = 0.0 :
  103. X        licht [0][8:9] = [0.0]
  104. X    else:
  105. X        licht [0][8:9] = [1.0]
  106. X    #
  107. X    light.bindlight (0)
  108. X
  109. X#
  110. X# initgl : initialize window, pipeline, light, viewing
  111. X#
  112. Xdef initgl () :
  113. X    #
  114. X    # init window
  115. X    #
  116. X    foreground ()
  117. X    keepaspect (1, 1)
  118. X    prefposition (100, 500, 100, 500)
  119. X    w = winopen ('flying objects')
  120. X    keepaspect (1, 1)
  121. X    winconstraints ()
  122. X    #
  123. X    # configure pipline 
  124. X    #
  125. X    doublebuffer ()
  126. X    shademodel (GOURAUD)
  127. X    zbuffer (1)
  128. X    RGBmode ()
  129. X    gconfig ()
  130. X    #
  131. X    # init lighting
  132. X    #
  133. X    light.bindlight (1)
  134. X    #
  135. X    # set viewing
  136. X    #
  137. X    lookat (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0)
  138. X    #
  139. X
  140. X#
  141. X# drawit : draws the object with the given attributes.
  142. X#
  143. X# rfac : the rotation factor.
  144. X# mat  : the material identification
  145. X# attr : a list of attributes : 
  146. X#
  147. X#    [[rotate vector ], [tranlate vector], [scale vector]]
  148. X#    i.e :
  149. X#    [[rX, rY, rZ], [tX, tY, tZ], [sX, sY, sZ]]
  150. X#
  151. Xdef drawit(object, rfac, attr, mat) :
  152. X    pushmatrix()
  153. X    rot (attr[0][0] * float (rfac), 'X')
  154. X    rot (attr[0][1] * float (rfac), 'Y')
  155. X    rot (attr[0][2] * float (rfac), 'Z')
  156. X    translate(attr[1][0], attr[1][1], attr[1][2])
  157. X    scale(attr[2][0], attr[2][1], attr[2][2])
  158. X    lmbind(MATERIAL, mat)
  159. X    objectdef.drawobject(object)
  160. X    popmatrix()
  161. X
  162. Xdef callbacksphere (a) :
  163. X    putDict (objects, 'sphere', int (a.val))
  164. X
  165. Xdef callbackcylinder (a) :
  166. X    putDict (objects, 'cylinder', int (a.val))
  167. X
  168. Xdef callbackcube (a) :
  169. X    putDict (objects, 'cube', int (a.val))
  170. X
  171. Xdef callbackicecream (a) :
  172. X    putDict (objects, 'icecream', int (a.val))
  173. X
  174. Xdef callbackdisk (a) :
  175. X    putDict (objects, 'disk', int (a.val))
  176. X
  177. Xdef callbackdiamond (a) :
  178. X    putDict (objects, 'diamond', int (a.val))
  179. X
  180. Xdef callbackglass (a) :
  181. X    putDict (objects, 'glass', int (a.val))
  182. X
  183. Xdef callbackpyramid (a) :
  184. X    putDict (objects, 'pyramid', int (a.val))
  185. X
  186. Xdef callbacktable (a) :
  187. X    putDict (objects, 'table', int (a.val))
  188. X
  189. Xdef callbackflat (a) :
  190. X    shademodel(FLAT)
  191. X
  192. Xdef callbackgouraud (a) :
  193. X    shademodel(GOURAUD)
  194. X
  195. Xdef callbackwire (a) :
  196. X    objectdef.putFunc ([bgnclosedline, endclosedline])
  197. X
  198. Xdef callbackfilled (a) :
  199. X    objectdef.putFunc ([bgnpolygon, endpolygon])
  200. X
  201. Xdef callbackquit (a) :
  202. X    import sys
  203. X    sys.exit (-1)
  204. X
  205. Xdef allObjects(p, val) :
  206. X    p.sphere.val = val
  207. X    p.sphere.fixact ()
  208. X    p.cube.val = val
  209. X    p.cube.fixact ()
  210. X    p.cylinder.val = val
  211. X    p.cylinder.fixact ()
  212. X    p.pyramid.val = val
  213. X    p.pyramid.fixact ()
  214. X    p.disk.val = val
  215. X    p.disk.fixact ()
  216. X    p.diamond.val = val
  217. X    p.diamond.fixact ()
  218. X    p.icecream.val = val
  219. X    p.icecream.fixact ()
  220. X    p.table.val = val
  221. X    p.table.fixact ()
  222. X    p.fixpanel()
  223. X    
  224. X
  225. Xdef callbackshowall (a) :
  226. X    #print objects
  227. X    for key in objects.keys () :
  228. X        #print key
  229. X        putDict (objects, key, 1)
  230. X    allObjects (a.back, 1.0)
  231. X
  232. Xdef callbackshownone (a) :
  233. X    for key in objects.keys () :
  234. X        putDict (objects, key, 0)
  235. X    allObjects (a.back, 0.0)
  236. X
  237. X#
  238. X# main : makeobjects, initialze graphics, and loop continuously.
  239. X#
  240. Xdef main () :
  241. X    #
  242. X    # iter keeps track of the iterations. It is used as the 
  243. X    # (x, y, z) rotation increments to which the objects rotate.
  244. X    iter = 0
  245. X    #
  246. X    # make the objects. the objects are put in the odict dictionary
  247. X    #
  248. X    od =  objectdef.makeobjects ()
  249. X    #
  250. X    # initialize gl
  251. X    #
  252. X    initgl ()
  253. X    #
  254. X    # initialize time and iterations per second
  255. X    #
  256. X    time0 = time.time () # epoch-time of previous second
  257. X    fps = 0 # frames per second
  258. X    #
  259. X    # initialize panels
  260. X    #
  261. X    panel.needredraw()
  262. X    panels = panel.defpanellist('flying.s') #XXX
  263. X    p = panels[0]
  264. X    p.sphere.upfunc = callbacksphere
  265. X    p.cylinder.upfunc = callbackcylinder
  266. X    p.cube.upfunc = callbackcube
  267. X    p.icecream.upfunc = callbackicecream
  268. X    p.disk.upfunc = callbackdisk
  269. X    p.diamond.upfunc = callbackdiamond
  270. X    # NOT YET IMPLEMENTED  p.glass.upfunc = callbackglass
  271. X    p.pyramid.upfunc = callbackpyramid
  272. X    p.table.upfunc = callbacktable
  273. X    p.wire.upfunc = callbackwire
  274. X    p.filled.upfunc = callbackfilled
  275. X    p.flat.upfunc = callbackflat
  276. X    p.gouraud.upfunc = callbackgouraud
  277. X    p.quit.upfunc = callbackquit
  278. X    p.showall.upfunc = callbackshowall
  279. X    p.shownone.upfunc = callbackshownone
  280. X    p.showall.back = p
  281. X    p.shownone.back = p
  282. X    #
  283. X    qanels = panel.defpanellist('freeze.s') #XXX
  284. X    q = qanels[0]
  285. X    #
  286. X    ranels = panel.defpanellist('materials.s') #XXX
  287. X    r = ranels[0]
  288. X    r.m9.upfunc = cbsetmaterial
  289. X    r.m8.upfunc = cbsetmaterial
  290. X    r.m7.upfunc = cbsetmaterial
  291. X    r.m6.upfunc = cbsetmaterial
  292. X    r.m5.upfunc = cbsetmaterial
  293. X    r.m4.upfunc = cbsetmaterial
  294. X    r.m3.upfunc = cbsetmaterial
  295. X    r.m2.upfunc = cbsetmaterial
  296. X    r.m1.upfunc = cbsetmaterial
  297. X    r.specR.activefunc = cbmaterial
  298. X    r.specG.activefunc = cbmaterial
  299. X    r.specB.activefunc = cbmaterial
  300. X    r.diffR.activefunc = cbmaterial
  301. X    r.diffG.activefunc = cbmaterial
  302. X    r.diffB.activefunc = cbmaterial
  303. X    r.shine.activefunc = cbmaterial
  304. X    r.m9.back = r
  305. X    r.m8.back = r
  306. X    r.m7.back = r
  307. X    r.m6.back = r
  308. X    r.m5.back = r
  309. X    r.m4.back = r
  310. X    r.m3.back = r
  311. X    r.m2.back = r
  312. X    r.m1.back = r
  313. X    r.diffR.back = r
  314. X    r.diffG.back = r
  315. X    r.diffB.back = r
  316. X    r.specR.back = r
  317. X    r.specG.back = r
  318. X    r.specB.back = r
  319. X    r.shine.back = r
  320. X    #
  321. X    sanels = panel.defpanellist('light.s') #XXX
  322. X    s = sanels[0]
  323. X    s.X.back = s
  324. X    s.Y.back = s
  325. X    s.Z.back = s
  326. X    s.R.back = s
  327. X    s.G.back = s
  328. X    s.B.back = s
  329. X    s.light1.back = s
  330. X    s.light2.back = s
  331. X    s.local.back = s
  332. X    s.light1.upfunc = cbsetlight
  333. X    s.light2.upfunc = cbsetlight
  334. X    s.R.activefunc = cblight
  335. X    s.G.activefunc = cblight
  336. X    s.B.activefunc = cblight
  337. X    s.X.activefunc = cblight
  338. X    s.Y.activefunc = cblight
  339. X    s.Z.activefunc = cblight
  340. X    #
  341. X    while 1 :
  342. X        #
  343. X        act = panel.dopanel()
  344. X        #
  345. X        wid =  panel.userredraw ()
  346. X        if wid :
  347. X            winset (wid)
  348. X            reshapeviewport()
  349. X        #
  350. X        # increment iter
  351. X        #
  352. X        if int (q.freeze.val) = 0 :
  353. X            iter = iter +  1
  354. X            fps = fps + 1
  355. X            if time.time() - time0 >= 1 :
  356. X                f = float(fps)/float(time.time()-time0)
  357. X                q.mystrip.val = f
  358. X                q.mystrip.fixact ()
  359. X                q.fixpanel()
  360. X                time0 = time.time()
  361. X                fps = 0
  362. X        #
  363. X        # clear the zbuffer and make the background light blue
  364. X        #
  365. X        zclear()
  366. X        c3i (LightBlue)
  367. X        clear()
  368. X        #
  369. X        # for each object in the objects dictionary
  370. X        #
  371. X        for key in objects.keys() :
  372. X            #
  373. X            # if the object should be displayed
  374. X            #
  375. X            if getDict (objects, key, 0) = ONE :
  376. X                loo = getDict (objects, key, 1)
  377. X                for o in loo :
  378. X                    #
  379. X                    # get attributes and materail
  380. X                    #
  381. X                    attr = o [1]
  382. X                    mat  = o [2]
  383. X                    #
  384. X                    #  display the object
  385. X                    #
  386. X                    drawit(od[o[0]],iter,attr,mat)
  387. X        #
  388. X        swapbuffers()
  389. X        #
  390. X
  391. Xmain()
  392. EOF
  393. chmod +x 'demo/sgi/gl_panel/flying/flying.py'
  394. fi
  395. if test -s 'lib/adv.py'
  396. then echo '*** I will not over-write existing file lib/adv.py'
  397. else
  398. echo 'x - lib/adv.py'
  399. sed 's/^X//' > 'lib/adv.py' << 'EOF'
  400. X#! /ufs/guido/bin/sgi/python
  401. X
  402. X# Module 'adv' -- text-oriented adventure game.
  403. X
  404. X
  405. X# Name a constant that may once appear in the language...
  406. X
  407. Xdef return_nil(): return
  408. Xnil = return_nil()
  409. X
  410. X
  411. X# Copy of string.split() (to avoid loading all of string.py)
  412. X
  413. Xwhitespace = ' \t\n'
  414. Xdef split(s):
  415. X    res = []
  416. X    i, n = 0, len(s)
  417. X    while i < n:
  418. X        while i < n and s[i] in whitespace: i = i+1
  419. X        if i = n: break
  420. X        j = i
  421. X        while j < n and s[j] not in whitespace: j = j+1
  422. X        res.append(s[i:j])
  423. X        i = j
  424. X    return res
  425. X
  426. X
  427. X# Constants to name directions
  428. X
  429. XN = 'north'
  430. XS = 'south'
  431. XW = 'west'
  432. XE = 'east'
  433. XU = 'up'
  434. XD = 'down'
  435. XNW = 'nw'
  436. XNE = 'ne'
  437. XSW = 'sw'
  438. XSE = 'se'
  439. X
  440. X
  441. X# Constants to name other commands
  442. X
  443. XINVENT = 'invent'
  444. XLOOK = 'look'
  445. XBACK = 'back'
  446. XHELP = 'help'
  447. XGET = 'get'
  448. XPUT = 'put'
  449. X
  450. X
  451. X# Aliases recognized by the parser
  452. X
  453. Xalias = {}
  454. Xalias['n'] = N
  455. Xalias['s'] = S
  456. Xalias['e'] = E
  457. Xalias['w'] = W
  458. Xalias['u'] = U
  459. Xalias['d'] = D
  460. Xalias['i'] = INVENT
  461. Xalias['l'] = LOOK
  462. Xalias['b'] = BACK
  463. Xalias['take'] = GET
  464. Xalias['drop'] = PUT
  465. X
  466. X
  467. X# Normalize a command, in place: truncate words to 6 chars, and expand aliases.
  468. X
  469. Xdef normalize(cmd):
  470. X    for i in range(len(cmd)):
  471. X        word = cmd[i][:6]
  472. X        if alias.has_key(word):
  473. X            word = alias[word]
  474. X        cmd[i] = word
  475. X
  476. X
  477. X# The Object class describes objects that the player can carry around.
  478. X
  479. Xclass Object():
  480. X    def init(this, name):
  481. X        this.name = name
  482. X        return this
  483. X    def describe(this):
  484. X        print 'A', this.name + '.'
  485. X    def get(this, (player, room)):
  486. X        del room.objects[this.name]
  487. X        player.objects[this.name] = this
  488. X    def put(this, (player, room)):
  489. X        del player.objects[this.name]
  490. X        room.objects[this.name] = this
  491. X
  492. X
  493. X# The Player class embodies first person control.
  494. X
  495. Xclass Player():
  496. X    # Set initial state, except current room.
  497. X    def init(self, initial_room):
  498. X        self.blind = 0
  499. X        self.here = initial_room
  500. X        self.prev = nil
  501. X        self.objects = {}
  502. X        return self
  503. X    # Read and execute commands forever.
  504. X    def play(self):
  505. X        self.here.casualdescribe()
  506. X        while 1:
  507. X            self.move()
  508. X    # Read and execute one command.
  509. X    def move(self):
  510. X        next = self.here.parser()
  511. X        if next and next <> self.here:
  512. X            self.prev = self.here
  513. X            self.here = next
  514. X            if not self.blind:
  515. X                self.here.casualdescribe()
  516. X    # Print inventory.
  517. X    def inventory(self):
  518. X        if not self.objects:
  519. X            print 'You aren\'t carrying anything.'
  520. X            return
  521. X        print 'You are carrying:'
  522. X        for key in self.objects.keys():
  523. X            self.objects[key].describe()
  524. X    # Go back to previous room.
  525. X    def back(self):
  526. X        if self.prev: return self.prev
  527. X        print 'You can\'t go back now.'
  528. X    # Get an object from the room.
  529. X    def get(self, name):
  530. X        if self.here.objects.has_key(name):
  531. X            self.here.objects[name].get(self, self.here)
  532. X        else:
  533. X            print 'I see no', name, 'here.'
  534. X    # Put an object in the room.
  535. X    def put(self, name):
  536. X        if self.objects.has_key(name):
  537. X            self.objects[name].put(self, self.here)
  538. X        else:
  539. X            print 'You have no', name, 'with you.'
  540. X
  541. X
  542. X# The Room class describes a generic room.
  543. X# Rooms with special properties are defined by derived classes
  544. X# that override certain operations.
  545. X
  546. Xclass Room():
  547. X    # Initialize a featureless room.
  548. X    def init(here, name):
  549. X        here.seen = 0
  550. X        here.name = name
  551. X        here.exits = {}
  552. X        here.objects = {}
  553. X        here.description = []
  554. X        return here
  555. X    # Add an object to the room.  Used during initialization.
  556. X    def add(here, obj):
  557. X        here.objects[obj.name] = obj
  558. X    # Print a casual description.
  559. X    def casualdescribe(here):
  560. X        if here.seen:
  561. X            print here.name + '.'
  562. X            here.listobjects()
  563. X            return
  564. X        here.seen = 1
  565. X        here.describe()
  566. X    # Print a full description, including all exits and objects seen.
  567. X    def describe(here):
  568. X        if not here.description:
  569. X            print here.name + '.'
  570. X            here.listexits()
  571. X        else:
  572. X            for line in here.description: print line
  573. X        here.listobjects()
  574. X    # List exits.
  575. X    def listexits(here):
  576. X        there = here.exits.keys()
  577. X        if there:
  578. X            if len(there) = 1:
  579. X                print 'There is an exit leading',
  580. X            else:
  581. X                print 'There are exits leading',
  582. X                for name in there[:-2]:
  583. X                    print name + ',',
  584. X                print there[len(there)-2], 'and',
  585. X            print there[len(there)-1] + '.'
  586. X    # List objects
  587. X    def listobjects(here):
  588. X        if here.objects:
  589. X            print 'I see:'
  590. X            for key in here.objects.keys():
  591. X                here.objects[key].describe()
  592. X    # Default parser.  Returns next room (possibly the same) or nil.
  593. X    def parser(here):
  594. X        cmd = here.getcmd(here.prompt())
  595. X        return here.decide(cmd)
  596. X    # Return default prompt string.
  597. X    def prompt(here): return '> '
  598. X    # Default input routine.  Returns a non-empty list of words.
  599. X    def getcmd(here, prompt):
  600. X        # Loop until non-empty command gotten
  601. X        # EOFError and KeyboardInterrupt may be caught elsewhere
  602. X        while 1:
  603. X            line = raw_input(prompt)
  604. X            cmd = split(line)
  605. X            if cmd:
  606. X                normalize(cmd)
  607. X                return cmd
  608. X    # Default decision routine.  Override for room-specific commands.
  609. X    def decide(here, cmd):
  610. X        key, args = cmd[0], cmd[1:]
  611. X        if not args:
  612. X            if key = N:        return here.north()
  613. X            if key = S:        return here.south()
  614. X            if key = E:        return here.east()
  615. X            if key = W:        return here.west()
  616. X            if key = U:        return here.up()
  617. X            if key = D:        return here.down()
  618. X            if key = NW:        return here.nw()
  619. X            if key = NE:        return here.ne()
  620. X            if key = SW:        return here.sw()
  621. X            if key = SE:        return here.se()
  622. X            if key = LOOK:        return here.look()
  623. X            if key = INVENT:    return here.inventory()
  624. X            if key = BACK:        return here.back()
  625. X            if here.objects.has_key(key):
  626. X                print 'What do you want to do with the', key+'?'
  627. X            else:
  628. X                print 'Huh?'
  629. X            return
  630. X        if key = GET:
  631. X            for arg in args:
  632. X                player.get(arg)
  633. X            return
  634. X        if key = PUT:
  635. X            for arg in args:
  636. X                player.put(arg)
  637. X    # Standard commands.
  638. X    def look(here):
  639. X        here.describe()
  640. X    def inventory(here):
  641. X        player.inventory()
  642. X    def back(here):
  643. X        return player.back()
  644. X    # Standard exits.
  645. X    def north(here):    return here.take_exit(N)
  646. X    def south(here):    return here.take_exit(S)
  647. X    def west(here):        return here.take_exit(W)
  648. X    def east(here):        return here.take_exit(E)
  649. X    def up(here):        return here.take_exit(U)
  650. X    def down(here):        return here.take_exit(D)
  651. X    def nw(here):        return here.take_exit(NW)
  652. X    def ne(here):        return here.take_exit(NE)
  653. X    def sw(here):        return here.take_exit(SW)
  654. X    def se(here):        return here.take_exit(SE)
  655. X    # Subroutine for standard exits.
  656. X    def take_exit(here, key):
  657. X        if here.exits.has_key(key):
  658. X            return here.exits[key]
  659. X        print 'You cannot go in that direction.'
  660. X        return here
  661. X
  662. X
  663. X# Create the objects we know about.
  664. X# Object names begin with 'o_'.
  665. X
  666. Xo_lamp = Object().init('lamp')
  667. Xo_python = Object().init('python')
  668. X
  669. X
  670. X# Subroutine to connect two rooms.
  671. X
  672. Xdef connect(rm1, rm2, dir1, dir2):
  673. X    if dir1:
  674. X        rm1.exits[dir1] = rm2
  675. X    if dir2:
  676. X        rm2.exits[dir2] = rm1
  677. X
  678. X
  679. X# Create the rooms and connect them together.
  680. X# Room names begin with 'r_'.
  681. X
  682. Xr_front = Room().init('Front of building')
  683. Xr_initial = r_front
  684. Xr_front.description = [ \
  685. X    'You are standing in front of a large, desolate building.', \
  686. X    'Huge neon letters spell "CWI".  The "I" is blinking.', \
  687. X    'There are entrances north and west from where you are standing.', \
  688. X    ]
  689. X
  690. Xr_entrance = Room().init('Entrance')
  691. Xr_entrance.description = [ \
  692. X    'You are standing in a small entrance room.', \
  693. X    'On the east side is a window to a reception room.', \
  694. X    'South is a door leading outside the building.', \
  695. X    'North is a large hall.' \
  696. X    ] 
  697. X
  698. Xr_hall_s = Room().init('South of hall')
  699. Xr_hall_s.description = [ \
  700. X    'You are standing at the south side of a very large hall.', \
  701. X    'There are doors leading west, southwest, south and southeast,', \
  702. X    'and a corridor leads east.', \
  703. X    'The hall continues to the north.' \
  704. X    ]
  705. X
  706. Xr_hall_n = Room().init('North of hall')
  707. Xr_hall_n.description = [ \
  708. X    'You are stanting at the north side of a very large hall.', \
  709. X    'There are corridors leading west, northwest, northeast,', \
  710. X    'an elevator door north, and a door leading outside east.', \
  711. X    'There are stairs leading up, and the hall continues to the south.' \
  712. X    ]
  713. X
  714. Xr_reception = Room().init('Reception')
  715. X
  716. Xr_mail = Room().init('Mail room')
  717. X
  718. Xconnect(r_front, r_entrance, N, S)
  719. Xconnect(r_entrance, r_hall_s, N, SW)
  720. Xconnect(r_hall_s, r_hall_n, N, S)
  721. Xconnect(r_hall_s, r_reception, S, N)
  722. Xconnect(r_hall_s, r_mail, SE, N)
  723. Xconnect(r_reception, r_mail, E, W)
  724. X
  725. Xr_aud_front = Room().init('Front of Auditorium')
  726. Xr_aud_back = Room().init('Back of Auditorium')
  727. Xr_aud_tech = Room().init('Technician\'s room in Auditorium')
  728. Xr_aud_proj = Room().init('Projection room in Auditorium')
  729. X
  730. Xconnect(r_aud_front, r_hall_s, E, W)
  731. Xconnect(r_aud_front, r_aud_back, S, N)
  732. Xconnect(r_aud_back, r_aud_proj, SE, N)
  733. Xconnect(r_aud_front, r_aud_tech, W, E)
  734. X
  735. Xr_floor1 = Room().init('First floor')
  736. Xr_floor2 = Room().init('Second floor')
  737. Xr_floor3 = Room().init('Third floor')
  738. X
  739. Xconnect(r_hall_n, r_floor1, U, D)
  740. Xconnect(r_floor1, r_floor2, U, D)
  741. Xconnect(r_floor2, r_floor3, U, D)
  742. X
  743. X
  744. X# Drop objects here and there
  745. X
  746. Xr_aud_proj.add(o_python)
  747. Xr_reception.add(o_lamp)
  748. X
  749. X# Create an uninitialized player object.
  750. X# It is initialized by main(), but must be created here (as global)
  751. X# since some Room methods reference it.  (Though maybe they shouldn't?)
  752. X
  753. Xplayer = Player()
  754. X
  755. X
  756. X# Play the game from the beginning.
  757. X
  758. Xdef main():
  759. X    x = player.init(r_initial)
  760. X    try:
  761. X        player.play()
  762. X    except (EOFError, KeyboardInterrupt):
  763. X        pass
  764. X
  765. Xmain()
  766. EOF
  767. fi
  768. if test -s 'lib/cmpcache.py'
  769. then echo '*** I will not over-write existing file lib/cmpcache.py'
  770. else
  771. echo 'x - lib/cmpcache.py'
  772. sed 's/^X//' > 'lib/cmpcache.py' << 'EOF'
  773. X# Module 'cmpcache'
  774. X#
  775. X# Efficiently compare files, boolean outcome only (equal / not equal).
  776. X#
  777. X# Tricks (used in this order):
  778. X#    - Use the statcache module to avoid statting files more than once
  779. X#    - Files with identical type, size & mtime are assumed to be clones
  780. X#    - Files with different type or size cannot be identical
  781. X#    - We keep a cache of outcomes of earlier comparisons
  782. X#    - We don't fork a process to run 'cmp' but read the files ourselves
  783. X
  784. Ximport posix
  785. Xfrom stat import *
  786. Ximport statcache
  787. X
  788. X
  789. X# The cache.
  790. X#
  791. Xcache = {}
  792. X
  793. X
  794. X# Compare two files, use the cache if possible.
  795. X# May raise posix.error if a stat or open of either fails.
  796. X#
  797. Xdef cmp(f1, f2):
  798. X    # Return 1 for identical files, 0 for different.
  799. X    # Raise exceptions if either file could not be statted, read, etc.
  800. X    s1, s2 = sig(statcache.stat(f1)), sig(statcache.stat(f2))
  801. X    if not S_ISREG(s1[0]) or not S_ISREG(s2[0]):
  802. X        # Either is a not a plain file -- always report as different
  803. X        return 0
  804. X    if s1 = s2:
  805. X        # type, size & mtime match -- report same
  806. X        return 1
  807. X    if s1[:2] <> s2[:2]: # Types or sizes differ, don't bother
  808. X        # types or sizes differ -- report different
  809. X        return 0
  810. X    # same type and size -- look in the cache
  811. X    key = f1 + ' ' + f2
  812. X    if cache.has_key(key):
  813. X        cs1, cs2, outcome = cache[key]
  814. X        # cache hit
  815. X        if s1 = cs1 and s2 = cs2:
  816. X            # cached signatures match
  817. X            return outcome
  818. X        # stale cached signature(s)
  819. X    # really compare
  820. X    outcome = do_cmp(f1, f2)
  821. X    cache[key] = s1, s2, outcome
  822. X    return outcome
  823. X
  824. X# Return signature (i.e., type, size, mtime) from raw stat data.
  825. X#
  826. Xdef sig(st):
  827. X    return S_IFMT(st[ST_MODE]), st[ST_SIZE], st[ST_MTIME]
  828. X
  829. X# Compare two files, really.
  830. X#
  831. Xdef do_cmp(f1, f2):
  832. X    #print '    cmp', f1, f2 # XXX remove when debugged
  833. X    bufsize = 8096 # Could be tuned
  834. X    fp1 = open(f1, 'r')
  835. X    fp2 = open(f2, 'r')
  836. X    while 1:
  837. X        b1 = fp1.read(bufsize)
  838. X        b2 = fp2.read(bufsize)
  839. X        if b1 <> b2: return 0
  840. X        if not b1: return 1
  841. EOF
  842. fi
  843. if test -s 'lib/macshell.py'
  844. then echo '*** I will not over-write existing file lib/macshell.py'
  845. else
  846. echo 'x - lib/macshell.py'
  847. sed 's/^X//' > 'lib/macshell.py' << 'EOF'
  848. X# Macintosh 'shell'
  849. X# vi:set tabsize=4:
  850. X
  851. X# XXX string quoting in arguments
  852. X# XXX directory stack
  853. X# XXX $macros?
  854. X# XXX ^C during any command
  855. X# XXX 'sh' builtin command?
  856. X# XXX why does open require absolute path? (need to fix chdir.c)
  857. X
  858. X
  859. Ximport mac
  860. X
  861. Ximport macpath
  862. Ximport string
  863. Ximport glob
  864. Xfrom macpath import isfile, isdir, exists
  865. Ximport TclUtil # For splitting/quoting mechanisms
  866. X
  867. Xclass Struct(): pass
  868. XG = Struct()
  869. X
  870. Xdef reset():
  871. X    G.debug = 0
  872. X    G.ps1 = '$ '
  873. X    G.homedir = mac.getcwd()
  874. X    G.commands = mkcmdtab()
  875. X    G.aliases = {}
  876. X
  877. Xdef mkcmdtab():
  878. X    tab = {}
  879. X    tab['alias'] = do_alias
  880. X    tab['cd'] = do_cd
  881. X    tab['debug'] = do_debug
  882. X    tab['grep'] = do_grep
  883. X    tab['help'] = do_help
  884. X    tab['ls'] = do_ls
  885. X    tab['mkdir'] = do_mkdir
  886. X    tab['mv'] = do_mv
  887. X    tab['page'] = do_page
  888. X    tab['pwd'] = do_pwd
  889. X    tab['reset'] = do_reset
  890. X    tab['rm'] = do_rm
  891. X    tab['rmdir'] = do_rmdir
  892. X    tab['sync'] = do_sync
  893. X    tab['unalias'] = do_unalias
  894. X    return tab
  895. X
  896. Xdef main():
  897. X    while 1:
  898. X        try:
  899. X            line = raw_input(G.ps1)
  900. X        except EOFError:
  901. X            print '[EOF]'
  902. X            break
  903. X        except KeyboardInterrupt:
  904. X            print '[Intr]'
  905. X            line = ''
  906. X        if G.debug:
  907. X            print 'line:', `line`
  908. X        words = TclUtil.SplitList(line)
  909. X        if G.debug:
  910. X            print 'words:', words
  911. X        if words and words[0][0] <> '#':
  912. X            run(words)
  913. X
  914. Xdef run(words):
  915. X    expandaliases(words)
  916. X    cmd = words[0]
  917. X    args = words[1:]
  918. X    if G.commands.has_key(cmd):
  919. X        if args:
  920. X            try:
  921. X                args = expandgloblist(args)
  922. X            except glob_error, msg:
  923. X                print cmd, ': glob error :', msg
  924. X                return
  925. X        G.commands[cmd](args)
  926. X        return
  927. X    if hasglobchar(cmd):
  928. X        if args:
  929. X            print cmd, ': cannot glob pattern with arguments'
  930. X            return
  931. X        try:
  932. X            words = expandglobword(cmd)
  933. X        except glob_error, msg:
  934. X            print cmd, ': glob error :', msg
  935. X            return
  936. X        if len(words) > 1:
  937. X            columnize(words)
  938. X            return
  939. X        cmd = words[0]
  940. X        print cmd
  941. X    if isfile(cmd):
  942. X        if args:
  943. X            print cmd, ': file command expects no arguments'
  944. X            return
  945. X        do_page([cmd])
  946. X    elif isdir(cmd):
  947. X        if args:
  948. X            print cmd, ': directory command expects no arguments'
  949. X            return
  950. X        do_cd([cmd])
  951. X    else:
  952. X        print cmd, ': no such command, file or directory'
  953. X
  954. Xglob_error = 'glob error'
  955. X
  956. Xdef expandgloblist(words):
  957. X    res = []
  958. X    for word in words:
  959. X        if hasglobchar(word):
  960. X            res = res + expandglobword(word)
  961. X        else:
  962. X            res.append(word)
  963. X    return res
  964. X
  965. Xdef expandglobword(word):
  966. X    names = glob.globlist(mac.listdir(':'), word)
  967. X    if not names: raise glob_error, 'no match for pattern ' + word
  968. X    return names
  969. X
  970. Xdef hasglobchar(word):
  971. X    return '*' in word or '?' in word
  972. X
  973. Xdef expandaliases(words):
  974. X    seen = []
  975. X    cmd = words[0]
  976. X    while cmd not in seen and G.aliases.has_key(cmd):
  977. X        seen.append(cmd)
  978. X        words[:1] = G.aliases[cmd]
  979. X        cmd = words[0]
  980. X
  981. Xdef do_alias(args):
  982. X    if not args:
  983. X        listaliases()
  984. X    elif len(args) = 1:
  985. X        listalias(args[0])
  986. X    else:
  987. X        defalias(args[0], args[1:])
  988. X
  989. Xdef listaliases():
  990. X    names = G.aliases.keys()
  991. X    names.sort()
  992. X    for name in names: listalias(name)
  993. X
  994. Xdef listalias(name):
  995. X    if not G.aliases.has_key(name):
  996. X        print name, ': no such alias'
  997. X        return
  998. X    print 'alias', name,
  999. X    printlist(G.aliases[name])
  1000. X    print
  1001. X
  1002. Xdef defalias(name, expansion):
  1003. X    G.aliases[name] = expansion
  1004. X
  1005. Xdef do_cd(args):
  1006. X    if len(args) > 1:
  1007. X        print 'usage: cd [dirname]'
  1008. X    elif args:
  1009. X        chdirto(args[0])
  1010. X    else:
  1011. X        chdirto(G.homedir)
  1012. X
  1013. Xdef chdirto(dirname):
  1014. X    try:
  1015. X        mac.chdir(dirname)
  1016. X    except mac.error, msg:
  1017. X        print dirname, ':', msg
  1018. X        return
  1019. X
  1020. Xdef do_debug(args):
  1021. X    G.debug = (not G.debug)
  1022. X
  1023. Xdef do_grep(args):
  1024. X    if len(args) < 2:
  1025. X        print 'usage: grep regexp file ...'
  1026. X        return
  1027. X    import regexp
  1028. X    try:
  1029. X        prog = regexp.compile(args[0])
  1030. X    except regexp.error, msg:
  1031. X        print 'regexp.compile error for', args[0], ':', msg
  1032. X        return
  1033. X    for file in args[1:]:
  1034. X        grepfile(prog, file)
  1035. X
  1036. Xdef grepfile(prog, file):
  1037. X    try:
  1038. X        fp = open(file, 'r')
  1039. X    except RuntimeError, msg:
  1040. X        print file, ': cannot open :', msg
  1041. X        return
  1042. X    lineno = 0
  1043. X    while 1:
  1044. X        line = fp.readline()
  1045. X        if not line: break
  1046. X        lineno = lineno+1
  1047. X        if prog.exec(line):
  1048. X            print file+'('+`lineno`+'):', line,
  1049. X
  1050. Xdef do_help(args):
  1051. X    if args:
  1052. X        print 'usage: help'
  1053. X        return
  1054. X    names = G.commands.keys()
  1055. X    names.sort()
  1056. X    columnize(names)
  1057. X
  1058. Xdef do_ls(args):
  1059. X    if not args:
  1060. X        lsdir(':')
  1061. X    else:
  1062. X        for dirname in args:
  1063. X            lsdir(dirname)
  1064. X
  1065. Xdef lsdir(dirname):
  1066. X    if not isdir(dirname):
  1067. X        print dirname, ': no such directory'
  1068. X        return
  1069. X    names = mac.listdir(dirname)
  1070. X    lsfiles(names, dirname)
  1071. X
  1072. Xdef lsfiles(names, dirname):
  1073. X    names = names[:] # Make a copy so we can modify it
  1074. X    for i in range(len(names)):
  1075. X        name = names[i]
  1076. X        if G.debug: print i, name
  1077. X        if isdir(macpath.cat(dirname, name)):
  1078. X            names[i] = ':' + name + ':'
  1079. X    columnize(names)
  1080. X
  1081. Xdef columnize(list):
  1082. X    COLUMNS = 80-1
  1083. X    n = len(list)
  1084. X    colwidth = maxwidth(list)
  1085. X    ncols = (COLUMNS + 1) / (colwidth + 1)
  1086. X    if ncols < 1: ncols = 1
  1087. X    nrows = (n + ncols - 1) / ncols
  1088. X    for irow in range(nrows):
  1089. X        line = ''
  1090. X        for icol in range(ncols):
  1091. X            i = irow + nrows*icol
  1092. X            if 0 <= i < n:
  1093. X                word = list[i]
  1094. X                if i+nrows < n:
  1095. X                    word = string.ljust(word, colwidth)
  1096. X                if icol > 0:
  1097. X                    word = ' ' + word
  1098. X                line = line + word
  1099. X        print line
  1100. X
  1101. Xdef maxwidth(list):
  1102. X    width = 0
  1103. X    for word in list:
  1104. X        if len(word) > width:
  1105. X            width = len(word)
  1106. X    return width
  1107. X
  1108. Xdef do_mv(args):
  1109. X    if len(args) <> 2:
  1110. X        print 'usage: mv src dst'
  1111. X        return
  1112. X    src, dst = args[0], args[1]
  1113. X    if not exists(src):
  1114. X        print src, ': source does not exist'
  1115. X        return
  1116. X    if exists(dst):
  1117. X        print src, ': destination already exists'
  1118. X        return
  1119. X    try:
  1120. X        mac.rename(src, dst)
  1121. X    except mac.error, msg:
  1122. X        print src, dst, ': rename failed:', msg
  1123. X
  1124. Xdef do_mkdir(args):
  1125. X    if not args:
  1126. X        print 'usage: mkdir name ...'
  1127. X        return
  1128. X    for name in args:
  1129. X        makedir(name)
  1130. X
  1131. Xdef makedir(name):
  1132. X    if exists(name):
  1133. X        print name, ': already exists'
  1134. X        return
  1135. X    try:
  1136. X        mac.mkdir(name, 0777)
  1137. X    except mac.error, msg:
  1138. X        print name, ': mkdir failed:', msg
  1139. X
  1140. Xdef do_page(args):
  1141. X    if not args:
  1142. X        print 'usage: page file ...'
  1143. X        return
  1144. X    for name in args:
  1145. X        pagefile(name)
  1146. X
  1147. Xdef pagefile(name):
  1148. X    if not isfile(name):
  1149. X        print name, ': no such file'
  1150. X        return
  1151. X    LINES = 24 - 1
  1152. X    # For THINK C 3.0, make the path absolute:
  1153. X    # if not macpath.isabs(name):
  1154. X    #     name = macpath.cat(mac.getcwd(), name)
  1155. X    try:
  1156. X        fp = open(name, 'r')
  1157. X    except:
  1158. X        print name, ': cannot open'
  1159. X        return
  1160. X    line = fp.readline()
  1161. X    while line:
  1162. X        for i in range(LINES):
  1163. X            print line,
  1164. X            line = fp.readline()
  1165. X            if not line: break
  1166. X        if line:
  1167. X            try:
  1168. X                more = raw_input('[more]')
  1169. X            except (EOFError, KeyboardInterrupt):
  1170. X                print
  1171. X                break
  1172. X            if string.strip(more)[:1] in ('q', 'Q'):
  1173. X                break
  1174. X
  1175. Xdef do_pwd(args):
  1176. X    if args:
  1177. X        print 'usage: pwd'
  1178. X    else:
  1179. X        print mac.getcwd()
  1180. X
  1181. Xdef do_reset(args):
  1182. X    if args:
  1183. X        print 'usage: reset'
  1184. X    else:
  1185. X        reset()
  1186. X
  1187. Xdef do_rm(args):
  1188. X    if not args:
  1189. X        print 'usage: rm file ...'
  1190. X        return
  1191. X    for name in args:
  1192. X        remove(name)
  1193. X
  1194. Xdef remove(name):
  1195. X    if not isfile(name):
  1196. X        print name, ': no such file'
  1197. X        return
  1198. X    try:
  1199. X        mac.unlink(name)
  1200. X    except mac.error, msg:
  1201. X        print name, ': unlink failed:', msg
  1202. X
  1203. Xdef do_rmdir(args):
  1204. X    if not args:
  1205. X        print 'usage: rmdir dir ...'
  1206. X        return
  1207. X    for name in args:
  1208. X        rmdir(name)
  1209. X
  1210. Xdef rmdir(name):
  1211. X    if not isdir(name):
  1212. X        print name, ': no such directory'
  1213. X        return
  1214. X    try:
  1215. X        mac.rmdir(name)
  1216. X    except mac.error, msg:
  1217. X        print name, ': rmdir failed:', msg
  1218. X
  1219. Xdef do_sync(args):
  1220. X    if args:
  1221. X        print 'usage: sync'
  1222. X        return
  1223. X    try:
  1224. X        mac.sync()
  1225. X    except mac.error, msg:
  1226. X        print 'sync failed:', msg
  1227. X
  1228. Xdef do_unalias(args):
  1229. X    if not args:
  1230. X        print 'usage: unalias name ...'
  1231. X        return
  1232. X    for name in args:
  1233. X        unalias(name)
  1234. X
  1235. Xdef unalias(name):
  1236. X    if not G.aliases.has_key(name):
  1237. X        print name, ': no such alias'
  1238. X        return
  1239. X    del G.aliases[name]
  1240. X
  1241. Xdef printlist(list):
  1242. X    for word in list:
  1243. X        print word,
  1244. X
  1245. Xreset()
  1246. Xmain()
  1247. EOF
  1248. fi
  1249. if test -s 'src/cgensupport.c'
  1250. then echo '*** I will not over-write existing file src/cgensupport.c'
  1251. else
  1252. echo 'x - src/cgensupport.c'
  1253. sed 's/^X//' > 'src/cgensupport.c' << 'EOF'
  1254. X/***********************************************************
  1255. XCopyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
  1256. XNetherlands.
  1257. X
  1258. X                        All Rights Reserved
  1259. X
  1260. XPermission to use, copy, modify, and distribute this software and its 
  1261. Xdocumentation for any purpose and without fee is hereby granted, 
  1262. Xprovided that the above copyright notice appear in all copies and that
  1263. Xboth that copyright notice and this permission notice appear in 
  1264. Xsupporting documentation, and that the names of Stichting Mathematisch
  1265. XCentrum or CWI not be used in advertising or publicity pertaining to
  1266. Xdistribution of the software without specific, written prior permission.
  1267. X
  1268. XSTICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  1269. XTHIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  1270. XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  1271. XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  1272. XWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  1273. XACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  1274. XOF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  1275. X
  1276. X******************************************************************/
  1277. X
  1278. X/* Functions used by cgen output */
  1279. X
  1280. X#include <stdio.h>
  1281. X
  1282. X#include "PROTO.h"
  1283. X#include "object.h"
  1284. X#include "intobject.h"
  1285. X#include "floatobject.h"
  1286. X#include "stringobject.h"
  1287. X#include "tupleobject.h"
  1288. X#include "listobject.h"
  1289. X#include "methodobject.h"
  1290. X#include "moduleobject.h"
  1291. X#include "modsupport.h"
  1292. X#include "import.h"
  1293. X#include "cgensupport.h"
  1294. X#include "errors.h"
  1295. X
  1296. X
  1297. X/* Functions to construct return values */
  1298. X
  1299. Xobject *
  1300. Xmknewcharobject(c)
  1301. X    int c;
  1302. X{
  1303. X    char ch[1];
  1304. X    ch[0] = c;
  1305. X    return newsizedstringobject(ch, 1);
  1306. X}
  1307. X
  1308. X/* Functions to extract arguments.
  1309. X   These needs to know the total number of arguments supplied,
  1310. X   since the argument list is a tuple only of there is more than
  1311. X   one argument. */
  1312. X
  1313. Xint
  1314. Xgetiobjectarg(args, nargs, i, p_arg)
  1315. X    register object *args;
  1316. X    int nargs, i;
  1317. X    object **p_arg;
  1318. X{
  1319. X    if (nargs != 1) {
  1320. X        if (args == NULL || !is_tupleobject(args) ||
  1321. X                nargs != gettuplesize(args) ||
  1322. X                i < 0 || i >= nargs) {
  1323. X            return err_badarg();
  1324. X        }
  1325. X        else {
  1326. X            args = gettupleitem(args, i);
  1327. X        }
  1328. X    }
  1329. X    if (args == NULL) {
  1330. X        return err_badarg();
  1331. X    }
  1332. X    *p_arg = args;
  1333. X    return 1;
  1334. X}
  1335. X
  1336. Xint
  1337. Xgetilongarg(args, nargs, i, p_arg)
  1338. X    register object *args;
  1339. X    int nargs, i;
  1340. X    long *p_arg;
  1341. X{
  1342. X    if (nargs != 1) {
  1343. X        if (args == NULL || !is_tupleobject(args) ||
  1344. X                nargs != gettuplesize(args) ||
  1345. X                i < 0 || i >= nargs) {
  1346. X            return err_badarg();
  1347. X        }
  1348. X        args = gettupleitem(args, i);
  1349. X    }
  1350. X    if (args == NULL || !is_intobject(args)) {
  1351. X        return err_badarg();
  1352. X    }
  1353. X    *p_arg = getintvalue(args);
  1354. X    return 1;
  1355. X}
  1356. X
  1357. Xint
  1358. Xgetishortarg(args, nargs, i, p_arg)
  1359. X    register object *args;
  1360. X    int nargs, i;
  1361. X    short *p_arg;
  1362. X{
  1363. X    long x;
  1364. X    if (!getilongarg(args, nargs, i, &x))
  1365. X        return 0;
  1366. X    *p_arg = x;
  1367. X    return 1;
  1368. X}
  1369. X
  1370. Xstatic int
  1371. Xextractdouble(v, p_arg)
  1372. X    register object *v;
  1373. X    double *p_arg;
  1374. X{
  1375. X    if (v == NULL) {
  1376. X        /* Fall through to error return at end of function */
  1377. X    }
  1378. X    else if (is_floatobject(v)) {
  1379. X        *p_arg = GETFLOATVALUE((floatobject *)v);
  1380. X        return 1;
  1381. X    }
  1382. X    else if (is_intobject(v)) {
  1383. X        *p_arg = GETINTVALUE((intobject *)v);
  1384. X        return 1;
  1385. X    }
  1386. X    return err_badarg();
  1387. X}
  1388. X
  1389. Xstatic int
  1390. Xextractfloat(v, p_arg)
  1391. X    register object *v;
  1392. X    float *p_arg;
  1393. X{
  1394. X    if (v == NULL) {
  1395. X        /* Fall through to error return at end of function */
  1396. X    }
  1397. X    else if (is_floatobject(v)) {
  1398. X        *p_arg = GETFLOATVALUE((floatobject *)v);
  1399. X        return 1;
  1400. X    }
  1401. X    else if (is_intobject(v)) {
  1402. X        *p_arg = GETINTVALUE((intobject *)v);
  1403. X        return 1;
  1404. X    }
  1405. X    return err_badarg();
  1406. X}
  1407. X
  1408. Xint
  1409. Xgetifloatarg(args, nargs, i, p_arg)
  1410. X    register object *args;
  1411. X    int nargs, i;
  1412. X    float *p_arg;
  1413. X{
  1414. X    object *v;
  1415. X    float x;
  1416. X    if (!getiobjectarg(args, nargs, i, &v))
  1417. X        return 0;
  1418. X    if (!extractfloat(v, &x))
  1419. X        return 0;
  1420. X    *p_arg = x;
  1421. X    return 1;
  1422. X}
  1423. X
  1424. Xint
  1425. Xgetistringarg(args, nargs, i, p_arg)
  1426. X    object *args;
  1427. X    int nargs, i;
  1428. X    string *p_arg;
  1429. X{
  1430. X    object *v;
  1431. X    if (!getiobjectarg(args, nargs, i, &v))
  1432. X        return NULL;
  1433. X    if (!is_stringobject(v)) {
  1434. X        return err_badarg();
  1435. X    }
  1436. X    *p_arg = getstringvalue(v);
  1437. X    return 1;
  1438. X}
  1439. X
  1440. Xint
  1441. Xgetichararg(args, nargs, i, p_arg)
  1442. X    object *args;
  1443. X    int nargs, i;
  1444. X    char *p_arg;
  1445. X{
  1446. X    string x;
  1447. X    if (!getistringarg(args, nargs, i, &x))
  1448. X        return 0;
  1449. X    if (x[0] == '\0' || x[1] != '\0') {
  1450. X        /* Not exactly one char */
  1451. X        return err_badarg();
  1452. X    }
  1453. X    *p_arg = x[0];
  1454. X    return 1;
  1455. X}
  1456. X
  1457. Xint
  1458. Xgetilongarraysize(args, nargs, i, p_arg)
  1459. X    object *args;
  1460. X    int nargs, i;
  1461. X    long *p_arg;
  1462. X{
  1463. X    object *v;
  1464. X    if (!getiobjectarg(args, nargs, i, &v))
  1465. X        return 0;
  1466. X    if (is_tupleobject(v)) {
  1467. X        *p_arg = gettuplesize(v);
  1468. X        return 1;
  1469. X    }
  1470. X    if (is_listobject(v)) {
  1471. X        *p_arg = getlistsize(v);
  1472. X        return 1;
  1473. X    }
  1474. X    return err_badarg();
  1475. X}
  1476. X
  1477. Xint
  1478. Xgetishortarraysize(args, nargs, i, p_arg)
  1479. X    object *args;
  1480. X    int nargs, i;
  1481. X    short *p_arg;
  1482. X{
  1483. X    long x;
  1484. X    if (!getilongarraysize(args, nargs, i, &x))
  1485. X        return 0;
  1486. X    *p_arg = x;
  1487. X    return 1;
  1488. X}
  1489. X
  1490. X/* XXX The following four are too similar.  Should share more code. */
  1491. X
  1492. Xint
  1493. Xgetilongarray(args, nargs, i, n, p_arg)
  1494. X    object *args;
  1495. X    int nargs, i;
  1496. X    int n;
  1497. X    long *p_arg; /* [n] */
  1498. X{
  1499. X    object *v, *w;
  1500. X    if (!getiobjectarg(args, nargs, i, &v))
  1501. X        return 0;
  1502. X    if (is_tupleobject(v)) {
  1503. X        if (gettuplesize(v) != n) {
  1504. X            return err_badarg();
  1505. X        }
  1506. X        for (i = 0; i < n; i++) {
  1507. X            w = gettupleitem(v, i);
  1508. X            if (!is_intobject(w)) {
  1509. X                return err_badarg();
  1510. X            }
  1511. X            p_arg[i] = getintvalue(w);
  1512. X        }
  1513. X        return 1;
  1514. X    }
  1515. X    else if (is_listobject(v)) {
  1516. X        if (getlistsize(v) != n) {
  1517. X            return err_badarg();
  1518. X        }
  1519. X        for (i = 0; i < n; i++) {
  1520. X            w = getlistitem(v, i);
  1521. X            if (!is_intobject(w)) {
  1522. X                return err_badarg();
  1523. X            }
  1524. X            p_arg[i] = getintvalue(w);
  1525. X        }
  1526. X        return 1;
  1527. X    }
  1528. X    else {
  1529. X        return err_badarg();
  1530. X    }
  1531. X}
  1532. X
  1533. Xint
  1534. Xgetishortarray(args, nargs, i, n, p_arg)
  1535. X    object *args;
  1536. X    int nargs, i;
  1537. X    int n;
  1538. X    short *p_arg; /* [n] */
  1539. X{
  1540. X    object *v, *w;
  1541. X    if (!getiobjectarg(args, nargs, i, &v))
  1542. X        return 0;
  1543. X    if (is_tupleobject(v)) {
  1544. X        if (gettuplesize(v) != n) {
  1545. X            return err_badarg();
  1546. X        }
  1547. X        for (i = 0; i < n; i++) {
  1548. X            w = gettupleitem(v, i);
  1549. X            if (!is_intobject(w)) {
  1550. X                return err_badarg();
  1551. X            }
  1552. X            p_arg[i] = getintvalue(w);
  1553. X        }
  1554. X        return 1;
  1555. X    }
  1556. X    else if (is_listobject(v)) {
  1557. X        if (getlistsize(v) != n) {
  1558. X            return err_badarg();
  1559. X        }
  1560. X        for (i = 0; i < n; i++) {
  1561. X            w = getlistitem(v, i);
  1562. X            if (!is_intobject(w)) {
  1563. X                return err_badarg();
  1564. X            }
  1565. X            p_arg[i] = getintvalue(w);
  1566. X        }
  1567. X        return 1;
  1568. X    }
  1569. X    else {
  1570. X        return err_badarg();
  1571. X    }
  1572. X}
  1573. X
  1574. Xint
  1575. Xgetidoublearray(args, nargs, i, n, p_arg)
  1576. X    object *args;
  1577. X    int nargs, i;
  1578. X    int n;
  1579. X    double *p_arg; /* [n] */
  1580. X{
  1581. X    object *v, *w;
  1582. X    if (!getiobjectarg(args, nargs, i, &v))
  1583. X        return 0;
  1584. X    if (is_tupleobject(v)) {
  1585. X        if (gettuplesize(v) != n) {
  1586. X            return err_badarg();
  1587. X        }
  1588. X        for (i = 0; i < n; i++) {
  1589. X            w = gettupleitem(v, i);
  1590. X            if (!extractdouble(w, &p_arg[i]))
  1591. X                return 0;
  1592. X        }
  1593. X        return 1;
  1594. X    }
  1595. X    else if (is_listobject(v)) {
  1596. X        if (getlistsize(v) != n) {
  1597. X            return err_badarg();
  1598. X        }
  1599. X        for (i = 0; i < n; i++) {
  1600. X            w = getlistitem(v, i);
  1601. X            if (!extractdouble(w, &p_arg[i]))
  1602. X                return 0;
  1603. X        }
  1604. X        return 1;
  1605. X    }
  1606. X    else {
  1607. X        return err_badarg();
  1608. X    }
  1609. X}
  1610. X
  1611. Xint
  1612. Xgetifloatarray(args, nargs, i, n, p_arg)
  1613. X    object *args;
  1614. X    int nargs, i;
  1615. X    int n;
  1616. X    float *p_arg; /* [n] */
  1617. X{
  1618. X    object *v, *w;
  1619. X    if (!getiobjectarg(args, nargs, i, &v))
  1620. X        return 0;
  1621. X    if (is_tupleobject(v)) {
  1622. X        if (gettuplesize(v) != n) {
  1623. X            return err_badarg();
  1624. X        }
  1625. X        for (i = 0; i < n; i++) {
  1626. X            w = gettupleitem(v, i);
  1627. X            if (!extractfloat(w, &p_arg[i]))
  1628. X                return 0;
  1629. X        }
  1630. X        return 1;
  1631. X    }
  1632. X    else if (is_listobject(v)) {
  1633. X        if (getlistsize(v) != n) {
  1634. X            return err_badarg();
  1635. X        }
  1636. X        for (i = 0; i < n; i++) {
  1637. X            w = getlistitem(v, i);
  1638. X            if (!extractfloat(w, &p_arg[i]))
  1639. X                return 0;
  1640. X        }
  1641. X        return 1;
  1642. X    }
  1643. X    else {
  1644. X        return err_badarg();
  1645. X    }
  1646. X}
  1647. EOF
  1648. fi
  1649. if test -s 'src/modsupport.c'
  1650. then echo '*** I will not over-write existing file src/modsupport.c'
  1651. else
  1652. echo 'x - src/modsupport.c'
  1653. sed 's/^X//' > 'src/modsupport.c' << 'EOF'
  1654. X/***********************************************************
  1655. XCopyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
  1656. XNetherlands.
  1657. X
  1658. X                        All Rights Reserved
  1659. X
  1660. XPermission to use, copy, modify, and distribute this software and its 
  1661. Xdocumentation for any purpose and without fee is hereby granted, 
  1662. Xprovided that the above copyright notice appear in all copies and that
  1663. Xboth that copyright notice and this permission notice appear in 
  1664. Xsupporting documentation, and that the names of Stichting Mathematisch
  1665. XCentrum or CWI not be used in advertising or publicity pertaining to
  1666. Xdistribution of the software without specific, written prior permission.
  1667. X
  1668. XSTICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  1669. XTHIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  1670. XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  1671. XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  1672. XWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  1673. XACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  1674. XOF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  1675. X
  1676. X******************************************************************/
  1677. X
  1678. X/* Module support implementation */
  1679. X
  1680. X#include "allobjects.h"
  1681. X#include "modsupport.h"
  1682. X#include "import.h"
  1683. X
  1684. X
  1685. Xobject *
  1686. Xinitmodule(name, methods)
  1687. X    char *name;
  1688. X    struct methodlist *methods;
  1689. X{
  1690. X    object *m, *d, *v;
  1691. X    struct methodlist *ml;
  1692. X    char namebuf[256];
  1693. X    if ((m = add_module(name)) == NULL) {
  1694. X        fprintf(stderr, "initializing module: %s\n", name);
  1695. X        fatal("can't create a module");
  1696. X    }
  1697. X    d = getmoduledict(m);
  1698. X    for (ml = methods; ml->ml_name != NULL; ml++) {
  1699. X        sprintf(namebuf, "%s.%s", name, ml->ml_name);
  1700. X        v = newmethodobject(strdup(namebuf), ml->ml_meth,
  1701. X                        (object *)NULL);
  1702. X        /* XXX The strdup'ed memory is never freed */
  1703. X        if (v == NULL || dictinsert(d, ml->ml_name, v) != 0) {
  1704. X            fprintf(stderr, "initializing module: %s\n", name);
  1705. X            fatal("can't initialize module");
  1706. X        }
  1707. X        DECREF(v);
  1708. X    }
  1709. X    return m;
  1710. X}
  1711. X
  1712. X
  1713. X/* Argument list handling tools.
  1714. X   All return 1 for success, or call err_set*() and return 0 for failure */
  1715. X
  1716. Xint
  1717. Xgetnoarg(v)
  1718. X    object *v;
  1719. X{
  1720. X    if (v != NULL) {
  1721. X        return err_badarg();
  1722. X    }
  1723. X    return 1;
  1724. X}
  1725. X
  1726. Xint
  1727. Xgetintarg(v, a)
  1728. X    object *v;
  1729. X    int *a;
  1730. X{
  1731. X    if (v == NULL || !is_intobject(v)) {
  1732. X        return err_badarg();
  1733. X    }
  1734. X    *a = getintvalue(v);
  1735. X    return 1;
  1736. X}
  1737. X
  1738. Xint
  1739. Xgetintintarg(v, a, b)
  1740. X    object *v;
  1741. X    int *a;
  1742. X    int *b;
  1743. X{
  1744. X    if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 2) {
  1745. X        return err_badarg();
  1746. X    }
  1747. X    return getintarg(gettupleitem(v, 0), a) &&
  1748. X        getintarg(gettupleitem(v, 1), b);
  1749. X}
  1750. X
  1751. Xint
  1752. Xgetlongarg(v, a)
  1753. X    object *v;
  1754. X    long *a;
  1755. X{
  1756. X    if (v == NULL || !is_intobject(v)) {
  1757. X        return err_badarg();
  1758. X    }
  1759. X    *a = getintvalue(v);
  1760. X    return 1;
  1761. X}
  1762. X
  1763. Xint
  1764. Xgetlonglongargs(v, a, b)
  1765. X    object *v;
  1766. X    long *a, *b;
  1767. X{
  1768. X    if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 2) {
  1769. X        return err_badarg();
  1770. X    }
  1771. X    return getlongarg(gettupleitem(v, 0), a) &&
  1772. X        getlongarg(gettupleitem(v, 1), b);
  1773. X}
  1774. X
  1775. Xint
  1776. Xgetlonglongobjectargs(v, a, b, c)
  1777. X    object *v;
  1778. X    long *a, *b;
  1779. X    object **c;
  1780. X{
  1781. X    if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 3) {
  1782. X        return err_badarg();
  1783. X    }
  1784. X    if (getlongarg(gettupleitem(v, 0), a) &&
  1785. X        getlongarg(gettupleitem(v, 1), b)) {
  1786. X        *c = gettupleitem(v, 2);
  1787. X        return 1;
  1788. X    }
  1789. X    else {
  1790. X        return err_badarg();
  1791. X    }
  1792. X}
  1793. X
  1794. Xint
  1795. Xgetstrarg(v, a)
  1796. X    object *v;
  1797. X    object **a;
  1798. X{
  1799. X    if (v == NULL || !is_stringobject(v)) {
  1800. X        return err_badarg();
  1801. X    }
  1802. X    *a = v;
  1803. X    return 1;
  1804. X}
  1805. X
  1806. Xint
  1807. Xgetstrstrarg(v, a, b)
  1808. X    object *v;
  1809. X    object **a;
  1810. X    object **b;
  1811. X{
  1812. X    if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 2) {
  1813. X        return err_badarg();
  1814. X    }
  1815. X    return getstrarg(gettupleitem(v, 0), a) &&
  1816. X        getstrarg(gettupleitem(v, 1), b);
  1817. X}
  1818. X
  1819. Xint
  1820. Xgetstrstrintarg(v, a, b, c)
  1821. X    object *v;
  1822. X    object **a;
  1823. X    object **b;
  1824. X    int *c;
  1825. X{
  1826. X    if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 3) {
  1827. X        return err_badarg();
  1828. X    }
  1829. X    return getstrarg(gettupleitem(v, 0), a) &&
  1830. X        getstrarg(gettupleitem(v, 1), b) &&
  1831. X        getintarg(gettupleitem(v, 2), c);
  1832. X}
  1833. X
  1834. Xint
  1835. Xgetstrintarg(v, a, b)
  1836. X    object *v;
  1837. X    object **a;
  1838. X    int *b;
  1839. X{
  1840. X    if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 2) {
  1841. X        return err_badarg();
  1842. X    }
  1843. X    return getstrarg(gettupleitem(v, 0), a) &&
  1844. X        getintarg(gettupleitem(v, 1), b);
  1845. X}
  1846. X
  1847. Xint
  1848. Xgetintstrarg(v, a, b)
  1849. X    object *v;
  1850. X    int *a;
  1851. X    object **b;
  1852. X{
  1853. X    if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 2) {
  1854. X        return err_badarg();
  1855. X    }
  1856. X    return getintarg(gettupleitem(v, 0), a) &&
  1857. X        getstrarg(gettupleitem(v, 1), b);
  1858. X}
  1859. X
  1860. Xint
  1861. Xgetpointarg(v, a)
  1862. X    object *v;
  1863. X    int *a; /* [2] */
  1864. X{
  1865. X    return getintintarg(v, a, a+1);
  1866. X}
  1867. X
  1868. Xint
  1869. Xget3pointarg(v, a)
  1870. X    object *v;
  1871. X    int *a; /* [6] */
  1872. X{
  1873. X    if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 3) {
  1874. X        return err_badarg();
  1875. X    }
  1876. X    return getpointarg(gettupleitem(v, 0), a) &&
  1877. X        getpointarg(gettupleitem(v, 1), a+2) &&
  1878. X        getpointarg(gettupleitem(v, 2), a+4);
  1879. X}
  1880. X
  1881. Xint
  1882. Xgetrectarg(v, a)
  1883. X    object *v;
  1884. X    int *a; /* [2+2] */
  1885. X{
  1886. X    if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 2) {
  1887. X        return err_badarg();
  1888. X    }
  1889. X    return getpointarg(gettupleitem(v, 0), a) &&
  1890. X        getpointarg(gettupleitem(v, 1), a+2);
  1891. X}
  1892. X
  1893. Xint
  1894. Xgetrectintarg(v, a)
  1895. X    object *v;
  1896. X    int *a; /* [4+1] */
  1897. X{
  1898. X    if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 2) {
  1899. X        return err_badarg();
  1900. X    }
  1901. X    return getrectarg(gettupleitem(v, 0), a) &&
  1902. X        getintarg(gettupleitem(v, 1), a+4);
  1903. X}
  1904. X
  1905. Xint
  1906. Xgetpointintarg(v, a)
  1907. X    object *v;
  1908. X    int *a; /* [2+1] */
  1909. X{
  1910. X    if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 2) {
  1911. X        return err_badarg();
  1912. X    }
  1913. X    return getpointarg(gettupleitem(v, 0), a) &&
  1914. X        getintarg(gettupleitem(v, 1), a+2);
  1915. X}
  1916. X
  1917. Xint
  1918. Xgetpointstrarg(v, a, b)
  1919. X    object *v;
  1920. X    int *a; /* [2] */
  1921. X    object **b;
  1922. X{
  1923. X    if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 2) {
  1924. X        return err_badarg();
  1925. X    }
  1926. X    return getpointarg(gettupleitem(v, 0), a) &&
  1927. X        getstrarg(gettupleitem(v, 1), b);
  1928. X}
  1929. X
  1930. Xint
  1931. Xgetstrintintarg(v, a, b, c)
  1932. X    object *v;
  1933. X    object *a;
  1934. X    int *b, *c;
  1935. X{
  1936. X    if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 3) {
  1937. X        return err_badarg();
  1938. X    }
  1939. X    return getstrarg(gettupleitem(v, 0), a) &&
  1940. X        getintarg(gettupleitem(v, 1), b) &&
  1941. X        getintarg(gettupleitem(v, 2), c);
  1942. X}
  1943. X
  1944. Xint
  1945. Xgetrectpointarg(v, a)
  1946. X    object *v;
  1947. X    int *a; /* [4+2] */
  1948. X{
  1949. X    if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 2) {
  1950. X        return err_badarg();
  1951. X    }
  1952. X    return getrectarg(gettupleitem(v, 0), a) &&
  1953. X        getpointarg(gettupleitem(v, 1), a+4);
  1954. X}
  1955. X
  1956. Xint
  1957. Xgetlongtuplearg(args, a, n)
  1958. X    object *args;
  1959. X    long *a; /* [n] */
  1960. X    int n;
  1961. X{
  1962. X    int i;
  1963. X    if (!is_tupleobject(args) || gettuplesize(args) != n) {
  1964. X        return err_badarg();
  1965. X    }
  1966. X    for (i = 0; i < n; i++) {
  1967. X        object *v = gettupleitem(args, i);
  1968. X        if (!is_intobject(v)) {
  1969. X            return err_badarg();
  1970. X        }
  1971. X        a[i] = getintvalue(v);
  1972. X    }
  1973. X    return 1;
  1974. X}
  1975. X
  1976. Xint
  1977. Xgetshorttuplearg(args, a, n)
  1978. X    object *args;
  1979. X    short *a; /* [n] */
  1980. X    int n;
  1981. X{
  1982. X    int i;
  1983. X    if (!is_tupleobject(args) || gettuplesize(args) != n) {
  1984. X        return err_badarg();
  1985. X    }
  1986. X    for (i = 0; i < n; i++) {
  1987. X        object *v = gettupleitem(args, i);
  1988. X        if (!is_intobject(v)) {
  1989. X            return err_badarg();
  1990. X        }
  1991. X        a[i] = getintvalue(v);
  1992. X    }
  1993. X    return 1;
  1994. X}
  1995. X
  1996. Xint
  1997. Xgetlonglistarg(args, a, n)
  1998. X    object *args;
  1999. X    long *a; /* [n] */
  2000. X    int n;
  2001. X{
  2002. X    int i;
  2003. X    if (!is_listobject(args) || getlistsize(args) != n) {
  2004. X        return err_badarg();
  2005. X    }
  2006. X    for (i = 0; i < n; i++) {
  2007. X        object *v = getlistitem(args, i);
  2008. X        if (!is_intobject(v)) {
  2009. X            return err_badarg();
  2010. X        }
  2011. X        a[i] = getintvalue(v);
  2012. X    }
  2013. X    return 1;
  2014. X}
  2015. X
  2016. Xint
  2017. Xgetshortlistarg(args, a, n)
  2018. X    object *args;
  2019. X    short *a; /* [n] */
  2020. X    int n;
  2021. X{
  2022. X    int i;
  2023. X    if (!is_listobject(args) || getlistsize(args) != n) {
  2024. X        return err_badarg();
  2025. X    }
  2026. X    for (i = 0; i < n; i++) {
  2027. X        object *v = getlistitem(args, i);
  2028. X        if (!is_intobject(v)) {
  2029. X            return err_badarg();
  2030. X        }
  2031. X        a[i] = getintvalue(v);
  2032. X    }
  2033. X    return 1;
  2034. X}
  2035. EOF
  2036. fi
  2037. if test -s 'src/pythonmain.c'
  2038. then echo '*** I will not over-write existing file src/pythonmain.c'
  2039. else
  2040. echo 'x - src/pythonmain.c'
  2041. sed 's/^X//' > 'src/pythonmain.c' << 'EOF'
  2042. X/***********************************************************
  2043. XCopyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
  2044. XNetherlands.
  2045. X
  2046. X                        All Rights Reserved
  2047. X
  2048. XPermission to use, copy, modify, and distribute this software and its 
  2049. Xdocumentation for any purpose and without fee is hereby granted, 
  2050. Xprovided that the above copyright notice appear in all copies and that
  2051. Xboth that copyright notice and this permission notice appear in 
  2052. Xsupporting documentation, and that the names of Stichting Mathematisch
  2053. XCentrum or CWI not be used in advertising or publicity pertaining to
  2054. Xdistribution of the software without specific, written prior permission.
  2055. X
  2056. XSTICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  2057. XTHIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  2058. XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  2059. XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  2060. XWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  2061. XACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  2062. XOF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  2063. X
  2064. X******************************************************************/
  2065. X
  2066. X/* Python interpreter main program */
  2067. X
  2068. X#include "patchlevel.h"
  2069. X
  2070. X#include "allobjects.h"
  2071. X
  2072. X#include "grammar.h"
  2073. X#include "node.h"
  2074. X#include "parsetok.h"
  2075. X#include "graminit.h"
  2076. X#include "errcode.h"
  2077. X#include "sysmodule.h"
  2078. X#include "compile.h"
  2079. X#include "ceval.h"
  2080. X#include "pythonrun.h"
  2081. X#include "import.h"
  2082. X
  2083. Xextern char *getpythonpath();
  2084. X
  2085. Xextern grammar gram; /* From graminit.c */
  2086. X
  2087. X#ifdef DEBUG
  2088. Xint debugging; /* Needed by parser.c */
  2089. X#endif
  2090. X
  2091. Xmain(argc, argv)
  2092. X    int argc;
  2093. X    char **argv;
  2094. X{
  2095. X    char *filename = NULL;
  2096. X    FILE *fp = stdin;
  2097. X    
  2098. X    initargs(&argc, &argv);
  2099. X    
  2100. X    if (argc > 1 && strcmp(argv[1], "-") != 0)
  2101. X        filename = argv[1];
  2102. X    
  2103. X    if (filename != NULL) {
  2104. X        if ((fp = fopen(filename, "r")) == NULL) {
  2105. X            fprintf(stderr, "python: can't open file '%s'\n",
  2106. X                filename);
  2107. X            exit(2);
  2108. X        }
  2109. X    }
  2110. X    
  2111. X    initall();
  2112. X    
  2113. X    setpythonpath(getpythonpath());
  2114. X    setpythonargv(argc-1, argv+1);
  2115. X    
  2116. X    goaway(run(fp, filename == NULL ? "<stdin>" : filename));
  2117. X    /*NOTREACHED*/
  2118. X}
  2119. X
  2120. X/* Initialize all */
  2121. X
  2122. Xvoid
  2123. Xinitall()
  2124. X{
  2125. X    static int inited;
  2126. X    
  2127. X    if (inited)
  2128. X        return;
  2129. X    inited = 1;
  2130. X    
  2131. X    initimport();
  2132. X    
  2133. X    /* Modules 'builtin' and 'sys' are initialized here,
  2134. X       they are needed by random bits of the interpreter.
  2135. X       All other modules are optional and should be initialized
  2136. X       by the initcalls() of a specific configuration. */
  2137. X    
  2138. X    initbuiltin(); /* Also initializes builtin exceptions */
  2139. X    initsys();
  2140. X    
  2141. X    initcalls(); /* Configuration-dependent initializations */
  2142. X    
  2143. X    initintr(); /* For intrcheck() */
  2144. X}
  2145. X
  2146. X/* Parse input from a file and execute it */
  2147. X
  2148. Xint
  2149. Xrun(fp, filename)
  2150. X    FILE *fp;
  2151. X    char *filename;
  2152. X{
  2153. X    if (filename == NULL)
  2154. X        filename = "???";
  2155. X    if (isatty(fileno(fp)))
  2156. X        return run_tty_loop(fp, filename);
  2157. X    else
  2158. X        return run_script(fp, filename);
  2159. X}
  2160. X
  2161. Xint
  2162. Xrun_tty_loop(fp, filename)
  2163. X    FILE *fp;
  2164. X    char *filename;
  2165. X{
  2166. X    object *v;
  2167. X    int ret;
  2168. X    v = sysget("ps1");
  2169. X    if (v == NULL) {
  2170. X        sysset("ps1", v = newstringobject(">>> "));
  2171. X        XDECREF(v);
  2172. X    }
  2173. X    v = sysget("ps2");
  2174. X    if (v == NULL) {
  2175. X        sysset("ps2", v = newstringobject("... "));
  2176. X        XDECREF(v);
  2177. X    }
  2178. X    for (;;) {
  2179. X        ret = run_tty_1(fp, filename);
  2180. X#ifdef REF_DEBUG
  2181. X        fprintf(stderr, "[%ld refs]\n", ref_total);
  2182. X#endif
  2183. X        if (ret == E_EOF)
  2184. X            return 0;
  2185. X        /*
  2186. X        if (ret == E_NOMEM)
  2187. X            return -1;
  2188. X        */
  2189. X    }
  2190. X}
  2191. X
  2192. Xint
  2193. Xrun_tty_1(fp, filename)
  2194. X    FILE *fp;
  2195. X    char *filename;
  2196. X{
  2197. X    object *m, *d, *v, *w;
  2198. X    node *n;
  2199. X    char *ps1, *ps2;
  2200. X    int err;
  2201. X    v = sysget("ps1");
  2202. X    w = sysget("ps2");
  2203. X    if (v != NULL && is_stringobject(v)) {
  2204. X        INCREF(v);
  2205. X        ps1 = getstringvalue(v);
  2206. X    }
  2207. X    else {
  2208. X        v = NULL;
  2209. X        ps1 = "";
  2210. X    }
  2211. X    if (w != NULL && is_stringobject(w)) {
  2212. X        INCREF(w);
  2213. X        ps2 = getstringvalue(w);
  2214. X    }
  2215. X    else {
  2216. X        w = NULL;
  2217. X        ps2 = "";
  2218. X    }
  2219. X    err = parsefile(fp, filename, &gram, single_input, ps1, ps2, &n);
  2220. X    XDECREF(v);
  2221. X    XDECREF(w);
  2222. X    if (err == E_EOF)
  2223. X        return E_EOF;
  2224. X    if (err != E_DONE) {
  2225. X        err_input(err);
  2226. X        print_error();
  2227. X        return err;
  2228. X    }
  2229. X    m = add_module("__main__");
  2230. X    if (m == NULL)
  2231. X        return -1;
  2232. X    d = getmoduledict(m);
  2233. X    v = run_node(n, filename, d, d);
  2234. X    flushline();
  2235. X    if (v == NULL) {
  2236. X        print_error();
  2237. X        return -1;
  2238. X    }
  2239. X    DECREF(v);
  2240. X    return 0;
  2241. X}
  2242. X
  2243. Xint
  2244. Xrun_script(fp, filename)
  2245. X    FILE *fp;
  2246. X    char *filename;
  2247. X{
  2248. X    object *m, *d, *v;
  2249. X    m = add_module("__main__");
  2250. X    if (m == NULL)
  2251. X        return -1;
  2252. X    d = getmoduledict(m);
  2253. X    v = run_file(fp, filename, file_input, d, d);
  2254. X    flushline();
  2255. X    if (v == NULL) {
  2256. X        print_error();
  2257. X        return -1;
  2258. X    }
  2259. X    DECREF(v);
  2260. X    return 0;
  2261. X}
  2262. X
  2263. Xvoid
  2264. Xprint_error()
  2265. X{
  2266. X    object *exception, *v;
  2267. X    err_get(&exception, &v);
  2268. X    fprintf(stderr, "Unhandled exception: ");
  2269. X    printobject(exception, stderr, PRINT_RAW);
  2270. X    if (v != NULL && v != None) {
  2271. X        fprintf(stderr, ": ");
  2272. X        printobject(v, stderr, PRINT_RAW);
  2273. X    }
  2274. X    fprintf(stderr, "\n");
  2275. X    XDECREF(exception);
  2276. X    XDECREF(v);
  2277. X    printtraceback(stderr);
  2278. X}
  2279. X
  2280. Xobject *
  2281. Xrun_string(str, start, globals, locals)
  2282. X    char *str;
  2283. X    int start;
  2284. X    /*dict*/object *globals, *locals;
  2285. X{
  2286. X    node *n;
  2287. X    int err;
  2288. X    err = parse_string(str, start, &n);
  2289. X    return run_err_node(err, n, "<string>", globals, locals);
  2290. X}
  2291. X
  2292. Xobject *
  2293. Xrun_file(fp, filename, start, globals, locals)
  2294. X    FILE *fp;
  2295. X    char *filename;
  2296. X    int start;
  2297. X    /*dict*/object *globals, *locals;
  2298. X{
  2299. X    node *n;
  2300. X    int err;
  2301. X    err = parse_file(fp, filename, start, &n);
  2302. X    return run_err_node(err, n, filename, globals, locals);
  2303. X}
  2304. X
  2305. Xobject *
  2306. Xrun_err_node(err, n, filename, globals, locals)
  2307. X    int err;
  2308. X    node *n;
  2309. X    char *filename;
  2310. X    /*dict*/object *globals, *locals;
  2311. X{
  2312. X    if (err != E_DONE) {
  2313. X        err_input(err);
  2314. X        return NULL;
  2315. X    }
  2316. X    return run_node(n, filename, globals, locals);
  2317. X}
  2318. X
  2319. Xobject *
  2320. Xrun_node(n, filename, globals, locals)
  2321. X    node *n;
  2322. X    char *filename;
  2323. X    /*dict*/object *globals, *locals;
  2324. X{
  2325. X    if (globals == NULL) {
  2326. X        globals = getglobals();
  2327. X        if (locals == NULL)
  2328. X            locals = getlocals();
  2329. X    }
  2330. X    else {
  2331. X        if (locals == NULL)
  2332. X            locals = globals;
  2333. X    }
  2334. X    return eval_node(n, filename, globals, locals);
  2335. X}
  2336. X
  2337. Xobject *
  2338. Xeval_node(n, filename, globals, locals)
  2339. X    node *n;
  2340. X    char *filename;
  2341. X    object *globals;
  2342. X    object *locals;
  2343. X{
  2344. X    codeobject *co;
  2345. X    object *v;
  2346. X    co = compile(n, filename);
  2347. X    freetree(n);
  2348. X    if (co == NULL)
  2349. X        return NULL;
  2350. X    v = eval_code(co, globals, locals, (object *)NULL);
  2351. X    DECREF(co);
  2352. X    return v;
  2353. X}
  2354. X
  2355. X/* Simplified interface to parsefile */
  2356. X
  2357. Xint
  2358. Xparse_file(fp, filename, start, n_ret)
  2359. X    FILE *fp;
  2360. X    char *filename;
  2361. X    int start;
  2362. X    node **n_ret;
  2363. X{
  2364. X    return parsefile(fp, filename, &gram, start,
  2365. X                (char *)0, (char *)0, n_ret);
  2366. X}
  2367. X
  2368. X/* Simplified interface to parsestring */
  2369. X
  2370. Xint
  2371. Xparse_string(str, start, n_ret)
  2372. X    char *str;
  2373. X    int start;
  2374. X    node **n_ret;
  2375. X{
  2376. X    int err = parsestring(str, &gram, start, n_ret);
  2377. X    /* Don't confuse early end of string with early end of input */
  2378. X    if (err == E_EOF)
  2379. X        err = E_SYNTAX;
  2380. X    return err;
  2381. X}
  2382. X
  2383. X/* Print fatal error message and abort */
  2384. X
  2385. Xvoid
  2386. Xfatal(msg)
  2387. X    char *msg;
  2388. X{
  2389. X    fprintf(stderr, "Fatal error: %s\n", msg);
  2390. X    abort();
  2391. X}
  2392. X
  2393. X/* Clean up and exit */
  2394. X
  2395. Xvoid
  2396. Xgoaway(sts)
  2397. X    int sts;
  2398. X{
  2399. X    flushline();
  2400. X    
  2401. X    /* XXX Call doneimport() before donecalls(), since donecalls()
  2402. X       calls wdone(), and doneimport() may close windows */
  2403. X    doneimport();
  2404. X    donecalls();
  2405. X    
  2406. X    err_clear();
  2407. X
  2408. X#ifdef REF_DEBUG
  2409. X    fprintf(stderr, "[%ld refs]\n", ref_total);
  2410. X#endif
  2411. X
  2412. X#ifdef THINK_C_3_0
  2413. X    if (sts == 0)
  2414. X        Click_On(0);
  2415. X#endif
  2416. X
  2417. X#ifdef TRACE_REFS
  2418. X    if (askyesno("Print left references?")) {
  2419. X#ifdef THINK_C_3_0
  2420. X        Click_On(1);
  2421. X#endif
  2422. X        printrefs(stderr);
  2423. X    }
  2424. X#endif /* TRACE_REFS */
  2425. X
  2426. X    exit(sts);
  2427. X    /*NOTREACHED*/
  2428. X}
  2429. X
  2430. Xstatic
  2431. Xfinaloutput()
  2432. X{
  2433. X#ifdef TRACE_REFS
  2434. X    if (!askyesno("Print left references?"))
  2435. X        return;
  2436. X#ifdef THINK_C_3_0
  2437. X    Click_On(1);
  2438. X#endif
  2439. X    printrefs(stderr);
  2440. X#endif /* TRACE_REFS */
  2441. X}
  2442. X
  2443. X/* Ask a yes/no question */
  2444. X
  2445. Xstatic int
  2446. Xaskyesno(prompt)
  2447. X    char *prompt;
  2448. X{
  2449. X    char buf[256];
  2450. X    
  2451. X    printf("%s [ny] ", prompt);
  2452. X    if (fgets(buf, sizeof buf, stdin) == NULL)
  2453. X        return 0;
  2454. X    return buf[0] == 'y' || buf[0] == 'Y';
  2455. X}
  2456. X
  2457. X#ifdef THINK_C_3_0
  2458. X
  2459. X/* Check for file descriptor connected to interactive device.
  2460. X   Pretend that stdin is always interactive, other files never. */
  2461. X
  2462. Xint
  2463. Xisatty(fd)
  2464. X    int fd;
  2465. X{
  2466. X    return fd == fileno(stdin);
  2467. X}
  2468. X
  2469. X#endif
  2470. X
  2471. X/*    XXX WISH LIST
  2472. X
  2473. X    - possible new types:
  2474. X        - iterator (for range, keys, ...)
  2475. X    - improve interpreter error handling, e.g., true tracebacks
  2476. X    - save precompiled modules on file?
  2477. X    - fork threads, locking
  2478. X    - allow syntax extensions
  2479. X*/
  2480. X
  2481. X/* "Floccinaucinihilipilification" */
  2482. EOF
  2483. fi
  2484. if test -s 'src/stringobject.c'
  2485. then echo '*** I will not over-write existing file src/stringobject.c'
  2486. else
  2487. echo 'x - src/stringobject.c'
  2488. sed 's/^X//' > 'src/stringobject.c' << 'EOF'
  2489. X/***********************************************************
  2490. XCopyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
  2491. XNetherlands.
  2492. X
  2493. X                        All Rights Reserved
  2494. X
  2495. XPermission to use, copy, modify, and distribute this software and its 
  2496. Xdocumentation for any purpose and without fee is hereby granted, 
  2497. Xprovided that the above copyright notice appear in all copies and that
  2498. Xboth that copyright notice and this permission notice appear in 
  2499. Xsupporting documentation, and that the names of Stichting Mathematisch
  2500. XCentrum or CWI not be used in advertising or publicity pertaining to
  2501. Xdistribution of the software without specific, written prior permission.
  2502. X
  2503. XSTICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  2504. XTHIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  2505. XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  2506. XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  2507. XWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  2508. XACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  2509. XOF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  2510. X
  2511. X******************************************************************/
  2512. X
  2513. X/* String object implementation */
  2514. X
  2515. X#include "allobjects.h"
  2516. X
  2517. Xobject *
  2518. Xnewsizedstringobject(str, size)
  2519. X    char *str;
  2520. X    int size;
  2521. X{
  2522. X    register stringobject *op = (stringobject *)
  2523. X        malloc(sizeof(stringobject) + size * sizeof(char));
  2524. X    if (op == NULL)
  2525. X        return err_nomem();
  2526. X    NEWREF(op);
  2527. X    op->ob_type = &Stringtype;
  2528. X    op->ob_size = size;
  2529. X    if (str != NULL)
  2530. X        memcpy(op->ob_sval, str, size);
  2531. X    op->ob_sval[size] = '\0';
  2532. X    return (object *) op;
  2533. X}
  2534. X
  2535. Xobject *
  2536. Xnewstringobject(str)
  2537. X    char *str;
  2538. X{
  2539. X    register unsigned int size = strlen(str);
  2540. X    register stringobject *op = (stringobject *)
  2541. X        malloc(sizeof(stringobject) + size * sizeof(char));
  2542. X    if (op == NULL)
  2543. X        return err_nomem();
  2544. X    NEWREF(op);
  2545. X    op->ob_type = &Stringtype;
  2546. X    op->ob_size = size;
  2547. X    strcpy(op->ob_sval, str);
  2548. X    return (object *) op;
  2549. X}
  2550. X
  2551. Xunsigned int
  2552. Xgetstringsize(op)
  2553. X    register object *op;
  2554. X{
  2555. X    if (!is_stringobject(op)) {
  2556. X        err_badcall();
  2557. X        return -1;
  2558. X    }
  2559. X    return ((stringobject *)op) -> ob_size;
  2560. X}
  2561. X
  2562. X/*const*/ char *
  2563. Xgetstringvalue(op)
  2564. X    register object *op;
  2565. X{
  2566. X    if (!is_stringobject(op)) {
  2567. X        err_badcall();
  2568. X        return NULL;
  2569. X    }
  2570. X    return ((stringobject *)op) -> ob_sval;
  2571. X}
  2572. X
  2573. X/* Methods */
  2574. X
  2575. Xstatic void
  2576. Xstringprint(op, fp, flags)
  2577. X    stringobject *op;
  2578. X    FILE *fp;
  2579. X    int flags;
  2580. X{
  2581. X    int i;
  2582. X    char c;
  2583. X    if (flags & PRINT_RAW) {
  2584. X        fwrite(op->ob_sval, 1, (int) op->ob_size, fp);
  2585. X        return;
  2586. X    }
  2587. X    fprintf(fp, "'");
  2588. X    for (i = 0; i < op->ob_size; i++) {
  2589. X        c = op->ob_sval[i];
  2590. X        if (c == '\'' || c == '\\')
  2591. X            fprintf(fp, "\\%c", c);
  2592. X        else if (c < ' ' || c >= 0177)
  2593. X            fprintf(fp, "\\%03o", c&0377);
  2594. X        else
  2595. X            putc(c, fp);
  2596. X    }
  2597. X    fprintf(fp, "'");
  2598. X}
  2599. X
  2600. Xstatic object *
  2601. Xstringrepr(op)
  2602. X    register stringobject *op;
  2603. X{
  2604. X    /* XXX overflow? */
  2605. X    int newsize = 2 + 4 * op->ob_size * sizeof(char);
  2606. X    object *v = newsizedstringobject((char *)NULL, newsize);
  2607. X    if (v == NULL) {
  2608. X        return err_nomem();
  2609. X    }
  2610. X    else {
  2611. X        register int i;
  2612. X        register char c;
  2613. X        register char *p;
  2614. X        NEWREF(v);
  2615. X        v->ob_type = &Stringtype;
  2616. X        ((stringobject *)v)->ob_size = newsize;
  2617. X        p = ((stringobject *)v)->ob_sval;
  2618. X        *p++ = '\'';
  2619. X        for (i = 0; i < op->ob_size; i++) {
  2620. X            c = op->ob_sval[i];
  2621. X            if (c == '\'' || c == '\\')
  2622. X                *p++ = '\\', *p++ = c;
  2623. X            else if (c < ' ' || c >= 0177) {
  2624. X                sprintf(p, "\\%03o", c&0377);
  2625. X                while (*p != '\0')
  2626. X                    p++;
  2627. X                
  2628. X            }
  2629. X            else
  2630. X                *p++ = c;
  2631. X        }
  2632. X        *p++ = '\'';
  2633. X        *p = '\0';
  2634. X        resizestring(&v, (int) (p - ((stringobject *)v)->ob_sval));
  2635. X        return v;
  2636. X    }
  2637. X}
  2638. X
  2639. Xstatic int
  2640. Xstringlength(a)
  2641. X    stringobject *a;
  2642. X{
  2643. X    return a->ob_size;
  2644. X}
  2645. X
  2646. Xstatic object *
  2647. Xstringconcat(a, bb)
  2648. X    register stringobject *a;
  2649. X    register object *bb;
  2650. X{
  2651. X    register unsigned int size;
  2652. X    register stringobject *op;
  2653. X    if (!is_stringobject(bb)) {
  2654. X        err_badarg();
  2655. X        return NULL;
  2656. X    }
  2657. X#define b ((stringobject *)bb)
  2658. X    /* Optimize cases with empty left or right operand */
  2659. X    if (a->ob_size == 0) {
  2660. X        INCREF(bb);
  2661. X        return bb;
  2662. X    }
  2663. X    if (b->ob_size == 0) {
  2664. X        INCREF(a);
  2665. X        return (object *)a;
  2666. X    }
  2667. X    size = a->ob_size + b->ob_size;
  2668. X    op = (stringobject *)
  2669. X        malloc(sizeof(stringobject) + size * sizeof(char));
  2670. X    if (op == NULL)
  2671. X        return err_nomem();
  2672. X    NEWREF(op);
  2673. X    op->ob_type = &Stringtype;
  2674. X    op->ob_size = size;
  2675. X    memcpy(op->ob_sval, a->ob_sval, (int) a->ob_size);
  2676. X    memcpy(op->ob_sval + a->ob_size, b->ob_sval, (int) b->ob_size);
  2677. X    op->ob_sval[size] = '\0';
  2678. X    return (object *) op;
  2679. X#undef b
  2680. X}
  2681. X
  2682. Xstatic object *
  2683. Xstringrepeat(a, n)
  2684. X    register stringobject *a;
  2685. X    register int n;
  2686. X{
  2687. X    register int i;
  2688. X    register unsigned int size;
  2689. X    register stringobject *op;
  2690. X    if (n < 0)
  2691. X        n = 0;
  2692. X    size = a->ob_size * n;
  2693. X    if (size == a->ob_size) {
  2694. X        INCREF(a);
  2695. X        return (object *)a;
  2696. X    }
  2697. X    op = (stringobject *)
  2698. X        malloc(sizeof(stringobject) + size * sizeof(char));
  2699. X    if (op == NULL)
  2700. X        return err_nomem();
  2701. X    NEWREF(op);
  2702. X    op->ob_type = &Stringtype;
  2703. X    op->ob_size = size;
  2704. X    for (i = 0; i < size; i += a->ob_size)
  2705. X        memcpy(op->ob_sval+i, a->ob_sval, (int) a->ob_size);
  2706. X    op->ob_sval[size] = '\0';
  2707. X    return (object *) op;
  2708. X}
  2709. X
  2710. X/* String slice a[i:j] consists of characters a[i] ... a[j-1] */
  2711. X
  2712. Xstatic object *
  2713. Xstringslice(a, i, j)
  2714. X    register stringobject *a;
  2715. X    register int i, j; /* May be negative! */
  2716. X{
  2717. X    if (i < 0)
  2718. X        i = 0;
  2719. X    if (j < 0)
  2720. X        j = 0; /* Avoid signed/unsigned bug in next line */
  2721. X    if (j > a->ob_size)
  2722. X        j = a->ob_size;
  2723. X    if (i == 0 && j == a->ob_size) { /* It's the same as a */
  2724. X        INCREF(a);
  2725. X        return (object *)a;
  2726. X    }
  2727. X    if (j < i)
  2728. X        j = i;
  2729. X    return newsizedstringobject(a->ob_sval + i, (int) (j-i));
  2730. X}
  2731. X
  2732. Xstatic object *
  2733. Xstringitem(a, i)
  2734. X    stringobject *a;
  2735. X    register int i;
  2736. X{
  2737. X    if (i < 0 || i >= a->ob_size) {
  2738. X        err_setstr(IndexError, "string index out of range");
  2739. X        return NULL;
  2740. X    }
  2741. X    return stringslice(a, i, i+1);
  2742. X}
  2743. X
  2744. Xstatic int
  2745. Xstringcompare(a, b)
  2746. X    stringobject *a, *b;
  2747. X{
  2748. X    int len_a = a->ob_size, len_b = b->ob_size;
  2749. X    int min_len = (len_a < len_b) ? len_a : len_b;
  2750. X    int cmp = memcmp(a->ob_sval, b->ob_sval, min_len);
  2751. X    if (cmp != 0)
  2752. X        return cmp;
  2753. X    return (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0;
  2754. X}
  2755. X
  2756. Xstatic sequence_methods string_as_sequence = {
  2757. X    stringlength,    /*tp_length*/
  2758. X    stringconcat,    /*tp_concat*/
  2759. X    stringrepeat,    /*tp_repeat*/
  2760. X    stringitem,    /*tp_item*/
  2761. X    stringslice,    /*tp_slice*/
  2762. X    0,    /*tp_ass_item*/
  2763. X    0,    /*tp_ass_slice*/
  2764. X};
  2765. X
  2766. Xtypeobject Stringtype = {
  2767. X    OB_HEAD_INIT(&Typetype)
  2768. X    0,
  2769. X    "string",
  2770. X    sizeof(stringobject),
  2771. X    sizeof(char),
  2772. X    free,        /*tp_dealloc*/
  2773. X    stringprint,    /*tp_print*/
  2774. X    0,        /*tp_getattr*/
  2775. X    0,        /*tp_setattr*/
  2776. X    stringcompare,    /*tp_compare*/
  2777. X    stringrepr,    /*tp_repr*/
  2778. X    0,        /*tp_as_number*/
  2779. X    &string_as_sequence,    /*tp_as_sequence*/
  2780. X    0,        /*tp_as_mapping*/
  2781. X};
  2782. X
  2783. Xvoid
  2784. Xjoinstring(pv, w)
  2785. X    register object **pv;
  2786. X    register object *w;
  2787. X{
  2788. X    register object *v;
  2789. X    if (*pv == NULL || w == NULL || !is_stringobject(*pv))
  2790. X        return;
  2791. X    v = stringconcat((stringobject *) *pv, w);
  2792. X    DECREF(*pv);
  2793. X    *pv = v;
  2794. X}
  2795. X
  2796. X/* The following function breaks the notion that strings are immutable:
  2797. X   it changes the size of a string.  We get away with this only if there
  2798. X   is only one module referencing the object.  You can also think of it
  2799. X   as creating a new string object and destroying the old one, only
  2800. X   more efficiently.  In any case, don't use this if the string may
  2801. X   already be known to some other part of the code... */
  2802. X
  2803. Xint
  2804. Xresizestring(pv, newsize)
  2805. X    object **pv;
  2806. X    int newsize;
  2807. X{
  2808. X    register object *v;
  2809. X    register stringobject *sv;
  2810. X    v = *pv;
  2811. X    if (!is_stringobject(v) || v->ob_refcnt != 1) {
  2812. X        *pv = 0;
  2813. X        DECREF(v);
  2814. X        err_badcall();
  2815. X        return -1;
  2816. X    }
  2817. X    /* XXX UNREF/NEWREF interface should be more symmetrical */
  2818. X#ifdef REF_DEBUG
  2819. X    --ref_total;
  2820. X#endif
  2821. X    UNREF(v);
  2822. X    *pv = (object *)
  2823. X        realloc((char *)v,
  2824. X            sizeof(stringobject) + newsize * sizeof(char));
  2825. X    if (*pv == NULL) {
  2826. X        DEL(v);
  2827. X        err_nomem();
  2828. X        return -1;
  2829. X    }
  2830. X    NEWREF(*pv);
  2831. X    sv = (stringobject *) *pv;
  2832. X    sv->ob_size = newsize;
  2833. X    sv->ob_sval[newsize] = '\0';
  2834. X    return 0;
  2835. X}
  2836. EOF
  2837. fi
  2838. echo 'Part 12 out of 21 of pack.out complete.'
  2839. exit 0
  2840.