[alt.sources] Python 0.9.1 part 06/21

guido@cwi.nl (Guido van Rossum) (02/20/91)

: 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 06 out of 21:'
if test -s 'doc/Makefile'
then echo '*** I will not over-write existing file doc/Makefile'
else
echo 'x - doc/Makefile'
sed 's/^X//' > 'doc/Makefile' << 'EOF'
X# Makefile for Python documentation.
X
XLATEX=		latex
XDVIPS=		dvips
XTEXPREVIEW=	xdvi
X
XPRINT=		lpr
X
Xtut:		tut.dvi
X		$(TEXPREVIEW) tut
X
Xtut.dvi tut.ps:	tut.toc tut.tex myformat.sty
X
Xmod:		mod.dvi
X		$(TEXPREVIEW) mod
X
Xmod.dvi mod.ps:	mod.toc mod.tex mod1.tex mod2.tex mod3.tex myformat.sty
X
XALL=		tut.ps mod.ps
X
Xall:		$(ALL)
X
Xprint:		$(ALL)
X		$(PRINT) $(ALL)
X
Xclean:
X		rm -f *.dvi *.aux *.toc *.log *.ps core [#@,]* *~
X
X.SUFFIXES:	# Remove default suffixes
X
X.SUFFIXES:	.tex .aux .toc .dvi .ps
X
X.tex.aux:
X		$(LATEX) $*
X
X.tex.toc:
X		$(LATEX) $*
X
X.tex.dvi:
X		$(LATEX) $*
X
X.dvi.ps:
X		$(DVIPS) $* >$*.ps
X
X.tex.ps:
X		$(LATEX) $*
X		$(DVIPS) $* >$*.ps
EOF
fi
if test -s 'doc/mod2.tex'
then echo '*** I will not over-write existing file doc/mod2.tex'
else
echo 'x - doc/mod2.tex'
sed 's/^X//' > 'doc/mod2.tex' << 'EOF'
X\section{Built-in Modules}
X
XThe modules described in this section are built into the interpreter.
XThey must be imported using
X{\tt import}.
XSome modules are not always available; it is a configuration option to
Xprovide them.
XDetails are listed with the descriptions, but the best way to see if
Xa module exists in a particular implementation is to attempt to import
Xit.
X
X\subsection{Built-in Module {\tt sys}}
X
XThis module provides access to some variables used or maintained by the
Xinterpreter and to functions that interact strongly with the interpreter.
XIt is always available.
X\begin{description}
X\funcitem{argv}
XThe list of command line arguments passed to a {\Python} script.
X{\tt sys.argv[0]}
Xis the script name.
XIf no script name was passed to the {\Python} interpreter,
X{\tt sys.argv}
Xis empty.
X\funcitem{exit}{n}
XExits from {\Python} with numeric exit status
X{\tt n}.
XThis closes all open files and performs other cleanup-actions required by
Xthe interpreter (but
X{\em finally clauses}
Xof
X{\tt try}
Xstatements are not executed!).
X\funcitem{modules}
XGives the list of modules that have already been loaded.
XThis can be manipulated to force reloading of modules and other tricks.
X\funcitem{path}
XA list of strings that specifies the search path for modules.
XInitialized from the environment variable {\tt PYTHONPATH}, or an
Xinstallation-dependent default.
X\funcitem{ps1,~ps2}
XStrings specifying the primary and secondary prompt of the interpreter.
XThese are only defined if the interpreter is in interactive mode.
XTheir initial values in this case are
X{\tt '>>> '}
Xand
X{\tt '... '}.
X\funcitem{stdin, stdout, stderr}
X%.br
XFile objects corresponding to the interpreter's standard input, output
Xand error streams.
X{\tt sys.stdin}
Xis used for all interpreter input except for scripts but including calls
Xto
X{\tt input()}
Xand
X{\tt raw\_input()}.
X{\tt sys.stdout}
Xis used for the output of
X{\tt print} and expression statements
Xand for the prompts of
X{\tt input()}
Xand
X{\tt raw\_input()}.
XThe interpreter's own prompts and its error messages are written to
Xstderr.
XAssigning to
X{\tt sys.stderr}
Xhas no effect on the interpreter; it can be used to write error messages
Xto stderr using
X{\tt print}.
X\end{description}
X
X\subsection{Built-in Module {\tt math}}
X
XThis module is always available.
XIt provides access to the mathematical functions defined by the C
Xstandard.
XThey are:
X{\tt acos(x)},
X{\tt asin(x)},
X{\tt atan(x)},
X{\tt atan2(x,y)},
X{\tt ceil(x)},
X{\tt cos(x)},
X{\tt cosh(x)},
X{\tt exp(x)},
X{\tt fabs(x)},
X{\tt floor(x)},
X%{\tt fmod(...)}  XXX not yet
X%{\tt frexp(...)} XXX not yet
X%{\tt ldexp(...)} XXX not yet
X{\tt log(x)},
X{\tt log10(x)},
X%{\tt modf(...)}  XXX not yet
X{\tt pow(x,y)},
X{\tt sin(x)},
X{\tt sinh(x)},
X{\tt sqrt(x)},
X{\tt tan(x)},
X{\tt tanh(x)}.
X
XIt also defines two mathematical constants:
X{\tt pi}
Xand
X{\tt e}.
X
X\subsection{Built-in Module {\tt time}}
X
XThis module provides various time-related functions.
XIt is always available.
XFunctions are:
X\begin{description}
X\funcitem{sleep}{secs}
XSuspends execution for the given number of seconds.
X\funcitem{time}{}
XReturns the time in seconds since the Epoch (Thursday January 1,
X00:00:00, 1970 UCT on \UNIX\ machines).
X\end{description}
X
X\noindent
XIn some versions (Amoeba, Mac) the following functions also exist:
X\begin{description}
X\funcitem{millisleep}{msecs}
XSuspends execution for the given number of milliseconds.
X\funcitem{millitimer}{}
XReturns the number of milliseconds of real time elapsed since some point
Xin the past that is fixed per execution of the python interpreter (but
Xmay change in each following run).
X\end{description}
X
X\noindent
XThe granularity of the milliseconds functions may be more than a
Xmillisecond (100 msecs on Amoeba, 1/60 sec on the Mac).
X
X\subsection{Built-in Module {\tt regexp}}
X
XThis module provides a regular expression matching operation.
XIt is always available.
X
XThe module defines a function and an exception:
X
X\begin{description}
X
X\funcitem{compile}{pattern}
X
XCompile a regular expression given as a string into a regular
Xexpression object.
XThe string must be an egrep-style regular expression;
Xthis means that the characters
X{\tt '(' ')' '*' '+' '?'\ '|' }\verb='^' '$'=
Xare special.
X(It is implemented using Henry Spencer's regular expression matching
Xfunctions.)
X
Xexcitem{error}{regexp.error}
X
XException raised when a string passed to {\tt compile()} is not a
Xvalid regular expression (e.g., unmatched parentheses) or when some other
Xerror occurs during compilation or matching
X(``no match found'' is not an error).
X
X\end{description}
X
XCompiled regular expression objects support a single method:
X
X\begin{description}
X
X\funcitem{exec}{str}
X
XFind the first occurrence of the compiled regular expression in the
Xstring {\tt str}.
XThe return value is a tuple of pairs specifying where a match was
Xfound and where matches were found for subpatterns specified with
X{\tt '('} and {\tt ')'} in the pattern.
XIf no match is found, an empty tuple is returned; otherwise the first
Xitem of the tuple is a pair of slice indices into the search string
Xgiving the match found.
XIf there were any subpatterns in the pattern, the returned tuple has an
Xadditional item for each subpattern, giving the slice indices into the
Xsearch string where that subpattern was found.
X
X\end{description}
X
XFor example:
X\bcode\begin{verbatim}
X>>> import regexp
X>>> r = regexp.compile('--(.*)--')
X>>> s = 'a--b--c'
X>>> r.exec(s)
X((1, 6), (3, 4))
X>>> s[1:6] # The entire match
X'--b--'
X>>> s[3:4] # The subpattern
X'b'
X>>> 
X\end{verbatim}\ecode
X
X\subsection{Built-in Module {\tt posix}}
X
XThis module provides access to operating system functionality that is
Xstandardized by the C Standard and the POSIX standard (a thinly diguised
X{\UNIX} interface).
XIt is available in all {\Python} versions except on the Macintosh.
XErrors are reported exceptions.
XIt defines the following items:
X\begin{description}
X\funcitem{chdir}{path}
XChanges the current directory to
X{\tt path}.
X\funcitem{chmod}{path, mode}
XChange the mode of
X{\tt path}
Xto the numeric
X{\tt mode}.
X\funcitem{environ}
XA dictionary representing the string environment at the time
Xthe interpreter was started.
X(Modifying this dictionary does not affect the string environment of the
Xinterpreter.)
XFor example,
X{\tt posix.environ['HOME']}
Xis the pathname of your home directory, equivalent to
X{\tt getenv("HOME")}
Xin C.
X\excitem{error}{posix.error}
X%.br
XThe exception raised when an POSIX function returns an error.
XThe value accompanying this exception is a pair containing the numeric
Xerror code from
X{\tt errno}
Xand the corresponding string, as would be printed by the C function
X{\tt perror()}.
X\funcitem{getcwd}{}
XReturns a string representing the current working directory.
X\funcitem{link}{src, dst}
XCreates a hard link pointing to
X{\tt src}
Xnamed
X{\tt dst}.
X\funcitem{listdir}{path}
XReturns a list containing the names of the entries in the
Xdirectory.
XThe list is in arbitrary order.
XIt includes the special entries
X{\tt '.'}
Xand
X{\tt '..'}
Xif they are present in the directory.
X\funcitem{mkdir}{path, mode}
XCreates a directory named
X{\tt path}
Xwith numeric mode
X{\tt mode}.
X\funcitem{rename}{src, dst}
XRenames the file or directory
X{\tt src}
Xto
X{\tt dst}.
X\funcitem{rmdir}{path}
XRemoves the directory
X{\tt path}.
X\funcitem{stat}{path}
XPerforms a
X{\em stat}
Xsystem call on the given path.
XThe return value is a tuple of at least 10 integers giving the most
Ximportant (and portable) members of the
X{\em stat}
Xstructure, in the order
X{\tt st\_mode},
X{\tt st\_ino},
X{\tt st\_dev},
X{\tt st\_nlink},
X{\tt st\_uid},
X{\tt st\_gid},
X{\tt st\_size},
X{\tt st\_atime},
X{\tt st\_mtime},
X{\tt st\_ctime}.
XMore items may be added at the end by some implementations.
X\funcitem{system}{command}
XExecutes the command (a string) in a subshell.
XThis is implemented by calling the Standard C function
X{\tt system()},
Xand has the same limitations.
XChanges to
X{\tt posix.environ},
X{\tt sys.stdin}
Xetc. are not reflected in the environment of the executed command.
XThe return value is the exit status of the process as returned by
XStandard C
X{\tt system()}.
X\funcitem{umask}{mask}
XSets the current numeric umask and returns the previous umask.
X\funcitem{unlink}{path}
XUnlinks the file
X{\tt path}.
X\funcitem{utimes(path, }{atime, mtime)}
X%.br
XSets the access and modified time of the file to the given values.
X(The second argument is a tuple of two items.)
X\end{description}
X
XThe following functions are only available on systems that support
Xsymbolic links:
X\begin{description}
X\funcitem{lstat}{path}
XLike
X{\tt stat()},
Xbut does not follow symbolic links.
X\funcitem{readlink}{path}
XReturns a string representing the path to which the symbolic link
Xpoints.
X\funcitem{symlink}{src, dst}
XCreates a symbolic link pointing to
X{\tt src}
Xnamed
X{\tt dst}.
X\end{description}
X
X\subsection{Built-in Module {\tt stdwin}}
X
XThis module defines several new object types and functions that
Xprovide access to the functionality of the Standard Window System
XInterface, STDWIN [CWI report CR-R8817].
XIt is available on systems to which STDWIN has been ported (which is
Xmost systems).
XIt is only available if the {\tt DISPLAY} environment variable is set
Xor an explicit `{\tt -display \it displayname}' argument is passed to
Xthe interpreter.
X
XFunctions have names that usually resemble their C STDWIN counterparts
Xwith the initial `w' dropped.
XPoints are represented by pairs of integers; rectangles
Xby pairs of points.
XFor a complete description of STDWIN please refer to the documentation
Xof STDWIN for C programmers (aforementioned CWI report).
X\subsubsection{Functions Defined in Module {\tt stdwin}}
X
XThe following functions are defined in the {\tt stdwin} module:
X\begin{description}
X\funcitem{open}{title}
X%.br
XOpens a new window whose initial title is given by the string argument.
XReturns a window object; window object methods are described below.%
X\footnote{
XThe {\Python} version of STDWIN does not support draw procedures; all
Xdrawing requests are reported as draw events.
X}
X\funcitem{getevent}{}
X%.br
XWaits for and returns the next event.
XAn event is returned as a triple: the first element is the event
Xtype, a small integer; the second element is the window object to which
Xthe event applies, or
X{\tt None}
Xif it applies to no window in particular;
Xthe third element is type-dependent.
XNames for event types and command codes are defined in the standard
Xmodule
X{\tt stdwinevent}.
X\funcitem{setdefwinpos}{h, v}
X%.br
XSets the default window position.
X\funcitem{setdefwinsize}{width, height}
X%.br
XSets the default window size.
X\funcitem{menucreate}{title}
X%.br
XCreates a menu object referring to a global menu (a menu that appears in
Xall windows).
XMethods of menu objects are described below.
X\funcitem{fleep}{}
X%.br
XCauses a beep or bell (or perhaps a `visual bell' or flash, hence the
Xname).
X\funcitem{message}{string}
X%.br
XDisplays a dialog box containing the string.
XThe user must click OK before the function returns.
X\funcitem{askync}{prompt, default}
X%.br
XDisplays a dialog that prompts the user to answer a question with yes or
Xno.
XThe function returns 0 for no, 1 for yes.
XIf the user hits the Return key, the default (which must be 0 or 1) is
Xreturned.
XIf the user cancels the dialog, the
X{\tt KeyboardInterrupt}
Xexception is raised.
X\funcitem{askstr}{prompt, default}
X%.br
XDisplays a dialog that prompts the user for a string.
XIf the user hits the Return key, the default string is returned.
XIf the user cancels the dialog, the
X{\tt KeyboardInterrupt}
Xexception is raised.
X\funcitem{askfile}{prompt, default, new}
X%.br
XAsks the user to specify a filename.
XIf
X{\tt new}
Xis zero it must be an existing file; otherwise, it must be a new file.
XIf the user cancels the dialog, the
X{\tt KeyboardInterrupt}
Xexception is raised.
X\funcitem{setcutbuffer}{i, string}
X%.br
XStores the string in the system's cut buffer number
X{\tt i},
Xwhere it can be found (for pasting) by other applications.
XOn X11, there are 8 cut buffers (numbered 0..7).
XCut buffer number 0 is the `clipboard' on the Macintosh.
X\funcitem{getcutbuffer}{i}
X%.br
XReturns the contents of the system's cut buffer number
X{\tt i}.
X\funcitem{rotatebutbuffers}{n}
X%.br
XOn X11, this rotates the 8 cut buffers by
X{\tt n}.
XIgnored on the Macintosh.
X\funcitem{getselection}{i}
X%.br
XReturns X11 selection number
X{\tt i.}
XSelections are not cut buffers.
XSelection numbers are defined in module
X{\tt stdwinevents}.
XSelection {\tt WS\_PRIMARY} is the
X{\em primary}
Xselection (used by
Xxterm,
Xfor instance);
Xselection {\tt WS\_SECONDARY} is the
X{\em secondary}
Xselection; selection {\tt WS\_CLIPBOARD} is the
X{\em clipboard}
Xselection (used by
Xxclipboard).
XOn the Macintosh, this always returns an empty string.
X\funcitem{resetselection}{i}
X%.br
XResets selection number
X{\tt i},
Xif this process owns it.
X(See window method
X{\tt setselection()}).
X\funcitem{baseline}{}
X%.br
XReturn the baseline of the current font (defined by STDWIN as the
Xvertical distance between the baseline and the top of the
Xcharacters).%
X\footnote{
XThere is no way yet to set the current font.
XThis will change in a future version.
X}
X\funcitem{lineheight}{}
X%.br
XReturn the total line height of the current font.
X\funcitem{textbreak}{str, width}
X%.br
XReturn the number of characters of the string that fit into a space of
X{\tt width}
Xbits wide when drawn in the curent font.
X\funcitem{textwidth}{str}
X%.br
XReturn the width in bits of the string when drawn in the current font.
X\end{description}
X
X\subsubsection{Window Object Methods}
X
XWindow objects are created by
X{\tt stdwin.open()}.
XThere is no explicit function to close a window; windows are closed when
Xthey are garbage-collected.
XWindow objects have the following methods:
X\begin{description}
X\funcitem{begindrawing}{}
XReturns a drawing object, whose methods (described below) allow drawing
Xin the window.
X\funcitem{change}{rect}
XInvalidates the given rectangle; this may cause a draw event.
X\funcitem{gettitle}{}
XReturns the window's title string.
X\funcitem{getdocsize}{}
X\begin{sloppypar}
XReturns a pair of integers giving the size of the document as set by
X{\tt setdocsize()}.
X\end{sloppypar}
X\funcitem{getorigin}{}
XReturns a pair of integers giving the origin of the window with respect
Xto the document.
X\funcitem{getwinsize}{}
XReturns a pair of integers giving the size of the window.
X\funcitem{menucreate}{title}
XCreates a menu object referring to a local menu (a menu that appears
Xonly in this window).
XMethods menu objects are described below.
X\funcitem{scroll}{rect,~point}
XScrolls the given rectangle by the vector given by the point.
X\funcitem{setwincursor}{name}
X\begin{sloppypar}
XSets the window cursor to a cursor of the given name.
XIt raises the
X{\tt Runtime\-Error}
Xexception if no cursor of the given name exists.
XSuitable names are
X{\tt 'ibeam'},
X{\tt 'arrow'},
X{\tt 'cross'},
X{\tt 'watch'}
Xand
X{\tt 'plus'}.
XOn X11, there are many more (see
X{\tt <X11/cursorfont.h>}).
X\end{sloppypar}
X\funcitem{setdocsize}{point}
XSets the size of the drawing document.
X\funcitem{setorigin}{point}
XMoves the origin of the window to the given point in the document.
X\funcitem{setselection}{i, str}
XAttempts to set X11 selection number
X{\tt i}
Xto the string
X{\tt str}.
X(See stdwin method
X{\tt getselection()}
Xfor the meaning of
X{\tt i}.)
XReturns true if it succeeds.
XIf it succeeds, the window ``owns'' the selection until
X(a) another applications takes ownership of the selection; or
X(b) the window is deleted; or
X(c) the application clears ownership by calling
X{\tt stdwin.resetselection(i)}.
XWhen another application takes ownership of the selection, a
X{\tt WE\_LOST\_SEL}
Xevent is received for no particular window and with the selection number
Xas detail.
XIgnored on the Macintosh.
X\funcitem{settitle}{title}
XSets the window's title string.
X\funcitem{settimer}{dsecs}
XSchedules a timer event for the window in
X{\tt dsecs/10}
Xseconds.
X\funcitem{show}{rect}
XTries to ensure that the given rectangle of the document is visible in
Xthe window.
X\funcitem{textcreate}{rect}
XCreates a text-edit object in the document at the given rectangle.
XMethods of text-edit objects are described below.
X\end{description}
X
X\subsubsection{Drawing Object Methods}
X
XDrawing objects are created exclusively by the window method
X{\tt begindrawing()}.
XOnly one drawing object can exist at any given time; the drawing object
Xmust be deleted to finish drawing.
XNo drawing object may exist when
X{\tt stdwin.getevent()}
Xis called.
XDrawing objects have the following methods:
X\begin{description}
X\funcitem{box}{rect}
XDraws a box around a rectangle.
X\funcitem{circle}{center, radius}
X%.br
XDraws a circle with given center point and radius.
X\funcitem{elarc(center, (rh, rv), }{a1, a2)}
X%.br
XDraws an elliptical arc with given center point.
X{\tt (rh, rv)}
Xgives the half sizes of the horizontal and vertical radii.
X{\tt (a1, a2)}
Xgives the angles (in degrees) of the begin and end points.
X0 degrees is at 3 o'clock, 90 degrees is at 12 o'clock.
X\funcitem{erase}{rect}
XErases a rectangle.
X\funcitem{invert}{rect}
XInverts a rectangle.
X\funcitem{line}{p1, p2}
XDraws a line from point
X{\tt p1}
Xto
X{\tt p2}.
X\funcitem{paint}{rect}
XFills a rectangle.
X\funcitem{text}{p, str}
XDraws a string starting at point p (the point specifies the
Xtop left coordinate of the string).
X\funcitem{shade}{rect, percent}
X%.br
XFills a rectangle with a shading pattern that is about
X{\tt percent}
Xpercent filled.
X\funcitem{xorline}{p1, p2}
XDraws a line in XOR mode.
X\funcitem{baseline(), lineheight(), textbreak(), textwidth}{}
X%.br
XThese functions are similar to the corresponding functions described
Xabove for the
X{\tt stdwin}
Xmodule, but use the current font of the window instead of the (global)
Xdefault font.
X\end{description}
X
X\subsubsection{Menu Object Methods}
X
XA menu object represents a menu.
XThe menu is destroyed when the menu object is deleted.
XThe following methods are defined:
X\begin{description}
X\funcitem{additem}{text, shortcut}
X%.br
XAdds a menu item with given text.
XThe shortcut must be a string of length 1, or omitted (to specify no
Xshortcut).
X\funcitem{setitem}{i, text}
XSets the text of item number
X{\tt i}.
X\funcitem{enable}{i, flag}
XEnables or disables item
X{\tt i}.
X\funcitem{check}{i, flag}
XSets or clears the
X{\em check mark}
Xfor item
X{\tt i}.
X\end{description}
X
X\subsubsection{Text-edit Object Methods}
X
XA text-edit object represents a text-edit block.
XFor semantics, see the STDWIN documentation for C programmers.
XThe following methods exist:
X\begin{description}
X\funcitem{arrow}{code}
XPasses an arrow event to the text-edit block.
XThe
X{\tt code}
Xmust be one of
X{\tt WC\_LEFT},
X{\tt WC\_RIGHT},
X{\tt WC\_UP}
Xor
X{\tt WC\_DOWN}
X(see module
X{\tt stdwinevents}).
X\funcitem{draw}{rect}
XPasses a draw event to the text-edit block.
XThe rectangle specifies the redraw area.
X\funcitem{event}{type, window, detail}
X%.br
XPasses an event gotten from
X{\tt stdwin.getevent()}
Xto the text-edit block.
XReturns true if the event was handled.
X\funcitem{getfocus}{}
XReturns 2 integers representing the start and end positions of the
Xfocus, usable as slice indices on the string returned by
X{\tt getfocustext()}.
X\funcitem{getfocustext}{}
XReturns the text in the focus.
X\funcitem{getrect}{}
XReturns a rectangle giving the actual position of the text-edit block.
X(The bottom coordinate may differ from the initial position because
Xthe block automatically shrinks or grows to fit.)
X\funcitem{gettext}{}
XReturns the entire text buffer.
X\funcitem{move}{rect}
XSpecifies a new position for the text-edit block in the document.
X\funcitem{replace}{str}
XReplaces the focus by the given string.
XThe new focus is an insert point at the end of the string.
X\funcitem{setfocus}{i,~j}
XSpecifies the new focus.
XOut-of-bounds values are silently clipped.
X\end{description}
X
X\subsubsection{Example}
X
XHere is a simple example of using STDWIN in Python.
XIt creates a window and draws the string ``Hello world'' in the top
Xleft corner of the window.
XThe window will be correctly redrawn when covered and re-exposed.
XThe program quits when the close icon or menu item is requested.
X\bcode\begin{verbatim}
Ximport stdwin
Xfrom stdwinevents import *
X
Xdef main():
X    mywin = stdwin.open('Hello')
X    #
X    while 1:
X        (type, win, detail) = stdwin.getevent()
X        if type = WE_DRAW:
X            draw = win.begindrawing()
X            draw.text((0, 0), 'Hello, world')
X            del draw
X        elif type = WE_CLOSE:
X            break
X
Xmain()
X\end{verbatim}\ecode
X
X\subsection{Built-in Module {\tt amoeba}}
X
XThis module provides some object types and operations useful for
XAmoeba applications.
XIt is only available on systems that support Amoeba operations.
XRPC errors and other Amoeba errors are reported as the exception
X{\tt amoeba.error = 'amoeba.error'}.
XThe module
X{\tt amoeba}
Xdefines the following items:
X\begin{description}
X\funcitem{name\_append}{path,~cap}
X%.br
XStores a capability in the Amoeba directory tree.
XArguments are the pathname (a string) and the capability (a capability
Xobject as returned by
X{\tt name\_lookup()}).
X\funcitem{name\_delete}{path}
X%.br
XDeletes a capability from the Amoeba directory tree.
XArgument is the pathname.
X\funcitem{name\_lookup}{path}
X%.br
XLooks up a capability.
XArgument is the pathname.
XReturns a
X{\em capability}
Xobject, to which various interesting operations apply, described below.
X\funcitem{name\_replace}{path,~cap}
X%.br
XReplaces a capability in the Amoeba directory tree.
XArguments are the pathname and the new capability.
X(This differs from
X{\tt name\_append()}
Xin the behavior when the pathname already exists:
X{\tt name\_append()}
Xfinds this an error while
X{\tt name\_replace()}
Xallows it, as its name suggests.)
X\funcitem{capv}
XA table representing the capability environment at the time the
Xinterpreter was started.
X(Alas, modifying this table does not affect the capability environment
Xof the interpreter.)
XFor example,
X{\tt amoeba.capv['ROOT']}
Xis the capability of your root directory, similar to
X{\tt getcap("ROOT")}
Xin C.
X\excitem{error}{amoeba.error}
X%.br
XThe exception raised when an Amoeba function returns an error.
XThe value accompanying this exception is a pair containing the numeric
Xerror code and the corresponding string, as returned by the C function
X{\tt err\_why()}.
X\funcitem{timeout}{msecs}
X%.br
XSets the transaction timeout, in milliseconds.
XReturns the previous timeout.
XInitially, the timeout is set to 2 seconds by the {\Python} interpreter.
X\end{description}
X
X\subsubsection{Capability Operations}
X
XCapabilities are written in a convenient ASCII format, also used by the
XAmoeba utilities
X{\em c2a}(U)
Xand
X{\em a2c}(U).
XFor example:
X\bcode\begin{verbatim}
X>>> amoeba.name_lookup('/profile/cap')
Xaa:1c:95:52:6a:fa/14(ff)/8e:ba:5b:8:11:1a
X>>> 
X\end{verbatim}\ecode
XThe following methods are defined for capability objects.
X\begin{description}
X\funcitem{dir\_list}{}
XReturns a list of the names of the entries in an Amoeba directory.
X\funcitem{b\_read}{offset, maxsize}
X%.br
XReads (at most)
X{\tt maxsize}
Xbytes from a bullet file at offset
X{\tt offset.}
XThe data is returned as a string.
XEOF is reported as an empty string.
X\funcitem{b\_size}{}
XReturns the size of a bullet file.
X\funcitem{dir\_append(), dir\_delete(), dir\_lookup(), dir\_replace}{}
X%.br
X\itembreak
XLike the corresponding
X{\tt name\_*}
Xfunctions, but with a path relative to the capability.
X(For paths beginning with a slash the capability is ignored, since this
Xis the defined semantics for Amoeba.)
X\funcitem{std\_info}{}
XReturns the standard info string of the object.
X\funcitem{tod\_gettime}{}
XReturns the time (in seconds since the Epoch, in UCT, as for POSIX) from
Xa time server.
X\funcitem{tod\_settime}{t}
XSets the time kept by a time server.
X\end{description}
X
X\subsection{Built-in Module {\tt audio}}
X
XThis module provides rudimentary access to the audio I/O device
X{\tt /dev/audio}
Xon the Silicon Graphics Personal IRIS; see audio(7).
XIt supports the following operations:
X\begin{description}
X\funcitem{setoutgain}{n}
XSets the output gain (0-255).
X\funcitem{getoutgain}{}
XReturns the output gain.
X\funcitem{setrate}{n}
XSets the sampling rate: 1=32K/sec, 2=16K/sec, 3=8K/sec.
X\funcitem{setduration}{n}
XSets the `sound duration' in units of 1/100 seconds.
X\funcitem{read}{n}
XReads a chunk of
X{\tt n}
Xsampled bytes from the audio input (line in or microphone).
XThe chunk is returned as a string of length n.
XEach byte encodes one sample as a signed 8-bit quantity using linear
Xencoding.
XThis string can be converted to numbers using {\tt chr2num()} described
Xbelow.
X\funcitem{write}{buf}
XWrites a chunk of samples to the audio output (speaker).
X\end{description}
X
XThese operations support asynchronous audio I/O:
X\begin{description}
X\funcitem{start\_recording}{n}
X%.br
XStarts a second thread (a process with shared memory) that begins reading
X{\tt n}
Xbytes from the audio device.
XThe main thread immediately continues.
X\funcitem{wait\_recording}{}
X%.br
XWaits for the second thread to finish and returns the data read.
X\funcitem{stop\_recording}{}
X%.br
XMakes the second thread stop reading as soon as possible.
XReturns the data read so far.
X\funcitem{poll\_recording}{}
X%.br
XReturns true if the second thread has finished reading (so
X{\tt wait\_recording()} would return the data without delay).
X\item[{\tt start\_playing(chunk)}, {\tt wait\_playing()},
X{\tt stop\_playing()}, {\tt poll\_playing()}]
X%.br
X\begin{sloppypar}
XSimilar but for output.
X{\tt stop\_playing()}
Xreturns a lower bound for the number of bytes actually played (not very
Xaccurate).
X\end{sloppypar}
X\end{description}
X
XThe following operations do not affect the audio device but are
Ximplemented in C for efficiency:
X\begin{description}
X\funcitem{amplify}{buf, f1, f2}
X%.br
XAmplifies a chunk of samples by a variable factor changing from
X{\tt f1}/256 to {\tt f2}/256.
XNegative factors are allowed.
XResulting values that are to large to fit in a byte are clipped.         
X\funcitem{reverse}{buf}
X%.br
XReturns a chunk of samples backwards.
X\funcitem{add}{buf1, buf2}
X%.br
XBytewise adds two chunks of samples.
XBytes that exceed the range are clipped.
XIf one buffer shorter, it is assumed to be padded with zeros.
X\funcitem{chr2num}{buf}
X%.br
XConverts a string of sampled bytes as returned by {\tt read()} into
Xa list containing the numeric values of the samples.
X\funcitem{num2chr}{list}
X%.br
X\begin{sloppypar}
XConverts a list as returned by
X{\tt chr2num()}
Xback to a buffer acceptable by
X{\tt write()}.
X\end{sloppypar}
X\end{description}
X
X\subsection{Built-in Module {\tt gl}}
X
XThis module provides access to the Silicon Graphics
X{\em Graphics Library}.
XIt is available only on Silicon Graphics machines.
X
X{\bf Warning:}
XSome illegal calls to the GL library cause the {\Python} interpreter to dump
Xcore.
XIn particular, the use of most GL calls is unsafe before the first
Xwindow is opened.
X
XThe module is too large to document here in its entirety, but the
Xfollowing should help you to get started.
XThe parameter conventions for the C functions are translated to {\Python} as
Xfollows:
X
X\begin{itemize}
X\item
XAll (short, long, unsigned) int values are represented by {\Python}
Xintegers.
X\item
XAll float and double values are represented by {\Python} floating point
Xnumbers.
XIn most cases, {\Python} integers are also allowed.
X\item
XAll arrays are represented by one-dimensional {\Python} lists.
XIn most cases, tuples are also allowed.
X\item
X\begin{sloppypar}
XAll string and character arguments are represented by {\Python} strings,
Xfor instance,
X{\tt winopen('Hi~There!')}
Xand
X{\tt rotate(900,~'z')}.
X\end{sloppypar}
X\item
XAll (short, long, unsigned) integer arguments or return values that are
Xonly used to specify the length of an array argument are omitted.
XFor example, the C call
X\bcode\begin{verbatim}
Xlmdef(deftype, index, np, props)
X\end{verbatim}\ecode
Xis translated to {\Python} as
X\bcode\begin{verbatim}
Xlmdef(deftype, index, props)
X\end{verbatim}\ecode
X\item
XOutput arguments are omitted from the argument list; they are
Xtransmitted as function return values instead.
XIf more than one value must be returned, the return value is a tuple.
XIf the C function has both a regular return value (that is not omitted
Xbecause of the previous rule) and an output argument, the return value
Xcomes first in the tuple.
XExamples: the C call
X\bcode\begin{verbatim}
Xgetmcolor(i, &red, &green, &blue)
X\end{verbatim}\ecode
Xis translated to {\Python} as
X\bcode\begin{verbatim}
Xred, green, blue = getmcolor(i)
X\end{verbatim}\ecode
X\end{itemize}
X
XThe following functions are non-standard or have special argument
Xconventions:
X\begin{description}
X\funcitem{varray}{}
XEquivalent to but faster than a number of
X{\tt v3d()}
Xcalls.
XThe argument is a list (or tuple) of points.
XEach point must be a tuple of coordinates (x, y, z) or (x, y).
XThe points may be 2- or 3-dimensional but must all have the
Xsame dimension.
XFloat and int values may be mixed however.
XThe points are always converted to 3D double precision points
Xby assuming z=0.0 if necessary (as indicated in the man page),
Xand for each point
X{\tt v3d()}
Xis called.
X\funcitem{nvarray}{}
XEquivalent to but faster than a number of
X{\tt n3f}
Xand
X{\tt v3f}
Xcalls.
XThe argument is an array (list or tuple) of pairs of normals and points.
XEach pair is a tuple of a point and a normal for that point.
XEach point or normal must be a tuple of coordinates (x, y, z).
XThree coordinates must be given.
XFloat and int values may be mixed.
XFor each pair,
X{\tt n3f()}
Xis called for the normal, and then
X{\tt v3f()}
Xis called for the point.
X\funcitem{vnarray}{}
XSimilar to 
X{\tt nvarray()}
Xbut the pairs have the point first and the normal second.
X\funcitem{nurbssurface}{s\_k[], t\_k[], ctl[][], s\_ord, t\_ord, type}
X%.br
X\itembreak
XDefines a nurbs surface.
XThe dimensions of
X{\tt ctl[][]}
Xare computed as follows:
X{\tt [len(s\_k)~-~s\_ord]},
X{\tt [len(t\_k)~-~t\_ord]}.
X\funcitem{nurbscurve}{knots, ctlpoints, order, type}
X%.br
XDefines a nurbs curve.
XThe length of ctlpoints is
X{\tt len(knots)~-~order}.
X\funcitem{pwlcurve}{points, type}
X%.br
XDefines a piecewise-linear curve.
X{\tt points}
Xis a list of points.
X{\tt type}
Xmust be
X{\tt N\_ST}.
X\funcitem{pick(n), select}{n}
X%.br
XThe only argument to these functions specifies the desired size of the
Xpick or select buffer.
X\funcitem{endpick(), endselect}{}
X%.br
XThese functions have no arguments.
XThey return a list of integers representing the used part of the
Xpick/select buffer.
XNo method is provided to detect buffer overrun.
X\end{description}
X
XHere is a tiny but complete example GL program in {\Python}:
X\bcode\begin{verbatim}
Ximport gl, GL, time
X
Xdef main():
X    gl.foreground()
X    gl.prefposition(500, 900, 500, 900)
X    w = gl.winopen('CrissCross')
X    gl.ortho2(0.0, 400.0, 0.0, 400.0)
X    gl.color(GL.WHITE)
X    gl.clear()
X    gl.color(GL.RED)
X    gl.bgnline()
X    gl.v2f(0.0, 0.0)
X    gl.v2f(400.0, 400.0)
X    gl.endline()
X    gl.bgnline()
X    gl.v2f(400.0, 0.0)
X    gl.v2f(0.0, 400.0)
X    gl.endline()
X    time.sleep(5)
X
Xmain()
X\end{verbatim}\ecode
X
X\subsection{Built-in Module {\tt pnl}}
X
XThis module provides access to the
X{\em Panel Library}
Xbuilt by NASA Ames (to get it, send e-mail to
X{\tt panel-request@nas.nasa.gov}).
XAll access to it should be done through the standard module
X{\tt panel},
Xwhich transparantly exports most functions from
X{\tt pnl}
Xbut redefines
X{\tt pnl.dopanel()}.
X
X{\bf Warning:}
Xthe {\Python} interpreter will dump core if you don't create a GL window
Xbefore calling
X{\tt pnl.mkpanel()}.
X
XThe module is too large to document here in its entirety.
EOF
fi
if test -s 'src/sc_interpr.c'
then echo '*** I will not over-write existing file src/sc_interpr.c'
else
echo 'x - src/sc_interpr.c'
sed 's/^X//' > 'src/sc_interpr.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#if 0
X#define STACK_TRACE
X#define SCDEBUG
X#endif
X#include <stdio.h>
X
X#include <ailamoeba.h>
X
X#include "PROTO.h"
X#include "sc_global.h"
X#include "object.h"
X#include "objimpl.h"
X#include "stringobject.h"
X#include "errors.h"
X#include "sc_errors.h"
X#include "stubcode.h"
X#include "tupleobject.h"
X#include "intobject.h"
X#include "listobject.h"
X
Xtypedef struct s_loopstruct {
X	struct s_loopstruct	*l_next;	/* Make a list of it      */
X	TscOperand		l_label;	/* Indentify the loop     */
X	int			l_index;	/* The index of the list  */
X	int			l_size;		/* The size of the list   */
X	int			l_retaddr;	/* Addres to jump back    */
X	int			l_endaddr;	/* Addres to jump to end  */
X	object			*l_list;	/* The list to append to  */
X} TsLoop, *TpsLoop;
X
X
X/*
X**	This file contains the Stubcode interpreter.
X**	All the instructions have there own function. The interpreter
X**	reads an instruction from the data and if needed also an operand.
X**	After this it calls the function that executes the instruction.
X*/
X
Xstruct sc_ProcessBlock {
X	object 		**stack;
X	unsigned char	*buffer, *data;
X	int 		sp, bp, pc, maxbufsize, datsize;
X	header 		hdr;
X	TpsLoop		loops;
X};
X
Xextern getcapability();
X
X/*
X *	 Clean up the mess the loops make.
X */
X
Xstatic void
XxCleanUpLoops(sc_pb)
X	struct sc_ProcessBlock *sc_pb;
X{
X	TpsLoop prev, this;
X
X	if (sc_pb->loops == NULL)
X		return;
X	prev = sc_pb->loops;
X	this = sc_pb->loops->l_next;
X	while(this) {
X		free((char *)prev);
X		prev = this;
X		this = this->l_next;
X	}
X	free((char *)prev);
X}
X
Xstatic int
Xfindendloop(label, sc_pb)
X	TscOperand label;
X	struct sc_ProcessBlock *sc_pb;
X{
X	TscOperand operand;
X	TscOpcode opcode;
X	int walk = sc_pb->pc, found = 0;
X
X	while (!found && (walk < sc_pb->datsize)) {
X		memcpy(&opcode, &sc_pb->data[walk], sizeof(TscOpcode));
X		walk += sizeof(TscOpcode);
X		if (opcode & (FLAGS | OPERAND)) {
X			memcpy(&operand, &sc_pb->data[walk], sizeof(TscOperand));
X			walk += sizeof(TscOperand);
X		}
X		if (opcode == EndLoop)
X			if (operand == label) found = 1;
X	}
X	if (found)
X		return walk;
X	return -1;
X}
X
Xstatic int
Xfindloop(ret, label, sc_pb)
X	TpsLoop *ret;
X	TscOperand label;
X	struct sc_ProcessBlock *sc_pb;
X{
X	TpsLoop walk;
X
X	for (walk = sc_pb->loops; walk != NULL; walk = walk->l_next) {
X		if (walk->l_label == label) break;
X	}
X	if (walk == NULL) {
X		TpsLoop newloop;
X
X		newloop = (TpsLoop)malloc(sizeof(TsLoop));
X		if (newloop == NULL) {
X			err_nomem();
X			return -1;
X		}
X		newloop->l_label = label;
X		newloop->l_index = 0;
X		newloop->l_retaddr = sc_pb->pc - (sizeof(TscOpcode) + sizeof(TscOperand));
X		/*
X		**	 We need a correction because the pc points to
X		**	 the instruction after the XXXLoop.
X		*/
X		if ((newloop->l_endaddr = findendloop(label, sc_pb)) < 0) {
X			free((char *)newloop);
X			err_scerr(NoEndLoop);
X			return -1;
X		}
X		newloop->l_list = NULL;
X		newloop->l_next = sc_pb->loops;
X		sc_pb->loops = newloop;
X		*ret = newloop;
X		return 1;
X	}
X	*ret = walk;
X	return 0;
X}
X
X#ifdef 0
X
Xstatic void
Xremoveloop(this, sc_pb)
X	TpsLoop this;
X	struct sc_ProcessBlock *sc_pb;
X{
X	TpsLoop walk, prev = NULL;
X
X	for (walk = sc_pb->loops; walk != NULL; walk = walk->l_next) {
X		if (walk->l_label == this->l_label) {
X			if (prev != NULL) {
X				prev->l_next = walk->l_next;
X			} else {
X				loop = walk->l_next;
X			}
X			free((char *)this);
X			break;
X		}
X		prev = walk;
X	}
X}
X
X#endif
X
Xstatic int
Xinit(self, sc_pb)
X	object *self;
X	struct sc_ProcessBlock *sc_pb;
X{
Xobject *string;
Xint datasize;
X
X	string = gettupleitem(self, STUBC);
X	if (string == NULL)
X		return -1;
X	sc_pb->data = getstringvalue(string);
X	if (sc_pb->data == NULL)
X		return -1;
X	datasize = (int)getstringsize(string);
X	if (datasize == -1)
X		return -1;
X	sc_pb->stack = (object **)malloc(STKSIZE * sizeof(object *));
X	if (sc_pb->stack == NULL) {
X		err_nomem();
X		return -1;
X	}
X	sc_pb->bp = sc_pb->sp = sc_pb->pc = 0;
X	sc_pb->loops = NULL;
X	return datasize;
X}
X
Xstatic void reinit(sc_pb)
X	struct sc_ProcessBlock *sc_pb;
X{
X	int i;
X
X	sc_pb->bp = 0;
X	for (i = 0; i < sc_pb->sp; i++) {
X		DECREF(sc_pb->stack[i]);
X	}
X	sc_pb->sp = 0;
X}
X
Xstatic void UnInit(self, sc_pb)
X	object *self;
X	struct sc_ProcessBlock *sc_pb;
X{
X	int i;
X
X	free(sc_pb->buffer);
X	reinit(sc_pb);
X	free((char *)sc_pb->stack);
X	xCleanUpLoops(sc_pb);
X}
X
Xstatic object *
Xstacktop(sc_pb)
X	struct sc_ProcessBlock *sc_pb;
X{
X
X	if (sc_pb->sp == 0)
X		return err_scerr(StackUnderflow);
X	if (sc_pb->sp == (STKSIZE + 1))
X		return err_scerr(StackOverflow);
X	return sc_pb->stack[sc_pb->sp - 1];
X}
X
X/*
X *	 Push an object on the stack.
X */
Xstatic int
XxPush(element, sc_pb)
X	object *element;
X	struct sc_ProcessBlock *sc_pb;
X{
X
X	if (sc_pb->sp >= STKSIZE) {
X		err_scerr(StackOverflow);
X		return -1;
X	}
X	if (element == NULL) {
X		err_scerr(ElementIsNull);
X		return -1;
X	}
X	INCREF(element);
X#ifdef STACK_TRACE
X	printf("pushed :");
X	printobject(element, stdout, 0);
X	printf("\n");
X#endif
X	sc_pb->stack[sc_pb->sp++] = element;
X	return 0;
X}
X
X/*
X *	 Perform the RPC.
X */
Xstatic int
XxTrans(self,cmd, sc_pb)
X	object *self;
X	TscOperand cmd;
X	struct sc_ProcessBlock *sc_pb;
X{
X	short ret;
X	capability cap;
X	object *capobj;
X
X	if ((capobj = gettupleitem(self, CAP)) == NULL)
X		return -1;
X	if (getcapability(capobj, &cap) == -1)
X		return -1;
X	sc_pb->hdr.h_port = cap.cap_port;
X	sc_pb->hdr.h_priv = cap.cap_priv;
X	sc_pb->hdr.h_command = (command)cmd;
X#ifdef SCDEBUG
X	printf("bp = %d maxbufsize = %d\n",sc_pb->bp, sc_pb->maxbufsize);
X	{
X		int i;
X
X		for (i = 0; i < sc_pb->bp; i++) {
X			printf("%x ", sc_pb->buffer[i]);
X		}
X	}
X	printf("\n");
X#endif
X	ret = trans(&sc_pb->hdr, sc_pb->buffer, (bufsize) sc_pb->bp, 
X		&sc_pb->hdr, sc_pb->buffer, (bufsize)sc_pb->maxbufsize);
X#ifdef SCDEBUG
X	printf("after Trans:ret = %d\n",ret);
X	{
X		int i;
X
X		for (i = 0; i < ret; i++) {
X			printf("%x ", sc_pb->buffer[i]);
X		}
X	}
X	printf("\n");
X#endif
X	if (ERR_STATUS(ret)) {
X		amoeba_error(ERR_CONVERT(ret));
X		return -1;
X	}
X	if (sc_pb->hdr.h_status != 0) {
X		object *v;
X
X		if ((v = newintobject(sc_pb->hdr.h_status)) == NULL)
X			return -1;
X		err_scerrset(TransError, v, "Trans");
X		DECREF(v);
X		return -1;
X	}
X	reinit(sc_pb);
X	return 0;
X}
X
X/*
X *	 Test the tuple size.
X */
Xstatic int
XxTTupleS(size, sc_pb)
X	TscOperand size;
X	struct sc_ProcessBlock *sc_pb;
X{
X	object *tuple;
X
X	if ((tuple = stacktop(sc_pb)) == NULL)
X		return -1;
X	if (!is_tupleobject(tuple))
X		return err_scerrset(TypeFailure, tuple, "TTupleS");
X	if (gettuplesize(tuple) != (unsigned int)size)
X		return err_scerrset(SizeError, tuple, "TTupleS");
X	return 0;
X}
X
X/*
X *	 Unpack a tuple
X */
Xstatic int
XxUnpack(size, sc_pb)
X	TscOperand size;
X	struct sc_ProcessBlock *sc_pb;
X{
X	object *tuple, *element;
X	int i;
X
X	if (size < (TscOperand)2) {
X		element = newintobject(size);
X		if (element == NULL) 
X			return -1;
X		return err_scerrset(SizeError, element, "Unpack");
X	}
X	if ((tuple = stacktop(sc_pb)) == NULL)
X		return -1;
X	INCREF(tuple);
X	if (xPop((TscOperand) 1, sc_pb) != 0) {
X		DECREF(tuple);
X		return -1;
X	}
X	for (i = 0; i < (int)size; i++) {
X		if ((element = gettupleitem(tuple, i)) == NULL) {
X			DECREF(tuple);
X			return -1;
X		}
X		if (xPush(element, sc_pb) != 0) {
X			DECREF(tuple);
X			return -1;
X		}
X	}
X	DECREF(tuple);
X	return 0;
X}
X
X/*
X *	 Marshal the Ailword to a headerfiels.
X */
Xstatic int
XxAilword(headerfield, sc_pb)
X	TscOperand headerfield;
X	struct sc_ProcessBlock *sc_pb;
X{
X
X	switch(headerfield) {
X	
X	case H_EXTRA:
X		sc_pb->hdr.h_extra = (uint16)_ailword;
X		return 0;
X	
X	case H_SIZE:
X		sc_pb->hdr.h_size = (bufsize)_ailword;
X		return 0;
X	
X	case H_OFFSET:
X		sc_pb->hdr.h_offset = (int32)_ailword;
X		return 0;
X	
X	default:
X		{
X			object *v;
X
X			if ((v = newintobject(headerfield)) == NULL)
X				return -1;
X			return err_scerrset(FlagError, v, "Ailword");
X		}
X	}
X}
X
Xstatic int
XxStringS(sc_pb)
X	struct sc_ProcessBlock *sc_pb;
X{
X	object *size, *string;
X	int s;
X
X	if ((string = stacktop(sc_pb)) == NULL)
X		return -1;
X	if (!is_stringobject(string))
X		return err_scerrset(TypeFailure, string, "StringS");
X	if ((s = getstringsize(string)) < 0)
X		return -1;
X	if (xPop((TscOperand) 1, sc_pb) != 0)
X		return -1;
X	if ((size = newintobject(s)) == NULL)
X		return -1;
X	if (xPush(size, sc_pb) != 0) {
X		DECREF(size);
X		return -1;
X	}
X	DECREF(size);
X	return 0;
X}
X
X/*
X *
X */
Xstatic int
XxListS(sc_pb)
X	struct sc_ProcessBlock *sc_pb;
X{
X	object *size, *list;
X	int s;
X
X	if ((list = stacktop(sc_pb)) == NULL)
X		return -1;
X	if (!is_listobject(list))
X		return err_scerrset(TypeFailure, list, "ListS");
X	if ((s = getlistsize(list)) < 0)
X		return -1;
X	if (xPop((TscOperand) 1, sc_pb) != 0)
X		return -1;
X	if ((size = newintobject(s)) == NULL)
X		return -1;
X	if (xPush(size, sc_pb) != 0) {
X		DECREF(size);
X		return -1;
X	}
X	DECREF(size);
X	return 0;
X}
X
X/*
X * Marshal a fixed string to the buffer.
X */
Xstatic int
XxPutFS(size, sc_pb)
X	TscOperand size;
X	struct sc_ProcessBlock *sc_pb;
X{
X	object *string;
X	char *str;
X
X	if ((string = stacktop(sc_pb)) == NULL) {
X		return -1;
X	}
X	if (!is_stringobject(string))
X		return err_scerrset(TypeFailure, string, "PutFS");
X	if (getstringsize(string) != size)
X		return err_scerrset(SizeError, string, "PutFS");
X	if ((str = getstringvalue(string)) == NULL)
X		return -1;
X	if ((size + sc_pb->bp) > sc_pb->maxbufsize) {
X		err_scerr(BufferOverflow);
X		return -1;
X	}
X	memcpy(&sc_pb->buffer[sc_pb->bp], str, (int)size);
X	sc_pb->bp += size;
X	return xPop((TscOperand) 1, sc_pb);
X}
X
X
X/*
X *	 Test the size of a string or list
X */
Xstatic int
XxTStringSeq(size, sc_pb)
X	TscOperand size;
X	struct sc_ProcessBlock *sc_pb;
X{
X	object *string;
X
X	if ((string = stacktop(sc_pb)) == NULL)
X		return -1;
X	if (!is_stringobject(string))
X		return err_scerrset(TypeFailure, string, "TStringSeq");
X	if (getstringsize(string) != size)
X		return err_scerrset(SizeError, string, "TStringSeq");
X	return 0;
X}
X
Xstatic int
XxTStringSlt(size, sc_pb)
X	TscOperand size;
X	struct sc_ProcessBlock *sc_pb;
X{
X	object *string;
X
X	if ((string = stacktop(sc_pb)) == NULL)
X		return -1;
X	if (!is_stringobject(string))
X		return err_scerrset(TypeFailure, string, "TStringSlt");
X	if (getstringsize(string) > size)
X		return err_scerrset(SizeError, string, "TStringSlt");
X	return 0;
X}
X
Xstatic int
XxTListSeq(size, sc_pb)
X	TscOperand size;
X	struct sc_ProcessBlock *sc_pb;
X{
X	object *list;
X
X	if ((list = stacktop(sc_pb)) == NULL)
X		return -1;
X	if (!is_listobject(list))
X		return err_scerrset(TypeFailure, list, "TListSeq");
X	if (getlistsize(list) != size)
X		return err_scerrset(SizeError, list, "TListSeq");
X	return 0;
X}
X
Xstatic int
XxTListSlt(size, sc_pb)
X	TscOperand size;
X	struct sc_ProcessBlock *sc_pb;
X{
X	object *list;
X
X	if ((list = stacktop(sc_pb)) == NULL)
X		return -1;
X	if (!is_listobject(list))
X		return err_scerrset(TypeFailure, list, "TListSlt");
X	if (getlistsize(list) > size)
X		return err_scerrset(SizeError, list, "TListSlt");
X	return 0;
X}
X
Xstatic int
XxPutVS(sc_pb)
X	struct sc_ProcessBlock *sc_pb;
X{
X	object *string;
X	char *str;
X	int size;
X
X	if ((string = stacktop(sc_pb)) == NULL)
X		return -1;
X	if ((size = getstringsize(string)) < 0)
X		return (size == -1 ? -1 : err_scerrset(SizeError, string, "PutVS"));
X	if ((str = getstringvalue(string)) == NULL)
X		return -1;
X	if (sc_pb->bp + size > sc_pb->maxbufsize) {
X		err_scerr(BufferOverflow);
X		return -1;
X	}
X	memcpy(&sc_pb->buffer[sc_pb->bp], str, size);
X	sc_pb->bp += size;
X	return xPop((TscOperand) 1, sc_pb);
X}
X
X/*
X *	 The loop instructions.
X */
Xstatic int
XxLoopPut(label, sc_pb)
X	TscOperand label;
X	struct sc_ProcessBlock *sc_pb;
X{
X	TpsLoop this;
X	object *list, *element;
X
X	if (findloop(&this, label, sc_pb) < 0)
X		return -1;
X	if ((list = stacktop(sc_pb)) == NULL)
X		return -1;
X	if (!is_listobject(list))
X		return err_scerrset(TypeFailure, list, "LoopPut");
X	if (this->l_index >= getlistsize(list)) {
X		sc_pb->pc = this->l_endaddr;
X		/*
X		**	Pop the list from the stack
X		*/
X		return xPop((TscOperand)1, sc_pb);
X	}
X	if ((element = getlistitem(list, this->l_index)) == NULL)
X		return -1;
X	return xPush(element, sc_pb);
X}
X
Xstatic int
XxLoopGet(label, sc_pb)
X	TscOperand label;
X	struct sc_ProcessBlock *sc_pb;
X{
X	TpsLoop this;
X	object *element, *integer;
X	int i;
X
X	if ((i = findloop(&this, label, sc_pb)) < 0)
X		return -1;
X	else if (i == 1) {
X		/*
X		 *	 It is the first time we enter LoopGet label
X		 */
X		if ((this->l_list = newlistobject(0)) == NULL)
X			return -1;
X		if ((integer = stacktop(sc_pb)) == NULL)
X			return -1;
X		if (!is_intobject(integer))
X			return err_scerrset(TypeFailure, integer, "LoopGet");
X		this->l_size = getintvalue(integer);
X		if (xPop((TscOperand) 1, sc_pb) != 0)
X			return -1;
X	} else {
X		if ((element = stacktop(sc_pb)) == NULL)
X			return -1;
X		if (addlistitem(this->l_list, element) != 0)
X			return -1;
X		if (xPop((TscOperand) 1, sc_pb) != 0)
X			return -1;
X	}
X	if (this->l_index >= this->l_size) {
X		int ret;
X
X		sc_pb->pc = this->l_endaddr;
X		ret = xPush(this->l_list, sc_pb);
X		DECREF(this->l_list);
X		return ret;
X	}
X	return 0;
X}
X
Xstatic int
XxEndLoop(label, sc_pb)
X	TscOperand label;
X	struct sc_ProcessBlock *sc_pb;
X{
X	TpsLoop this;
X
X	if (findloop(&this, label, sc_pb) < 0)
X		return -1;
X	this ->l_index += 1;
X	sc_pb->pc = this->l_retaddr;
X	return 0;
X}
X
Xstatic int
XxPutI(flags, sc_pb)
X	TscOperand flags;
X	struct sc_ProcessBlock *sc_pb;
X{
X	object *integer;
X
X	if ((integer = stacktop(sc_pb)) == NULL)
X		return -1;
X	if (!is_intobject(integer))
X		return err_scerrset(TypeFailure, integer, "PutI");
X	if (flags & ALL_FIELDS) {
X		long i;
X
X		/*
X		 *	 The integer must be marshalles in the header.
X		 *	 No type casting according to the type flag because
X		 *	 we have to cast to the headerfield types.
X		 */
X		i = getintvalue(integer);
X		switch(flags & ALL_FIELDS) {
X		
X		case H_EXTRA:
X			sc_pb->hdr.h_extra = (uint16)i;
X			break;
X	
X		case H_SIZE:
X			sc_pb->hdr.h_size = (bufsize)i;
X			break;
X	
X		case H_OFFSET:
X			sc_pb->hdr.h_offset = (int32)i;
X			break;
X	
X		default:
X			if ((integer = newintobject(flags & ALL_FIELDS)) == NULL)
X				return -1;
X			err_scerrset(FlagError, integer, "Ailword");
X			DECREF(integer);
X			return -1;
X		}
X	} else {
X		long i;
X
X		i = getintvalue(integer);
X		switch(flags & ALLTYPES) {
X		
X		case 0:
X			{
X				int16 x;
X
X				x = (int16)i;
X				if ((sc_pb->bp + sizeof(int16)) > sc_pb->maxbufsize) {
X					err_scerr(BufferOverflow);
X					return -1;
X				}
X				memcpy(&sc_pb->buffer[sc_pb->bp], &x, sizeof(int16));
X				sc_pb->bp += sizeof(int16);
X				break;
X			}
X
X		case NOSIGN:
X			{
X				uint16 x;
X
X				x = (uint16)i;
X				if ((sc_pb->bp + sizeof(uint16)) > sc_pb->maxbufsize) {
X					err_scerr(BufferOverflow);
X					return -1;
X				}
X				memcpy(&sc_pb->buffer[sc_pb->bp], &x, sizeof(uint16));
X				sc_pb->bp += sizeof(uint16);
X				break;
X			}
X
X		case INT32:
X			{
X				int32 x;
X
X				x = (int32)i;
X				if ((sc_pb->bp + sizeof(int32)) > sc_pb->maxbufsize) {
X					err_scerr(BufferOverflow);
X					return -1;
X				}
X				memcpy(&sc_pb->buffer[sc_pb->bp], &x, sizeof(int32));
X				sc_pb->bp += sizeof(int32);
X				break;
X			}
X
X		case INT32 | NOSIGN:
X			{
X				uint32 x;
X
X				x = (uint32)i;
X				if ((sc_pb->bp + sizeof(uint32)) > sc_pb->maxbufsize) {
X					err_scerr(BufferOverflow);
X					return -1;
X				}
X				memcpy(&sc_pb->buffer[sc_pb->bp], &x, sizeof(uint32));
X				sc_pb->bp += sizeof(uint32);
X				break;
X			}
X		default:
X			{
X				object *x;
X
X				if ((x = newintobject(flags)) == NULL)
X					return -1;
X				err_scerrset(FlagError, x, "PutI");
X				DECREF(x);
X				return -1;
X			}
X		}
X	}
X	return xPop((TscOperand)1, sc_pb);
X}
X
Xstatic int
XxPutC(sc_pb)
X	struct sc_ProcessBlock *sc_pb;
X{
X	capability cap;
X	object *capobj;
X
X	if ((capobj = stacktop(sc_pb)) == NULL)
X		return -1;
X	if (!is_capobj(capobj))
X		return err_scerrset(TypeFailure, capobj, "xPutC");
X	if (getcapability(capobj, &cap) != 0)
X		return -1;
X	if ((sc_pb->bp + CAPSIZE) > sc_pb->maxbufsize) {
X		err_scerr(BufferOverflow);
X		return -1;
X	}
X	memcpy(&sc_pb->buffer[sc_pb->bp], &cap, CAPSIZE);
X	sc_pb->bp += CAPSIZE;
X	return xPop((TscOperand) 1, sc_pb);
X}
X
Xstatic int
XxDup(n, sc_pb)
X	TscOperand n;
X	struct sc_ProcessBlock *sc_pb;
X{
X
X	if ((int)n > sc_pb->sp) {
X		object *i;
X
X		if ((i = newintobject((long)n)) == NULL)
X			return -1;
X		err_scerrset(RangeError, i, "Dup");
X		DECREF(i);
X		return -1;
X	}
X	return xPush(sc_pb->stack[sc_pb->sp - n], sc_pb);
X}
X
Xstatic int
XxPop(n, sc_pb)
X	TscOperand n;
X	struct sc_ProcessBlock *sc_pb;
X{
X	int i;
X
X	if ((sc_pb->sp - (int)n) < 0) {
X		err_scerr(StackUnderflow);
X		return -1;
X	}
X	for (i = 0; i < (int)n; i++) {
X		sc_pb->sp--;
X#ifdef STACK_TRACE
X		printf("popped :");
X		printobject(sc_pb->stack[sc_pb->sp], stdout, 0);
X		printf("\n");
X#endif
X		DECREF(sc_pb->stack[sc_pb->sp]);
X	}
X	return 0;
X}
X
Xstatic int
XxAlign(n, sc_pb)
X	TscOperand n;
X	struct sc_ProcessBlock *sc_pb;
X{
X	int align = sc_pb->bp % (int)n;
X
X#ifdef SCDEBUG
X	printf("Old bp = %d\n", sc_pb->bp);
X#endif
X	sc_pb->bp += (align == 0) ? 0 : ((int)n - align);
X#ifdef SCDEBUG
X	printf("New bp = %d\n", sc_pb->bp);
X#endif
X	return 0;
X}
X
Xstatic int
XxPack(size, sc_pb)
X	TscOperand size;
X	struct sc_ProcessBlock *sc_pb;
X{
X	object *element, *tuple;
X	int i, ret;
X
X	if ((tuple = newtupleobject((int)size)) == NULL)
X		return -1;
X	for (i = 0; i < (int)size; i++) {
X		if ((element = stacktop(sc_pb)) == NULL)
X			return -1;
X		if (settupleitem(tuple, (int)size - i - 1, element) != 0)
X			return -1;
X		INCREF(element);
X		if (xPop((TscOperand) 1, sc_pb) != 0)
X			return -1;
X	}
X	ret = xPush(tuple, sc_pb);
X	DECREF(tuple);
X	return ret;
X}
X
Xstatic int
XxGetVS(sc_pb)
X	struct sc_ProcessBlock *sc_pb;
X{
X	object *string, *integer;
X	int size;
X
X	if ((integer = stacktop(sc_pb)) == NULL)
X		return -1;
X	if (!is_intobject(integer))
X		return err_scerrset(TypeFailure, integer, "GetVS");
X	size = getintvalue(integer);
X	if ((sc_pb->bp + size) > sc_pb->maxbufsize) {
X		err_scerr(BufferOverflow);
X		return -1;
X	}
X	if ((string = newsizedstringobject(&sc_pb->buffer[sc_pb->bp], size)) == NULL)
X		return -1;
X	sc_pb->bp += size;
X	if (xPop((TscOperand) 1, sc_pb) != 0)
X		return -1;
X	if (xPush(string, sc_pb) != 0) {
X		return -1;
X	}
X	DECREF(string);
X	return 0;
X}
X
Xstatic int
XxGetFS(size, sc_pb)
X	TscOperand size;
X	struct sc_ProcessBlock *sc_pb;
X{
X	object *string;
X
X	if ((sc_pb->bp + (int)size) > sc_pb->maxbufsize) {
X		err_scerr(BufferOverflow);
X		return -1;
X	}
X	if ((string = newsizedstringobject(&sc_pb->buffer[sc_pb->bp], (int)size)) == NULL)
X		return -1;
X	sc_pb->bp += (int)size;
X	if(xPush(string, sc_pb) != 0) {
X		return -1;
X	}
X	DECREF(string);
X	return 0;
X}
X
Xstatic int
XxGetI(flags, sc_pb)
X	TscOperand flags;
X	struct sc_ProcessBlock *sc_pb;
X{
X	object *integer;
X	long i;
X
X	if (flags & ALL_FIELDS) {
X
X		switch(flags & ALL_FIELDS) {
X		
X		case H_EXTRA:
X			i = (long)sc_pb->hdr.h_extra;
X			break;
X
X		case H_SIZE:
X			i = (long)sc_pb->hdr.h_size;
X			break;
X	
X		case H_OFFSET:
X			i = (long)sc_pb->hdr.h_offset;
X			break;
X	
X		default:
X			if ((integer = newintobject(flags & ALL_FIELDS)) == NULL)
X				return -1;
X			err_scerrset(FlagError, integer, "Ailword");
X			DECREF(integer);
X			return -1;
X		}
X	} else {
X		switch(flags & ALLTYPES) {
X		
X		case 0:
X			{
X				int16 x;
X
X				if ((sc_pb->bp + sizeof(int16)) > sc_pb->maxbufsize) {
X					err_scerr(BufferOverflow);
X					return -1;
X				}
X				memcpy(&x, &sc_pb->buffer[sc_pb->bp], sizeof(int16));
X				sc_pb->bp += sizeof(int16);
X				i = (long)x;
X				break;
X			}
X
X		case NOSIGN:
X			{
X				uint16 x;
X
X				if ((sc_pb->bp + sizeof(uint16)) > sc_pb->maxbufsize) {
X					err_scerr(BufferOverflow);
X					return -1;
X				}
X				memcpy(&x, &sc_pb->buffer[sc_pb->bp], sizeof(uint16));
X				sc_pb->bp += sizeof(uint16);
X				i = (long)x;
X				break;
X			}
X
X		case INT32:
X			{
X				int32 x;
X
X				if ((sc_pb->bp + sizeof(int32)) > sc_pb->maxbufsize) {
X					err_scerr(BufferOverflow);
X					return -1;
X				}
X				memcpy(&x, &sc_pb->buffer[sc_pb->bp], sizeof(int32));
X				sc_pb->bp += sizeof(int32);
X				i = (long)x;
X				break;
X			}
X
X		case INT32 | NOSIGN:
X			{
X				uint32 x;
X
X				if ((sc_pb->bp + sizeof(uint32)) > sc_pb->maxbufsize) {
X					err_scerr(BufferOverflow);
X					return -1;
X				}
X				memcpy(&x, &sc_pb->buffer[sc_pb->bp], sizeof(uint32));
X				sc_pb->bp += sizeof(uint32);
X				i = (long)x;
X				break;
X			}
X		default:
X			{
X				if ((integer = newintobject(flags)) == NULL)
X					return -1;
X				err_scerrset(FlagError, integer, "GetI");
X				DECREF(integer);
X				return -1;
X			}
X		}
X	}
X	if ((integer = newintobject(i)) == NULL)
X		return -1;
X	if (xPush(integer, sc_pb) != 0) {
X		DECREF(integer);
X		return -1;
X	}
X	DECREF(integer);
X	return 0;
X}
X
Xstatic int
XxGetC(flags, sc_pb)
X	TscOperand flags;
X	struct sc_ProcessBlock *sc_pb;
X{
X	extern object *newcapobject();
X	object *capobj;
X	capability cap;
X
X	if ((int)flags != 0) {
X		switch ((int)flags) {
X		
X		case PSEUDOFIELD:
X			cap.cap_port = sc_pb->hdr.h_port;
X			cap.cap_priv = sc_pb->hdr.h_priv;
X			break;
X		}
X	} else {
X		if ((CAPSIZE + sc_pb->bp) > sc_pb->maxbufsize) {
X			err_scerr(BufferOverflow);
X			return -1;
X		}
X		memcpy(&cap, &sc_pb->buffer[sc_pb->bp], CAPSIZE);
X	}
X	if ((capobj = newcapobject(&cap)) == NULL)
X		return -1;
X	return xPush(capobj, sc_pb);
X}
X
Xstatic int
XxEqual(sc_pb)
X	struct sc_ProcessBlock *sc_pb;
X{
X	object *int1, *int2;
X
X	if (sc_pb->sp < 2) {
X		err_scerr(StackUnderflow);
X		return -1;
X	}
X	int1 = sc_pb->stack[sc_pb->sp - 1];
X	int2 = sc_pb->stack[sc_pb->sp - 2];
X	if ((int1 == NULL) || (int2 == NULL))
X		return -1;
X	if (!is_intobject(int1))
X		return err_scerrset(TypeFailure, int1, "Equal");
X	if (!is_intobject(int2))
X		return err_scerrset(TypeFailure, int2, "Equal");
X	if (getintvalue(int1) != getintvalue(int2)) {
X		object *tmptuple;
X
X		if ((tmptuple = newtupleobject(2)) == NULL)
X			return -1;
X		INCREF(int1);
X		if (settupleitem(tmptuple, 0, int1) != 0) {
X			DECREF(tmptuple);
X			DECREF(int1);
X			return -1;
X		}
X		if (settupleitem(tmptuple, 1, int2) != 0) {
X			DECREF(tmptuple);
X			DECREF(int2);
X			return -1;
X		}
X		return err_scerrset(SizeError, tmptuple, "Equal");
X	}
X	return 0;
X}
X
Xobject *
Xsc_interpreter(self, args)
X	object *self, *args;
X{
XTscOpcode opcode;
XTscOperand operand;
Xint datasize, ret;
Xobject *returnobject;
Xstruct sc_ProcessBlock sc_pb;
X
X	if ((datasize = init(self, &sc_pb)) < 0)
X		return NULL;
X	memcpy(&opcode, sc_pb.data, sizeof(TscOpcode));
X	sc_pb.datsize = datasize;
X	sc_pb.pc += sizeof(TscOpcode);
X	if (opcode != BufSize) {
X		free((char *)sc_pb.stack);
X		return err_scerr(NoBufSize);
X	}
X	memcpy(&operand, &sc_pb.data[sc_pb.pc], sizeof(TscOperand));
X	sc_pb.pc += sizeof(TscOperand);
X	sc_pb.buffer = (unsigned char *)malloc(operand);
X	sc_pb.maxbufsize = (int)operand;
X	if (sc_pb.buffer == NULL) {
X		free((char *)sc_pb.stack);
X		return err_nomem();
X	}
X	memcpy(&opcode, &sc_pb.data[sc_pb.pc], sizeof(TscOpcode));
X	if (opcode != NoArgs) {
X		if (xPush(args, &sc_pb) != 0) {
X			UnInit(self, &sc_pb);
X			return NULL;
X		}
X	}
X	while (sc_pb.pc < datasize) {
X		memcpy(&opcode, &sc_pb.data[sc_pb.pc], sizeof(TscOpcode));
X		sc_pb.pc += sizeof(TscOpcode);
X		if (opcode & (OPERAND | FLAGS)) {
X			memcpy(&operand, &sc_pb.data[sc_pb.pc], sizeof(TscOperand));
X			sc_pb.pc += sizeof(TscOperand);
X		}
X#ifdef SCDEBUG
X		xPrintCode(opcode);
X		if ((opcode & FLAGS) && (opcode & OPERAND))
X			xPrintFlags(operand);
X		else if (opcode & OPERAND)
X			xPrintNum(operand);
X		printf("\n");
X		fflush(stdout);
X#endif
X#ifdef STACK_TRACE
X		{
X			register i;
X
X			printf("Stack trace :\n");
X			for(i = 0; i < sc_pb.sp; i++) {
X				printobject(sc_pb.stack[i], stdout, 0);
X				printf("\n");
X			}
X		}
X#endif
X		switch(opcode) {
X
X		case NoArgs:
X			ret = 0;
X			if (args != NULL) {
X				err_scerrset(TypeFailure, args, "NoArgs");
X				ret = -1;
X			}
X			break;
X
X		case BufSize:
X			UnInit(self, &sc_pb);
X			return err_scerr(TwoBufSize);
X
X		case Trans:
X			ret = xTrans(self, operand, &sc_pb);
X			break;
X
X		case TTupleS:
X			ret = xTTupleS(operand, &sc_pb);
X			break;
X
X		case Unpack:
X			ret = xUnpack(operand, &sc_pb);
X			break;
X
X		case AilWord:
X			ret = xAilword(operand, &sc_pb);
X			break;
X
X		case StringS:
X			ret = xStringS(&sc_pb);
X			break;
X
X		case ListS:
X			ret = xListS(&sc_pb);
X			break;
X
X		case PutFS:
X			ret = xPutFS(operand, &sc_pb);
X			break;
X
X		case TStringSeq:
X			ret = xTStringSeq(operand, &sc_pb);
X			break;
X
X		case TStringSlt:
X			ret = xTStringSlt(operand, &sc_pb);
X			break;
X
X		case PutVS:
X			ret = xPutVS(&sc_pb);
X			break;
X
X		case TListSeq:
X			ret = xTListSeq(operand, &sc_pb);
X			break;
X
X		case TListSlt:
X			ret = xTListSlt(operand, &sc_pb);
X			break;
X
X		case LoopPut:
X			ret = xLoopPut(operand, &sc_pb);
X			break;
X
X		case EndLoop:
X			ret = xEndLoop(operand, &sc_pb);
X			break;
X
X		case PutI:
X			ret = xPutI(operand, &sc_pb);
X			break;
X
X		case PutC:
X			ret = xPutC(&sc_pb);
X			break;
X
X		case Dup:
X			ret = xDup(operand, &sc_pb);
X			break;
X
X		case Pop:
X			ret = xPop(operand, &sc_pb);
X			break;
X
X		case Align:
X			ret = xAlign(operand, &sc_pb);
X			break;
X		
X		case Pack:
X			ret = xPack(operand, &sc_pb);
X			break;
X
X		case GetVS:
X			ret = xGetVS(&sc_pb);
X			break;
X		
X		case LoopGet:
X			ret = xLoopGet(operand, &sc_pb);
X			break;
X		
X		case GetFS:
X			ret = xGetFS(operand, &sc_pb);
X			break;
X		
X		case GetI:
X			ret = xGetI(operand, &sc_pb);
X			break;
X		
X		case GetC:
X			ret = xGetC(operand, &sc_pb);
X			break;
X		
X		case PushI:
X			{
X				object *element;
X			
X				element = newintobject((long)operand);
X				if (element == NULL) {
X					UnInit(self, &sc_pb);
X					return NULL;
X				}
X				ret = xPush(element, &sc_pb);
X				if (ret == 0)
X					DECREF(element);
X			}
X			break;
X
X		case Equal:
X			ret = xEqual(&sc_pb);
X			break;
X
X		default:
X			{
X				char errstr[256];
X
X				UnInit(self, &sc_pb);
X				sprintf(errstr, "Unknow stubcode %d", opcode);
X				err_setstr(RuntimeError, errstr);
X				return NULL;
X			}
X		}
X		if (ret != 0) {
X			UnInit(self, &sc_pb);
X			return NULL;
X		}
X	}
X	if (sc_pb.sp > 0) {
X		INCREF(sc_pb.stack[sc_pb.sp - 1]);
X		returnobject = sc_pb.stack[sc_pb.sp - 1];
X	} else {
X		INCREF(None);
X		returnobject = None;
X	}
X	UnInit(self, &sc_pb);
X	return returnobject;
X}
EOF
fi
echo 'Part 06 out of 21 of pack.out complete.'
exit 0