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

  1. From: guido@cwi.nl (Guido van Rossum)
  2. Newsgroups: alt.sources
  3. Subject: Python 0.9.1 part 14/21
  4. Message-ID: <2976@charon.cwi.nl>
  5. Date: 19 Feb 91 17:42:20 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 14 out of 21:'
  12. if test -s 'demo/sgi/audio_stdwin/rec.py'
  13. then echo '*** I will not over-write existing file demo/sgi/audio_stdwin/rec.py'
  14. else
  15. echo 'x - demo/sgi/audio_stdwin/rec.py'
  16. sed 's/^X//' > 'demo/sgi/audio_stdwin/rec.py' << 'EOF'
  17. X#! /ufs/guido/bin/sgi/python
  18. X
  19. Ximport sys
  20. Ximport audio
  21. Ximport stdwin
  22. X
  23. Ximport string
  24. Ximport getopt
  25. X
  26. Xfrom stdwinevents import *
  27. Xfrom Buttons import *
  28. Xfrom Sliders import *
  29. X#from Soundogram import Soundogram
  30. Xfrom VUMeter import VUMeter
  31. Xfrom WindowParent import WindowParent
  32. Xfrom HVSplit import HSplit, VSplit
  33. X
  34. Xclass TimeOutToggleButton() = ToggleButton():
  35. X    def define(self, parent):
  36. X        self = ToggleButton.define(self, parent)
  37. X        self.parent.need_timer(self)
  38. X        self.timer_hook = 0
  39. X        return self
  40. X    def timer(self):
  41. X        if self.timer_hook:
  42. X            self.timer_hook(self)
  43. X
  44. XK = 1024
  45. XBUFSIZE = 30*8*K
  46. XRates = [0, 32*K, 16*K, 8*K]
  47. XMagics = ['', '0032', '0016', '0008']
  48. X
  49. Xclass Struct(): pass
  50. XG = Struct()
  51. X
  52. Xdef main():
  53. X    #
  54. X    # Set default state
  55. X    #
  56. X    G.gain = 60
  57. X    G.rate = 3
  58. X    G.nomuting = 0
  59. X    G.savefile = '@rec'
  60. X    #
  61. X    # Set default values
  62. X    #
  63. X    G.data = ''
  64. X    G.playing = 0
  65. X    G.recording = 0
  66. X    G.sogram = 0
  67. X    #
  68. X    # Parse options
  69. X    #
  70. X    optlist, args = getopt.getopt(sys.argv[1:], 'mdg:r:')
  71. X    #
  72. X    for optname, optarg in optlist:
  73. X        if 0: # (So all cases start with elif)
  74. X            pass
  75. X        elif optname = '-d':
  76. X            G.debug = 1
  77. X        elif optname = '-g':
  78. X            G.gain = string.atoi(optarg)
  79. X            if not (0 < G.gain < 256):
  80. X                raise optarg.error, '-g gain out of range'
  81. X        elif optname = '-m':
  82. X            G.nomuting = (not G.nomuting)
  83. X        elif optname = '-r':
  84. X            G.rate = string.atoi(optarg)
  85. X            if not (1 <= G.rate <= 3):
  86. X                raise optarg.error, '-r rate out of range'
  87. X    #
  88. X    if args:
  89. X        G.savefile = args[0]
  90. X    #
  91. X    # Initialize the sound package
  92. X    #
  93. X    audio.setoutgain(G.nomuting * G.gain)    # Silence the speaker
  94. X    audio.setrate(G.rate)
  95. X    #
  96. X    # Create the WindowParent and VSplit
  97. X    #
  98. X    G.window = WindowParent().create('Recorder', (0, 0))
  99. X    w = G.vsplit = VSplit().create(G.window)
  100. X    #
  101. X    # VU-meter
  102. X    #
  103. X    G.vubtn = VUMeter().define(w)
  104. X    #
  105. X    # Radiobuttons for rates
  106. X    #
  107. X    r1btn = RadioButton().definetext(w, '32 K/sec')
  108. X    r1btn.on_hook = rate_hook
  109. X    r1btn.rate = 1
  110. X    #
  111. X    r2btn = RadioButton().definetext(w, '16 K/sec')
  112. X    r2btn.on_hook = rate_hook
  113. X    r2btn.rate = 2
  114. X    #
  115. X    r3btn = RadioButton().definetext(w, '8 K/sec')
  116. X    r3btn.on_hook = rate_hook
  117. X    r3btn.rate = 3
  118. X    #
  119. X    radios = [r1btn, r2btn, r3btn]
  120. X    r1btn.group = r2btn.group = r3btn.group = radios
  121. X    for r in radios:
  122. X        if r.rate = G.rate: r.select(1)
  123. X    #
  124. X    # Other controls
  125. X    #
  126. X    G.recbtn = TimeOutToggleButton().definetext(w, 'Record')
  127. X    G.recbtn.on_hook = record_on_hook
  128. X    G.recbtn.timer_hook = record_timer_hook
  129. X    G.recbtn.off_hook = record_off_hook
  130. X    #
  131. X    G.mutebtn = CheckButton().definetext(w, 'Mute')
  132. X    G.mutebtn.select(not G.nomuting)
  133. X    G.mutebtn.hook = mute_hook
  134. X    #
  135. X    G.playbtn = TimeOutToggleButton().definetext(w, 'Playback')
  136. X    G.playbtn.on_hook = play_on_hook
  137. X    G.playbtn.timer_hook = play_timer_hook
  138. X    G.playbtn.off_hook = play_off_hook
  139. X    #
  140. X    G.gainbtn = ComplexSlider().define(w)
  141. X    G.gainbtn.settexts('  Volume: ', '  ')
  142. X    G.gainbtn.setminvalmax(0, G.gain, 255)
  143. X    G.gainbtn.sethook(gain_hook)
  144. X    #
  145. X    G.sizebtn = Label().definetext(w, `len(G.data)` + ' bytes')
  146. X    #
  147. X    #G.showbtn = PushButton().definetext(w, 'Sound-o-gram...')
  148. X    #G.showbtn.hook = show_hook
  149. X    #
  150. X    G.savebtn = PushButton().definetext(w, 'Save...')
  151. X    G.savebtn.hook = save_hook
  152. X    #
  153. X    G.quitbtn = PushButton().definetext(w, 'Quit')
  154. X    G.quitbtn.hook = quit_hook
  155. X    G.playbtn.enable(0)
  156. X    G.savebtn.enable(0)
  157. X    #G.showbtn.enable(0)
  158. X    start_vu()
  159. X    G.window.realize()
  160. X    #
  161. X    # Event loop
  162. X    #
  163. X    while 1:
  164. X        e = stdwin.getevent()
  165. X        G.window.dispatch(e)
  166. X
  167. X# XXX Disabled...
  168. Xdef show_hook(self):
  169. X    savetext = self.text
  170. X    self.settext('Be patient...')
  171. X    close_sogram()
  172. X    stdwin.setdefwinsize(400, 300)
  173. X    win = stdwin.open('Sound-o-gram')
  174. X    G.sogram = Soundogram().define(win, G.data)
  175. X    win.buttons = [G.sogram]
  176. X    self.settext(savetext)
  177. X
  178. Xdef close_sogram():
  179. X    if G.sogram:
  180. X        # Break circular references
  181. X        G.sogram.win.buttons[:] = []
  182. X        del G.sogram.win
  183. X        G.sogram = 0
  184. X
  185. Xdef mute_hook(self):
  186. X    G.nomuting = (not self.selected)
  187. X    audio.setoutgain(G.nomuting * G.gain)
  188. X
  189. Xdef rate_hook(self):
  190. X    G.rate = self.rate
  191. X    audio.setrate(G.rate)
  192. X
  193. Xdef record_on_hook(self):
  194. X    stop_vu()
  195. X    close_sogram()
  196. X    audio.setrate(G.rate)
  197. X    audio.setoutgain(G.nomuting * G.gain)
  198. X    audio.start_recording(BUFSIZE)
  199. X    G.recording = 1
  200. X    G.playbtn.enable(0)
  201. X    G.window.settimer(10 * BUFSIZE / Rates[G.rate])
  202. X
  203. Xdef record_timer_hook(self):
  204. X    if G.recording:
  205. X        if audio.poll_recording():
  206. X            self.hilite(0)
  207. X            record_off_hook(self)
  208. X        else:
  209. X            self.parent.settimer(5)
  210. X
  211. Xdef record_off_hook(self):
  212. X    if not G.recording:
  213. X        return
  214. X    G.data = audio.stop_recording()
  215. X    G.recording = 0
  216. X    G.sizebtn.settext(`len(G.data)` + ' bytes')
  217. X    audio.setoutgain(G.nomuting * G.gain)
  218. X    G.playbtn.enable((len(G.data) > 0))
  219. X    G.savebtn.enable((len(G.data) > 0))
  220. X    #G.showbtn.enable((len(G.data) > 0))
  221. X    G.window.settimer(0)
  222. X    start_vu()
  223. X
  224. Xdef play_on_hook(self):
  225. X    stop_vu()
  226. X    audio.setrate(G.rate)
  227. X    audio.setoutgain(G.gain)
  228. X    audio.start_playing(G.data)
  229. X    G.playing = 1
  230. X    G.recbtn.enable(0)
  231. X    G.window.settimer(max(10 * len(G.data) / Rates[G.rate], 1))
  232. X
  233. Xdef play_timer_hook(self):
  234. X    if G.playing:
  235. X        if audio.poll_playing():
  236. X            self.hilite(0)
  237. X            play_off_hook(self)
  238. X        else:
  239. X            self.parent.settimer(5)
  240. X
  241. Xdef play_off_hook(self):
  242. X    if not G.playing:
  243. X        return
  244. X    x = audio.stop_playing()
  245. X    G.playing = 0
  246. X    audio.setoutgain(G.nomuting * G.gain)
  247. X    G.recbtn.enable(1)
  248. X    G.window.settimer(0)
  249. X    start_vu()
  250. X
  251. Xdef gain_hook(self):
  252. X    G.gain = self.val
  253. X    if G.playing or G.nomuting: audio.setoutgain(G.gain)
  254. X
  255. Xdef save_hook(self):
  256. X    if not G.data:
  257. X        stdwin.fleep()
  258. X    else:
  259. X        prompt = 'Store sampled data on file: '
  260. X        try:
  261. X            G.savefile = stdwin.askfile(prompt, G.savefile, 1)
  262. X        except KeyboardInterrupt:
  263. X            return
  264. X        try:
  265. X            fp = open(G.savefile, 'w')
  266. X            fp.write(Magics[G.rate] + G.data)
  267. X        except:
  268. X            stdwin.message('Cannot create ' + file)
  269. X
  270. Xdef stop_vu():
  271. X    G.vubtn.stop()
  272. X
  273. Xdef start_vu():
  274. X    G.vubtn.start()
  275. X
  276. XExit = 'exit' # exception
  277. X
  278. Xdef quit_hook(self):
  279. X    raise Exit, 0
  280. X
  281. Xtry:
  282. X    try:
  283. X        main()
  284. X    finally:
  285. X        audio.setoutgain(0)
  286. Xexcept Exit, sts:
  287. X    sys.exit(sts)
  288. EOF
  289. chmod +x 'demo/sgi/audio_stdwin/rec.py'
  290. fi
  291. if test -s 'lib/TclShell.py'
  292. then echo '*** I will not over-write existing file lib/TclShell.py'
  293. else
  294. echo 'x - lib/TclShell.py'
  295. sed 's/^X//' > 'lib/TclShell.py' << 'EOF'
  296. X# Tcl-based shell (for the Macintosh)
  297. X
  298. Ximport TclUtil
  299. Ximport Tcl
  300. Xfrom Tcl import Interpreter, TclRuntimeError
  301. Ximport mac
  302. Ximport macpath
  303. Xfrom macpath import isfile, isdir, exists
  304. X
  305. XUsageError = TclRuntimeError
  306. X
  307. Xclass ShellInterpreter() = Interpreter():
  308. X    #
  309. X    def ResetVariables(interp):
  310. X        interp.globals['ps1'] = '$ '
  311. X        interp.globals['ps2'] = '> '
  312. X        interp.globals['home'] = mac.getcwd()
  313. X    #
  314. X    def DefineCommands(interp):
  315. X        interp.commands['cd'] = interp.CdCmd
  316. X        interp.commands['grep'] = interp.GrepCmd
  317. X        interp.commands['ls'] = interp.LsCmd
  318. X        interp.commands['mkdir'] = interp.MkdirCmd
  319. X        interp.commands['mv'] = interp.MvCmd
  320. X        interp.commands['pg'] = interp.PgCmd
  321. X        interp.commands['pwd'] = interp.PwdCmd
  322. X        interp.commands['rm'] = interp.RmCmd
  323. X        interp.commands['rmdir'] = interp.RmdirCmd
  324. X        interp.commands['sync'] = interp.SyncCmd
  325. X    #
  326. X    def Reset(interp):
  327. X        interp.ResetVariables()
  328. X        interp.DefineCommands()
  329. X    #
  330. X    def Create(interp):
  331. X        interp = Interpreter.Create(interp) # initialize base class
  332. X        interp.Reset()
  333. X        return interp
  334. X    #
  335. X    # Command-implementing functions
  336. X    #
  337. X    def CdCmd(interp, argv):
  338. X        if len(argv) > 2:
  339. X            raise UsageError, 'usage: cd [dirname]'
  340. X        if len(argv) = 2:
  341. X            chdirto(argv[1])
  342. X        else:
  343. X            chdirto(interp.globals['home'])
  344. X        return ''
  345. X    #
  346. X    def GrepCmd(interp, argv):
  347. X        if len(argv) < 3:
  348. X            raise UsageError, 'usage: grep regexp file ...'
  349. X        import regexp
  350. X        try:
  351. X            prog = regexp.compile(argv[1])
  352. X        except regexp.error, msg:
  353. X            raise TclRuntimeError, \
  354. X              ('grep', argv[1], ': bad regexp :', msg)
  355. X        for file in argv[2:]:
  356. X            grepfile(prog, file)
  357. X        return ''
  358. X    #
  359. X    def LsCmd(interp, argv):
  360. X        if len(argv) < 2:
  361. X            lsdir(':')
  362. X        else:
  363. X            for dirname in argv[1:]:
  364. X                lsdir(dirname)
  365. X        return ''
  366. X    #
  367. X    def MkdirCmd(interp, argv):
  368. X        if len(argv) < 2:
  369. X            raise UsageError, 'usage: mkdir name ...'
  370. X        for name in argv[1:]:
  371. X            makedir(name)
  372. X        return ''
  373. X    #
  374. X    def MvCmd(interp, argv):
  375. X        if len(argv) <> 3:
  376. X            raise UsageError, 'usage: mv src dst'
  377. X        src, dst = argv[1], argv[2]
  378. X        if not exists(src):
  379. X            raise TclRuntimeError, \
  380. X              ('mv', src, dst, ': source does not exist')
  381. X        if exists(dst):
  382. X            raise TclRuntimeError, \
  383. X              ('mv', src, dst, ': destination already exists')
  384. X        try:
  385. X            mac.rename(src, dst)
  386. X        except mac.error, msg:
  387. X            raise TclRuntimeError, \
  388. X                (src, dst, ': rename failed :', msg)
  389. X        return ''
  390. X    #
  391. X    def PgCmd(interp, argv):
  392. X        if len(argv) < 2:
  393. X            raise UsageError, 'usage: page file ...'
  394. X        for name in argv[1:]:
  395. X            pagefile(name)
  396. X        return ''
  397. X    #
  398. X    def PwdCmd(interp, argv):
  399. X        if len(argv) > 1:
  400. X            raise UsageError, 'usage: pwd'
  401. X        else:
  402. X            return mac.getcwd()
  403. X    #
  404. X    def RmCmd(interp, argv):
  405. X        if len(argv) < 2:
  406. X            raise UsageError, 'usage: rm file ...'
  407. X        for name in argv[1:]:
  408. X            remove(name)
  409. X        return ''
  410. X    #
  411. X    def RmdirCmd(interp, argv):
  412. X        if len(argv) < 2:
  413. X            raise UsageError, 'usage: rmdir dir ...'
  414. X        for name in argv[1:]:
  415. X            rmdir(name)
  416. X        return ''
  417. X    #
  418. X    def SyncCmd(interp, argv):
  419. X        if len(argv) > 1:
  420. X            raise UsageError, 'usage: sync'
  421. X        try:
  422. X            mac.sync()
  423. X        except mac.error, msg:
  424. X            raise TclRuntimeError, ('sync failed :', msg)
  425. X    #
  426. X
  427. Xdef chdirto(dirname):
  428. X    try:
  429. X        mac.chdir(dirname)
  430. X    except mac.error, msg:
  431. X        raise TclRuntimeError, (dirname, ': chdir failed :', msg)
  432. X
  433. Xdef grepfile(prog, file):
  434. X    try:
  435. X        fp = open(file, 'r')
  436. X    except RuntimeError, msg:
  437. X        raise TclRuntimeError, (file, ': open failed :', msg)
  438. X    lineno = 0
  439. X    while 1:
  440. X        line = fp.readline()
  441. X        if not line: break
  442. X        lineno = lineno+1
  443. X        if prog.exec(line):
  444. X            print file+'('+`lineno`+'):', line,
  445. X
  446. Xdef lsdir(dirname):
  447. X    if not isdir(dirname):
  448. X        print dirname, ': no such directory'
  449. X        return
  450. X    names = mac.listdir(dirname)
  451. X    lsfiles(names, dirname)
  452. X
  453. Xdef lsfiles(names, dirname):
  454. X    names = names[:] # Make a copy so we can modify it
  455. X    for i in range(len(names)):
  456. X        name = names[i]
  457. X        if isdir(macpath.cat(dirname, name)):
  458. X            names[i] = ':' + name + ':'
  459. X    columnize(names)
  460. X
  461. Xdef makedir(name):
  462. X    if exists(name):
  463. X        print name, ': already exists'
  464. X        return
  465. X    try:
  466. X        mac.mkdir(name, 0777)
  467. X    except mac.error, msg:
  468. X        raise TclRuntimeError, (name, ': mkdir failed :', msg)
  469. X
  470. Xdef pagefile(name):
  471. X    import string
  472. X    if not isfile(name):
  473. X        print name, ': no such file'
  474. X        return
  475. X    LINES = 24 - 1
  476. X    # For THINK C 3.0, make the path absolute:
  477. X    # if not macpath.isabs(name):
  478. X    #     name = macpath.cat(mac.getcwd(), name)
  479. X    try:
  480. X        fp = open(name, 'r')
  481. X    except RuntimeError, msg:
  482. X        raise TclRuntimeError, (name, ': open failed :', msg)
  483. X    line = fp.readline()
  484. X    while line:
  485. X        for i in range(LINES):
  486. X            print line,
  487. X            line = fp.readline()
  488. X            if not line: break
  489. X        if line:
  490. X            try:
  491. X                more = raw_input('[more]')
  492. X            except (EOFError, KeyboardInterrupt):
  493. X                print
  494. X                break
  495. X            if string.strip(more)[:1] in ('q', 'Q'):
  496. X                break
  497. X
  498. Xdef remove(name):
  499. X    if not isfile(name):
  500. X        print name, ': no such file'
  501. X        return
  502. X    try:
  503. X        mac.unlink(name)
  504. X    except mac.error, msg:
  505. X        raise TclRuntimeError, (name, ': unlink failed :', msg)
  506. X
  507. Xdef rmdir(name):
  508. X    if not isdir(name):
  509. X        raise TclRuntimeError, (name, ': no such directory')
  510. X    try:
  511. X        mac.rmdir(name)
  512. X    except mac.error, msg:
  513. X        raise TclRuntimeError, (name, ': rmdir failed :', msg)
  514. X
  515. Xdef printlist(list):
  516. X    for word in list:
  517. X        print word,
  518. X
  519. Xdef columnize(list):
  520. X    import string
  521. X    COLUMNS = 80-1
  522. X    n = len(list)
  523. X    colwidth = maxwidth(list)
  524. X    ncols = (COLUMNS + 1) / (colwidth + 1)
  525. X    if ncols < 1: ncols = 1
  526. X    nrows = (n + ncols - 1) / ncols
  527. X    for irow in range(nrows):
  528. X        line = ''
  529. X        for icol in range(ncols):
  530. X            i = irow + nrows*icol
  531. X            if 0 <= i < n:
  532. X                word = list[i]
  533. X                if i+nrows < n:
  534. X                    word = string.ljust(word, colwidth)
  535. X                if icol > 0:
  536. X                    word = ' ' + word
  537. X                line = line + word
  538. X        print line
  539. X
  540. Xdef maxwidth(list):
  541. X    width = 0
  542. X    for word in list:
  543. X        if len(word) > width:
  544. X            width = len(word)
  545. X    return width
  546. X
  547. Xthe_interpreter = ShellInterpreter().Create()
  548. X
  549. Xdef main():
  550. X    Tcl.MainLoop(the_interpreter)
  551. EOF
  552. fi
  553. if test -s 'lib/tablewin.py'
  554. then echo '*** I will not over-write existing file lib/tablewin.py'
  555. else
  556. echo 'x - lib/tablewin.py'
  557. sed 's/^X//' > 'lib/tablewin.py' << 'EOF'
  558. X# Module 'tablewin'
  559. X
  560. X# Display a table, with per-item actions:
  561. X
  562. X#       A1   |   A2   |   A3   |  ....  |   AN
  563. X#       B1   |   B2   |   B3   |  ....  |   BN
  564. X#       C1   |   C2   |   C3   |  ....  |   CN
  565. X#       ..   |   ..   |   ..   |  ....  |   ..
  566. X#       Z1   |   Z2   |   Z3   |  ....  |   ZN
  567. X
  568. X# Not all columns need to have the same length.
  569. X# The data structure is a list of columns;
  570. X# each column is a list of items.
  571. X# Each item is a pair of a string and an action procedure.
  572. X# The first item may be a column title.
  573. X
  574. Ximport stdwin
  575. Ximport gwin
  576. X
  577. Xdef open(title, data): # Public function to open a table window
  578. X    #
  579. X    # Set geometry parameters (one day, these may be changeable)
  580. X    #
  581. X    margin = stdwin.textwidth('  ')
  582. X    lineheight = stdwin.lineheight()
  583. X    #
  584. X    # Geometry calculations
  585. X    #
  586. X    colstarts = [0]
  587. X    totwidth = 0
  588. X    maxrows = 0
  589. X    for coldata in data:
  590. X        # Height calculations
  591. X        rows = len(coldata)
  592. X        if rows > maxrows: maxrows = rows
  593. X        # Width calculations
  594. X        width = colwidth(coldata) + margin
  595. X        totwidth = totwidth + width
  596. X        colstarts.append(totwidth)
  597. X    #
  598. X    # Calculate document and window height
  599. X    #
  600. X    docwidth, docheight = totwidth, maxrows*lineheight
  601. X    winwidth, winheight = docwidth, docheight
  602. X    if winwidth > stdwin.textwidth('n')*100: winwidth = 0
  603. X    if winheight > stdwin.lineheight()*30: winheight = 0
  604. X    #
  605. X    # Create the window
  606. X    #
  607. X    stdwin.setdefwinsize(winwidth, winheight)
  608. X    w = gwin.open(title)
  609. X    #
  610. X    # Set properties and override methods
  611. X    #
  612. X    w.data = data
  613. X    w.margin = margin
  614. X    w.lineheight = lineheight
  615. X    w.colstarts = colstarts
  616. X    w.totwidth = totwidth
  617. X    w.maxrows = maxrows
  618. X    w.selection = (-1, -1)
  619. X    w.lastselection = (-1, -1)
  620. X    w.selshown = 0
  621. X    w.setdocsize(docwidth, docheight)
  622. X    w.draw = draw
  623. X    w.mup = mup
  624. X    w.arrow = arrow
  625. X    #
  626. X    # Return
  627. X    #
  628. X    return w
  629. X
  630. Xdef update(w, data): # Change the data
  631. X    #
  632. X    # Hide selection
  633. X    #
  634. X    hidesel(w, w.begindrawing())
  635. X    #
  636. X    # Get old geometry parameters
  637. X    #
  638. X    margin = w.margin
  639. X    lineheight = w.lineheight
  640. X    #
  641. X    # Geometry calculations
  642. X    #
  643. X    colstarts = [0]
  644. X    totwidth = 0
  645. X    maxrows = 0
  646. X    for coldata in data:
  647. X        # Height calculations
  648. X        rows = len(coldata)
  649. X        if rows > maxrows: maxrows = rows
  650. X        # Width calculations
  651. X        width = colwidth(coldata) + margin
  652. X        totwidth = totwidth + width
  653. X        colstarts.append(totwidth)
  654. X    #
  655. X    # Calculate document and window height
  656. X    #
  657. X    docwidth, docheight = totwidth, maxrows*lineheight
  658. X    #
  659. X    # Set changed properties and change window size
  660. X    #
  661. X    w.data = data
  662. X    w.colstarts = colstarts
  663. X    w.totwidth = totwidth
  664. X    w.maxrows = maxrows
  665. X    w.change((0, 0), (10000, 10000))
  666. X    w.setdocsize(docwidth, docheight)
  667. X    w.change((0, 0), (docwidth, docheight))
  668. X    #
  669. X    # Show selection, or forget it if out of range
  670. X    #
  671. X    showsel(w, w.begindrawing())
  672. X    if not w.selshown: w.selection = (-1, -1)
  673. X
  674. Xdef colwidth(coldata): # Subroutine to calculate column width
  675. X    maxwidth = 0
  676. X    for string, action in coldata:
  677. X        width = stdwin.textwidth(string)
  678. X        if width > maxwidth: maxwidth = width
  679. X    return maxwidth
  680. X
  681. Xdef draw(w, ((left, top), (right, bottom))): # Draw method
  682. X    ileft = whichcol(w, left)
  683. X    iright = whichcol(w, right-1) + 1
  684. X    if iright > len(w.data): iright = len(w.data)
  685. X    itop = divmod(top, w.lineheight)[0]
  686. X    if itop < 0: itop = 0
  687. X    ibottom, remainder = divmod(bottom, w.lineheight)
  688. X    if remainder: ibottom = ibottom + 1
  689. X    d = w.begindrawing()
  690. X    if ileft <= w.selection[0] < iright:
  691. X        if itop <= w.selection[1] < ibottom:
  692. X            hidesel(w, d)
  693. X    d.erase((left, top), (right, bottom))
  694. X    for i in range(ileft, iright):
  695. X        col = w.data[i]
  696. X        jbottom = len(col)
  697. X        if ibottom < jbottom: jbottom = ibottom
  698. X        h = w.colstarts[i]
  699. X        v = itop * w.lineheight
  700. X        for j in range(itop, jbottom):
  701. X            string, action = col[j]
  702. X            d.text((h, v), string)
  703. X            v = v + w.lineheight
  704. X    showsel(w, d)
  705. X
  706. Xdef mup(w, detail): # Mouse up method
  707. X    (h, v), nclicks, button, mask = detail
  708. X    icol = whichcol(w, h)
  709. X    if 0 <= icol < len(w.data):
  710. X        irow = divmod(v, w.lineheight)[0]
  711. X        col = w.data[icol]
  712. X        if 0 <= irow < len(col):
  713. X            string, action = col[irow]
  714. X            action(w, string, (icol, irow), detail)
  715. X
  716. Xdef whichcol(w, h): # Return column number (may be >= len(w.data))
  717. X    for icol in range(0, len(w.data)):
  718. X        if h < w.colstarts[icol+1]:
  719. X            return icol
  720. X    return len(w.data)
  721. X
  722. Xdef arrow(w, type):
  723. X    import stdwinsupport
  724. X    S = stdwinsupport
  725. X    if type = S.wc_left:
  726. X        incr = -1, 0
  727. X    elif type = S.wc_up:
  728. X        incr = 0, -1
  729. X    elif type = S.wc_right:
  730. X        incr = 1, 0
  731. X    elif type = S.wc_down:
  732. X        incr = 0, 1
  733. X    else:
  734. X        return
  735. X    icol, irow = w.lastselection
  736. X    icol = icol + incr[0]
  737. X    if icol < 0: icol = len(w.data)-1
  738. X    if icol >= len(w.data): icol = 0
  739. X    if 0 <= icol < len(w.data):
  740. X        irow = irow + incr[1]
  741. X        if irow < 0: irow = len(w.data[icol]) - 1
  742. X        if irow >= len(w.data[icol]): irow = 0
  743. X    else:
  744. X        irow = 0
  745. X    if 0 <= icol < len(w.data) and 0 <= irow < len(w.data[icol]):
  746. X        w.lastselection = icol, irow
  747. X        string, action = w.data[icol][irow]
  748. X        detail = (0, 0), 1, 1, 1
  749. X        action(w, string, (icol, irow), detail)
  750. X
  751. X
  752. X# Selection management
  753. X# TO DO: allow multiple selected entries
  754. X
  755. Xdef select(w, selection): # Public function to set the item selection
  756. X    d = w.begindrawing()
  757. X    hidesel(w, d)
  758. X    w.selection = selection
  759. X    showsel(w, d)
  760. X    if w.selshown: lastselection = selection
  761. X
  762. Xdef hidesel(w, d): # Hide the selection, if shown
  763. X    if w.selshown: invertsel(w, d)
  764. X
  765. Xdef showsel(w, d): # Show the selection, if hidden
  766. X    if not w.selshown: invertsel(w, d)
  767. X
  768. Xdef invertsel(w, d): # Invert the selection, if valid
  769. X    icol, irow = w.selection
  770. X    if 0 <= icol < len(w.data) and 0 <= irow < len(w.data[icol]):
  771. X        left = w.colstarts[icol]
  772. X        right = w.colstarts[icol+1]
  773. X        top = irow * w.lineheight
  774. X        bottom = (irow+1) * w.lineheight
  775. X        d.invert((left, top), (right, bottom))
  776. X        w.selshown = (not w.selshown)
  777. X
  778. X
  779. X# Demonstration
  780. X
  781. Xdef demo_action(w, string, (icol, irow), detail): # Action function for demo
  782. X    select(w, (irow, icol))
  783. X
  784. Xdef demo(): # Demonstration
  785. X    da = demo_action # shorthand
  786. X    col0 = [('a1', da), ('bbb1', da), ('c1', da)]
  787. X    col1 = [('a2', da), ('bbb2', da)]
  788. X    col2 = [('a3', da), ('b3', da), ('c3', da), ('d4', da), ('d5', da)]
  789. X    col3 = []
  790. X    for i in range(1, 31): col3.append('xxx' + `i`, da)
  791. X    data = [col0, col1, col2, col3]
  792. X    w = open('tablewin.demo', data)
  793. X    gwin.mainloop()
  794. X    return w
  795. EOF
  796. fi
  797. if test -s 'src/fileobject.c'
  798. then echo '*** I will not over-write existing file src/fileobject.c'
  799. else
  800. echo 'x - src/fileobject.c'
  801. sed 's/^X//' > 'src/fileobject.c' << 'EOF'
  802. X/***********************************************************
  803. XCopyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
  804. XNetherlands.
  805. X
  806. X                        All Rights Reserved
  807. X
  808. XPermission to use, copy, modify, and distribute this software and its 
  809. Xdocumentation for any purpose and without fee is hereby granted, 
  810. Xprovided that the above copyright notice appear in all copies and that
  811. Xboth that copyright notice and this permission notice appear in 
  812. Xsupporting documentation, and that the names of Stichting Mathematisch
  813. XCentrum or CWI not be used in advertising or publicity pertaining to
  814. Xdistribution of the software without specific, written prior permission.
  815. X
  816. XSTICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  817. XTHIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  818. XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  819. XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  820. XWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  821. XACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  822. XOF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  823. X
  824. X******************************************************************/
  825. X
  826. X/* File object implementation */
  827. X
  828. X/* XXX This should become a built-in module 'io'.  It should support more
  829. X   functionality, better exception handling for invalid calls, etc.
  830. X   (Especially reading on a write-only file or vice versa!)
  831. X   It should also cooperate with posix to support popen(), which should
  832. X   share most code but have a special close function. */
  833. X
  834. X#include "allobjects.h"
  835. X
  836. X#include "errno.h"
  837. X#ifndef errno
  838. Xextern int errno;
  839. X#endif
  840. X
  841. Xtypedef struct {
  842. X    OB_HEAD
  843. X    FILE *f_fp;
  844. X    object *f_name;
  845. X    object *f_mode;
  846. X    /* XXX Should move the 'need space' on printing flag here */
  847. X} fileobject;
  848. X
  849. XFILE *
  850. Xgetfilefile(f)
  851. X    object *f;
  852. X{
  853. X    if (!is_fileobject(f)) {
  854. X        err_badcall();
  855. X        return NULL;
  856. X    }
  857. X    return ((fileobject *)f)->f_fp;
  858. X}
  859. X
  860. Xobject *
  861. Xnewopenfileobject(fp, name, mode)
  862. X    FILE *fp;
  863. X    char *name;
  864. X    char *mode;
  865. X{
  866. X    fileobject *f = NEWOBJ(fileobject, &Filetype);
  867. X    if (f == NULL)
  868. X        return NULL;
  869. X    f->f_fp = NULL;
  870. X    f->f_name = newstringobject(name);
  871. X    f->f_mode = newstringobject(mode);
  872. X    if (f->f_name == NULL || f->f_mode == NULL) {
  873. X        DECREF(f);
  874. X        return NULL;
  875. X    }
  876. X    f->f_fp = fp;
  877. X    return (object *) f;
  878. X}
  879. X
  880. Xobject *
  881. Xnewfileobject(name, mode)
  882. X    char *name, *mode;
  883. X{
  884. X    fileobject *f;
  885. X    FILE *fp;
  886. X    f = (fileobject *) newopenfileobject((FILE *)NULL, name, mode);
  887. X    if (f == NULL)
  888. X        return NULL;
  889. X#ifdef THINK_C
  890. X    if (*mode == '*') {
  891. X        FILE *fopenRF();
  892. X        f->f_fp = fopenRF(name, mode+1);
  893. X    }
  894. X    else
  895. X#endif
  896. X    f->f_fp = fopen(name, mode);
  897. X    if (f->f_fp == NULL) {
  898. X        err_errno(RuntimeError);
  899. X        DECREF(f);
  900. X        return NULL;
  901. X    }
  902. X    return (object *)f;
  903. X}
  904. X
  905. X/* Methods */
  906. X
  907. Xstatic void
  908. Xfile_dealloc(f)
  909. X    fileobject *f;
  910. X{
  911. X    if (f->f_fp != NULL)
  912. X        fclose(f->f_fp);
  913. X    if (f->f_name != NULL)
  914. X        DECREF(f->f_name);
  915. X    if (f->f_mode != NULL)
  916. X        DECREF(f->f_mode);
  917. X    free((char *)f);
  918. X}
  919. X
  920. Xstatic void
  921. Xfile_print(f, fp, flags)
  922. X    fileobject *f;
  923. X    FILE *fp;
  924. X    int flags;
  925. X{
  926. X    fprintf(fp, "<%s file ", f->f_fp == NULL ? "closed" : "open");
  927. X    printobject(f->f_name, fp, flags);
  928. X    fprintf(fp, ", mode ");
  929. X    printobject(f->f_mode, fp, flags);
  930. X    fprintf(fp, ">");
  931. X}
  932. X
  933. Xstatic object *
  934. Xfile_repr(f)
  935. X    fileobject *f;
  936. X{
  937. X    char buf[300];
  938. X    /* XXX This differs from file_print if the filename contains
  939. X       quotes or other funny characters. */
  940. X    sprintf(buf, "<%s file '%.256s', mode '%.10s'>",
  941. X        f->f_fp == NULL ? "closed" : "open",
  942. X        getstringvalue(f->f_name),
  943. X        getstringvalue(f->f_mode));
  944. X    return newstringobject(buf);
  945. X}
  946. X
  947. Xstatic object *
  948. Xfile_close(f, args)
  949. X    fileobject *f;
  950. X    object *args;
  951. X{
  952. X    if (args != NULL) {
  953. X        err_badarg();
  954. X        return NULL;
  955. X    }
  956. X    if (f->f_fp != NULL) {
  957. X        fclose(f->f_fp);
  958. X        f->f_fp = NULL;
  959. X    }
  960. X    INCREF(None);
  961. X    return None;
  962. X}
  963. X
  964. Xstatic object *
  965. Xfile_read(f, args)
  966. X    fileobject *f;
  967. X    object *args;
  968. X{
  969. X    int n;
  970. X    object *v;
  971. X    if (f->f_fp == NULL) {
  972. X        err_badarg();
  973. X        return NULL;
  974. X    }
  975. X    if (args == NULL || !is_intobject(args)) {
  976. X        err_badarg();
  977. X        return NULL;
  978. X    }
  979. X    n = getintvalue(args);
  980. X    if (n < 0) {
  981. X        err_badarg();
  982. X        return NULL;
  983. X    }
  984. X    v = newsizedstringobject((char *)NULL, n);
  985. X    if (v == NULL)
  986. X        return NULL;
  987. X    n = fread(getstringvalue(v), 1, n, f->f_fp);
  988. X    /* EOF is reported as an empty string */
  989. X    /* XXX should detect real I/O errors? */
  990. X    resizestring(&v, n);
  991. X    return v;
  992. X}
  993. X
  994. X/* XXX Should this be unified with raw_input()? */
  995. X
  996. Xstatic object *
  997. Xfile_readline(f, args)
  998. X    fileobject *f;
  999. X    object *args;
  1000. X{
  1001. X    int n;
  1002. X    object *v;
  1003. X    if (f->f_fp == NULL) {
  1004. X        err_badarg();
  1005. X        return NULL;
  1006. X    }
  1007. X    if (args == NULL) {
  1008. X        n = 10000; /* XXX should really be unlimited */
  1009. X    }
  1010. X    else if (is_intobject(args)) {
  1011. X        n = getintvalue(args);
  1012. X        if (n < 0) {
  1013. X            err_badarg();
  1014. X            return NULL;
  1015. X        }
  1016. X    }
  1017. X    else {
  1018. X        err_badarg();
  1019. X        return NULL;
  1020. X    }
  1021. X    v = newsizedstringobject((char *)NULL, n);
  1022. X    if (v == NULL)
  1023. X        return NULL;
  1024. X#ifndef THINK_C_3_0
  1025. X    /* XXX Think C 3.0 wrongly reads up to n characters... */
  1026. X    n = n+1;
  1027. X#endif
  1028. X    if (fgets(getstringvalue(v), n, f->f_fp) == NULL) {
  1029. X        /* EOF is reported as an empty string */
  1030. X        /* XXX should detect real I/O errors? */
  1031. X        n = 0;
  1032. X    }
  1033. X    else {
  1034. X        n = strlen(getstringvalue(v));
  1035. X    }
  1036. X    resizestring(&v, n);
  1037. X    return v;
  1038. X}
  1039. X
  1040. Xstatic object *
  1041. Xfile_write(f, args)
  1042. X    fileobject *f;
  1043. X    object *args;
  1044. X{
  1045. X    int n, n2;
  1046. X    if (f->f_fp == NULL) {
  1047. X        err_badarg();
  1048. X        return NULL;
  1049. X    }
  1050. X    if (args == NULL || !is_stringobject(args)) {
  1051. X        err_badarg();
  1052. X        return NULL;
  1053. X    }
  1054. X    errno = 0;
  1055. X    n2 = fwrite(getstringvalue(args), 1, n = getstringsize(args), f->f_fp);
  1056. X    if (n2 != n) {
  1057. X        if (errno == 0)
  1058. X            errno = EIO;
  1059. X        err_errno(RuntimeError);
  1060. X        return NULL;
  1061. X    }
  1062. X    INCREF(None);
  1063. X    return None;
  1064. X}
  1065. X
  1066. Xstatic struct methodlist file_methods[] = {
  1067. X    {"write",    file_write},
  1068. X    {"read",    file_read},
  1069. X    {"readline",    file_readline},
  1070. X    {"close",    file_close},
  1071. X    {NULL,        NULL}        /* sentinel */
  1072. X};
  1073. X
  1074. Xstatic object *
  1075. Xfile_getattr(f, name)
  1076. X    fileobject *f;
  1077. X    char *name;
  1078. X{
  1079. X    return findmethod(file_methods, (object *)f, name);
  1080. X}
  1081. X
  1082. Xtypeobject Filetype = {
  1083. X    OB_HEAD_INIT(&Typetype)
  1084. X    0,
  1085. X    "file",
  1086. X    sizeof(fileobject),
  1087. X    0,
  1088. X    file_dealloc,    /*tp_dealloc*/
  1089. X    file_print,    /*tp_print*/
  1090. X    file_getattr,    /*tp_getattr*/
  1091. X    0,        /*tp_setattr*/
  1092. X    0,        /*tp_compare*/
  1093. X    file_repr,    /*tp_repr*/
  1094. X};
  1095. EOF
  1096. fi
  1097. if test -s 'src/floatobject.c'
  1098. then echo '*** I will not over-write existing file src/floatobject.c'
  1099. else
  1100. echo 'x - src/floatobject.c'
  1101. sed 's/^X//' > 'src/floatobject.c' << 'EOF'
  1102. X/***********************************************************
  1103. XCopyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
  1104. XNetherlands.
  1105. X
  1106. X                        All Rights Reserved
  1107. X
  1108. XPermission to use, copy, modify, and distribute this software and its 
  1109. Xdocumentation for any purpose and without fee is hereby granted, 
  1110. Xprovided that the above copyright notice appear in all copies and that
  1111. Xboth that copyright notice and this permission notice appear in 
  1112. Xsupporting documentation, and that the names of Stichting Mathematisch
  1113. XCentrum or CWI not be used in advertising or publicity pertaining to
  1114. Xdistribution of the software without specific, written prior permission.
  1115. X
  1116. XSTICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  1117. XTHIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  1118. XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  1119. XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  1120. XWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  1121. XACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  1122. XOF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  1123. X
  1124. X******************************************************************/
  1125. X
  1126. X/* Float object implementation */
  1127. X
  1128. X/* XXX There should be overflow checks here, but it's hard to check
  1129. X   for any kind of float exception without losing portability. */
  1130. X
  1131. X#include "allobjects.h"
  1132. X
  1133. X#include <errno.h>
  1134. X#ifndef errno
  1135. Xextern int errno;
  1136. X#endif
  1137. X
  1138. X#include <ctype.h>
  1139. X#include <math.h>
  1140. X
  1141. X#ifndef THINK_C
  1142. Xextern double fmod PROTO((double, double));
  1143. Xextern double pow PROTO((double, double));
  1144. X#endif
  1145. X
  1146. Xobject *
  1147. Xnewfloatobject(fval)
  1148. X    double fval;
  1149. X{
  1150. X    /* For efficiency, this code is copied from newobject() */
  1151. X    register floatobject *op = (floatobject *) malloc(sizeof(floatobject));
  1152. X    if (op == NULL)
  1153. X        return err_nomem();
  1154. X    NEWREF(op);
  1155. X    op->ob_type = &Floattype;
  1156. X    op->ob_fval = fval;
  1157. X    return (object *) op;
  1158. X}
  1159. X
  1160. Xdouble
  1161. Xgetfloatvalue(op)
  1162. X    object *op;
  1163. X{
  1164. X    if (!is_floatobject(op)) {
  1165. X        err_badarg();
  1166. X        return -1;
  1167. X    }
  1168. X    else
  1169. X        return ((floatobject *)op) -> ob_fval;
  1170. X}
  1171. X
  1172. X/* Methods */
  1173. X
  1174. Xstatic void
  1175. Xfloat_buf_repr(buf, v)
  1176. X    char *buf;
  1177. X    floatobject *v;
  1178. X{
  1179. X    register char *cp;
  1180. X    /* Subroutine for float_repr and float_print.
  1181. X       We want float numbers to be recognizable as such,
  1182. X       i.e., they should contain a decimal point or an exponent.
  1183. X       However, %g may print the number as an integer;
  1184. X       in such cases, we append ".0" to the string. */
  1185. X    sprintf(buf, "%.12g", v->ob_fval);
  1186. X    cp = buf;
  1187. X    if (*cp == '-')
  1188. X        cp++;
  1189. X    for (; *cp != '\0'; cp++) {
  1190. X        /* Any non-digit means it's not an integer;
  1191. X           this takes care of NAN and INF as well. */
  1192. X        if (!isdigit(*cp))
  1193. X            break;
  1194. X    }
  1195. X    if (*cp == '\0') {
  1196. X        *cp++ = '.';
  1197. X        *cp++ = '0';
  1198. X        *cp++ = '\0';
  1199. X    }
  1200. X}
  1201. X
  1202. Xstatic void
  1203. Xfloat_print(v, fp, flags)
  1204. X    floatobject *v;
  1205. X    FILE *fp;
  1206. X    int flags;
  1207. X{
  1208. X    char buf[100];
  1209. X    float_buf_repr(buf, v);
  1210. X    fputs(buf, fp);
  1211. X}
  1212. X
  1213. Xstatic object *
  1214. Xfloat_repr(v)
  1215. X    floatobject *v;
  1216. X{
  1217. X    char buf[100];
  1218. X    float_buf_repr(buf, v);
  1219. X    return newstringobject(buf);
  1220. X}
  1221. X
  1222. Xstatic int
  1223. Xfloat_compare(v, w)
  1224. X    floatobject *v, *w;
  1225. X{
  1226. X    double i = v->ob_fval;
  1227. X    double j = w->ob_fval;
  1228. X    return (i < j) ? -1 : (i > j) ? 1 : 0;
  1229. X}
  1230. X
  1231. Xstatic object *
  1232. Xfloat_add(v, w)
  1233. X    floatobject *v;
  1234. X    object *w;
  1235. X{
  1236. X    if (!is_floatobject(w)) {
  1237. X        err_badarg();
  1238. X        return NULL;
  1239. X    }
  1240. X    return newfloatobject(v->ob_fval + ((floatobject *)w) -> ob_fval);
  1241. X}
  1242. X
  1243. Xstatic object *
  1244. Xfloat_sub(v, w)
  1245. X    floatobject *v;
  1246. X    object *w;
  1247. X{
  1248. X    if (!is_floatobject(w)) {
  1249. X        err_badarg();
  1250. X        return NULL;
  1251. X    }
  1252. X    return newfloatobject(v->ob_fval - ((floatobject *)w) -> ob_fval);
  1253. X}
  1254. X
  1255. Xstatic object *
  1256. Xfloat_mul(v, w)
  1257. X    floatobject *v;
  1258. X    object *w;
  1259. X{
  1260. X    if (!is_floatobject(w)) {
  1261. X        err_badarg();
  1262. X        return NULL;
  1263. X    }
  1264. X    return newfloatobject(v->ob_fval * ((floatobject *)w) -> ob_fval);
  1265. X}
  1266. X
  1267. Xstatic object *
  1268. Xfloat_div(v, w)
  1269. X    floatobject *v;
  1270. X    object *w;
  1271. X{
  1272. X    if (!is_floatobject(w)) {
  1273. X        err_badarg();
  1274. X        return NULL;
  1275. X    }
  1276. X    if (((floatobject *)w) -> ob_fval == 0) {
  1277. X        err_setstr(ZeroDivisionError, "float division by zero");
  1278. X        return NULL;
  1279. X    }
  1280. X    return newfloatobject(v->ob_fval / ((floatobject *)w) -> ob_fval);
  1281. X}
  1282. X
  1283. Xstatic object *
  1284. Xfloat_rem(v, w)
  1285. X    floatobject *v;
  1286. X    object *w;
  1287. X{
  1288. X    double wx;
  1289. X    if (!is_floatobject(w)) {
  1290. X        err_badarg();
  1291. X        return NULL;
  1292. X    }
  1293. X    wx = ((floatobject *)w) -> ob_fval;
  1294. X    if (wx == 0.0) {
  1295. X        err_setstr(ZeroDivisionError, "float division by zero");
  1296. X        return NULL;
  1297. X    }
  1298. X    return newfloatobject(fmod(v->ob_fval, wx));
  1299. X}
  1300. X
  1301. Xstatic object *
  1302. Xfloat_pow(v, w)
  1303. X    floatobject *v;
  1304. X    object *w;
  1305. X{
  1306. X    double iv, iw, ix;
  1307. X    if (!is_floatobject(w)) {
  1308. X        err_badarg();
  1309. X        return NULL;
  1310. X    }
  1311. X    iv = v->ob_fval;
  1312. X    iw = ((floatobject *)w)->ob_fval;
  1313. X    if (iw == 0.0)
  1314. X        return newfloatobject(1.0); /* x**0 is always 1, even 0**0 */
  1315. X    errno = 0;
  1316. X    ix = pow(iv, iw);
  1317. X    if (errno != 0) {
  1318. X        /* XXX could it be another type of error? */
  1319. X        err_errno(OverflowError);
  1320. X        return NULL;
  1321. X    }
  1322. X    return newfloatobject(ix);
  1323. X}
  1324. X
  1325. Xstatic object *
  1326. Xfloat_neg(v)
  1327. X    floatobject *v;
  1328. X{
  1329. X    return newfloatobject(-v->ob_fval);
  1330. X}
  1331. X
  1332. Xstatic object *
  1333. Xfloat_pos(v)
  1334. X    floatobject *v;
  1335. X{
  1336. X    return newfloatobject(v->ob_fval);
  1337. X}
  1338. X
  1339. Xstatic number_methods float_as_number = {
  1340. X    float_add,    /*tp_add*/
  1341. X    float_sub,    /*tp_subtract*/
  1342. X    float_mul,    /*tp_multiply*/
  1343. X    float_div,    /*tp_divide*/
  1344. X    float_rem,    /*tp_remainder*/
  1345. X    float_pow,    /*tp_power*/
  1346. X    float_neg,    /*tp_negate*/
  1347. X    float_pos,    /*tp_plus*/
  1348. X};
  1349. X
  1350. Xtypeobject Floattype = {
  1351. X    OB_HEAD_INIT(&Typetype)
  1352. X    0,
  1353. X    "float",
  1354. X    sizeof(floatobject),
  1355. X    0,
  1356. X    free,            /*tp_dealloc*/
  1357. X    float_print,        /*tp_print*/
  1358. X    0,            /*tp_getattr*/
  1359. X    0,            /*tp_setattr*/
  1360. X    float_compare,        /*tp_compare*/
  1361. X    float_repr,        /*tp_repr*/
  1362. X    &float_as_number,    /*tp_as_number*/
  1363. X    0,            /*tp_as_sequence*/
  1364. X    0,            /*tp_as_mapping*/
  1365. X};
  1366. X
  1367. X/*
  1368. XXXX This is not enough.  Need:
  1369. X- automatic casts for mixed arithmetic (3.1 * 4)
  1370. X- mixed comparisons (!)
  1371. X- look at other uses of ints that could be extended to floats
  1372. X*/
  1373. EOF
  1374. fi
  1375. if test -s 'src/grammar.c'
  1376. then echo '*** I will not over-write existing file src/grammar.c'
  1377. else
  1378. echo 'x - src/grammar.c'
  1379. sed 's/^X//' > 'src/grammar.c' << 'EOF'
  1380. X/***********************************************************
  1381. XCopyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
  1382. XNetherlands.
  1383. X
  1384. X                        All Rights Reserved
  1385. X
  1386. XPermission to use, copy, modify, and distribute this software and its 
  1387. Xdocumentation for any purpose and without fee is hereby granted, 
  1388. Xprovided that the above copyright notice appear in all copies and that
  1389. Xboth that copyright notice and this permission notice appear in 
  1390. Xsupporting documentation, and that the names of Stichting Mathematisch
  1391. XCentrum or CWI not be used in advertising or publicity pertaining to
  1392. Xdistribution of the software without specific, written prior permission.
  1393. X
  1394. XSTICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  1395. XTHIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  1396. XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  1397. XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  1398. XWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  1399. XACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  1400. XOF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  1401. X
  1402. X******************************************************************/
  1403. X
  1404. X/* Grammar implementation */
  1405. X
  1406. X#include "pgenheaders.h"
  1407. X
  1408. X#include <ctype.h>
  1409. X
  1410. X#include "assert.h"
  1411. X#include "token.h"
  1412. X#include "grammar.h"
  1413. X
  1414. Xextern int debugging;
  1415. X
  1416. Xgrammar *
  1417. Xnewgrammar(start)
  1418. X    int start;
  1419. X{
  1420. X    grammar *g;
  1421. X    
  1422. X    g = NEW(grammar, 1);
  1423. X    if (g == NULL)
  1424. X        fatal("no mem for new grammar");
  1425. X    g->g_ndfas = 0;
  1426. X    g->g_dfa = NULL;
  1427. X    g->g_start = start;
  1428. X    g->g_ll.ll_nlabels = 0;
  1429. X    g->g_ll.ll_label = NULL;
  1430. X    return g;
  1431. X}
  1432. X
  1433. Xdfa *
  1434. Xadddfa(g, type, name)
  1435. X    grammar *g;
  1436. X    int type;
  1437. X    char *name;
  1438. X{
  1439. X    dfa *d;
  1440. X    
  1441. X    RESIZE(g->g_dfa, dfa, g->g_ndfas + 1);
  1442. X    if (g->g_dfa == NULL)
  1443. X        fatal("no mem to resize dfa in adddfa");
  1444. X    d = &g->g_dfa[g->g_ndfas++];
  1445. X    d->d_type = type;
  1446. X    d->d_name = name;
  1447. X    d->d_nstates = 0;
  1448. X    d->d_state = NULL;
  1449. X    d->d_initial = -1;
  1450. X    d->d_first = NULL;
  1451. X    return d; /* Only use while fresh! */
  1452. X}
  1453. X
  1454. Xint
  1455. Xaddstate(d)
  1456. X    dfa *d;
  1457. X{
  1458. X    state *s;
  1459. X    
  1460. X    RESIZE(d->d_state, state, d->d_nstates + 1);
  1461. X    if (d->d_state == NULL)
  1462. X        fatal("no mem to resize state in addstate");
  1463. X    s = &d->d_state[d->d_nstates++];
  1464. X    s->s_narcs = 0;
  1465. X    s->s_arc = NULL;
  1466. X    return s - d->d_state;
  1467. X}
  1468. X
  1469. Xvoid
  1470. Xaddarc(d, from, to, lbl)
  1471. X    dfa *d;
  1472. X    int lbl;
  1473. X{
  1474. X    state *s;
  1475. X    arc *a;
  1476. X    
  1477. X    assert(0 <= from && from < d->d_nstates);
  1478. X    assert(0 <= to && to < d->d_nstates);
  1479. X    
  1480. X    s = &d->d_state[from];
  1481. X    RESIZE(s->s_arc, arc, s->s_narcs + 1);
  1482. X    if (s->s_arc == NULL)
  1483. X        fatal("no mem to resize arc list in addarc");
  1484. X    a = &s->s_arc[s->s_narcs++];
  1485. X    a->a_lbl = lbl;
  1486. X    a->a_arrow = to;
  1487. X}
  1488. X
  1489. Xint
  1490. Xaddlabel(ll, type, str)
  1491. X    labellist *ll;
  1492. X    int type;
  1493. X    char *str;
  1494. X{
  1495. X    int i;
  1496. X    label *lb;
  1497. X    
  1498. X    for (i = 0; i < ll->ll_nlabels; i++) {
  1499. X        if (ll->ll_label[i].lb_type == type &&
  1500. X            strcmp(ll->ll_label[i].lb_str, str) == 0)
  1501. X            return i;
  1502. X    }
  1503. X    RESIZE(ll->ll_label, label, ll->ll_nlabels + 1);
  1504. X    if (ll->ll_label == NULL)
  1505. X        fatal("no mem to resize labellist in addlabel");
  1506. X    lb = &ll->ll_label[ll->ll_nlabels++];
  1507. X    lb->lb_type = type;
  1508. X    lb->lb_str = str; /* XXX strdup(str) ??? */
  1509. X    return lb - ll->ll_label;
  1510. X}
  1511. X
  1512. X/* Same, but rather dies than adds */
  1513. X
  1514. Xint
  1515. Xfindlabel(ll, type, str)
  1516. X    labellist *ll;
  1517. X    int type;
  1518. X    char *str;
  1519. X{
  1520. X    int i;
  1521. X    label *lb;
  1522. X    
  1523. X    for (i = 0; i < ll->ll_nlabels; i++) {
  1524. X        if (ll->ll_label[i].lb_type == type /*&&
  1525. X            strcmp(ll->ll_label[i].lb_str, str) == 0*/)
  1526. X            return i;
  1527. X    }
  1528. X    fprintf(stderr, "Label %d/'%s' not found\n", type, str);
  1529. X    abort();
  1530. X}
  1531. X
  1532. X/* Forward */
  1533. Xstatic void translabel PROTO((grammar *, label *));
  1534. X
  1535. Xvoid
  1536. Xtranslatelabels(g)
  1537. X    grammar *g;
  1538. X{
  1539. X    int i;
  1540. X    
  1541. X    printf("Translating labels ...\n");
  1542. X    /* Don't translate EMPTY */
  1543. X    for (i = EMPTY+1; i < g->g_ll.ll_nlabels; i++)
  1544. X        translabel(g, &g->g_ll.ll_label[i]);
  1545. X}
  1546. X
  1547. Xstatic void
  1548. Xtranslabel(g, lb)
  1549. X    grammar *g;
  1550. X    label *lb;
  1551. X{
  1552. X    int i;
  1553. X    
  1554. X    if (debugging)
  1555. X        printf("Translating label %s ...\n", labelrepr(lb));
  1556. X    
  1557. X    if (lb->lb_type == NAME) {
  1558. X        for (i = 0; i < g->g_ndfas; i++) {
  1559. X            if (strcmp(lb->lb_str, g->g_dfa[i].d_name) == 0) {
  1560. X                if (debugging)
  1561. X                    printf("Label %s is non-terminal %d.\n",
  1562. X                        lb->lb_str,
  1563. X                        g->g_dfa[i].d_type);
  1564. X                lb->lb_type = g->g_dfa[i].d_type;
  1565. X                lb->lb_str = NULL;
  1566. X                return;
  1567. X            }
  1568. X        }
  1569. X        for (i = 0; i < (int)N_TOKENS; i++) {
  1570. X            if (strcmp(lb->lb_str, tok_name[i]) == 0) {
  1571. X                if (debugging)
  1572. X                    printf("Label %s is terminal %d.\n",
  1573. X                        lb->lb_str, i);
  1574. X                lb->lb_type = i;
  1575. X                lb->lb_str = NULL;
  1576. X                return;
  1577. X            }
  1578. X        }
  1579. X        printf("Can't translate NAME label '%s'\n", lb->lb_str);
  1580. X        return;
  1581. X    }
  1582. X    
  1583. X    if (lb->lb_type == STRING) {
  1584. X        if (isalpha(lb->lb_str[1])) {
  1585. X            char *p, *strchr();
  1586. X            if (debugging)
  1587. X                printf("Label %s is a keyword\n", lb->lb_str);
  1588. X            lb->lb_type = NAME;
  1589. X            lb->lb_str++;
  1590. X            p = strchr(lb->lb_str, '\'');
  1591. X            if (p)
  1592. X                *p = '\0';
  1593. X        }
  1594. X        else {
  1595. X            if (lb->lb_str[2] == lb->lb_str[0]) {
  1596. X                int type = (int) tok_1char(lb->lb_str[1]);
  1597. X                if (type != OP) {
  1598. X                    lb->lb_type = type;
  1599. X                    lb->lb_str = NULL;
  1600. X                }
  1601. X                else
  1602. X                    printf("Unknown OP label %s\n",
  1603. X                        lb->lb_str);
  1604. X            }
  1605. X            else
  1606. X                printf("Can't translate STRING label %s\n",
  1607. X                    lb->lb_str);
  1608. X        }
  1609. X    }
  1610. X    else
  1611. X        printf("Can't translate label '%s'\n", labelrepr(lb));
  1612. X}
  1613. EOF
  1614. fi
  1615. if test -s 'src/import.c'
  1616. then echo '*** I will not over-write existing file src/import.c'
  1617. else
  1618. echo 'x - src/import.c'
  1619. sed 's/^X//' > 'src/import.c' << 'EOF'
  1620. X/***********************************************************
  1621. XCopyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
  1622. XNetherlands.
  1623. X
  1624. X                        All Rights Reserved
  1625. X
  1626. XPermission to use, copy, modify, and distribute this software and its 
  1627. Xdocumentation for any purpose and without fee is hereby granted, 
  1628. Xprovided that the above copyright notice appear in all copies and that
  1629. Xboth that copyright notice and this permission notice appear in 
  1630. Xsupporting documentation, and that the names of Stichting Mathematisch
  1631. XCentrum or CWI not be used in advertising or publicity pertaining to
  1632. Xdistribution of the software without specific, written prior permission.
  1633. X
  1634. XSTICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  1635. XTHIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  1636. XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  1637. XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  1638. XWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  1639. XACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  1640. XOF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  1641. X
  1642. X******************************************************************/
  1643. X
  1644. X/* Module definition and import implementation */
  1645. X
  1646. X#include "allobjects.h"
  1647. X
  1648. X#include "node.h"
  1649. X#include "token.h"
  1650. X#include "graminit.h"
  1651. X#include "import.h"
  1652. X#include "errcode.h"
  1653. X#include "sysmodule.h"
  1654. X#include "pythonrun.h"
  1655. X
  1656. X/* Define pathname separator used in file names */
  1657. X
  1658. X#ifdef THINK_C
  1659. X#define SEP ':'
  1660. X#endif
  1661. X
  1662. X#ifndef SEP
  1663. X#define SEP '/'
  1664. X#endif
  1665. X
  1666. Xstatic object *modules;
  1667. X
  1668. X/* Initialization */
  1669. X
  1670. Xvoid
  1671. Xinitimport()
  1672. X{
  1673. X    if ((modules = newdictobject()) == NULL)
  1674. X        fatal("no mem for dictionary of modules");
  1675. X}
  1676. X
  1677. Xobject *
  1678. Xget_modules()
  1679. X{
  1680. X    return modules;
  1681. X}
  1682. X
  1683. Xobject *
  1684. Xadd_module(name)
  1685. X    char *name;
  1686. X{
  1687. X    object *m;
  1688. X    if ((m = dictlookup(modules, name)) != NULL && is_moduleobject(m))
  1689. X        return m;
  1690. X    m = newmoduleobject(name);
  1691. X    if (m == NULL)
  1692. X        return NULL;
  1693. X    if (dictinsert(modules, name, m) != 0) {
  1694. X        DECREF(m);
  1695. X        return NULL;
  1696. X    }
  1697. X    DECREF(m); /* Yes, it still exists, in modules! */
  1698. X    return m;
  1699. X}
  1700. X
  1701. Xstatic FILE *
  1702. Xopen_module(name, suffix, namebuf)
  1703. X    char *name;
  1704. X    char *suffix;
  1705. X    char *namebuf; /* XXX No buffer overflow checks! */
  1706. X{
  1707. X    object *path;
  1708. X    FILE *fp;
  1709. X    
  1710. X    path = sysget("path");
  1711. X    if (path == NULL || !is_listobject(path)) {
  1712. X        strcpy(namebuf, name);
  1713. X        strcat(namebuf, suffix);
  1714. X        fp = fopen(namebuf, "r");
  1715. X    }
  1716. X    else {
  1717. X        int npath = getlistsize(path);
  1718. X        int i;
  1719. X        fp = NULL;
  1720. X        for (i = 0; i < npath; i++) {
  1721. X            object *v = getlistitem(path, i);
  1722. X            int len;
  1723. X            if (!is_stringobject(v))
  1724. X                continue;
  1725. X            strcpy(namebuf, getstringvalue(v));
  1726. X            len = getstringsize(v);
  1727. X            if (len > 0 && namebuf[len-1] != SEP)
  1728. X                namebuf[len++] = SEP;
  1729. X            strcpy(namebuf+len, name);
  1730. X            strcat(namebuf, suffix);
  1731. X            fp = fopen(namebuf, "r");
  1732. X            if (fp != NULL)
  1733. X                break;
  1734. X        }
  1735. X    }
  1736. X    return fp;
  1737. X}
  1738. X
  1739. Xstatic object *
  1740. Xget_module(m, name, m_ret)
  1741. X    /*module*/object *m;
  1742. X    char *name;
  1743. X    object **m_ret;
  1744. X{
  1745. X    object *d;
  1746. X    FILE *fp;
  1747. X    node *n;
  1748. X    int err;
  1749. X    char namebuf[256];
  1750. X    
  1751. X    fp = open_module(name, ".py", namebuf);
  1752. X    if (fp == NULL) {
  1753. X        if (m == NULL)
  1754. X            err_setstr(NameError, name);
  1755. X        else
  1756. X            err_setstr(RuntimeError, "no module source file");
  1757. X        return NULL;
  1758. X    }
  1759. X    err = parse_file(fp, namebuf, file_input, &n);
  1760. X    fclose(fp);
  1761. X    if (err != E_DONE) {
  1762. X        err_input(err);
  1763. X        return NULL;
  1764. X    }
  1765. X    if (m == NULL) {
  1766. X        m = add_module(name);
  1767. X        if (m == NULL) {
  1768. X            freetree(n);
  1769. X            return NULL;
  1770. X        }
  1771. X        *m_ret = m;
  1772. X    }
  1773. X    d = getmoduledict(m);
  1774. X    return run_node(n, namebuf, d, d);
  1775. X}
  1776. X
  1777. Xstatic object *
  1778. Xload_module(name)
  1779. X    char *name;
  1780. X{
  1781. X    object *m, *v;
  1782. X    v = get_module((object *)NULL, name, &m);
  1783. X    if (v == NULL)
  1784. X        return NULL;
  1785. X    DECREF(v);
  1786. X    return m;
  1787. X}
  1788. X
  1789. Xobject *
  1790. Ximport_module(name)
  1791. X    char *name;
  1792. X{
  1793. X    object *m;
  1794. X    if ((m = dictlookup(modules, name)) == NULL) {
  1795. X        if (init_builtin(name)) {
  1796. X            if ((m = dictlookup(modules, name)) == NULL)
  1797. X                err_setstr(SystemError, "builtin module missing");
  1798. X        }
  1799. X        else {
  1800. X            m = load_module(name);
  1801. X        }
  1802. X    }
  1803. X    return m;
  1804. X}
  1805. X
  1806. Xobject *
  1807. Xreload_module(m)
  1808. X    object *m;
  1809. X{
  1810. X    if (m == NULL || !is_moduleobject(m)) {
  1811. X        err_setstr(TypeError, "reload() argument must be module");
  1812. X        return NULL;
  1813. X    }
  1814. X    /* XXX Ought to check for builtin modules -- can't reload these... */
  1815. X    return get_module(m, getmodulename(m), (object **)NULL);
  1816. X}
  1817. X
  1818. Xstatic void
  1819. Xcleardict(d)
  1820. X    object *d;
  1821. X{
  1822. X    int i;
  1823. X    for (i = getdictsize(d); --i >= 0; ) {
  1824. X        char *k;
  1825. X        k = getdictkey(d, i);
  1826. X        if (k != NULL)
  1827. X            (void) dictremove(d, k);
  1828. X    }
  1829. X}
  1830. X
  1831. Xvoid
  1832. Xdoneimport()
  1833. X{
  1834. X    if (modules != NULL) {
  1835. X        int i;
  1836. X        /* Explicitly erase all modules; this is the safest way
  1837. X           to get rid of at least *some* circular dependencies */
  1838. X        for (i = getdictsize(modules); --i >= 0; ) {
  1839. X            char *k;
  1840. X            k = getdictkey(modules, i);
  1841. X            if (k != NULL) {
  1842. X                object *m;
  1843. X                m = dictlookup(modules, k);
  1844. X                if (m != NULL && is_moduleobject(m)) {
  1845. X                    object *d;
  1846. X                    d = getmoduledict(m);
  1847. X                    if (d != NULL && is_dictobject(d)) {
  1848. X                        cleardict(d);
  1849. X                    }
  1850. X                }
  1851. X            }
  1852. X        }
  1853. X        cleardict(modules);
  1854. X    }
  1855. X    DECREF(modules);
  1856. X}
  1857. X
  1858. X
  1859. X/* Initialize built-in modules when first imported */
  1860. X
  1861. Xextern struct {
  1862. X    char *name;
  1863. X    void (*initfunc)();
  1864. X} inittab[];
  1865. X
  1866. Xstatic int
  1867. Xinit_builtin(name)
  1868. X    char *name;
  1869. X{
  1870. X    int i;
  1871. X    for (i = 0; inittab[i].name != NULL; i++) {
  1872. X        if (strcmp(name, inittab[i].name) == 0) {
  1873. X            (*inittab[i].initfunc)();
  1874. X            return 1;
  1875. X        }
  1876. X    }
  1877. X    return 0;
  1878. X}
  1879. EOF
  1880. fi
  1881. if test -s 'src/macmodule.c'
  1882. then echo '*** I will not over-write existing file src/macmodule.c'
  1883. else
  1884. echo 'x - src/macmodule.c'
  1885. sed 's/^X//' > 'src/macmodule.c' << 'EOF'
  1886. X/***********************************************************
  1887. XCopyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
  1888. XNetherlands.
  1889. X
  1890. X                        All Rights Reserved
  1891. X
  1892. XPermission to use, copy, modify, and distribute this software and its 
  1893. Xdocumentation for any purpose and without fee is hereby granted, 
  1894. Xprovided that the above copyright notice appear in all copies and that
  1895. Xboth that copyright notice and this permission notice appear in 
  1896. Xsupporting documentation, and that the names of Stichting Mathematisch
  1897. XCentrum or CWI not be used in advertising or publicity pertaining to
  1898. Xdistribution of the software without specific, written prior permission.
  1899. X
  1900. XSTICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  1901. XTHIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  1902. XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  1903. XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  1904. XWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  1905. XACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  1906. XOF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  1907. X
  1908. X******************************************************************/
  1909. X
  1910. X/* Macintosh OS module implementation */
  1911. X
  1912. X#include "allobjects.h"
  1913. X
  1914. X#include "import.h"
  1915. X#include "modsupport.h"
  1916. X
  1917. X#include "sigtype.h"
  1918. X
  1919. X#include "::unixemu:dir.h"
  1920. X#include "::unixemu:stat.h"
  1921. X
  1922. Xstatic object *MacError; /* Exception */
  1923. X
  1924. X
  1925. Xstatic object *
  1926. Xmac_chdir(self, args)
  1927. X    object *self;
  1928. X    object *args;
  1929. X{
  1930. X    object *path;
  1931. X    if (!getstrarg(args, &path))
  1932. X        return NULL;
  1933. X    if (chdir(getstringvalue(path)) != 0)
  1934. X        return err_errno(MacError);
  1935. X    INCREF(None);
  1936. X    return None;
  1937. X}
  1938. X
  1939. X
  1940. Xstatic object *
  1941. Xmac_getcwd(self, args)
  1942. X    object *self;
  1943. X    object *args;
  1944. X{
  1945. X    extern char *getwd();
  1946. X    char buf[1025];
  1947. X    if (!getnoarg(args))
  1948. X        return NULL;
  1949. X    strcpy(buf, "mac.getcwd() failed"); /* In case getwd() doesn't set a msg */
  1950. X    if (getwd(buf) == NULL) {
  1951. X        err_setstr(MacError, buf);
  1952. X        return NULL;
  1953. X    }
  1954. X    return newstringobject(buf);
  1955. X}
  1956. X
  1957. X
  1958. Xstatic object *
  1959. Xmac_listdir(self, args)
  1960. X    object *self;
  1961. X    object *args;
  1962. X{
  1963. X    object *name, *d, *v;
  1964. X    DIR *dirp;
  1965. X    struct direct *ep;
  1966. X    if (!getstrarg(args, &name))
  1967. X        return NULL;
  1968. X    if ((dirp = opendir(getstringvalue(name))) == NULL)
  1969. X        return err_errno(MacError);
  1970. X    if ((d = newlistobject(0)) == NULL) {
  1971. X        closedir(dirp);
  1972. X        return NULL;
  1973. X    }
  1974. X    while ((ep = readdir(dirp)) != NULL) {
  1975. X        v = newstringobject(ep->d_name);
  1976. X        if (v == NULL) {
  1977. X            DECREF(d);
  1978. X            d = NULL;
  1979. X            break;
  1980. X        }
  1981. X        if (addlistitem(d, v) != 0) {
  1982. X            DECREF(v);
  1983. X            DECREF(d);
  1984. X            d = NULL;
  1985. X            break;
  1986. X        }
  1987. X        DECREF(v);
  1988. X    }
  1989. X    closedir(dirp);
  1990. X    return d;
  1991. X}
  1992. X
  1993. X
  1994. Xstatic object *
  1995. Xmac_mkdir(self, args)
  1996. X    object *self;
  1997. X    object *args;
  1998. X{
  1999. X    object *path;
  2000. X    int mode;
  2001. X    if (!getstrintarg(args, &path, &mode))
  2002. X        return NULL;
  2003. X    if (mkdir(getstringvalue(path), mode) != 0)
  2004. X        return err_errno(MacError);
  2005. X    INCREF(None);
  2006. X    return None;
  2007. X}
  2008. X
  2009. X
  2010. Xstatic object *
  2011. Xmac_rename(self, args)
  2012. X    object *self;
  2013. X    object *args;
  2014. X{
  2015. X    object *src, *dst;
  2016. X    if (!getstrstrarg(args, &src, &dst))
  2017. X        return NULL;
  2018. X    if (rename(getstringvalue(src), getstringvalue(dst)) != 0)
  2019. X        return err_errno(MacError);
  2020. X    INCREF(None);
  2021. X    return None;
  2022. X}
  2023. X
  2024. X
  2025. Xstatic object *
  2026. Xmac_rmdir(self, args)
  2027. X    object *self;
  2028. X    object *args;
  2029. X{
  2030. X    object *path;
  2031. X    if (!getstrarg(args, &path))
  2032. X        return NULL;
  2033. X    if (rmdir(getstringvalue(path)) != 0)
  2034. X        return err_errno(MacError);
  2035. X    INCREF(None);
  2036. X    return None;
  2037. X}
  2038. X
  2039. X
  2040. Xstatic object *
  2041. Xmac_stat(self, args)
  2042. X    object *self;
  2043. X    object *args;
  2044. X{
  2045. X    struct stat st;
  2046. X    object *path;
  2047. X    object *v;
  2048. X    if (!getstrarg(args, &path))
  2049. X        return NULL;
  2050. X    if (stat(getstringvalue(path), &st) != 0)
  2051. X        return err_errno(MacError);
  2052. X    v = newtupleobject(11);
  2053. X    if (v == NULL)
  2054. X        return NULL;
  2055. X#define SET(i, val) settupleitem(v, i, newintobject((long)(val)))
  2056. X#define XXX(i, val) SET(i, 0) /* For values my Mac stat doesn't support */
  2057. X    SET(0, st.st_mode);
  2058. X    XXX(1, st.st_ino);
  2059. X    XXX(2, st.st_dev);
  2060. X    XXX(3, st.st_nlink);
  2061. X    XXX(4, st.st_uid);
  2062. X    XXX(5, st.st_gid);
  2063. X    SET(6, st.st_size);
  2064. X    XXX(7, st.st_atime);
  2065. X    SET(8, st.st_mtime);
  2066. X    XXX(9, st.st_ctime);
  2067. X    SET(10, st.st_rsize); /* Mac-specific: resource size */
  2068. X#undef SET
  2069. X    if (err_occurred()) {
  2070. X        DECREF(v);
  2071. X        return NULL;
  2072. X    }
  2073. X    return v;
  2074. X}
  2075. X
  2076. X
  2077. Xstatic object *
  2078. Xmac_sync(self, args)
  2079. X    object *self;
  2080. X    object *args;
  2081. X{
  2082. X    if (!getnoarg(args))
  2083. X        return NULL;
  2084. X    sync();
  2085. X    INCREF(None);
  2086. X    return None;
  2087. X}
  2088. X
  2089. X
  2090. Xstatic object *
  2091. Xmac_unlink(self, args)
  2092. X    object *self;
  2093. X    object *args;
  2094. X{
  2095. X    object *path;
  2096. X    if (!getstrarg(args, &path))
  2097. X        return NULL;
  2098. X    if (unlink(getstringvalue(path)) != 0)
  2099. X        return err_errno(MacError);
  2100. X    INCREF(None);
  2101. X    return None;
  2102. X}
  2103. X
  2104. X
  2105. Xstatic struct methodlist mac_methods[] = {
  2106. X    {"chdir",    mac_chdir},
  2107. X    {"getcwd",    mac_getcwd},
  2108. X    {"listdir",    mac_listdir},
  2109. X    {"mkdir",    mac_mkdir},
  2110. X    {"rename",    mac_rename},
  2111. X    {"rmdir",    mac_rmdir},
  2112. X    {"stat",    mac_stat},
  2113. X    {"sync",    mac_sync},
  2114. X    {"unlink",    mac_unlink},
  2115. X    {NULL,        NULL}         /* Sentinel */
  2116. X};
  2117. X
  2118. X
  2119. Xvoid
  2120. Xinitmac()
  2121. X{
  2122. X    object *m, *d;
  2123. X    
  2124. X    m = initmodule("mac", mac_methods);
  2125. X    d = getmoduledict(m);
  2126. X    
  2127. X    /* Initialize mac.error exception */
  2128. X    MacError = newstringobject("mac.error");
  2129. X    if (MacError == NULL || dictinsert(d, "error", MacError) != 0)
  2130. X        fatal("can't define mac.error");
  2131. X}
  2132. EOF
  2133. fi
  2134. if test -s 'src/object.c'
  2135. then echo '*** I will not over-write existing file src/object.c'
  2136. else
  2137. echo 'x - src/object.c'
  2138. sed 's/^X//' > 'src/object.c' << 'EOF'
  2139. X/***********************************************************
  2140. XCopyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
  2141. XNetherlands.
  2142. X
  2143. X                        All Rights Reserved
  2144. X
  2145. XPermission to use, copy, modify, and distribute this software and its 
  2146. Xdocumentation for any purpose and without fee is hereby granted, 
  2147. Xprovided that the above copyright notice appear in all copies and that
  2148. Xboth that copyright notice and this permission notice appear in 
  2149. Xsupporting documentation, and that the names of Stichting Mathematisch
  2150. XCentrum or CWI not be used in advertising or publicity pertaining to
  2151. Xdistribution of the software without specific, written prior permission.
  2152. X
  2153. XSTICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  2154. XTHIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  2155. XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  2156. XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  2157. XWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  2158. XACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  2159. XOF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  2160. X
  2161. X******************************************************************/
  2162. X
  2163. X/* Generic object operations; and implementation of None (NoObject) */
  2164. X
  2165. X#include "allobjects.h"
  2166. X
  2167. X#ifdef REF_DEBUG
  2168. Xlong ref_total;
  2169. X#endif
  2170. X
  2171. X/* Object allocation routines used by NEWOBJ and NEWVAROBJ macros.
  2172. X   These are used by the individual routines for object creation.
  2173. X   Do not call them otherwise, they do not initialize the object! */
  2174. X
  2175. Xobject *
  2176. Xnewobject(tp)
  2177. X    typeobject *tp;
  2178. X{
  2179. X    object *op = (object *) malloc(tp->tp_basicsize);
  2180. X    if (op == NULL)
  2181. X        return err_nomem();
  2182. X    NEWREF(op);
  2183. X    op->ob_type = tp;
  2184. X    return op;
  2185. X}
  2186. X
  2187. X#if 0 /* unused */
  2188. X
  2189. Xvarobject *
  2190. Xnewvarobject(tp, size)
  2191. X    typeobject *tp;
  2192. X    unsigned int size;
  2193. X{
  2194. X    varobject *op = (varobject *)
  2195. X        malloc(tp->tp_basicsize + size * tp->tp_itemsize);
  2196. X    if (op == NULL)
  2197. X        return err_nomem();
  2198. X    NEWREF(op);
  2199. X    op->ob_type = tp;
  2200. X    op->ob_size = size;
  2201. X    return op;
  2202. X}
  2203. X
  2204. X#endif
  2205. X
  2206. Xint StopPrint; /* Flag to indicate printing must be stopped */
  2207. X
  2208. Xstatic int prlevel;
  2209. X
  2210. Xvoid
  2211. Xprintobject(op, fp, flags)
  2212. X    object *op;
  2213. X    FILE *fp;
  2214. X    int flags;
  2215. X{
  2216. X    /* Hacks to make printing a long or recursive object interruptible */
  2217. X    /* XXX Interrupts should leave a more permanent error */
  2218. X    prlevel++;
  2219. X    if (!StopPrint && intrcheck()) {
  2220. X        fprintf(fp, "\n[print interrupted]\n");
  2221. X        StopPrint = 1;
  2222. X    }
  2223. X    if (!StopPrint) {
  2224. X        if (op == NULL) {
  2225. X            fprintf(fp, "<nil>");
  2226. X        }
  2227. X        else {
  2228. X            if (op->ob_refcnt <= 0)
  2229. X                fprintf(fp, "(refcnt %d):", op->ob_refcnt);
  2230. X            if (op->ob_type->tp_print == NULL) {
  2231. X                fprintf(fp, "<%s object at %lx>",
  2232. X                    op->ob_type->tp_name, (long)op);
  2233. X            }
  2234. X            else {
  2235. X                (*op->ob_type->tp_print)(op, fp, flags);
  2236. X            }
  2237. X        }
  2238. X    }
  2239. X    prlevel--;
  2240. X    if (prlevel == 0)
  2241. X        StopPrint = 0;
  2242. X}
  2243. X
  2244. Xobject *
  2245. Xreprobject(v)
  2246. X    object *v;
  2247. X{
  2248. X    object *w = NULL;
  2249. X    /* Hacks to make converting a long or recursive object interruptible */
  2250. X    prlevel++;
  2251. X    if (!StopPrint && intrcheck()) {
  2252. X        StopPrint = 1;
  2253. X        err_set(KeyboardInterrupt);
  2254. X    }
  2255. X    if (!StopPrint) {
  2256. X        if (v == NULL) {
  2257. X            w = newstringobject("<NULL>");
  2258. X        }
  2259. X        else if (v->ob_type->tp_repr == NULL) {
  2260. X            char buf[100];
  2261. X            sprintf(buf, "<%.80s object at %lx>",
  2262. X                v->ob_type->tp_name, (long)v);
  2263. X            w = newstringobject(buf);
  2264. X        }
  2265. X        else {
  2266. X            w = (*v->ob_type->tp_repr)(v);
  2267. X        }
  2268. X        if (StopPrint) {
  2269. X            XDECREF(w);
  2270. X            w = NULL;
  2271. X        }
  2272. X    }
  2273. X    prlevel--;
  2274. X    if (prlevel == 0)
  2275. X        StopPrint = 0;
  2276. X    return w;
  2277. X}
  2278. X
  2279. Xint
  2280. Xcmpobject(v, w)
  2281. X    object *v, *w;
  2282. X{
  2283. X    typeobject *tp;
  2284. X    if (v == w)
  2285. X        return 0;
  2286. X    if (v == NULL)
  2287. X        return -1;
  2288. X    if (w == NULL)
  2289. X        return 1;
  2290. X    if ((tp = v->ob_type) != w->ob_type)
  2291. X        return strcmp(tp->tp_name, w->ob_type->tp_name);
  2292. X    if (tp->tp_compare == NULL)
  2293. X        return (v < w) ? -1 : 1;
  2294. X    return ((*tp->tp_compare)(v, w));
  2295. X}
  2296. X
  2297. Xobject *
  2298. Xgetattr(v, name)
  2299. X    object *v;
  2300. X    char *name;
  2301. X{
  2302. X    if (v->ob_type->tp_getattr == NULL) {
  2303. X        err_setstr(TypeError, "attribute-less object");
  2304. X        return NULL;
  2305. X    }
  2306. X    else {
  2307. X        return (*v->ob_type->tp_getattr)(v, name);
  2308. X    }
  2309. X}
  2310. X
  2311. Xint
  2312. Xsetattr(v, name, w)
  2313. X    object *v;
  2314. X    char *name;
  2315. X    object *w;
  2316. X{
  2317. X    if (v->ob_type->tp_setattr == NULL) {
  2318. X        if (v->ob_type->tp_getattr == NULL)
  2319. X            err_setstr(TypeError, "attribute-less object");
  2320. X        else
  2321. X            err_setstr(TypeError, "object has read-only attributes");
  2322. X        return -1;
  2323. X    }
  2324. X    else {
  2325. X        return (*v->ob_type->tp_setattr)(v, name, w);
  2326. X    }
  2327. X}
  2328. X
  2329. X
  2330. X/*
  2331. XNoObject is usable as a non-NULL undefined value, used by the macro None.
  2332. XThere is (and should be!) no way to create other objects of this type,
  2333. Xso there is exactly one (which is indestructible, by the way).
  2334. X*/
  2335. X
  2336. Xstatic void
  2337. Xnone_print(op, fp, flags)
  2338. X    object *op;
  2339. X    FILE *fp;
  2340. X    int flags;
  2341. X{
  2342. X    fprintf(fp, "None");
  2343. X}
  2344. X
  2345. Xstatic object *
  2346. Xnone_repr(op)
  2347. X    object *op;
  2348. X{
  2349. X    return newstringobject("None");
  2350. X}
  2351. X
  2352. Xstatic typeobject Notype = {
  2353. X    OB_HEAD_INIT(&Typetype)
  2354. X    0,
  2355. X    "None",
  2356. X    0,
  2357. X    0,
  2358. X    0,        /*tp_dealloc*/ /*never called*/
  2359. X    none_print,    /*tp_print*/
  2360. X    0,        /*tp_getattr*/
  2361. X    0,        /*tp_setattr*/
  2362. X    0,        /*tp_compare*/
  2363. X    none_repr,    /*tp_repr*/
  2364. X    0,        /*tp_as_number*/
  2365. X    0,        /*tp_as_sequence*/
  2366. X    0,        /*tp_as_mapping*/
  2367. X};
  2368. X
  2369. Xobject NoObject = {
  2370. X    OB_HEAD_INIT(&Notype)
  2371. X};
  2372. X
  2373. X
  2374. X#ifdef TRACE_REFS
  2375. X
  2376. Xstatic object refchain = {&refchain, &refchain};
  2377. X
  2378. XNEWREF(op)
  2379. X    object *op;
  2380. X{
  2381. X    ref_total++;
  2382. X    op->ob_refcnt = 1;
  2383. X    op->_ob_next = refchain._ob_next;
  2384. X    op->_ob_prev = &refchain;
  2385. X    refchain._ob_next->_ob_prev = op;
  2386. X    refchain._ob_next = op;
  2387. X}
  2388. X
  2389. XUNREF(op)
  2390. X    register object *op;
  2391. X{
  2392. X    register object *p;
  2393. X    if (op->ob_refcnt < 0) {
  2394. X        fprintf(stderr, "UNREF negative refcnt\n");
  2395. X        abort();
  2396. X    }
  2397. X    for (p = refchain._ob_next; p != &refchain; p = p->_ob_next) {
  2398. X        if (p == op)
  2399. X            break;
  2400. X    }
  2401. X    if (p == &refchain) { /* Not found */
  2402. X        fprintf(stderr, "UNREF unknown object\n");
  2403. X        abort();
  2404. X    }
  2405. X    op->_ob_next->_ob_prev = op->_ob_prev;
  2406. X    op->_ob_prev->_ob_next = op->_ob_next;
  2407. X}
  2408. X
  2409. XDELREF(op)
  2410. X    object *op;
  2411. X{
  2412. X    UNREF(op);
  2413. X    (*(op)->ob_type->tp_dealloc)(op);
  2414. X}
  2415. X
  2416. Xprintrefs(fp)
  2417. X    FILE *fp;
  2418. X{
  2419. X    object *op;
  2420. X    fprintf(fp, "Remaining objects:\n");
  2421. X    for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) {
  2422. X        fprintf(fp, "[%d] ", op->ob_refcnt);
  2423. X        printobject(op, fp, 0);
  2424. X        putc('\n', fp);
  2425. X    }
  2426. X}
  2427. X
  2428. X#endif
  2429. EOF
  2430. fi
  2431. if test -s 'src/tupleobject.c'
  2432. then echo '*** I will not over-write existing file src/tupleobject.c'
  2433. else
  2434. echo 'x - src/tupleobject.c'
  2435. sed 's/^X//' > 'src/tupleobject.c' << 'EOF'
  2436. X/***********************************************************
  2437. XCopyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
  2438. XNetherlands.
  2439. X
  2440. X                        All Rights Reserved
  2441. X
  2442. XPermission to use, copy, modify, and distribute this software and its 
  2443. Xdocumentation for any purpose and without fee is hereby granted, 
  2444. Xprovided that the above copyright notice appear in all copies and that
  2445. Xboth that copyright notice and this permission notice appear in 
  2446. Xsupporting documentation, and that the names of Stichting Mathematisch
  2447. XCentrum or CWI not be used in advertising or publicity pertaining to
  2448. Xdistribution of the software without specific, written prior permission.
  2449. X
  2450. XSTICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  2451. XTHIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  2452. XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  2453. XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  2454. XWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  2455. XACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  2456. XOF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  2457. X
  2458. X******************************************************************/
  2459. X
  2460. X/* Tuple object implementation */
  2461. X
  2462. X#include "allobjects.h"
  2463. X
  2464. Xobject *
  2465. Xnewtupleobject(size)
  2466. X    register int size;
  2467. X{
  2468. X    register int i;
  2469. X    register tupleobject *op;
  2470. X    if (size < 0) {
  2471. X        err_badcall();
  2472. X        return NULL;
  2473. X    }
  2474. X    op = (tupleobject *)
  2475. X        malloc(sizeof(tupleobject) + size * sizeof(object *));
  2476. X    if (op == NULL)
  2477. X        return err_nomem();
  2478. X    NEWREF(op);
  2479. X    op->ob_type = &Tupletype;
  2480. X    op->ob_size = size;
  2481. X    for (i = 0; i < size; i++)
  2482. X        op->ob_item[i] = NULL;
  2483. X    return (object *) op;
  2484. X}
  2485. X
  2486. Xint
  2487. Xgettuplesize(op)
  2488. X    register object *op;
  2489. X{
  2490. X    if (!is_tupleobject(op)) {
  2491. X        err_badcall();
  2492. X        return -1;
  2493. X    }
  2494. X    else
  2495. X        return ((tupleobject *)op)->ob_size;
  2496. X}
  2497. X
  2498. Xobject *
  2499. Xgettupleitem(op, i)
  2500. X    register object *op;
  2501. X    register int i;
  2502. X{
  2503. X    if (!is_tupleobject(op)) {
  2504. X        err_badcall();
  2505. X        return NULL;
  2506. X    }
  2507. X    if (i < 0 || i >= ((tupleobject *)op) -> ob_size) {
  2508. X        err_setstr(IndexError, "tuple index out of range");
  2509. X        return NULL;
  2510. X    }
  2511. X    return ((tupleobject *)op) -> ob_item[i];
  2512. X}
  2513. X
  2514. Xint
  2515. Xsettupleitem(op, i, newitem)
  2516. X    register object *op;
  2517. X    register int i;
  2518. X    register object *newitem;
  2519. X{
  2520. X    register object *olditem;
  2521. X    if (!is_tupleobject(op)) {
  2522. X        if (newitem != NULL)
  2523. X            DECREF(newitem);
  2524. X        err_badcall();
  2525. X        return -1;
  2526. X    }
  2527. X    if (i < 0 || i >= ((tupleobject *)op) -> ob_size) {
  2528. X        if (newitem != NULL)
  2529. X            DECREF(newitem);
  2530. X        err_setstr(IndexError, "tuple assignment index out of range");
  2531. X        return -1;
  2532. X    }
  2533. X    olditem = ((tupleobject *)op) -> ob_item[i];
  2534. X    ((tupleobject *)op) -> ob_item[i] = newitem;
  2535. X    if (olditem != NULL)
  2536. X        DECREF(olditem);
  2537. X    return 0;
  2538. X}
  2539. X
  2540. X/* Methods */
  2541. X
  2542. Xstatic void
  2543. Xtupledealloc(op)
  2544. X    register tupleobject *op;
  2545. X{
  2546. X    register int i;
  2547. X    for (i = 0; i < op->ob_size; i++) {
  2548. X        if (op->ob_item[i] != NULL)
  2549. X            DECREF(op->ob_item[i]);
  2550. X    }
  2551. X    free((ANY *)op);
  2552. X}
  2553. X
  2554. Xstatic void
  2555. Xtupleprint(op, fp, flags)
  2556. X    tupleobject *op;
  2557. X    FILE *fp;
  2558. X    int flags;
  2559. X{
  2560. X    int i;
  2561. X    fprintf(fp, "(");
  2562. X    for (i = 0; i < op->ob_size && !StopPrint; i++) {
  2563. X        if (i > 0) {
  2564. X            fprintf(fp, ", ");
  2565. X        }
  2566. X        printobject(op->ob_item[i], fp, flags);
  2567. X    }
  2568. X    if (op->ob_size == 1)
  2569. X        fprintf(fp, ",");
  2570. X    fprintf(fp, ")");
  2571. X}
  2572. X
  2573. Xobject *
  2574. Xtuplerepr(v)
  2575. X    tupleobject *v;
  2576. X{
  2577. X    object *s, *t, *comma;
  2578. X    int i;
  2579. X    s = newstringobject("(");
  2580. X    comma = newstringobject(", ");
  2581. X    for (i = 0; i < v->ob_size && s != NULL; i++) {
  2582. X        if (i > 0)
  2583. X            joinstring(&s, comma);
  2584. X        t = reprobject(v->ob_item[i]);
  2585. X        joinstring(&s, t);
  2586. X        if (t != NULL)
  2587. X            DECREF(t);
  2588. X    }
  2589. X    DECREF(comma);
  2590. X    if (v->ob_size == 1) {
  2591. X        t = newstringobject(",");
  2592. X        joinstring(&s, t);
  2593. X        DECREF(t);
  2594. X    }
  2595. X    t = newstringobject(")");
  2596. X    joinstring(&s, t);
  2597. X    DECREF(t);
  2598. X    return s;
  2599. X}
  2600. X
  2601. Xstatic int
  2602. Xtuplecompare(v, w)
  2603. X    register tupleobject *v, *w;
  2604. X{
  2605. X    register int len =
  2606. X        (v->ob_size < w->ob_size) ? v->ob_size : w->ob_size;
  2607. X    register int i;
  2608. X    for (i = 0; i < len; i++) {
  2609. X        int cmp = cmpobject(v->ob_item[i], w->ob_item[i]);
  2610. X        if (cmp != 0)
  2611. X            return cmp;
  2612. X    }
  2613. X    return v->ob_size - w->ob_size;
  2614. X}
  2615. X
  2616. Xstatic int
  2617. Xtuplelength(a)
  2618. X    tupleobject *a;
  2619. X{
  2620. X    return a->ob_size;
  2621. X}
  2622. X
  2623. Xstatic object *
  2624. Xtupleitem(a, i)
  2625. X    register tupleobject *a;
  2626. X    register int i;
  2627. X{
  2628. X    if (i < 0 || i >= a->ob_size) {
  2629. X        err_setstr(IndexError, "tuple index out of range");
  2630. X        return NULL;
  2631. X    }
  2632. X    INCREF(a->ob_item[i]);
  2633. X    return a->ob_item[i];
  2634. X}
  2635. X
  2636. Xstatic object *
  2637. Xtupleslice(a, ilow, ihigh)
  2638. X    register tupleobject *a;
  2639. X    register int ilow, ihigh;
  2640. X{
  2641. X    register tupleobject *np;
  2642. X    register int i;
  2643. X    if (ilow < 0)
  2644. X        ilow = 0;
  2645. X    if (ihigh > a->ob_size)
  2646. X        ihigh = a->ob_size;
  2647. X    if (ihigh < ilow)
  2648. X        ihigh = ilow;
  2649. X    if (ilow == 0 && ihigh == a->ob_size) {
  2650. X        /* XXX can only do this if tuples are immutable! */
  2651. X        INCREF(a);
  2652. X        return (object *)a;
  2653. X    }
  2654. X    np = (tupleobject *)newtupleobject(ihigh - ilow);
  2655. X    if (np == NULL)
  2656. X        return NULL;
  2657. X    for (i = ilow; i < ihigh; i++) {
  2658. X        object *v = a->ob_item[i];
  2659. X        INCREF(v);
  2660. X        np->ob_item[i - ilow] = v;
  2661. X    }
  2662. X    return (object *)np;
  2663. X}
  2664. X
  2665. Xstatic object *
  2666. Xtupleconcat(a, bb)
  2667. X    register tupleobject *a;
  2668. X    register object *bb;
  2669. X{
  2670. X    register int size;
  2671. X    register int i;
  2672. X    tupleobject *np;
  2673. X    if (!is_tupleobject(bb)) {
  2674. X        err_badarg();
  2675. X        return NULL;
  2676. X    }
  2677. X#define b ((tupleobject *)bb)
  2678. X    size = a->ob_size + b->ob_size;
  2679. X    np = (tupleobject *) newtupleobject(size);
  2680. X    if (np == NULL) {
  2681. X        return err_nomem();
  2682. X    }
  2683. X    for (i = 0; i < a->ob_size; i++) {
  2684. X        object *v = a->ob_item[i];
  2685. X        INCREF(v);
  2686. X        np->ob_item[i] = v;
  2687. X    }
  2688. X    for (i = 0; i < b->ob_size; i++) {
  2689. X        object *v = b->ob_item[i];
  2690. X        INCREF(v);
  2691. X        np->ob_item[i + a->ob_size] = v;
  2692. X    }
  2693. X    return (object *)np;
  2694. X#undef b
  2695. X}
  2696. X
  2697. Xstatic sequence_methods tuple_as_sequence = {
  2698. X    tuplelength,    /*sq_length*/
  2699. X    tupleconcat,    /*sq_concat*/
  2700. X    0,        /*sq_repeat*/
  2701. X    tupleitem,    /*sq_item*/
  2702. X    tupleslice,    /*sq_slice*/
  2703. X    0,        /*sq_ass_item*/
  2704. X    0,        /*sq_ass_slice*/
  2705. X};
  2706. X
  2707. Xtypeobject Tupletype = {
  2708. X    OB_HEAD_INIT(&Typetype)
  2709. X    0,
  2710. X    "tuple",
  2711. X    sizeof(tupleobject) - sizeof(object *),
  2712. X    sizeof(object *),
  2713. X    tupledealloc,    /*tp_dealloc*/
  2714. X    tupleprint,    /*tp_print*/
  2715. X    0,        /*tp_getattr*/
  2716. X    0,        /*tp_setattr*/
  2717. X    tuplecompare,    /*tp_compare*/
  2718. X    tuplerepr,    /*tp_repr*/
  2719. X    0,        /*tp_as_number*/
  2720. X    &tuple_as_sequence,    /*tp_as_sequence*/
  2721. X    0,        /*tp_as_mapping*/
  2722. X};
  2723. EOF
  2724. fi
  2725. echo 'Part 14 out of 21 of pack.out complete.'
  2726. exit 0
  2727.