home *** CD-ROM | disk | FTP | other *** search
- From: guido@cwi.nl (Guido van Rossum)
- Newsgroups: alt.sources
- Subject: Python 0.9.1 part 11/21
- Message-ID: <2973@charon.cwi.nl>
- Date: 19 Feb 91 17:42:05 GMT
-
- : 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
-