aboutsummaryrefslogtreecommitdiff
path: root/shar/python-0.9.1-07-21.shar
diff options
context:
space:
mode:
authorSkip Montanaro <[email protected]>2021-02-16 14:40:46 -0600
committerSkip Montanaro <[email protected]>2021-02-16 14:40:46 -0600
commita19a216bc60160c162e616145ef091dd18ce4e61 (patch)
treefa4bdff21f9b04a125c84a2bfab8a1c738359e15 /shar/python-0.9.1-07-21.shar
downloadpython-0.9.1-patched-QoL-a19a216bc60160c162e616145ef091dd18ce4e61.tar.xz
python-0.9.1-patched-QoL-a19a216bc60160c162e616145ef091dd18ce4e61.zip
Python 0.9.1 as posted in alt.sources
Diffstat (limited to 'shar/python-0.9.1-07-21.shar')
-rw-r--r--shar/python-0.9.1-07-21.shar2518
1 files changed, 2518 insertions, 0 deletions
diff --git a/shar/python-0.9.1-07-21.shar b/shar/python-0.9.1-07-21.shar
new file mode 100644
index 0000000..e242423
--- /dev/null
+++ b/shar/python-0.9.1-07-21.shar
@@ -0,0 +1,2518 @@
+: This is a shell archive.
+: Extract with 'sh this_file'.
+:
+: Extract part 01 first since it makes all directories
+echo 'Start of pack.out, part 07 out of 21:'
+if test -s 'demo/sgi/gl/mclock.py'
+then echo '*** I will not over-write existing file demo/sgi/gl/mclock.py'
+else
+echo 'x - demo/sgi/gl/mclock.py'
+sed 's/^X//' > 'demo/sgi/gl/mclock.py' << 'EOF'
+X#! /ufs/guido/bin/sgi/python
+X
+X#############################################################################
+X# NOTA BENE: Before installing, fix TZDIFF to reflect your local time zone! #
+X#############################################################################
+X
+X# "M Clock"
+X#
+X# An implementation in software of an original design by Rob Juda.
+X# Clock implementation: Guido van Rossum.
+X# Alarm and Gong features: Sape Mullender.
+X#
+X# XXX TO DO:
+X# find out local time zone difference automatically
+X# add a date indicator
+X# allow multiple alarms
+X# allow the menu to change more parameters
+X
+Ximport sys
+X
+Xfrom gl import *
+Xfrom GL import *
+Xfrom DEVICE import *
+Ximport time
+Ximport getopt
+Ximport string
+Ximport path
+Xfrom math import pi
+Ximport math
+Ximport posix
+X
+XFULLC = 3600 # Full circle in 1/10-ths of a degree
+XMIDN = 900 # Angle of the 12 o'clock position
+XR, G, B = 0, 1, 2 # Indices of colors in RGB list
+X
+XHOUR = 3600 # Number of seconds per hour
+XMINUTE = 60 # Number of seconds per minute
+X
+Xclass struct(): pass # Class to define featureless structures
+XGl = struct() # Object to hold writable global variables
+X
+X# Default constants (used in multiple places)
+X
+XSCREENBG = 127, 156, 191
+XNPARTS = 9
+XTITLE = 'M Clock'
+XTZDIFF = -1*HOUR # <--- change this to reflect your local time zone
+X
+X# Default parameters
+X
+XGl.foreground = 0 # If set, run in the foreground
+XGl.fullscreen = 0 # If set, run on full screen
+XGl.tzdiff = TZDIFF # Seconds west of Greenwich (winter time)
+XGl.nparts = NPARTS # Number of parts each circle is divided in (>= 2)
+XGl.debug = 0 # If set, print debug output
+XGl.doublebuffer = 1 # If set, use double buffering
+XGl.update = 0 # Update interval; seconds hand is suppressed if > 1
+XGl.colorsubset = 0 # If set, display only a subset of the colors
+XGl.cyan = 0 # If set, display cyan overlay (big hand)
+XGl.magenta = 0 # If set, display magenta overlay (little hand)
+XGl.yellow = 0 # If set, display yellow overlay (fixed background)
+XGl.black = 0 # If set, display black overlay (hands)
+XGl.colormap = 0 # If set, use colormap mode instead of RGB mode
+XGl.warnings = 0 # If set, print warnings
+XGl.title = '- - ' # Window title (default set later)
+XGl.border = 1 # If set, use a window border (and title)
+XGl.bg = 0, 0, 0 # Background color R, G, B value
+XGl.iconic = 0 # Set in iconic state
+XGl.fg = 255, 0, 0 # Alarm background RGB (either normal or alarm)
+XGl.ox,Gl.oy = 0,0 # Window origin
+XGl.cx,Gl.cy = 0,0 # Window size
+XGl.alarm_set = 0 # Alarm on or off
+XGl.alarm_on = 0 # Alarm is ringing
+XGl.alarm_time = 0 # Alarm time in seconds after midnight
+XGl.alarm_hours = 0 # Alarm hour setting, 24 hour clock
+XGl.alarm_minutes = 0 # Alarm minutes setting
+XGl.alarm_rgb = 0,0,0 # Alarm display RGB colors
+XGl.alarm_cmd = '' # Command to execute when alarm goes off
+XGl.mouse2down = 0 # Mouse button state
+XGl.mouse3down = 0 # Mouse button state
+XGl.gong_cmd = '' # Command to execute when chimes go off
+XGl.gong_int = 3600 # Gong interval
+XGl.indices = R, G, B # Colors (permuted when alarm is on)
+X
+Xdef main():
+X #
+X sys.stdout = sys.stderr # All output is errors/warnings etc.
+X #
+X try:
+X args = getoptions()
+X except string.atoi_error, value:
+X usage(string.atoi_error, value)
+X except getopt.error, msg:
+X usage(getopt.error, msg)
+X #
+X if args:
+X realtime = 0
+X hours = string.atoi(args[0])
+X minutes = seconds = 0
+X if args[1:]: minutes = string.atoi(args[1])
+X if args[2:]: seconds = string.atoi(args[2])
+X localtime = ((hours*60)+minutes)*60+seconds
+X else:
+X realtime = 1
+X #
+X if Gl.title = '- - ':
+X if realtime:
+X Gl.title = TITLE
+X else:
+X title = ''
+X for arg in args: title = title + ' ' + arg
+X Gl.title = title[1:]
+X del title
+X #
+X wid = makewindow()
+X Gl.ox,Gl.oy = getorigin()
+X Gl.cx,Gl.cy = getsize()
+X initmenu()
+X clearall()
+X #
+X if not Gl.update:
+X Gl.update = 60
+X #
+X if Gl.update <= 1:
+X Gl.timernoise = 6
+X else:
+X Gl.timernoise = 60
+X noise(TIMER0, Gl.timernoise)
+X #
+X qdevice(WINSHUT)
+X qdevice(WINQUIT)
+X qdevice(ESCKEY)
+X if realtime:
+X qdevice(TIMER0)
+X qdevice(REDRAW)
+X qdevice(WINFREEZE)
+X qdevice(WINTHAW)
+X qdevice(MENUBUTTON) # MOUSE1
+X qdevice(MOUSE3) # Left button
+X qdevice(MOUSE2) # Middle button
+X unqdevice(INPUTCHANGE)
+X #
+X lasttime = 0
+X Gl.change = 1
+X while 1:
+X if realtime:
+X localtime = time.time() - Gl.tzdiff
+X if Gl.alarm_set:
+X if localtime%(24*HOUR) = Gl.alarm_time:
+X # Ring the alarm!
+X if Gl.debug:
+X print 'Rrrringg!'
+X Gl.alarm_on = 1
+X if Gl.alarm_cmd <> '':
+X d = posix.system(Gl.alarm_cmd+' '+`Gl.alarm_time/3600`+' '+`(Gl.alarm_time/60)%60` + ' &')
+X Gl.change = 1
+X clearall()
+X if Gl.alarm_on:
+X if (localtime - Gl.alarm_time) % (24*HOUR) > 300:
+X # More than 5 minutes away from alarm
+X Gl.alarm_on = 0
+X if Gl.debug:
+X print 'Alarm turned off'
+X Gl.change = 1
+X clearall()
+X Gl.indices = R, G, B
+X else:
+X if localtime % 2 = 0:
+X # Permute color indices
+X Gl.indices = Gl.indices[2:] + Gl.indices[:2]
+X Gl.change = 1
+X if Gl.gong_cmd <> '' and localtime%Gl.gong_int = 0:
+X d = posix.system(Gl.gong_cmd+' '+`(localtime/3600)%24`+' '+`(localtime/60)%60` + ' &')
+X if localtime/Gl.update <> lasttime/Gl.update:
+X if Gl.debug: print 'new time'
+X Gl.change = 1
+X if Gl.change:
+X if Gl.debug: print 'drawing'
+X doit(localtime)
+X lasttime = localtime
+X Gl.change = 0
+X dev, data = qread()
+X if Gl.debug and dev <> TIMER0:
+X print dev, data
+X if dev = TIMER0:
+X if Gl.debug > 1:
+X print dev, data
+X elif dev = MOUSE3:
+X mousex = getvaluator(MOUSEX)
+X mousey = getvaluator(MOUSEY)
+X if mouseclick(3, data, mousex, mousey):
+X Gl.change = 1
+X elif dev = MOUSE2:
+X mousex = getvaluator(MOUSEX)
+X mousey = getvaluator(MOUSEY)
+X if mouseclick(2, data, mousex, mousey):
+X Gl.change = 1
+X elif dev = MOUSEX:
+X mousex = data
+X if Gl.mouse2down:
+X mouse2track(mousex, mousey)
+X if Gl.mouse3down:
+X mouse3track(mousex, mousey)
+X elif dev = MOUSEY:
+X mousey = data
+X if Gl.mouse2down:
+X mouse2track(mousex, mousey)
+X if Gl.mouse3down:
+X mouse3track(mousex, mousey)
+X elif dev = REDRAW or dev = REDRAWICONIC:
+X if Gl.debug:
+X if dev = REDRAW: print 'REDRAW'
+X else: print 'REDRAWICONIC'
+X reshapeviewport()
+X Gl.ox,Gl.oy = getorigin()
+X Gl.cx,Gl.cy = getsize()
+X Gl.change = 1
+X clearall()
+X elif dev = MENUBUTTON:
+X if Gl.debug: print 'MENUBUTTON'
+X handlemenu()
+X elif dev = WINFREEZE:
+X if Gl.debug: print 'WINFREEZE'
+X Gl.iconic = 1
+X noise(TIMER0, 60*60) # Redraw every 60 seconds only
+X elif dev = WINTHAW:
+X if Gl.debug: print 'WINTHAW'
+X Gl.iconic = 0
+X noise(TIMER0, Gl.timernoise)
+X Gl.change = 1
+X elif dev = ESCKEY or dev = WINSHUT or dev = WINQUIT:
+X if Gl.debug: print 'Exit'
+X sys.exit(0)
+X
+Xdef getoptions():
+X optlist, args = getopt.getopt(sys.argv[1:], 'A:a:B:bc:dFfG:g:n:sT:t:u:wCMYK')
+X for optname, optarg in optlist:
+X if optname = '-A':
+X Gl.fg = eval(optarg) # Should be (r,g,b)
+X elif optname = '-a':
+X Gl.alarm_cmd = optarg
+X elif optname = '-B':
+X Gl.bg = eval(optarg) # Should be (r,g,b)
+X elif optname = '-b':
+X Gl.border = 0
+X elif optname = '-c':
+X Gl.colormap = string.atoi(optarg)
+X elif optname = '-d':
+X Gl.debug = Gl.debug + 1
+X Gl.warnings = 1
+X elif optname = '-F':
+X Gl.foreground = 1
+X elif optname = '-f':
+X Gl.fullscreen = 1
+X elif optname = '-G':
+X Gl.gong_int = 60*string.atoi(optarg)
+X elif optname = '-g':
+X Gl.gong_cmd = optarg
+X elif optname = '-n':
+X Gl.nparts = string.atoi(optarg)
+X elif optname = '-s':
+X Gl.doublebuffer = 0
+X elif optname = '-T':
+X Gl.title = optarg
+X elif optname = '-t':
+X Gl.tzdiff = string.atoi(optarg)
+X elif optname = '-u':
+X Gl.update = string.atoi(optarg)
+X elif optname = '-w':
+X Gl.warnings = 1
+X elif optname = '-C':
+X Gl.cyan = Gl.colorsubset = 1
+X elif optname = '-M':
+X Gl.magenta = Gl.colorsubset = 1
+X elif optname = '-Y':
+X Gl.yellow = Gl.colorsubset = 1
+X elif optname = '-K':
+X Gl.black = Gl.colorsubset = 1
+X else:
+X print 'Unsupported option', optname
+X return args
+X
+Xdef usage(exc, msg):
+X if sys.argv:
+X progname = path.basename(sys.argv[0])
+X else:
+X progname = 'mclock'
+X #
+X print progname + ':',
+X if exc = string.atoi_error:
+X print 'non-numeric argument:',
+X print msg
+X #
+X print 'usage:', progname, '[options] [hh [mm [ss]]]'
+X #
+X print '-A r,g,b : alarm background red,green,blue [255,0,0]'
+X print '-a cmd : shell command executed when alarm goes off'
+X print '-B r,g,b : background red,green,blue [0,0,0]'
+X print ' (-B SCREENBG uses the default screen background)'
+X print '-b : suppress window border and title'
+X print '-c cmapid : select explicit colormap'
+X print '-d : more debug output (implies -F, -w)'
+X print '-F : run in foreground'
+X print '-f : use full screen'
+X print '-G intrvl : interval between chimes in minutes [60]'
+X print '-g cmd : shell command executed when chimes go off'
+X print '-s : single buffer mode'
+X print '-w : print various warnings'
+X print '-n nparts : number of parts [' + `NPARTS` + ']'
+X print '-T title : alternate window title [\'' + TITLE + '\']'
+X print '-t tzdiff : time zone difference [' + `TZDIFF` + ']'
+X print '-u update : update interval [60]'
+X print '-CMYK : Cyan, Magenta, Yellow or blacK overlay only'
+X print 'if hh [mm [ss]] is specified, display that time statically'
+X print 'on machines with < 12 bitplanes, -c and -s are forced on'
+X #
+X sys.exit(2)
+X
+Xdef doit(localtime):
+X hands = makehands(localtime)
+X list = makelist(hands)
+X render(list, hands)
+X
+Xdef makehands(localtime):
+X localtime = localtime % (12*HOUR)
+X seconds_hand = MIDN + FULLC - (localtime*60) % FULLC
+X big_hand = (MIDN + FULLC - (localtime%HOUR)) % FULLC
+X little_hand = (MIDN + FULLC - ((localtime/12) % HOUR)) % FULLC
+X return little_hand, big_hand, seconds_hand
+X
+Xdef makelist(little_hand, big_hand, seconds_hand):
+X total = []
+X if Gl.cyan or not Gl.colorsubset:
+X total = total + makesublist(big_hand, Gl.indices[0])
+X if Gl.magenta or not Gl.colorsubset:
+X total = total + makesublist(little_hand, Gl.indices[1])
+X if Gl.yellow or not Gl.colorsubset:
+X total = total + makesublist(MIDN, Gl.indices[2])
+X total.sort()
+X return total
+X
+Xdef makesublist(first, icolor):
+X list = []
+X alpha = FULLC/Gl.nparts
+X a = first - alpha/2
+X for i in range(Gl.nparts):
+X angle = (a + i*alpha + FULLC) % FULLC
+X value = 255*(Gl.nparts-1-i)/(Gl.nparts-1)
+X list.append(angle, icolor, value)
+X list.sort()
+X a, icolor, value = list[0]
+X if a <> 0:
+X a, icolor, value = list[len(list)-1]
+X t = 0, icolor, value
+X list.insert(0, t)
+X return list
+X
+Xdef rgb_fg():
+X return Gl.fg
+X # Obsolete code:
+X if Gl.alarm_on:
+X return Gl.bg
+X else:
+X return Gl.fg
+X
+Xdef rgb_bg():
+X return Gl.bg
+X # Obsolete code:
+X if Gl.alarm_on:
+X return Gl.fg
+X else:
+X return Gl.bg
+X
+Xdef clearall():
+X Gl.c3i(rgb_bg())
+X clear()
+X if Gl.doublebuffer:
+X swapbuffers()
+X clear()
+X
+Xdef draw_alarm(color):
+X frontbuffer(TRUE)
+X Gl.c3i(color)
+X pushmatrix()
+X rotate(-((Gl.alarm_time/12)%3600), 'z')
+X bgnpolygon()
+X v2f( 0.00,1.00)
+X v2f( 0.04,1.05)
+X v2f(-0.04,1.05)
+X endpolygon()
+X popmatrix()
+X #
+X pushmatrix()
+X rotate(-((Gl.alarm_time)%3600), 'z')
+X bgnpolygon()
+X v2f( 0.00,1.05)
+X v2f( 0.07,1.10)
+X v2f(-0.07,1.10)
+X endpolygon()
+X popmatrix()
+X #
+X cmov2(-1.06, -1.06)
+X charstr(string.rjust(`Gl.alarm_time/3600`,2))
+X charstr(':')
+X charstr(string.zfill((Gl.alarm_time/60)%60,2))
+X frontbuffer(FALSE)
+X
+Xdef render(list, (little_hand, big_hand, seconds_hand)):
+X #
+X if Gl.colormap:
+X resetindex()
+X #
+X if not list:
+X Gl.c3i(255, 255, 255) # White
+X circf(0.0, 0.0, 1.0)
+X else:
+X list.append(3600, 0, 255) # Sentinel
+X #
+X rgb = [255, 255, 255]
+X a_prev = 0
+X for a, icolor, value in list:
+X if a <> a_prev:
+X [r, g, b] = rgb
+X if Gl.debug > 1:
+X print rgb, a_prev, a
+X Gl.c3i(r, g, b)
+X arcf(0.0, 0.0, 1.0, a_prev, a)
+X rgb[icolor] = value
+X a_prev = a
+X #
+X if Gl.black or not Gl.colorsubset:
+X #
+X # Draw the hands -- in black
+X #
+X Gl.c3i(0, 0, 0)
+X #
+X if Gl.update = 1 and not Gl.iconic:
+X # Seconds hand is only drawn if we update every second
+X pushmatrix()
+X rotate(seconds_hand, 'z')
+X bgnline()
+X v2f(0.0, 0.0)
+X v2f(1.0, 0.0)
+X endline()
+X popmatrix()
+X #
+X pushmatrix()
+X rotate(big_hand, 'z')
+X rectf(0.0, -0.01, 0.97, 0.01)
+X circf(0.0, 0.0, 0.01)
+X circf(0.97, 0.0, 0.01)
+X popmatrix()
+X #
+X pushmatrix()
+X rotate(little_hand, 'z')
+X rectf(0.04, -0.02, 0.63, 0.02)
+X circf(0.04, 0.0, 0.02)
+X circf(0.63, 0.0, 0.02)
+X popmatrix()
+X #
+X # Draw the alarm time, if set or being set
+X #
+X if Gl.alarm_set:
+X draw_alarm(rgb_fg())
+X #
+X if Gl.doublebuffer: swapbuffers()
+X
+Xdef makewindow():
+X #
+X if Gl.debug or Gl.foreground:
+X foreground()
+X #
+X if Gl.fullscreen:
+X # XXX Should find out true screen size using getgdesc()
+X prefposition(0, 1279, 0, 1023)
+X else:
+X keepaspect(1, 1)
+X minsize(64, 64)
+X #
+X if not Gl.border:
+X noborder()
+X wid = winopen(Gl.title)
+X #
+X if not Gl.fullscreen:
+X keepaspect(1, 1)
+X minsize(10, 10)
+X maxsize(2000, 2000)
+X iconsize(66, 66)
+X winconstraints()
+X #
+X nplanes = getplanes()
+X nmaps = getgdesc(GD_NMMAPS)
+X if Gl.warnings:
+X print nplanes, 'color planes,', nmaps, 'color maps'
+X #
+X if nplanes < 12 or Gl.colormap:
+X if not Gl.colormap:
+X Gl.colormap = nmaps - 1
+X if Gl.warnings:
+X print 'not enough color planes available',
+X print 'for RGB mode; forcing colormap mode'
+X print 'using color map number', Gl.colormap
+X if not Gl.colorsubset:
+X needed = 3
+X else:
+X needed = Gl.cyan + Gl.magenta + Gl.yellow
+X needed = needed*Gl.nparts
+X if Gl.bg <> (0, 0, 0):
+X needed = needed+1
+X if Gl.fg <> (0, 0, 0):
+X needed = needed+1
+X if Gl.doublebuffer:
+X if needed > available(nplanes/2):
+X Gl.doublebuffer = 0
+X if Gl.warnings:
+X print 'not enough colors available',
+X print 'for double buffer mode;',
+X print 'forcing single buffer mode'
+X else:
+X nplanes = nplanes/2
+X if needed > available(nplanes):
+X # Do this warning always
+X print 'still not enough colors available;',
+X print 'parts will be left white'
+X print '(needed', needed, 'but have only',
+X print available(nplanes), 'colors available)'
+X #
+X if Gl.doublebuffer:
+X doublebuffer()
+X gconfig()
+X #
+X if Gl.colormap:
+X Gl.c3i = pseudo_c3i
+X fixcolormap()
+X else:
+X Gl.c3i = c3i
+X RGBmode()
+X gconfig()
+X #
+X if Gl.fullscreen:
+X # XXX Should find out true screen size using getgdesc()
+X ortho2(-1.1*1.280, 1.1*1.280, -1.1*1.024, 1.1*1.024)
+X else:
+X ortho2(-1.1, 1.1, -1.1, 1.1)
+X #
+X return wid
+X
+Xdef available(nplanes):
+X return pow(2, nplanes) - 1 # Reserve one pixel for black
+X
+Xdef fixcolormap():
+X multimap()
+X gconfig()
+X nplanes = getplanes()
+X if Gl.warnings:
+X print 'multimap mode has', nplanes, 'color planes'
+X imap = Gl.colormap
+X Gl.startindex = pow(2, nplanes) - 1
+X Gl.stopindex = 1
+X setmap(imap)
+X mapcolor(0, 0, 0, 0) # Fixed entry for black
+X if Gl.bg <> (0, 0, 0):
+X r, g, b = Gl.bg
+X mapcolor(1, r, g, b) # Fixed entry for Gl.bg
+X Gl.stopindex = 2
+X if Gl.fg <> (0, 0, 0):
+X r, g, b = Gl.fg
+X mapcolor(2, r, g, b) # Fixed entry for Gl.fg
+X Gl.stopindex = 3
+X Gl.overflow_seen = 0
+X resetindex()
+X
+Xdef resetindex():
+X Gl.index = Gl.startindex
+X
+Xr0g0b0 = (0, 0, 0)
+X
+Xdef pseudo_c3i(rgb):
+X if rgb = r0g0b0:
+X index = 0
+X elif rgb = Gl.bg:
+X index = 1
+X elif rgb = Gl.fg:
+X index = 2
+X else:
+X index = definecolor(rgb)
+X color(index)
+X
+Xdef definecolor(rgb):
+X index = Gl.index
+X if index < Gl.stopindex:
+X if Gl.debug: print 'definecolor hard case', rgb
+X # First see if we already have this one...
+X for index in range(Gl.stopindex, Gl.startindex+1):
+X if rgb = getmcolor(index):
+X if Gl.debug: print 'return', index
+X return index
+X # Don't clobber reserverd colormap entries
+X if not Gl.overflow_seen:
+X # Shouldn't happen any more, hence no Gl.warnings test
+X print 'mclock: out of colormap entries'
+X Gl.overflow_seen = 1
+X return Gl.stopindex
+X r, g, b = rgb
+X if Gl.debug > 1: print 'mapcolor', (index, r, g, b)
+X mapcolor(index, r, g, b)
+X Gl.index = index - 1
+X return index
+X
+X# Compute n**i
+Xdef pow(n, i):
+X x = 1
+X for j in range(i): x = x*n
+X return x
+X
+Xdef mouseclick(mouse, updown, x, y):
+X if updown = 1:
+X # mouse button came down, start tracking
+X if Gl.debug:
+X print 'mouse', mouse, 'down at', x, y
+X if mouse = 2:
+X Gl.mouse2down = 1
+X mouse2track(x, y)
+X elif mouse = 3:
+X Gl.mouse3down = 1
+X mouse3track(x, y)
+X else:
+X print 'fatal error'
+X qdevice(MOUSEX)
+X qdevice(MOUSEY)
+X return 0
+X else:
+X # mouse button came up, stop tracking
+X if Gl.debug:
+X print 'mouse', mouse, 'up at', x, y
+X unqdevice(MOUSEX)
+X unqdevice(MOUSEY)
+X if mouse = 2:
+X mouse2track(x, y)
+X Gl.mouse2down = 0
+X elif mouse = 3:
+X mouse3track(x, y)
+X Gl.mouse3down = 0
+X else:
+X print 'fatal error'
+X Gl.alarm_set = 1
+X return 1
+X
+Xdef mouse3track(x, y):
+X # first compute polar coordinates from x and y
+X cx, cy = Gl.ox + Gl.cx/2, Gl.oy + Gl.cy/2
+X x, y = x - cx, y - cy
+X if (x, y) = (0, 0): return # would cause an exception
+X minutes = int(30.5 + 30.0*math.atan2(float(-x), float(-y))/pi)
+X if minutes = 60: minutes = 0
+X a,b = Gl.alarm_minutes/15, minutes/15
+X if (a,b) = (0,3):
+X # Moved backward through 12 o'clock:
+X Gl.alarm_hours = Gl.alarm_hours - 1
+X if Gl.alarm_hours < 0: Gl.alarm_hours = Gl.alarm_hours + 24
+X if (a,b) = (3,0):
+X # Moved forward through 12 o'clock:
+X Gl.alarm_hours = Gl.alarm_hours + 1
+X if Gl.alarm_hours >= 24: Gl.alarm_hours = Gl.alarm_hours - 24
+X Gl.alarm_minutes = minutes
+X seconds = Gl.alarm_hours * HOUR + Gl.alarm_minutes * MINUTE
+X if seconds <> Gl.alarm_time:
+X draw_alarm(rgb_bg())
+X Gl.alarm_time = seconds
+X draw_alarm(rgb_fg())
+X
+Xdef mouse2track(x, y):
+X # first compute polar coordinates from x and y
+X cx, cy = Gl.ox + Gl.cx/2, Gl.oy + Gl.cy/2
+X x, y = x - cx, y - cy
+X if (x, y) = (0, 0): return # would cause an exception
+X hours = int(6.5 - float(Gl.alarm_minutes)/60.0 + 6.0*math.atan2(float(-x), float(-y))/pi)
+X if hours = 12: hours = 0
+X if (Gl.alarm_hours,hours) = (0,11):
+X # Moved backward through midnight:
+X Gl.alarm_hours = 23
+X elif (Gl.alarm_hours,hours) = (12,11):
+X # Moved backward through noon:
+X Gl.alarm_hours = 11
+X elif (Gl.alarm_hours,hours) = (11,0):
+X # Moved forward through noon:
+X Gl.alarm_hours = 12
+X elif (Gl.alarm_hours,hours) = (23,0):
+X # Moved forward through midnight:
+X Gl.alarm_hours = 0
+X elif Gl.alarm_hours < 12:
+X Gl.alarm_hours = hours
+X else:
+X Gl.alarm_hours = hours + 12
+X seconds = Gl.alarm_hours * HOUR + Gl.alarm_minutes * MINUTE
+X if seconds <> Gl.alarm_time:
+X draw_alarm(rgb_bg())
+X Gl.alarm_time = seconds
+X draw_alarm(rgb_fg())
+X
+Xdef initmenu():
+X Gl.pup = pup = newpup()
+X addtopup(pup, 'M Clock%t|Alarm On/Off|Seconds Hand On/Off|Quit', 0)
+X
+Xdef handlemenu():
+X item = dopup(Gl.pup)
+X if item = 1:
+X # Toggle alarm
+X if Gl.alarm_set:
+X Gl.alarm_set = 0
+X Gl.alarm_on = 0
+X else:
+X Gl.alarm_set = 1
+X Gl.change = 1
+X clearall()
+X elif item = 2:
+X # Toggle Seconds Hand
+X if Gl.update = 1:
+X Gl.update = 60
+X Gl.timernoise = 60
+X else:
+X Gl.update = 1
+X Gl.timernoise = 6
+X Gl.change = 1
+X elif item = 3:
+X if Gl.debug: print 'Exit'
+X sys.exit(0)
+X
+Xmain()
+EOF
+chmod +x 'demo/sgi/gl/mclock.py'
+fi
+if test -s 'src/ceval.c'
+then echo '*** I will not over-write existing file src/ceval.c'
+else
+echo 'x - src/ceval.c'
+sed 's/^X//' > 'src/ceval.c' << 'EOF'
+X/***********************************************************
+XCopyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
+XNetherlands.
+X
+X All Rights Reserved
+X
+XPermission to use, copy, modify, and distribute this software and its
+Xdocumentation for any purpose and without fee is hereby granted,
+Xprovided that the above copyright notice appear in all copies and that
+Xboth that copyright notice and this permission notice appear in
+Xsupporting documentation, and that the names of Stichting Mathematisch
+XCentrum or CWI not be used in advertising or publicity pertaining to
+Xdistribution of the software without specific, written prior permission.
+X
+XSTICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+XTHIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+XWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+XACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+XOF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+X
+X******************************************************************/
+X
+X/* Execute compiled code */
+X
+X#include "allobjects.h"
+X
+X#include "import.h"
+X#include "sysmodule.h"
+X#include "compile.h"
+X#include "frameobject.h"
+X#include "ceval.h"
+X#include "opcode.h"
+X#include "bltinmodule.h"
+X#include "traceback.h"
+X
+X#ifndef NDEBUG
+X#define TRACE
+X#endif
+X
+X#ifdef TRACE
+Xstatic int
+Xprtrace(v, str)
+X object *v;
+X char *str;
+X{
+X printf("%s ", str);
+X printobject(v, stdout, 0);
+X printf("\n");
+X}
+X#endif
+X
+Xstatic frameobject *current_frame;
+X
+Xobject *
+Xgetlocals()
+X{
+X if (current_frame == NULL)
+X return NULL;
+X else
+X return current_frame->f_locals;
+X}
+X
+Xobject *
+Xgetglobals()
+X{
+X if (current_frame == NULL)
+X return NULL;
+X else
+X return current_frame->f_globals;
+X}
+X
+Xvoid
+Xprinttraceback(fp)
+X FILE *fp;
+X{
+X object *v = tb_fetch();
+X if (v != NULL) {
+X fprintf(fp, "Stack backtrace (innermost last):\n");
+X tb_print(v, fp);
+X DECREF(v);
+X }
+X}
+X
+X
+X/* XXX Mixing "print ...," and direct file I/O on stdin/stdout
+X XXX has some bad consequences. The needspace flag should
+X XXX really be part of the file object. */
+X
+Xstatic int needspace;
+X
+Xvoid
+Xflushline()
+X{
+X FILE *fp = sysgetfile("stdout", stdout);
+X if (needspace) {
+X fprintf(fp, "\n");
+X needspace = 0;
+X }
+X}
+X
+X
+X/* Test a value used as condition, e.g., in a for or if statement */
+X
+Xstatic int
+Xtestbool(v)
+X object *v;
+X{
+X if (is_intobject(v))
+X return getintvalue(v) != 0;
+X if (is_floatobject(v))
+X return getfloatvalue(v) != 0.0;
+X if (v->ob_type->tp_as_sequence != NULL)
+X return (*v->ob_type->tp_as_sequence->sq_length)(v) != 0;
+X if (v->ob_type->tp_as_mapping != NULL)
+X return (*v->ob_type->tp_as_mapping->mp_length)(v) != 0;
+X if (v == None)
+X return 0;
+X /* All other objects are 'true' */
+X return 1;
+X}
+X
+Xstatic object *
+Xadd(v, w)
+X object *v, *w;
+X{
+X if (v->ob_type->tp_as_number != NULL)
+X v = (*v->ob_type->tp_as_number->nb_add)(v, w);
+X else if (v->ob_type->tp_as_sequence != NULL)
+X v = (*v->ob_type->tp_as_sequence->sq_concat)(v, w);
+X else {
+X err_setstr(TypeError, "+ not supported by operands");
+X return NULL;
+X }
+X return v;
+X}
+X
+Xstatic object *
+Xsub(v, w)
+X object *v, *w;
+X{
+X if (v->ob_type->tp_as_number != NULL)
+X return (*v->ob_type->tp_as_number->nb_subtract)(v, w);
+X err_setstr(TypeError, "bad operand type(s) for -");
+X return NULL;
+X}
+X
+Xstatic object *
+Xmul(v, w)
+X object *v, *w;
+X{
+X typeobject *tp;
+X if (is_intobject(v) && w->ob_type->tp_as_sequence != NULL) {
+X /* int*sequence -- swap v and w */
+X object *tmp = v;
+X v = w;
+X w = tmp;
+X }
+X tp = v->ob_type;
+X if (tp->tp_as_number != NULL)
+X return (*tp->tp_as_number->nb_multiply)(v, w);
+X if (tp->tp_as_sequence != NULL) {
+X if (!is_intobject(w)) {
+X err_setstr(TypeError,
+X "can't multiply sequence with non-int");
+X return NULL;
+X }
+X if (tp->tp_as_sequence->sq_repeat == NULL) {
+X err_setstr(TypeError, "sequence does not support *");
+X return NULL;
+X }
+X return (*tp->tp_as_sequence->sq_repeat)
+X (v, (int)getintvalue(w));
+X }
+X err_setstr(TypeError, "bad operand type(s) for *");
+X return NULL;
+X}
+X
+Xstatic object *
+Xdivide(v, w)
+X object *v, *w;
+X{
+X if (v->ob_type->tp_as_number != NULL)
+X return (*v->ob_type->tp_as_number->nb_divide)(v, w);
+X err_setstr(TypeError, "bad operand type(s) for /");
+X return NULL;
+X}
+X
+Xstatic object *
+Xrem(v, w)
+X object *v, *w;
+X{
+X if (v->ob_type->tp_as_number != NULL)
+X return (*v->ob_type->tp_as_number->nb_remainder)(v, w);
+X err_setstr(TypeError, "bad operand type(s) for %");
+X return NULL;
+X}
+X
+Xstatic object *
+Xneg(v)
+X object *v;
+X{
+X if (v->ob_type->tp_as_number != NULL)
+X return (*v->ob_type->tp_as_number->nb_negative)(v);
+X err_setstr(TypeError, "bad operand type(s) for unary -");
+X return NULL;
+X}
+X
+Xstatic object *
+Xpos(v)
+X object *v;
+X{
+X if (v->ob_type->tp_as_number != NULL)
+X return (*v->ob_type->tp_as_number->nb_positive)(v);
+X err_setstr(TypeError, "bad operand type(s) for unary +");
+X return NULL;
+X}
+X
+Xstatic object *
+Xnot(v)
+X object *v;
+X{
+X int outcome = testbool(v);
+X object *w = outcome == 0 ? True : False;
+X INCREF(w);
+X return w;
+X}
+X
+Xstatic object *
+Xcall_builtin(func, arg)
+X object *func;
+X object *arg;
+X{
+X if (is_methodobject(func)) {
+X method meth = getmethod(func);
+X object *self = getself(func);
+X return (*meth)(self, arg);
+X }
+X if (is_classobject(func)) {
+X if (arg != NULL) {
+X err_setstr(TypeError,
+X "classobject() allows no arguments");
+X return NULL;
+X }
+X return newclassmemberobject(func);
+X }
+X err_setstr(TypeError, "call of non-function");
+X return NULL;
+X}
+X
+Xstatic object *
+Xcall_function(func, arg)
+X object *func;
+X object *arg;
+X{
+X object *newarg = NULL;
+X object *newlocals, *newglobals;
+X object *co, *v;
+X
+X if (is_classmethodobject(func)) {
+X object *self = classmethodgetself(func);
+X func = classmethodgetfunc(func);
+X if (arg == NULL) {
+X arg = self;
+X }
+X else {
+X newarg = newtupleobject(2);
+X if (newarg == NULL)
+X return NULL;
+X INCREF(self);
+X INCREF(arg);
+X settupleitem(newarg, 0, self);
+X settupleitem(newarg, 1, arg);
+X arg = newarg;
+X }
+X }
+X else {
+X if (!is_funcobject(func)) {
+X err_setstr(TypeError, "call of non-function");
+X return NULL;
+X }
+X }
+X
+X co = getfunccode(func);
+X if (co == NULL) {
+X XDECREF(newarg);
+X return NULL;
+X }
+X if (!is_codeobject(co)) {
+X fprintf(stderr, "XXX Bad code\n");
+X abort();
+X }
+X newlocals = newdictobject();
+X if (newlocals == NULL) {
+X XDECREF(newarg);
+X return NULL;
+X }
+X
+X newglobals = getfuncglobals(func);
+X INCREF(newglobals);
+X
+X v = eval_code((codeobject *)co, newglobals, newlocals, arg);
+X
+X DECREF(newlocals);
+X DECREF(newglobals);
+X
+X XDECREF(newarg);
+X
+X return v;
+X}
+X
+Xstatic object *
+Xapply_subscript(v, w)
+X object *v, *w;
+X{
+X typeobject *tp = v->ob_type;
+X if (tp->tp_as_sequence == NULL && tp->tp_as_mapping == NULL) {
+X err_setstr(TypeError, "unsubscriptable object");
+X return NULL;
+X }
+X if (tp->tp_as_sequence != NULL) {
+X int i;
+X if (!is_intobject(w)) {
+X err_setstr(TypeError, "sequence subscript not int");
+X return NULL;
+X }
+X i = getintvalue(w);
+X return (*tp->tp_as_sequence->sq_item)(v, i);
+X }
+X return (*tp->tp_as_mapping->mp_subscript)(v, w);
+X}
+X
+Xstatic object *
+Xloop_subscript(v, w)
+X object *v, *w;
+X{
+X sequence_methods *sq = v->ob_type->tp_as_sequence;
+X int i, n;
+X if (sq == NULL) {
+X err_setstr(TypeError, "loop over non-sequence");
+X return NULL;
+X }
+X i = getintvalue(w);
+X n = (*sq->sq_length)(v);
+X if (i >= n)
+X return NULL; /* End of loop */
+X return (*sq->sq_item)(v, i);
+X}
+X
+Xstatic int
+Xslice_index(v, isize, pi)
+X object *v;
+X int isize;
+X int *pi;
+X{
+X if (v != NULL) {
+X if (!is_intobject(v)) {
+X err_setstr(TypeError, "slice index must be int");
+X return -1;
+X }
+X *pi = getintvalue(v);
+X if (*pi < 0)
+X *pi += isize;
+X }
+X return 0;
+X}
+X
+Xstatic object *
+Xapply_slice(u, v, w) /* return u[v:w] */
+X object *u, *v, *w;
+X{
+X typeobject *tp = u->ob_type;
+X int ilow, ihigh, isize;
+X if (tp->tp_as_sequence == NULL) {
+X err_setstr(TypeError, "only sequences can be sliced");
+X return NULL;
+X }
+X ilow = 0;
+X isize = ihigh = (*tp->tp_as_sequence->sq_length)(u);
+X if (slice_index(v, isize, &ilow) != 0)
+X return NULL;
+X if (slice_index(w, isize, &ihigh) != 0)
+X return NULL;
+X return (*tp->tp_as_sequence->sq_slice)(u, ilow, ihigh);
+X}
+X
+Xstatic int
+Xassign_subscript(w, key, v) /* w[key] = v */
+X object *w;
+X object *key;
+X object *v;
+X{
+X typeobject *tp = w->ob_type;
+X sequence_methods *sq;
+X mapping_methods *mp;
+X int (*func)();
+X if ((sq = tp->tp_as_sequence) != NULL &&
+X (func = sq->sq_ass_item) != NULL) {
+X if (!is_intobject(key)) {
+X err_setstr(TypeError,
+X "sequence subscript must be integer");
+X return -1;
+X }
+X else
+X return (*func)(w, (int)getintvalue(key), v);
+X }
+X else if ((mp = tp->tp_as_mapping) != NULL &&
+X (func = mp->mp_ass_subscript) != NULL) {
+X return (*func)(w, key, v);
+X }
+X else {
+X err_setstr(TypeError,
+X "can't assign to this subscripted object");
+X return -1;
+X }
+X}
+X
+Xstatic int
+Xassign_slice(u, v, w, x) /* u[v:w] = x */
+X object *u, *v, *w, *x;
+X{
+X sequence_methods *sq = u->ob_type->tp_as_sequence;
+X int ilow, ihigh, isize;
+X if (sq == NULL) {
+X err_setstr(TypeError, "assign to slice of non-sequence");
+X return -1;
+X }
+X if (sq == NULL || sq->sq_ass_slice == NULL) {
+X err_setstr(TypeError, "unassignable slice");
+X return -1;
+X }
+X ilow = 0;
+X isize = ihigh = (*sq->sq_length)(u);
+X if (slice_index(v, isize, &ilow) != 0)
+X return -1;
+X if (slice_index(w, isize, &ihigh) != 0)
+X return -1;
+X return (*sq->sq_ass_slice)(u, ilow, ihigh, x);
+X}
+X
+Xstatic int
+Xcmp_exception(err, v)
+X object *err, *v;
+X{
+X if (is_tupleobject(v)) {
+X int i, n;
+X n = gettuplesize(v);
+X for (i = 0; i < n; i++) {
+X if (err == gettupleitem(v, i))
+X return 1;
+X }
+X return 0;
+X }
+X return err == v;
+X}
+X
+Xstatic int
+Xcmp_member(v, w)
+X object *v, *w;
+X{
+X int i, n, cmp;
+X object *x;
+X sequence_methods *sq;
+X /* Special case for char in string */
+X if (is_stringobject(w)) {
+X register char *s, *end;
+X register char c;
+X if (!is_stringobject(v) || getstringsize(v) != 1) {
+X err_setstr(TypeError,
+X "string member test needs char left operand");
+X return -1;
+X }
+X c = getstringvalue(v)[0];
+X s = getstringvalue(w);
+X end = s + getstringsize(w);
+X while (s < end) {
+X if (c == *s++)
+X return 1;
+X }
+X return 0;
+X }
+X sq = w->ob_type->tp_as_sequence;
+X if (sq == NULL) {
+X err_setstr(TypeError,
+X "'in' or 'not in' needs sequence right argument");
+X return -1;
+X }
+X n = (*sq->sq_length)(w);
+X for (i = 0; i < n; i++) {
+X x = (*sq->sq_item)(w, i);
+X cmp = cmpobject(v, x);
+X XDECREF(x);
+X if (cmp == 0)
+X return 1;
+X }
+X return 0;
+X}
+X
+Xstatic object *
+Xcmp_outcome(op, v, w)
+X enum cmp_op op;
+X register object *v;
+X register object *w;
+X{
+X register int cmp;
+X register int res = 0;
+X switch (op) {
+X case IS:
+X case IS_NOT:
+X res = (v == w);
+X if (op == IS_NOT)
+X res = !res;
+X break;
+X case IN:
+X case NOT_IN:
+X res = cmp_member(v, w);
+X if (res < 0)
+X return NULL;
+X if (op == NOT_IN)
+X res = !res;
+X break;
+X case EXC_MATCH:
+X res = cmp_exception(v, w);
+X break;
+X default:
+X cmp = cmpobject(v, w);
+X switch (op) {
+X case LT: res = cmp < 0; break;
+X case LE: res = cmp <= 0; break;
+X case EQ: res = cmp == 0; break;
+X case NE: res = cmp != 0; break;
+X case GT: res = cmp > 0; break;
+X case GE: res = cmp >= 0; break;
+X /* XXX no default? (res is initialized to 0 though) */
+X }
+X }
+X v = res ? True : False;
+X INCREF(v);
+X return v;
+X}
+X
+Xstatic int
+Ximport_from(locals, v, name)
+X object *locals;
+X object *v;
+X char *name;
+X{
+X object *w, *x;
+X w = getmoduledict(v);
+X if (name[0] == '*') {
+X int i;
+X int n = getdictsize(w);
+X for (i = 0; i < n; i++) {
+X name = getdictkey(w, i);
+X if (name == NULL || name[0] == '_')
+X continue;
+X x = dictlookup(w, name);
+X if (x == NULL) {
+X /* XXX can't happen? */
+X err_setstr(NameError, name);
+X return -1;
+X }
+X if (dictinsert(locals, name, x) != 0)
+X return -1;
+X }
+X return 0;
+X }
+X else {
+X x = dictlookup(w, name);
+X if (x == NULL) {
+X err_setstr(NameError, name);
+X return -1;
+X }
+X else
+X return dictinsert(locals, name, x);
+X }
+X}
+X
+Xstatic object *
+Xbuild_class(v, w)
+X object *v; /* None or tuple containing base classes */
+X object *w; /* dictionary */
+X{
+X if (is_tupleobject(v)) {
+X int i;
+X for (i = gettuplesize(v); --i >= 0; ) {
+X object *x = gettupleitem(v, i);
+X if (!is_classobject(x)) {
+X err_setstr(TypeError,
+X "base is not a class object");
+X return NULL;
+X }
+X }
+X }
+X else {
+X v = NULL;
+X }
+X if (!is_dictobject(w)) {
+X err_setstr(SystemError, "build_class with non-dictionary");
+X return NULL;
+X }
+X return newclassobject(v, w);
+X}
+X
+X
+X/* Status code for main loop (reason for stack unwind) */
+X
+Xenum why_code {
+X WHY_NOT, /* No error */
+X WHY_EXCEPTION, /* Exception occurred */
+X WHY_RERAISE, /* Exception re-raised by 'finally' */
+X WHY_RETURN, /* 'return' statement */
+X WHY_BREAK /* 'break' statement */
+X};
+X
+X/* Interpreter main loop */
+X
+Xobject *
+Xeval_code(co, globals, locals, arg)
+X codeobject *co;
+X object *globals;
+X object *locals;
+X object *arg;
+X{
+X register unsigned char *next_instr;
+X register int opcode; /* Current opcode */
+X register int oparg; /* Current opcode argument, if any */
+X register object **stack_pointer;
+X register enum why_code why; /* Reason for block stack unwind */
+X register int err; /* Error status -- nonzero if error */
+X register object *x; /* Result object -- NULL if error */
+X register object *v; /* Temporary objects popped off stack */
+X register object *w;
+X register object *u;
+X register object *t;
+X register frameobject *f; /* Current frame */
+X int lineno; /* Current line number */
+X object *retval; /* Return value iff why == WHY_RETURN */
+X char *name; /* Name used by some instructions */
+X FILE *fp; /* Used by print operations */
+X#ifdef TRACE
+X int trace = dictlookup(globals, "__trace__") != NULL;
+X#endif
+X
+X/* Code access macros */
+X
+X#define GETCONST(i) Getconst(f, i)
+X#define GETNAME(i) Getname(f, i)
+X#define FIRST_INSTR() (GETUSTRINGVALUE(f->f_code->co_code))
+X#define INSTR_OFFSET() (next_instr - FIRST_INSTR())
+X#define NEXTOP() (*next_instr++)
+X#define NEXTARG() (next_instr += 2, (next_instr[-1]<<8) + next_instr[-2])
+X#define JUMPTO(x) (next_instr = FIRST_INSTR() + (x))
+X#define JUMPBY(x) (next_instr += (x))
+X
+X/* Stack manipulation macros */
+X
+X#define STACK_LEVEL() (stack_pointer - f->f_valuestack)
+X#define EMPTY() (STACK_LEVEL() == 0)
+X#define TOP() (stack_pointer[-1])
+X#define BASIC_PUSH(v) (*stack_pointer++ = (v))
+X#define BASIC_POP() (*--stack_pointer)
+X
+X#ifdef TRACE
+X#define PUSH(v) (BASIC_PUSH(v), trace && prtrace(TOP(), "push"))
+X#define POP() (trace && prtrace(TOP(), "pop"), BASIC_POP())
+X#else
+X#define PUSH(v) BASIC_PUSH(v)
+X#define POP() BASIC_POP()
+X#endif
+X
+X f = newframeobject(
+X current_frame, /*back*/
+X co, /*code*/
+X globals, /*globals*/
+X locals, /*locals*/
+X 50, /*nvalues*/
+X 20); /*nblocks*/
+X if (f == NULL)
+X return NULL;
+X
+X current_frame = f;
+X
+X next_instr = GETUSTRINGVALUE(f->f_code->co_code);
+X
+X stack_pointer = f->f_valuestack;
+X
+X if (arg != NULL) {
+X INCREF(arg);
+X PUSH(arg);
+X }
+X
+X why = WHY_NOT;
+X err = 0;
+X x = None; /* Not a reference, just anything non-NULL */
+X lineno = -1;
+X
+X for (;;) {
+X static ticker;
+X
+X /* Do periodic things */
+X
+X if (--ticker < 0) {
+X ticker = 100;
+X if (intrcheck()) {
+X err_set(KeyboardInterrupt);
+X why = WHY_EXCEPTION;
+X tb_here(f, INSTR_OFFSET(), lineno);
+X break;
+X }
+X }
+X
+X /* Extract opcode and argument */
+X
+X opcode = NEXTOP();
+X if (HAS_ARG(opcode))
+X oparg = NEXTARG();
+X
+X#ifdef TRACE
+X /* Instruction tracing */
+X
+X if (trace) {
+X if (HAS_ARG(opcode)) {
+X printf("%d: %d, %d\n",
+X (int) (INSTR_OFFSET() - 3),
+X opcode, oparg);
+X }
+X else {
+X printf("%d: %d\n",
+X (int) (INSTR_OFFSET() - 1), opcode);
+X }
+X }
+X#endif
+X
+X /* Main switch on opcode */
+X
+X switch (opcode) {
+X
+X /* BEWARE!
+X It is essential that any operation that fails sets either
+X x to NULL, err to nonzero, or why to anything but WHY_NOT,
+X and that no operation that succeeds does this! */
+X
+X /* case STOP_CODE: this is an error! */
+X
+X case POP_TOP:
+X v = POP();
+X DECREF(v);
+X break;
+X
+X case ROT_TWO:
+X v = POP();
+X w = POP();
+X PUSH(v);
+X PUSH(w);
+X break;
+X
+X case ROT_THREE:
+X v = POP();
+X w = POP();
+X x = POP();
+X PUSH(v);
+X PUSH(x);
+X PUSH(w);
+X break;
+X
+X case DUP_TOP:
+X v = TOP();
+X INCREF(v);
+X PUSH(v);
+X break;
+X
+X case UNARY_POSITIVE:
+X v = POP();
+X x = pos(v);
+X DECREF(v);
+X PUSH(x);
+X break;
+X
+X case UNARY_NEGATIVE:
+X v = POP();
+X x = neg(v);
+X DECREF(v);
+X PUSH(x);
+X break;
+X
+X case UNARY_NOT:
+X v = POP();
+X x = not(v);
+X DECREF(v);
+X PUSH(x);
+X break;
+X
+X case UNARY_CONVERT:
+X v = POP();
+X x = reprobject(v);
+X DECREF(v);
+X PUSH(x);
+X break;
+X
+X case UNARY_CALL:
+X v = POP();
+X if (is_classmethodobject(v) || is_funcobject(v))
+X x = call_function(v, (object *)NULL);
+X else
+X x = call_builtin(v, (object *)NULL);
+X DECREF(v);
+X PUSH(x);
+X break;
+X
+X case BINARY_MULTIPLY:
+X w = POP();
+X v = POP();
+X x = mul(v, w);
+X DECREF(v);
+X DECREF(w);
+X PUSH(x);
+X break;
+X
+X case BINARY_DIVIDE:
+X w = POP();
+X v = POP();
+X x = divide(v, w);
+X DECREF(v);
+X DECREF(w);
+X PUSH(x);
+X break;
+X
+X case BINARY_MODULO:
+X w = POP();
+X v = POP();
+X x = rem(v, w);
+X DECREF(v);
+X DECREF(w);
+X PUSH(x);
+X break;
+X
+X case BINARY_ADD:
+X w = POP();
+X v = POP();
+X x = add(v, w);
+X DECREF(v);
+X DECREF(w);
+X PUSH(x);
+X break;
+X
+X case BINARY_SUBTRACT:
+X w = POP();
+X v = POP();
+X x = sub(v, w);
+X DECREF(v);
+X DECREF(w);
+X PUSH(x);
+X break;
+X
+X case BINARY_SUBSCR:
+X w = POP();
+X v = POP();
+X x = apply_subscript(v, w);
+X DECREF(v);
+X DECREF(w);
+X PUSH(x);
+X break;
+X
+X case BINARY_CALL:
+X w = POP();
+X v = POP();
+X if (is_classmethodobject(v) || is_funcobject(v))
+X x = call_function(v, w);
+X else
+X x = call_builtin(v, w);
+X DECREF(v);
+X DECREF(w);
+X PUSH(x);
+X break;
+X
+X case SLICE+0:
+X case SLICE+1:
+X case SLICE+2:
+X case SLICE+3:
+X if ((opcode-SLICE) & 2)
+X w = POP();
+X else
+X w = NULL;
+X if ((opcode-SLICE) & 1)
+X v = POP();
+X else
+X v = NULL;
+X u = POP();
+X x = apply_slice(u, v, w);
+X DECREF(u);
+X XDECREF(v);
+X XDECREF(w);
+X PUSH(x);
+X break;
+X
+X case STORE_SLICE+0:
+X case STORE_SLICE+1:
+X case STORE_SLICE+2:
+X case STORE_SLICE+3:
+X if ((opcode-STORE_SLICE) & 2)
+X w = POP();
+X else
+X w = NULL;
+X if ((opcode-STORE_SLICE) & 1)
+X v = POP();
+X else
+X v = NULL;
+X u = POP();
+X t = POP();
+X err = assign_slice(u, v, w, t); /* u[v:w] = t */
+X DECREF(t);
+X DECREF(u);
+X XDECREF(v);
+X XDECREF(w);
+X break;
+X
+X case DELETE_SLICE+0:
+X case DELETE_SLICE+1:
+X case DELETE_SLICE+2:
+X case DELETE_SLICE+3:
+X if ((opcode-DELETE_SLICE) & 2)
+X w = POP();
+X else
+X w = NULL;
+X if ((opcode-DELETE_SLICE) & 1)
+X v = POP();
+X else
+X v = NULL;
+X u = POP();
+X err = assign_slice(u, v, w, (object *)NULL);
+X /* del u[v:w] */
+X DECREF(u);
+X XDECREF(v);
+X XDECREF(w);
+X break;
+X
+X case STORE_SUBSCR:
+X w = POP();
+X v = POP();
+X u = POP();
+X /* v[w] = u */
+X err = assign_subscript(v, w, u);
+X DECREF(u);
+X DECREF(v);
+X DECREF(w);
+X break;
+X
+X case DELETE_SUBSCR:
+X w = POP();
+X v = POP();
+X /* del v[w] */
+X err = assign_subscript(v, w, (object *)NULL);
+X DECREF(v);
+X DECREF(w);
+X break;
+X
+X case PRINT_EXPR:
+X v = POP();
+X fp = sysgetfile("stdout", stdout);
+X /* Print value except if procedure result */
+X if (v != None) {
+X flushline();
+X printobject(v, fp, 0);
+X fprintf(fp, "\n");
+X }
+X DECREF(v);
+X break;
+X
+X case PRINT_ITEM:
+X v = POP();
+X fp = sysgetfile("stdout", stdout);
+X if (needspace)
+X fprintf(fp, " ");
+X if (is_stringobject(v)) {
+X char *s = getstringvalue(v);
+X int len = getstringsize(v);
+X fwrite(s, 1, len, fp);
+X if (len > 0 && s[len-1] == '\n')
+X needspace = 0;
+X else
+X needspace = 1;
+X }
+X else {
+X printobject(v, fp, 0);
+X needspace = 1;
+X }
+X DECREF(v);
+X break;
+X
+X case PRINT_NEWLINE:
+X fp = sysgetfile("stdout", stdout);
+X fprintf(fp, "\n");
+X needspace = 0;
+X break;
+X
+X case BREAK_LOOP:
+X why = WHY_BREAK;
+X break;
+X
+X case RAISE_EXCEPTION:
+X v = POP();
+X w = POP();
+X if (!is_stringobject(w))
+X err_setstr(TypeError,
+X "exceptions must be strings");
+X else
+X err_setval(w, v);
+X DECREF(v);
+X DECREF(w);
+X why = WHY_EXCEPTION;
+X break;
+X
+X case LOAD_LOCALS:
+X v = f->f_locals;
+X INCREF(v);
+X PUSH(v);
+X break;
+X
+X case RETURN_VALUE:
+X retval = POP();
+X why = WHY_RETURN;
+X break;
+X
+X case REQUIRE_ARGS:
+X if (EMPTY()) {
+X err_setstr(TypeError,
+X "function expects argument(s)");
+X why = WHY_EXCEPTION;
+X }
+X break;
+X
+X case REFUSE_ARGS:
+X if (!EMPTY()) {
+X err_setstr(TypeError,
+X "function expects no argument(s)");
+X why = WHY_EXCEPTION;
+X }
+X break;
+X
+X case BUILD_FUNCTION:
+X v = POP();
+X x = newfuncobject(v, f->f_globals);
+X DECREF(v);
+X PUSH(x);
+X break;
+X
+X case POP_BLOCK:
+X {
+X block *b = pop_block(f);
+X while (STACK_LEVEL() > b->b_level) {
+X v = POP();
+X DECREF(v);
+X }
+X }
+X break;
+X
+X case END_FINALLY:
+X v = POP();
+X if (is_intobject(v)) {
+X why = (enum why_code) getintvalue(v);
+X if (why == WHY_RETURN)
+X retval = POP();
+X }
+X else if (is_stringobject(v)) {
+X w = POP();
+X err_setval(v, w);
+X DECREF(w);
+X w = POP();
+X tb_store(w);
+X DECREF(w);
+X why = WHY_RERAISE;
+X }
+X else if (v != None) {
+X err_setstr(SystemError,
+X "'finally' pops bad exception");
+X why = WHY_EXCEPTION;
+X }
+X DECREF(v);
+X break;
+X
+X case BUILD_CLASS:
+X w = POP();
+X v = POP();
+X x = build_class(v, w);
+X PUSH(x);
+X DECREF(v);
+X DECREF(w);
+X break;
+X
+X case STORE_NAME:
+X name = GETNAME(oparg);
+X v = POP();
+X err = dictinsert(f->f_locals, name, v);
+X DECREF(v);
+X break;
+X
+X case DELETE_NAME:
+X name = GETNAME(oparg);
+X if ((err = dictremove(f->f_locals, name)) != 0)
+X err_setstr(NameError, name);
+X break;
+X
+X case UNPACK_TUPLE:
+X v = POP();
+X if (!is_tupleobject(v)) {
+X err_setstr(TypeError, "unpack non-tuple");
+X why = WHY_EXCEPTION;
+X }
+X else if (gettuplesize(v) != oparg) {
+X err_setstr(RuntimeError,
+X "unpack tuple of wrong size");
+X why = WHY_EXCEPTION;
+X }
+X else {
+X for (; --oparg >= 0; ) {
+X w = gettupleitem(v, oparg);
+X INCREF(w);
+X PUSH(w);
+X }
+X }
+X DECREF(v);
+X break;
+X
+X case UNPACK_LIST:
+X v = POP();
+X if (!is_listobject(v)) {
+X err_setstr(TypeError, "unpack non-list");
+X why = WHY_EXCEPTION;
+X }
+X else if (getlistsize(v) != oparg) {
+X err_setstr(RuntimeError,
+X "unpack list of wrong size");
+X why = WHY_EXCEPTION;
+X }
+X else {
+X for (; --oparg >= 0; ) {
+X w = getlistitem(v, oparg);
+X INCREF(w);
+X PUSH(w);
+X }
+X }
+X DECREF(v);
+X break;
+X
+X case STORE_ATTR:
+X name = GETNAME(oparg);
+X v = POP();
+X u = POP();
+X err = setattr(v, name, u); /* v.name = u */
+X DECREF(v);
+X DECREF(u);
+X break;
+X
+X case DELETE_ATTR:
+X name = GETNAME(oparg);
+X v = POP();
+X err = setattr(v, name, (object *)NULL);
+X /* del v.name */
+X DECREF(v);
+X break;
+X
+X case LOAD_CONST:
+X x = GETCONST(oparg);
+X INCREF(x);
+X PUSH(x);
+X break;
+X
+X case LOAD_NAME:
+X name = GETNAME(oparg);
+X x = dictlookup(f->f_locals, name);
+X if (x == NULL) {
+X x = dictlookup(f->f_globals, name);
+X if (x == NULL)
+X x = getbuiltin(name);
+X }
+X if (x == NULL)
+X err_setstr(NameError, name);
+X else
+X INCREF(x);
+X PUSH(x);
+X break;
+X
+X case BUILD_TUPLE:
+X x = newtupleobject(oparg);
+X if (x != NULL) {
+X for (; --oparg >= 0;) {
+X w = POP();
+X err = settupleitem(x, oparg, w);
+X if (err != 0)
+X break;
+X }
+X PUSH(x);
+X }
+X break;
+X
+X case BUILD_LIST:
+X x = newlistobject(oparg);
+X if (x != NULL) {
+X for (; --oparg >= 0;) {
+X w = POP();
+X err = setlistitem(x, oparg, w);
+X if (err != 0)
+X break;
+X }
+X PUSH(x);
+X }
+X break;
+X
+X case BUILD_MAP:
+X x = newdictobject();
+X PUSH(x);
+X break;
+X
+X case LOAD_ATTR:
+X name = GETNAME(oparg);
+X v = POP();
+X x = getattr(v, name);
+X DECREF(v);
+X PUSH(x);
+X break;
+X
+X case COMPARE_OP:
+X w = POP();
+X v = POP();
+X x = cmp_outcome((enum cmp_op)oparg, v, w);
+X DECREF(v);
+X DECREF(w);
+X PUSH(x);
+X break;
+X
+X case IMPORT_NAME:
+X name = GETNAME(oparg);
+X x = import_module(name);
+X XINCREF(x);
+X PUSH(x);
+X break;
+X
+X case IMPORT_FROM:
+X name = GETNAME(oparg);
+X v = TOP();
+X err = import_from(f->f_locals, v, name);
+X break;
+X
+X case JUMP_FORWARD:
+X JUMPBY(oparg);
+X break;
+X
+X case JUMP_IF_FALSE:
+X if (!testbool(TOP()))
+X JUMPBY(oparg);
+X break;
+X
+X case JUMP_IF_TRUE:
+X if (testbool(TOP()))
+X JUMPBY(oparg);
+X break;
+X
+X case JUMP_ABSOLUTE:
+X JUMPTO(oparg);
+X break;
+X
+X case FOR_LOOP:
+X /* for v in s: ...
+X On entry: stack contains s, i.
+X On exit: stack contains s, i+1, s[i];
+X but if loop exhausted:
+X s, i are popped, and we jump */
+X w = POP(); /* Loop index */
+X v = POP(); /* Sequence object */
+X u = loop_subscript(v, w);
+X if (u != NULL) {
+X PUSH(v);
+X x = newintobject(getintvalue(w)+1);
+X PUSH(x);
+X DECREF(w);
+X PUSH(u);
+X }
+X else {
+X DECREF(v);
+X DECREF(w);
+X /* A NULL can mean "s exhausted"
+X but also an error: */
+X if (err_occurred())
+X why = WHY_EXCEPTION;
+X else
+X JUMPBY(oparg);
+X }
+X break;
+X
+X case SETUP_LOOP:
+X case SETUP_EXCEPT:
+X case SETUP_FINALLY:
+X setup_block(f, opcode, INSTR_OFFSET() + oparg,
+X STACK_LEVEL());
+X break;
+X
+X case SET_LINENO:
+X#ifdef TRACE
+X if (trace)
+X printf("--- Line %d ---\n", oparg);
+X#endif
+X lineno = oparg;
+X break;
+X
+X default:
+X fprintf(stderr,
+X "XXX lineno: %d, opcode: %d\n",
+X lineno, opcode);
+X err_setstr(SystemError, "eval_code: unknown opcode");
+X why = WHY_EXCEPTION;
+X break;
+X
+X } /* switch */
+X
+X
+X /* Quickly continue if no error occurred */
+X
+X if (why == WHY_NOT) {
+X if (err == 0 && x != NULL)
+X continue; /* Normal, fast path */
+X why = WHY_EXCEPTION;
+X x = None;
+X err = 0;
+X }
+X
+X#ifndef NDEBUG
+X /* Double-check exception status */
+X
+X if (why == WHY_EXCEPTION || why == WHY_RERAISE) {
+X if (!err_occurred()) {
+X fprintf(stderr, "XXX ghost error\n");
+X err_setstr(SystemError, "ghost error");
+X why = WHY_EXCEPTION;
+X }
+X }
+X else {
+X if (err_occurred()) {
+X fprintf(stderr, "XXX undetected error\n");
+X why = WHY_EXCEPTION;
+X }
+X }
+X#endif
+X
+X /* Log traceback info if this is a real exception */
+X
+X if (why == WHY_EXCEPTION) {
+X int lasti = INSTR_OFFSET() - 1;
+X if (HAS_ARG(opcode))
+X lasti -= 2;
+X tb_here(f, lasti, lineno);
+X }
+X
+X /* For the rest, treat WHY_RERAISE as WHY_EXCEPTION */
+X
+X if (why == WHY_RERAISE)
+X why = WHY_EXCEPTION;
+X
+X /* Unwind stacks if a (pseudo) exception occurred */
+X
+X while (why != WHY_NOT && f->f_iblock > 0) {
+X block *b = pop_block(f);
+X while (STACK_LEVEL() > b->b_level) {
+X v = POP();
+X XDECREF(v);
+X }
+X if (b->b_type == SETUP_LOOP && why == WHY_BREAK) {
+X why = WHY_NOT;
+X JUMPTO(b->b_handler);
+X break;
+X }
+X if (b->b_type == SETUP_FINALLY ||
+X b->b_type == SETUP_EXCEPT &&
+X why == WHY_EXCEPTION) {
+X if (why == WHY_EXCEPTION) {
+X object *exc, *val;
+X err_get(&exc, &val);
+X if (val == NULL) {
+X val = None;
+X INCREF(val);
+X }
+X v = tb_fetch();
+X /* Make the raw exception data
+X available to the handler,
+X so a program can emulate the
+X Python main loop. Don't do
+X this for 'finally'. */
+X if (b->b_type == SETUP_EXCEPT) {
+X#if 0 /* Oops, this breaks too many things */
+X sysset("exc_traceback", v);
+X#endif
+X sysset("exc_value", val);
+X sysset("exc_type", exc);
+X err_clear();
+X }
+X PUSH(v);
+X PUSH(val);
+X PUSH(exc);
+X }
+X else {
+X if (why == WHY_RETURN)
+X PUSH(retval);
+X v = newintobject((long)why);
+X PUSH(v);
+X }
+X why = WHY_NOT;
+X JUMPTO(b->b_handler);
+X break;
+X }
+X } /* unwind stack */
+X
+X /* End the loop if we still have an error (or return) */
+X
+X if (why != WHY_NOT)
+X break;
+X
+X } /* main loop */
+X
+X /* Pop remaining stack entries */
+X
+X while (!EMPTY()) {
+X v = POP();
+X XDECREF(v);
+X }
+X
+X /* Restore previous frame and release the current one */
+X
+X current_frame = f->f_back;
+X DECREF(f);
+X
+X if (why == WHY_RETURN)
+X return retval;
+X else
+X return NULL;
+X}
+EOF
+fi
+if test -s 'src/object.h'
+then echo '*** I will not over-write existing file src/object.h'
+else
+echo 'x - src/object.h'
+sed 's/^X//' > 'src/object.h' << 'EOF'
+X/***********************************************************
+XCopyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
+XNetherlands.
+X
+X All Rights Reserved
+X
+XPermission to use, copy, modify, and distribute this software and its
+Xdocumentation for any purpose and without fee is hereby granted,
+Xprovided that the above copyright notice appear in all copies and that
+Xboth that copyright notice and this permission notice appear in
+Xsupporting documentation, and that the names of Stichting Mathematisch
+XCentrum or CWI not be used in advertising or publicity pertaining to
+Xdistribution of the software without specific, written prior permission.
+X
+XSTICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+XTHIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+XFITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+XFOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+XWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+XACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+XOF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+X
+X******************************************************************/
+X
+X#define NDEBUG
+X/* Object and type object interface */
+X
+X/*
+X123456789-123456789-123456789-123456789-123456789-123456789-123456789-12
+X
+XObjects are structures allocated on the heap. Special rules apply to
+Xthe use of objects to ensure they are properly garbage-collected.
+XObjects are never allocated statically or on the stack; they must be
+Xaccessed through special macros and functions only. (Type objects are
+Xexceptions to the first rule; the standard types are represented by
+Xstatically initialized type objects.)
+X
+XAn object has a 'reference count' that is increased or decreased when a
+Xpointer to the object is copied or deleted; when the reference count
+Xreaches zero there are no references to the object left and it can be
+Xremoved from the heap.
+X
+XAn object has a 'type' that determines what it represents and what kind
+Xof data it contains. An object's type is fixed when it is created.
+XTypes themselves are represented as objects; an object contains a
+Xpointer to the corresponding type object. The type itself has a type
+Xpointer pointing to the object representing the type 'type', which
+Xcontains a pointer to itself!).
+X
+XObjects do not float around in memory; once allocated an object keeps
+Xthe same size and address. Objects that must hold variable-size data
+Xcan contain pointers to variable-size parts of the object. Not all
+Xobjects of the same type have the same size; but the size cannot change
+Xafter allocation. (These restrictions are made so a reference to an
+Xobject can be simply a pointer -- moving an object would require
+Xupdating all the pointers, and changing an object's size would require
+Xmoving it if there was another object right next to it.)
+X
+XObjects are always accessed through pointers of the type 'object *'.
+XThe type 'object' is a structure that only contains the reference count
+Xand the type pointer. The actual memory allocated for an object
+Xcontains other data that can only be accessed after casting the pointer
+Xto a pointer to a longer structure type. This longer type must start
+Xwith the reference count and type fields; the macro OB_HEAD should be
+Xused for this (to accomodate for future changes). The implementation
+Xof a particular object type can cast the object pointer to the proper
+Xtype and back.
+X
+XA standard interface exists for objects that contain an array of items
+Xwhose size is determined when the object is allocated.
+X
+X123456789-123456789-123456789-123456789-123456789-123456789-123456789-12
+X*/
+X
+X#ifndef NDEBUG
+X
+X/* Turn on heavy reference debugging */
+X#define TRACE_REFS
+X
+X/* Turn on reference counting */
+X#define REF_DEBUG
+X
+X#endif /* NDEBUG */
+X
+X#ifdef TRACE_REFS
+X#define OB_HEAD \
+X struct _object *_ob_next, *_ob_prev; \
+X int ob_refcnt; \
+X struct _typeobject *ob_type;
+X#define OB_HEAD_INIT(type) 0, 0, 1, type,
+X#else
+X#define OB_HEAD \
+X unsigned int ob_refcnt; \
+X struct _typeobject *ob_type;
+X#define OB_HEAD_INIT(type) 1, type,
+X#endif
+X
+X#define OB_VARHEAD \
+X OB_HEAD \
+X unsigned int ob_size; /* Number of items in variable part */
+X
+Xtypedef struct _object {
+X OB_HEAD
+X} object;
+X
+Xtypedef struct {
+X OB_VARHEAD
+X} varobject;
+X
+X
+X/*
+X123456789-123456789-123456789-123456789-123456789-123456789-123456789-12
+X
+XType objects contain a string containing the type name (to help somewhat
+Xin debugging), the allocation parameters (see newobj() and newvarobj()),
+Xand methods for accessing objects of the type. Methods are optional,a
+Xnil pointer meaning that particular kind of access is not available for
+Xthis type. The DECREF() macro uses the tp_dealloc method without
+Xchecking for a nil pointer; it should always be implemented except if
+Xthe implementation can guarantee that the reference count will never
+Xreach zero (e.g., for type objects).
+X
+XNB: the methods for certain type groups are now contained in separate
+Xmethod blocks.
+X*/
+X
+Xtypedef struct {
+X object *(*nb_add) FPROTO((object *, object *));
+X object *(*nb_subtract) FPROTO((object *, object *));
+X object *(*nb_multiply) FPROTO((object *, object *));
+X object *(*nb_divide) FPROTO((object *, object *));
+X object *(*nb_remainder) FPROTO((object *, object *));
+X object *(*nb_power) FPROTO((object *, object *));
+X object *(*nb_negative) FPROTO((object *));
+X object *(*nb_positive) FPROTO((object *));
+X} number_methods;
+X
+Xtypedef struct {
+X int (*sq_length) FPROTO((object *));
+X object *(*sq_concat) FPROTO((object *, object *));
+X object *(*sq_repeat) FPROTO((object *, int));
+X object *(*sq_item) FPROTO((object *, int));
+X object *(*sq_slice) FPROTO((object *, int, int));
+X int (*sq_ass_item) FPROTO((object *, int, object *));
+X int (*sq_ass_slice) FPROTO((object *, int, int, object *));
+X} sequence_methods;
+X
+Xtypedef struct {
+X int (*mp_length) FPROTO((object *));
+X object *(*mp_subscript) FPROTO((object *, object *));
+X int (*mp_ass_subscript) FPROTO((object *, object *, object *));
+X} mapping_methods;
+X
+Xtypedef struct _typeobject {
+X OB_VARHEAD
+X char *tp_name; /* For printing */
+X unsigned int tp_basicsize, tp_itemsize; /* For allocation */
+X
+X /* Methods to implement standard operations */
+X
+X void (*tp_dealloc) FPROTO((object *));
+X void (*tp_print) FPROTO((object *, FILE *, int));
+X object *(*tp_getattr) FPROTO((object *, char *));
+X int (*tp_setattr) FPROTO((object *, char *, object *));
+X int (*tp_compare) FPROTO((object *, object *));
+X object *(*tp_repr) FPROTO((object *));
+X
+X /* Method suites for standard classes */
+X
+X number_methods *tp_as_number;
+X sequence_methods *tp_as_sequence;
+X mapping_methods *tp_as_mapping;
+X} typeobject;
+X
+Xextern typeobject Typetype; /* The type of type objects */
+X
+X#define is_typeobject(op) ((op)->ob_type == &Typetype)
+X
+X/* Generic operations on objects */
+Xextern void printobject PROTO((object *, FILE *, int));
+Xextern object * reprobject PROTO((object *));
+Xextern int cmpobject PROTO((object *, object *));
+Xextern object *getattr PROTO((object *, char *));
+Xextern int setattr PROTO((object *, char *, object *));
+X
+X/* Flag bits for printing: */
+X#define PRINT_RAW 1 /* No string quotes etc. */
+X
+X/*
+X123456789-123456789-123456789-123456789-123456789-123456789-123456789-12
+X
+XThe macros INCREF(op) and DECREF(op) are used to increment or decrement
+Xreference counts. DECREF calls the object's deallocator function; for
+Xobjects that don't contain references to other objects or heap memory
+Xthis can be the standard function free(). Both macros can be used
+Xwhereever a void expression is allowed. The argument shouldn't be a
+XNIL pointer. The macro NEWREF(op) is used only to initialize reference
+Xcounts to 1; it is defined here for convenience.
+X
+XWe assume that the reference count field can never overflow; this can
+Xbe proven when the size of the field is the same as the pointer size
+Xbut even with a 16-bit reference count field it is pretty unlikely so
+Xwe ignore the possibility. (If you are paranoid, make it a long.)
+X
+XType objects should never be deallocated; the type pointer in an object
+Xis not considered to be a reference to the type object, to save
+Xcomplications in the deallocation function. (This is actually a
+Xdecision that's up to the implementer of each new type so if you want,
+Xyou can count such references to the type object.)
+X
+X*** WARNING*** The DECREF macro must have a side-effect-free argument
+Xsince it may evaluate its argument multiple times. (The alternative
+Xwould be to mace it a proper function or assign it to a global temporary
+Xvariable first, both of which are slower; and in a multi-threaded
+Xenvironment the global variable trick is not safe.)
+X*/
+X
+X#ifdef TRACE_REFS
+X#ifndef REF_DEBUG
+X#define REF_DEBUG
+X#endif
+X#endif
+X
+X#ifndef TRACE_REFS
+X#define DELREF(op) (*(op)->ob_type->tp_dealloc)((object *)(op))
+X#define UNREF(op) /*empty*/
+X#endif
+X
+X#ifdef REF_DEBUG
+Xextern long ref_total;
+X#ifndef TRACE_REFS
+X#define NEWREF(op) (ref_total++, (op)->ob_refcnt = 1)
+X#endif
+X#define INCREF(op) (ref_total++, (op)->ob_refcnt++)
+X#define DECREF(op) \
+X if (--ref_total, --(op)->ob_refcnt > 0) \
+X ; \
+X else \
+X DELREF(op)
+X#else
+X#define NEWREF(op) ((op)->ob_refcnt = 1)
+X#define INCREF(op) ((op)->ob_refcnt++)
+X#define DECREF(op) \
+X if (--(op)->ob_refcnt > 0) \
+X ; \
+X else \
+X DELREF(op)
+X#endif
+X
+X/* Macros to use in case the object pointer may be NULL: */
+X
+X#define XINCREF(op) if ((op) == NULL) ; else INCREF(op)
+X#define XDECREF(op) if ((op) == NULL) ; else DECREF(op)
+X
+X/* Definition of NULL, so you don't have to include <stdio.h> */
+X
+X#ifndef NULL
+X#define NULL 0
+X#endif
+X
+X
+X/*
+XNoObject is an object of undefined type which can be used in contexts
+Xwhere NULL (nil) is not suitable (since NULL often means 'error').
+X
+XDon't forget to apply INCREF() when returning this value!!!
+X*/
+X
+Xextern object NoObject; /* Don't use this directly */
+X
+X#define None (&NoObject)
+X
+X
+X/*
+X123456789-123456789-123456789-123456789-123456789-123456789-123456789-12
+X
+XMore conventions
+X================
+X
+XArgument Checking
+X-----------------
+X
+XFunctions that take objects as arguments normally don't check for nil
+Xarguments, but they do check the type of the argument, and return an
+Xerror if the function doesn't apply to the type.
+X
+XFailure Modes
+X-------------
+X
+XFunctions may fail for a variety of reasons, including running out of
+Xmemory. This is communicated to the caller in two ways: an error string
+Xis set (see errors.h), and the function result differs: functions that
+Xnormally return a pointer return NULL for failure, functions returning
+Xan integer return -1 (which could be a legal return value too!), and
+Xother functions return 0 for success and -1 for failure.
+XCallers should always check for errors before using the result.
+X
+XReference Counts
+X----------------
+X
+XIt takes a while to get used to the proper usage of reference counts.
+X
+XFunctions that create an object set the reference count to 1; such new
+Xobjects must be stored somewhere or destroyed again with DECREF().
+XFunctions that 'store' objects such as settupleitem() and dictinsert()
+Xdon't increment the reference count of the object, since the most
+Xfrequent use is to store a fresh object. Functions that 'retrieve'
+Xobjects such as gettupleitem() and dictlookup() also don't increment
+Xthe reference count, since most frequently the object is only looked at
+Xquickly. Thus, to retrieve an object and store it again, the caller
+Xmust call INCREF() explicitly.
+X
+XNOTE: functions that 'consume' a reference count like dictinsert() even
+Xconsume the reference if the object wasn't stored, to simplify error
+Xhandling.
+X
+XIt seems attractive to make other functions that take an object as
+Xargument consume a reference count; however this may quickly get
+Xconfusing (even the current practice is already confusing). Consider
+Xit carefully, it may safe lots of calls to INCREF() and DECREF() at
+Xtimes.
+X
+X123456789-123456789-123456789-123456789-123456789-123456789-123456789-12
+X*/
+EOF
+fi
+echo 'Part 07 out of 21 of pack.out complete.'
+exit 0