diff options
Diffstat (limited to 'shar/python-0.9.1-08-21.shar')
| -rw-r--r-- | shar/python-0.9.1-08-21.shar | 2349 |
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 |
