aboutsummaryrefslogtreecommitdiff
path: root/shar/python-0.9.1-08-21.shar
diff options
context:
space:
mode:
Diffstat (limited to 'shar/python-0.9.1-08-21.shar')
-rw-r--r--shar/python-0.9.1-08-21.shar2349
1 files changed, 2349 insertions, 0 deletions
diff --git a/shar/python-0.9.1-08-21.shar b/shar/python-0.9.1-08-21.shar
new file mode 100644
index 0000000..7ac6f14
--- /dev/null
+++ b/shar/python-0.9.1-08-21.shar
@@ -0,0 +1,2349 @@
+: 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 08 out of 21:'
+if test -s 'doc/mod1.tex'
+then echo '*** I will not over-write existing file doc/mod1.tex'
+else
+echo 'x - doc/mod1.tex'
+sed 's/^X//' > 'doc/mod1.tex' << 'EOF'
+X\section{Introduction}
+X
+XThe {\Python} library consists of three parts, with different levels of
+Xintegration with the interpreter.
+XClosest to the interpreter are built-in types, exceptions and functions.
+XNext are built-in modules, which are written in C and linked statically
+Xwith the interpreter.
+XFinally there are standard modules that are implemented entirely in
+X{\Python}, but are always available.
+XFor efficiency, some standard modules may become built-in modules in
+Xfuture versions of the interpreter.
+X
+X\section{Built-in Types, Exceptions and Functions}
+X
+XNames for built-in exceptions and functions are found in a separate
+Xread-only symbol table which cannot be modified.
+XThis table is searched last, so local and global user-defined names can
+Xoverride built-in names.
+XBuilt-in types have no names but are created by syntactic constructs
+X(such as constants) or built-in functions.
+XThey are described together here for easy reference.%
+X\footnote{
+XThe descriptions sorely lack explanations of the exceptions that
+Xmay be raised---this will be fixed in a future version of this
+Xdocument.
+X}
+X
+X\subsection{Built-in Types}
+X
+XThe following sections describe the standard types that are built into the
+Xinterpreter.
+X\subsubsection{Numeric Types}
+X
+XThere are two numeric types: integers and floating point numbers.
+XIntegers are implemented using {\tt long} in C, so they have at least 32
+Xbits of precision.
+XFloating point numbers are implemented using {\tt double} in C.
+XAll bets on precision are off.
+XNumbers are created by numeric constants or as the result of built-in
+Xfunctions and operators.
+X
+XNumeric types support the following operations:
+X
+X\begin{center}
+X\begin{tabular}{|c|l|c|}
+X\hline
+XOperation & Result & Notes \\
+X\hline
+X{\tt abs}({\em x}) & absolute value of {\em x} & \\
+X{\tt int}({\em x}) & {\em x} converted to integer & (1) \\
+X{\tt float}({\em x}) & {\em x} converted to floating point & \\
+X{\tt -}{\em x} & {\em x} negated & \\
+X{\tt +}{\em x} & {\em x} unchanged & \\
+X{\em x}{\tt +}{\em y} & sum of {\em x} and {\em y} & \\
+X{\em x}{\tt -}{\em y} & difference of {\em x} and {\em y} & \\
+X{\em x}{\tt *}{\em y} & product of {\em x} and {\em y} & \\
+X{\em x}{\tt /}{\em y} & quotient of {\em x} and {\em y} & (2) \\
+X{\em x}{\tt \%}{\em y} & remainder of {\em x}{\tt /}{\em y} & (3) \\
+X\hline
+X\end{tabular}
+X\end{center}
+X
+X\noindent
+XNotes:
+X\begin{description}
+X\item[(1)]
+XThis may round or truncate as in C; see functions {\tt floor} and
+X{\tt ceil} in module {\tt math}.
+X\item[(2)]
+XInteger division is defined as in C: the result is an integer; with
+Xpositive operands, it truncates towards zero; with a negative operand,
+Xthe result is unspecified.
+X\item[(3)]
+XOnly defined for integers.
+X\end{description}
+X
+XMixed arithmetic is not supported; both operands must have the same type.
+XMixed comparisons return the wrong result (floats always compare smaller
+Xthan integers).%
+X\footnote{
+XThese restrictions are bugs in the language definitions and will be
+Xfixed in the future.
+X}
+X\subsubsection{Sequence Types}
+X
+XThere are three sequence types: strings, lists and tuples.
+XStrings constants are written in single quotes: {\tt 'xyzzy'}.
+XLists are constructed with square brackets: {\tt [a,~b,~c]}.
+XTuples are constructed by the comma operator or with an empty set of
+Xparentheses: {\tt a,~b,~c} or {\tt ()}.
+X
+XSequence types support the following operations ({\em s} and {\em t} are
+Xsequences of the same type; {\em n}, {\em i} and {\em j} are integers):
+X
+X\begin{center}
+X\begin{tabular}{|c|l|c|}
+X\hline
+XOperation & Result & Notes \\
+X\hline
+X{\tt len}({\em s}) & length of {\em s} & \\
+X{\tt min}({\em s}) & smallest item of {\em s} & \\
+X{\tt max}({\em s}) & largest item of {\em s} & \\
+X{\em x} {\tt in} {\em s} &
+X true if an item of {\em s} is equal to {\em x} & \\
+X{\em x} {\tt not} {\tt in} {\em s} &
+X false if an item of {\em s} is equal to {\em x} & \\
+X{\em s}{\tt +}{\em t} & the concatenation of {\em s} and {\em t} & \\
+X{\em s}{\tt *}{\em n}, {\em n}*{\em s} &
+X {\em n} copies of {\em s} concatenated & (1) \\
+X{\em s}[{\em i}] & {\em i}'th item of {\em s} & \\
+X{\em s}[{\em i}:{\em j}] &
+X slice of {\em s} from {\em i} to {\em j} & (2) \\
+X\hline
+X\end{tabular}
+X\end{center}
+X
+X\noindent
+XNotes:
+X\begin{description}
+X\item[(1)]
+XSequence repetition is only supported for strings.
+X\item[(2)]
+XThe slice of $s$ from $i$ to $j$ is defined as the sequence
+Xof items with index $k$ such that $i \leq k < j$.
+XSpecial rules apply for negative and omitted indices; see the Tutorial
+Xor the Reference Manual.
+X\end{description}
+X
+X\paragraph{Mutable Sequence Types.}
+X
+XList objects support additional operations that allow in-place
+Xmodification of the object.
+XThese operations would be supported by other mutable sequence types
+X(when added to the language) as well.
+XStrings and tuples are immutable sequence types and such objects cannot
+Xbe modified once created.
+XThe following operations are defined on mutable sequence types (where
+X{\em x} is an arbitrary object):
+X
+X\begin{center}
+X\begin{tabular}{|c|l|}
+X\hline
+XOperation & Result \\
+X\hline
+X{\em s}[{\em i}] = {\em x} &
+X item {\em i} of {\em s} is replaced by {\em x} \\
+X{\em s}[{\em i}:{\em j}] = {\em t} &
+X slice of {\em s} from {\em i} to {\em j} is replaced by {\em t} \\
+X{\tt del} {\em s}[{\em i}:{\em j}] &
+X same as {\em s}[{\em i}:{\em j}] = [] \\
+X{\em s}.{\tt append}({\em x}) &
+X same as {\em s}[{\tt len}({\em x}):{\tt len}({\em x})] = [{\em x}] \\
+X{\em s}.{\tt insert}({\em i}, {\em x}) &
+X same as {\em s}[{\em i}:{\em i}] = [{\em x}] \\
+X{\em s}.{\tt sort}() &
+X the items of {\em s} are permuted to satisfy \\
+X &
+X $s[i] \leq s[j]$ for $i < j$\\
+X\hline
+X\end{tabular}
+X\end{center}
+X
+X\subsubsection{Mapping Types}
+X
+XA
+X{\em mapping}
+Xobject maps values of one type (the key type) to arbitrary objects.
+XMappings are mutable objects.
+XThere is currently only one mapping type, the
+X{\em dictionary}.
+XA dictionary's keys are strings.
+XAn empty dictionary is created by the expression \verb"{}".
+XAn extension of this notation is used to display dictionaries when
+Xwritten (see the example below).
+X
+XThe following operations are defined on mappings (where {\em a} is a
+Xmapping, {\em k} is a key and {\em x} is an arbitrary object):
+X
+X\begin{center}
+X\begin{tabular}{|c|l|c|}
+X\hline
+XOperation & Result & Notes\\
+X\hline
+X{\tt len}({\em a}) & the number of elements in {\em a} & \\
+X{\em a}[{\em k}] & the item of {\em a} with key {\em k} & \\
+X{\em a}[{\em k}] = {\em x} & set {\em a}[{\em k}] to {\em x} & \\
+X{\tt del} {\em a}[{\em k}] & remove {\em a}[{\em k}] from {\em a} & \\
+X{\em a}.{\tt keys}() & a copy of {\em a}'s list of keys & (1) \\
+X{\em a}.{\tt has\_key}({\em k}) & true if {\em a} has a key {\em k} & \\
+X\hline
+X\end{tabular}
+X\end{center}
+X
+X\noindent
+XNotes:
+X\begin{description}
+X\item[(1)]
+XKeys are listed in random order.
+X\end{description}
+X
+XA small example using a dictionary:
+X\bcode\begin{verbatim}
+X>>> tel = {}
+X>>> tel['jack'] = 4098
+X>>> tel['sape'] = 4139
+X>>> tel['guido'] = 4127
+X>>> tel['jack']
+X4098
+X>>> tel
+X{'sape': 4139; 'guido': 4127; 'jack': 4098}
+X>>> del tel['sape']
+X>>> tel['irv'] = 4127
+X>>> tel
+X{'guido': 4127; 'irv': 4127; 'jack': 4098}
+X>>> tel.keys()
+X['guido', 'irv', 'jack']
+X>>> tel.has_key('guido')
+X1
+X>>>
+X\end{verbatim}\ecode
+X\subsubsection{Other Built-in Types}
+X
+XThe interpreter supports several other kinds of objects.
+XMost of these support only one or two operations.
+X
+X\paragraph{Modules.}
+X
+XThe only operation on a module is member acces: {\em m}{\tt .}{\em name},
+Xwhere {\em m} is a module and {\em name} accesses a name defined in
+X{\em m}'s symbol table.
+XModule members can be assigned to.
+X
+X\paragraph{Classes and Class Objects.}
+X
+XXXX Classes will be explained at length in a later version of this
+Xdocument.
+X
+X\paragraph{Functions.}
+X
+XFunction objects are created by function definitions.
+XThe only operation on a function object is to call it:
+X{\em func}({\em optional-arguments}).
+X
+XBuilt-in functions have a different type than user-defined functions,
+Xbut they support the same operation.
+X
+X\paragraph{Methods.}
+X
+XMethods are functions that are called using the member acces notation.
+XThere are two flavors: built-in methods (such as {\tt append()} on
+Xlists) and class member methods.
+XBuilt-in methods are described with the types that support them.
+XXXX Class member methods will be described in a later version of this
+Xdocument.
+X
+X\paragraph{Type Objects.}
+X
+XType objects represent the various object types.
+XAn object's type is accessed by the built-in function
+X{\tt type()}.
+XThere are no operations on type objects.
+X
+X\paragraph{The Null Object.}
+X
+XThis object is returned by functions that don't explicitly return a
+Xvalue.
+XIt supports no operations.
+XThere is exactly one null object, named {\tt None}
+X(a built-in name).
+X
+X\paragraph{File Objects.}
+X
+XFile objects are implemented using C's
+X{\em stdio}
+Xpackage and can be created with the built-in function
+X{\tt open()}.
+XThey have the following methods:
+X\begin{description}
+X\funcitem{close}{}
+XCloses the file.
+XA closed file cannot be read or written anymore.
+X\funcitem{read}{size}
+XReads at most
+X{\tt size}
+Xbytes from the file (less if the read hits EOF).
+XThe bytes are returned as a string object.
+XAn empty string is returned when EOF is hit immediately.
+X(For certain files, like ttys, it makes sense to continue reading after
+Xan EOF is hit.)
+X\funcitem{readline}{size}
+XReads a line of at most
+X{\tt size}
+Xbytes from the file.
+XA trailing newline character, if present, is kept in the string.
+XThe size is optional and defaults to a large number (but not infinity).
+XEOF is reported as by
+X{\tt read().}
+X\funcitem{write}{str}
+XWrites a string to the file.
+XReturns no value.
+X\end{description}
+X
+X\subsection{Built-in Exceptions}
+X
+XThe following exceptions can be generated by the interpreter or
+Xbuilt-in functions.
+XExcept where mentioned, they have a string argument (also known as the
+X`associated value' of an exception) indicating the detailed cause of the
+Xerror.
+XThe strings listed with the exception names are their values when used
+Xin an expression or printed.
+X\begin{description}
+X\excitem{EOFError}{end-of-file read}
+X(No argument.)
+XRaised when a built-in function ({\tt input()} or {\tt raw\_input()})
+Xhits an end-of-file condition (EOF) without reading any data.
+X(N.B.: the {\tt read()} and {\tt readline()} methods of file objects
+Xreturn an empty string when they hit EOF.)
+X\excitem{KeyboardInterrupt}{end-of-file read}
+X(No argument.)
+XRaised when the user hits the interrupt key (normally Control-C or DEL).
+XDuring execution, a check for interrupts is made regularly.
+XInterrupts typed when a built-in function ({\tt input()} or
+X{\tt raw\_input()}) is waiting for input also raise this exception.
+X\excitem{MemoryError}{out of memory}
+X%.br
+XRaised when an operation runs out of memory but the situation
+Xmay still be rescued (by deleting some objects).
+X\excitem{NameError}{undefined name}
+X%.br
+XRaised when a name is not found.
+XThis applies to unqualified names, module names (on {\tt import}),
+Xmodule members and object methods.
+XThe string argument is the name that could not be found.
+X\excitem{RuntimeError}{run-time error}
+X%.br
+XRaised for a variety of reasons, e.g., division by zero or index out of
+Xrange.
+X\excitem{SystemError}{system error}
+X%.br
+XRaised when the interpreter finds an internal error, but the situation
+Xdoes not look so serious to cause it to abandon all hope.
+X\excitem{TypeError}{type error}
+X%.br
+XRaised when an operation or built-in function is applied to an object of
+Xinappropriate type.
+X\end{description}
+X
+X\subsection{Built-in Functions}
+X
+XThe {\Python} interpreter has a small number of functions built into it that
+Xare always available.
+XThey are listed here in alphabetical order.
+X\begin{description}
+X\funcitem{abs}{x}
+XReturns the absolute value of a number.
+XThe argument may be an integer or floating point number.
+X\funcitem{chr}{i}
+XReturns a string of one character
+Xwhose ASCII code is the integer {\tt i},
+Xe.g., {\tt chr(97)} returns the string {\tt 'a'}.
+XThis is the inverse of {\tt ord()}.
+X\funcitem{dir}{}
+XWithout arguments, this function returns the list of names in the
+Xcurrent local symbol table, sorted alphabetically.
+XWith a module object as argument, it returns the sorted list of names in
+Xthat module's global symbol table.
+XFor example:
+X\bcode\begin{verbatim}
+X>>> import sys
+X>>> dir()
+X['sys']
+X>>> dir(sys)
+X['argv', 'exit', 'modules', 'path', 'stderr', 'stdin', 'stdout']
+X>>>
+X\end{verbatim}\ecode
+X\funcitem{divmod}{a, b}
+X%.br
+XTakes two integers as arguments and returns a pair of integers
+Xconsisting of their quotient and remainder.
+XFor
+X\bcode\begin{verbatim}
+Xq, r = divmod(a, b)
+X\end{verbatim}\ecode
+Xthe invariants are:
+X\bcode\begin{verbatim}
+Xa = q*b + r
+Xabs(r) < abs(b)
+Xr has the same sign as b
+X\end{verbatim}\ecode
+XFor example:
+X\bcode\begin{verbatim}
+X>>> divmod(100, 7)
+X(14, 2)
+X>>> divmod(-100, 7)
+X(-15, 5)
+X>>> divmod(100, -7)
+X(-15, -5)
+X>>> divmod(-100, -7)
+X(14, -2)
+X>>>
+X\end{verbatim}\ecode
+X\funcitem{eval}{s}
+XTakes a string as argument and parses and evaluates it as a {\Python}
+Xexpression.
+XThe expression is executed using the current local and global symbol
+Xtables.
+XSyntax errors are reported as exceptions.
+XFor example:
+X\bcode\begin{verbatim}
+X>>> x = 1
+X>>> eval('x+1')
+X2
+X>>>
+X\end{verbatim}\ecode
+X\funcitem{exec}{s}
+XTakes a string as argument and parses and evaluates it as a sequence of
+X{\Python} statements.
+XThe string should end with a newline (\verb"'\n'").
+XThe statement is executed using the current local and global symbol
+Xtables.
+XSyntax errors are reported as exceptions.
+XFor example:
+X\bcode\begin{verbatim}
+X>>> x = 1
+X>>> exec('x = x+1\n')
+X>>> x
+X2
+X>>>
+X\end{verbatim}\ecode
+X\funcitem{float}{x}
+XConverts a number to floating point.
+XThe argument may be an integer or floating point number.
+X\funcitem{input}{s}
+XEquivalent to
+X{\tt eval(raw\_input(s))}.
+XAs for
+X{\tt raw\_input()},
+Xthe argument is optional.
+X\funcitem{int}{x}
+XConverts a number to integer.
+XThe argument may be an integer or floating point number.
+X\funcitem{len}{s}
+XReturns the length (the number of items) of an object.
+XThe argument may be a sequence (string, tuple or list) or a mapping
+X(dictionary).
+X\funcitem{max}{s}
+XReturns the largest item of a non-empty sequence (string, tuple or list).
+X\funcitem{min}{s}
+XReturns the smallest item of a non-empty sequence (string, tuple or list).
+X\funcitem{open}{name, mode}
+X%.br
+XReturns a file object (described earlier under Built-in Types).
+XThe string arguments are the same as for stdio's
+X{\tt fopen()}:
+X{\tt 'r'}
+Xopens the file for reading,
+X{\tt 'w'}
+Xopens it for writing (truncating an existing file),
+X{\tt 'a'}
+Xopens it for appending.%
+X\footnote{
+XThis function should go into a built-in module
+X{\tt io}.
+X}
+X\funcitem{ord}{c}
+XTakes a string of one character and returns its
+XASCII value, e.g., {\tt ord('a')} returns the integer {\tt 97}.
+XThis is the inverse of {\tt chr()}.
+X\funcitem{range}{}
+XThis is a versatile function to create lists containing arithmetic
+Xprogressions of integers.
+XWith two integer arguments, it returns the ascending sequence of
+Xintegers starting at the first and ending one before the second
+Xargument.
+XA single argument is used as the end point of the sequence, with 0 used
+Xas the starting point.
+XA third argument specifies the step size; negative steps are allowed and
+Xwork as expected, but don't specify a zero step.
+XThe resulting list may be empty.
+XFor example:
+X\bcode\begin{verbatim}
+X>>> range(10)
+X[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+X>>> range(1, 1+10)
+X[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+X>>> range(0, 30, 5)
+X[0, 5, 10, 15, 20, 25]
+X>>> range(0, 10, 3)
+X[0, 3, 6, 9]
+X>>> range(0, -10, -1)
+X[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
+X>>> range(0)
+X[]
+X>>> range(1, 0)
+X[]
+X>>>
+X\end{verbatim}\ecode
+X\funcitem{raw\_input}{s}
+X%.br
+XThe argument is optional; if present, it is written to standard output
+Xwithout a trailing newline.
+XThe function then reads a line from input, converts it to a string
+X(stripping a trailing newline), and returns that.
+XEOF is reported as an exception.
+XFor example:
+X\bcode\begin{verbatim}
+X>>> raw_input('Type anything: ')
+XType anything: Mutant Teenage Ninja Turtles
+X'Mutant Teenage Ninja Turtles'
+X>>>
+X\end{verbatim}\ecode
+X\funcitem{reload}{module}
+XCauses an already imported module to be re-parsed and re-initialized.
+XThis is useful if you have edited the module source file and want to
+Xtry out the new version without leaving {\Python}.
+X\funcitem{type}{x}
+XReturns the type of an object.
+XTypes are objects themselves:
+Xthe type of a type object is its own type.
+X\end{description}
+EOF
+fi
+if test -s 'src/Makefile'
+then echo '*** I will not over-write existing file src/Makefile'
+else
+echo 'x - src/Makefile'
+sed 's/^X//' > 'src/Makefile' << 'EOF'
+X# /***********************************************************
+X# Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
+X# Netherlands.
+X#
+X# All Rights Reserved
+X#
+X# Permission to use, copy, modify, and distribute this software and its
+X# documentation for any purpose and without fee is hereby granted,
+X# provided that the above copyright notice appear in all copies and that
+X# both that copyright notice and this permission notice appear in
+X# supporting documentation, and that the names of Stichting Mathematisch
+X# Centrum or CWI not be used in advertising or publicity pertaining to
+X# distribution of the software without specific, written prior permission.
+X#
+X# STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+X# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+X# FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+X# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+X# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+X# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+X# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+X#
+X# ******************************************************************/
+X
+X# Makefile for Python
+X# ===================
+X#
+X# If you are in a hurry, you can just edit this Makefile to choose the
+X# correct settings for SYSV and RANLIB below, and type "make" in this
+X# directory. If you are using a recent version of SunOS (or Ultrix?)
+X# you don't even have to edit: the Makefile comes pre-configured for
+X# such systems with all configurable options turned off, building the
+X# minimal portable version of the Python interpreter.
+X#
+X# If have more time, read the section on configurable options below.
+X# It may still be wise to begin building the minimal portable Python,
+X# to see if it works at all, and select options later. You don't have
+X# to rebuild all objects when you turn on options; all dependencies
+X# are concentrated in the file "config.c" which is rebuilt whenever
+X# the Makefile changes. (Except if you turn on the GNU Readline option
+X# you may have to toss out the tokenizer.o object.)
+X
+X
+X# Operating System Defines (ALWAYS READ THIS)
+X# ===========================================
+X
+X# Uncomment the following line if you are using a System V derivative.
+X# This must be used, for instance, on an SGI IRIS. Don't use it for
+X# SunOS. (This is only needed by posixmodule.c...)
+X
+X#SYSVDEF= -DSYSV
+X
+X# Choose one of the following two lines depending on whether your system
+X# requires the use of 'ranlib' after creating a library, or not.
+X
+X#RANLIB = true # For System V
+XRANLIB = ranlib # For BSD
+X
+X# If your system doesn't have symbolic links, uncomment the following
+X# line.
+X
+X#NOSYMLINKDEF= -DNO_LSTAT
+X
+X
+X# Installation Options
+X# ====================
+X
+X# You may want to change PYTHONPATH to reflect where you install the
+X# Python module library.
+X
+XPYTHONPATH= .:/usr/local/lib/python:/ufs/guido/lib/python
+X
+X
+X# For "Pure" BSD Systems
+X# ======================
+X#
+X# "Pure" BSD systems (as opposed to enhanced BSD derivatives like SunOS)
+X# often miss certain standard library functions. Source for
+X# these is provided, you just have to turn it on. This may work for
+X# other systems as well, where these things are needed.
+X
+X# If your system does not have a strerror() function in the library,
+X# uncomment the following two lines to use one I wrote. (Actually, this
+X# is missing in most systems I have encountered, so it is turned on
+X# in the Makefile. Turn it off if your system doesn't have sys_errlist.)
+X
+XSTRERROR_SRC= strerror.c
+XSTRERROR_OBJ= strerror.o
+X
+X# If your BSD system does not have a fmod() function in the library,
+X# uncomment the following two lines to use one I wrote.
+X
+X#FMOD_SRC= fmod.c
+X#FMOD_OBJ= fmod.o
+X
+X# If your BSD system does not have a strtol() function in the library,
+X# uncomment the following two lines to use one I wrote.
+X
+X#STRTOL_SRC= strtol.c
+X#STRTOL_OBJ= strtol.o
+X
+X# If your BSD system does not have a getcwd() function in the library,
+X# but it does have a getwd() function, uncomment the following two lines
+X# to use one I wrote. (If you don't have getwd() either, turn on the
+X# NO_GETWD #define in getcwd.c.)
+X
+X#GETCWD_SRC= getcwd.c
+X#GETCWD_OBJ= getcwd.o
+X
+X# If your signal() function believes signal handlers return int,
+X# uncomment the following line.
+X
+X#SIGTYPEDEF= -DSIGTYPE=int
+X
+X
+X# Further porting hints
+X# =====================
+X#
+X# If you don't have the header file <string.h>, but you do have
+X# <strings.h>, create a file "string.h" in this directory which contains
+X# the single line "#include <strings.h>", and add "-I." to CFLAGS.
+X# If you don't have the functions strchr and strrchr, add definitions
+X# "-Dstrchr=index -Dstrrchr=rindex" to CFLAGS. (NB: CFLAGS is not
+X# defined in this Makefile.)
+X
+X
+X# Configurable Options
+X# ====================
+X#
+X# Python can be configured to interface to various system libraries that
+X# are not available on all systems. It is also possible to configure
+X# the input module to use the GNU Readline library for interactive
+X# input. For each configuration choice you must uncomment the relevant
+X# section of the Makefile below. Note: you may also have to change a
+X# pathname and/or an architecture identifier that is hardcoded in the
+X# Makefile.
+X#
+X# Read the comments to determine if you can use the option. (You can
+X# always leave all options off and build a minimal portable version of
+X# Python.)
+X
+X
+X# BSD Time Option
+X# ===============
+X#
+X# This option does not add a new module but adds two functions to
+X# an existing module.
+X#
+X# It implements time.millisleep() and time.millitimer()
+X# using the BSD system calls select() and gettimeofday().
+X#
+X# Uncomment the following line to select this option.
+X
+X#BSDTIMEDEF= -DBSD_TIME
+X
+X
+X# GNU Readline Option
+X# ===================
+X#
+X# If you have the sources of the GNU Readline library you can have
+X# full interactive command line editing and history in Python.
+X# The GNU Readline library is distributed with the BASH shell
+X# (I only know of version 1.05). You must build the GNU Readline
+X# library and the alloca routine it needs in their own source
+X# directories (which are subdirectories of the basg source directory),
+X# and plant a pointer to the BASH source directory in this Makefile.
+X#
+X# Uncomment and edit the following block to use the GNU Readline option.
+X# - Edit the definition of BASHDIR to point to the bash source tree.
+X# You may have to fix the definition of LIBTERMCAP; leave the LIBALLOCA
+X# definition commented if alloca() is in your C library.
+X
+X#BASHDIR= ../../bash-1.05
+X#LIBREADLINE= $(BASHDIR)/readline/libreadline.a
+X#LIBALLOCA= $(BASHDIR)/alloc-files/alloca.o
+X#LIBTERMCAP= -ltermcap
+X#RL_USE = -DUSE_READLINE
+X#RL_LIBS= $(LIBREADLINE) $(LIBALLOCA) $(LIBTERMCAP)
+X#RL_LIBDEPS= $(LIBREADLINE) $(LIBALLOCA)
+X
+X
+X# STDWIN Option
+X# =============
+X#
+X# If you have the sources of STDWIN (by the same author) you can
+X# configure Python to incorporate the built-in module 'stdwin'.
+X# This requires a fairly recent version of STDWIN (dated late 1990).
+X#
+X# Uncomment and edit the following block to use the STDWIN option.
+X# - Edit the STDWINDIR defition to reflect the top of the STDWIN source
+X# tree.
+X# - Edit the ARCH definition to reflect your system's architecture
+X# (usually the program 'arch' or 'machine' returns this).
+X# You may have to edit the LIBX11 defition to reflect the location of
+X# the X11 runtime library if it is non-standard.
+X
+X#STDWINDIR= ../../stdwin
+X#ARCH= sgi
+X#LIBSTDWIN= $(STDWINDIR)/Build/$(ARCH)/x11/lib/lib.a
+X#LIBX11 = -lX11
+X#STDW_INCL= -I$(STDWINDIR)/H
+X#STDW_USE= -DUSE_STDWIN
+X#STDW_LIBS= $(LIBSTDWIN) $(LIBX11)
+X#STDW_LIBDEPS= $(LIBSTDWIN)
+X#STDW_SRC= stdwinmodule.c
+X#STDW_OBJ= stdwinmodule.o
+X
+X
+X# Amoeba Option
+X# =============
+X#
+X# If you have the Amoeba 4.0 distribution (Beta or otherwise) you can
+X# configure Python to incorporate the built-in module 'amoeba'.
+X# (Python can also be built for native Amoeba, but it requires more
+X# work and thought. Contact the author.)
+X#
+X# Uncomment and edit the following block to use the Amoeba option.
+X# - Edit the AMOEBADIR defition to reflect the top of the Amoeba source
+X# tree.
+X# - Edit the AM_CONF definition to reflect the machine/operating system
+X# configuration needed by Amoeba (this is the name of a subdirectory
+X# of $(AMOEBADIR)/conf/unix, e.g., vax.ultrix).
+X
+X#AMOEBADIR= /usr/amoeba
+X#AM_CONF= mipseb.irix
+X#LIBAMUNIX= $(AMOEBADIR)/conf/unix/$(AM_CONF)/lib/amunix/libamunix.a
+X#AM_INCL= -I$(AMOEBADIR)/src/h
+X#AM_USE = -DUSE_AMOEBA
+X#AM_LIBDEPS= $(LIBAMUNIX)
+X#AM_LIBS= $(LIBAMUNIX)
+X#AM_SRC = amoebamodule.c sc_interpr.c sc_errors.c
+X#AM_OBJ = amoebamodule.o sc_interpr.o sc_errors.o
+X
+X
+X# Silicon Graphics IRIS Options
+X# =============================
+X#
+X# The following three options are only relevant if you are using a
+X# Silicon Graphics IRIS machine. These have been tested with IRIX 3.3.1
+X# on a 4D/25.
+X
+X
+X# GL Option
+X# =========
+X#
+X# This option incorporates the built-in module 'gl', which provides a
+X# complete interface to the Silicon Graphics GL library. It adds
+X# about 70K to the Python text size and about 260K to the unstripped
+X# binary size.
+X#
+X# Note: the file 'glmodule.c' is created by a Python script. If you
+X# lost the file and have no working Python interpreter, turn off the GL
+X# and Panel options, rebuild the Python interpreter, use it to create
+X# glmodule.c, and then turn the options back on.
+X#
+X# Uncomment the following block to use the GL option.
+X
+X#GL_USE = -DUSE_GL
+X#GL_LIBDEPS=
+X#GL_LIBS= -lgl_s
+X#GL_SRC = glmodule.c cgensupport.c
+X#GL_OBJ = glmodule.o cgensupport.o
+X
+X
+X# Panel Option
+X# ============
+X#
+X# If you have source to the NASA Ames Panel Library, you can configure
+X# Python to incorporate the built-in module 'pnl', which is used byu
+X# the standard module 'panel' to provide an interface to most features
+X# of the Panel Library. This option requires that you also turn on the
+X# GL option. It adds about 100K to the Python text size and about 160K
+X# to the unstripped binary size.
+X#
+X# Uncomment and edit the following block to use the Panel option.
+X# - Edit the PANELDIR definition to point to the top-level directory
+X# of the Panel distribution tree.
+X
+X#PANELDIR= /usr/people/guido/src/pl
+X#PANELLIBDIR= $(PANELDIR)/library
+X#LIBPANEL= $(PANELLIBDIR)/lib/libpanel.a
+X#PANEL_USE= -DUSE_PANEL
+X#PANEL_INCL= -I$(PANELLIBDIR)/include
+X#PANEL_LIBDEPS= $(LIBPANEL)
+X#PANEL_LIBS= $(LIBPANEL)
+X#PANEL_SRC= panelmodule.c
+X#PANEL_OBJ= panelmodule.o
+X
+X
+X# Audio Option
+X# ============
+X#
+X# This option lets you play with /dev/audio on the IRIS 4D/25.
+X# It incorporates the built-in module 'audio'.
+X# Warning: using the asynchronous I/O facilities of this module can
+X# create a second 'thread', which looks in the listings of 'ps' like a
+X# forked child. However, it shares its address space with the parent.
+X#
+X# Uncomment the following block to use the Audio option.
+X
+X#AUDIO_USE= -DUSE_AUDIO
+X#AUDIO_SRC= audiomodule.c asa.c
+X#AUDIO_OBJ= audiomodule.o asa.o
+X
+X
+X# Major Definitions
+X# =================
+X
+XSTANDARD_OBJ= acceler.o bltinmodule.o ceval.o classobject.o \
+X compile.o dictobject.o errors.o fgetsintr.o \
+X fileobject.o floatobject.o $(FMOD_OBJ) frameobject.o \
+X funcobject.o $(GETCWD_OBJ) \
+X graminit.o grammar1.o import.o \
+X intobject.o intrcheck.o listnode.o listobject.o \
+X mathmodule.o methodobject.o modsupport.o \
+X moduleobject.o node.o object.o parser.o \
+X parsetok.o posixmodule.o regexp.o regexpmodule.o \
+X strdup.o $(STRERROR_OBJ) \
+X stringobject.o $(STRTOL_OBJ) structmember.o \
+X sysmodule.o timemodule.o tokenizer.o traceback.o \
+X tupleobject.o typeobject.o
+X
+XSTANDARD_SRC= acceler.c bltinmodule.c ceval.c classobject.c \
+X compile.c dictobject.c errors.c fgetsintr.c \
+X fileobject.c floatobject.c $(FMOD_SRC) frameobject.c \
+X funcobject.c $(GETCWD_SRC) \
+X graminit.c grammar1.c import.c \
+X intobject.c intrcheck.c listnode.c listobject.c \
+X mathmodule.c methodobject.c modsupport.c \
+X moduleobject.c node.c object.c parser.c \
+X parsetok.c posixmodule.c regexp.c regexpmodule.c \
+X strdup.c $(STRERROR_SRC) \
+X stringobject.c $(STRTOL_SRC) structmember.c \
+X sysmodule.c timemodule.c tokenizer.c traceback.c \
+X tupleobject.c typeobject.c
+X
+XCONFIGDEFS= $(STDW_USE) $(AM_USE) $(AUDIO_USE) $(GL_USE) $(PANEL_USE) \
+X '-DPYTHONPATH="$(PYTHONPATH)"'
+X
+XCONFIGINCLS= $(STDW_INCL)
+X
+XLIBDEPS= libpython.a $(STDW_LIBDEPS) $(AM_LIBDEPS) \
+X $(GL_LIBDEPS) $(PANEL_LIBSDEP) $(RL_LIBDEPS)
+X
+X# NB: the ordering of items in LIBS is significant!
+XLIBS= libpython.a $(STDW_LIBS) $(AM_LIBS) \
+X $(PANEL_LIBS) $(GL_LIBS) $(RL_LIBS) -lm
+X
+XLIBOBJECTS= $(STANDARD_OBJ) $(STDW_OBJ) $(AM_OBJ) $(AUDIO_OBJ) \
+X $(GL_OBJ) $(PANEL_OBJ)
+X
+XLIBSOURCES= $(STANDARD_SRC) $(STDW_SRC) $(AM_SRC) $(AUDIO_SRC) \
+X $(GL_SRC) $(PANEL_SRC)
+X
+XOBJECTS= pythonmain.o config.o
+X
+XSOURCES= $(LIBSOURCES) pythonmain.c config.c
+X
+XGENOBJECTS= acceler.o fgetsintr.o grammar1.o \
+X intrcheck.o listnode.o node.o parser.o \
+X parsetok.o strdup.o tokenizer.o bitset.o \
+X firstsets.o grammar.o metagrammar.o pgen.o \
+X pgenmain.o printgrammar.o
+X
+XGENSOURCES= acceler.c fgetsintr.c grammar1.c \
+X intrcheck.c listnode.c node.c parser.c \
+X parsetok.c strdup.c tokenizer.c bitset.c \
+X firstsets.c grammar.c metagrammar.c pgen.c \
+X pgenmain.c printgrammar.c
+X
+X
+X# Main Targets
+X# ============
+X
+Xpython: libpython.a $(OBJECTS) $(LIBDEPS) Makefile
+X $(CC) $(CFLAGS) $(OBJECTS) $(LIBS) -o @python
+X mv @python python
+X
+Xlibpython.a: $(LIBOBJECTS)
+X -rm -f @lib
+X ar cr @lib $(LIBOBJECTS)
+X $(RANLIB) @lib
+X mv @lib libpython.a
+X
+Xpython_gen: $(GENOBJECTS) $(RL_LIBDEPS)
+X $(CC) $(CFLAGS) $(GENOBJECTS) $(RL_LIBS) -o python_gen
+X
+X
+X# Utility Targets
+X# ===============
+X
+X# Don't take the output from lint too seriously. I have not attempted
+X# to make Python lint-free. But I use function prototypes.
+X
+XLINTFLAGS= -h
+X
+XLINTCPPFLAGS= $(CONFIGDEFS) $(CONFIGINCLS) $(SYSVDEF) \
+X $(AM_INCL) $(PANEL_INCL)
+X
+XLINT= lint
+X
+Xlint:: $(SOURCES)
+X $(LINT) $(LINTFLAGS) $(LINTCPPFLAGS) $(SOURCES)
+X
+Xlint:: $(GENSOURCES)
+X $(LINT) $(LINTFLAGS) $(GENSOURCES)
+X
+X# Generating dependencies is only necessary if you intend to hack Python.
+X# You may change $(MKDEP) to your favorite dependency generator (it should
+X# edit the Makefile in place).
+X
+XMKDEP= mkdep
+X
+Xdepend::
+X $(MKDEP) $(LINTCPPFLAGS) $(SOURCES) $(GENSOURCES)
+X
+X# You may change $(CTAGS) to suit your taste...
+X
+XCTAGS= ctags -t -w
+X
+XHEADERS= *.h
+X
+Xtags: $(SOURCES) $(GENSOURCES) $(HEADERS)
+X $(CTAGS) $(SOURCES) $(GENSOURCES) $(HEADERS)
+X
+Xclean::
+X -rm -f *.o core [,#@]*
+X
+Xclobber:: clean
+X -rm -f python python_gen libpython.a tags
+X
+X
+X# Build Special Objects
+X# =====================
+X
+X# You may change $(COMPILE) to reflect the default .c.o rule...
+X
+XCOMPILE= $(CC) -c $(CFLAGS)
+X
+Xamoebamodule.o: amoebamodule.c
+X $(COMPILE) $(AM_INCL) $*.c
+X
+Xconfig.o: config.c Makefile
+X $(COMPILE) $(CONFIGDEFS) $(CONFIGINCLS) $*.c
+X
+Xfgetsintr.o: fgetsintr.c
+X $(COMPILE) $(SIGTYPEDEF) $*.c
+X
+Xintrcheck.o: intrcheck.c
+X $(COMPILE) $(SIGTYPEDEF) $*.c
+X
+Xpanelmodule.o: panelmodule.c
+X $(COMPILE) $(PANEL_INCL) $*.c
+X
+Xposixmodule.o: posixmodule.c
+X $(COMPILE) $(SYSVDEF) $(NOSYMLINKDEF) $*.c
+X
+Xsc_interpr.o: sc_interpr.c
+X $(COMPILE) $(AM_INCL) $*.c
+X
+Xsc_error.o: sc_error.c
+X $(COMPILE) $(AM_INCL) $*.c
+X
+Xstdwinmodule.o: stdwinmodule.c
+X $(COMPILE) $(STDW_INCL) $*.c
+X
+Xtimemodule.o: timemodule.c
+X $(COMPILE) $(SIGTYPEDEF) $(BSDTIMEDEF) $*.c
+X
+Xtokenizer.o: tokenizer.c
+X $(COMPILE) $(RL_USE) $*.c
+X
+X.PRECIOUS: python libpython.a glmodule.c graminit.c graminit.h
+X
+X
+X# Generated Sources
+X# =================
+X#
+X# Some source files are (or may be) generated.
+X# The rules for doing so are given here.
+X
+X# Build "glmodule.c", the GL interface.
+X# Ignore the messages emitted by the cgen script.
+X# Also ignore the warnings emitted while compiling glmodule.c; it works.
+X
+Xglmodule.c: cstubs cgen
+X python cgen <cstubs >@glmodule.c
+X mv @glmodule.c glmodule.c
+X
+X# The dependencies for graminit.[ch] are not turned on in the
+X# distributed Makefile because the files themselves are distributed.
+X# Turn them on if you want to hack the grammar.
+X
+X#graminit.c graminit.h: Grammar python_gen
+X# python_gen Grammar
+X
+EOF
+fi
+if test -s 'src/amoebamodule.c'
+then echo '*** I will not over-write existing file src/amoebamodule.c'
+else
+echo 'x - src/amoebamodule.c'
+sed 's/^X//' > 'src/amoebamodule.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/* Amoeba module implementation */
+X
+X/* Amoeba includes */
+X#include <amoeba.h>
+X#include <cmdreg.h>
+X#include <stdcom.h>
+X#include <stderr.h>
+X#include <caplist.h>
+X#include <server/bullet/bullet.h>
+X#include <server/tod/tod.h>
+X#include <module/name.h>
+X#include <module/direct.h>
+X#include <module/mutex.h>
+X#include <module/prv.h>
+X#include <module/stdcmd.h>
+X
+X/* C includes */
+X#include <stdlib.h>
+X#include <ctype.h>
+X
+X/* POSIX includes */
+X#include <fcntl.h>
+X#include <sys/types.h>
+X#include <sys/stat.h>
+X
+X/* Python includes */
+X#include "allobjects.h"
+X#include "modsupport.h"
+X#include "sc_global.h"
+X#include "stubcode.h"
+X
+Xextern char *err_why();
+Xextern char *ar_cap();
+X
+X#define STUBCODE "+stubcode"
+X
+Xstatic object *AmoebaError;
+Xobject *StubcodeError;
+X
+Xstatic object *sc_dict;
+X
+X/* Module initialization */
+X
+Xextern struct methodlist amoeba_methods[]; /* Forward */
+Xextern object *convertcapv(); /* Forward */
+X
+Xstatic void
+Xins(d, name, v)
+X object *d;
+X char *name;
+X object *v;
+X{
+X if (v == NULL || dictinsert(d, name, v) != 0)
+X fatal("can't initialize amoeba module");
+X}
+X
+Xvoid
+Xinitamoeba()
+X{
+X object *m, *d, *v;
+X
+X m = initmodule("amoeba", amoeba_methods);
+X d = getmoduledict(m);
+X
+X /* Define capv */
+X v = convertcapv();
+X ins(d, "capv", v);
+X DECREF(v);
+X
+X /* Set timeout */
+X timeout((interval)2000);
+X
+X /* Initialize amoeba.error exception */
+X AmoebaError = newstringobject("amoeba.error");
+X ins(d, "error", AmoebaError);
+X StubcodeError = newstringobject("amoeba.stubcode_error");
+X ins(d, "stubcode_error", StubcodeError);
+X sc_dict = newdictobject();
+X}
+X
+X
+X/* Set an Amoeba-specific error, and return NULL */
+X
+Xobject *
+Xamoeba_error(err)
+X errstat err;
+X{
+X object *v = newtupleobject(2);
+X if (v != NULL) {
+X settupleitem(v, 0, newintobject((long)err));
+X settupleitem(v, 1, newstringobject(err_why(err)));
+X }
+X err_setval(AmoebaError, v);
+X if (v != NULL)
+X DECREF(v);
+X return NULL;
+X}
+X
+X
+X/* Capability object implementation */
+X
+Xextern typeobject Captype; /* Forward */
+X
+X#define is_capobject(v) ((v)->ob_type == &Captype)
+X
+Xtypedef struct {
+X OB_HEAD
+X capability ob_cap;
+X} capobject;
+X
+Xobject *
+Xnewcapobject(cap)
+X capability *cap;
+X{
+X capobject *v = NEWOBJ(capobject, &Captype);
+X if (v == NULL)
+X return NULL;
+X v->ob_cap = *cap;
+X return (object *)v;
+X}
+X
+Xgetcapability(v, cap)
+X object *v;
+X capability *cap;
+X{
+X
+X if (!is_capobject(v))
+X return err_badarg();
+X *cap = ((capobject *)v)->ob_cap;
+X return 0;
+X}
+X
+X/*
+X * is_capobj exports the is_capobject macro to the stubcode modules
+X */
+X
+Xint
+Xis_capobj(v)
+X object *v;
+X{
+X
+X return is_capobject(v);
+X}
+X
+X/* Methods */
+X
+Xstatic void
+Xcapprint(v, fp, flags)
+X capobject *v;
+X FILE *fp;
+X int flags;
+X{
+X /* XXX needs lock when multi-threading */
+X fputs(ar_cap(&v->ob_cap), fp);
+X}
+X
+Xstatic object *
+Xcaprepr(v)
+X capobject *v;
+X{
+X /* XXX needs lock when multi-threading */
+X return newstringobject(ar_cap(&v->ob_cap));
+X}
+X
+Xextern object *sc_interpreter();
+X
+Xextern struct methodlist cap_methods[]; /* Forward */
+X
+Xobject *
+Xsc_makeself(cap, stubcode, name)
+X object *cap, *stubcode;
+X char *name;
+X{
+X object *sc_name, *sc_self;
+X
+X sc_name = newstringobject(name);
+X if (sc_name == NULL)
+X return NULL;
+X sc_self = newtupleobject(3);
+X if (sc_self == NULL) {
+X DECREF(sc_name);
+X return NULL;
+X }
+X if (settupleitem(sc_self, NAME, sc_name) != 0) {
+X DECREF(sc_self);
+X return NULL;
+X }
+X INCREF(cap);
+X if (settupleitem(sc_self, CAP, cap) != 0) {
+X DECREF(sc_self);
+X return NULL;
+X }
+X INCREF(stubcode);
+X if (settupleitem(sc_self, STUBC, stubcode) != 0) {
+X DECREF(sc_self);
+X return NULL;
+X }
+X return sc_self;
+X}
+X
+X
+Xstatic void
+Xswapcode(code, len)
+X char *code;
+X int len;
+X{
+X int i = sizeof(TscOperand);
+X TscOpcode opcode;
+X TscOperand operand;
+X
+X while (i < len) {
+X memcpy(&opcode, &code[i], sizeof(TscOpcode));
+X SwapOpcode(opcode);
+X memcpy(&code[i], &opcode, sizeof(TscOpcode));
+X i += sizeof(TscOpcode);
+X if (opcode & OPERAND) {
+X memcpy(&operand, &code[i], sizeof(TscOperand));
+X SwapOperand(operand);
+X memcpy(&code[i], &operand, sizeof(TscOperand));
+X i += sizeof(TscOperand);
+X }
+X }
+X}
+X
+Xobject *
+Xsc_findstubcode(v, name)
+X object *v;
+X char *name;
+X{
+X int fd, fsize;
+X char *fname, *buffer;
+X struct stat statbuf;
+X object *sc_stubcode, *ret;
+X TscOperand sc_magic;
+X
+X /*
+X * Only look in the current directory for now.
+X */
+X fname = malloc(strlen(name) + 4);
+X if (fname == NULL) {
+X return err_nomem();
+X }
+X sprintf(fname, "%s.sc", name);
+X if ((fd = open(fname, O_RDONLY)) == -1) {
+X extern int errno;
+X
+X if (errno == 2) {
+X /*
+X ** errno == 2 is file not found.
+X */
+X err_setstr(NameError, fname);
+X return NULL;
+X }
+X free(fname);
+X return err_errno(newstringobject(name));
+X }
+X fstat(fd, &statbuf);
+X fsize = (int)statbuf.st_size;
+X buffer = malloc(fsize);
+X if (buffer == NULL) {
+X free(fname);
+X close(fd);
+X return err_nomem();
+X }
+X if (read(fd, buffer, fsize) != fsize) {
+X close(fd);
+X free(fname);
+X return err_errno(newstringobject(name));
+X }
+X close(fd);
+X free(fname);
+X memcpy(&sc_magic, buffer, sizeof(TscOperand));
+X if (sc_magic != SC_MAGIC) {
+X SwapOperand(sc_magic);
+X if (sc_magic != SC_MAGIC) {
+X free(buffer);
+X return NULL;
+X } else {
+X swapcode(buffer, fsize);
+X }
+X }
+X sc_stubcode = newsizedstringobject( &buffer[sizeof(TscOperand)],
+X fsize - sizeof(TscOperand));
+X free(buffer);
+X if (sc_stubcode == NULL) {
+X return NULL;
+X }
+X if (dictinsert(sc_dict, name, sc_stubcode) != 0) {
+X DECREF(sc_stubcode);
+X return NULL;
+X }
+X DECREF(sc_stubcode); /* XXXX */
+X sc_stubcode = sc_makeself(v, sc_stubcode, name);
+X if (sc_stubcode == NULL) {
+X return NULL;
+X }
+X return sc_stubcode;
+X}
+X
+Xobject *
+Xcapgetattr(v, name)
+X capobject *v;
+X char *name;
+X{
+X object *sc_method, *sc_stubcodemethod;
+X
+X if (sc_dict == NULL) {
+X /*
+X ** For some reason the dictionary has not been
+X ** initialized. Try to find one of the built in
+X ** methods.
+X */
+X return findmethod(cap_methods, (object *)v, name);
+X }
+X sc_stubcodemethod = dictlookup(sc_dict, name);
+X if (sc_stubcodemethod != NULL) {
+X /*
+X ** There is a stubcode method in the dictionary.
+X ** Execute the stubcode interpreter with the right
+X ** arguments.
+X */
+X object *self, *ret;
+X
+X self = sc_makeself((object *)v, sc_stubcodemethod, name);
+X if (self == NULL) {
+X return NULL;
+X }
+X ret = findmethod(cap_methods, self, STUBCODE);
+X DECREF(self);
+X return ret;
+X }
+X err_clear();
+X sc_method = findmethod(cap_methods, (object *)v, name);
+X if (sc_method == NULL) {
+X /*
+X ** The method is not built in and not in the
+X ** dictionary. Try to find it as a stubcode file.
+X */
+X object *self, *ret;
+X
+X err_clear();
+X self = sc_findstubcode((object *)v, name);
+X if (self == NULL) {
+X return NULL;
+X }
+X ret = findmethod(cap_methods, self, STUBCODE);
+X DECREF(self);
+X return ret;
+X }
+X return sc_method;
+X}
+X
+Xint
+Xcapcompare(v, w)
+X capobject *v, *w;
+X{
+X int cmp = bcmp((char *)&v->ob_cap.cap_port,
+X (char *)&w->ob_cap, PORTSIZE);
+X if (cmp != 0)
+X return cmp;
+X return prv_number(&v->ob_cap.cap_priv) -
+X prv_number(&w->ob_cap.cap_priv);
+X}
+X
+Xstatic typeobject Captype = {
+X OB_HEAD_INIT(&Typetype)
+X 0,
+X "capability",
+X sizeof(capobject),
+X 0,
+X free, /*tp_dealloc*/
+X capprint, /*tp_print*/
+X capgetattr, /*tp_getattr*/
+X 0, /*tp_setattr*/
+X capcompare, /*tp_comp
+are*/
+X caprepr, /*tp_repr*/
+X 0, /*tp_as_number*/
+X 0, /*tp_as_sequence*/
+X 0, /*tp_as_mapping*/
+X};
+X
+X
+X/* Return a dictionary corresponding to capv */
+X
+Xextern struct caplist *capv;
+X
+Xstatic object *
+Xconvertcapv()
+X{
+X object *d;
+X struct caplist *c;
+X d = newdictobject();
+X if (d == NULL)
+X return NULL;
+X if (capv == NULL)
+X return d;
+X for (c = capv; c->cl_name != NULL; c++) {
+X object *v = newcapobject(c->cl_cap);
+X if (v == NULL || dictinsert(d, c->cl_name, v) != 0) {
+X DECREF(d);
+X return NULL;
+X }
+X DECREF(v);
+X }
+X return d;
+X}
+X
+X
+X/* Strongly Amoeba-specific argument handlers */
+X
+Xstatic int
+Xgetcaparg(v, a)
+X object *v;
+X capability *a;
+X{
+X if (v == NULL || !is_capobject(v))
+X return err_badarg();
+X *a = ((capobject *)v) -> ob_cap;
+X return 1;
+X}
+X
+Xstatic int
+Xgetstrcapargs(v, a, b)
+X object *v;
+X object **a;
+X capability *b;
+X{
+X if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 2)
+X return err_badarg();
+X return getstrarg(gettupleitem(v, 0), a) &&
+X getcaparg(gettupleitem(v, 1), b);
+X}
+X
+X
+X/* Amoeba methods */
+X
+Xstatic object *
+Xamoeba_name_lookup(self, args)
+X object *self;
+X object *args;
+X{
+X object *name;
+X capability cap;
+X errstat err;
+X if (!getstrarg(args, &name))
+X return NULL;
+X err = name_lookup(getstringvalue(name), &cap);
+X if (err != STD_OK)
+X return amoeba_error(err);
+X return newcapobject(&cap);
+X}
+X
+Xstatic object *
+Xamoeba_name_append(self, args)
+X object *self;
+X object *args;
+X{
+X object *name;
+X capability cap;
+X errstat err;
+X if (!getstrcapargs(args, &name, &cap))
+X return NULL;
+X err = name_append(getstringvalue(name), &cap);
+X if (err != STD_OK)
+X return amoeba_error(err);
+X INCREF(None);
+X return None;
+X}
+X
+Xstatic object *
+Xamoeba_name_replace(self, args)
+X object *self;
+X object *args;
+X{
+X object *name;
+X capability cap;
+X errstat err;
+X if (!getstrcapargs(args, &name, &cap))
+X return NULL;
+X err = name_replace(getstringvalue(name), &cap);
+X if (err != STD_OK)
+X return amoeba_error(err);
+X INCREF(None);
+X return None;
+X}
+X
+Xstatic object *
+Xamoeba_name_delete(self, args)
+X object *self;
+X object *args;
+X{
+X object *name;
+X errstat err;
+X if (!getstrarg(args, &name))
+X return NULL;
+X err = name_delete(getstringvalue(name));
+X if (err != STD_OK)
+X return amoeba_error(err);
+X INCREF(None);
+X return None;
+X}
+X
+Xstatic object *
+Xamoeba_timeout(self, args)
+X object *self;
+X object *args;
+X{
+X int i;
+X object *v;
+X interval tout;
+X if (!getintarg(args, &i))
+X return NULL;
+X tout = timeout((interval)i);
+X v = newintobject((long)tout);
+X if (v == NULL)
+X timeout(tout);
+X return v;
+X}
+X
+Xstatic struct methodlist amoeba_methods[] = {
+X {"name_append", amoeba_name_append},
+X {"name_delete", amoeba_name_delete},
+X {"name_lookup", amoeba_name_lookup},
+X {"name_replace", amoeba_name_replace},
+X {"timeout", amoeba_timeout},
+X {NULL, NULL} /* Sentinel */
+X};
+X
+X/* Capability methods */
+X
+Xstatic object *
+Xcap_b_size(self, args)
+X capobject *self;
+X object *args;
+X{
+X errstat err;
+X b_fsize size;
+X if (!getnoarg(args))
+X return NULL;
+X err = b_size(&self->ob_cap, &size);
+X if (err != STD_OK)
+X return amoeba_error(err);
+X return newintobject((long)size);
+X}
+X
+Xstatic object *
+Xcap_b_read(self, args)
+X capobject *self;
+X object *args;
+X{
+X errstat err;
+X char *buf;
+X object *v;
+X long offset, size;
+X b_fsize nread;
+X if (!getlonglongargs(args, &offset, &size))
+X return NULL;
+X buf = malloc((unsigned int)size);
+X if (buf == NULL) {
+X return err_nomem();
+X }
+X err = b_read(&self->ob_cap, (b_fsize)offset, buf, (b_fsize)size,
+X &nread);
+X if (err != STD_OK) {
+X free(buf);
+X return amoeba_error(err);
+X }
+X v = newsizedstringobject(buf, (int)nread);
+X free(buf);
+X return v;
+X}
+X
+Xstatic object *
+Xcap_dir_lookup(self, args)
+X capobject *self;
+X object *args;
+X{
+X object *name;
+X capability cap;
+X errstat err;
+X if (!getstrarg(args, &name))
+X return NULL;
+X err = dir_lookup(&self->ob_cap, getstringvalue(name), &cap);
+X if (err != STD_OK)
+X return amoeba_error(err);
+X return newcapobject(&cap);
+X}
+X
+Xstatic object *
+Xcap_dir_append(self, args)
+X capobject *self;
+X object *args;
+X{
+X object *name;
+X capability cap;
+X errstat err;
+X if (!getstrcapargs(args, &name, &cap))
+X return NULL;
+X err = dir_append(&self->ob_cap, getstringvalue(name), &cap);
+X if (err != STD_OK)
+X return amoeba_error(err);
+X INCREF(None);
+X return None;
+X}
+X
+Xstatic object *
+Xcap_dir_delete(self, args)
+X capobject *self;
+X object *args;
+X{
+X object *name;
+X errstat err;
+X if (!getstrarg(args, &name))
+X return NULL;
+X err = dir_delete(&self->ob_cap, getstringvalue(name));
+X if (err != STD_OK)
+X return amoeba_error(err);
+X INCREF(None);
+X return None;
+X}
+X
+Xstatic object *
+Xcap_dir_replace(self, args)
+X capobject *self;
+X object *args;
+X{
+X object *name;
+X capability cap;
+X errstat err;
+X if (!getstrcapargs(args, &name, &cap))
+X return NULL;
+X err = dir_replace(&self->ob_cap, getstringvalue(name), &cap);
+X if (err != STD_OK)
+X return amoeba_error(err);
+X INCREF(None);
+X return None;
+X}
+X
+Xstatic object *
+Xcap_dir_list(self, args)
+X capobject *self;
+X object *args;
+X{
+X errstat err;
+X struct dir_open *dd;
+X object *d;
+X char *name;
+X if (!getnoarg(args))
+X return NULL;
+X if ((dd = dir_open(&self->ob_cap)) == NULL)
+X return amoeba_error(STD_COMBAD);
+X if ((d = newlistobject(0)) == NULL) {
+X dir_close(dd);
+X return NULL;
+X }
+X while ((name = dir_next(dd)) != NULL) {
+X object *v;
+X v = newstringobject(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 dir_close(dd);
+X return d;
+X}
+X
+Xobject *
+Xcap_std_info(self, args)
+X capobject *self;
+X object *args;
+X{
+X char buf[256];
+X errstat err;
+X int n;
+X if (!getnoarg(args))
+X return NULL;
+X err = std_info(&self->ob_cap, buf, sizeof buf, &n);
+X if (err != STD_OK)
+X return amoeba_error(err);
+X return newsizedstringobject(buf, n);
+X}
+X
+Xobject *
+Xcap_tod_gettime(self, args)
+X capobject *self;
+X object *args;
+X{
+X header h;
+X errstat err;
+X bufsize n;
+X long sec;
+X int msec, tz, dst;
+X if (!getnoarg(args))
+X return NULL;
+X h.h_port = self->ob_cap.cap_port;
+X h.h_priv = self->ob_cap.cap_priv;
+X h.h_command = TOD_GETTIME;
+X n = trans(&h, NILBUF, 0, &h, NILBUF, 0);
+X if (ERR_STATUS(n))
+X return amoeba_error(ERR_CONVERT(n));
+X tod_decode(&h, &sec, &msec, &tz, &dst);
+X return newintobject(sec);
+X}
+X
+Xobject *
+Xcap_tod_settime(self, args)
+X capobject *self;
+X object *args;
+X{
+X header h;
+X errstat err;
+X bufsize n;
+X long sec;
+X if (!getlongarg(args, &sec))
+X return NULL;
+X h.h_port = self->ob_cap.cap_port;
+X h.h_priv = self->ob_cap.cap_priv;
+X h.h_command = TOD_SETTIME;
+X tod_encode(&h, sec, 0, 0, 0);
+X n = trans(&h, NILBUF, 0, &h, NILBUF, 0);
+X if (ERR_STATUS(n))
+X return amoeba_error(ERR_CONVERT(n));
+X INCREF(None);
+X return None;
+X}
+X
+Xstatic struct methodlist cap_methods[] = {
+X { STUBCODE, sc_interpreter},
+X {"b_read", cap_b_read},
+X {"b_size", cap_b_size},
+X {"dir_append", cap_dir_append},
+X {"dir_delete", cap_dir_delete},
+X {"dir_list", cap_dir_list},
+X {"dir_lookup", cap_dir_lookup},
+X {"dir_replace", cap_dir_replace},
+X {"std_info", cap_std_info},
+X {"tod_gettime", cap_tod_gettime},
+X {"tod_settime", cap_tod_settime},
+X {NULL, NULL} /* Sentinel */
+X};
+EOF
+fi
+if test -s 'src/tokenizer.c'
+then echo '*** I will not over-write existing file src/tokenizer.c'
+else
+echo 'x - src/tokenizer.c'
+sed 's/^X//' > 'src/tokenizer.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/* Tokenizer implementation */
+X
+X/* XXX This is rather old, should be restructured perhaps */
+X/* XXX Need a better interface to report errors than writing to stderr */
+X/* XXX Should use editor resource to fetch true tab size on Macintosh */
+X
+X#include "pgenheaders.h"
+X
+X#include <ctype.h>
+X#include "string.h"
+X
+X#include "fgetsintr.h"
+X#include "tokenizer.h"
+X#include "errcode.h"
+X
+X#ifdef THINK_C
+X#define TABSIZE 4
+X#endif
+X
+X#ifndef TABSIZE
+X#define TABSIZE 8
+X#endif
+X
+X/* Forward */
+Xstatic struct tok_state *tok_new PROTO((void));
+Xstatic int tok_nextc PROTO((struct tok_state *tok));
+Xstatic void tok_backup PROTO((struct tok_state *tok, int c));
+X
+X/* Token names */
+X
+Xchar *tok_name[] = {
+X "ENDMARKER",
+X "NAME",
+X "NUMBER",
+X "STRING",
+X "NEWLINE",
+X "INDENT",
+X "DEDENT",
+X "LPAR",
+X "RPAR",
+X "LSQB",
+X "RSQB",
+X "COLON",
+X "COMMA",
+X "SEMI",
+X "PLUS",
+X "MINUS",
+X "STAR",
+X "SLASH",
+X "VBAR",
+X "AMPER",
+X "LESS",
+X "GREATER",
+X "EQUAL",
+X "DOT",
+X "PERCENT",
+X "BACKQUOTE",
+X "LBRACE",
+X "RBRACE",
+X "OP",
+X "<ERRORTOKEN>",
+X "<N_TOKENS>"
+X};
+X
+X
+X/* Create and initialize a new tok_state structure */
+X
+Xstatic struct tok_state *
+Xtok_new()
+X{
+X struct tok_state *tok = NEW(struct tok_state, 1);
+X if (tok == NULL)
+X return NULL;
+X tok->buf = tok->cur = tok->end = tok->inp = NULL;
+X tok->done = E_OK;
+X tok->fp = NULL;
+X tok->tabsize = TABSIZE;
+X tok->indent = 0;
+X tok->indstack[0] = 0;
+X tok->atbol = 1;
+X tok->pendin = 0;
+X tok->prompt = tok->nextprompt = NULL;
+X tok->lineno = 0;
+X return tok;
+X}
+X
+X
+X/* Set up tokenizer for string */
+X
+Xstruct tok_state *
+Xtok_setups(str)
+X char *str;
+X{
+X struct tok_state *tok = tok_new();
+X if (tok == NULL)
+X return NULL;
+X tok->buf = tok->cur = str;
+X tok->end = tok->inp = strchr(str, '\0');
+X return tok;
+X}
+X
+X
+X/* Set up tokenizer for string */
+X
+Xstruct tok_state *
+Xtok_setupf(fp, ps1, ps2)
+X FILE *fp;
+X char *ps1, *ps2;
+X{
+X struct tok_state *tok = tok_new();
+X if (tok == NULL)
+X return NULL;
+X if ((tok->buf = NEW(char, BUFSIZ)) == NULL) {
+X DEL(tok);
+X return NULL;
+X }
+X tok->cur = tok->inp = tok->buf;
+X tok->end = tok->buf + BUFSIZ;
+X tok->fp = fp;
+X tok->prompt = ps1;
+X tok->nextprompt = ps2;
+X return tok;
+X}
+X
+X
+X/* Free a tok_state structure */
+X
+Xvoid
+Xtok_free(tok)
+X struct tok_state *tok;
+X{
+X /* XXX really need a separate flag to say 'my buffer' */
+X if (tok->fp != NULL && tok->buf != NULL)
+X DEL(tok->buf);
+X DEL(tok);
+X}
+X
+X
+X/* Get next char, updating state; error code goes into tok->done */
+X
+Xstatic int
+Xtok_nextc(tok)
+X register struct tok_state *tok;
+X{
+X if (tok->done != E_OK)
+X return EOF;
+X
+X for (;;) {
+X if (tok->cur < tok->inp)
+X return *tok->cur++;
+X if (tok->fp == NULL) {
+X tok->done = E_EOF;
+X return EOF;
+X }
+X if (tok->inp > tok->buf && tok->inp[-1] == '\n')
+X tok->inp = tok->buf;
+X if (tok->inp == tok->end) {
+X int n = tok->end - tok->buf;
+X char *new = tok->buf;
+X RESIZE(new, char, n+n);
+X if (new == NULL) {
+X fprintf(stderr, "tokenizer out of mem\n");
+X tok->done = E_NOMEM;
+X return EOF;
+X }
+X tok->buf = new;
+X tok->inp = tok->buf + n;
+X tok->end = tok->inp + n;
+X }
+X#ifdef USE_READLINE
+X if (tok->prompt != NULL) {
+X extern char *readline PROTO((char *prompt));
+X static int been_here;
+X if (!been_here) {
+X /* Force rebind of TAB to insert-tab */
+X extern int rl_insert();
+X rl_bind_key('\t', rl_insert);
+X been_here++;
+X }
+X if (tok->buf != NULL)
+X free(tok->buf);
+X tok->buf = readline(tok->prompt);
+X (void) intrcheck(); /* Clear pending interrupt */
+X if (tok->nextprompt != NULL)
+X tok->prompt = tok->nextprompt;
+X /* XXX different semantics w/o readline()! */
+X if (tok->buf == NULL) {
+X tok->done = E_EOF;
+X }
+X else {
+X unsigned int n = strlen(tok->buf);
+X if (n > 0)
+X add_history(tok->buf);
+X /* Append the '\n' that readline()
+X doesn't give us, for the tokenizer... */
+X tok->buf = realloc(tok->buf, n+2);
+X if (tok->buf == NULL)
+X tok->done = E_NOMEM;
+X else {
+X tok->end = tok->buf + n;
+X *tok->end++ = '\n';
+X *tok->end = '\0';
+X tok->inp = tok->end;
+X tok->cur = tok->buf;
+X }
+X }
+X }
+X else
+X#endif
+X {
+X tok->cur = tok->inp;
+X if (tok->prompt != NULL && tok->inp == tok->buf) {
+X fprintf(stderr, "%s", tok->prompt);
+X tok->prompt = tok->nextprompt;
+X }
+X tok->done = fgets_intr(tok->inp,
+X (int)(tok->end - tok->inp), tok->fp);
+X }
+X if (tok->done != E_OK) {
+X if (tok->prompt != NULL)
+X fprintf(stderr, "\n");
+X return EOF;
+X }
+X tok->inp = strchr(tok->inp, '\0');
+X }
+X}
+X
+X
+X/* Back-up one character */
+X
+Xstatic void
+Xtok_backup(tok, c)
+X register struct tok_state *tok;
+X register int c;
+X{
+X if (c != EOF) {
+X if (--tok->cur < tok->buf) {
+X fprintf(stderr, "tok_backup: begin of buffer\n");
+X abort();
+X }
+X if (*tok->cur != c)
+X *tok->cur = c;
+X }
+X}
+X
+X
+X/* Return the token corresponding to a single character */
+X
+Xint
+Xtok_1char(c)
+X int c;
+X{
+X switch (c) {
+X case '(': return LPAR;
+X case ')': return RPAR;
+X case '[': return LSQB;
+X case ']': return RSQB;
+X case ':': return COLON;
+X case ',': return COMMA;
+X case ';': return SEMI;
+X case '+': return PLUS;
+X case '-': return MINUS;
+X case '*': return STAR;
+X case '/': return SLASH;
+X case '|': return VBAR;
+X case '&': return AMPER;
+X case '<': return LESS;
+X case '>': return GREATER;
+X case '=': return EQUAL;
+X case '.': return DOT;
+X case '%': return PERCENT;
+X case '`': return BACKQUOTE;
+X case '{': return LBRACE;
+X case '}': return RBRACE;
+X default: return OP;
+X }
+X}
+X
+X
+X/* Get next token, after space stripping etc. */
+X
+Xint
+Xtok_get(tok, p_start, p_end)
+X register struct tok_state *tok; /* In/out: tokenizer state */
+X char **p_start, **p_end; /* Out: point to start/end of token */
+X{
+X register int c;
+X
+X /* Get indentation level */
+X if (tok->atbol) {
+X register int col = 0;
+X tok->atbol = 0;
+X tok->lineno++;
+X for (;;) {
+X c = tok_nextc(tok);
+X if (c == ' ')
+X col++;
+X else if (c == '\t')
+X col = (col/tok->tabsize + 1) * tok->tabsize;
+X else
+X break;
+X }
+X tok_backup(tok, c);
+X if (col == tok->indstack[tok->indent]) {
+X /* No change */
+X }
+X else if (col > tok->indstack[tok->indent]) {
+X /* Indent -- always one */
+X if (tok->indent+1 >= MAXINDENT) {
+X fprintf(stderr, "excessive indent\n");
+X tok->done = E_TOKEN;
+X return ERRORTOKEN;
+X }
+X tok->pendin++;
+X tok->indstack[++tok->indent] = col;
+X }
+X else /* col < tok->indstack[tok->indent] */ {
+X /* Dedent -- any number, must be consistent */
+X while (tok->indent > 0 &&
+X col < tok->indstack[tok->indent]) {
+X tok->indent--;
+X tok->pendin--;
+X }
+X if (col != tok->indstack[tok->indent]) {
+X fprintf(stderr, "inconsistent dedent\n");
+X tok->done = E_TOKEN;
+X return ERRORTOKEN;
+X }
+X }
+X }
+X
+X *p_start = *p_end = tok->cur;
+X
+X /* Return pending indents/dedents */
+X if (tok->pendin != 0) {
+X if (tok->pendin < 0) {
+X tok->pendin++;
+X return DEDENT;
+X }
+X else {
+X tok->pendin--;
+X return INDENT;
+X }
+X }
+X
+X again:
+X /* Skip spaces */
+X do {
+X c = tok_nextc(tok);
+X } while (c == ' ' || c == '\t');
+X
+X /* Set start of current token */
+X *p_start = tok->cur - 1;
+X
+X /* Skip comment */
+X if (c == '#') {
+X /* Hack to allow overriding the tabsize in the file.
+X This is also recognized by vi, when it occurs near the
+X beginning or end of the file. (Will vi never die...?) */
+X int x;
+X /* XXX The case to (unsigned char *) is needed by THINK C 3.0 */
+X if (sscanf(/*(unsigned char *)*/tok->cur,
+X " vi:set tabsize=%d:", &x) == 1 &&
+X x >= 1 && x <= 40) {
+X fprintf(stderr, "# vi:set tabsize=%d:\n", x);
+X tok->tabsize = x;
+X }
+X do {
+X c = tok_nextc(tok);
+X } while (c != EOF && c != '\n');
+X }
+X
+X /* Check for EOF and errors now */
+X if (c == EOF)
+X return tok->done == E_EOF ? ENDMARKER : ERRORTOKEN;
+X
+X /* Identifier (most frequent token!) */
+X if (isalpha(c) || c == '_') {
+X do {
+X c = tok_nextc(tok);
+X } while (isalnum(c) || c == '_');
+X tok_backup(tok, c);
+X *p_end = tok->cur;
+X return NAME;
+X }
+X
+X /* Newline */
+X if (c == '\n') {
+X tok->atbol = 1;
+X *p_end = tok->cur - 1; /* Leave '\n' out of the string */
+X return NEWLINE;
+X }
+X
+X /* Number */
+X if (isdigit(c)) {
+X if (c == '0') {
+X /* Hex or octal */
+X c = tok_nextc(tok);
+X if (c == '.')
+X goto fraction;
+X if (c == 'x' || c == 'X') {
+X /* Hex */
+X do {
+X c = tok_nextc(tok);
+X } while (isxdigit(c));
+X }
+X else {
+X /* Octal; c is first char of it */
+X /* There's no 'isoctdigit' macro, sigh */
+X while ('0' <= c && c < '8') {
+X c = tok_nextc(tok);
+X }
+X }
+X }
+X else {
+X /* Decimal */
+X do {
+X c = tok_nextc(tok);
+X } while (isdigit(c));
+X /* Accept floating point numbers.
+X XXX This accepts incomplete things like 12e or 1e+;
+X worry about that at run-time.
+X XXX Doesn't accept numbers starting with a dot */
+X if (c == '.') {
+X fraction:
+X /* Fraction */
+X do {
+X c = tok_nextc(tok);
+X } while (isdigit(c));
+X }
+X if (c == 'e' || c == 'E') {
+X /* Exponent part */
+X c = tok_nextc(tok);
+X if (c == '+' || c == '-')
+X c = tok_nextc(tok);
+X while (isdigit(c)) {
+X c = tok_nextc(tok);
+X }
+X }
+X }
+X tok_backup(tok, c);
+X *p_end = tok->cur;
+X return NUMBER;
+X }
+X
+X /* String */
+X if (c == '\'') {
+X for (;;) {
+X c = tok_nextc(tok);
+X if (c == '\n' || c == EOF) {
+X tok->done = E_TOKEN;
+X return ERRORTOKEN;
+X }
+X if (c == '\\') {
+X c = tok_nextc(tok);
+X *p_end = tok->cur;
+X if (c == '\n' || c == EOF) {
+X tok->done = E_TOKEN;
+X return ERRORTOKEN;
+X }
+X continue;
+X }
+X if (c == '\'')
+X break;
+X }
+X *p_end = tok->cur;
+X return STRING;
+X }
+X
+X /* Line continuation */
+X if (c == '\\') {
+X c = tok_nextc(tok);
+X if (c != '\n') {
+X tok->done = E_TOKEN;
+X return ERRORTOKEN;
+X }
+X tok->lineno++;
+X goto again; /* Read next line */
+X }
+X
+X /* Punctuation character */
+X *p_end = tok->cur;
+X return tok_1char(c);
+X}
+X
+X
+X#ifdef DEBUG
+X
+Xvoid
+Xtok_dump(type, start, end)
+X int type;
+X char *start, *end;
+X{
+X printf("%s", tok_name[type]);
+X if (type == NAME || type == NUMBER || type == STRING || type == OP)
+X printf("(%.*s)", (int)(end - start), start);
+X}
+X
+X#endif
+EOF
+fi
+echo 'Part 08 out of 21 of pack.out complete.'
+exit 0