aboutsummaryrefslogtreecommitdiff
path: root/shar/python-0.9.1-11-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-11-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-11-21.shar')
-rw-r--r--shar/python-0.9.1-11-21.shar2618
1 files changed, 2618 insertions, 0 deletions
diff --git a/shar/python-0.9.1-11-21.shar b/shar/python-0.9.1-11-21.shar
new file mode 100644
index 0000000..59aa0a2
--- /dev/null
+++ b/shar/python-0.9.1-11-21.shar
@@ -0,0 +1,2618 @@
+: 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 11 out of 21:'
+if test -s 'lib/Buttons.py'
+then echo '*** I will not over-write existing file lib/Buttons.py'
+else
+echo 'x - lib/Buttons.py'
+sed 's/^X//' > 'lib/Buttons.py' << 'EOF'
+X# Module 'Buttons'
+X
+X
+X# Import module 'rect' renamed as '_rect' to avoid exporting it on
+X# 'from Buttons import *'
+X#
+Ximport rect
+X_rect = rect
+Xdel rect
+X
+X
+X# Field indices in mouse event detail
+X#
+X_HV = 0
+X_CLICKS = 1
+X_BUTTON = 2
+X_MASK = 3
+X
+X
+X# LabelAppearance provides defaults for all appearance methods.
+X# selected state not visible
+X# disabled --> crossed out
+X# hilited --> inverted
+X#
+Xclass LabelAppearance():
+X #
+X # Initialization
+X #
+X def init_appearance(self):
+X self.bounds = _rect.empty
+X self.enabled = 1
+X self.hilited = 0
+X self.selected = 0
+X self.text = ''
+X #
+X # Size enquiry
+X #
+X def minsize(self, m):
+X try:
+X self.text = self.text
+X except NameError:
+X self.text = ''
+X return m.textwidth(self.text) + 6, m.lineheight() + 6
+X #
+X def getbounds(self):
+X return self.bounds
+X #
+X # Changing the parameters
+X #
+X def settext(self, text):
+X self.text = text
+X if self.bounds <> _rect.empty:
+X self.recalctextpos()
+X self.redraw()
+X #
+X def setbounds(self, bounds):
+X if self.bounds <> _rect.empty:
+X self.parent.change(self.bounds)
+X self.bounds = bounds
+X if self.bounds <> _rect.empty:
+X self.recalc()
+X self.parent.change(bounds)
+X #
+X # Changing the state bits
+X #
+X def enable(self, flag):
+X if flag <> self.enabled:
+X self.enabled = flag
+X if self.bounds <> _rect.empty:
+X self.flipenable(self.parent.begindrawing())
+X #
+X def hilite(self, flag):
+X if flag <> self.hilited:
+X self.hilited = flag
+X if self.bounds <> _rect.empty:
+X self.fliphilite(self.parent.begindrawing())
+X #
+X def select(self, flag):
+X if flag <> self.selected:
+X self.selected = flag
+X if self.bounds <> _rect.empty:
+X self.redraw()
+X #
+X # Recalculate the box bounds and text position.
+X # This can be overridden by buttons that draw different boxes
+X # or want their text in a different position.
+X #
+X def recalc(self):
+X if self.bounds <> _rect.empty:
+X self.recalcbounds()
+X self.recalctextpos()
+X #
+X def recalcbounds(self):
+X self.hilitebounds = _rect.inset(self.bounds, (3, 3))
+X self.crossbounds = self.bounds
+X #
+X def recalctextpos(self):
+X (left, top), (right, bottom) = self.bounds
+X m = self.parent.beginmeasuring()
+X h = (left + right - m.textwidth(self.text)) / 2
+X v = (top + bottom - m.lineheight()) / 2
+X self.textpos = h, v
+X #
+X # Generic drawing interface.
+X # Do not override redraw() or draw() methods; override drawit() c.s.
+X #
+X def redraw(self):
+X if self.bounds <> _rect.empty:
+X self.draw(self.parent.begindrawing(), self.bounds)
+X #
+X def draw(self, (d, area)):
+X area = _rect.intersect(area, self.bounds)
+X if area = _rect.empty:
+X return
+X d.cliprect(area)
+X d.erase(self.bounds)
+X self.drawit(d)
+X d.noclip()
+X #
+X # The drawit() method is fairly generic but may be overridden.
+X #
+X def drawit(self, d):
+X self.drawpict(d)
+X if self.text:
+X d.text(self.textpos, self.text)
+X if not self.enabled:
+X self.flipenable(d)
+X if self.hilited:
+X self.fliphilite(d)
+X #
+X # Default drawing detail functions.
+X # Overriding these is normally sufficient to get different
+X # appearances.
+X #
+X def drawpict(self, d):
+X pass
+X #
+X def flipenable(self, d):
+X _xorcross(d, self.crossbounds)
+X #
+X def fliphilite(self, d):
+X d.invert(self.hilitebounds)
+X
+X
+X# ButtonAppearance displays a centered string in a box.
+X# selected --> bold border
+X# disabled --> crossed out
+X# hilited --> inverted
+X#
+Xclass ButtonAppearance() = LabelAppearance():
+X #
+X def drawpict(self, d):
+X d.box(_rect.inset(self.bounds, (1, 1)))
+X if self.selected:
+X # Make a thicker box
+X d.box(self.bounds)
+X d.box(_rect.inset(self.bounds, (2, 2)))
+X d.box(_rect.inset(self.bounds, (3, 3)))
+X #
+X
+X
+X# CheckAppearance displays a small square box and a left-justified string.
+X# selected --> a cross appears in the box
+X# disabled --> whole button crossed out
+X# hilited --> box is inverted
+X#
+Xclass CheckAppearance() = LabelAppearance():
+X #
+X def minsize(self, m):
+X width, height = m.textwidth(self.text) + 6, m.lineheight() + 6
+X return width + height + m.textwidth(' '), height
+X #
+X def drawpict(self, d):
+X d.box(self.boxbounds)
+X if self.selected: _xorcross(d, self.boxbounds)
+X #
+X def recalcbounds(self):
+X LabelAppearance.recalcbounds(self)
+X (left, top), (right, bottom) = self.bounds
+X self.size = bottom - top - 4
+X self.boxbounds = (left+2, top+2), (left+2+self.size, bottom-2)
+X self.hilitebounds = self.boxbounds
+X #
+X def recalctextpos(self):
+X m = self.parent.beginmeasuring()
+X (left, top), (right, bottom) = self.boxbounds
+X h = right + m.textwidth(' ')
+X v = top + (self.size - m.lineheight()) / 2
+X self.textpos = h, v
+X #
+X
+X
+X# RadioAppearance displays a round indicator and a left-justified string.
+X# selected --> a dot appears in the indicator
+X# disabled --> whole button crossed out
+X# hilited --> indicator is inverted
+X#
+Xclass RadioAppearance() = CheckAppearance():
+X #
+X def drawpict(self, d):
+X (left, top), (right, bottom) = self.boxbounds
+X radius = self.size / 2
+X h, v = left + radius, top + radius
+X d.circle((h, v), radius)
+X if self.selected:
+X some = radius/3
+X d.paint((h-some, v-some), (h+some, v+some))
+X #
+X
+X
+X# NoReactivity ignores mouse events.
+X#
+Xclass NoReactivity():
+X def init_reactivity(self): pass
+X
+X
+X# BaseReactivity defines hooks and asks for mouse events,
+X# but provides only dummy mouse event handlers.
+X# The trigger methods call the corresponding hooks set by the user.
+X# Hooks (and triggers) mean the following:
+X# down_hook called on some mouse-down events
+X# move_hook called on some mouse-move events
+X# up_hook called on mouse-up events
+X# on_hook called for buttons with on/off state, when it goes on
+X# hook called when a button 'fires' or a radiobutton goes on
+X# There are usually extra conditions, e.g., hooks are only called
+X# when the button is enabled, or active, or selected (on).
+X#
+Xclass BaseReactivity():
+X #
+X def init_reactivity(self):
+X self.down_hook = self.move_hook = self.up_hook = \
+X self.on_hook = self.off_hook = \
+X self.hook = self.active = 0
+X self.parent.need_mouse(self)
+X #
+X def mousetest(self, hv):
+X return _rect.pointinrect(hv, self.bounds)
+X #
+X def mouse_down(self, detail):
+X pass
+X #
+X def mouse_move(self, detail):
+X pass
+X #
+X def mouse_up(self, detail):
+X pass
+X #
+X def down_trigger(self):
+X if self.down_hook: self.down_hook(self)
+X #
+X def move_trigger(self):
+X if self.move_hook: self.move_hook(self)
+X #
+X def up_trigger(self):
+X if self.up_hook: self.up_hook(self)
+X #
+X def on_trigger(self):
+X if self.on_hook: self.on_hook(self)
+X #
+X def off_trigger(self):
+X if self.off_hook: self.off_hook(self)
+X #
+X def trigger(self):
+X if self.hook: self.hook(self)
+X
+X
+X# ToggleReactivity acts like a simple pushbutton.
+X# It toggles its hilite state on mouse down events.
+X#
+Xclass ToggleReactivity() = BaseReactivity():
+X #
+X def mouse_down(self, detail):
+X if self.enabled and self.mousetest(detail[_HV]):
+X self.active = 1
+X self.hilite(not self.hilited)
+X self.down_trigger()
+X #
+X def mouse_move(self, detail):
+X if self.active:
+X self.move_trigger()
+X #
+X def mouse_up(self, detail):
+X if self.active:
+X self.up_trigger()
+X self.active = 0
+X #
+X def down_trigger(self):
+X if self.hilited:
+X self.on_trigger()
+X else:
+X self.off_trigger()
+X self.trigger()
+X #
+X
+X
+X# TriggerReactivity acts like a fancy pushbutton.
+X# It hilites itself while the mouse is down within its bounds.
+X#
+Xclass TriggerReactivity() = BaseReactivity():
+X #
+X def mouse_down(self, detail):
+X if self.enabled and self.mousetest(detail[_HV]):
+X self.active = 1
+X self.hilite(1)
+X self.down_trigger()
+X #
+X def mouse_move(self, detail):
+X if self.active:
+X self.hilite(self.mousetest(detail[_HV]))
+X if self.hilited:
+X self.move_trigger()
+X #
+X def mouse_up(self, detail):
+X if self.active:
+X self.hilite(self.mousetest(detail[_HV]))
+X if self.hilited:
+X self.up_trigger()
+X self.trigger()
+X self.active = 0
+X self.hilite(0)
+X #
+X
+X
+X# CheckReactivity handles mouse events like TriggerReactivity,
+X# It overrides the up_trigger method to flip its selected state.
+X#
+Xclass CheckReactivity() = TriggerReactivity():
+X #
+X def up_trigger(self):
+X self.select(not self.selected)
+X if self.selected:
+X self.on_trigger()
+X else:
+X self.off_trigger()
+X self.trigger()
+X
+X
+X# RadioReactivity turns itself on and the other buttons in its group
+X# off when its up_trigger method is called.
+X#
+Xclass RadioReactivity() = TriggerReactivity():
+X #
+X def init_reactivity(self):
+X TriggerReactivity.init_reactivity(self)
+X self.group = []
+X #
+X def up_trigger(self):
+X for b in self.group:
+X if b <> self:
+X if b.selected:
+X b.select(0)
+X b.off_trigger()
+X self.select(1)
+X self.on_trigger()
+X self.trigger()
+X
+X
+X# Auxiliary class for 'define' method.
+X# Call the initializers in the right order.
+X#
+Xclass Define():
+X #
+X def define(self, parent):
+X self.parent = parent
+X parent.addchild(self)
+X self.init_appearance()
+X self.init_reactivity()
+X return self
+X #
+X def destroy(self):
+X self.parent = 0
+X #
+X def definetext(self, (parent, text)):
+X self = self.define(parent)
+X self.settext(text)
+X return self
+X
+X
+X# Subroutine to cross out a rectangle.
+X#
+Xdef _xorcross(d, bounds):
+X ((left, top), (right, bottom)) = bounds
+X # This is s bit funny to make it look better
+X left = left + 2
+X right = right - 2
+X top = top + 2
+X bottom = bottom - 3
+X d.xorline(((left, top), (right, bottom)))
+X d.xorline((left, bottom), (right, top))
+X
+X
+X# Ready-made button classes.
+X#
+Xclass Label() = NoReactivity(), LabelAppearance(), Define(): pass
+Xclass PushButton() = TriggerReactivity(), ButtonAppearance(), Define(): pass
+Xclass CheckButton() = CheckReactivity(), CheckAppearance(), Define(): pass
+Xclass RadioButton() = RadioReactivity(), RadioAppearance(), Define(): pass
+Xclass ToggleButton() = ToggleReactivity(), ButtonAppearance(), Define(): pass
+EOF
+fi
+if test -s 'lib/TclUtil.py'
+then echo '*** I will not over-write existing file lib/TclUtil.py'
+else
+echo 'x - lib/TclUtil.py'
+sed 's/^X//' > 'lib/TclUtil.py' << 'EOF'
+X# Utilities used by 'Tcl' emulator.
+X
+X
+X# Many functions in this file parse specific constructs from strings.
+X# In order to limit the number of slice operations (the strings can
+X# be very large), they always receive indices into the string that
+X# indicate the slice of the string that should be considered.
+X# The return value is in general another index, pointing to the first
+X# character in the string beyond the recognized construct.
+X# Errors are reported as exceptions (TclSyntaxError, TclMatchingError).
+X# A few functions have multiple return values.
+X
+X
+X# For efficiency, the Tcl "tokenizing" routines used pre-compiled
+X# regular expressions. This is less readable but should be much faster
+X# than scanning the string a character at a time.
+X#
+X# The global variables
+X# containing the compiled regexp's are named _foo_prog where foo is
+X# an indication of the function that uses them.
+X#
+X# The patterns always
+X# have the form <something>* so they always match at the start of the
+X# search buffer---maybe with the empty string. This makes it possible
+X# to use the expression "_foo_prog.exec(str, i)[0][1]" to find the first
+X# character beyond the matched string. Note that this may be beyond the
+X# end variable -- where this matters, "min(i, end)" is used.
+X
+X# Constructs that cannot
+X# be recognized by a finite automaton (like matching braces) are scanned
+X# by a hybrid technique where the regular expression excludes the
+X# braces.
+X#
+X# Many regular expressions contain an expression that matches
+X# a Tcl backslash sequence as a subpart:
+X# \\\\C?M?(.|\n)
+X#
+X# This is a bit hard to
+X# read because the backslash contained in it must be doubled twice:
+X# once to get past Python's backslash mechanism, once to get past that
+X# of regular expressions. It uses (.|\n) to match absolutely
+X# *every character*, becase the MULTILINE regular expression package does
+X# not accept '\n' as a match for '.'.
+X#
+X# There is also a simplification in the pattern for backslashes:
+X# *any* single character following a backslash is escaped,
+X# so hex and octal
+X# excapes are not scanned fully. The forms \Cx, \Mx and \CMx are
+X# scanned correctly, as these may hide a special character.
+X# (This does not invalidate the recognition of strings, although the
+X# match is effectuated in a different way than by the Backslash function.)
+X
+Ximport regexp
+X
+X
+X# Exceptions raised for various error conditions.
+X
+XTclAssertError = 'Tcl assert error'
+XTclSyntaxError = 'Tcl syntax error'
+XTclRuntimeError = 'Tcl runtime error'
+XTclMatchingError = 'Tcl matching error'
+X
+X
+X# Find a variable name.
+X# A variable name is either a (possiblly empty) sequence of letters,
+X# digits and underscores, or anything enclosed in matching braces.
+X# Return the index past the end of the name.
+X
+X_varname_prog = regexp.compile('[a-zA-Z0-9_]*')
+X
+Xdef FindVarName(str, i, end):
+X if i < end and str[i] = '{': return BalanceBraces(str, i, end)
+X i = _varname_prog.exec(str, i)[0][1]
+X return min(i, end)
+X
+X
+X# Split a list into its elements.
+X# Return a list of elements (strings).
+X
+Xdef SplitList(str):
+X i, end = 0, len(str)
+X list = []
+X while 1:
+X i = SkipSpaces(str, i, end)
+X if i >= end: break
+X j = i
+X i = FindNextElement(str, i, end)
+X if str[j] = '{' and str[i-1] = '}':
+X element = str[j+1:i-1]
+X else:
+X element = Collapse(str[j:i])
+X list.append(element)
+X return list
+X
+X
+X# Find the next element from a list.
+X
+X_element_prog = regexp.compile('([^ \t\n\\]+|\\\\C?M?(.|\n))*')
+X
+Xdef FindNextElement(str, i, end):
+X if i < end and str[i] = '{':
+X i = BalanceBraces(str, i, end)
+X if i < end and str[i] not in ' \t\n':
+X raise TclSyntaxError, 'Garbage after } in list'
+X return i
+X i = _element_prog.exec(str, i)[0][1]
+X return min(i, end)
+X
+X
+X# Copy a string, expanding all backslash sequences.
+X
+X_collapse_prog = regexp.compile('(\n|[^\\]+)*')
+X
+Xdef Collapse(str):
+X if '\\' not in str: return str
+X i, end = 0, len(str)
+X result = ''
+X while i < end:
+X j = _collapse_prog.exec(str, i)[0][1]
+X j = min(j, end)
+X result = result + str[i:j]
+X if j >= end: break
+X c = str[j]
+X if c <> '\\': raise TclAssertError, 'collapse error'
+X x, i = Backslash(str, j, end)
+X result = result + x
+X return result
+X
+X
+X# Find the next full command.
+X# Return a list of begin, end indices of words in the string,
+X# and an index pointing just after the terminating newline or
+X# semicolon.
+X# Initial spaces are skipped.
+X# If the command begins with '#', it is considered empty and
+X# characters until '\n' are skipped.
+X
+X_eol_prog = regexp.compile('[^\n]*')
+X
+Xdef FindNextCommand(str, i, end, bracketed):
+X i = SkipSpaces(str, i, end)
+X if i >= end: return [], end
+X if str[i] = '#':
+X i = _eol_prog.exec(str, i)
+X i = min(i, end)
+X if i < end and str[i] = '\n': i = i+1
+X return [], i
+X if bracketed: terminators = [';']
+X else: terminators = [';', '\n']
+X list = []
+X while i < end:
+X j = FindNextWord(str, i, end)
+X word = str[i:j]
+X if word in terminators:
+X i = j
+X break
+X if word <> '\n': list.append(i, j)
+X i = SkipSpaces(str, j, end)
+X return list, i
+X
+X
+X# Find the next word of a command.
+X# Semicolon and newline terminate words but also count as a word
+X# themselves.
+X# The start index must point to the start of the word.
+X
+X_word_prog = regexp.compile('([^ \t\n;[\\]+|\\\\C?M?(.|\n))*')
+X
+Xdef FindNextWord(str, i, end):
+X if i >= end: return end
+X if str[i] in '{"':
+X if str[i] = '{': i = BalanceBraces(str, i, end)
+X else: i = BalanceQuotes(str, i, end)
+X if i >= end or str[i] in ' \t\n;': return min(i, end)
+X raise TclSyntaxError, 'Garbage after } or "'
+X begin = i
+X while i < end:
+X i = _word_prog.exec(str, i)[0][1]
+X if i >= end:
+X i = end
+X break
+X c = str[i]
+X if c in ' \t': break
+X if c in ';\n':
+X if i = begin: i = i+1
+X break
+X if c = '[': i = BalanceBrackets(str, i, end)
+X else: raise TclAssertError, 'word error'
+X return i
+X
+X
+X# Parse balanced brackets from str[i:end].
+X# str[i] must be '['.
+X# Returns end such that str[i:end] ends with ']'
+X# and contains balanced braces and brackets.
+X
+X_brackets_prog = regexp.compile('([^][{\\]+|\n|\\\\C?M?(.|\n))*')
+X
+Xdef BalanceBrackets(str, i, end):
+X if i >= end or str[i] <> '[':
+X raise TclAssertError, 'BalanceBrackets'
+X nesting = 0
+X while i < end:
+X i = _brackets_prog.exec(str, i)[0][1]
+X if i >= end: break
+X c = str[i]
+X if c = '{': i = BalanceBraces(str, i, end)
+X else:
+X i = i+1
+X if c = '[': nesting = nesting + 1
+X elif c = ']':
+X nesting = nesting - 1
+X if nesting = 0: return i
+X else: raise TclAssertError, 'brackets error'
+X raise TclMatchingError, 'Unmatched bracket ([)'
+X
+X
+X# Parse balanced braces from str[i:end].
+X# str[i] must be '{'.
+X# Returns end such that str[i:end] ends with '}'
+X# and contains balanced braces.
+X
+X_braces_prog = regexp.compile('([^{}\\]+|\n|\\\\C?M?(.|\n))*')
+X
+Xdef BalanceBraces(str, i, end):
+X if i >= end or str[i] <> '{':
+X raise TclAssertError, 'BalanceBraces'
+X nesting = 0
+X while i < end:
+X i = _braces_prog.exec(str, i)[0][1]
+X if i >= end: break
+X c = str[i]
+X i = i+1
+X if c = '{': nesting = nesting + 1
+X elif c = '}':
+X nesting = nesting - 1
+X if nesting = 0: return i
+X else: raise TclAssertError, 'braces error'
+X raise TclMatchingError, 'Unmatched brace ({)'
+X
+X
+X# Parse double quotes from str[i:end].
+X# str[i] must be '"'.
+X# Returns end such that str[i:end] ends with an unescaped '"'.
+X
+X_quotes_prog = regexp.compile('([^"\\]+|\n|\\\\C?M?(.|\n))*')
+X
+Xdef BalanceQuotes(str, i, end):
+X if i >= end or str[i] <> '"':
+X raise TclAssertError, 'BalanceQuotes'
+X i = _quotes_prog.exec(str, i+1)[0][1]
+X if i < end and str[i] = '"': return i+1
+X raise TclMatchingError, 'Unmatched quote (")'
+X
+X
+X# Static data used by Backslash()
+X
+X_bstab = {}
+X_bstab['n'] = '\n'
+X_bstab['r'] = '\r'
+X_bstab['t'] = '\t'
+X_bstab['b'] = '\b'
+X_bstab['e'] = '\033'
+X_bstab['\n'] = ''
+Xfor c in ' {}[]$";\\': _bstab[c] = c
+Xdel c
+X
+X# Backslash interpretation.
+X# First character must be a backslash.
+X# Return a pair (<replacement string>, <end of sequence>).
+X# Unrecognized or incomplete backslash sequences are not errors;
+X# this takes only the backslash itself off the string.
+X
+Xdef Backslash(str, i, end):
+X if i >= end or str[i] <> '\\':
+X raise TclAssertError, 'Backslash'
+X i = i+1
+X if i = end: return '\\', i
+X c = str[i]
+X i = i+1
+X if _bstab.has_key(c): return _bstab[c], i
+X if c = 'C':
+X if i = end: return '\\', i-1
+X c = str[i]
+X i = i+1
+X if c = 'M':
+X if i = end: return '\\', i-2
+X c = str[i]
+X i = i+1
+X x = ord(c) % 040 + 0200
+X else:
+X x = ord(c) % 040
+X return chr(x), i
+X elif c = 'M':
+X if i = end: return '\\', i-1
+X c = str[i]
+X i = i+1
+X x = ord(c)
+X if x < 0200: x = x + 0200
+X return chr(x), i
+X elif c and c in '0123456789':
+X x = ord(c) - ord('0')
+X end = min(end, i+2)
+X while i < end:
+X c = str[i]
+X if c not in '0123456789': break
+X i = i+1
+X x = x*8 + ord(c) - ord('0')
+X return ord(x), i
+X else:
+X # Not something that we recognize
+X return '\\', i-1
+X
+X
+X# Skip over spaces and tabs (but not newlines).
+X
+X_spaces_prog = regexp.compile('[ \t]*')
+X
+Xdef SkipSpaces(str, i, end):
+X i = _spaces_prog.exec(str, i)[0][1]
+X return min(i, end)
+X
+X
+X# Concatenate the elements of a list with intervening spaces.
+X
+Xdef Concat(argv):
+X result = ''
+X sep = ''
+X for arg in argv:
+X result = result + (sep + arg)
+X sep = ' '
+X return result
+X
+X
+X# Concatenate list elements, adding braces etc. to make them parseable
+X# again with SplitList.
+X
+Xdef BuildList(argv):
+X result = ''
+X sep = ''
+X for arg in argv:
+X arg = AddBraces(arg)
+X result = result + (sep + arg)
+X sep = ' '
+X return result
+X
+X
+X# Add braces around a string if necessary to make it parseable by SplitList.
+X
+Xdef AddBraces(str):
+X # Special case for empty string
+X if str = '': return '{}'
+X # See if it contains balanced braces
+X res = '{' + str + '}'
+X if TryNextElement(res):
+X # See if it would survive unquoted
+X # XXX should escape [] and $ as well???
+X if TryNextElement(str) and Collapse(str) = str: return str
+X # No -- return with added braces
+X return res
+X # Unbalanced braces. Add backslashes before suspect characters
+X res = ''
+X for c in str:
+X if c in '$\\[]{} ;': c = '\\' + c
+X elif c = '\n': c = '\\n'
+X elif c = '\t': c = '\\t'
+X res = res + c
+X return res
+X
+X
+Xdef TryNextElement(str):
+X end = len(str)
+X try:
+X i = FindNextElement(str, 0, end)
+X return i = end
+X except (TclSyntaxError, TclMatchingError):
+X return 0
+EOF
+fi
+if test -s 'lib/testall.py'
+then echo '*** I will not over-write existing file lib/testall.py'
+else
+echo 'x - lib/testall.py'
+sed 's/^X//' > 'lib/testall.py' << 'EOF'
+X# Module 'testall'
+X#
+X# Python test set, should exercise:
+X# - all lexical and grammatical constructs
+X# - all opcodes from "opcode.h"
+X# - all operations on all object types
+X# - all builtin functions
+X# Ideally also:
+X# - all possible exception situations (Thank God we've got 'try')
+X# - all boundary cases
+X
+X
+XTestFailed = 'testall -- test failed' # Exception
+X
+X
+X#########################################################
+X# Part 1. Test all lexical and grammatical constructs.
+X# This just tests whether the parser accepts them all.
+X#########################################################
+X
+Xprint '1. Parser'
+X
+Xprint '1.1 Tokens'
+X
+Xprint '1.1.1 Backslashes'
+X
+X# Backslash means line continuation:
+Xx = 1 \
+X+ 1
+Xif x <> 2: raise TestFailed, 'backslash for line continuation'
+X
+X# Backslash does not means continuation in comments :\
+Xx = 0
+Xif x <> 0: raise TestFailed, 'backslash ending comment'
+X
+Xprint '1.1.2 Number formats'
+X
+Xif 0xff <> 255: raise TestFailed, 'hex number'
+Xif 0377 <> 255: raise TestFailed, 'octal number'
+Xx = 3.14
+Xx = 0.314
+Xx = 3e14
+Xx = 3E14
+Xx = 3e-14
+X
+Xprint '1.2 Grammar'
+X
+Xprint 'single_input' # NEWLINE | simple_stmt | compound_stmt NEWLINE
+X# XXX can't test in a script -- this rule is only used when interactive
+X
+Xprint 'file_input' # (NEWLINE | stmt)* ENDMARKER
+X# Being tested as this very moment this very module
+X
+Xprint 'expr_input' # testlist NEWLINE
+X# XXX Hard to test -- used only in calls to input()
+X
+Xprint 'eval_input' # testlist ENDMARKER
+Xx = eval('1, 0 or 1')
+X
+Xprint 'funcdef' # 'def' NAME parameters ':' suite
+X### parameters: '(' [fplist] ')'
+X### fplist: fpdef (',' fpdef)*
+X### fpdef: NAME | '(' fplist ')'
+Xdef f1(): pass
+Xdef f2(one_argument): pass
+Xdef f3(two, arguments): pass
+Xdef f4(two, (compound, (arguments))): pass
+X
+X### stmt: simple_stmt | compound_stmt
+X### simple_stmt: expr_stmt | print_stmt | pass_stmt | del_stmt | flow_stmt | import_stmt
+X# Tested below
+X
+Xprint 'expr_stmt' # (exprlist '=')* exprlist NEWLINE
+X1
+X1, 2, 3
+Xx = 1
+Xx = 1, 2, 3
+Xx = y = z = 1, 2, 3
+Xx, y, z = 1, 2, 3
+Xabc = a, b, c = x, y, z = xyz = 1, 2, (3, 4)
+X# NB these variables are deleted below
+X
+Xprint 'print_stmt' # 'print' (test ',')* [test] NEWLINE
+Xprint 1, 2, 3
+Xprint 1, 2, 3,
+Xprint
+Xprint 0 or 1, 0 or 1,
+Xprint 0 or 1
+X
+Xprint 'del_stmt' # 'del' exprlist NEWLINE
+Xdel abc
+Xdel x, y, (z, xyz)
+X
+Xprint 'pass_stmt' # 'pass' NEWLINE
+Xpass
+X
+Xprint 'flow_stmt' # break_stmt | return_stmt | raise_stmt
+X# Tested below
+X
+Xprint 'break_stmt' # 'break' NEWLINE
+Xwhile 1: break
+X
+Xprint 'return_stmt' # 'return' [testlist] NEWLINE
+Xdef g1(): return
+Xdef g2(): return 1
+Xg1()
+Xx = g2()
+X
+Xprint 'raise_stmt' # 'raise' expr [',' expr] NEWLINE
+Xtry: raise RuntimeError, 'just testing'
+Xexcept RuntimeError: pass
+Xtry: raise KeyboardInterrupt
+Xexcept KeyboardInterrupt: pass
+X
+Xprint 'import_stmt' # 'import' NAME (',' NAME)* NEWLINE | 'from' NAME 'import' ('*' | NAME (',' NAME)*) NEWLINE
+X[1]
+Ximport sys
+X[2]
+Ximport time, math
+X[3]
+Xfrom time import sleep
+X[4]
+Xfrom math import *
+X[5]
+Xfrom sys import modules, ps1, ps2
+X[6]
+X
+X### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
+X# Tested below
+X
+Xprint 'if_stmt' # 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
+Xif 1: pass
+Xif 1: pass
+Xelse: pass
+Xif 0: pass
+Xelif 0: pass
+Xif 0: pass
+Xelif 0: pass
+Xelif 0: pass
+Xelif 0: pass
+Xelse: pass
+X
+Xprint 'while_stmt' # 'while' test ':' suite ['else' ':' suite]
+Xwhile 0: pass
+Xwhile 0: pass
+Xelse: pass
+X
+Xprint 'for_stmt' # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite]
+X[1]
+Xfor i in 1, 2, 3: pass
+X[2]
+Xfor i, j, k in (): pass
+Xelse: pass
+X[3]
+X
+Xprint 'try_stmt' # 'try' ':' suite (except_clause ':' suite)* ['finally' ':' suite]
+X### except_clause: 'except' [expr [',' expr]]
+Xtry: pass
+Xtry: 1/0
+Xexcept RuntimeError: pass
+Xtry: 1/0
+Xexcept EOFError: pass
+Xexcept TypeError, msg: pass
+Xexcept RuntimeError, msg: pass
+Xexcept: pass
+Xtry: pass
+Xfinally: pass
+Xtry: 1/0
+Xexcept: pass
+Xfinally: pass
+X
+Xprint 'suite' # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT
+Xif 1: pass
+Xif 1:
+X pass
+Xif 1:
+X #
+X #
+X #
+X pass
+X pass
+X #
+X pass
+X #
+X
+Xprint 'test' # and_test ('or' and_test)*
+X### and_test: not_test ('and' not_test)*
+X### not_test: 'not' not_test | comparison
+X### comparison: expr (comp_op expr)*
+X### comp_op: '<'|'>'|'='|'>' '='|'<' '='|'<' '>'|'in'|'not' 'in'|'is'|'is' 'not'
+Xif 1: pass
+Xif 1 = 1: pass
+Xif 1 < 1 > 1 = 1 >= 1 <= 1 <> 1 in 1 not in 1 is 1 is not 1: pass
+Xif not 1 = 1 = 1: pass
+Xif not 1 = 1 and 1 and 1: pass
+Xif 1 and 1 or 1 and 1 and 1 or not 1 = 1 = 1 and 1: pass
+X
+Xprint 'expr' # term (('+'|'-') term)*
+Xx = 1
+Xx = 1 + 1
+Xx = 1 - 1 - 1
+Xx = 1 - 1 + 1 - 1 + 1
+X
+Xprint 'term' # factor (('*'|'/'|'%') factor)*
+Xx = 1 * 1
+Xx = 1 / 1
+Xx = 1 % 1
+Xx = 1 / 1 * 1 % 1
+X
+Xprint 'factor' # ('+'|'-') factor | atom trailer*
+X### trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME
+X### subscript: expr | [expr] ':' [expr]
+Xx = +1
+Xx = -1
+Xx = 1
+Xc = sys.ps1[0]
+Xx = time.time()
+Xx = sys.modules['time'].time()
+Xa = '01234'
+Xc = a[0]
+Xc = a[0:5]
+Xc = a[:5]
+Xc = a[0:]
+Xc = a[:]
+Xc = a[-5:]
+Xc = a[:-1]
+Xc = a[-4:-3]
+X
+Xprint 'atom' # '(' [testlist] ')' | '[' [testlist] ']' | '{' '}' | '`' testlist '`' | NAME | NUMBER | STRING
+Xx = (1)
+Xx = (1 or 2 or 3)
+Xx = (1 or 2 or 3, 2, 3)
+Xx = []
+Xx = [1]
+Xx = [1 or 2 or 3]
+Xx = [1 or 2 or 3, 2, 3]
+Xx = []
+Xx = {}
+Xx = `x`
+Xx = x
+Xx = 'x'
+Xx = 123
+X
+X### exprlist: expr (',' expr)* [',']
+X### testlist: test (',' test)* [',']
+X# These have been exercised enough above
+X
+Xprint 'classdef' # 'class' NAME parameters ['=' baselist] ':' suite
+X### baselist: atom arguments (',' atom arguments)*
+X### arguments: '(' [testlist] ')'
+Xclass B(): pass
+Xclass C1() = B(): pass
+Xclass C2() = B(): pass
+Xclass D() = C1(), C2(), B(): pass
+Xclass C():
+X def meth1(self): pass
+X def meth2(self, arg): pass
+X def meth3(self, (a1, a2)): pass
+X
+X
+X#########################################################
+X# Part 2. Test all opcodes from "opcode.h"
+X#########################################################
+X
+Xprint '2. Opcodes'
+Xprint 'XXX Not yet fully implemented'
+X
+Xprint '2.1 try inside for loop'
+Xn = 0
+Xfor i in range(10):
+X n = n+i
+X try: 1/0
+X except NameError: pass
+X except RuntimeError: pass
+X except TypeError: pass
+X finally: pass
+X try: pass
+X except: pass
+X try: pass
+X finally: pass
+X n = n+i
+Xif n <> 90:
+X raise TestFailed, 'try inside for'
+X
+X
+X#########################################################
+X# Part 3. Test all operations on all object types
+X#########################################################
+X
+Xprint '3. Object types'
+Xprint 'XXX Not yet implemented'
+X
+X
+X#########################################################
+X# Part 4. Test all built-in functions
+X#########################################################
+X
+Xprint '4. Built-in functions'
+X
+Xprint 'abs'
+Xif abs(0) <> 0: raise TestFailed, 'abs(0)'
+Xif abs(1234) <> 1234: raise TestFailed, 'abs(1234)'
+Xif abs(-1234) <> 1234: raise TestFailed, 'abs(-1234)'
+Xif abs(0.0) <> 0.0: raise TestFailed, 'abs(0.0)'
+Xif abs(3.14) <> 3.14: raise TestFailed, 'abs(3.14)'
+Xif abs(-3.14) <> 3.14: raise TestFailed, 'abs(-3.14)'
+X
+Xprint 'dir'
+Xif 'x' not in dir(): raise TestFailed, 'dir()'
+Xif 'modules' not in dir(sys): raise TestFailed, 'dir(sys)'
+X
+Xprint 'divmod'
+Xif divmod(12, 7) <> (1, 5): raise TestFailed, 'divmod(12, 7)'
+Xif divmod(-12, 7) <> (-2, 2): raise TestFailed, 'divmod(-12, 7)'
+Xif divmod(12, -7) <> (-2, -2): raise TestFailed, 'divmod(12, -7)'
+Xif divmod(-12, -7) <> (1, -5): raise TestFailed, 'divmod(-12, -7)'
+X
+Xprint 'eval'
+Xif eval('1+1') <> 2: raise TestFailed, 'eval(\'1+1\')'
+X
+Xprint 'exec'
+Xexec('z=1+1\n')
+Xif z <> 2: raise TestFailed, 'exec(\'z=1+1\'\\n)'
+X
+Xprint 'float'
+Xif float(3.14) <> 3.14: raise TestFailed, 'float(3.14)'
+Xif float(314) <> 314.0: raise TestFailed, 'float(314)'
+X
+Xprint 'input'
+X# Can't test in a script
+X
+Xprint 'int'
+Xif int(100) <> 100: raise TestFailed, 'int(100)'
+Xif int(3.14) <> 3: raise TestFailed, 'int(3.14)'
+X
+Xprint 'len'
+Xif len('123') <> 3: raise TestFailed, 'len(\'123\')'
+Xif len(()) <> 0: raise TestFailed, 'len(())'
+Xif len((1, 2, 3, 4)) <> 4: raise TestFailed, 'len((1, 2, 3, 4))'
+Xif len([1, 2, 3, 4]) <> 4: raise TestFailed, 'len([1, 2, 3, 4])'
+Xif len({}) <> 0: raise TestFailed, 'len({})'
+X
+Xprint 'min'
+Xif min('123123') <> '1': raise TestFailed, 'min(\'123123\')'
+Xif min(1, 2, 3) <> 1: raise TestFailed, 'min(1, 2, 3)'
+Xif min((1, 2, 3, 1, 2, 3)) <> 1: raise TestFailed, 'min((1, 2, 3, 1, 2, 3))'
+Xif min([1, 2, 3, 1, 2, 3]) <> 1: raise TestFailed, 'min([1, 2, 3, 1, 2, 3])'
+X
+Xprint 'max'
+Xif max('123123') <> '3': raise TestFailed, 'max(\'123123\')'
+Xif max(1, 2, 3) <> 3: raise TestFailed, 'max(1, 2, 3)'
+Xif max((1, 2, 3, 1, 2, 3)) <> 3: raise TestFailed, 'max((1, 2, 3, 1, 2, 3))'
+Xif max([1, 2, 3, 1, 2, 3]) <> 3: raise TestFailed, 'max([1, 2, 3, 1, 2, 3])'
+X
+Xprint 'open'
+Xprint 'NB! This test creates a file named "@test" in the current directory.'
+Xfp = open('@test', 'w')
+Xfp.write('The quick brown fox jumps over the lazy dog')
+Xfp.write('.\n')
+Xfp.write('Dear John\n')
+Xfp.write('XXX'*100)
+Xfp.write('YYY'*100)
+Xfp.close()
+Xdel fp
+Xfp = open('@test', 'r')
+Xif fp.readline() <> 'The quick brown fox jumps over the lazy dog.\n':
+X raise TestFailed, 'readline()'
+Xif fp.readline(4) <> 'Dear': raise TestFailed, 'readline(4) # short'
+Xif fp.readline(100) <> ' John\n': raise TestFailed, 'readline(100)'
+Xif fp.read(300) <> 'XXX'*100: raise TestFailed, 'read(300)'
+Xif fp.read(1000) <> 'YYY'*100: raise TestFailed, 'read(1000) # truncate'
+Xfp.close()
+Xdel fp
+X
+Xprint 'range'
+Xif range(3) <> [0, 1, 2]: raise TestFailed, 'range(3)'
+Xif range(1, 5) <> [1, 2, 3, 4]: raise TestFailed, 'range(1, 5)'
+Xif range(0) <> []: raise TestFailed, 'range(0)'
+Xif range(-3) <> []: raise TestFailed, 'range(-3)'
+Xif range(1, 10, 3) <> [1, 4, 7]: raise TestFailed, 'range(1, 10, 3)'
+Xif range(5, -5, -3) <> [5, 2, -1, -4]: raise TestFailed, 'range(5, -5, -3)'
+X
+Xprint 'raw_input'
+Xsavestdin = sys.stdin
+Xtry:
+X sys.stdin = open('@test', 'r')
+X if raw_input() <> 'The quick brown fox jumps over the lazy dog.':
+X raise TestFailed, 'raw_input()'
+X if raw_input('testing\n') <> 'Dear John':
+X raise TestFailed, 'raw_input(\'testing\\n\')'
+Xfinally:
+X sys.stdin = savestdin
+X
+Xprint 'reload'
+Ximport string
+Xreload(string)
+X
+Xprint 'type'
+Xif type('') <> type('123') or type('') = type(()):
+X raise TestFailed, 'type()'
+X
+X
+Xprint 'Passed all tests.'
+X
+Xtry:
+X import mac
+X unlink = mac.unlink
+Xexcept NameError:
+X try:
+X import posix
+X unlink = posix.unlink
+X except NameError:
+X pass
+X
+Xunlink('@test')
+Xprint 'Unlinked @test'
+EOF
+fi
+if test -s 'src/listobject.c'
+then echo '*** I will not over-write existing file src/listobject.c'
+else
+echo 'x - src/listobject.c'
+sed 's/^X//' > 'src/listobject.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/* List object implementation */
+X
+X#include "allobjects.h"
+X
+Xobject *
+Xnewlistobject(size)
+X int size;
+X{
+X int i;
+X listobject *op;
+X if (size < 0) {
+X err_badcall();
+X return NULL;
+X }
+X op = (listobject *) malloc(sizeof(listobject));
+X if (op == NULL) {
+X return err_nomem();
+X }
+X if (size <= 0) {
+X op->ob_item = NULL;
+X }
+X else {
+X op->ob_item = (object **) malloc(size * sizeof(object *));
+X if (op->ob_item == NULL) {
+X free((ANY *)op);
+X return err_nomem();
+X }
+X }
+X NEWREF(op);
+X op->ob_type = &Listtype;
+X op->ob_size = size;
+X for (i = 0; i < size; i++)
+X op->ob_item[i] = NULL;
+X return (object *) op;
+X}
+X
+Xint
+Xgetlistsize(op)
+X object *op;
+X{
+X if (!is_listobject(op)) {
+X err_badcall();
+X return -1;
+X }
+X else
+X return ((listobject *)op) -> ob_size;
+X}
+X
+Xobject *
+Xgetlistitem(op, i)
+X object *op;
+X int i;
+X{
+X if (!is_listobject(op)) {
+X err_badcall();
+X return NULL;
+X }
+X if (i < 0 || i >= ((listobject *)op) -> ob_size) {
+X err_setstr(IndexError, "list index out of range");
+X return NULL;
+X }
+X return ((listobject *)op) -> ob_item[i];
+X}
+X
+Xint
+Xsetlistitem(op, i, newitem)
+X register object *op;
+X register int i;
+X register object *newitem;
+X{
+X register object *olditem;
+X if (!is_listobject(op)) {
+X if (newitem != NULL)
+X DECREF(newitem);
+X err_badcall();
+X return -1;
+X }
+X if (i < 0 || i >= ((listobject *)op) -> ob_size) {
+X if (newitem != NULL)
+X DECREF(newitem);
+X err_setstr(IndexError, "list assignment index out of range");
+X return -1;
+X }
+X olditem = ((listobject *)op) -> ob_item[i];
+X ((listobject *)op) -> ob_item[i] = newitem;
+X if (olditem != NULL)
+X DECREF(olditem);
+X return 0;
+X}
+X
+Xstatic int
+Xins1(self, where, v)
+X listobject *self;
+X int where;
+X object *v;
+X{
+X int i;
+X object **items;
+X if (v == NULL) {
+X err_badcall();
+X return -1;
+X }
+X items = self->ob_item;
+X RESIZE(items, object *, self->ob_size+1);
+X if (items == NULL) {
+X err_nomem();
+X return -1;
+X }
+X if (where < 0)
+X where = 0;
+X if (where > self->ob_size)
+X where = self->ob_size;
+X for (i = self->ob_size; --i >= where; )
+X items[i+1] = items[i];
+X INCREF(v);
+X items[where] = v;
+X self->ob_item = items;
+X self->ob_size++;
+X return 0;
+X}
+X
+Xint
+Xinslistitem(op, where, newitem)
+X object *op;
+X int where;
+X object *newitem;
+X{
+X if (!is_listobject(op)) {
+X err_badcall();
+X return -1;
+X }
+X return ins1((listobject *)op, where, newitem);
+X}
+X
+Xint
+Xaddlistitem(op, newitem)
+X object *op;
+X object *newitem;
+X{
+X if (!is_listobject(op)) {
+X err_badcall();
+X return -1;
+X }
+X return ins1((listobject *)op,
+X (int) ((listobject *)op)->ob_size, newitem);
+X}
+X
+X/* Methods */
+X
+Xstatic void
+Xlist_dealloc(op)
+X listobject *op;
+X{
+X int i;
+X for (i = 0; i < op->ob_size; i++) {
+X if (op->ob_item[i] != NULL)
+X DECREF(op->ob_item[i]);
+X }
+X if (op->ob_item != NULL)
+X free((ANY *)op->ob_item);
+X free((ANY *)op);
+X}
+X
+Xstatic void
+Xlist_print(op, fp, flags)
+X listobject *op;
+X FILE *fp;
+X int flags;
+X{
+X int i;
+X fprintf(fp, "[");
+X for (i = 0; i < op->ob_size && !StopPrint; i++) {
+X if (i > 0) {
+X fprintf(fp, ", ");
+X }
+X printobject(op->ob_item[i], fp, flags);
+X }
+X fprintf(fp, "]");
+X}
+X
+Xobject *
+Xlist_repr(v)
+X listobject *v;
+X{
+X object *s, *t, *comma;
+X int i;
+X s = newstringobject("[");
+X comma = newstringobject(", ");
+X for (i = 0; i < v->ob_size && s != NULL; i++) {
+X if (i > 0)
+X joinstring(&s, comma);
+X t = reprobject(v->ob_item[i]);
+X joinstring(&s, t);
+X DECREF(t);
+X }
+X DECREF(comma);
+X t = newstringobject("]");
+X joinstring(&s, t);
+X DECREF(t);
+X return s;
+X}
+X
+Xstatic int
+Xlist_compare(v, w)
+X listobject *v, *w;
+X{
+X int len = (v->ob_size < w->ob_size) ? v->ob_size : w->ob_size;
+X int i;
+X for (i = 0; i < len; i++) {
+X int cmp = cmpobject(v->ob_item[i], w->ob_item[i]);
+X if (cmp != 0)
+X return cmp;
+X }
+X return v->ob_size - w->ob_size;
+X}
+X
+Xstatic int
+Xlist_length(a)
+X listobject *a;
+X{
+X return a->ob_size;
+X}
+X
+Xstatic object *
+Xlist_item(a, i)
+X listobject *a;
+X int i;
+X{
+X if (i < 0 || i >= a->ob_size) {
+X err_setstr(IndexError, "list index out of range");
+X return NULL;
+X }
+X INCREF(a->ob_item[i]);
+X return a->ob_item[i];
+X}
+X
+Xstatic object *
+Xlist_slice(a, ilow, ihigh)
+X listobject *a;
+X int ilow, ihigh;
+X{
+X listobject *np;
+X int i;
+X if (ilow < 0)
+X ilow = 0;
+X else if (ilow > a->ob_size)
+X ilow = a->ob_size;
+X if (ihigh < 0)
+X ihigh = 0;
+X if (ihigh < ilow)
+X ihigh = ilow;
+X else if (ihigh > a->ob_size)
+X ihigh = a->ob_size;
+X np = (listobject *) newlistobject(ihigh - ilow);
+X if (np == NULL)
+X return NULL;
+X for (i = ilow; i < ihigh; i++) {
+X object *v = a->ob_item[i];
+X INCREF(v);
+X np->ob_item[i - ilow] = v;
+X }
+X return (object *)np;
+X}
+X
+Xstatic object *
+Xlist_concat(a, bb)
+X listobject *a;
+X object *bb;
+X{
+X int size;
+X int i;
+X listobject *np;
+X if (!is_listobject(bb)) {
+X err_badarg();
+X return NULL;
+X }
+X#define b ((listobject *)bb)
+X size = a->ob_size + b->ob_size;
+X np = (listobject *) newlistobject(size);
+X if (np == NULL) {
+X return err_nomem();
+X }
+X for (i = 0; i < a->ob_size; i++) {
+X object *v = a->ob_item[i];
+X INCREF(v);
+X np->ob_item[i] = v;
+X }
+X for (i = 0; i < b->ob_size; i++) {
+X object *v = b->ob_item[i];
+X INCREF(v);
+X np->ob_item[i + a->ob_size] = v;
+X }
+X return (object *)np;
+X#undef b
+X}
+X
+Xstatic int
+Xlist_ass_item(a, i, v)
+X listobject *a;
+X int i;
+X object *v;
+X{
+X if (i < 0 || i >= a->ob_size) {
+X err_setstr(IndexError, "list assignment index out of range");
+X return -1;
+X }
+X if (v == NULL)
+X return list_ass_slice(a, i, i+1, v);
+X INCREF(v);
+X DECREF(a->ob_item[i]);
+X a->ob_item[i] = v;
+X return 0;
+X}
+X
+Xstatic int
+Xlist_ass_slice(a, ilow, ihigh, v)
+X listobject *a;
+X int ilow, ihigh;
+X object *v;
+X{
+X object **item;
+X int n; /* Size of replacement list */
+X int d; /* Change in size */
+X int k; /* Loop index */
+X#define b ((listobject *)v)
+X if (v == NULL)
+X n = 0;
+X else if (is_listobject(v))
+X n = b->ob_size;
+X else {
+X err_badarg();
+X return -1;
+X }
+X if (ilow < 0)
+X ilow = 0;
+X else if (ilow > a->ob_size)
+X ilow = a->ob_size;
+X if (ihigh < 0)
+X ihigh = 0;
+X if (ihigh < ilow)
+X ihigh = ilow;
+X else if (ihigh > a->ob_size)
+X ihigh = a->ob_size;
+X item = a->ob_item;
+X d = n - (ihigh-ilow);
+X if (d <= 0) { /* Delete -d items; DECREF ihigh-ilow items */
+X for (k = ilow; k < ihigh; k++)
+X DECREF(item[k]);
+X if (d < 0) {
+X for (/*k = ihigh*/; k < a->ob_size; k++)
+X item[k+d] = item[k];
+X a->ob_size += d;
+X RESIZE(item, object *, a->ob_size); /* Can't fail */
+X a->ob_item = item;
+X }
+X }
+X else { /* Insert d items; DECREF ihigh-ilow items */
+X RESIZE(item, object *, a->ob_size + d);
+X if (item == NULL) {
+X err_nomem();
+X return -1;
+X }
+X for (k = a->ob_size; --k >= ihigh; )
+X item[k+d] = item[k];
+X for (/*k = ihigh-1*/; k >= ilow; --k)
+X DECREF(item[k]);
+X a->ob_item = item;
+X a->ob_size += d;
+X }
+X for (k = 0; k < n; k++, ilow++) {
+X object *w = b->ob_item[k];
+X INCREF(w);
+X item[ilow] = w;
+X }
+X return 0;
+X#undef b
+X}
+X
+Xstatic object *
+Xins(self, where, v)
+X listobject *self;
+X int where;
+X object *v;
+X{
+X if (ins1(self, where, v) != 0)
+X return NULL;
+X INCREF(None);
+X return None;
+X}
+X
+Xstatic object *
+Xlistinsert(self, args)
+X listobject *self;
+X object *args;
+X{
+X int i;
+X if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2) {
+X err_badarg();
+X return NULL;
+X }
+X if (!getintarg(gettupleitem(args, 0), &i))
+X return NULL;
+X return ins(self, i, gettupleitem(args, 1));
+X}
+X
+Xstatic object *
+Xlistappend(self, args)
+X listobject *self;
+X object *args;
+X{
+X return ins(self, (int) self->ob_size, args);
+X}
+X
+Xstatic int
+Xcmp(v, w)
+X char *v, *w;
+X{
+X return cmpobject(* (object **) v, * (object **) w);
+X}
+X
+Xstatic object *
+Xlistsort(self, args)
+X listobject *self;
+X object *args;
+X{
+X if (args != NULL) {
+X err_badarg();
+X return NULL;
+X }
+X err_clear();
+X if (self->ob_size > 1)
+X qsort((char *)self->ob_item,
+X (int) self->ob_size, sizeof(object *), cmp);
+X if (err_occurred())
+X return NULL;
+X INCREF(None);
+X return None;
+X}
+X
+Xint
+Xsortlist(v)
+X object *v;
+X{
+X if (v == NULL || !is_listobject(v)) {
+X err_badcall();
+X return -1;
+X }
+X v = listsort((listobject *)v, (object *)NULL);
+X if (v == NULL)
+X return -1;
+X DECREF(v);
+X return 0;
+X}
+X
+Xstatic struct methodlist list_methods[] = {
+X {"append", listappend},
+X {"insert", listinsert},
+X {"sort", listsort},
+X {NULL, NULL} /* sentinel */
+X};
+X
+Xstatic object *
+Xlist_getattr(f, name)
+X listobject *f;
+X char *name;
+X{
+X return findmethod(list_methods, (object *)f, name);
+X}
+X
+Xstatic sequence_methods list_as_sequence = {
+X list_length, /*sq_length*/
+X list_concat, /*sq_concat*/
+X 0, /*sq_repeat*/
+X list_item, /*sq_item*/
+X list_slice, /*sq_slice*/
+X list_ass_item, /*sq_ass_item*/
+X list_ass_slice, /*sq_ass_slice*/
+X};
+X
+Xtypeobject Listtype = {
+X OB_HEAD_INIT(&Typetype)
+X 0,
+X "list",
+X sizeof(listobject),
+X 0,
+X list_dealloc, /*tp_dealloc*/
+X list_print, /*tp_print*/
+X list_getattr, /*tp_getattr*/
+X 0, /*tp_setattr*/
+X list_compare, /*tp_compare*/
+X list_repr, /*tp_repr*/
+X 0, /*tp_as_number*/
+X &list_as_sequence, /*tp_as_sequence*/
+X 0, /*tp_as_mapping*/
+X};
+EOF
+fi
+if test -s 'src/parser.c'
+then echo '*** I will not over-write existing file src/parser.c'
+else
+echo 'x - src/parser.c'
+sed 's/^X//' > 'src/parser.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/* Parser implementation */
+X
+X/* For a description, see the comments at end of this file */
+X
+X/* XXX To do: error recovery */
+X
+X#include "pgenheaders.h"
+X#include "assert.h"
+X#include "token.h"
+X#include "grammar.h"
+X#include "node.h"
+X#include "parser.h"
+X#include "errcode.h"
+X
+X
+X#ifdef DEBUG
+Xextern int debugging;
+X#define D(x) if (!debugging); else x
+X#else
+X#define D(x)
+X#endif
+X
+X
+X/* STACK DATA TYPE */
+X
+Xstatic void s_reset PROTO((stack *));
+X
+Xstatic void
+Xs_reset(s)
+X stack *s;
+X{
+X s->s_top = &s->s_base[MAXSTACK];
+X}
+X
+X#define s_empty(s) ((s)->s_top == &(s)->s_base[MAXSTACK])
+X
+Xstatic int s_push PROTO((stack *, dfa *, node *));
+X
+Xstatic int
+Xs_push(s, d, parent)
+X register stack *s;
+X dfa *d;
+X node *parent;
+X{
+X register stackentry *top;
+X if (s->s_top == s->s_base) {
+X fprintf(stderr, "s_push: parser stack overflow\n");
+X return -1;
+X }
+X top = --s->s_top;
+X top->s_dfa = d;
+X top->s_parent = parent;
+X top->s_state = 0;
+X return 0;
+X}
+X
+X#ifdef DEBUG
+X
+Xstatic void s_pop PROTO((stack *));
+X
+Xstatic void
+Xs_pop(s)
+X register stack *s;
+X{
+X if (s_empty(s)) {
+X fprintf(stderr, "s_pop: parser stack underflow -- FATAL\n");
+X abort();
+X }
+X s->s_top++;
+X}
+X
+X#else /* !DEBUG */
+X
+X#define s_pop(s) (s)->s_top++
+X
+X#endif
+X
+X
+X/* PARSER CREATION */
+X
+Xparser_state *
+Xnewparser(g, start)
+X grammar *g;
+X int start;
+X{
+X parser_state *ps;
+X
+X if (!g->g_accel)
+X addaccelerators(g);
+X ps = NEW(parser_state, 1);
+X if (ps == NULL)
+X return NULL;
+X ps->p_grammar = g;
+X ps->p_tree = newtree(start);
+X if (ps->p_tree == NULL) {
+X DEL(ps);
+X return NULL;
+X }
+X s_reset(&ps->p_stack);
+X (void) s_push(&ps->p_stack, finddfa(g, start), ps->p_tree);
+X return ps;
+X}
+X
+Xvoid
+Xdelparser(ps)
+X parser_state *ps;
+X{
+X /* NB If you want to save the parse tree,
+X you must set p_tree to NULL before calling delparser! */
+X freetree(ps->p_tree);
+X DEL(ps);
+X}
+X
+X
+X/* PARSER STACK OPERATIONS */
+X
+Xstatic int shift PROTO((stack *, int, char *, int, int));
+X
+Xstatic int
+Xshift(s, type, str, newstate, lineno)
+X register stack *s;
+X int type;
+X char *str;
+X int newstate;
+X int lineno;
+X{
+X assert(!s_empty(s));
+X if (addchild(s->s_top->s_parent, type, str, lineno) == NULL) {
+X fprintf(stderr, "shift: no mem in addchild\n");
+X return -1;
+X }
+X s->s_top->s_state = newstate;
+X return 0;
+X}
+X
+Xstatic int push PROTO((stack *, int, dfa *, int, int));
+X
+Xstatic int
+Xpush(s, type, d, newstate, lineno)
+X register stack *s;
+X int type;
+X dfa *d;
+X int newstate;
+X int lineno;
+X{
+X register node *n;
+X n = s->s_top->s_parent;
+X assert(!s_empty(s));
+X if (addchild(n, type, (char *)NULL, lineno) == NULL) {
+X fprintf(stderr, "push: no mem in addchild\n");
+X return -1;
+X }
+X s->s_top->s_state = newstate;
+X return s_push(s, d, CHILD(n, NCH(n)-1));
+X}
+X
+X
+X/* PARSER PROPER */
+X
+Xstatic int classify PROTO((grammar *, int, char *));
+X
+Xstatic int
+Xclassify(g, type, str)
+X grammar *g;
+X register int type;
+X char *str;
+X{
+X register int n = g->g_ll.ll_nlabels;
+X
+X if (type == NAME) {
+X register char *s = str;
+X register label *l = g->g_ll.ll_label;
+X register int i;
+X for (i = n; i > 0; i--, l++) {
+X if (l->lb_type == NAME && l->lb_str != NULL &&
+X l->lb_str[0] == s[0] &&
+X strcmp(l->lb_str, s) == 0) {
+X D(printf("It's a keyword\n"));
+X return n - i;
+X }
+X }
+X }
+X
+X {
+X register label *l = g->g_ll.ll_label;
+X register int i;
+X for (i = n; i > 0; i--, l++) {
+X if (l->lb_type == type && l->lb_str == NULL) {
+X D(printf("It's a token we know\n"));
+X return n - i;
+X }
+X }
+X }
+X
+X D(printf("Illegal token\n"));
+X return -1;
+X}
+X
+Xint
+Xaddtoken(ps, type, str, lineno)
+X register parser_state *ps;
+X register int type;
+X char *str;
+X int lineno;
+X{
+X register int ilabel;
+X
+X D(printf("Token %s/'%s' ... ", tok_name[type], str));
+X
+X /* Find out which label this token is */
+X ilabel = classify(ps->p_grammar, type, str);
+X if (ilabel < 0)
+X return E_SYNTAX;
+X
+X /* Loop until the token is shifted or an error occurred */
+X for (;;) {
+X /* Fetch the current dfa and state */
+X register dfa *d = ps->p_stack.s_top->s_dfa;
+X register state *s = &d->d_state[ps->p_stack.s_top->s_state];
+X
+X D(printf(" DFA '%s', state %d:",
+X d->d_name, ps->p_stack.s_top->s_state));
+X
+X /* Check accelerator */
+X if (s->s_lower <= ilabel && ilabel < s->s_upper) {
+X register int x = s->s_accel[ilabel - s->s_lower];
+X if (x != -1) {
+X if (x & (1<<7)) {
+X /* Push non-terminal */
+X int nt = (x >> 8) + NT_OFFSET;
+X int arrow = x & ((1<<7)-1);
+X dfa *d1 = finddfa(ps->p_grammar, nt);
+X if (push(&ps->p_stack, nt, d1,
+X arrow, lineno) < 0) {
+X D(printf(" MemError: push.\n"));
+X return E_NOMEM;
+X }
+X D(printf(" Push ...\n"));
+X continue;
+X }
+X
+X /* Shift the token */
+X if (shift(&ps->p_stack, type, str,
+X x, lineno) < 0) {
+X D(printf(" MemError: shift.\n"));
+X return E_NOMEM;
+X }
+X D(printf(" Shift.\n"));
+X /* Pop while we are in an accept-only state */
+X while (s = &d->d_state
+X [ps->p_stack.s_top->s_state],
+X s->s_accept && s->s_narcs == 1) {
+X D(printf(" Direct pop.\n"));
+X s_pop(&ps->p_stack);
+X if (s_empty(&ps->p_stack)) {
+X D(printf(" ACCEPT.\n"));
+X return E_DONE;
+X }
+X d = ps->p_stack.s_top->s_dfa;
+X }
+X return E_OK;
+X }
+X }
+X
+X if (s->s_accept) {
+X /* Pop this dfa and try again */
+X s_pop(&ps->p_stack);
+X D(printf(" Pop ...\n"));
+X if (s_empty(&ps->p_stack)) {
+X D(printf(" Error: bottom of stack.\n"));
+X return E_SYNTAX;
+X }
+X continue;
+X }
+X
+X /* Stuck, report syntax error */
+X D(printf(" Error.\n"));
+X return E_SYNTAX;
+X }
+X}
+X
+X
+X#ifdef DEBUG
+X
+X/* DEBUG OUTPUT */
+X
+Xvoid
+Xdumptree(g, n)
+X grammar *g;
+X node *n;
+X{
+X int i;
+X
+X if (n == NULL)
+X printf("NIL");
+X else {
+X label l;
+X l.lb_type = TYPE(n);
+X l.lb_str = TYPE(str);
+X printf("%s", labelrepr(&l));
+X if (ISNONTERMINAL(TYPE(n))) {
+X printf("(");
+X for (i = 0; i < NCH(n); i++) {
+X if (i > 0)
+X printf(",");
+X dumptree(g, CHILD(n, i));
+X }
+X printf(")");
+X }
+X }
+X}
+X
+Xvoid
+Xshowtree(g, n)
+X grammar *g;
+X node *n;
+X{
+X int i;
+X
+X if (n == NULL)
+X return;
+X if (ISNONTERMINAL(TYPE(n))) {
+X for (i = 0; i < NCH(n); i++)
+X showtree(g, CHILD(n, i));
+X }
+X else if (ISTERMINAL(TYPE(n))) {
+X printf("%s", tok_name[TYPE(n)]);
+X if (TYPE(n) == NUMBER || TYPE(n) == NAME)
+X printf("(%s)", STR(n));
+X printf(" ");
+X }
+X else
+X printf("? ");
+X}
+X
+Xvoid
+Xprinttree(ps)
+X parser_state *ps;
+X{
+X if (debugging) {
+X printf("Parse tree:\n");
+X dumptree(ps->p_grammar, ps->p_tree);
+X printf("\n");
+X printf("Tokens:\n");
+X showtree(ps->p_grammar, ps->p_tree);
+X printf("\n");
+X }
+X printf("Listing:\n");
+X listtree(ps->p_tree);
+X printf("\n");
+X}
+X
+X#endif /* DEBUG */
+X
+X/*
+X
+XDescription
+X-----------
+X
+XThe parser's interface is different than usual: the function addtoken()
+Xmust be called for each token in the input. This makes it possible to
+Xturn it into an incremental parsing system later. The parsing system
+Xconstructs a parse tree as it goes.
+X
+XA parsing rule is represented as a Deterministic Finite-state Automaton
+X(DFA). A node in a DFA represents a state of the parser; an arc represents
+Xa transition. Transitions are either labeled with terminal symbols or
+Xwith non-terminals. When the parser decides to follow an arc labeled
+Xwith a non-terminal, it is invoked recursively with the DFA representing
+Xthe parsing rule for that as its initial state; when that DFA accepts,
+Xthe parser that invoked it continues. The parse tree constructed by the
+Xrecursively called parser is inserted as a child in the current parse tree.
+X
+XThe DFA's can be constructed automatically from a more conventional
+Xlanguage description. An extended LL(1) grammar (ELL(1)) is suitable.
+XCertain restrictions make the parser's life easier: rules that can produce
+Xthe empty string should be outlawed (there are other ways to put loops
+Xor optional parts in the language). To avoid the need to construct
+XFIRST sets, we can require that all but the last alternative of a rule
+X(really: arc going out of a DFA's state) must begin with a terminal
+Xsymbol.
+X
+XAs an example, consider this grammar:
+X
+Xexpr: term (OP term)*
+Xterm: CONSTANT | '(' expr ')'
+X
+XThe DFA corresponding to the rule for expr is:
+X
+X------->.---term-->.------->
+X ^ |
+X | |
+X \----OP----/
+X
+XThe parse tree generated for the input a+b is:
+X
+X(expr: (term: (NAME: a)), (OP: +), (term: (NAME: b)))
+X
+X*/
+EOF
+fi
+if test -s 'src/patchlevel.h'
+then echo '*** I will not over-write existing file src/patchlevel.h'
+else
+echo 'x - src/patchlevel.h'
+sed 's/^X//' > 'src/patchlevel.h' << 'EOF'
+X1
+EOF
+fi
+if test -s 'src/posixmodule.c'
+then echo '*** I will not over-write existing file src/posixmodule.c'
+else
+echo 'x - src/posixmodule.c'
+sed 's/^X//' > 'src/posixmodule.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/* POSIX module implementation */
+X
+X#include <signal.h>
+X#include <string.h>
+X#include <setjmp.h>
+X#include <sys/types.h>
+X#include <sys/stat.h>
+X#include <sys/time.h>
+X#ifdef SYSV
+X#include <dirent.h>
+X#define direct dirent
+X#else
+X#include <sys/dir.h>
+X#endif
+X
+X#include "allobjects.h"
+X#include "modsupport.h"
+X
+Xextern char *strerror PROTO((int));
+X
+X#ifdef AMOEBA
+X#define NO_LSTAT
+X#endif
+X
+X
+X/* Return a dictionary corresponding to the POSIX environment table */
+X
+Xextern char **environ;
+X
+Xstatic object *
+Xconvertenviron()
+X{
+X object *d;
+X char **e;
+X d = newdictobject();
+X if (d == NULL)
+X return NULL;
+X if (environ == NULL)
+X return d;
+X /* XXX This part ignores errors */
+X for (e = environ; *e != NULL; e++) {
+X object *v;
+X char *p = strchr(*e, '=');
+X if (p == NULL)
+X continue;
+X v = newstringobject(p+1);
+X if (v == NULL)
+X continue;
+X *p = '\0';
+X (void) dictinsert(d, *e, v);
+X *p = '=';
+X DECREF(v);
+X }
+X return d;
+X}
+X
+X
+Xstatic object *PosixError; /* Exception posix.error */
+X
+X/* Set a POSIX-specific error from errno, and return NULL */
+X
+Xstatic object *
+Xposix_error()
+X{
+X return err_errno(PosixError);
+X}
+X
+X
+X/* POSIX generic methods */
+X
+Xstatic object *
+Xposix_1str(args, func)
+X object *args;
+X int (*func) FPROTO((const char *));
+X{
+X object *path1;
+X if (!getstrarg(args, &path1))
+X return NULL;
+X if ((*func)(getstringvalue(path1)) < 0)
+X return posix_error();
+X INCREF(None);
+X return None;
+X}
+X
+Xstatic object *
+Xposix_2str(args, func)
+X object *args;
+X int (*func) FPROTO((const char *, const char *));
+X{
+X object *path1, *path2;
+X if (!getstrstrarg(args, &path1, &path2))
+X return NULL;
+X if ((*func)(getstringvalue(path1), getstringvalue(path2)) < 0)
+X return posix_error();
+X INCREF(None);
+X return None;
+X}
+X
+Xstatic object *
+Xposix_strint(args, func)
+X object *args;
+X int (*func) FPROTO((const char *, int));
+X{
+X object *path1;
+X int i;
+X if (!getstrintarg(args, &path1, &i))
+X return NULL;
+X if ((*func)(getstringvalue(path1), i) < 0)
+X return posix_error();
+X INCREF(None);
+X return None;
+X}
+X
+Xstatic object *
+Xposix_do_stat(self, args, statfunc)
+X object *self;
+X object *args;
+X int (*statfunc) FPROTO((const char *, struct stat *));
+X{
+X struct stat st;
+X object *path;
+X object *v;
+X if (!getstrarg(args, &path))
+X return NULL;
+X if ((*statfunc)(getstringvalue(path), &st) != 0)
+X return posix_error();
+X v = newtupleobject(10);
+X if (v == NULL)
+X return NULL;
+X#define SET(i, st_member) settupleitem(v, i, newintobject((long)st.st_member))
+X SET(0, st_mode);
+X SET(1, st_ino);
+X SET(2, st_dev);
+X SET(3, st_nlink);
+X SET(4, st_uid);
+X SET(5, st_gid);
+X SET(6, st_size);
+X SET(7, st_atime);
+X SET(8, st_mtime);
+X SET(9, st_ctime);
+X#undef SET
+X if (err_occurred()) {
+X DECREF(v);
+X return NULL;
+X }
+X return v;
+X}
+X
+X
+X/* POSIX methods */
+X
+Xstatic object *
+Xposix_chdir(self, args)
+X object *self;
+X object *args;
+X{
+X extern int chdir PROTO((const char *));
+X return posix_1str(args, chdir);
+X}
+X
+Xstatic object *
+Xposix_chmod(self, args)
+X object *self;
+X object *args;
+X{
+X extern int chmod PROTO((const char *, mode_t));
+X return posix_strint(args, chmod);
+X}
+X
+Xstatic object *
+Xposix_getcwd(self, args)
+X object *self;
+X object *args;
+X{
+X char buf[1026];
+X extern char *getcwd PROTO((char *, int));
+X if (!getnoarg(args))
+X return NULL;
+X if (getcwd(buf, sizeof buf) == NULL)
+X return posix_error();
+X return newstringobject(buf);
+X}
+X
+Xstatic object *
+Xposix_link(self, args)
+X object *self;
+X object *args;
+X{
+X extern int link PROTO((const char *, const char *));
+X return posix_2str(args, link);
+X}
+X
+Xstatic object *
+Xposix_listdir(self, args)
+X object *self;
+X object *args;
+X{
+X object *name, *d, *v;
+X DIR *dirp;
+X struct direct *ep;
+X if (!getstrarg(args, &name))
+X return NULL;
+X if ((dirp = opendir(getstringvalue(name))) == NULL)
+X return posix_error();
+X if ((d = newlistobject(0)) == NULL) {
+X closedir(dirp);
+X return NULL;
+X }
+X while ((ep = readdir(dirp)) != NULL) {
+X v = newstringobject(ep->d_name);
+X if (v == NULL) {
+X DECREF(d);
+X d = NULL;
+X break;
+X }
+X if (addlistitem(d, v) != 0) {
+X DECREF(v);
+X DECREF(d);
+X d = NULL;
+X break;
+X }
+X DECREF(v);
+X }
+X closedir(dirp);
+X return d;
+X}
+X
+Xstatic object *
+Xposix_mkdir(self, args)
+X object *self;
+X object *args;
+X{
+X extern int mkdir PROTO((const char *, mode_t));
+X return posix_strint(args, mkdir);
+X}
+X
+Xstatic object *
+Xposix_rename(self, args)
+X object *self;
+X object *args;
+X{
+X extern int rename PROTO((const char *, const char *));
+X return posix_2str(args, rename);
+X}
+X
+Xstatic object *
+Xposix_rmdir(self, args)
+X object *self;
+X object *args;
+X{
+X extern int rmdir PROTO((const char *));
+X return posix_1str(args, rmdir);
+X}
+X
+Xstatic object *
+Xposix_stat(self, args)
+X object *self;
+X object *args;
+X{
+X extern int stat PROTO((const char *, struct stat *));
+X return posix_do_stat(self, args, stat);
+X}
+X
+Xstatic object *
+Xposix_system(self, args)
+X object *self;
+X object *args;
+X{
+X object *command;
+X int sts;
+X if (!getstrarg(args, &command))
+X return NULL;
+X sts = system(getstringvalue(command));
+X return newintobject((long)sts);
+X}
+X
+Xstatic object *
+Xposix_umask(self, args)
+X object *self;
+X object *args;
+X{
+X int i;
+X if (!getintarg(args, &i))
+X return NULL;
+X i = umask(i);
+X if (i < 0)
+X return posix_error();
+X return newintobject((long)i);
+X}
+X
+Xstatic object *
+Xposix_unlink(self, args)
+X object *self;
+X object *args;
+X{
+X extern int unlink PROTO((const char *));
+X return posix_1str(args, unlink);
+X}
+X
+Xstatic object *
+Xposix_utimes(self, args)
+X object *self;
+X object *args;
+X{
+X object *path;
+X struct timeval tv[2];
+X if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2) {
+X err_badarg();
+X return NULL;
+X }
+X if (!getstrarg(gettupleitem(args, 0), &path) ||
+X !getlonglongargs(gettupleitem(args, 1),
+X &tv[0].tv_sec, &tv[1].tv_sec))
+X return NULL;
+X tv[0].tv_usec = tv[1].tv_usec = 0;
+X if (utimes(getstringvalue(path), tv) < 0)
+X return posix_error();
+X INCREF(None);
+X return None;
+X}
+X
+X
+X#ifndef NO_LSTAT
+X
+Xstatic object *
+Xposix_lstat(self, args)
+X object *self;
+X object *args;
+X{
+X extern int lstat PROTO((const char *, struct stat *));
+X return posix_do_stat(self, args, lstat);
+X}
+X
+Xstatic object *
+Xposix_readlink(self, args)
+X object *self;
+X object *args;
+X{
+X char buf[1024]; /* XXX Should use MAXPATHLEN */
+X object *path;
+X int n;
+X if (!getstrarg(args, &path))
+X return NULL;
+X n = readlink(getstringvalue(path), buf, sizeof buf);
+X if (n < 0)
+X return posix_error();
+X return newsizedstringobject(buf, n);
+X}
+X
+Xstatic object *
+Xposix_symlink(self, args)
+X object *self;
+X object *args;
+X{
+X extern int symlink PROTO((const char *, const char *));
+X return posix_2str(args, symlink);
+X}
+X
+X#endif /* NO_LSTAT */
+X
+X
+Xstatic struct methodlist posix_methods[] = {
+X {"chdir", posix_chdir},
+X {"chmod", posix_chmod},
+X {"getcwd", posix_getcwd},
+X {"link", posix_link},
+X {"listdir", posix_listdir},
+X {"mkdir", posix_mkdir},
+X {"rename", posix_rename},
+X {"rmdir", posix_rmdir},
+X {"stat", posix_stat},
+X {"system", posix_system},
+X {"umask", posix_umask},
+X {"unlink", posix_unlink},
+X {"utimes", posix_utimes},
+X#ifndef NO_LSTAT
+X {"lstat", posix_lstat},
+X {"readlink", posix_readlink},
+X {"symlink", posix_symlink},
+X#endif
+X {NULL, NULL} /* Sentinel */
+X};
+X
+X
+Xvoid
+Xinitposix()
+X{
+X object *m, *d, *v;
+X
+X m = initmodule("posix", posix_methods);
+X d = getmoduledict(m);
+X
+X /* Initialize posix.environ dictionary */
+X v = convertenviron();
+X if (v == NULL || dictinsert(d, "environ", v) != 0)
+X fatal("can't define posix.environ");
+X DECREF(v);
+X
+X /* Initialize posix.error exception */
+X PosixError = newstringobject("posix.error");
+X if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
+X fatal("can't define posix.error");
+X}
+EOF
+fi
+echo 'Part 11 out of 21 of pack.out complete.'
+exit 0