aboutsummaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authordos-reis <gdr@axiomatics.org>2007-08-14 05:14:52 +0000
committerdos-reis <gdr@axiomatics.org>2007-08-14 05:14:52 +0000
commitab8cc85adde879fb963c94d15675783f2cf4b183 (patch)
treec202482327f474583b750b2c45dedfc4e4312b1d /src/lib
downloadopen-axiom-ab8cc85adde879fb963c94d15675783f2cf4b183.tar.gz
Initial population.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/ChangeLog211
-rw-r--r--src/lib/Makefile.in77
-rw-r--r--src/lib/Makefile.pamphlet212
-rw-r--r--src/lib/XDither.c.pamphlet254
-rw-r--r--src/lib/XShade.c.pamphlet236
-rw-r--r--src/lib/XSpadFill.c.pamphlet321
-rw-r--r--src/lib/axiom.xpm.pamphlet163
-rw-r--r--src/lib/bsdsignal.c.pamphlet320
-rw-r--r--src/lib/cfuns-c.c.pamphlet285
-rw-r--r--src/lib/cursor.c.pamphlet164
-rw-r--r--src/lib/edin.c.pamphlet971
-rw-r--r--src/lib/emupty.c.pamphlet242
-rw-r--r--src/lib/fnct_key.c.pamphlet395
-rw-r--r--src/lib/halloc.c.pamphlet79
-rw-r--r--src/lib/hash.c.pamphlet240
-rw-r--r--src/lib/openpty.c.pamphlet226
-rw-r--r--src/lib/pixmap.c.pamphlet352
-rw-r--r--src/lib/prt.c.pamphlet429
-rw-r--r--src/lib/sockio-c.c.pamphlet1218
-rw-r--r--src/lib/spadcolors.c.pamphlet618
-rw-r--r--src/lib/util.c.pamphlet192
-rw-r--r--src/lib/wct.c.pamphlet768
22 files changed, 7973 insertions, 0 deletions
diff --git a/src/lib/ChangeLog b/src/lib/ChangeLog
new file mode 100644
index 00000000..cb5b0396
--- /dev/null
+++ b/src/lib/ChangeLog
@@ -0,0 +1,211 @@
+2007-07-27 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet: Partially rework, taking advantage of libtool.
+ * Makefile.in: Regenerate.
+
+2007-03-21 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * cfuns-c.c.pamphlet: Fix typos.
+
+2006-12-15 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * sockio-c.c.pamphlet (is_valid_socket): New function. Check for
+ valid sockets.
+ (sock_accept_connection, server_switch): Use it.
+
+2006-12-15 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * sockio-c.c.pamphlet (axiom_communication_link): Use default
+ protocol.
+
+2006-12-06 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * sockio-c.c.pamphlet (axiom_sleep): Fix return type.
+
+2006-12-06 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * sockio-c.c.pamphlet (AXIOM_AF_LOCAL): New macro.
+ (axiom_sleep): New function. Abstract over differences between
+ Windows and POSIX/UNIX.
+ (send_signal): Use kill only if available.
+ (send_wakeup): Send SIGUSR1 signal only if supported.
+ (open_server): Set SIGPIPE only if supported.
+
+ * cfuns-c.c.pamphlet (axiom_has_write_access): New function.
+ (writeablep): USe it. Document.
+ (readablep): Document. Refactor
+
+2006-12-04 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * cfuns-c.c.pamphlet (getuid, geteuid, getgid, getegid):
+ Define where unavailable in the host environement.
+
+2006-12-04 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * sockio-c.c.pamphlet: Replace __MINGW32__ with __WIN32__.
+
+2006-12-04 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * cfuns-c.c.pamphlet: Remove obfuscation.
+ (directoryp): Simplify.
+
+2006-12-04 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * sockio-c.c.pamphlet: Remove obsfucation.
+ (axiom_load_socket_module): New. Implement initialization required
+ by Winsock.
+ (axiom_communication_link): New. Encapsulate socket creation.
+ (is_invalid_socket): New. Encapsulate test for invalid sockets.
+ (axiom_close_socket): New. Encapsulate socket hang up.
+ (axiom_call_was_cancelled, axiom_connection_refused): New.
+ Encapsulate test for errors.
+ (sread): Use axiom_read, axiom_call_was_cancelled, and
+ axiom_close_socket.
+ (swrite): Use axiom_write, axiom_call_was_cancelled, and
+ axiom_close_socket.
+ (sselect): Use axiom_call_was_cancelled.
+ (send_signal): Use axiom_close_socket.
+ (connect_to_local_server_new): Use axiom_communication_link,
+ is_invalid_socket, and axiom_connection_refused.
+ (connect_to_local_server): Likewise.
+ (close_socket): Use axiom_close_socket.
+ (open_server): Use axiom_communication_link and is_invalid_socket.
+ (accept_connection): USe is_invalid_socket.
+ (sock_accept_connection): Likewise.
+ (server_switch): Likewise.
+
+2006-12-03 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * bsdsignal.c.pamphlet: Use configure-time macro
+ HAVE_DECL_SIGACTION.
+
+2006-12-02 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet (core_sources, terminal_io_sources,
+ graphics_sources): New variables.
+ (libspad_a_sources): Use them.
+ * Makefile.in: Regenerate.
+
+2006-12-01 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * cfuns-c.c.pamphlet (CLgetpid): Remove.
+
+2006-11-30 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * bsdsignal.c.pamphlet: Don't include useproto.h
+ * cfuns-c.c.pamphlet: Likewise.
+ * cursor.c.pamphlet: Likewise.
+ * edin.c.pamphlet: Likewise.
+ * emupty.c.pamphlet: Likewise.
+ * fnct_key.c.pamphlet: Likewise.
+ * halloc.c.pamphlet: Likewise.
+ * hash.c.pamphlet: Likewise.
+ * openpty.c.pamphlet: Likewise.
+ * pixmap.c.pamphlet: Likewise.
+ * prt.c.pamphlet: Likewise.
+ * sockio-c.c.pamphlet: Likewise.
+ * spadcolors.c.pamphlet: Likewise.
+ * util.c.pamphlet: Likewise.
+ * wct.c.pamphlet: Likewise.
+ * XDither.c.pamphlet: Likewise.
+ * XShade.c.pamphlet: Likewise.
+ * XSpadFill.c.pamphlet: Likewise.
+
+2006-11-26 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * XDither.c.pamphlet: Include axiom-c-macros.h
+ * XShade.c.pamphlet: Likewise.
+ * XSpadFill.c.pamphlet: Likewise.
+ * bsdsignal.c.pamphlet: Likewise.
+ * cfuns-c.c.pamphlet: Likewise.
+ * cursor.c.pamphlet: Likewise.
+ * edin.c.pamphlet: Likewise.
+ * fnct_key.c.pamphlet: Likewise.
+ * halloc.c.pamphlet: Likewise.
+ * hash.c.pamphlet: Likewise.
+ * openpty.c.pamphlet: Likewise.
+ * pixmap.c.pamphlet: Likewise.
+ * prt.c.pamphlet: Likewise.
+ * sockio-c.c.pamphlet: Likewise.
+ * spadcolors.c.pamphlet: Likewise.
+ * util.c.pamphlet: Likewise.
+ * wct.c.pamphlet: Likewise.
+
+2006-11-24 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet (INC): Remove.
+ (%.$(OBJEXT)): Depend on $(axiom_c_macros_h).
+ (all-lib): New phony target.
+ * Makefile.in: Regenerate.
+
+2006-11-22 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * pixmap.c.pamphlet: Fix comment thinko.
+
+2006-11-21 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * bsdsignal.c.pamphlet: Remove K&R C style function declaration.
+ * cfuns-c.c.pamphlet: Likewise.
+ * cursor.c.pamphlet: Likewise.
+ * edin.c.pamphlet: Likewise.
+ * emupty.c.pamphlet: Likewise.
+ * fnct_key.c.pamphlet: Likewise.
+ * halloc.c.pamphlet: Likewise.
+ * hash.c.pamphlet: Likewise.
+ * openpty.c.pamphlet: Likewise.
+ * pixmap.c.pamphlet: Likewise.
+ * prt.c.pamphlet: Likewise.
+ * sockio-c.c.pamphlet: Likewise.
+ * spadcolors.c.pamphlet: Likewise.
+ * util.c.pamphlet: Likewise.
+ * wct.c.pamphlet: Likewise.
+ * XDither.c.pamphlet: Likewise.
+ * XShade.c.pamphlet: Likewise.
+ * XSpadFill.c.pamphlet: Likewise.
+
+2006-11-18 Bill Page <bill.page1@synthesis.anikast.ca>
+
+ * Makefile.pamphlet (INC): Add path to X11 header files.
+ * Makefile.in: Regenerate.
+
+2006-10-28 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet (<<cleanup>>): Rename from <<clean-local>>.
+ (mostlyclean-local): New.
+ (clean-local): Tidy.
+ (distclean-local): New.
+
+2006-09-25 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet: Tidy.
+
+2006-09-18 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet: Simplify.
+ * Makefile.in: Regenerate.
+
+2006-09-05 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet ($(builddir)/%.dvi): Ignore noise from latex.
+ ($(builddir)/%.tex): Explicit name the output file.
+ ($(builddir)/%.c): Likewise.
+ * Makefile.in: Regenerate.
+
+2006-09-04 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet: Use generic rules. Remove individual cases
+ that replicate the same pattern. Don't care about MID. Extract
+ to the builddir. Adjust include path INC.
+ (distclean): New rule.
+ * Makefile.in: Regenerate.
+
+2006-09-03 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet: Use axiom class directly -- don't use
+ relative path.
+
+ Use generic rules to make and copy DVI files. Remove special
+ cases.
+
+ * Makefile.in: New.
+
diff --git a/src/lib/Makefile.in b/src/lib/Makefile.in
new file mode 100644
index 00000000..8a22fe97
--- /dev/null
+++ b/src/lib/Makefile.in
@@ -0,0 +1,77 @@
+core_sources = bsdsignal.c cfuns-c.c sockio-c.c
+terminal_io_sources = cursor.c edin.c fnct_key.c openpty.c prt.c wct.c
+graphics_sources = \
+ halloc.c \
+ hash.c \
+ pixmap.c \
+ spadcolors.c \
+ util.c \
+ XDither.c \
+ XShade.c \
+ XSpadFill.c
+
+libspad_la_sources = $(foreach comp, \
+ $(addsuffix _sources, @axiom_c_runtime@), \
+ $($(comp)))
+
+libspad_la_SOURCES = $(addsuffix .pamphlet,$(libspad_la_sources))
+
+other_sources = cfuns-c.c
+
+other_SOURCES = $(addsuffix .pamphlet,$(other_sources))
+
+unused_sources = emupty.c
+
+libspad_la_objects = $(libspad_la_sources:.c=.lo)
+
+other_objects = $(other_sources:.c=.$(OBJEXT))
+
+pamphlets = Makefile.pamphlet $(libspad_la_SOURCES) $(other_SOURCES)
+
+subdir = src/lib/
+
+.PHONY: all all-lib
+.SUFFIXES:
+.SUFFIXES: .o .lo .obj .c .h
+
+all: all-ax
+
+all-ax all-lib: stamp
+stamp: $(axiom_target_libdir)/libspad.la
+ rm -f stamp
+ $(STAMP) stamp
+
+.PHONY: mk-target-libdir
+mk-target-libdir:
+ [ -d $(axiom_target_libdir) ] \
+ || $(mkinstalldirs) $(axiom_target_libdir)
+
+
+$(axiom_target_libdir)/libspad.la: $(libspad_la_objects) mk-target-libdir
+ $(LIBTOOL) --mode=link $(CC) -o $@ $(libspad_la_objects) \
+ -rpath $(libdir)/axiom/target/$(target)/lib
+
+.PRECIOUS: %.c
+
+%.c: $(srcdir)/%.c.pamphlet
+ $(axiom_build_document) --tangle --output=$@ $<
+
+.PRECIOUS: %.$(OBJEXT) %.lo
+
+%.lo: %.c $(axiom_c_macros_h)
+ $(COMPILE) -o $@ $(CCF) $(axiom_includes) $(AXIOM_X11_CFLAGS) $<
+
+# This is a support library, so it does not change often and
+# we don't need to remove the produced objects in mostlyclean.
+# The remoal is done by clean.
+mostlyclean-local:
+ @rm -f *.lo *.$(OBJEXT)
+
+clean-local: mostlyclean-local
+ @$(LIBTOOL) --mode=clean $(axiom_target_libdir)/libspad.la
+ @rm -f $(other_objects)
+ @rm -f $(libspad_la_sources) $(other_sources)
+ @rm -fr .libs _libs
+ @rm -f stamp
+
+distclean-local: clean-local
diff --git a/src/lib/Makefile.pamphlet b/src/lib/Makefile.pamphlet
new file mode 100644
index 00000000..3f2f37ac
--- /dev/null
+++ b/src/lib/Makefile.pamphlet
@@ -0,0 +1,212 @@
+%% Oh Emacs, this is a -*- Makefile -*-, so give me tabs.
+\documentclass{article}
+\usepackage{axiom}
+
+\title{\$SPAD/src/lib Makefile}
+\author{Timothy Daly \and Gabriel Dos~Reis}
+
+\begin{document}
+\maketitle
+
+\begin{abstract}
+ This Makefile builds the \Tool{Axiom} C runtime system. This runtime
+ support consists of three main compoments: core, terminal I/O, and
+ graphics.
+\end{abstract}
+\eject
+
+\tableofcontents
+\eject
+
+\section{Components}
+
+\subsection{Core runtime}
+
+The core C runtime system is required on all hosts. It is composed of
+\begin{itemize}
+\item \verb!iint bsdSignal()!
+\item \verb!int addtopath(const char*)!
+\item \verb!int directoryp(const char*)!
+\item \verb!int make_path_from_file(const char*, const char*)!
+\item \verb!int writeablep(const char*)!
+\item \verb!int readablep(const char*)!
+\item \verb!int findString(const char*, const char*)!
+\item \verb!int copyEnvValue(const char*, char*)!
+\end{itemize}
+
+Those functions are implemented in \File{cfuns-c.c} and
+\File{sockio-c.c}. For the most part,
+they depend on [[<unistd.h>]], [[<sys/stat.h>]], and
+[[<sys/socket.h>]]
+
+<<environment>>=
+core_sources = bsdsignal.c cfuns-c.c sockio-c.c
+@
+
+
+\subsection{Terminal I/O}
+
+This component provides all the routines necessary to build
+the \Tool{Superman} component.
+
+<<environment>>=
+terminal_io_sources = cursor.c edin.c fnct_key.c openpty.c prt.c wct.c
+@
+
+
+\subsection{Graphics}
+
+HyperDoc and any other graphics capability.
+
+<<environment>>=
+graphics_sources = \
+ halloc.c \
+ hash.c \
+ pixmap.c \
+ spadcolors.c \
+ util.c \
+ XDither.c \
+ XShade.c \
+ XSpadFill.c
+@
+
+??? document each of those files.???
+
+
+\section{environment}
+
+The \Tool{Autoconf}-subst'd variable [[axiom_c_runtime]] is computed
+at configure time, based on the characteristics of the host environment.
+It is a list of the main components. It also contain [[core]]
+
+<<environment>>=
+
+libspad_la_sources = $(foreach comp, \
+ $(addsuffix _sources, @axiom_c_runtime@), \
+ $($(comp)))
+
+libspad_la_SOURCES = $(addsuffix .pamphlet,$(libspad_la_sources))
+
+other_sources = cfuns-c.c
+
+other_SOURCES = $(addsuffix .pamphlet,$(other_sources))
+
+unused_sources = emupty.c
+
+libspad_la_objects = $(libspad_la_sources:.c=.lo)
+
+other_objects = $(other_sources:.c=.$(OBJEXT))
+
+pamphlets = Makefile.pamphlet $(libspad_la_SOURCES) $(other_SOURCES)
+@
+
+\section{Files}
+
+\subsection{C from pamphlet}
+<<C from pamphlet>>=
+.PRECIOUS: %.c
+
+%.c: $(srcdir)/%.c.pamphlet
+ $(axiom_build_document) --tangle --output=$@ $<
+@
+
+\subsection{object from C}
+<<object from C>>=
+.PRECIOUS: %.$(OBJEXT) %.lo
+
+%.lo: %.c $(axiom_c_macros_h)
+ $(COMPILE) -o $@ $(CCF) $(axiom_includes) $(AXIOM_X11_CFLAGS) $<
+@
+
+
+
+\subsection{cfuns-c.c \cite{2}}
+The cfuns-c file contains socket primitives used by Axiom.
+They must be linked into and visible from the inferior lisp.
+In GCL this link happens thru setting a shell variable called
+{\bf EXTRAS} in the {\bf h/386-linux.defs} file. This file
+gets included as part of the final system build of GCL.
+
+\subsection{hash.c \cite{6}}
+This a a string-based hash table that is used both in the graph
+and hyper functions. It is included here because we need it built
+earlier so the graph and hyper routines can refer to it.
+
+\subsection{sockio-c.c \cite{10}}
+The sockio-c file contains socket primitives used by Axiom.
+They must be linked into and visible from the inferior lisp.
+In GCL this link happens thru setting a shell variable called
+{\bf EXTRAS} in the {\bf h/386-linux.defs} file. This file
+gets included as part of the final system build of GCL.
+
+\section{The cleanup stanza}
+<<cleanup>>=
+# This is a support library, so it does not change often and
+# we don't need to remove the produced objects in mostlyclean.
+# The remoal is done by clean.
+mostlyclean-local:
+ @rm -f *.lo *.$(OBJEXT)
+
+clean-local: mostlyclean-local
+ @$(LIBTOOL) --mode=clean $(axiom_target_libdir)/libspad.la
+ @rm -f $(other_objects)
+ @rm -f $(libspad_la_sources) $(other_sources)
+ @rm -fr .libs _libs
+ @rm -f stamp
+
+distclean-local: clean-local
+@
+
+<<*>>=
+<<environment>>
+
+subdir = src/lib/
+
+.PHONY: all all-lib
+.SUFFIXES:
+.SUFFIXES: .o .lo .obj .c .h
+
+all: all-ax
+
+all-ax all-lib: stamp
+stamp: $(axiom_target_libdir)/libspad.la
+ rm -f stamp
+ $(STAMP) stamp
+
+.PHONY: mk-target-libdir
+mk-target-libdir:
+ [ -d $(axiom_target_libdir) ] \
+ || $(mkinstalldirs) $(axiom_target_libdir)
+
+
+$(axiom_target_libdir)/libspad.la: $(libspad_la_objects) mk-target-libdir
+ $(LIBTOOL) --mode=link $(CC) -o $@ $(libspad_la_objects) \
+ -rpath $(libdir)/axiom/target/$(target)/lib
+
+<<C from pamphlet>>
+
+<<object from C>>
+
+<<cleanup>>
+@
+
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} {\$SPAD/src/lib/bsdssignal.c.pamphlet}
+\bibitem{2} {\$SPAD/src/lib/cfuns-c.c.pamphlet}
+\bibitem{3} {\$SPAD/src/lib/cursor.c.pamphlet}
+\bibitem{4} {\$SPAD/src/lib/edin.c.pamphlet}
+\bibitem{5} {\$SPAD/src/lib/fnct\_key.c.pamphlet}
+\bibitem{6} {\$SPAD/src/lib/halloc.c.pamphlet}
+\bibitem{7} {\$SPAD/src/lib/openpty.c.pamphlet}
+\bibitem{8} {\$SPAD/src/lib/pixmap.c.pamphlet}
+\bibitem{9} {\$SPAD/src/lib/prt.c.pamphlet}
+\bibitem{10} {\$SPAD/src/lib/sockio-c.c.pamphlet}
+\bibitem{11} {\$SPAD/src/lib/spadcolors.c.pamphlet}
+\bibitem{12} {\$SPAD/src/lib/util.c.pamphlet}
+\bibitem{13} {\$SPAD/src/lib/wct.c.pamphlet}
+\bibitem{14} {\$SPAD/src/lib/XDither.c.pamphlet}
+\bibitem{15} {\$SPAD/src/lib/XShade.c.pamphlet}
+\bibitem{16} {\$SPAD/src/lib/XSpadFill.c.pamphlet}
+\end{thebibliography}
+\end{document}
diff --git a/src/lib/XDither.c.pamphlet b/src/lib/XDither.c.pamphlet
new file mode 100644
index 00000000..8344a584
--- /dev/null
+++ b/src/lib/XDither.c.pamphlet
@@ -0,0 +1,254 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/lib XDither.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+@
+<<*>>=
+<<license>>
+
+#include "axiom-c-macros.h"
+#ifndef MSYSplatform
+
+#include <stdio.h>
+#include <stdlib.h>
+#if !defined(BSDplatform)
+#include <malloc.h>
+#endif
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xos.h>
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#include <X11/cursorfont.h>
+
+#define XDitherWidth 3
+#define XDitherMax 10
+
+char XDitherBits[] = {
+ 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x00,
+ 0x00, 0x03, 0x00,
+ 0x00, 0x03, 0x02,
+ 0x00, 0x07, 0x02,
+ 0x04, 0x07, 0x02,
+ 0x04, 0x07, 0x03,
+ 0x05, 0x07, 0x03,
+ 0x05, 0x07, 0x07,
+ 0x07, 0x07, 0x07 };
+
+#include "XDither.H1"
+
+Pixmap XDither[XDitherMax];
+unsigned int DITHERINIT = 0;
+
+
+
+/*
+ * This routine has the function of returning the number of characters needed
+ * to store a bitmap. It first calculates the number of bits needed per line.
+ * Then it finds the closest multiple of 8 which is bigger than the number of
+ * bits. Once that is done, it multiplies this number by the number of bits
+ * high the bitmap is.
+ */
+int
+dither_char_bitmap(void)
+{
+ int bits_line;
+ int total_chars;
+
+ for (bits_line = 8, total_chars = 1; bits_line < XDitherWidth; total_chars++)
+ bits_line += 8;
+
+ total_chars = total_chars * XDitherWidth;
+
+ return total_chars;
+}
+
+int
+XInitDither(Display *display, int screen, GC gc, unsigned long fg,
+ unsigned long bg)
+{
+
+ char *bits;
+ int count;
+ int chars_bitmap = dither_char_bitmap();
+ int bit;
+ XGCValues xgcv;
+
+ DITHERINIT = 1;
+
+ /*
+ * First thing I should do is load in the Pixmaps
+ */
+ bits = (char *) malloc(chars_bitmap * sizeof(char));
+
+ for (count = 0; count < XDitherMax; count++) {
+
+ /*
+ * Load in the next bitmap
+ */
+ for (bit = 0; bit < chars_bitmap; bit++)
+ bits[bit] = XDitherBits[count * chars_bitmap + bit];
+
+ /*
+ * Create it and put it into the Pixmap array
+ */
+ XDither[count] = XCreatePixmapFromBitmapData(display,
+ RootWindow(display, screen),
+ bits,
+ XDitherWidth, XDitherWidth,
+ BlackPixel(display, screen),
+ WhitePixel(display, screen),
+ 1);
+ }
+
+ /*
+ * Now reset the gc values to be as I need them
+ */
+ xgcv.background = bg;
+ xgcv.foreground = fg;
+ xgcv.fill_style = FillOpaqueStippled;
+ xgcv.stipple = XDither[4];
+
+ XChangeGC(display, gc,
+ GCForeground | GCBackground | GCFillStyle | GCStipple, &xgcv);
+
+ return (XDitherMax);
+
+}
+
+
+int
+XChangeDither(Display *display, GC gc, int dither)
+{
+ if (!DITHERINIT) {
+ fprintf(stderr, "XChange Error: Init Not Called\n");
+ exit(-1);
+ }
+ if (dither >= XDitherMax || dither < 0) {
+ fprintf(stderr, "Dither %d, out of range\n",dither);
+ return (-1);
+ }
+ XSetStipple(display, gc, XDither[dither]);
+ return (1);
+}
+
+
+void
+XDitherRectangle(Display *display, Drawable drawable, GC gc, int x,
+ int y, unsigned int width, unsigned int height)
+{
+
+
+ if (!DITHERINIT) {
+ fprintf(stderr, "XDither Error: Tried to fill before INIT called\n");
+ exit(-1);
+ }
+ XFillRectangle(display, drawable, gc, x, y, width, height);
+
+}
+
+
+void
+XDitherRectangles(Display *display, Drawable drawable, GC gc,
+ XRectangle *rectangles, int nrectangles)
+{
+
+
+ if (!DITHERINIT) {
+ fprintf(stderr, "XDither Error: Tried to fill before INIT called\n");
+ exit(-1);
+ }
+ XFillRectangles(display, drawable, gc,
+ rectangles, nrectangles);
+
+}
+
+
+void
+XDitherPolygon(Display * display, Drawable drawable, GC gc,
+ XPoint *points, int npoints, int shape, int mode)
+{
+ if (!DITHERINIT) {
+ fprintf(stderr, "XDither Error: Tried to fill before INIT called\n");
+ exit(-1);
+ }
+
+ XFillPolygon(display, drawable, gc,
+ points, npoints, shape, mode);
+
+}
+
+void
+XDitherArc(Display *display, Drawable drawable, GC gc, int x,int y,
+ unsigned int width, unsigned int height, int angle1, int angle2)
+{
+
+ if (!DITHERINIT) {
+ fprintf(stderr, "XDither Error: Tried to fill before INIT called\n");
+ exit(-1);
+ }
+ XFillArc(display, drawable, gc, x, y, width,
+ height, angle1, angle2);
+}
+
+
+void
+XDitherArcs(Display *display,Drawable drawable, GC gc, XArc *arcs,int narcs)
+{
+
+ if (!DITHERINIT) {
+ fprintf(stderr, "XDither Error: Tried to fill before INIT called\n");
+ exit(-1);
+ }
+ XFillArcs(display, drawable, gc, arcs, narcs);
+}
+#endif /* MSYSplatform */
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/lib/XShade.c.pamphlet b/src/lib/XShade.c.pamphlet
new file mode 100644
index 00000000..8435b2dd
--- /dev/null
+++ b/src/lib/XShade.c.pamphlet
@@ -0,0 +1,236 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/lib XShade.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+@
+<<*>>=
+<<license>>
+
+#include "axiom-c-macros.h"
+#ifndef MSYSplatform
+
+#include <stdio.h>
+#if !defined(BSDplatform)
+#include <malloc.h>
+#endif
+#include <stdlib.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xos.h>
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#include <X11/cursorfont.h>
+
+#define XShadeWidth 4
+#define XShadeMax 17
+
+char XShadeBits[] = {
+ 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x04, 0x00,
+ 0x05, 0x00, 0x04, 0x00,
+ 0x05, 0x00, 0x05, 0x00,
+ 0x05, 0x02, 0x05, 0x00,
+ 0x05, 0x02, 0x05, 0x08,
+ 0x05, 0x0a, 0x05, 0x08,
+ 0x05, 0x0a, 0x05, 0x0a,
+ 0x07, 0x0a, 0x05, 0x0a,
+ 0x07, 0x0a, 0x0d, 0x0a,
+ 0x0f, 0x0a, 0x0d, 0x0a,
+ 0x0f, 0x0a, 0x0f, 0x0a,
+ 0x0f, 0x0b, 0x0f, 0x0a,
+ 0x0f, 0x0b, 0x0f, 0x0e,
+ 0x0f, 0x0f, 0x0f, 0x0e,
+ 0x0f, 0x0f, 0x0f, 0x0f};
+
+#include "XShade.H1"
+
+Pixmap XShade[XShadeMax];
+GC TileGC;
+unsigned int INIT = 1;
+
+/*
+ * This routine has the function of returning the number of characters needed
+ * to store a bitmap. It first calculates the number of bits needed per line.
+ * Then it finds the closest multiple of 8 which is bigger than the number of
+ * bits. Once that is done, it multiplies this number by the number of bits
+ * high the bitmap is.
+ */
+int
+char_bitmap(void)
+{
+ int bits_line;
+ int total_chars;
+
+ for (bits_line = 8, total_chars = 1; bits_line < XShadeWidth; total_chars++)
+ bits_line += 8;
+
+ total_chars = total_chars * XShadeWidth;
+
+ return total_chars;
+}
+
+int
+XInitShades(Display *display, int screen)
+{
+ char *bits;
+ int count;
+ int chars_bitmap = char_bitmap();
+ int bit;
+
+ bits = (char *) malloc(chars_bitmap * sizeof(char));
+
+ for (count = 0; count < XShadeMax; count++) {
+
+ /* Load in the next bitmap */
+
+ for (bit = 0; bit < chars_bitmap; bit++)
+ bits[bit] = XShadeBits[count * chars_bitmap + bit];
+
+ /* Create it and put it into the Pixmap array */
+
+ XShade[count] = XCreatePixmapFromBitmapData(display,
+ RootWindow(display, screen),
+ bits,
+ XShadeWidth, XShadeWidth,
+ BlackPixel(display, screen),
+ WhitePixel(display, screen),
+ DisplayPlanes(display, screen));
+ }
+ TileGC = XCreateGC(display, RootWindow(display, screen), 0, NULL);
+ XSetFillStyle(display, TileGC, FillTiled);
+ XSetTile(display, TileGC, XShade[XShadeMax / 2]);
+ return XShadeMax;
+}
+
+
+int
+XChangeShade(Display *display, int shade)
+{
+ if (shade >= XShadeMax || shade < 0) {
+ fprintf(stderr, "Shade %d, out of range\n",shade);
+ return (-1);
+ }
+ XSetTile(display, TileGC, XShade[shade]);
+ return (1);
+}
+
+int
+XQueryShades(unsigned int *shades)
+{
+ *shades = XShadeMax;
+ return 1;
+}
+
+
+void
+XShadeRectangle(Display *display, Drawable drawable, int x,int y,
+ unsigned int width, unsigned int height)
+{
+ if (!INIT) {
+ fprintf(stderr, "XShade Error: Tried to fill before INIT called\n");
+ exit(-1);
+ }
+ XFillRectangle(display, drawable, TileGC, x, y, width, height);
+}
+
+
+void
+XShadeRectangles(Display *display, Drawable drawable,
+ XRectangle *rectangles, int nrectangles)
+{
+ if (!INIT) {
+ fprintf(stderr, "XShade Error: Tried to fill before INIT called\n");
+ exit(-1);
+ }
+ XFillRectangles(display, drawable, TileGC,
+ rectangles, nrectangles);
+}
+
+
+void
+XShadePolygon(Display *display, Drawable drawable, XPoint * points,
+ int npoints, int shape, int mode)
+{
+ if (!INIT) {
+ fprintf(stderr, "XShade Error: Tried to fill before INIT called\n");
+ exit(-1);
+ }
+
+ XFillPolygon(display, drawable, TileGC,
+ points, npoints, shape, mode);
+}
+
+void
+XShadeArc(Display *display, Drawable drawable, int x, int y,
+ unsigned int width, unsigned int height, int angle1, int angle2)
+{
+ if (!INIT) {
+ fprintf(stderr, "XShade Error: Tried to fill before INIT called\n");
+ exit(-1);
+ }
+ XFillArc(display, drawable, TileGC, x, y, width,
+ height, angle1, angle2);
+}
+
+
+void
+XShadeArcs(Display *display, Drawable drawable, XArc *arcs, int narcs)
+{
+ if (!INIT) {
+ fprintf(stderr, "XShade Error: Tried to fill before INIT called\n");
+ exit(-1);
+ }
+ XFillArcs(display, drawable, TileGC, arcs, narcs);
+}
+
+#endif /* MSYSplatform */
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/lib/XSpadFill.c.pamphlet b/src/lib/XSpadFill.c.pamphlet
new file mode 100644
index 00000000..0172ea32
--- /dev/null
+++ b/src/lib/XSpadFill.c.pamphlet
@@ -0,0 +1,321 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/lib XSpadFill.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\begin{verbatim}
+
+This file contains the routines needed in order to dither using the
+spadcolors. The routines will have names such as XSpadFill, ... The user
+simply gives the normal arguments as with the corresponding XFill routine,
+with two additional arguments which choose the shade and the hue.
+
+The file will maintain twoGC's: stippleGC - will be used when stippling the
+backgrounds. solidGC - will be used when the background should be solid
+
+The user should call XSpadInit to get everthing going. This routine has the
+job of Initializing the dithering routines, and getting the colors all
+into place.
+
+\end{verbatim}
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+@
+<<*>>=
+<<license>>
+
+#include "axiom-c-macros.h"
+#ifndef MSYSplatform
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xos.h>
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+
+#include "spadcolors.h"
+
+#include "XSpadFill.H1"
+#include "XShade.H1"
+#include "XDither.H1"
+#include "spadcolors.H1"
+
+extern unsigned long *spadColors;
+static GC stippleGC, solidGC;
+Colormap cmap;
+int SpadFillInit = 0;
+long white, black;
+int max_spad_shades;
+extern Display *dsply;
+
+extern int totalHues;
+extern int totalDithered;
+extern int totalSolid;
+extern int totalShades;
+extern int totalColors;
+extern int maxGreyShade;
+
+int
+XInitSpadFill(Display *dsply, int scr, Colormap * mapOfColors, int * hues,
+ int *solid, int * dithered, int * shades)
+{
+ int maxDither;
+ XColor BlackColor, WhiteColor;
+ XColor retColor;
+ int maxSolid;
+
+ SpadFillInit = 1;
+
+
+ /*
+ * First thing I should do is get the GC's
+ */
+ stippleGC = XCreateGC(dsply, RootWindow(dsply, scr), 0, NULL);
+ solidGC = XCreateGC(dsply, RootWindow(dsply, scr), 0, NULL);
+ XSetArcMode(dsply, solidGC, ArcPieSlice);
+ XSetArcMode(dsply, stippleGC, ArcPieSlice);
+
+
+ cmap = DefaultColormap(dsply, scr);
+ *mapOfColors = cmap;
+ XAllocNamedColor(dsply, cmap, "Black", &BlackColor, &retColor);
+ XAllocNamedColor(dsply, cmap, "White", &WhiteColor, &retColor);
+ black = BlackColor.pixel;
+ white = WhiteColor.pixel;
+
+ /*
+ * Now I check to see if I am on a monochrome display. If so then I
+ * simply set totalHues to be one, and total Shades to be 2. I also have
+ * to allocate balck and white colors. This I put into the first two
+ * memory locations of spadcolors.
+ *
+ * was if(DisplayPlanes(dsply, scr) < 2) changed temporarily to < 8
+ * because of problems with screens with 4 planes . Now if we don't have
+ * 8 planes to play with we switch to monochrome
+ */
+
+ if (DisplayPlanes(dsply, scr) < 8) {
+ *dithered = totalDithered = maxGreyShade = XInitShades(dsply, scr);
+ maxDither = *dithered - 1;
+ spadColors = (unsigned long *) malloc(2 * sizeof(unsigned long));
+ spadColors[0] = BlackColor.pixel;
+ spadColors[1] = WhiteColor.pixel;
+ *hues = totalHues = 1;
+ *solid = totalSolid = 2;
+ *shades = totalColors = totalShades = totalDithered;
+ return (totalColors);
+ }
+
+ /*
+ * Now I have to get all the spad colors as every good spad program
+ * should Now I should initialize the dithering routines
+ */
+
+ *dithered = totalDithered =
+ XInitDither(dsply, scr, stippleGC, black, white);
+ maxDither = *dithered - 1;
+
+ if ((maxSolid = makeColors(dsply, scr, &cmap, &spadColors, &totalSolid)) > 0) {
+ *solid = totalSolid + 2;
+ *hues = totalHues = maxSolid / totalSolid;
+ *shades = totalShades = (totalSolid + 1) * (totalDithered - 1) + 1;
+ totalColors = totalHues * totalShades;
+ return (totalColors);
+ }
+ else {
+
+ /*
+ * makeColors managed to fail -- switch to mono
+ */
+ *dithered = totalDithered = maxGreyShade = XInitShades(dsply, scr);
+ maxDither = *dithered - 1;
+ spadColors = (unsigned long *) malloc(2 * sizeof(unsigned long));
+ spadColors[0] = BlackColor.pixel;
+ spadColors[1] = WhiteColor.pixel;
+ *hues = totalHues = 1;
+ *solid = totalSolid = 2;
+ *shades = totalColors = totalShades = totalDithered;
+ return (totalColors);
+ }
+}
+
+
+void
+XSpadFillSetArcMode(Display *dsply, int mode)
+{
+ XSetArcMode(dsply, solidGC, mode);
+ XSetArcMode(dsply, stippleGC, mode);
+}
+
+GC
+SpadFillGC(Display *dsply,int hue, int theshade,char * fill_routine)
+{
+ int dither;
+ int color;
+
+
+ if (!SpadFillInit) {
+ fprintf(stderr, "Tried to use SpadFillGC before calling XInitSpadFill\n");
+ exit(0);
+ }
+
+ if (theshade >= totalShades) {
+ fprintf(stderr, "Shade %d out of range\n",theshade);
+ exit(-1);
+ }
+ if (hue >= totalHues) {
+ fprintf(stderr, "Error Hue %d is out of range\n",hue);
+ exit(-1);
+ }
+ dither = ((theshade) % (totalDithered - 1));
+ if (dither != 0) {
+ XChangeDither(dsply, stippleGC, dither);
+ if (theshade < totalDithered) { /* Dither to black */
+ color = totalSolid * hue;
+ XSetForeground(dsply, stippleGC, black);
+ XSetBackground(dsply, stippleGC, spadColors[color]);
+ }
+ else if (theshade > (totalShades - totalDithered)) { /* Dither to white */
+ color = ((theshade) / (totalDithered - 1)) + totalSolid * hue - 1;
+ XSetForeground(dsply, stippleGC, spadColors[color]);
+ XSetBackground(dsply, stippleGC, white);
+ }
+ else {
+ color = ((theshade) / (totalDithered - 1)) + totalSolid * hue - 1;
+ XSetForeground(dsply, stippleGC, spadColors[color]);
+ XSetBackground(dsply, stippleGC, spadColors[color + 1]);
+ }
+ return (stippleGC);
+ }
+ else {
+ if (theshade == 0)
+ XSetForeground(dsply, solidGC, black);
+ else if (theshade == (totalShades - 1))
+ XSetForeground(dsply, solidGC, white);
+ else {
+ color = ((theshade) / (totalDithered - 1)) + totalSolid * hue - 1;
+ XSetForeground(dsply, solidGC, spadColors[color]);
+ }
+ return (solidGC);
+ }
+
+}
+
+unsigned long
+XSolidColor(int hue, int theshade)
+{
+ if (hue >= totalHues)
+ return -1;
+ if (theshade >= totalSolid)
+ return -1;
+ return (spadColors[hue * (totalSolid) + theshade]);
+}
+
+void
+XSpadFillRectangle(Display *dsply, Drawable drawable, int x, int y,
+ unsigned int width, unsigned int height,
+ int hue, int theshade)
+{
+
+ XFillRectangle(dsply, drawable,
+ SpadFillGC(dsply, hue, theshade, "XSpadFillRectangle"),
+ x, y, width, height);
+
+}
+
+
+void
+XSpadFillRectangles(Display *dsply, Drawable drawable,
+ XRectangle * rectangles, int nrectangles,
+ int hue, int theshade)
+{
+
+
+ XFillRectangles(dsply, drawable,
+ SpadFillGC(dsply, hue, theshade, "XSpadFillRectangle"),
+ rectangles, nrectangles);
+
+}
+
+
+void
+XSpadFillPolygon(Display *dsply, Drawable drawable, XPoint * points,
+ int npoints, int shape, int mode, int hue, int theshade)
+{
+ XFillPolygon(dsply, drawable,
+ SpadFillGC(dsply, hue, theshade, "XSpadFillRectangle"),
+ points, npoints, shape, mode);
+
+}
+
+void
+XSpadFillArc(Display *dsply, Drawable drawable, int x, int y,
+ unsigned int width, unsigned int height,
+ int angle1, int angle2, int hue, int theshade)
+{
+
+ XFillArc(dsply, drawable,
+ SpadFillGC(dsply, hue, theshade, "XSpadFillRectangle"),
+ x, y, width, height, angle1, angle2);
+}
+
+
+void
+XSpadFillArcs(Display *dsply, Drawable drawable,XArc *arcs, int narcs,
+ int hue, int theshade)
+{
+ XFillArcs(dsply, drawable,
+ SpadFillGC(dsply, hue, theshade, "XSpadFillArcs"),
+ arcs, narcs);
+}
+
+
+#endif /* MSYSplatform */
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/lib/axiom.xpm.pamphlet b/src/lib/axiom.xpm.pamphlet
new file mode 100644
index 00000000..bb78e3af
--- /dev/null
+++ b/src/lib/axiom.xpm.pamphlet
@@ -0,0 +1,163 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/lib axiom.xpm}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+<<*>>=
+/* XPM */
+static char ourcolormap[] = {
+/* width height ncolors chars_per_pixel */
+"137 1 137 2",
+/* colors */
+"`` c #000000",
+"`a c #6FE0E0",
+"`b c #086025",
+"`c c #E09C6F",
+"`d c #606008",
+"`e c #C4EFE1",
+"`f c #E0866F",
+"`g c #341C93",
+"`h c #604E08",
+"`i c #E07A6F",
+"`j c #604608",
+"`k c #BFBF30",
+"`l c #C96FE0",
+"`m c #603408",
+"`n c #6F9CE0",
+"`o c #602208",
+"`p c #601A08",
+"`q c #6F86E0",
+"`r c #3D0860",
+"`s c #600808",
+"`t c #93581C",
+"`u c #30BFBF",
+"`v c #934C1C",
+"`w c #7B1C93",
+"`x c #BF7730",
+"`y c #083D60",
+"`z c #4E0860",
+"a` c #93401C",
+"aa c #BF6930",
+"ab c #082B60",
+"ac c #93341C",
+"ad c #BF5B30",
+"ae c #93281C",
+"af c #BF4D30",
+"ag c #931C1C",
+"ah c #436008",
+"ai c #BF3F30",
+"aj c #3069BF",
+"ak c #30BF30",
+"al c #95E06F",
+"am c #304DBF",
+"an c #1C9344",
+"ao c #BAE06F",
+"ap c #44931C",
+"aq c #1C931C",
+"ar c #EFE6C4",
+"as c #EFE2C4",
+"at c #DEC4EF",
+"au c #EFDEC4",
+"av c #EFCCC4",
+"aw c #EFC8C4",
+"ax c #EFC4C4",
+"ay c #30BF8F",
+"az c #EFC4EF",
+"b` c #60BF30",
+"ba c #1A0860",
+"bb c #1C4C93",
+"bc c #2B0860",
+"bd c #C4E6EF",
+"be c #C4DEEF",
+"bf c #1C3493",
+"bg c #E0D56F",
+"bh c #C4CCEF",
+"bi c #1C1C93",
+"bj c #C4C4EF",
+"bk c #E0C96F",
+"bl c #086043",
+"bm c #E0B36F",
+"bn c #D5C4EF",
+"bo c #E0A76F",
+"bp c #E0916F",
+"bq c #605708",
+"br c #6FC9E0",
+"bs c #E6C4EF",
+"bt c #631C93",
+"bu c #6FB3E0",
+"bv c #E06F6F",
+"bw c #93931C",
+"bx c #603D08",
+"by c #866FE0",
+"bz c #6FE06F",
+"c` c #93871C",
+"ca c #BFB030",
+"cb c #602B08",
+"cc c #937B1C",
+"cd c #6B931C",
+"ce c #BFA230",
+"cf c #936F1C",
+"cg c #086060",
+"ch c #4D30BF",
+"ci c #BF9430",
+"cj c #601108",
+"ck c #93631C",
+"cl c #8630BF",
+"cm c #084E60",
+"cn c #BF30BF",
+"co c #BF8630",
+"cp c #4C1C93",
+"cq c #6F6FE0",
+"cr c #CCC4EF",
+"cs c #30A2BF",
+"ct c #081A60",
+"cu c #3086BF",
+"cv c #080860",
+"cw c #BF3030",
+"cx c #256008",
+"cy c #931C93",
+"cz c #E1EFC4",
+"d` c #6FE0BA",
+"da c #3030BF",
+"db c #B36FE0",
+"dc c #6930BF",
+"dd c #FFFFFF",
+"de c #A230BF",
+"df c #C4EFD2",
+"dg c #EFEFC4",
+"dh c #EFEBC4",
+"di c #600860",
+"dj c #1C9393",
+"dk c #6FE095",
+"dl c #9C6FE0",
+"dm c #EFD9C4",
+"dn c #EFD5C4",
+"do c #1C7B93",
+"dp c #EFD1C4",
+"dq c #1C936B",
+"dr c #1C6393",
+"ds c #086008",
+"dt c #8FBF30",
+"du c #C4EFC4",
+"dv c #C4EFEF",
+"dw c #E0E06F",
+"dx c #C4D5EF",
+"dy c #30BF60",
+"dz c #E0BE6F",
+"e` c #E06FE0",
+"ea c #D2EFC4",
+/* pixels */
+"`sagcwbvaxcjaeai`iaw`pacaf`fav`oa`adbpdpcb`vaa`cdn`m`t`xbodmbxckcobmau`jcfcidzas`hcccebkarbqc`cabgdh`dbw`kdwdgahcddtaoczcxapb`aleadsaqakbzdu`bandydkdfbldqayd``ecgdj`u`advcmdocsbrbd`ydrcububeabbbaj`ndxctbfam`qbhcvbidacqbjba`gchbycrbccpdcdlbn`rbtcldbat`z`wde`lbsdicycne`az``dd"
+};
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/lib/bsdsignal.c.pamphlet b/src/lib/bsdsignal.c.pamphlet
new file mode 100644
index 00000000..5807659b
--- /dev/null
+++ b/src/lib/bsdsignal.c.pamphlet
@@ -0,0 +1,320 @@
+\documentclass{article}
+\usepackage{axiom}
+
+\newcommand{\var}[1]{\textsl{#1}}
+
+\title{\File{src/lib/bsdsignal.c} Pamphlet}
+\author{The Axiom Team}
+
+\begin{document}
+\maketitle
+
+\begin{abstract}
+\end{abstract}
+\eject
+
+\tableofcontents
+\newpage
+
+\section{Executive Overview}
+
+\section{Signals}
+
+The system defines a set of signals that may be delivered to a process.
+Signal
+delivery resembles the occurrence of a hardware interrupt: the signal is
+normally blocked from further occurrence, the current process context is
+saved,
+and a new one is built. A process may specify a \emph{handler} to
+which a signal
+is delivered, or specify that a signal is to be \emph{ignored}. A process may
+also specify that a default action is to be taken by the system when a signal
+occurs. A signal may also be \emph{blocked}, in which case its delivery is
+postponed until it is \emph{unblocked}. The action to be taken on delivery is
+determined at the time of delivery. Normally, signal handlers execute on the
+current stack of the process. This may be changed, on a per-handler basis, so
+that signals are taken on a special \emph{signal stack}.
+
+Signal routines normally execute with the signal that caused their invocation
+\emph{blocked}, but other signals may yet occur. A global \emph{signal mask}
+defines the set of signals currently blocked from delivery to a process.
+The signal mask for a process is initialized from that of its parent
+(normally empty). It may be changed with a \emph{[[sigprocmask]](2)} call, or
+when a signal is delivered to the process.
+
+When a signal condition arises for a process, the signal is added to a set of
+signals pending for the process. If the signal is not currently \emph{blocked}
+by the process then it is delivered to the process. Signals may be delivered
+any time a process enters the operating system (e.g., during a system call,
+page fault or trap, or clock interrupt). If muliple signals are ready to be
+delivered at the same time, any signals that could be caused by traps are
+delivered first. Additional signals may be processed at the same time, with
+each appearing to interrupt the handlers for the previous signals before
+their first instructions. The set of pending signals is retuned by the
+\emph{[[sigpending]](2)} system call. When a caught signal is delivered,
+the current
+state of the process is saved, a new signal mask is calculated (as described
+below), and the signal handler is invoked. The call to the handler is arranged
+so that if the signal handling routine returns normally the process will resume
+execution in the context from before the signal's delivery. If the process
+wishes to resume in a different context, then it must arrange to restore
+the previous context itself.
+
+When a signal is delivered to a proces a new signal mask is installed for the
+duration of the process's signal handler (or until a \emph{[[sigprocmask]](2)}
+system call is made). This mask is formed by taking the union of the current
+signal mask set, the signal to be delivered, and the signal mask associated
+with the handler to be invoked.
+
+The \emph{[[sigaction]]()} system call assigns an action for a signal
+specified by \var{sig}. If \var{act} is non-zero, it specifies an action
+([[SIG_DFL]], [[SIG_IGN]], or a handler routine) and mask to be used when
+delivering the specified signal.
+If \var{oact} is non-zero, the previous handling information for the signal is
+returned to the user.
+
+Once a signal handler is installed, it normally remains installed until
+another
+[[sigaction()]] system call is made, or an \emph{[[execve]](2)} is performed.
+A
+signal-specific default action may be reset by setting [[sa_handler]] to
+[[SIG_DFL]]. The defaults are process termination, possibly with core dump;
+no action; stopping the process; or continuing the process. See the signal
+list below for each signal's default action. If [[sa_handler]] is [[SIG_DFL]],
+the default action for the signal is to discard the signal, and if a signal
+is pending, the pending signal is discarded even if the signal is masked. If
+[[sa_handler]] is set to [[SIG_IGN]] current and pending instances of the
+signal
+are ignored and discarded.
+
+Options may be specified by setting [[sa_flags]]. The meaning of the various
+bits is as follows:
+\begin{tabular}{ll}
+SA\_NOCLDSTOP & If this bit is set when installing a catching function for\\
+ & the SIGCHLD signal, the SIGCHLD signal will be generated only\\
+ & when a child process exits, not when a child process stops.\\
+SA\_NOCLDWAIT & If this bit is set when calling {\sl sigaction()} for the\\
+ & SIGCHLD signal, the system will not create zombie processes\\
+ & when children of the calling process exit. If the calling\\
+ & process subsequently issues a {\sf wait()} (or equivalent),\\
+ & it blocks until all of the calling process's child processes\\
+ & terminate, and then returns a value of -1 with errno set to\\
+ & ECHILD.\\
+SA\_ONSTACK & If this bit is set, the system will deliver the signal to\\
+ & the process on a {\sl signal stack}, specified with\\
+ & {\bf sigaltstack(2)}.\\
+SA\_NODEFER & If this bit is set, further occurrences of the delivered\\
+ & signal are not masked during the execution of the handler.\\
+SA\_RESETHAND & If this bit is set, the handler is reset back to SIG\_DFL\\
+ & at the moment the signal is delivered.\\
+SA\_RESTART & See the paragraph below\\
+SA\_SIGINFO & If this bit is set, the handler function is assumed to be\\
+ & pointed to by the sa\_sigaction member of struct sigaction\\
+ & and should match the prototype shown above or as below in\\
+ & EXAMPLES. This bit should not be set when assigning SIG\_DFL\\
+ & or SIG\_IGN
+\end{tabular}
+
+If a signal is caught during the system calls listed below, the call may be
+forced to terminate with the error [[EINTR]], the call may return with a data
+transfer shorter than requested, or the call may be restarted. Restart of
+pending calls is requested by setting the SA\_RESTART bit in {\sl sa\_flags}.
+The affected system calls include {\bf open(2)}, {\bf read(2)}, {\bf write(2)},
+{\bf sendto(2)}, {\bf recvfrom(2)}, {\bf sendmsg(2)} and {\bf recvmsg(2)}
+on a communications channel or a slow device (such as a terminal, but not a
+regular file) and during a {\bf wait(2)} or {\bf ioctl(2)}. However, calls
+that have already committed are not restarted, but instead return a partial
+success (for example, a short read count).
+
+After a {\bf fork(2)} or {\bf vfork(2)} all signals, the signal mask, the
+signal stack, and the restart/interrupt flags are inherited by the child.
+
+The {\bf execve(2)} system call reinstates the default action for all signals
+which were caught and resets all signals to be caught on the user stack.
+Ignored signals remain ignored; the signal mask remains the same; signals
+that restart pending system calls continue to do so.
+
+The following is a list of all signals with names as in the include file
+{\sl <signal.h>}:
+
+\begin{tabular}{lll}
+{\bf NAME} & {\bf Default Action} & Description\\
+SIGHUP & terminate process & terminal line hangup\\
+SIGINT & terminate process & interrupt program\\
+SIGQUIT & create core image & quit program\\
+SIGILL & create core image & illegal instruction\\
+SIGTRAP & create core image & trace trap\\
+SIGABRT & create core image & {\bf abort(3)} call (formerly SIGIOT)\\
+SIGEMT & create core image & emulate instruction executed\\
+SIGFPE & create core image & floating-point exception\\
+SIGKILL & terminate process & kill program\\
+SIGBUS & create core image & bus error\\
+SIGSEGV & create core image & segmentation violation\\
+SIGSYS & create core image & non-existent system call invoked\\
+SIGPIPE & terminate process & write on a pipe with no reader\\
+SIGALRM & terminate process & real-time timer expired\\
+SIGTERM & terminate process & software termination signal\\
+SIGURG & discard signal & urgent condition present on socket\\
+SIGSTOP & stop process & stop (cannot be caught or ignored)\\
+SIGSTP & stop process & stop signal generated from keyboard\\
+SIGCONT & discard signal & continue after stop\\
+SIGCHLD & discard signal & child status has changed\\
+SIGTTIN & stop process & background read attempted from \\
+ & & control terminal\\
+SIGTTOU & stop process & background write attempted from\\
+ & & control terminal\\
+SIGIO & discard signal & I/O is possible on a descriptor {\bf fcntl(2)}\\
+SIGXCPU & terminate process & cpu time limit exceeded {\bf setrlimit(2)}\\
+SIGXFSZ & terminate process & file size limit exceeded {\bf setrlimit(2)}\\
+SIGVTALRM & terminate process & virtual time alarm {\bf setitimer(2)}\\
+SIGPROF & terminate process & profiling timer alarm {\bf setitimer(2)}\\
+SIGWINCH & discard signal & Window size change\\
+SIGINFO & discard signal & status request from keyboard\\
+SIGUSR1 & terminate process & User defined signal 1\\
+SIGUSR2 & terminate process & User defined signal 2
+\end{tabular}
+
+The {\sl sigaction()} function returns the value 0 if successful; otherwise
+the value -1 is returned and the global variable {\sl errno} is set to indicate
+the error.
+
+Signal handlers should have either the ANSI C prototype:
+\begin{verbatim}
+ void handler(int);
+\end{verbatim}
+or the POSIX SA\_SIGINFO prototype:
+\begin{verbatim}
+ void handler(int, siginfo\_t *info, ucontext\_t *uap);
+\end{verbatim}
+
+The handler function should match the SA\_SIGINFO prototype if the SA\_SIGINFO
+bit is set in flags. It then should be pointed to by the sa\_sigaction member
+of struct sigaction. Note that you should not assign SIG\_DFL or SIG\_IGN this way.
+
+If the SA\_SIGINFO flag is not set, the handler function should match either
+the ANSI C or traditional BSD prototype and be pointed to by the sa\_handler
+member of struct sigaction. In practice, FreeBSD always sends the three
+arguments of the latter and since the ANSI C prototype is a subset, both
+will work. The sa\_handler member declaration in FreeBSD include files is
+that of ANSI C (as required by POSIX), so a function pointer of a BSD-style
+function needs to be casted to compile without warning. The traditional BSD
+style is not portable and since its capabilities are a full subset of a
+SA\_SIGNFO handler its use is deprecated.
+
+The {\sl sig} argument is the signal number, one of the SIG\ldots values from
+{\sl <signal.h>}.
+
+The {\sl code} argument of the BSD-style handler and the si\_code member of the
+info argument to a SA\_SIGINFO handler contain a numeric code explaining the
+cause of the signal, usually on of the SI\_\ldots values from {\sl <sys/signal.h>}
+or codes specific to a signal, i.e. one of the FPE\_\ldots values for SIGFPE.
+
+The {\sl uap} argument to a POSIX SA\_SIGINFO handler points to an instance of
+ucontext\_t.
+
+The {\bf sigaction()} system call will fail and no new signal handler will be
+installed if one of the following occurs:
+\begin{tabular}{ll}
+EFAULT & Either {\sl act} or {\sl oact} points to memory that is not a\\
+ & valid part of the process address space\\
+EINVAL & The {\sl sig} argument is not a valid signal number\\
+EINVAL & An attempt is made to ignore or supply a handler for SIGKILL\\
+ & or SIGSTOP
+\end{tabular}
+\section{MAC OSX and BSD platform change}
+<<*>>=
+<<license>>
+
+#include "axiom-c-macros.h"
+#include "bsdsignal.h"
+
+@
+The MACOSX platform is broken because no matter what you do it seems to
+include files from [[/usr/include/sys]] ahead of [[/usr/include]]. On linux
+systems these files include themselves which causes an infinite regression
+of includes that fails. GCC gracefully steps over that problem but the
+build fails anyway. On MACOSX the [[/usr/include/sys]] versions
+of files are badly broken with respect to the [[/usr/include]] versions.
+<<*>>=
+#if defined(MACOSXplatform)
+#include "/usr/include/signal.h"
+#else
+#include <signal.h>
+#endif
+
+#include "bsdsignal.H1"
+
+
+SignalHandlerFunc
+bsdSignal(int sig, SignalHandlerFunc action, int restartSystemCall)
+{
+#if HAVE_DECL_SIGACTION
+
+ struct sigaction in,out;
+ in.sa_handler = action;
+ /* handler is reinstalled - calls are restarted if restartSystemCall */
+@
+
+We needed to change [[SIGCLD]] to [[SIGCHLD]] for the [[MAC OSX]] platform
+and we need to create a new platform variable. This change is made to
+propogate that platform variable.
+<<*>>=
+#ifdef SA_RESTART
+ if(restartSystemCall) in.sa_flags = SA_RESTART;
+ else in.sa_flags = 0;
+#elif defined(SA_INTERRUPT)
+ if (restartSystemCall) in.sa_flags = 0;
+ else in.sa_flags = SA_INTERRUPT;
+#else
+ in.sa_flags = 0;
+#endif
+
+ return (sigaction(sig, &in, &out) ? (SignalHandlerFunc) -1 :
+ (SignalHandlerFunc) out.sa_handler);
+#else /* !HAVE_DECL_SIGACTION */
+ return (SignalHandlerFunc) -1;
+#endif /* HAVE_DECL_SIGACTION */
+}
+
+
+@
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+@
+\newpage
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/lib/cfuns-c.c.pamphlet b/src/lib/cfuns-c.c.pamphlet
new file mode 100644
index 00000000..ad5a97e8
--- /dev/null
+++ b/src/lib/cfuns-c.c.pamphlet
@@ -0,0 +1,285 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/lib cfuns-c.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+@
+<<*>>=
+<<license>>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "axiom-c-macros.h"
+
+#include "cfuns-c.H1"
+
+/* Most versions of Windows don't have the POSIX functions getuid(),
+ geteuid(), getgid(), and getegid(). The following definitions are
+ approximations, to patch for the deficiencies of Windows
+ POSIX interface. */
+
+#if !HAVE_DECL_GETUID
+# define getuid() 0
+#endif
+
+#if !HAVE_DECL_GETGID
+# define getgid() 0
+#endif
+
+#if !HAVE_DECL_GETEUID
+# define geteuid() getuid()
+#endif
+
+#if !HAVE_DECL_GETEGID
+# define getegid() getgid()
+#endif
+
+int
+addtopath(char *dir)
+{
+ char *path, *newpath;
+
+ path = getenv("PATH");
+ if (path == NULL)
+ return -1;
+
+ newpath = (char *) malloc(1 + strlen(path) + strlen(dir) + strlen("PATH=:"));
+ if (newpath == NULL)
+ return -1;
+
+ sprintf(newpath, "PATH=%s:%s", path, dir);
+
+ return putenv(newpath);
+}
+
+/*
+ * Test whether the path is the name of a directory. Returns 1 if so, 0 if
+ * not, -1 if it doesn't exist.
+ */
+
+
+int
+directoryp(char *path)
+{
+ struct stat buf;
+ int code = stat(path, &buf);
+
+ return code == -1 ? -1 : S_ISDIR(buf.st_mode);
+}
+
+int
+make_path_from_file(char *s, char *t)
+{
+ char *pos = "";
+ char *c;
+
+ /** simply copies the path name from t into s **/
+ for (c = t + strlen(t); c != s; c--)
+ if (*c == '/') {
+ pos = c;
+ break;
+ }
+ /** Check to see if the path was actually present **/
+ if (c == t) { /** No Path, so return the pwd **/
+ return (-1);
+ }
+ /** now just do the copying **/
+ strncpy(s, t, pos - t);
+ return 1;
+}
+
+/* The functions writeablep() and readablep() determine write and
+ read access of a file designated by its name. The function
+ axiom_has_write_access is a sub-routine of writeablep.
+
+ The access is determined based on the POSIX semantics; see
+ "Advanced Programming in the UNIX Environement", section 4.5.
+
+ 1. If the effective user ID of the process is 0 (the superuser),
+ access is allowed. This gives the superuser free rein throughout
+ the entire file system.
+
+ 2. If the effective user ID of the process equals the owner ID of
+ the file (i.e., the process owns the file), access is allowed
+ if the appropriate user access permission bit is set. [...]
+
+ 3. If the effective group ID of the process or one of the
+ supplementary group IDs of the process equals the group ID
+ of the file, access is allowed if the appropriate
+ group access permission bit is set. Otherwise, permission
+ is denied.
+
+ 4. If the appropriate other access permission bit is set, access is
+ allowed. Otherwise, permission is defined. */
+
+
+/* Return 1 if the process has write access of file as explained above.
+ Otherwise, return 0. */
+
+static inline int
+axiom_has_write_access(const struct stat* file_info)
+{
+ int effetive_uid = geteuid();
+
+ if (effetive_uid == 0)
+ return 1;
+
+ if (effetive_uid == file_info->st_uid)
+ return file_info->st_mode & S_IWUSR;
+
+#ifdef S_IWGRP
+ if (getegid() == file_info->st_gid)
+ return file_info->st_mode & S_IWGRP;
+#endif
+
+#ifdef S_IWOTH
+ return file_info->st_mode & S_IWOTH;
+#else
+ return 0;
+#endif
+}
+
+
+/* Return
+ -1 if the file designated by PATH is inexistent.
+ 0 if the file exists but wirte access is denied.
+ 1 if the file exists and process has write access.
+ 2 if the file does not exists but process has write
+ has write access to the dirname of path. */
+
+int
+writeablep(char *path)
+{
+ struct stat buf;
+ char newpath[100];
+ int code;
+
+ code = stat(path, &buf);
+ if (code == -1) {
+ /** The file does not exist, so check to see
+ if the directory is writable *****/
+ if (make_path_from_file(newpath, path) == -1
+ || stat(newpath, &buf) == -1)
+ return -1;
+
+ return 2 * axiom_has_write_access(&buf);
+ }
+
+ return axiom_has_write_access(&buf);
+}
+
+
+/* Return
+ -1 if the file designated by PATH is inexistent.
+ 0 if the file exists but process has no read access.
+ 1 if the file exists and read access is granted. */
+
+int
+readablep(char *path)
+{
+ struct stat buf;
+ int code;
+
+ code = stat(path, &buf);
+ if (code == -1)
+ return -1;
+
+ if (geteuid() == buf.st_uid)
+ return ((buf.st_mode & S_IREAD) != 0);
+
+#ifdef S_IRGRP
+ if (getegid() == buf.st_gid)
+ return ((buf.st_mode & S_IRGRP) != 0);
+#endif
+
+#ifdef S_IROTH
+ return ((buf.st_mode & S_IROTH) != 0);
+#else
+ return 0;
+#endif
+}
+
+
+
+long
+findString(char *file, char *string)
+{
+ int nstring, charpos;
+ FILE *fn;
+ char buffer[1024];
+
+ if ((fn = fopen(file, "r")) == NULL)
+ return -1;
+
+ for (charpos = 0, nstring = strlen(string);
+ fgets(buffer, sizeof buffer, fn) != NULL;
+ charpos += strlen(buffer)
+ )
+ if (!strncmp(buffer, string, nstring))
+ return charpos;
+ return -1;
+
+}
+
+int
+copyEnvValue(char *varName, char *buffer)
+{
+ char *s;
+
+ s = getenv(varName);
+ if (s == NULL)
+ return 0;
+ strcpy(buffer, s);
+ return strlen(s);
+}
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/lib/cursor.c.pamphlet b/src/lib/cursor.c.pamphlet
new file mode 100644
index 00000000..dd2d34da
--- /dev/null
+++ b/src/lib/cursor.c.pamphlet
@@ -0,0 +1,164 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/lib cursor.c}
+\author{Stephen Watt, James Wen}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+@
+<<*>>=
+<<license>>
+
+#include <stdlib.h>
+#include "axiom-c-macros.h"
+
+#include "cursor.H1"
+
+/*
+ * This routine changes the shape of the cursor. it is a modified version of
+ * a program by SMWatt, called cursor.c. JMW 6/22/89
+ */
+
+/* this stuff can only be done on AIX <AND> the right terminal (aixterm,hft) */
+#if (defined(RIOSplatform) || defined(RTplatform)) && !defined(_AIX41)
+#include "edible.h"
+/* the HFT stuff requires ioctl's and termio's */
+#include <termio.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/hft.h>
+
+int
+Cursor_shape(int shape)
+{
+ int hftfd;
+ char hftpath[16], s[100];
+ int chno;
+ int i;
+ struct termio oldterm, newterm;
+ struct hftgetid hftgid;
+ char *termVal;
+
+ termVal = (char *) getenv("TERM");
+ if (strcmp("hft", termVal) && strncmp("aixterm", termVal, 7))
+ return;
+
+
+
+ /* determine the desired shape */
+ if (shape < 0 || shape > 5) {
+ fprintf(stderr, "%d - Invalid cursor number\n");
+ return (-1);
+ }
+ /* change the shape */
+ s[0] = 033; /* hf_intro.hf_esc */
+ s[1] = '['; /* hf_intro.hf_lbr */
+ s[2] = 'x'; /* hf_intro.hf_ex */
+ s[3] = 0; /* hf_intro.hf_len[0] */
+ s[4] = 0; /* hf_intro.hf_len[1] */
+ s[5] = 0; /* hf_intro.hf_len[2] */
+ s[6] = 10; /* hf_intro.hf_len[3] */
+ s[7] = 2; /* hf_intro.hf_typehi */
+ s[8] = 8; /* hf_intro.hf_typelo */
+ s[9] = 2; /* hf_sublen */
+ s[10] = 0; /* hf_subtype */
+ s[11] = 0; /* hf_rsvd */
+ s[12] = shape; /* hf_shape */
+
+ if (ioctl(0, HFTGETID, &hftgid) < 0) {
+ /* perror("ioctl: HFTGETID"); */
+ chno = -1;
+ }
+ else
+ chno = hftgid.hf_chan;
+ if (chno == -1) {
+ /** try being moronic and just writing what I want to
+ standard output ****/
+
+ if (((ioctl(2, TCGETA, &oldterm)) == -1) ||
+ ((ioctl(2, TCGETA, &newterm)) == -1)) {
+ perror("Getting termio");
+ exit(0);
+ }
+ newterm.c_oflag = newterm.c_lflag = newterm.c_iflag = 0;
+ newterm.c_cc[0] = -1;
+ for (i = 1; i <= 5; i++)
+ newterm.c_cc[i] = 0;
+ if ((ioctl(2, TCSETAF, &newterm)) == -1) {
+ perror("Setting to raw mode");
+ exit(0);
+ }
+ write(2, s, 13);
+ read(0, s, 1024);
+ if ((ioctl(2, TCSETAF, &oldterm)) == -1) {
+ perror("Resetting terminal");
+ exit(0);
+ }
+ }
+ else {
+ /* open the currently active virtual terminal on the hft */
+ sprintf(hftpath, "/dev/hft/%d", chno);
+ if ((hftfd = open(hftpath, O_RDWR)) == -1) {
+ perror("Could not open hft channel\n");
+ exit(0);
+ }
+ write(hftfd, s, 13);
+ }
+}
+#else
+
+int
+Cursor_shape(int shape)
+{
+ return shape;
+}
+#endif
+
+
+
+
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/lib/edin.c.pamphlet b/src/lib/edin.c.pamphlet
new file mode 100644
index 00000000..97b9143a
--- /dev/null
+++ b/src/lib/edin.c.pamphlet
@@ -0,0 +1,971 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/lib edin.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+@
+<<*>>=
+<<license>>
+
+/* #define debug 1 */
+
+#include <stdlib.h>
+#include "axiom-c-macros.h"
+@
+The MACOSX platform is broken because no matter what you do it seems to
+include files from [[/usr/include/sys]] ahead of [[/usr/include]]. On linux
+systems these files include themselves which causes an infinite regression
+of includes that fails. GCC gracefully steps over that problem but the
+build fails anyway. On MACOSX the [[/usr/include/sys]] versions
+of files are badly broken with respect to the [[/usr/include]] versions.
+<<*>>=
+#if defined(MACOSXplatform)
+#include "/usr/include/unistd.h"
+#else
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+
+#include "edible.h"
+
+#define HFT 0
+#define SUN 1
+#define DEC 2
+#define control_to_alpha(x) (x + ('A' - 0x01))
+#define alpha_to_control(x) (x - ('A' - 0x01))
+
+int termId;
+QueStruct *ring = NULL;
+QueStruct *current = NULL;
+int ring_size = 0;
+int MAXRING = 64;
+int prev_check = 10;
+int curr_pntr;
+int num_pntr;
+int num_proc;
+int had_tab;
+int had_tab_last;
+extern char buff[1024]; /* Buffers for collecting input and */
+extern int buff_flag[1024]; /* flags for whether buff chars
+ are printing or non-printing */
+int buff_pntr; /* present length of buff */
+
+
+#include "edin.H1"
+#include "prt.H1"
+#include "wct.H1"
+#include "cursor.H1"
+#include "fnct_key.H1"
+
+
+
+void
+init_reader(void)
+{
+ char *termVal;
+
+ buff[50] = '\0'; /** initialize some stuff ***/
+ init_flag(buff_flag, MAXLINE);
+ buff_pntr = curr_pntr = 0;
+
+ had_tab = 0;
+ had_tab_last = 0;
+ termVal = (char *) getenv("TERM");
+ if (!strcmp("sun", termVal))
+ termId = SUN;
+ else if (!strcmp("xterm", termVal) || !strncmp("vt", termVal, 2))
+ termId = DEC;
+ else if (!strcmp("hft", termVal) || !strncmp("aixterm", termVal, 7))
+ termId = HFT;
+}
+
+
+void
+do_reading(void)
+{
+ int ttt_read;
+ int done_completely;
+
+ done_completely = 0;
+ num_proc = 0;
+ while (num_proc < num_read) {
+ if(in_buff[num_proc]== _ERASE) {
+ back_over_current_char();
+ num_proc++;
+ }
+ else {
+ switch (in_buff[num_proc]) {
+ /* lets start checking for different types of chars */
+ case _EOLN:
+ case _CR:
+ /* If I have read a complete line, so send it to the child */
+ send_line_to_child();
+ if (!PTY)
+ myputchar('\n');
+ break;
+
+ /*
+ * Use 0x7f as delete
+ */
+ case _DEL:
+ /* Had a delete key */
+ delete_current_char();
+ break;
+
+ case _CNTRL_W:
+ move_back_word();
+ num_proc++;
+ break;
+ case _TAB:
+ had_tab = 1;
+ /* command completion stuff */
+ num_proc++;
+ if (had_tab_last)
+ rescan_wct();
+ else
+ find_wct();
+ break;
+ case _BELL:
+ insert_buff_nonprinting(1);
+ putchar(_BELL);
+ fflush(stdout);
+ break;
+ case _ESC:
+
+ /*
+ * get 2 characters more
+ */
+ while (!(num_read - num_proc > 2)) {
+ ttt_read = read(0,
+ in_buff + num_read,
+ 2 - (num_read - num_proc) + 1);
+ if (ttt_read > 0)
+ num_read = num_read + ttt_read;
+ }
+ if ((in_buff[num_proc + 1] == _LBRACK)) {
+
+ /* ESC [ */
+
+ switch (in_buff[num_proc + 2]) {
+ /* look for arrows */
+ case _A:
+ /* up arrow */
+
+ /*
+ * The first thing I plan to do is get rid of the present
+ * input **
+ */
+ prev_buff();
+ curr_pntr = buff_pntr;
+ num_proc = num_proc + 3;
+ break;
+ case _B:
+ /* down arrow */
+ next_buff();
+ curr_pntr = buff_pntr;
+ num_proc = num_proc + 3;
+ break;
+ case _C:
+ /* right arrow */
+ move_ahead();
+ num_proc = num_proc + 3;
+ break;
+ case _D:
+ /* left arrow */
+ move_back();
+ num_proc = num_proc + 3;
+ break;
+
+ /*
+ * Use ^[[P as delete
+ */
+ case _P:
+ /*** Had a delete key ****/
+ delete_current_char();
+ break;
+ case _H:
+ case 0:
+ move_home();
+ num_proc += 3;
+ break;
+ case _M:
+ case _Z:
+ insert_buff_nonprinting(3);
+ done_completely = 1;
+ num_proc += 3;
+ break;
+ case _x:
+ num_proc = num_read;
+ break;
+ case _1:
+ case _2:
+ case _0:
+
+ /*
+ * I have had a possible function key hit, look for the
+ * ones I want. check for ESC ] x ~
+ */
+ while (!(num_read - num_proc > 3)) {
+ ttt_read = read(0,
+ in_buff + num_read,
+ 3 - (num_read - num_proc) + 1);
+ if (ttt_read > 0)
+ num_read = num_read + ttt_read;
+ }
+ if (in_buff[num_proc + 3] == _twiddle) {
+
+ /*
+ * treat ESC ] x ~
+ */
+ switch (in_buff[num_proc + 2]) {
+ case _2:
+ flip(INS_MODE);
+ if (INS_MODE)
+ Cursor_shape(5);
+ else
+ Cursor_shape(2);
+ reprint(curr_pntr);
+ num_proc += 4;
+ break;
+ default:
+ insert_buff_nonprinting(1);
+ break;
+ }
+ break;
+ }
+ /* check for ESC ] x y ~ */
+ while (!(num_read - num_proc > 4)) {
+ ttt_read = read(0,
+ in_buff + num_read,
+ 4 - (num_read - num_proc) + 1);
+ if (ttt_read > 0)
+ num_read = num_read + ttt_read;
+ }
+ if (in_buff[num_proc + 4] == _twiddle) {
+
+ /*
+ * treat ESC ] x y ~
+ */
+ insert_buff_nonprinting(1);
+ break;
+ }
+
+ /* check for ESC ] x y z [q|z] */
+
+ while (!(num_read - num_proc > 5)) {
+ ttt_read = read(0,
+ in_buff + num_read,
+ 5 - (num_read - num_proc) + 1);
+ if (ttt_read > 0)
+ num_read = num_read + ttt_read;
+ }
+ if (insert_toggle(&in_buff[num_proc + 3])) {
+ flip(INS_MODE);
+ if (INS_MODE)
+ Cursor_shape(5);
+ else
+ Cursor_shape(2);
+ reprint(curr_pntr);
+ num_proc = num_proc + 6;
+ break;
+ }
+ else if (cntrl_end(&in_buff[num_proc + 3])) {
+ num_proc = num_proc + 6;
+ delete_to_end_of_line();
+ break;
+ }
+ else if (back_word(&in_buff[num_proc + 3])) {
+ move_back_word();
+ num_proc += 6;
+ break;
+ }
+ else if (fore_word(&in_buff[num_proc + 3])) {
+ move_fore_word();
+ num_proc += 6;
+ break;
+ }
+ else if (end_key(&in_buff[num_proc + 3])) {
+ move_end();
+ num_proc += 6;
+ break;
+ }
+ switch (in_buff[num_proc + 5]) {
+ case _q:
+
+ /*
+ * IBM function keys
+ */
+ {
+ char num[3];
+ int key;
+
+ num[0] = in_buff[num_proc + 3];
+ num[1] = in_buff[num_proc + 4];
+ num[2] = '\0';
+ key = atoi(num);
+ if (key > 0 && key < 13) {
+ if (function_key[key].str != NULL) {
+ handle_function_key(key, contNum);
+ done_completely = 1;
+ }
+ else {
+ insert_buff_nonprinting(6);
+ done_completely = 1;
+ }
+ }
+ else {
+ insert_buff_nonprinting(6);
+ done_completely = 1;
+ }
+ break;
+ }
+ case _z:
+
+ /*
+ * Sun function keys
+ */
+ {
+ char num[3];
+ int key;
+
+ num[0] = in_buff[num_proc + 3];
+ num[1] = in_buff[num_proc + 4];
+ num[2] = '\0';
+ key = atoi(num) - 23;
+ if (key > 0 && key < 13) {
+ if (function_key[key].str != NULL) {
+ handle_function_key(key, contNum);
+ done_completely = 1;
+ }
+ else {
+ insert_buff_nonprinting(6);
+ done_completely = 1;
+ }
+ }
+ else if (atoi(num) == 14) {
+ move_home();
+ num_proc += 6;
+ done_completely = 1;
+ }
+ else if (atoi(num) == 20) {
+ move_end();
+ num_proc += 6;
+ done_completely = 1;
+ }
+ else if (atoi(num) == 47) {
+ flip(INS_MODE);
+ if (INS_MODE)
+ Cursor_shape(5);
+ else
+ Cursor_shape(2);
+ reprint(curr_pntr);
+ num_proc = num_proc + 6;
+ done_completely = 1;
+ }
+ else {
+ insert_buff_nonprinting(6);
+ done_completely = 1;
+ }
+
+ break;
+ }
+
+ default:
+ insert_buff_nonprinting(1);
+ break;
+ }
+ default:
+ if (!done_completely)
+ insert_buff_nonprinting(1);
+ break;
+ }
+ } /* if */
+ else { /* ESC w/o [ */
+ insert_buff_nonprinting(1);
+ }
+ break;
+
+ case _BKSPC:
+ back_over_current_char();
+ num_proc++;
+ break;
+ default:
+ if (in_buff[num_proc] == _KILL) {
+ delete_line();
+ num_proc++;
+ }
+ else {
+ if ((in_buff[num_proc] == _INTR) || (in_buff[num_proc] == _QUIT)) {
+ write(contNum, &in_buff[num_proc], num_read - num_proc);
+ if (!PTY)
+ write(contNum, "\n", 1);
+ num_proc++;
+ }
+ else {
+ if (in_buff[num_proc] == _EOF) {
+ insert_buff_nonprinting(1);
+ if (!PTY)
+ write(contNum, "\n", 1);
+
+ /*comment out this bit
+ if (!buff_pntr) {
+ write(contNum, &in_buff[num_proc], 1);
+ if (!PTY)
+ write(contNum, "\n", 1);
+ }
+ else {
+ write(contNum, buff, buff_pntr);
+ }
+ */
+ num_proc++;
+ }
+ else {
+ if (in_buff[num_proc] == _EOL) {
+ send_line_to_child();
+ if (!PTY)
+ write(contNum, "\n", 1);
+ }
+ else {
+ if (in_buff[num_proc] == _ERASE) {
+ back_over_current_char();
+ num_proc++;
+ }
+ else {
+ if (control_char(in_buff[num_proc]))
+ insert_buff_nonprinting(1);
+ else
+ insert_buff_printing(1);
+ }
+ }
+ }
+ }
+ } /* close the default case */
+ break;
+ } /* switch */
+ } /*else*/
+ if (had_tab) {
+ had_tab_last = 1;
+ had_tab = 0;
+ }
+ else
+ had_tab_last = 0;
+
+ } /* while */
+}
+
+
+
+void
+send_line_to_child(void)
+{
+ static char converted_buffer[MAXLINE];
+ int converted_num;
+
+ /* Takes care of sending a line to the child, and resetting the
+ buffer for new input */
+
+ back_it_up(curr_pntr);
+
+ /* start by putting the line into the command line ring ***/
+ if (buff_pntr)
+ insert_queue();
+
+ /* finish the line and send it to the child **/
+ buff[buff_pntr] = in_buff[num_proc];
+ buff_flag[buff_pntr++] = 1;
+ buff[buff_pntr] = '\0';
+ buff_flag[buff_pntr] = -1;
+
+ /*
+ * Instead of actually writing the Line, I have to substitute in the
+ * actual characters recieved
+ */
+ converted_num =
+ convert_buffer(converted_buffer, buff, buff_flag, buff_pntr);
+ write(contNum, converted_buffer, converted_num);
+
+ /** reinitialize the buffer ***/
+ init_flag(buff_flag, buff_pntr);
+ init_buff(buff, buff_pntr);
+ /** reinitialize my buffer pointers **/
+ buff_pntr = curr_pntr = 0;
+
+ /** reset the ring pointer **/
+ current = NULL;
+ num_proc++;
+ return;
+}
+
+int
+convert_buffer(char *target, char *source,int * source_flag, int num)
+{
+ int i, j;
+
+ /*
+ * Until I get something wierd, just keep copying
+ */
+ for (i = 0, j = 0; i < num; i++, j++) {
+ switch (source[i]) {
+ case _CARROT:
+ if (source_flag[i] == 1) {
+ target[j] = source[i];
+ }
+ else {
+ if (source[i + 1] == _LBRACK) {
+ target[j] = _ESC;
+ i++;
+ }
+ else if (source[i + 1] >= 'A' && source[i + 1] <= 'Z') {
+ target[j] = alpha_to_control(source[i + 1]);
+ i++;
+ }
+ }
+ break;
+ case '?':
+ default:
+ target[j] = source[i];
+ }
+ }
+ return j;
+}
+
+
+void
+insert_buff_printing(int amount)
+{
+ int count;
+
+ /* This procedure takes the character at in_buff[num_proc] and adds
+ it to the buffer. It first checks to see if we should be inserting
+ or overwriting, and then does the appropriate thing */
+
+ if ((buff_pntr + amount) > 1023) {
+ putchar(_BELL);
+ fflush(stdout);
+ num_proc += amount;
+ }
+ else {
+
+ if (INS_MODE) {
+
+ forwardcopy(&buff[curr_pntr + amount],
+ &buff[curr_pntr],
+ buff_pntr - curr_pntr);
+ forwardflag_cpy(&buff_flag[curr_pntr + amount],
+ &buff_flag[curr_pntr],
+ buff_pntr - curr_pntr);
+ for (count = 0; count < amount; count++) {
+ buff[curr_pntr + count] = in_buff[num_proc + count];
+ buff_flag[curr_pntr + count] = 1;
+ }
+ ins_print(curr_pntr, amount);
+ buff_pntr = buff_pntr + amount;
+ }
+ else {
+ for (count = 0; count < amount; count++) {
+ if (buff_flag[curr_pntr + count] == 2) {
+ myputchar(buff[curr_pntr + count]);
+ curr_pntr += count + 1;
+ delete_current_char();
+ /** fix num_proc affected by delete **/
+ num_proc -= 3;
+ curr_pntr -= count + 1;
+ myputchar(_BKSPC);
+ }
+ buff[curr_pntr + count] = in_buff[num_proc + count];
+ buff_flag[curr_pntr + count] = 1;
+ }
+ myputchar(in_buff[num_proc]);
+ if (curr_pntr == buff_pntr)
+ buff_pntr++;
+ }
+ num_proc = num_proc + amount;
+ curr_pntr = curr_pntr + amount;
+ fflush(stdout);
+ }
+ return;
+
+}
+
+void
+insert_buff_nonprinting(int amount)
+{
+ int count;
+
+ /* This procedure takes the character at in_buff[num_proc] and adds
+ it to the buffer. It first checks to see if we should be inserting
+ or overwriting, and then does the appropriate thing */
+
+ /* it takes care of the special case, when I have an esc character */
+
+ if ((buff_pntr + amount) > 1023) {
+ myputchar(_BELL);
+ fflush(stdout);
+ num_proc += amount;
+ }
+ else {
+ if (INS_MODE) {
+ forwardcopy(&buff[curr_pntr + amount + 1],
+ &buff[curr_pntr],
+ buff_pntr - curr_pntr);
+ forwardflag_cpy(&buff_flag[curr_pntr + amount + 1],
+ &buff_flag[curr_pntr],
+ buff_pntr - curr_pntr);
+ /** now insert the special character **/
+ switch (in_buff[num_proc]) {
+ case _ESC:
+ /** in this case I insert a '^[' into the string ***/
+ buff[curr_pntr] = _CARROT;
+ buff_flag[curr_pntr] = 2;
+ buff[curr_pntr + 1] = _LBRACK;
+ buff_flag[curr_pntr + 1] = 0;
+ break;
+ default:
+ if (control_char(in_buff[num_proc])) {
+ buff[curr_pntr] = _CARROT;
+ buff_flag[curr_pntr] = 2;
+ buff[curr_pntr + 1] = control_to_alpha(in_buff[num_proc]);
+ buff_flag[curr_pntr + 1] = 0;
+ }
+ else {
+ /** What do I have ? **/
+ buff[curr_pntr] = '?';
+ buff_flag[curr_pntr] = 2;
+ buff[curr_pntr + 1] = in_buff[num_proc];
+ buff_flag[curr_pntr] = 0;
+ break;
+ }
+ }
+ /** Now add the normal characters **/
+ for (count = 1; count < amount; count++) {
+ buff[curr_pntr + count + 1] = in_buff[num_proc + count];
+ buff_flag[curr_pntr + count + 1] = 1;
+ }
+ ins_print(curr_pntr, amount + 1);
+ buff_pntr = buff_pntr + amount + 1;
+ }
+ else {
+ /** I am in the overstrike mode **/
+ switch (in_buff[num_proc]) {
+ case _ESC:
+ /** in this case I insert a '^[' into the string ***/
+ buff[curr_pntr] = _CARROT;
+ buff_flag[curr_pntr] = 2;
+ buff[curr_pntr + 1] = _LBRACK;
+ buff_flag[curr_pntr + 1] = 0;
+ break;
+ default:
+ if (control_char(in_buff[num_proc])) {
+ buff[curr_pntr] = _CARROT;
+ buff_flag[curr_pntr] = 2;
+ buff[curr_pntr + 1] = control_to_alpha(in_buff[num_proc]);
+ buff_flag[curr_pntr + 1] = 0;
+ }
+ else {
+ /** What do I have ? **/
+ buff[curr_pntr] = '?';
+ buff_flag[curr_pntr] = 2;
+ buff[curr_pntr + 1] = in_buff[num_proc];
+ buff_flag[curr_pntr] = 0;
+ break;
+ }
+ }
+ for (count = 1; count < amount; count++) {
+ if (buff_flag[curr_pntr + count] == 2) {
+ curr_pntr += count + 1;
+ delete_current_char();
+ /** fix num. processed form delete **/
+ num_proc -= 3;
+ curr_pntr -= count + 1;
+ }
+ buff[curr_pntr + count + 1] = in_buff[num_proc + count];
+ buff_flag[curr_pntr + count + 1] = 1;
+ }
+ /** now print the characters I have put in **/
+ printbuff(curr_pntr, amount + 1);
+ }
+ num_proc = num_proc + amount;
+ curr_pntr = curr_pntr + amount + 1;
+ if (curr_pntr > buff_pntr)
+ buff_pntr = curr_pntr;
+ }
+ return;
+
+}
+
+void
+prev_buff(void)
+{
+
+ /*
+ * If the current command ring is NULL, then I should NOT clear the
+ * current line. Thus my business is already done
+ */
+ if (ring == NULL)
+ return;
+ clear_buff();
+ init_buff(buff, buff_pntr);
+ init_flag(buff_flag, buff_pntr);
+
+ if (current == NULL) {
+ if (ring == NULL)
+ return;
+ current = ring;
+ }
+ else
+ current = current->prev;
+ strcpy(buff, current->buff);
+ flagcpy(buff_flag, current->flags);
+
+ /* first back up and blank the line */
+ fflush(stdout);
+ printbuff(0, strlen(buff));
+ curr_pntr = buff_pntr = strlen(buff);
+ fflush(stdout);
+ return ;
+}
+
+void
+next_buff(void)
+{
+
+ /*
+ * If the current command ring is NULL, then I should NOT clear the
+ * current line. Thus my business is already done
+ */
+ if (ring == NULL)
+ return;
+ clear_buff();
+ init_buff(buff, buff_pntr);
+ init_flag(buff_flag, buff_pntr);
+ if (current == NULL) {
+ if (ring == NULL)
+ return;
+ current = ring->next;
+ }
+ else
+ current = current->next;
+ strcpy(buff, current->buff);
+ flagcpy(buff_flag, current->flags);
+
+ /* first back up and blank the line **/
+ fflush(stdout);
+ printbuff(0, strlen(buff));
+ curr_pntr = buff_pntr = strlen(buff);
+ fflush(stdout);
+ return ;
+}
+
+
+void
+forwardcopy(char *buff1,char * buff2,int num)
+{
+ int count;
+
+ for (count = num; count >= 0; count--)
+ buff1[count] = buff2[count];
+}
+
+
+void
+forwardflag_cpy(int *buff1,int * buff2,int num)
+{
+ int count;
+
+ for (count = num; count >= 0; count--)
+ buff1[count] = buff2[count];
+}
+
+void
+flagcpy(int *s,int *t)
+{
+ while (*t >= 0)
+ *s++ = *t++;
+ *s = *t;
+}
+
+void
+flagncpy(int *s,int *t,int n)
+{
+ while (n-- > 0)
+ *s++ = *t++;
+}
+
+void
+insert_queue(void)
+{
+ QueStruct *trace;
+ QueStruct *new;
+ int c;
+
+ if (!ECHOIT)
+ return;
+ if (ring != NULL && !strcmp(buff, ring->buff))
+ return;
+ for (c = 0, trace = ring; trace != NULL && c < (prev_check - 1);
+ c++, trace = trace->prev) {
+ if (!strcmp(buff, trace->buff)) {
+
+ /*
+ * throw this puppy at the end of the ring
+ */
+ trace->next->prev = trace->prev;
+ trace->prev->next = trace->next;
+ trace->prev = ring;
+ trace->next = ring->next;
+ ring->next = trace;
+ trace->next->prev = trace;
+ ring = trace;
+ return;
+ }
+ }
+
+ /*
+ * simply places the buff command into the front of the queue
+ */
+ if (ring_size < MAXRING) {
+ new = (QueStruct *) malloc(sizeof(struct que_struct));
+ if (new == NULL) {
+ fprintf(stderr, "Malloc Error: Ran out of memory\n");
+ exit(-1);
+ }
+ if (ring_size == 0) {
+ ring = new;
+ ring->prev = ring->next = new;
+ }
+ else {
+ new->next = ring->next;
+ new->prev = ring;
+ ring->next = new;
+ new->next->prev = new;
+ ring = new;
+ }
+ ring_size++;
+ }
+ else
+ ring = ring->next;
+
+ init_flag(ring->flags, MAXLINE);
+ init_buff(ring->buff, MAXLINE);
+ strcpy(ring->buff, buff);
+ flagncpy(ring->flags, buff_flag, buff_pntr);
+ (ring->buff)[buff_pntr] = '\0';
+ (ring->flags)[buff_pntr] = -1;
+}
+
+
+void
+init_flag(int *flags, int num)
+{
+ int i;
+
+ for (i = 0; i < num; i++)
+ flags[i] = -1;
+}
+
+void
+init_buff(char *flags, int num)
+{
+ int i;
+
+ for (i = 0; i < num; i++)
+ flags[i] = '\0';
+}
+
+
+void
+send_function_to_child(void)
+{
+ /* Takes care of sending a line to the child, and resetting the
+ buffer for new input */
+
+ back_it_up(curr_pntr);
+ /** start by putting the line into the command line ring ***/
+ if (buff_pntr)
+ insert_queue();
+
+ /** finish the line and send it to the child **/
+ buff[buff_pntr] = _EOLN;
+
+ buff_flag[buff_pntr++] = 1;
+ buff[buff_pntr] = '\0';
+ buff_flag[buff_pntr] = 0;
+ write(contNum, buff, buff_pntr);
+
+ /** reinitialize the buffer ***/
+ init_flag(buff_flag, buff_pntr);
+ init_buff(buff, buff_pntr);
+ /** reinitialize my buffer pointers **/
+ buff_pntr = curr_pntr = 0;
+
+ /** reset the ring pointer **/
+ current = NULL;
+
+ num_proc++;
+ return;
+}
+
+void
+send_buff_to_child(int chann)
+{
+ if (buff_pntr > 0)
+ write(chann, buff, buff_pntr);
+ num_proc += 6;
+ /** reinitialize the buffer ***/
+ init_flag(buff_flag, buff_pntr);
+ init_buff(buff, buff_pntr);
+ /** reinitialize my buffer pointers **/
+ buff_pntr = curr_pntr = 0;
+ /** reset the ring pointer **/
+ current = NULL;
+ return;
+}
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/lib/emupty.c.pamphlet b/src/lib/emupty.c.pamphlet
new file mode 100644
index 00000000..32dd3931
--- /dev/null
+++ b/src/lib/emupty.c.pamphlet
@@ -0,0 +1,242 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/lib emupty.c}
+\author{Nick Simicich}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+@
+<<*>>=
+<<license>>
+
+#include "axiom-c-macros.h"
+
+/*
+ Here is some code taken from Nick Simicich. It takes an escape sequence
+ from the child, and if I am actually talking to an HFT device, it
+ translates that escape sequence into an ioctl call.
+ */
+
+
+#if 0
+
+#include "edible.h"
+#include "sys/devinfo.h"
+#include <sys/ioctl.h>
+
+typedef union {
+ struct hfintro *hf;
+ struct hfctlreq *re;
+ char *c;
+} Argument;
+
+emuhft(Argument arg, int tty, int ptc, int len)
+{
+ /* What does it do? */
+ /* 1. There are a number of ioctl's associated with the HFT terminal. */
+ /* 2. When an HFT terminal is being emulated over a PTY, the */
+ /* IOCTL cannot be executed directly on the server end of the PTY. */
+ /* 3. A system defined structure is set up such that the program */
+ /* at the end of the PTY can issue the ioctl as an escape */
+ /* sequence and get its response as an escape sequence. */
+ /* 4. This is badly broken, even stupid. If the protocol is */
+ /* defined, and everyone is supposed to use it, then the HFT */
+ /* should react directly to it. But No.... */
+ /* 5. Furthermore, our terminal itself might be a pty. In that */
+ /* case, we have to transmit the data just as we got it to the */
+ /* other PTY, instead of executing the IOCTL. */
+
+ static union {
+ struct hfintro hfi;
+ struct hfctlack ackn;
+ char charvector[1024]; /* Spacer to make sure that response can be
+ * moved here */
+ } aa;
+
+ extern int errno;
+
+#ifdef DEBUG
+ dstream(arg.c, stderr, NULL, "From emuhft (input)");
+#endif
+
+ if (len > 1000) {
+ fprintf(stderr, "Unreasonable value for len %d\n", len);
+ return -1;
+ }
+
+ if (ioctl(tty, IOCTYPE, 0) != (DD_PSEU << 8)) { /* is it a pty ? */
+ switch (arg.re->hf_request) {
+ case HFQUERY:{
+ struct hfquery hfqur;
+ int i;
+
+ hfqur.hf_resplen = iiret(arg.re->hf_rsp_len);
+ if (hfqur.hf_resplen > 0) {
+ hfqur.hf_resp = aa.charvector + sizeof aa.ackn;
+ if (hfqur.hf_resplen > (sizeof aa.charvector - sizeof
+ aa.ackn)) {
+ errno = ENOMEM;
+ perror("Can't store HFQUERY response");
+ return -1;
+ }
+ }
+ else
+ hfqur.hf_resp = NULL;
+
+ hfqur.hf_cmd = arg.c + 3 + ciret(arg.hf->hf_len);
+ hfqur.hf_cmdlen = iiret(arg.re->hf_arg_len);
+ i = ioctl(tty, HFQUERY, &hfqur); /* The meat of the
+ * matter */
+ aa.hfi.hf_esc = HFINTROESC;
+ aa.hfi.hf_lbr = HFINTROLBR;
+ aa.hfi.hf_ex = HFINTROEX;
+ icmove(sizeof aa.ackn - 3, aa.hfi.hf_len);
+ aa.hfi.hf_typehi = HFCTLACKCH;
+ aa.hfi.hf_typelo = HFCTLACKCL;
+ if (i == -1)
+ aa.ackn.hf_retcode = errno;
+ else
+ aa.ackn.hf_retcode = 0;
+ aa.ackn.hf_sublen = arg.re->hf_sublen;
+ aa.ackn.hf_subtype = arg.re->hf_subtype;
+ aa.ackn.hf_request = iiret(arg.re->hf_request);
+ aa.ackn.hf_arg_len = hfqur.hf_resplen;
+ if (-1 == write(ptc, aa.charvector, (sizeof aa.ackn) +
+ hfqur.hf_resplen)) {
+ perror("write of HFQUERY acknowledgement failed");
+ return (-1);
+ }
+#ifdef DEBUG
+ dstream(aa.charvector, stderr, NULL, "From emuhft (hfquery ack)");
+#endif
+ break;
+ }
+ case HFSKBD:{
+ struct hfbuf hfkey;
+ int i;
+
+ hfkey.hf_bufp = arg.c + 3 + ciret(arg.hf->hf_len);
+ hfkey.hf_buflen = iiret(arg.re->hf_arg_len);
+ i = ioctl(tty, HFSKBD, &hfkey); /* The meat of the matter */
+ aa.hfi.hf_esc = HFINTROESC;
+ aa.hfi.hf_lbr = HFINTROLBR;
+ aa.hfi.hf_ex = HFINTROEX;
+ icmove(sizeof aa.ackn - 3, aa.hfi.hf_len);
+ aa.hfi.hf_typehi = HFCTLACKCH;
+ aa.hfi.hf_typelo = HFCTLACKCL;
+ if (i == -1)
+ aa.ackn.hf_retcode = errno;
+ else
+ aa.ackn.hf_retcode = 0;
+ aa.ackn.hf_sublen = arg.re->hf_sublen;
+ aa.ackn.hf_subtype = arg.re->hf_subtype;
+ aa.ackn.hf_request = iiret(arg.re->hf_request);
+ aa.ackn.hf_arg_len = 0;
+ if (-1 == write(ptc, aa.charvector, sizeof aa.ackn)) {
+ perror("write of HFSKEY acknowledgement failed");
+ return (-1);
+ }
+#ifdef DEBUG
+ dstream(aa.charvector, stderr, NULL, "From emuhft (HFSKEY ack)");
+#endif
+ break;
+ }
+ default:{
+ aa.hfi.hf_esc = HFINTROESC;
+ aa.hfi.hf_lbr = HFINTROLBR;
+ aa.hfi.hf_ex = HFINTROEX;
+ icmove(sizeof aa.ackn - 3, aa.hfi.hf_len);
+ aa.hfi.hf_typehi = HFCTLACKCH;
+ aa.hfi.hf_typelo = HFCTLACKCL;
+ aa.ackn.hf_retcode = EINVAL;
+ aa.ackn.hf_sublen = arg.re->hf_sublen;
+ aa.ackn.hf_subtype = arg.re->hf_subtype;
+ aa.ackn.hf_request = iiret(arg.re->hf_request);
+ aa.ackn.hf_arg_len = 0;
+ if (-1 == write(ptc, aa.charvector, sizeof aa.ackn)) {
+ perror("write of default acknowledgement failed");
+ return (-1);
+ }
+#ifdef DEBUG
+ dstream(aa.charvector, stderr, NULL, "From emuhft (default ack)");
+#endif
+
+ break;
+ }
+ }
+ }
+ else {
+ /* Well, if we get here, we are a pseudo-device ourselves. So */
+ /* we will just send on the request that we got. we are in a */
+ /* unique situation. We believe that both ptc and tty are as */
+ /* transparent as we can get them, so we don't have to worry. */
+ /* We will just write the request to the tty, which we */
+ /* believe is a pty, and sooner or later, the ack will come */
+ /* back. */
+ if (-1 == write(tty, arg.c, len)) {
+ perror("write of control sequence to pty failed");
+ fprintf(stderr, "tty = %d, len = %d\n", tty, len);
+ return (-1);
+ }
+#ifdef DEBUG
+ dstream(arg.c, stderr, NULL, "From emuhft (on pty transfer)");
+ fprintf(stderr, "tty = %d, len = %d\r\n", tty, len);
+ fflush(stderr);
+#endif
+
+ }
+ return 0;
+}
+
+
+
+#endif
+
+static int _ThatsAll_(int x)
+{
+return x;
+}
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/lib/fnct_key.c.pamphlet b/src/lib/fnct_key.c.pamphlet
new file mode 100644
index 00000000..576b89ac
--- /dev/null
+++ b/src/lib/fnct_key.c.pamphlet
@@ -0,0 +1,395 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/lib fnct\_key.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{MAC OSX and BSD port}
+On the MAC OSX the signal [[SIGCLD]] has been renamed to [[SIGCHLD]].
+In order to handle this change we need to ensure that the platform
+variable is set properly and that the platform variable is changed
+everywhere.
+<<mac os signal rename>>=
+#if defined(MACOSXplatform) || defined(BSDplatform)
+ bsdSignal(SIGCHLD, null_fnct,RestartSystemCalls);
+#else
+ bsdSignal(SIGCLD, null_fnct,RestartSystemCalls);
+#endif
+@
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+@
+<<*>>=
+<<license>>
+
+#include "axiom-c-macros.h"
+@
+The MACOSX platform is broken because no matter what you do it seems to
+include files from [[/usr/include/sys]] ahead of [[/usr/include]]. On linux
+systems these files include themselves which causes an infinite regression
+of includes that fails. GCC gracefully steps over that problem but the
+build fails anyway. On MACOSX the [[/usr/include/sys]] versions
+of files are badly broken with respect to the [[/usr/include]] versions.
+<<*>>=
+#if defined(MACOSXplatform)
+#include "/usr/include/unistd.h"
+#else
+#include <unistd.h>
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+
+
+#include "edible.h"
+#include "bsdsignal.h"
+
+
+#include "bsdsignal.H1"
+#include "fnct_key.H1"
+#include "prt.H1"
+#include "edin.H1"
+
+
+/** Some constants for functio key defs ****/
+#define DELAYED 0
+#define IMMEDIATE 1
+#define SPECIAL 2
+
+
+/** Here is the structure for storing bound pf-keys ***/
+fkey function_key[13]; /** Strings which replace function
+ keys when a key is hit ***/
+
+static char *defaulteditor = "clefedit";
+char editorfilename[100];
+
+
+
+/*
+ * The following function environment variable clef editor. The command
+ * should be the one that the user wishes to have execed
+ */
+
+void
+set_editor_key(void)
+{
+ int pid;
+
+ sprintf(editorfilename, "/tmp/clef%d", pid = getpid());
+
+ if (function_key[12].str == NULL) {
+ (function_key[12]).type = SPECIAL;
+ (function_key[12]).str = defaulteditor;
+ }
+}
+
+
+
+
+/*** This routine id used to find the users function key mappings. It
+ simply searches the users HOME directory for a file called ".clef".
+ If found it gets the key bindings from within
+ *****/
+
+void
+define_function_keys(void)
+{
+ char *HOME, path[1024], string[1024];
+ int key;
+ int fd;
+ char type;
+ int length;
+
+ /** lets initialize the key pointers **/
+ for (key = 0; key < 13; key++)
+ (function_key[key]).str = NULL;
+ /** see if the user has a .clef file ***/
+ HOME = getenv("HOME");
+ sprintf(path, "%s/.clef", HOME);
+ if ((fd = open(path, O_RDONLY)) == -1) {
+ return;
+ }
+ else {
+ /*** If so, then get the key bindings **/
+ while ((key = get_key(fd, &type))) {
+ length = get_str(fd, string);
+ switch (type) {
+ case 'D':
+ if (key == 12) {
+ fprintf(stderr,
+ "Clef Error: PF12 can only be of type E in .clef\n");
+ fprintf(stderr, "Line will be ignored\n");
+ type = -1;
+ }
+ else {
+ (function_key[key]).type = DELAYED;
+ }
+ break;
+ case 'F':
+ if (key == 12) {
+ fprintf(stderr,
+ "Clef Error: PF12 can only be of type E in .clef\n");
+ fprintf(stderr, "Line will be ignored\n");
+ type = -1;
+ }
+ else {
+ (function_key[key]).type = IMMEDIATE;
+ }
+ break;
+ case 'E':
+ if (key != 12) {
+ fprintf(stderr,
+ "Clef Error: PF12 can only be of type E in .clef\n");
+ fprintf(stderr, "Line will be ignored\n");
+ type = -1;
+ }
+ else {
+ (function_key[key]).type = SPECIAL;
+ }
+ break;
+ }
+ if (type != -1) {
+ (function_key[key]).str =
+ (char *) malloc(strlen(string) + 1);
+ sprintf((function_key[key]).str, "%s", string);
+ }
+ }
+ }
+
+ /*
+ * Now set the editor function key
+ */
+ set_editor_key();
+}
+
+
+#define defof(c) ((c == 'F' || c == 'D' || c == 'E')?(1):(0))
+
+int
+get_key(int fd,char * ty)
+{
+
+ /*
+ * Determines the key number being mapped, and whether it is immediate or
+ * delay. It reurns the key value, and modifies the parameter type
+ */
+ char keynum[1024];
+ int nr;
+
+ nr = read(fd, keynum, 3);
+ if (nr != -1 && nr != 0) {
+ if (!defof(keynum[0])) {
+ return 0;
+ }
+ else {
+ *ty = keynum[0];
+ keynum[3] = '\0';
+ return (atoi(&keynum[1]));
+ }
+ }
+ else
+ return 0;
+}
+
+int
+get_str(int fd,char * string)
+{
+ /** Gets the key mapping being bound **/
+ char c;
+ int count = 0;
+ char *trace = string;
+
+ read(fd, &c, 1);
+ while (c == ' ')
+ read(fd, &c, 1);
+ while (c != '\n') {
+ count++;
+ *trace++ = c;
+ if (read(fd, &c, 1) == 0)
+ break;
+ }
+ *trace = '\0';
+ return count;
+}
+
+void
+null_fnct(int sig)
+{
+ return;
+}
+
+void
+handle_function_key(int key,int chann)
+{
+ /** this procedure simply adds the string specified by the function key
+ to the buffer ****/
+ int count, fd;
+ int amount = strlen(function_key[key].str);
+ int id;
+ int save_echo;
+
+ /*** This procedure takes the character at in_buff[num_proc] and adds
+ it to the buffer. It first checks to see if we should be inserting
+ or overwriting, and then does the appropriate thing *******/
+
+ switch ((function_key[key]).type) {
+ case IMMEDIATE:
+ if (INS_MODE) {
+ forwardcopy(&buff[curr_pntr + amount],
+ &buff[curr_pntr],
+ buff_pntr - curr_pntr);
+ forwardflag_cpy(&buff_flag[curr_pntr + amount],
+ &buff_flag[curr_pntr],
+ buff_pntr - curr_pntr);
+ for (count = 0; count < amount; count++) {
+ buff[curr_pntr + count] = (function_key[key].str)[count];
+ buff_flag[curr_pntr + count] = '1';
+ }
+ ins_print(curr_pntr, amount + 1);
+ buff_pntr = buff_pntr + amount;
+ }
+ else {
+ for (count = 0; count < amount; count++) {
+ buff[curr_pntr + count] = (function_key[key].str)[count];
+ buff_flag[curr_pntr + count] = '1';
+ myputchar((function_key[key].str)[count]);
+ }
+ }
+ num_proc = num_proc + 6;
+ curr_pntr = curr_pntr + amount;
+ buff_pntr = buff_pntr + amount;
+ send_function_to_child();
+ break;
+ case DELAYED:
+ if (INS_MODE) {
+ forwardcopy(&buff[curr_pntr + amount],
+ &buff[curr_pntr],
+ buff_pntr - curr_pntr);
+ forwardflag_cpy(&buff_flag[curr_pntr + amount],
+ &buff_flag[curr_pntr],
+ buff_pntr - curr_pntr);
+ for (count = 0; count < amount; count++) {
+ buff[curr_pntr + count] = (function_key[key].str)[count];
+ buff_flag[curr_pntr + count] = '1';
+ }
+ ins_print(curr_pntr, amount + 1);
+ buff_pntr = buff_pntr + amount;
+ }
+ else {
+ for (count = 0; count < amount; count++) {
+ buff[curr_pntr + count] = (function_key[key].str)[count];
+ buff_flag[curr_pntr + count] = '1';
+ myputchar((function_key[key].str)[count]);
+ }
+ }
+ num_proc = num_proc + 6;
+ curr_pntr = curr_pntr + amount;
+ buff_pntr = buff_pntr + amount;
+ fflush(stdout);
+ break;
+ case SPECIAL:
+ /* fprintf(stderr, "Here I am \n"); */
+ if (access(editorfilename, F_OK) < 0) {
+ fd = open(editorfilename, O_RDWR | O_CREAT, 0666);
+ write(fd, buff, buff_pntr);
+ back_up(buff_pntr);
+ close(fd);
+ }
+ else {
+ if (buff_pntr > 0) {
+ fd = open(editorfilename, O_RDWR | O_TRUNC);
+ write(fd, buff, buff_pntr);
+ back_up(buff_pntr);
+ close(fd);
+ }
+ }
+<<mac os signal rename>>
+ switch (id = fork()) {
+ case -1:
+ perror("Special key");
+ break;
+ case 0:
+ execlp((function_key[12]).str,
+ (function_key[12]).str,
+ editorfilename, NULL);
+ perror("Returned from exec");
+ exit(0);
+
+ }
+ while (wait((int *) 0) < 0);
+ /** now I should read that file and send all it stuff thru the
+ reader *****/
+ fd = open(editorfilename, O_RDWR);
+ if (fd == -1) {
+ perror("Opening temp file");
+ exit(-1);
+ }
+ num_proc += 6;
+
+ /** reinitialize the buffer ***/
+ init_flag(buff_flag, buff_pntr);
+ init_buff(buff, buff_pntr);
+ /** reinitialize my buffer pointers **/
+ buff_pntr = curr_pntr = 0;
+ /** reset the ring pointer **/
+ current = NULL;
+ save_echo = ECHOIT;
+ ECHOIT = 0;
+ while ((num_read = read(fd, in_buff, MAXLINE))) {
+ do_reading();
+ }
+ close(fd);
+ break;
+ }
+ return;
+
+}
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/lib/halloc.c.pamphlet b/src/lib/halloc.c.pamphlet
new file mode 100644
index 00000000..037181d3
--- /dev/null
+++ b/src/lib/halloc.c.pamphlet
@@ -0,0 +1,79 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/lib halloc.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+@
+<<*>>=
+<<license>>
+
+#include "axiom-c-macros.h"
+
+/* memory allocation used by HyperDoc and addfile */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "halloc.H1"
+
+
+/* allocate memory and bomb if none left (hyperTeX alloc) */
+char *
+halloc(int bytes,char * msg)
+{
+ static char buf[200];
+ char *result;
+
+ result = (char *) malloc(bytes);
+ if (result == NULL) {
+ sprintf(buf, "Ran out of memory allocating %s.\b", msg);
+ exit(-1);
+ }
+ return result;
+}
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/lib/hash.c.pamphlet b/src/lib/hash.c.pamphlet
new file mode 100644
index 00000000..44fed43a
--- /dev/null
+++ b/src/lib/hash.c.pamphlet
@@ -0,0 +1,240 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{no title}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+@
+<<*>>=
+<<license>>
+
+#include "axiom-c-macros.h"
+#define _HASH_C
+#include "debug.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "hash.h"
+
+#include "hash.H1"
+#include "halloc.H1"
+
+/* initialize a hash table */
+
+void
+hash_init(HashTable *table, int size, EqualFunction equal,
+ HashcodeFunction hash_code)
+{
+ int i;
+
+ table->table =
+ (HashEntry **) halloc(size * sizeof(HashEntry *), "HashEntry");
+ for (i = 0; i < size; i++)
+ table->table[i] = NULL;
+ table->size = size;
+ table->equal = equal;
+ table->hash_code = hash_code;
+ table->num_entries = 0;
+}
+
+void
+free_hash(HashTable *table, FreeFunction free_fun)
+{
+ if (table) {
+ int i;
+
+ for (i = 0; i < table->size; i++) {
+ HashEntry *e, *next;
+
+ for (e = table->table[i]; e != NULL;) {
+ next = e->next;
+ (*free_fun) (e->data);
+ (*e).data=0;
+ free(e);
+ e = next;
+ }
+ }
+ free(table->table);
+ }
+}
+
+/* insert an entry into a hash table */
+
+void
+hash_insert(HashTable *table, char *data, char *key)
+{
+ HashEntry *entry = (HashEntry *) halloc(sizeof(HashEntry), "HashEntry");
+ int code;
+
+ entry->data = data;
+ entry->key = key;
+ code = (*table->hash_code) (key, table->size) % table->size;
+#ifdef DEBUG
+ fprintf(stderr, "Hash value = %d\n", code);
+#endif
+ entry->next = table->table[code];
+ table->table[code] = entry;
+ table->num_entries++;
+}
+
+char *
+hash_find(HashTable *table, char *key)
+{
+ HashEntry *entry;
+ int code = table->hash_code(key, table->size) % table->size;
+
+ for (entry = table->table[code]; entry != NULL; entry = entry->next)
+ if ((*table->equal) (entry->key, key))
+ return entry->data;
+ return NULL;
+}
+
+char *
+hash_replace(HashTable *table, char *data, char *key)
+{
+ HashEntry *entry;
+ int code = table->hash_code(key, table->size) % table->size;
+
+ for (entry = table->table[code]; entry != NULL; entry = entry->next)
+ if ((*table->equal) (entry->key, key)) {
+ entry->data = data;
+ return entry->data;
+ }
+ return NULL;
+}
+
+void
+hash_delete(HashTable *table, char *key)
+{
+ HashEntry **entry;
+ int code = table->hash_code(key, table->size) % table->size;
+
+ for (entry = &table->table[code]; *entry != NULL; entry = &((*entry)->next))
+ if ((*table->equal) ((*entry)->key, key)) {
+ *entry = (*entry)->next;
+ table->num_entries--;
+ return;
+ }
+}
+
+void
+hash_map(HashTable *table, MappableFunction func)
+{
+ int i;
+ HashEntry *e;
+
+ if (table == NULL)
+ return;
+ for (i = 0; i < table->size; i++)
+ for (e = table->table[i]; e != NULL; e = e->next)
+ (*func) (e->data);
+}
+
+HashEntry *
+hash_copy_entry(HashEntry *e)
+{
+ HashEntry *ne;
+
+ if (e == NULL)
+ return e;
+ ne = (HashEntry *) halloc(sizeof(HashEntry), "HashEntry");
+ ne->data = e->data;
+ ne->key = e->key;
+ ne->next = hash_copy_entry(e->next);
+ return ne;
+}
+
+/* copy a hash table */
+HashTable *
+hash_copy_table(HashTable *table)
+{
+ HashTable *nt = (HashTable *) halloc(sizeof(HashTable), "copy hash table");
+ int i;
+
+ nt->size = table->size;
+ nt->num_entries = table->num_entries;
+ nt->equal = table->equal;
+ nt->hash_code = table->hash_code;
+ nt->table = (HashEntry **) halloc(nt->size * sizeof(HashEntry *),
+ "copy table");
+ for (i = 0; i < table->size; i++)
+ nt->table[i] = hash_copy_entry(table->table[i]);
+ return nt;
+}
+
+/* hash code function for strings */
+int
+string_hash(char *s, int size)
+{
+ int c = 0;
+ char *p =s;
+
+
+ while (*p)
+ c += *p++;
+ return c % size;
+}
+
+/* test strings for equality */
+
+int
+string_equal(char *s1, char *s2)
+{
+ return (strcmp(s1, s2) == 0);
+}
+
+/* make a fresh copy of the given string */
+char *
+alloc_string(char *str)
+{
+ char * result;
+ result = halloc(strlen(str)+1,"String");
+ strcpy(result,str);
+ return (result);
+}
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/lib/openpty.c.pamphlet b/src/lib/openpty.c.pamphlet
new file mode 100644
index 00000000..20976367
--- /dev/null
+++ b/src/lib/openpty.c.pamphlet
@@ -0,0 +1,226 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/lib openpty.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{MAC OSX and BSD platform changes}
+Since we have no other information we are adding the [[MACOSXplatform]] variable
+to the list everywhere we find [[LINUXplatform]]. This may not be correct but
+we have no way to know yet. We have also added the [[BSDplatform]] variable.
+MAC OSX is some variant of BSD. These should probably be merged but we
+cannot yet prove that.
+<<mac osx platform change 1>>=
+#if defined(SUN4OS5platform) ||defined(ALPHAplatform) || defined(HP10platform) || defined(LINUXplatform) || defined(MACOSXplatform) || defined(BSDplatform)
+@
+<<mac osx platform change 2>>=
+#if defined(SUNplatform) || defined(HP9platform) || defined(LINUXplatform) || defined(MACOSXplatform) || defined(BSDplatform)
+@
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+@
+<<*>>=
+<<license>>
+
+#include "axiom-c-macros.h"
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+
+#if defined(SUN4OS5platform) || defined(HP10platform)
+#include <stropts.h>
+#endif
+
+
+#include "openpty.H1"
+
+
+/*
+ * The main function is ptyopen. It simply opens up both sides of a
+ * pseudo-terminal. It uses and saves the pathnames for
+ * the devices which were actually opened.
+ *
+ * If it fails it simply exits the program.
+ *
+ *
+ * ptyopen(controller, server, controllerPath, serverPath)
+ * int *controller; The file descriptor for controller side of the pty
+ * int *server; The file descriptor for the server side
+ * char *controllerPath; actually , this is not used anywhere on return
+ and can be taken out of the call sequence
+ * char *serverPath;
+ *
+ * The path name vars should be declared of size 11 or more
+ */
+
+
+int
+ptyopen(int *controller,int * server, char *controllerPath,char * serverPath)
+{
+#if defined(SUNplatform) || defined (HP9platform) || defined(RTplatform) ||defined(AIX370platform) || defined(BSDplatform)
+ int looking = 1, i;
+ int oflag = O_RDWR; /* flag for opening the pty */
+
+ for (i = 0; looking && i < 1000; i++) {
+ makeNextPtyNames(controllerPath, serverPath);
+ if (access(controllerPath, 6) != 0) continue;
+ *controller = open(controllerPath, oflag, 0);
+ if (*controller >= 0) {
+ *server = open(serverPath, oflag, 0);
+ if (*server > 0)
+ looking = 0;
+ else
+ close(*controller);
+ }
+ }
+ if (looking) {
+ fprintf(stderr, "Couldn't find a free pty.\n");
+ exit(-1);
+ }
+ return (*controller);
+#endif
+#if defined RIOSplatform
+ int fdm,fds;
+ char *slavename;
+
+ /* open master */
+ if ((fdm=open("/dev/ptc",O_RDWR))<0)
+ perror("ptyopen failed to open /dev/ptc");
+ else {
+ /* get slave name */
+ if((slavename = ttyname(fdm))==0)
+ perror("ptyopen failed to get the slave device name");
+ /* open slave */
+ if ((fds = open(slavename, O_RDWR)) < 0 )
+ perror("ptyopen: Failed to open slave");
+ strcpy(serverPath,slavename);
+ *controller=fdm;
+ *server=fds;
+ }
+ return(fdm);
+#endif
+
+<<mac osx platform change 1>>
+extern int grantpt(int);
+extern int unlockpt(int);
+extern char* ptsname(int);
+ int fdm,fds;
+ char *slavename;
+
+ /* open master */
+ if ((fdm = open("/dev/ptmx", O_RDWR)) < 0 )
+ perror("ptyopen: Failed to open /dev/ptmx");
+ else {
+ /* change permission ofslave */
+ if (grantpt(fdm) < 0)
+ perror("ptyopen: Failed to grant access to slave device");
+ /* unlock slave */
+ if (unlockpt(fdm) < 0)
+ perror("ptyopen: Failed to unlock master/slave pair");
+ /* get name of slave */
+ if ((slavename = ptsname(fdm)) == NULL)
+ perror("ptyopen: Failed to get name of slave device");
+ /* open slave */
+ if ((fds = open(slavename, O_RDWR)) < 0 )
+ perror("ptyopen: Failed to open slave");
+ else {
+#if defined(SUN4OS5platform) || defined(HP10platform)
+ /* push ptem */
+ if (ioctl(fds, I_PUSH, "ptem") < 0)
+ perror("ptyopen: Failed to push ptem");
+ /* push ldterm */
+ if (ioctl(fds, I_PUSH, "ldterm") < 0)
+ perror("ptyopen: Failed to push idterm");
+#endif
+ strcpy(serverPath,slavename);
+ *controller=fdm;
+ *server=fds;
+ }
+ }
+ return(fdm);
+#endif
+#if defined SGIplatform
+ char *fds;
+ fds = _getpty(controller, O_RDWR|O_NDELAY, 0600, 0);
+ strcpy(serverPath,fds);
+ if (0 == serverPath)
+ return(-1);
+ if (0 > (*server = open(serverPath,O_RDWR))) {
+ (void) close(*controller);
+ return(-1);
+ }
+ return (*controller);
+
+#endif
+}
+
+
+void
+makeNextPtyNames(char *cont,char * serv)
+{
+#ifdef AIX370platform
+ static int channelNo = 0;
+ sprintf(cont, "/dev/ptyp%02x", channelNo);
+ sprintf(serv, "/dev/ttyp%02x", channelNo);
+ channelNo++;
+#endif
+<<mac osx platform change 2>>
+ static int channelNo = 0;
+ static char group[] = "pqrstuvwxyzPQRST";
+ static int groupNo = 0;
+
+ sprintf(cont, "/dev/pty%c%x", group[groupNo], channelNo);
+ sprintf(serv, "/dev/tty%c%x", group[groupNo], channelNo);
+ channelNo++; /* try next */
+ if (channelNo == 16) { /* move to new group */
+ channelNo = 0;
+ groupNo++;
+ if (groupNo == 16) groupNo = 0; /* recycle */
+ }
+#endif
+}
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/lib/pixmap.c.pamphlet b/src/lib/pixmap.c.pamphlet
new file mode 100644
index 00000000..509e1ea3
--- /dev/null
+++ b/src/lib/pixmap.c.pamphlet
@@ -0,0 +1,352 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/lib pixmap.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{MAC OSX zopen redefinition}
+On the [[MAC OSX]] platform they defined [[zopen]]. Since the function
+is only used in this file we simply rename it to [[zzopen]].
+<<mac zopen redefinition 1>>=
+FILE *
+zzopen(char *file,char * mode)
+@
+<<mac zopen redefinition 2>>=
+ file = zzopen(filename, "r");
+@
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+@
+<<*>>=
+<<license>>
+
+#include "axiom-c-macros.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xos.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <netinet/in.h>
+
+#define yes 1
+#define no 0
+
+
+
+#include "spadcolors.h"
+
+#include "pixmap.H1"
+#include "halloc.H1"
+#include "spadcolors.H1"
+
+
+
+/* returns true if the file exists */
+
+int
+file_exists(char *file)
+{
+ FILE *f;
+
+ if ((f = fopen(file, "r")) != NULL) {
+ fclose(f);
+ return 1;
+ }
+ return 0;
+}
+
+<<mac zopen redefinition 1>>
+{
+ char com[512], zfile[512];
+
+ if (file_exists(file))
+ return fopen(file, mode);
+ sprintf(zfile, "%s.Z", file);
+ if (file_exists(zfile)) {
+ sprintf(com, "gunzip -c %s.Z 2>/dev/null", file);
+ return popen(com, mode);
+ }
+ return NULL;
+}
+#ifdef OLD
+
+/*******************************************************************
+ KF 6/14/90
+ write_pixmap_file(display, filename, pm, width, height)
+ and
+ write_pixmap_file_xy(display, filename, pm, x, y, width, height)
+ has been merged into one function.
+
+ INPUT: display dsp, screen s, file name fn to write the file in,
+ window id wid where pixmap is,
+ upper left corner x, y of original pixmap,
+ width and height of pixmap
+ OUTPUT: binary file with data
+ PURPOSE: write_pixmap_file gets the image structure of the input
+ pixmap, convert the image data with the permutation color
+ vector, writes the image structure out to filename.
+
+ Note that writing out a Z pixmap is 8x faster than XY pixmap.
+ This is because XY writes out each pixel value per plane, thus
+ number of bits; Z writes out each pixel, or 8 bits at a time.
+
+ The XY format may have been chosen for a reason -- I don't know.
+
+********************************************************************/
+void
+write_pixmap_file(Display *dsp, int scr, char *fn,
+ Window wid, int x, int y, int width,int height)
+{
+ XImage *xi;
+ FILE *file;
+ int *permVector;
+ int num;
+ int num_colors;
+
+ /* get color map and permutation vector */
+ if ((num_colors = makePermVector(dsp, scr,(unsigned long **)&permVector)) < 0) {
+ printf("num_colors < 0!!\n");
+ exit(-1);
+ }
+
+ /* reads image structure in ZPixmap format */
+ xi = XGetImage(dsp, wid, x, y, width, height, AllPlanes, ZPixmap);
+ file = fopen(fn, "wb");
+ if (file == NULL) {
+ perror("opening pixmap file for write");
+ exit(-1);
+ }
+
+#define PUTW(a,b) putw(htonl(a),b)
+
+
+ PUTW(xi->width, file);
+ PUTW(xi->height, file);
+ PUTW(xi->xoffset, file);
+ PUTW(xi->format, file);
+ PUTW(xi->byte_order, file);
+ PUTW(xi->bitmap_unit, file);
+ PUTW(xi->bitmap_bit_order, file);
+ PUTW(xi->bitmap_pad, file);
+ PUTW(xi->depth, file);
+ PUTW(xi->bytes_per_line, file);
+ PUTW(xi->bits_per_pixel, file);
+ PUTW(xi->red_mask, file);
+ PUTW(xi->green_mask, file);
+ PUTW(xi->blue_mask, file);
+
+ num = xi->bytes_per_line * height; /* total number of pixels in pixmap */
+
+ /* store value from permutation */
+ {
+ int ii, jj;
+
+ for (ii = 0; ii < width; ii++)
+ for (jj = 0; jj < height; jj++) {
+ XPutPixel(xi, ii, jj, permVector[(int) XGetPixel(xi, ii, jj)]);
+ }
+ }
+ fwrite(xi->data, 1, num, file);
+ fclose(file);
+}
+
+/*******************************************************************
+ KF 6/14/90
+
+ INPUT: display, screen, filename to read the pixmap data from,
+ OUTPUT: ximage structure xi, width and height of pixmap
+ PURPOSE: read_pixmap_file reads an Ximage data structure from
+ the input file.
+ This routine can handle pixmaps of both XYPixmap and
+ ZPixmap. If a pixmap has ZPixmap format, then the image
+ data, read in as spadColor index, is converted to the
+ pixel value using spadColor.
+
+ Note that reading in Z format takes less space and time too.
+
+********************************************************************/
+int
+read_pixmap_file(Display *display, int screen, char *filename,
+ XImage **xi, int *width, int *height)
+{
+ FILE *file;
+ int wi, h, num, num_colors, read_this_time, offset;
+ Colormap cmap;
+ int ts;
+ unsigned long *spadColors;
+
+ /* colormap is necessary to call makeColors */
+ cmap = DefaultColormap(display, screen);
+ if ((num_colors = makeColors(display, screen, &cmap, &spadColors, &ts)) < 0) {
+ return(-1);
+ }
+<<mac zopen redefinition 2>>
+ if (file == NULL) {
+ printf("couldn't open %s\n", filename);
+ return BitmapOpenFailed;
+ }
+#define GETW(f) ntohl(getw(f))
+ *width = wi = GETW(file);
+ *height = h = GETW(file);
+ (*xi) = XCreateImage(display, DefaultVisual(display, screen),
+ DisplayPlanes(display, screen),
+ ZPixmap, 0, NULL, wi, h, 16, 0); /* handles both XY & Z */
+ if ((*xi) == NULL) {
+ fprintf(stderr, "Unable to create image\n");
+ return(-1);
+ }
+ (*xi)->width = wi;
+ (*xi)->height = h;
+ (*xi)->xoffset = GETW(file);
+ (*xi)->format = GETW(file);
+ (*xi)->byte_order = GETW(file);
+ (*xi)->bitmap_unit = GETW(file);
+ (*xi)->bitmap_bit_order = GETW(file);
+ (*xi)->bitmap_pad = GETW(file);
+ (*xi)->depth = GETW(file);
+ (*xi)->bytes_per_line = GETW(file);
+ (*xi)->bits_per_pixel = GETW(file);
+ (*xi)->red_mask = GETW(file);
+ (*xi)->green_mask = GETW(file);
+ (*xi)->blue_mask = GETW(file);
+
+ /* program will bomb if XYPixmap is not allocated enough space */
+ if ((*xi)->format == XYPixmap) {
+ /* printf("picture is in XYPixmap format.\n"); */
+ num = (*xi)->bytes_per_line * h * (*xi)->depth;
+ }
+ else /* ZPixmap */
+ num = (*xi)->bytes_per_line * h;
+ (*xi)->data = (void*)halloc(num, "Ximage data");
+
+ offset = 0;
+ while (offset < num) {
+ read_this_time = fread(((*xi)->data + offset), 1, num - offset, file);
+ offset = offset + read_this_time;
+ }
+ fclose(file);
+
+ /*
+ * pixmap data in ZPixmap format are spadColor indices; pixmap data in
+ * XYPixmap format are pixel values
+ */
+ if ((*xi)->format == ZPixmap) {
+
+ int ii, jj;
+
+ for (ii = 0; ii < wi; ii++)
+ for (jj = 0; jj < h; jj++) {
+ XPutPixel(*xi, ii, jj, spadColors[(int) XGetPixel(*xi, ii, jj)]);
+ }
+
+
+ }
+
+ return 0;
+}
+
+
+#else /*OLD*/
+
+
+#include "xpm.h"
+
+int
+read_pixmap_file(Display *display, int screen, char *filename,
+ XImage **xi, int *width, int *height)
+{
+ XpmAttributes attr;
+ XImage *xireturn;
+ int status;
+
+ attr.valuemask = 0;
+
+ attr.bitmap_format=ZPixmap; /* instead of XYPixmap */
+ attr.valuemask |= XpmBitmapFormat;
+ attr.valuemask |= XpmSize; /* we want feedback on width,height */
+ attr.valuemask |= XpmCharsPerPixel; /* and cpp */
+ attr.valuemask |= XpmReturnPixels; /* and pixels, npixels */
+ attr.valuemask |= XpmReturnAllocPixels; /* and alloc_pixels, nalloc_pixels */
+ attr.exactColors = False;
+ attr.valuemask |= XpmExactColors; /* we don't want exact colors*/
+ attr.closeness = 30000;
+ attr.valuemask |= XpmCloseness; /* we specify closeness*/
+ attr.alloc_close_colors = False;
+ attr.valuemask |= XpmAllocCloseColors; /* we don't allocate close colors*/
+
+
+ status=XpmReadFileToImage(display,filename,xi,&xireturn, &attr );
+ *width= (*xi)->width;
+ *height=(*xi)->height;
+#ifdef DEBUG
+ fprintf(stderr,"image file:%s\n",filename);
+ fprintf(stderr,"\twidth:%d\theight:%d\tcpp:%d\n",attr.width,attr.height,attr.cpp);
+ fprintf(stderr,"\tused/alloc'ed color pixels:%d/%d\n",attr.npixels,attr.nalloc_pixels);
+#endif
+ return 0;
+}
+
+
+void
+write_pixmap_file(Display *dsp, int scr, char *fn,
+ Window wid, int x, int y, int width,int height)
+{
+ XImage *xi;
+ int status;
+
+ /* reads image structure in ZPixmap format */
+ xi = XGetImage(dsp, wid, x, y, width, height, AllPlanes, ZPixmap);
+ if (xi==0) return ;
+ status=XpmWriteFileFromImage(dsp,fn,xi,0,0);
+
+}
+
+
+#endif
+
+
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/lib/prt.c.pamphlet b/src/lib/prt.c.pamphlet
new file mode 100644
index 00000000..7491c9fb
--- /dev/null
+++ b/src/lib/prt.c.pamphlet
@@ -0,0 +1,429 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/lib prt.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+@
+<<*>>=
+<<license>>
+
+#include "axiom-c-macros.h"
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include "edible.h"
+
+#include "prt.H1"
+#include "edin.H1"
+
+void
+myputchar(char c)
+{
+ if (ECHOIT)
+ putchar(c);
+ return;
+}
+
+void
+clear_buff(void)
+{
+ int count;
+
+ /*** called when spadbuf gives me a line incase there is something already
+ on the line ****/
+ if (buff_pntr > 0) {
+ /*** backup to the beginning of the line ***/
+ for (count = curr_pntr; count > 0; count--)
+ myputchar(_BKSPC);
+ /** blank over the line ***/
+ for (count = 0; count < buff_pntr; count++) {
+ myputchar(_BLANK);
+ }
+ /** back up again ***/
+ for (count = buff_pntr; count > 0; count--)
+ myputchar(_BKSPC);
+ init_buff(buff, buff_pntr);
+ init_flag(buff_flag, buff_pntr);
+ curr_pntr = buff_pntr = 0;
+ }
+}
+
+
+void
+move_end(void)
+{
+
+ /** Moves cursor to the end of the line ***/
+ if (curr_pntr == buff_pntr) {
+ putchar(_BELL);
+ }
+ else {
+ for (; curr_pntr < buff_pntr;) {
+ myputchar(buff[curr_pntr++]);
+ }
+ }
+ fflush(stdout);
+}
+
+void
+move_home(void)
+{
+
+ /*** Moves the cursor to the front of the line ***/
+ if (curr_pntr > 0) {
+ for (; curr_pntr > 0;) {
+ myputchar(_BKSPC);
+ curr_pntr--;
+ }
+ }
+ else {
+ putchar(_BELL);
+ }
+ fflush(stdout);
+
+}
+
+void
+move_fore_word(void)
+{
+ /** move the cursor to the next blank space **/
+ if (curr_pntr != buff_pntr) {
+ myputchar(buff[curr_pntr]);
+ curr_pntr++;
+ while (curr_pntr < buff_pntr && buff[curr_pntr] != ' ') {
+ myputchar(buff[curr_pntr]);
+ curr_pntr++;
+ }
+ }
+ else
+ putchar(_BELL);
+ fflush(stdout);
+ return;
+}
+
+void
+move_back_word(void)
+{
+ /*** moves the cursor to the last blank space ***/
+ if (curr_pntr > 0) {
+ myputchar(_BKSPC);
+ curr_pntr--;
+ while (curr_pntr > 0 && buff[curr_pntr - 1] != ' ') {
+ myputchar(_BKSPC);
+ curr_pntr--;
+ }
+
+ }
+ else
+ putchar(_BELL);
+ fflush(stdout);
+ return;
+}
+
+void
+delete_current_char(void)
+{
+ /** deletes the char currently above the current_pntr, if it can be **/
+ if (curr_pntr != buff_pntr) {
+ if (buff_flag[curr_pntr] == 1 || buff_flag[curr_pntr] == 0) {
+ myputchar(_BLANK);
+ myputchar(_BKSPC);
+ strcpy(&buff[curr_pntr],
+ &buff[curr_pntr + 1]);
+ flagcpy(&buff_flag[curr_pntr],
+ &buff_flag[curr_pntr + 1]);
+ buff_pntr--;
+ del_print(curr_pntr, 1);
+ }
+ else {
+ /** lets delete two of the little buggers **/
+ myputchar(_BLANK);
+ myputchar(_BLANK);
+ myputchar(_BKSPC);
+ myputchar(_BKSPC);
+ strcpy(&buff[curr_pntr],
+ &buff[curr_pntr + 2]);
+ flagcpy(&buff_flag[curr_pntr],
+ &buff_flag[curr_pntr + 2]);
+ buff_pntr -= 2;
+ del_print(curr_pntr, 2);
+ }
+ }
+ else {
+ putchar(_BELL);
+ fflush(stdout);
+ }
+ num_proc = num_proc + 3;
+}
+
+void
+delete_to_end_of_line(void)
+{
+ int count;
+
+ /*** deletes from the curr_pntr to the end of line ***/
+
+ if (curr_pntr == buff_pntr)
+ return; /** There is nothing to do **/
+
+ /** blank over the end of the line ***/
+ for (count = curr_pntr; count < buff_pntr; count++) {
+ myputchar(_BLANK);
+ }
+ /** back up again ***/
+ for (count = buff_pntr; count > curr_pntr; count--)
+ myputchar(_BKSPC);
+
+ buff_pntr = curr_pntr;
+ fflush(stdout);
+ return;
+
+}
+
+void
+delete_line(void)
+{
+ int count;
+
+ /*** deletes the entire line *****/
+
+ if (buff_pntr == 0)
+ return; /** There is nothing to do **/
+
+ /** first I have to back up to the beginning of the line ****/
+ for (count = curr_pntr; count > 0; count--)
+ myputchar(_BKSPC);
+
+ /** blank over the end of the line ***/
+ for (count = 0; count < buff_pntr; count++) {
+ myputchar(_BLANK);
+ }
+ /** back up again ***/
+ for (count = buff_pntr; count > 0; count--)
+ myputchar(_BKSPC);
+
+ /* Also clear the buffer */
+ init_buff(buff, buff_pntr);
+ init_flag(buff_flag, buff_pntr);
+ buff_pntr = curr_pntr = 0;
+
+ fflush(stdout);
+ return;
+
+}
+
+void
+printbuff(int start,int num)
+{
+ int trace;
+
+ for (trace = start; trace < start + num; trace++)
+ if (buff[trace] != '\0')
+ myputchar(buff[trace]);
+ fflush(stdout);
+}
+
+void
+del_print(int start, int num)
+{
+ int count;
+
+ /*** move the rest of the string ***/
+ for (count = start; count < buff_pntr; count++) {
+ myputchar(buff[count]);
+ }
+ /** now blank out the number of chars we are supposed to ***/
+ for (count = 0; count < num; count++)
+ myputchar(_BLANK);
+ /*** Now back up ***/
+ for (count = buff_pntr + num; count > start; count--)
+ myputchar(_BKSPC);
+ fflush(stdout);
+}
+
+
+void
+ins_print(int start,int num)
+{
+ int count;
+
+ /** write the rest of the word ***/
+ for (count = start; count < buff_pntr + num; count++) {
+ myputchar(buff[count]);
+ }
+ /** now back up to where we should be ***/
+ for (count = buff_pntr; count > start; count--)
+ myputchar(_BKSPC);
+ fflush(stdout);
+}
+
+void
+reprint(int start)
+{
+ /** simply reprints a single character **/
+ if (buff[start] == '\0')
+ myputchar(_BLANK);
+ else
+ myputchar(buff[start]);
+ myputchar(_BKSPC);
+ fflush(stdout);
+ return;
+}
+
+void
+back_up(int num_chars)
+{
+ int cnt;
+
+ for (cnt = 0; cnt < num_chars; cnt++)
+ myputchar(_BKSPC);
+ for (cnt = 0; cnt < num_chars; cnt++)
+ myputchar(_BLANK);
+ for (cnt = 0; cnt < num_chars; cnt++)
+ myputchar(_BKSPC);
+ fflush(stdout);
+
+}
+
+void
+back_it_up(int num_chars)
+{
+ int cnt;
+
+ for (cnt = 0; cnt < num_chars; cnt++)
+ myputchar(_BKSPC);
+ fflush(stdout);
+}
+
+
+void
+print_whole_buff(void)
+{
+ int trace;
+
+ for (trace = 0; trace < buff_pntr; trace++)
+ if (buff[trace] != '\0')
+ myputchar(buff[trace]);
+ fflush(stdout);
+}
+
+void
+move_ahead(void)
+{
+ /*** simply moves the pointer ahead a single word ***/
+ if (curr_pntr == buff_pntr) {
+ putchar(_BELL);
+ }
+ else {
+ if (buff_flag[curr_pntr] == 2) {
+ myputchar(buff[curr_pntr++]);
+ }
+ myputchar(buff[curr_pntr++]);
+ }
+ fflush(stdout);
+}
+
+void
+move_back(void)
+{
+ /** simply moves the cursor back one position **/
+ if (curr_pntr == 0) {
+ putchar(_BELL);
+ }
+ else {
+ if (!buff_flag[curr_pntr - 1]) {
+ myputchar(_BKSPC);
+ curr_pntr--;
+ }
+ myputchar(_BKSPC);
+ curr_pntr--;
+ }
+ fflush(stdout);
+}
+
+void
+back_over_current_char(void)
+{
+ /*** simply backs over the character behind the cursor ***/
+ if (curr_pntr == 0) {
+ putchar(_BELL);
+ }
+ else {
+ if (!buff_flag[curr_pntr - 1]) {
+ myputchar(_BKSPC);
+ myputchar(_BKSPC);
+ myputchar(_BLANK);
+ myputchar(_BLANK);
+ myputchar(_BKSPC);
+ myputchar(_BKSPC);
+ strcpy(&buff[curr_pntr - 2],
+ &buff[curr_pntr]);
+ flagcpy(&buff_flag[curr_pntr - 2],
+ &buff_flag[curr_pntr]);
+ buff_pntr -= 2;
+ curr_pntr -= 2;
+ del_print(curr_pntr, 2);
+ }
+ else {
+ myputchar(_BKSPC);
+ myputchar(_BLANK);
+ myputchar(_BKSPC);
+ strcpy(&buff[curr_pntr - 1],
+ &buff[curr_pntr]);
+ flagcpy(&buff_flag[curr_pntr - 1],
+ &buff_flag[curr_pntr]);
+ curr_pntr--;
+ buff_pntr--;
+ del_print(curr_pntr, 1);
+ }
+ }
+ fflush(stdout);
+ return;
+}
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/lib/sockio-c.c.pamphlet b/src/lib/sockio-c.c.pamphlet
new file mode 100644
index 00000000..184a5ff5
--- /dev/null
+++ b/src/lib/sockio-c.c.pamphlet
@@ -0,0 +1,1218 @@
+\documentclass{article}
+\usepackage{axiom}
+
+\title{\$SPAD/src/lib sockio-c.c}
+\author{The Axiom Team}
+
+\begin{document}
+\maketitle
+
+\begin{abstract}
+\end{abstract}
+\eject
+
+\tableofcontents
+\eject
+
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+@
+<<*>>=
+<<license>>
+
+/* socket i/o primitives */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <sys/time.h>
+#include <string.h>
+#include <signal.h>
+
+#include "com.h"
+#include "bsdsignal.h"
+
+#define TotalMaxPurposes 50
+#define MaxServerNumbers 100
+#define accept_if_needed(purpose) \
+ ( purpose_table[purpose] == NULL ? sock_accept_connection(purpose) : 1 )
+
+/* Note that the name AF_LOCAL is more portable than AF_UNIX, but MingW
+ implementation and Windows documentation don't always agree. */
+
+#if HAVE_AF_LOCAL
+# define AXIOM_AF_LOCAL AF_LOCAL
+#elif HAVE_AF_UNIX
+# define AXIOM_AF_LOCAL AF_UNIX
+#else
+# error needs one of AF_LOCAL or AF_UNIX
+#endif
+
+
+
+Sock clients[MaxClients]; /* socket description of spad clients */
+Sock server[2]; /* AF_LOCAL and AF_INET sockets for server */
+Sock *purpose_table[TotalMaxPurposes]; /* table of dedicated socket types */
+fd_set socket_mask; /* bit mask of active sockets */
+fd_set server_mask; /* bit mask of server sockets */
+int socket_closed; /* used to identify closed socket on SIGPIPE */
+int spad_server_number = -1; /* spad server number used in sman */
+int str_len = 0;
+int still_reading = 0;
+
+
+
+#include "bsdsignal.H1"
+#include "sockio-c.H1"
+
+/* The function sleep is not available under Windows. Instead they
+ have Sleep(), with capital S, please. Furthermore, it does not
+ take argument in second, but in milliseconds, three order
+ of magnitude of difference when compared to the Unix world.
+ We abstract over that difference here. */
+
+static inline void
+axiom_sleep(int n)
+{
+#ifdef __WIN32__
+ Sleep(n * 1000);
+#else
+ sleep(n);
+#endif
+}
+
+/* Windows require some handshaking with the WinSock DLL before
+ we can even think about talking about sockets. */
+
+static void
+axiom_load_socket_module()
+{
+#ifdef __WIN32__
+ WSADATA wsaData;
+
+ /* Request version 2.0 of WinSock DLL. */
+ if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) {
+ perror("could not find suitable WinSock DLL.");
+ exit(WSAGetLastError());
+ }
+
+ if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0) {
+ perror("could not find suitable WinSock DLL.");
+ WSACleanup();
+ exit(WSAGetLastError());
+ }
+#endif
+}
+
+
+/* Get a socket identifier to a local server. We take whatever protocol
+ is the default for the address family in the SOCK_STREAM type. */
+static inline axiom_socket
+axiom_communication_link(int family)
+{
+ axiom_load_socket_module();
+ return socket(family, SOCK_STREAM, 0);
+}
+
+
+/* Returns 1 if SOCKET is an invalid socket. Otherwise return 0. */
+
+static inline int
+is_invalid_socket(const Sock* s)
+{
+#ifdef __WIN32__
+ return s->socket == INVALID_SOCKET;
+#else
+ return s->socket < 0;
+#endif
+}
+
+/* Returns 1 if SOCKET is a valid socket. Otherwise return 0. */
+
+static inline int
+is_valid_socket(const Sock* s)
+{
+#ifdef __WIN32__
+ return s->socket != INVALID_SOCKET;
+#else
+ return s->socket > 0;
+#endif
+}
+
+
+/* Because a socket on Windows platform is a not just a simple file
+ descriptor as it is in the Unix world, it is invalid to use
+ a socket identifier as argument for read(), or close, and
+ any other file descriptor function. Furthermore, Windows
+ requires cleanup. */
+
+void
+axiom_close_socket(axiom_socket s)
+{
+#ifdef __WIN32__
+ shutdown(s, SD_BOTH);
+ closesocket(s);
+ WSACleanup();
+#else
+ close(s);
+#endif
+}
+
+/* Return 1 is the last call was cancelled. */
+
+static inline int
+axiom_call_was_cancelled(void)
+{
+#ifdef __WIN32__
+ return WSAGetLastError() == WSAEINTR;
+#else
+ return errno == EINTR;
+#endif
+}
+
+/* Return 1 is last connect() was refused. */
+
+static inline int
+axiom_connection_refused(void)
+{
+#ifdef __WIN32__
+ return WSAGetLastError() == WSAECONNREFUSED;
+#else
+ return errno == ECONNREFUSED;
+#endif
+}
+
+
+void
+sigpipe_handler(int sig)
+{
+ socket_closed = 1;
+}
+
+int
+wait_for_client_read(Sock *sock, char *buf, int buf_size, char *msg)
+{
+ int ret_val;
+ switch(sock->purpose) {
+ case SessionManager:
+ case ViewportServer:
+ sock_accept_connection(sock->purpose);
+ ret_val = sread(purpose_table[sock->purpose], buf, buf_size, msg);
+ sock->socket = 0;
+ return ret_val;
+ default:
+ sock->socket = 0;
+ return -1;
+ }
+}
+
+int
+wait_for_client_write(Sock *sock,char *buf,int buf_size,char *msg)
+{
+ int ret_val;
+ switch(sock->purpose) {
+ case SessionManager:
+ case ViewportServer:
+ sock_accept_connection(sock->purpose);
+ ret_val = swrite(purpose_table[sock->purpose], buf, buf_size, msg);
+ sock->socket = 0;
+ return ret_val;
+ default:
+ sock->socket = 0;
+ return -1;
+ }
+}
+
+int
+sread(Sock *sock, char *buf, int buf_size, char *msg)
+{
+ int ret_val;
+ char err_msg[256];
+ errno = 0;
+ do {
+ ret_val = axiom_read(sock, buf, buf_size);
+ } while (ret_val == -1 && axiom_call_was_cancelled());
+ if (ret_val == 0) {
+ FD_CLR(sock->socket, &socket_mask);
+ purpose_table[sock->purpose] = NULL;
+ axiom_close_socket(sock->socket);
+ return wait_for_client_read(sock, buf, buf_size, msg);
+ }
+ if (ret_val == -1) {
+ if (msg) {
+ sprintf(err_msg, "reading: %s", msg);
+ perror(err_msg);
+ }
+ return -1;
+ }
+ return ret_val;
+}
+
+int
+swrite(Sock *sock,char *buf,int buf_size,char *msg)
+{
+ int ret_val;
+ char err_msg[256];
+ errno = 0;
+ socket_closed = 0;
+ ret_val = axiom_write(sock, buf, buf_size);
+ if (ret_val == -1) {
+ if (socket_closed) {
+ FD_CLR(sock->socket, &socket_mask);
+ purpose_table[sock->purpose] = NULL;
+ /* printf(" closing socket %d\n", sock->socket); */
+ axiom_close_socket(sock->socket);
+ return wait_for_client_write(sock, buf, buf_size, msg);
+ } else {
+ if (msg) {
+ sprintf(err_msg, "writing: %s", msg);
+ perror(err_msg);
+ }
+ return -1;
+ }
+ }
+ return ret_val;
+}
+
+int
+sselect(int n,fd_set *rd, fd_set *wr, fd_set *ex, void *timeout)
+{
+ int ret_val;
+ do {
+ ret_val = select(n, (void *)rd, (void *)wr, (void *)ex, (struct timeval *) timeout);
+ } while (ret_val == -1 && axiom_call_was_cancelled());
+ return ret_val;
+}
+
+int
+fill_buf(Sock *sock,char *buf, int len, char *msg)
+{
+ int bytes = 0, ret_val;
+ while(bytes < len) {
+ ret_val = sread(sock, buf + bytes, len - bytes, msg);
+ if (ret_val == -1) return -1;
+ bytes += ret_val;
+ }
+ return bytes;
+}
+
+int
+get_int(Sock *sock)
+{
+ int val = -1, len;
+ len = fill_buf(sock, (char *)&val, sizeof(int), "integer");
+ if (len != sizeof(int)) {
+#ifdef DEBUG
+ fprintf(stderr,"get_int: caught error\n",val);
+#endif
+ return -1;
+ }
+#ifdef DEBUG
+ fprintf(stderr,"get_int: received %d\n",val);
+#endif
+ return val;
+}
+
+int
+sock_get_int(int purpose)
+{
+ if (accept_if_needed(purpose) != -1)
+ return get_int(purpose_table[purpose]);
+ else return -1;
+}
+
+int
+get_ints(Sock *sock, int *vals, int num)
+{
+ int i;
+ for(i=0; i<num; i++)
+ *vals++ = get_int(sock);
+ return 0;
+}
+
+int
+sock_get_ints(int purpose, int *vals, int num)
+{
+ if (accept_if_needed(purpose) != -1)
+ return get_ints(purpose_table[purpose], vals, num);
+ return -1;
+}
+
+int
+send_int(Sock *sock,int val)
+{
+ int ret_val;
+ ret_val = swrite(sock, (char *)&val, sizeof(int), NULL);
+ if (ret_val == -1) {
+ return -1;
+ }
+ return 0;
+}
+
+int
+sock_send_int(int purpose,int val)
+{
+ if (accept_if_needed(purpose) != -1)
+ return send_int(purpose_table[purpose], val);
+ return -1;
+}
+
+int
+send_ints(Sock *sock, int *vals, int num)
+{
+ int i;
+ for(i=0; i<num; i++)
+ if (send_int(sock, *vals++) == -1)
+ return -1;
+ return 0;
+}
+
+int
+sock_send_ints(int purpose, int *vals, int num)
+{
+ if (accept_if_needed(purpose) != -1)
+ return send_ints(purpose_table[purpose], vals, num);
+ return -1;
+}
+
+int
+send_string_len(Sock *sock,char *str,int len)
+{
+ int val;
+ if (len > 1023) {
+ char *buf;
+ buf = malloc(len+1);
+ strncpy(buf,str,len);
+ buf[len]='\0';
+ send_int(sock,len+1);
+ val = swrite(sock, buf, len+1, NULL);
+ free(buf);
+ } else {
+ static char buf[1024];
+ strncpy(buf, str, len);
+ buf[len] = '\0';
+ send_int(sock, len+1);
+ val = swrite(sock, buf, len+1, NULL);
+ }
+ if (val == -1) {
+ return -1;
+ }
+ return 0;
+}
+
+int
+send_string(Sock *sock, char *str)
+{
+ int val, len = strlen(str);
+ send_int(sock, len+1);
+ val = swrite(sock, str, len+1, NULL);
+ if (val == -1) {
+ return -1;
+ }
+ return 0;
+}
+
+
+int
+sock_send_string(int purpose, char *str)
+{
+ if (accept_if_needed(purpose) != -1)
+ return send_string(purpose_table[purpose], str);
+ return -1;
+}
+
+int
+sock_send_string_len(int purpose, char * str, int len)
+{
+ if (accept_if_needed(purpose) != -1)
+ return send_string_len(purpose_table[purpose], str, len);
+ return -1;
+}
+
+int
+send_strings(Sock *sock, char ** vals, int num)
+{
+ int i;
+ for(i=0; i<num; i++)
+ if (send_string(sock, *vals++) == -1)
+ return -1;
+ return 0;
+}
+
+int
+sock_send_strings(int purpose, char **vals, int num)
+{
+ if (accept_if_needed(purpose) != -1)
+ return send_strings(purpose_table[purpose], vals, num);
+ return -1;
+}
+
+char *
+get_string(Sock *sock)
+{
+ int val, len;
+ char *buf;
+ len = get_int(sock);
+ if (len <0) return NULL;
+ buf = malloc(len*sizeof(char));
+ val = fill_buf(sock, buf, len, "string");
+ if (val == -1){
+ free(buf);
+ return NULL;
+ }
+#ifdef DEBUG
+ fprintf(stderr,"get_string: received \"%s\" \n",buf);
+#endif
+ return buf;
+}
+
+char *
+sock_get_string(int purpose)
+{
+ if (accept_if_needed(purpose) != -1)
+ return get_string(purpose_table[purpose]);
+ else return NULL;
+}
+
+
+char *
+get_string_buf(Sock *sock, char *buf, int buf_len)
+{
+ int val;
+ if(!str_len) str_len = get_int(sock);
+ if (str_len > buf_len) {
+ val = fill_buf(sock, buf, buf_len, "buffered string");
+ str_len = str_len - buf_len;
+ if (val == -1)
+ return NULL;
+ return buf;
+ }
+ else {
+ val = fill_buf(sock, buf, str_len, "buffered string");
+ str_len = 0;
+ if (val == -1)
+ return NULL;
+ return NULL;
+ }
+}
+
+char *
+sock_get_string_buf(int purpose, char * buf, int buf_len)
+{
+ if (accept_if_needed(purpose) != -1)
+ return get_string_buf(purpose_table[purpose], buf, buf_len);
+ return NULL;
+}
+
+int
+get_strings(Sock *sock,char **vals,int num)
+{
+ int i;
+ for(i=0; i<num; i++)
+ *vals++ = get_string(sock);
+ return 0;
+}
+
+int
+sock_get_strings(int purpose, char ** vals, int num)
+{
+ if (accept_if_needed(purpose) != -1)
+ return get_strings(purpose_table[purpose], vals, num);
+ return -1;
+}
+
+int
+send_float(Sock *sock, double num)
+{
+ int val;
+ val = swrite(sock, (char *)&num, sizeof(double), NULL);
+ if (val == -1) {
+ return -1;
+ }
+ return 0;
+}
+
+int
+sock_send_float(int purpose, double num)
+{
+ if (accept_if_needed(purpose) != -1)
+ return send_float(purpose_table[purpose], num);
+ return -1;
+}
+
+int
+send_sfloats(Sock *sock, float *vals,int num)
+{
+ int i;
+ for(i=0; i<num; i++)
+ if (send_float(sock, (double) *vals++) == -1)
+ return -1;
+ return 0;
+}
+
+int
+sock_send_sfloats(int purpose, float * vals, int num)
+{
+ if (accept_if_needed(purpose) != -1)
+ return send_sfloats(purpose_table[purpose], vals, num);
+ return -1;
+}
+
+int
+send_floats(Sock *sock, double *vals, int num)
+{
+ int i;
+ for(i=0; i<num; i++)
+ if (send_float(sock, *vals++) == -1)
+ return -1;
+ return 0;
+}
+
+int
+sock_send_floats(int purpose, double *vals, int num)
+{
+ if (accept_if_needed(purpose) != -1)
+ return send_floats(purpose_table[purpose], vals, num);
+ return -1;
+}
+
+double
+get_float(Sock *sock)
+{
+ int val;
+ double num = -1.0;
+ val = fill_buf(sock, (char *)&num, sizeof(double), "double");
+#ifdef DEBUG
+ fprintf(stderr,"get_float: received %f\n",num);
+#endif
+ return num;
+}
+
+double
+sock_get_float(int purpose)
+{
+ if (accept_if_needed(purpose) != -1)
+ return get_float(purpose_table[purpose]);
+ else return 0.0;
+}
+
+int
+get_sfloats(Sock *sock, float *vals, int num)
+{
+ int i;
+ for(i=0; i<num; i++)
+ *vals++ = (float) get_float(sock);
+ return 0;
+}
+
+
+int
+sock_get_sfloats(int purpose,float * vals, int num)
+{
+ if (accept_if_needed(purpose) != -1)
+ return get_sfloats(purpose_table[purpose], vals, num);
+ return -1;
+}
+
+int
+get_floats(Sock *sock,double *vals,int num)
+{
+ int i;
+ for(i=0; i<num; i++)
+ *vals++ = get_float(sock);
+ return 0;
+}
+
+
+int
+sock_get_floats(int purpose, double *vals, int num)
+{
+ if (accept_if_needed(purpose) != -1)
+ return get_floats(purpose_table[purpose], vals, num);
+ return -1;
+}
+
+int
+wait_for_client_kill(Sock *sock, int sig)
+{
+ int ret_val;
+ switch(sock->purpose) {
+ case SessionManager:
+ case ViewportServer:
+ sock_accept_connection(sock->purpose);
+ ret_val = send_signal(purpose_table[sock->purpose], sig);
+ sock->socket = 0;
+ return ret_val;
+ default:
+ sock->socket = 0;
+ return -1;
+ }
+}
+
+
+int
+sock_get_remote_fd(int purpose)
+{
+ if (accept_if_needed(purpose) != -1)
+ return purpose_table[purpose]->remote;
+ return -1;
+}
+
+int
+send_signal(Sock *sock, int sig)
+{
+ int ret_val;
+#if HAVE_DECL_KILL
+ ret_val = kill(sock->pid, sig);
+#else
+ ret_val = raise(sig);
+#endif
+ if (ret_val == -1 && errno == ESRCH) {
+ FD_CLR(sock->socket, &socket_mask);
+ purpose_table[sock->purpose] = NULL;
+/* printf(" closing socket %d\n", sock->socket); */
+ axiom_close_socket(sock->socket);
+ return wait_for_client_kill(sock, sig);
+ }
+ return ret_val;
+}
+
+int
+sock_send_signal(int purpose,int sig)
+{
+ if (accept_if_needed(purpose) != -1)
+ return send_signal(purpose_table[purpose], sig);
+ return -1;
+}
+
+int
+send_wakeup(Sock *sock)
+{
+#ifdef SIGUSR1
+ return send_signal(sock, SIGUSR1);
+#else
+ return -1;
+#endif
+}
+
+int
+sock_send_wakeup(int purpose)
+{
+ if (accept_if_needed(purpose) != -1)
+ return send_wakeup(purpose_table[purpose]);
+ return -1;
+}
+
+Sock *
+connect_to_local_server_new(char *server_name, int purpose, int time_out)
+{
+ int max_con=(time_out == 0 ? 1000000 : time_out), i, code=-1;
+ Sock *sock;
+ char name[256];
+
+ make_server_name(name, server_name);
+ sock = (Sock *) calloc(sizeof(Sock), 1);
+ if (sock == NULL) {
+ perror("allocating socket space");
+ return NULL;
+ }
+
+ sock->socket = axiom_communication_link(AXIOM_AF_LOCAL);
+ if (is_invalid_socket(sock)) {
+ perror("opening client socket");
+ free(sock);
+ return NULL;
+ }
+
+ memset(server[1].addr.u_addr.sa_data, 0,
+ sizeof(server[1].addr.u_addr.sa_data));
+ sock->addr.u_addr.sa_family = AXIOM_AF_LOCAL;
+ strcpy(sock->addr.u_addr.sa_data, name);
+ for(i=0; i<max_con; i++) {
+ code = connect(sock->socket, &sock->addr.u_addr,
+ sizeof(sock->addr.u_addr));
+ if (code == -1) {
+ if (errno != ENOENT && !axiom_connection_refused()) {
+ perror("connecting server stream socket");
+ return NULL;
+ } else {
+ if (i != max_con - 1)
+ axiom_sleep(1);
+ continue;
+ }
+ } else break;
+ }
+
+ if (code == -1) {
+ return NULL;
+ }
+
+ send_int(sock, getpid());
+ send_int(sock, purpose);
+ send_int(sock, sock->socket);
+ sock->pid = get_int(sock);
+ sock->remote = get_int(sock);
+ return sock;
+}
+
+Sock *
+connect_to_local_server(char *server_name, int purpose, int time_out)
+{
+ int max_con=(time_out == 0 ? 1000000 : time_out), i, code=-1;
+ Sock *sock;
+ char name[256];
+
+ make_server_name(name, server_name);
+ sock = (Sock *) calloc(sizeof(Sock), 1);
+ if (sock == NULL) {
+ perror("allocating socket space");
+ return NULL;
+ }
+
+ sock->purpose = purpose;
+ /* create the socket */
+ sock->socket = axiom_communication_link(AXIOM_AF_LOCAL);
+ if (is_invalid_socket(sock)) {
+ perror("opening client socket");
+ free(sock);
+ return NULL;
+ }
+ /* connect socket using name specified in command line */
+ memset(server[1].addr.u_addr.sa_data, 0,
+ sizeof(server[1].addr.u_addr.sa_data));
+ sock->addr.u_addr.sa_family = AXIOM_AF_LOCAL;
+ strcpy(sock->addr.u_addr.sa_data, name);
+ for(i=0; i<max_con; i++) {
+ code = connect(sock->socket, &sock->addr.u_addr,
+ sizeof(sock->addr.u_addr));
+ if (code == -1) {
+ if (errno != ENOENT && !axiom_connection_refused()) {
+ perror("connecting server stream socket");
+ return NULL;
+ } else {
+ if (i != max_con - 1)
+ axiom_sleep(1);
+ continue;
+ }
+ } else break;
+ }
+ if (code == -1) {
+ return NULL;
+ }
+ send_int(sock, getpid());
+ send_int(sock, sock->purpose);
+ send_int(sock, sock->socket);
+ sock->pid = get_int(sock);
+/* fprintf(stderr, "Got int form socket\n"); */
+ sock->remote = get_int(sock);
+ return sock;
+}
+
+/* act as terminal session for sock connected to stdin and stdout of another
+ process */
+void
+remote_stdio(Sock *sock)
+{
+ char buf[1024];
+ fd_set rd;
+ int len;
+ while (1) {
+ FD_ZERO(&rd);
+ FD_SET(sock->socket,&rd);
+ FD_SET(0, &rd);
+ len = sselect(FD_SETSIZE, (fd_set *)&rd, (fd_set *)0, (fd_set *)0, NULL);
+ if (len == -1) {
+ perror("stdio select");
+ return;
+ }
+ if (FD_ISSET(0, &rd)) {
+ fgets(buf,1024,stdin);
+ len = strlen(buf);
+ /*
+ gets(buf);
+ len = strlen(buf);
+ *(buf+len) = '\n';
+ *(buf+len+1) = '\0';
+ */
+ swrite(sock, buf, len, "writing to remote stdin");
+ }
+ if (FD_ISSET(sock->socket, &rd)) {
+ len = sread(sock, buf, 1024, "stdio");
+ if (len == -1)
+ return;
+ else {
+ *(buf + len) = '\0';
+ fputs(buf, stdout);
+ fflush(stdout);
+ }
+ }
+ }
+}
+
+/* initialize the table of dedicated sockets */
+void
+init_purpose_table(void)
+{
+ int i;
+ for(i=0; i<TotalMaxPurposes; i++) {
+ purpose_table[i] = NULL;
+ }
+}
+
+
+int
+make_server_number(void)
+{
+ spad_server_number = getpid();
+ return spad_server_number;
+}
+
+void
+close_socket(axiom_socket socket_num, char *name)
+{
+ axiom_close_socket(socket_num);
+#ifndef RTplatform
+ unlink(name);
+#endif
+}
+
+int
+make_server_name(char *name,char * base)
+{
+ char *num;
+ if (spad_server_number != -1) {
+ sprintf(name, "%s%d", base, spad_server_number);
+ return 0;
+ }
+ num = getenv("SPADNUM");
+ if (num == NULL) {
+/* fprintf(stderr,
+ "\n(AXIOM Sockets) The AXIOM server number is undefined.\n");
+*/
+ return -1;
+ }
+ sprintf(name, "%s%s", base, num);
+ return 0;
+}
+
+/* client Spad server sockets. Two sockets are created: server[0]
+ is the internet server socket, and server[1] is a local domain socket. */
+int
+open_server(char *server_name)
+{
+ char *s, name[256];
+
+ init_socks();
+#ifdef SIGPIPE
+ bsdSignal(SIGPIPE, sigpipe_handler,RestartSystemCalls);
+#endif
+ if (make_server_name(name, server_name) == -1)
+ return -2;
+ /* create the socket internet socket */
+ server[0].socket = 0;
+/* server[0].socket = axiom_communication_link(AF_INET);
+ if (is_invalid_socket(&server[0])) {
+ server[0].socket = 0;
+ } else {
+ server[0].addr.i_addr.sin_family = AF_INET;
+ server[0].addr.i_addr.sin_addr.s_addr = INADDR_ANY;
+ server[0].addr.i_addr.sin_port = 0;
+ if (bind(server[0].socket, &server[0].addr.i_addr,
+ sizeof(server[0].addr.i_addr))) {
+ perror("binding INET stream socket");
+ server[0].socket = 0;
+ return -1;
+ }
+ length = sizeof(server[0].addr.i_addr);
+ if (getsockname(server[0].socket, &server[0].addr.i_addr, &length)) {
+ perror("getting INET server socket name");
+ server[0].socket = 0;
+ return -1;
+ }
+ server_port = ntohs(server[0].addr.i_addr.sin_port);
+ FD_SET(server[0].socket, &socket_mask);
+ FD_SET(server[0].socket, &server_mask);
+ listen(server[0].socket,5);
+ } */
+ /* Next create the local domain socket */
+ server[1].socket = axiom_communication_link(AXIOM_AF_LOCAL);
+ if (is_invalid_socket(&server[1])) {
+ perror("opening local server socket");
+ server[1].socket = 0;
+ return -2;
+ } else {
+ server[1].addr.u_addr.sa_family = AXIOM_AF_LOCAL;
+ memset(server[1].addr.u_addr.sa_data, 0,
+ sizeof(server[1].addr.u_addr.sa_data));
+ strcpy(server[1].addr.u_addr.sa_data, name);
+ if (bind(server[1].socket, &server[1].addr.u_addr,
+ sizeof(server[1].addr.u_addr))) {
+ perror("binding local server socket");
+ server[1].socket = 0;
+ return -2;
+ }
+ FD_SET(server[1].socket, &socket_mask);
+ FD_SET(server[1].socket, &server_mask);
+ listen(server[1].socket, 5);
+ }
+ s = getenv("SPADSERVER");
+ if (s == NULL) {
+/* fprintf(stderr, "Not a spad server system\n"); */
+ return -1;
+ }
+ return 0;
+}
+
+int
+accept_connection(Sock *sock)
+{
+ int client;
+ for(client=0; client<MaxClients && clients[client].socket != 0; client++);
+ if (client == MaxClients) {
+ printf("Ran out of client Sock structures\n");
+ return -1;
+ }
+ clients[client].socket = accept(sock->socket, 0, 0);
+ if (is_invalid_socket(&clients[client])) {
+ perror("accept_connection");
+ clients[client].socket = 0;
+ return -1;
+ }
+ FD_SET(clients[client].socket, &socket_mask);
+ get_socket_type(clients+client);
+ return clients[client].purpose;
+}
+
+/* reads a the socket purpose declaration for classification */
+void
+get_socket_type(Sock *sock)
+{
+ sock->pid = get_int(sock);
+ sock->purpose = get_int(sock);
+ sock->remote = get_int(sock);
+ send_int(sock, getpid());
+ send_int(sock, sock->socket);
+ purpose_table[sock->purpose] = sock;
+ switch (sock->purpose) {
+ case SessionManager:
+ break;
+ case ViewportServer:
+ break;
+ case MenuServer:
+ break;
+ case SessionIO:
+/* redirect_stdio(sock); */
+ break;
+ }
+}
+
+int
+sock_accept_connection(int purpose)
+{
+ fd_set rd;
+ int ret_val, i, p;
+ if (getenv("SPADNUM") == NULL) return -1;
+ while (1) {
+ rd = server_mask;
+ ret_val = sselect(FD_SETSIZE, (fd_set *)&rd, (fd_set *)0, (fd_set *)0, NULL);
+ if (ret_val == -1) {
+ /* perror ("Select"); */
+ return -1;
+ }
+ for(i=0; i<2; i++) {
+ if (is_valid_socket(&server[i])
+ && FD_ISSET(server[i].socket, &rd)) {
+ p = accept_connection(server+i);
+ if (p == purpose) return 1;
+ }
+ }
+ }
+}
+
+/* direct stdin and stdout from the given socket */
+void
+redirect_stdio(Sock *sock)
+{
+ int fd;
+/* setbuf(stdout, NULL); */
+ fd = dup2(sock->socket, 1);
+ if (fd != 1) {
+ fprintf(stderr, "Error connecting stdout to socket\n");
+ return;
+ }
+ fd = dup2(sock->socket, 0);
+ if (fd != 0) {
+ fprintf(stderr, "Error connecting stdin to socket\n");
+ return;
+ }
+ fprintf(stderr, "Redirected standard IO\n");
+ FD_CLR(sock->socket, &socket_mask);
+}
+
+void
+init_socks(void)
+{
+ int i;
+ FD_ZERO(&socket_mask);
+ FD_ZERO(&server_mask);
+ init_purpose_table();
+ for(i=0; i<2; i++) server[i].socket = 0;
+ for(i=0; i<MaxClients; i++) clients[i].socket = 0;
+}
+
+/* Socket I/O selection called from the BOOT serverLoop function */
+
+int
+server_switch(void)
+{
+ int ret_val, i, cmd = 0;
+ fd_set rd, wr, ex, fds_mask;
+ FD_ZERO(&rd);
+ FD_ZERO(&wr);
+ FD_ZERO(&ex);
+ fds_mask = server_mask;
+ cmd = 0;
+ if (purpose_table[SessionManager] != NULL) {
+ FD_SET(0, &fds_mask);
+ FD_SET(purpose_table[SessionManager]->socket, &fds_mask);
+ }
+ while (1) {
+ do {
+ if (purpose_table[MenuServer] != NULL) {
+ FD_SET(purpose_table[MenuServer]->socket, &fds_mask);
+ }
+ rd = fds_mask;
+ ret_val = select(FD_SETSIZE, (void *) &rd, (void *) 0, (void *) 0, (void *) 0);
+ if (ret_val == -1) {
+ /* perror ("Select in switch"); */
+ return -1;
+ }
+ for(i=0; i<2; i++) {
+ if (is_valid_socket(&server[i])
+ && (FD_ISSET(server[i].socket, &rd)))
+ accept_connection(server+i);
+ }
+ } while (purpose_table[SessionManager] == NULL);
+ FD_SET(purpose_table[SessionManager]->socket, &fds_mask);
+ if (FD_ISSET(purpose_table[SessionManager]->socket, &rd)) {
+ cmd = get_int(purpose_table[SessionManager]);
+ return cmd;
+ }
+ if (FD_ISSET(0, &rd)) {
+ return CallInterp;
+ }
+ if (purpose_table[MenuServer] != NULL &&
+ (FD_ISSET(purpose_table[MenuServer]->socket, &rd))) {
+ cmd = get_int(purpose_table[MenuServer]);
+ return cmd;
+ }
+ }
+}
+
+void
+flush_stdout(void)
+{
+ static FILE *fp = NULL;
+ if (fp == NULL) {
+ fp = fdopen(purpose_table[SessionIO]->socket, "w");
+ if (fp == NULL) {
+ perror("fdopen");
+ return;
+ }
+ }
+ fflush(fp);
+}
+
+void
+print_line(char *s)
+{
+ printf("%s\n", s);
+}
+
+
+typedef union {
+ double f;
+ long l[2];
+ } DoubleFloat;
+
+double
+plus_infinity(void )
+{
+ static int init = 0;
+ static DoubleFloat pinf;
+ if (! init) {
+ pinf.l[0] = 0x7ff00000;
+ pinf.l[1] = 0;
+ init = 1;
+ }
+ return pinf.f;
+}
+
+double
+minus_infinity(void)
+{
+ static int init = 0;
+ static DoubleFloat minf;
+ if (! init) {
+ minf.l[0] = 0xfff00000L;
+ minf.l[1] = 0;
+ init = 1;
+ }
+ return minf.f;
+}
+
+double
+NANQ(void)
+{
+ static int init = 0;
+ static DoubleFloat nanq;
+ if (! init) {
+ nanq.l[0] = 0x7ff80000L;
+ nanq.l[1] = 0;
+ init = 1;
+ }
+ return nanq.f;
+}
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/lib/spadcolors.c.pamphlet b/src/lib/spadcolors.c.pamphlet
new file mode 100644
index 00000000..635b0f9f
--- /dev/null
+++ b/src/lib/spadcolors.c.pamphlet
@@ -0,0 +1,618 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/lib spadcolors.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+@
+<<*>>=
+<<license>>
+
+#include "axiom-c-macros.h"
+#include "spadcolors.h"
+
+#include <X11/Xlib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "spadcolors.H1"
+#include "util.H1"
+
+#if 0
+int colors[100];
+#endif
+
+static unsigned long pixels[smoothConst+1];
+
+
+/*
+ * make sure you define a global variable like int *spadColors; in the main
+ * program
+ */
+
+/*
+ * code taken from Foley and Van Dam "Fundamentals of Interactive Computer
+ * Graphics"
+ */
+
+
+
+RGB
+HSVtoRGB(HSV hsv)
+{
+ RGB rgb;
+ float h, f, p, q, t;
+ int i;
+
+ rgb.r = 0.0;
+ rgb.g = 0.0;
+ rgb.b = 0.0;
+ if (hsv.s == 0.0) {
+ rgb.r = rgb.g = rgb.b = hsv.v;
+ return (rgb);
+ }
+ else {
+ if (hsv.h == 360.0) {
+ hsv.h = 0.0;
+ }
+ h = hsv.h / 60;
+ i = floor(h);
+ f = h - i;
+ p = hsv.v * (1 - hsv.s);
+ q = hsv.v * (1 - (hsv.s * f));
+ t = hsv.v * (1 - (hsv.s * (1 - f)));
+ switch (i) {
+ case 0:
+ rgb.r = hsv.v;
+ rgb.g = t;
+ rgb.b = p;
+ break;
+ case 1:
+ rgb.r = q;
+ rgb.g = hsv.v;
+ rgb.b = p;
+ break;
+ case 2:
+ rgb.r = p;
+ rgb.g = hsv.v;
+ rgb.b = t;
+ break;
+ case 3:
+ rgb.r = p;
+ rgb.g = q;
+ rgb.b = hsv.v;
+ break;
+ case 4:
+ rgb.r = t;
+ rgb.g = p;
+ rgb.b = hsv.v;
+ break;
+ case 5:
+ rgb.r = hsv.v;
+ rgb.g = p;
+ rgb.b = q;
+ break;
+ }
+ return (rgb);
+ }
+}
+
+float
+value(float n1, float n2, float hue)
+{
+ float v;
+
+ if (hue > 360.0)
+ hue -= 360.0;
+ if (hue < 0.0)
+ hue += 360.0;
+ if (hue < 60.0) {
+ v = n1 + (n2 - n1) * hue / 60.0;
+ }
+ else {
+ if (hue < 180.0)
+ v = n2;
+ else {
+ if (hue < 240.0)
+ v = n1 + (n2 - n1) * (240.0 - hue) / 60.0;
+ else
+ v = n1;
+ }
+ }
+ return (v);
+}
+
+
+
+RGB
+HLStoRGB(HLS hls)
+{
+ RGB rgb;
+ float m1, m2;
+
+ if (hls.l <= 0.5) {
+ m2 = hls.l * (1.0 + hls.s);
+ }
+ else {
+ m2 = hls.l + hls.s - hls.l * hls.s;
+ }
+ m1 = 2.0 * hls.l - m2;
+ rgb.r = value(m1, m2, hls.h + 120.0);
+ rgb.g = value(m1, m2, hls.h);
+ rgb.b = value(m1, m2, hls.h - 120.0);
+
+ return (rgb);
+}
+
+
+/******************************************************
+ * int makeColors(dsply,scrn,colorMap,total_Shades) *
+ * *
+ * This routine tries to allocate an adequate color *
+ * map to be used by all the AXIOM applications *
+ * that are to be run under X Windows that use *
+ * colors that may be user-definable (e.g. viewports, *
+ * HyperTeX, etc). All these application should call *
+ * this routine and then access the colors with the *
+ * the returned color map. *
+ * For example, the following creates the map and *
+ * then sets the foreground color for a GC: *
+ * *
+ * i = makeColors(d,s,&cmap,&spadColors,&ts); *
+ * XSetForegroundColor(d,gc,spadColors[3]); *
+ * *
+ * where *
+ * spadColors is of type (unsigned long *) *
+ * i (the return value) is the total number of colors *
+ * allocated. *
+ * ts is the total number of shades for each hue *
+ * *
+ * KF 6/14/90 (modification) *
+ * makeColors creates color table once only. *
+ * hiya is of type static. *
+ ******************************************************/
+
+int
+makeColors(Display *dsply, int scrn, Colormap *colorMap,
+ unsigned long **colorIndex, int *total_Shades)
+{
+
+ int h, s;
+ static unsigned long *hiya; /* keep colortable around for next time */
+ HSV hsv;
+ RGB rgb;
+ XColor color;
+ int okay = yes; /* is true (1) so long as XAllocColor is
+ * working ok. if 0, then we ran out of room
+ * on the color table. */
+ int colorNum;
+
+ /* shade5 definition */
+
+ static float saturations[5] = {0.90, 0.80, 0.74, 0.50, 0.18};
+ static float values[5] = {0.38, 0.58, 0.75, 0.88, 0.94};
+
+ /* static float values[5] = {0.34, 0.52, 0.80, 0.88, 0.94}; */
+
+ /* fprintf(stderr,"makeColors called\n");*/
+
+ /* printf("making new colors....\n"); */
+ *total_Shades = totalShadesConst;
+
+ /* space for color table */
+ hiya = (unsigned long *) saymem("spadcolors30.c", totalHuesConst * (*total_Shades) + 2, sizeof(unsigned long));
+ *colorIndex = hiya;
+
+ for (h = 0, colorNum = 0; okay && h < 60; h += (hueStep - 6)) {
+ for (s = 0; okay && s < *total_Shades; s++) {
+ hsv.h = h;
+ hsv.s = saturations[s];
+ hsv.v = values[s];
+ rgb = HSVtoRGB(hsv);
+ color.red = rgb.r *((1<<16)-1);
+ color.green = rgb.g *((1<<16)-1);
+ color.blue = rgb.b *((1<<16)-1);
+ color.flags = DoRed | DoGreen | DoBlue;
+ /*
+ fprintf(stderr,"%f\t%f\t%f\n",rgb.r,rgb.g,rgb.b);
+ fprintf(stderr,"%d\t%d\t%d\n",color.red,color.green,color.blue);
+ */
+ if ((okay = XAllocColor(dsply, *colorMap, &color)))
+ hiya[colorNum++] = color.pixel; /* hiya points to table */
+ } /* for s */
+ } /* for h */
+ for (h = 60; okay && h < 180; h += 20) {
+ for (s = 0; okay && s < *total_Shades; s++) {
+ hsv.h = h;
+ hsv.s = saturations[s];
+ hsv.v = values[s];
+ rgb = HSVtoRGB(hsv);
+
+ color.red = rgb.r *((1<<16)-1);
+ color.green = rgb.g *((1<<16)-1);
+ color.blue = rgb.b *((1<<16)-1);
+ color.flags = DoRed | DoGreen | DoBlue;
+ /*
+ fprintf(stderr,"%f\t%f\t%f\n",rgb.r,rgb.g,rgb.b);
+ fprintf(stderr,"%d\t%d\t%d\n",color.red,color.green,color.blue);
+ */
+
+ if ((okay = XAllocColor(dsply, *colorMap, &color)))
+ hiya[colorNum++] = color.pixel;
+ }
+ }
+
+ for (h = 180; okay && h <= 300; h += hueStep) {
+ for (s = 0; okay && s < *total_Shades; s++) {
+ hsv.h = h;
+ hsv.s = saturations[s];
+ hsv.v = values[s];
+ rgb = HSVtoRGB(hsv);
+
+ color.red = rgb.r *((1<<16)-1);
+ color.green = rgb.g *((1<<16)-1);
+ color.blue = rgb.b *((1<<16)-1);
+ color.flags = DoRed | DoGreen | DoBlue;
+ /*
+ fprintf(stderr,"%f\t%f\t%f\n",rgb.r,rgb.g,rgb.b);
+ fprintf(stderr,"%d\t%d\t%d\n",color.red,color.green,color.blue);
+ */
+ if ((okay = XAllocColor(dsply, *colorMap, &color)))
+ hiya[colorNum++] = color.pixel;
+ }
+ }
+
+ hiya[colorNum++] = BlackPixel(dsply, scrn);
+ hiya[colorNum++] = WhitePixel(dsply, scrn);
+
+ if (colorNum < (totalShadesConst * totalHuesConst + 2)) {
+ free(*colorIndex);
+ fprintf(stderr,
+ " > Warning: cannot allocate all the necessary colors - switching to monochrome mode\n");
+ *colorIndex = (unsigned long *) saymem("while allocating the colormap for AXIOM ", 2, sizeof(unsigned long));
+ (*colorIndex)[0] = BlackPixel(dsply, scrn);
+ (*colorIndex)[1] = WhitePixel(dsply, scrn);
+ return (-1);
+ }
+
+ return (colorNum);
+}
+
+#ifdef OLD
+/***********************************************************************
+ KF 6/14/90
+ INPUT: display dsply, screen scrn
+ OUTPUT: a pointer to the permutation color vector (permIndex)
+ PURPOSE: when called for the first time, this procedure creates a
+ permutation vector of the color table spadColor. It
+ returns the pointer to this vector for subsequent calls.
+
+***********************************************************************/
+
+int
+makePermVector(Display *dsply, int scrn, unsigned long **permIndex)
+{
+ static int firstTime = yes;
+ unsigned long *spadColorsToo;
+ static unsigned long *pIndex;
+ Colormap cmap;
+ int num_colors;
+ int i, ts;
+
+ if (firstTime) {
+
+ /* initialization */
+
+ cmap = DefaultColormap(dsply, scrn); /* what are other cmaps?? */
+ pIndex = (unsigned long *) saymem("makePermVector", Colorcells, sizeof(unsigned long));
+
+ /* get spadColors table */
+
+ if ((num_colors = makeColors(dsply, scrn, &cmap, &spadColorsToo, &ts)) < 0) {
+ printf("num_colors < 0!!\n");
+ exit(-1);
+ }
+
+ /* initialize unused slots in permutation vector */
+
+ for (i = 0; i < spadColorsToo[0]; i++)
+ pIndex[i] = 0;
+ for (i = num_colors; i < Colorcells; i++)
+ pIndex[i] = 0;
+
+ /* make permutation vector */
+
+ for (i = 0; i < num_colors; i++)
+ pIndex[spadColorsToo[i]] = i;
+
+ firstTime = no;
+ }
+
+ *permIndex = pIndex;
+ return (Colorcells);
+}
+
+#endif
+
+/******************************************************
+ * int makeNewColorMap(dsply,colorMap,smoothHue) *
+ * *
+ * This routine tries to allocate an adequate color *
+ * map to be used by the AXIOM smooth shading *
+ * application that is to be run under X Windows. *
+ * The colors are allocated from available space in *
+ * the colorMap and returned in the array pixels. *
+ * The size of the array is determined by smoothConst *
+ * which is the number of shades desired. The colors *
+ * returned are variations in lightness of the hue *
+ * smoothHue indicated on the control panel Colormap. *
+ * *
+ * If smoothConst colors can be allocated the value *
+ * 1 is returned, otherwise returns 0 *
+ * *
+ ******************************************************/
+
+
+int
+makeNewColorMap(Display *dsply, Colormap colorMap, int smoothHue)
+
+{
+
+ int count, i;
+ float lightness;
+ RGB rgb;
+ XColor xcolor;
+ HLS hls;
+
+ count = 0;
+ for (i = 0; i < (smoothConst + 1); i++) { /* i = 0 .. smoothConst */
+ lightness = (float) (i) / (float) (smoothConst); /* lightnes = 0.0 .. 1.0 */
+ hls.h = (float) smoothHue;
+ hls.l = lightness;
+ hls.s = saturation;
+ rgb = HLStoRGB(hls);
+
+ xcolor.red = rgb.r *((1<<16)-1);
+ xcolor.green = rgb.g *((1<<16)-1);
+ xcolor.blue = rgb.b *((1<<16)-1);
+ xcolor.flags = DoRed | DoGreen | DoBlue;
+ /*
+ fprintf(stderr,"%f\t%f\t%f\n",rgb.r,rgb.g,rgb.b);
+ fprintf(stderr,"%d\t%d\t%d\n",xcolor.red,xcolor.green,xcolor.blue);
+ */
+ if (XAllocColor(dsply, colorMap, &xcolor)) {
+ pixels[count] = xcolor.pixel;
+ count++;
+ }
+ }
+ /* count says how many succeeded */
+ if (count != (smoothConst+1) ) {
+
+ /* we have failed to get all of them - free the ones we got */
+
+ FreePixels(dsply,colorMap,count);
+ return (0);
+ }
+ return (1);
+}
+
+
+
+/******************************************************
+ * unsigned long XPixelColor(num) *
+ * *
+ * XPixelColor is a straight forward function that *
+ * merely returns the XColor value desired within *
+ * the pixels array. For smooth shading, given an *
+ * intensity from 0..1, scaling by the number of *
+ * values in the array will return the location in *
+ * pixels[] of the desired color for that intensity. *
+ * *
+ ******************************************************/
+
+unsigned long
+XPixelColor(int num)
+{
+ if (num < 0)
+ num = 0;
+ return (pixels[num]);
+}
+
+
+/******************************************************
+ * FreePixels(dsply,colorMap,num) *
+ * *
+ * FreePixels is a call to XFreeColors which frees *
+ * previously allocated colors for the indicated *
+ * colorMap. If it cannot free the number of colors *
+ * given by num a BadAccess error will crash the *
+ * viewport process. This should ONLY be used if *
+ * it can be guaranteed that there will be num colors *
+ * to free in colorMap. return 0 == success *
+ * *
+ ******************************************************/
+
+
+void
+FreePixels(Display *dsply, Colormap colorMap, int num)
+{
+
+ XFreeColors(dsply, colorMap, pixels, num, 0);
+}
+
+
+
+/******************************************************
+ * int AllocCells(dsply,colorMap,smoothHue) *
+ * *
+ * Use either makeNewColormap() OR AllocCells(). *
+ * This routine tries to allocate an adequate color *
+ * map to be used by the AXIOM smooth shading *
+ * application that is to be run under X Windows. *
+ * The colors are allocated from available space in *
+ * the colorMap and returned in the array pixels. *
+ * The size of the array is determined by smoothConst *
+ * which is the number of shades desired. The colors *
+ * returned are variations in lightness of the hue *
+ * smoothHue indicated on the control panel Colormap. *
+ * *
+ * It is different from makeNewColormap() in that *
+ * the cells are read/write, and if it cannot alloc *
+ * all the colors desired it doesn't allocate any. *
+ * *
+ ******************************************************/
+
+
+int
+AllocCells(Display *dsply, Colormap colorMap, int smoothHue)
+@
+This routine used to have the following code block. However this
+code block makes no sense. To see why you need to know that an
+XColor object looks like:
+\begin{verbatim}
+/*
+ * Data structure used by color operations
+ */
+typedef struct {
+ unsigned long pixel;
+ unsigned short red, green, blue;
+ char flags; /* do_red, do_green, do_blue */
+ char pad;
+} XColor;
+\end{verbatim}
+This routine used to set the values of all of the elements of the XColor struct
+except [[pixel]]. This is usually done to specify a desired color in RGB
+values. To try to get a pixel value close to that color you call XAllocColor.
+This routine sets up the desired color values but it never asks for the pixel
+(which is really an index into the colormap of the nearest color) value that
+corresponds to the desired color. In fact it uses pixel without ever giving
+it a value. I've rewritten that code.
+\begin{verbatim}
+{
+ unsigned long plane_masks[1];
+ int i, count;
+ float lightness;
+ RGB rgb;
+ XColor xcolor;
+ HLS hls;
+
+ count = 0;
+ for (i = 0; i < (smoothConst + 1); i++) {
+ lightness = (float) (i) / (float) (smoothConst);
+ hls.h = (float) smoothHue;
+ hls.l = lightness;
+ hls.s = saturation;
+ rgb = HLStoRGB(hls);
+ xcolor.red = rgb.r *((1@<<16)-1);
+ xcolor.green = rgb.g *((1@<<16)-1);
+ xcolor.blue = rgb.b *((1@<<16)-1);
+ xcolor.flags = DoRed | DoGreen | DoBlue;
+ /*
+ fprintf(stderr,"%f\t%f\t%f\n",rgb.r,rgb.g,rgb.b);
+ fprintf(stderr,"%d\t%d\t%d\n",xcolor.red,xcolor.green,xcolor.blue);
+ */
+ pixels[i] = xcolor.pixel;
+ count++;
+ }
+ if (XAllocColorCells(dsply, colorMap, False,
+ plane_masks, 0, pixels, smoothConst + 1)) {
+ return (smoothConst + 1);
+ }
+ else {
+ return (0);
+ }
+}
+\end{verbatim}
+<<*>>=
+{
+ unsigned long plane_masks[1];
+ int i, count;
+ float lightness;
+ RGB rgb;
+ XColor xcolor;
+ HLS hls;
+
+ count = 0;
+ for (i = 0; i < (smoothConst + 1); i++) {
+ lightness = (float) (i) / (float) (smoothConst);
+ hls.h = (float) smoothHue;
+ hls.l = lightness;
+ hls.s = saturation;
+ rgb = HLStoRGB(hls);
+ xcolor.red = rgb.r *((1<<16)-1);
+ xcolor.green = rgb.g *((1<<16)-1);
+ xcolor.blue = rgb.b *((1<<16)-1);
+ xcolor.flags = DoRed | DoGreen | DoBlue;
+ /*
+ fprintf(stderr,"%f\t%f\t%f\n",rgb.r,rgb.g,rgb.b);
+ fprintf(stderr,"%d\t%d\t%d\n",xcolor.red,xcolor.green,xcolor.blue);
+ */
+@
+Here I've modified the code to actually as for the pixel (colormap index) that
+most closely matches our requested RGB values.
+<<*>>=
+ if (XAllocColor(dsply, colorMap, &xcolor)) {
+ pixels[count] = xcolor.pixel;
+ count++;
+ }
+ }
+ /* count says how many succeeded */
+ if (count != (smoothConst+1) ) {
+ /* we have failed to get all of them - free the ones we got */
+ FreePixels(dsply,colorMap,count);
+ return (0);
+ }
+ if (XAllocColorCells(dsply, colorMap, False,
+ plane_masks, 0, pixels, smoothConst + 1)) {
+ return (smoothConst + 1);
+ }
+ else {
+ return (0);
+ }
+}
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/lib/util.c.pamphlet b/src/lib/util.c.pamphlet
new file mode 100644
index 00000000..f4ec3a6e
--- /dev/null
+++ b/src/lib/util.c.pamphlet
@@ -0,0 +1,192 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/lib util.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\newpage
+<<*>>=
+<<license>>
+
+#include "axiom-c-macros.h"
+
+#include <stdlib.h>
+@
+The MACOSX platform is broken because no matter what you do it seems to
+include files from [[/usr/include/sys]] ahead of [[/usr/include]]. On linux
+systems these files include themselves which causes an infinite regression
+of includes that fails. GCC gracefully steps over that problem but the
+build fails anyway. On MACOSX the [[/usr/include/sys]] versions
+of files are badly broken with respect to the [[/usr/include]] versions.
+<<*>>=
+#if defined(MACOSXplatform)
+#include "/usr/include/unistd.h"
+#else
+#include <unistd.h>
+#endif
+#include <sys/types.h>
+#include <stdio.h>
+#include <errno.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include "view.h"
+
+
+#include "util.H1"
+
+
+
+
+int
+checker(int code, int lineNumber, char *errorStr)
+{
+ if (code < 0) {
+ fprintf(stderr, "Error occured during %s\n", errorStr);
+ fprintf(stderr, "Error code of %d\n", errno);
+ fprintf(stderr, "Error in line number %d of process %d\n", lineNumber, getpid());
+ perror("");
+ }
+ return (code);
+}
+
+
+
+
+char *
+getmemWithLine(int nbytes, char *str, int lineNum)
+{
+ char *p;
+
+ p = (char *) malloc(nbytes);
+ if (!p) {
+ fprintf(stderr, "getmem: Could not get %d bytes for %s at line %d\n", nbytes, str, lineNum);
+ exit(99);
+ }
+ return p;
+}
+
+
+char *
+saymemWithLine(char *str, int num, int size, int lineNum)
+{
+ char *p;
+
+ p = getmemWithLine(num * size, str, lineNum);
+ return p;
+
+}
+
+
+void
+#ifdef _NO_PROTO
+myfree(p, size)
+ void *p;
+ int size;
+#else
+myfree(void *p, int size)
+#endif
+{
+ free(p);
+}
+
+
+
+
+XPoint
+getWindowPositionXY(Display *display, Window w)
+{
+ XPoint position;
+ Window rootW, parentW, *childrenWs, tmpW;
+ unsigned int nChildren;
+ XWindowAttributes windowAttrib;
+ int screen, tmp = 1;
+
+ screen = DefaultScreen(display);
+ tmpW = w;
+ while (tmp) {
+ XQueryTree(display, tmpW, &rootW, &parentW, &childrenWs, &nChildren);
+ XFree((char *)childrenWs);
+ if (parentW == RootWindow(display, screen))
+ tmp = 0;
+ else
+ tmpW = parentW;
+ }
+ XGetWindowAttributes(display, tmpW, &windowAttrib);
+ position.x = (short) windowAttrib.x;
+ position.y = (short) windowAttrib.y;
+
+ return (position);
+}
+
+
+
+XPoint
+getWindowSizeXY(Display *display,Window w)
+{
+ XPoint size;
+ Window rootW, parentW, *childrenWs, tmpW;
+ unsigned int nChildren;
+ XWindowAttributes windowAttrib;
+ int screen, tmp = 1;
+
+ screen = DefaultScreen(display);
+ tmpW = w;
+ while (tmp) {
+ XQueryTree(display, tmpW, &rootW, &parentW, &childrenWs, &nChildren);
+ XFree((char *)childrenWs);
+ if (parentW == RootWindow(display, screen))
+ tmp = 0;
+ else
+ tmpW = parentW;
+ }
+ XGetWindowAttributes(display, tmpW, &windowAttrib);
+ size.x = (short) windowAttrib.width;
+ size.y = (short) windowAttrib.height;
+
+ return (size);
+}
+@
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+@
+\newpage
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/lib/wct.c.pamphlet b/src/lib/wct.c.pamphlet
new file mode 100644
index 00000000..0ceff558
--- /dev/null
+++ b/src/lib/wct.c.pamphlet
@@ -0,0 +1,768 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/lib wct.c}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\newpage
+<<*>>=
+<<license>>
+/*
+ * Word completion.
+ *
+ *
+ * Word completion is driven from a list of completion tables. Each table
+ * contains a list of words.
+ *
+ */
+
+#include "axiom-c-macros.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+@
+The MACOSX platform is broken because no matter what you do it seems to
+include files from [[/usr/include/sys]] ahead of [[/usr/include]]. On linux
+systems these files include themselves which causes an infinite regression
+of includes that fails. GCC gracefully steps over that problem but the
+build fails anyway. On MACOSX the [[/usr/include/sys]] versions
+of files are badly broken with respect to the [[/usr/include]] versions.
+<<*>>=
+#if defined(MACOSXplatform)
+#include "/usr/include/unistd.h"
+#else
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <fcntl.h>
+#if defined(MACOSXplatform)
+#include "/usr/include/time.h"
+#else
+#include <time.h>
+#endif
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+/* #define PINFO *//* A flag to suppress printing of the file info */
+
+#define WCT /* A flag needed because ctype.h stole some
+ * of my constants */
+#include "edible.h"
+
+#define MAX_PREFIX 1024
+#define strneql(a,b,n) (*(a) == *(b) && !strncmp((a),(b),(n)))
+#define Delimiter(c) (! isalnum(c) && c != '%' && c != '!' && c != '?' && c != '_')
+
+
+#include "wct.H1"
+#include "prt.H1"
+#include "edin.H1"
+
+
+
+static Wct *pwct = 0;
+static Wix *pwix;
+static Wix curr_wix;
+static char curr_prefix[MAX_PREFIX];
+static Wct *pHeadwct;
+
+time_t
+ftime(char *path)
+{
+ int rc;
+ struct stat stbuf;
+
+ rc = stat(path, &stbuf);
+ if (rc == -1)
+ fatal("Cannot deterimine status of %s.", path);
+
+ return stbuf.st_mtime;
+}
+
+off_t
+fsize(char *path)
+{
+ int rc;
+ struct stat stbuf;
+
+ rc = stat(path, &stbuf);
+ if (rc == -1)
+ fatal("Cannot deterimine status of %s.", path);
+
+ return stbuf.st_size;
+}
+
+
+/*
+ * Scan a word completion table for a particular word.
+ */
+
+
+Wix *
+scanWct(Wct *pwct, char *prefix)
+{
+ long fmod;
+ int preflen, i, wc;
+ char **wv;
+
+ preflen = strlen(prefix);
+ strncpy(curr_prefix, prefix, MAX_PREFIX);
+
+ pHeadwct = pwct;
+ curr_wix.pwct = 0;
+ curr_wix.word = 0;
+
+ for (; pwct; pwct = pwct->next) {
+ curr_wix.pwct = pwct;
+
+
+
+ fmod = ftime(pwct->fname);
+ if (fmod > pwct->ftime)
+ reintern1Wct(pwct);
+
+ wv = pwct->wordv;
+ wc = pwct->wordc;
+ for (i = 0; i < wc; i++) {
+ curr_wix.word = i;
+ if (strneql(wv[i], prefix, preflen))
+ return &curr_wix;
+ }
+ }
+ return 0;
+}
+
+Wix *
+rescanWct(void)
+{
+ Wct *pwct, *start_pwct;
+ int preflen, start_word, i, wc;
+ char **wv, *prefix;
+
+ start_pwct = curr_wix.pwct;
+ start_word = curr_wix.word;
+
+ if (!start_pwct) return(0);
+ prefix = curr_prefix;
+ preflen = strlen(prefix);
+
+ /*
+ * Finish the current structure.
+ */
+
+ pwct = start_pwct;
+
+ curr_wix.pwct = pwct;
+ wv = pwct->wordv;
+ wc = pwct->wordc;
+ for (i = start_word + 1; i < wc; i++) {
+ curr_wix.word = i;
+ if (strneql(wv[i], prefix, preflen))
+ return &curr_wix;
+ }
+
+ /*
+ * Finish to the end of the list, doing whole structures.
+ */
+ for (pwct = pwct->next; pwct; pwct = pwct->next) {
+ curr_wix.pwct = pwct;
+
+ wv = pwct->wordv;
+ wc = pwct->wordc;
+ for (i = 0; i < wc; i++) {
+ curr_wix.word = i;
+ if (strneql(wv[i], prefix, preflen))
+ return &curr_wix;
+ }
+ }
+
+ /*
+ * Restart at beginning, doing whole structures.
+ */
+ for (pwct = pHeadwct; pwct != start_pwct; pwct = pwct->next) {
+ curr_wix.pwct = pwct;
+
+ wv = pwct->wordv;
+ wc = pwct->wordc;
+ for (i = 0; i < wc; i++) {
+ curr_wix.word = i;
+ if (strneql(wv[i], prefix, preflen))
+ return &curr_wix;
+ }
+ }
+
+ /*
+ * Do beginning half of the start structure.
+ */
+ curr_wix.pwct = pwct;
+ wv = pwct->wordv;
+ wc = pwct->wordc;
+ for (i = 0; i <= start_word; i++) {
+ curr_wix.word = i;
+ if (strneql(wv[i], prefix, preflen))
+ return &curr_wix;
+ }
+
+ /* Not found? */
+ return 0;
+}
+
+/*
+ * Summarize a table.
+ */
+void
+skimWct(Wct *pwct)
+{
+ while (pwct) {
+#ifdef PINFO
+ skim1Wct(pwct);
+#endif
+ pwct = pwct->next;
+ }
+}
+
+void
+skim1Wct(Wct *pwct)
+{
+#define NHEAD 13
+#define NTAIL 7
+
+ int cc;
+
+ printf("%-10s", pwct->fname);
+ printTime((long *)&(pwct->ftime));
+ cc = skimString(pwct->fimage, pwct->fsize, NHEAD, NTAIL);
+ printf("%s", " " + (cc - (NHEAD + NTAIL)));
+ printf(" [%d w, %ld c]", pwct->wordc, (long)(pwct->fsize));
+ printf("\n");
+
+#ifdef SHOW_WORDS
+ {
+ int i;
+ char **wv;
+
+ for (i = 1, wv = pwct->wordv; *wv; i++, wv++) {
+ printf("%5d: %s\n", i, *wv);
+ }
+ }
+#endif
+}
+
+void
+printTime(long *clock)
+{
+ struct tm *tm;
+
+ tm = localtime((time_t *)clock);
+ printf("%.2d/%.2d/%.2d %.2d:%.2d:%.2d ",
+ tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+}
+
+int
+skimString(char *s, int slen,int nhead,int ntail)
+{
+ int spos, tlen, i, cc;
+
+ cc = printf("\"");
+ for (spos = 0; spos < slen && cc <= nhead; spos++)
+ cc += prChar(s[spos]);
+
+ /* Assume same tail has the same multi-character format ratio. */
+ tlen = ntail * ((1.0 * spos) / nhead);
+
+ if (spos + tlen >= slen)
+ for (; spos < slen; spos++)
+ cc += prChar(s[spos]);
+ else {
+ cc += printf("\"...\"");
+ for (i = slen - tlen; i < slen; i++)
+ cc += prChar(s[i]);
+ }
+ cc += printf("\"");
+ return cc;
+}
+
+int
+prChar(int c)
+{
+ if (c == '\n')
+ return printf("\\n");
+ if (c == '\t')
+ return printf("\\t");
+ if (c == '\b')
+ return printf("\\b");
+ if (c == '"')
+ return printf("\\\"");
+ if (iscntrl(c))
+ return printf("^%c", (c + 0100) % 0200);
+ if (isascii(c))
+ return printf("%c", c);
+
+ return printf("\\%d", c);
+}
+
+Wct *
+reread1Wct(Wct *pwct)
+{
+ int fd, rc;
+
+ /* Check information about the file. */
+ pwct->fsize = fsize(pwct->fname);
+ pwct->ftime = ftime(pwct->fname);
+
+ /* Allocate space for file image */
+ if (pwct->fimage)
+ free(pwct->fimage);
+ pwct->fimage = (char *) malloc(pwct->fsize + 1);
+ if (pwct->fimage == 0)
+ sfatal("Cannot allocate new table.");
+ pwct->fimage[pwct->fsize] = 0;
+
+ /* Read file into buffer. */
+ fd = open(pwct->fname, O_RDONLY);
+ if (fd == -1)
+ fatal("Cannot read file %s.", pwct->fname);
+ rc = read(fd, pwct->fimage, pwct->fsize);
+ if (rc != pwct->fsize)
+ fatal("Did not read all of file %s.", pwct->fname);
+
+ return pwct;
+}
+
+Wct *
+read1Wct(char *fname)
+{
+ Wct *pwct;
+
+ /* Allocate a new link for this file. */
+ pwct = (Wct *) malloc(sizeof(Wct));
+ if (pwct == 0)
+ sfatal("Cannot allocate new table.");
+
+ pwct->fname = fname;
+ pwct->wordc = 0;
+ pwct->wordv = 0;
+ pwct->fimage = 0;
+ pwct->next = 0;
+
+ return reread1Wct(pwct);
+}
+
+Wct *
+nconcWct(Wct *pwct,Wct * qwct)
+{
+ Wct *p0 = pwct;
+
+ if (!p0)
+ return qwct;
+
+ while (pwct->next)
+ pwct = pwct->next;
+ pwct->next = qwct;
+
+ return p0;
+}
+
+void
+sortWct(Wct *pwct)
+{
+ while (pwct) {
+ sort1Wct(pwct);
+ pwct = pwct->next;
+ }
+}
+
+void
+sort1Wct(Wct *pwct)
+{
+ qsort((char *) pwct->wordv, pwct->wordc,
+ sizeof(*(pwct->wordv)), mystrcmp);
+}
+
+int
+mystrcmp(const void *s1,const void * s2)
+{
+ return strcmp(*(char **)s1, *(char **)s2);
+}
+
+/*
+ * Break wct struct into words.
+ */
+
+void
+burstWct(Wct *pwct)
+{
+ while (pwct) {
+ burst1Wct(pwct);
+ pwct = pwct->next;
+ }
+}
+
+void
+burst1Wct(Wct *pwct)
+{
+ char *s, **wv;
+ int i, j, inword = 0;
+
+
+ for (s = pwct->fimage, i = 0; i < pwct->fsize; s++, i++) {
+ if (isspace(*s) || iscntrl(*s)) {
+ *s = 0;
+ inword = 0;
+ }
+ else if (!inword) {
+ inword = 1;
+ pwct->wordc++;
+ }
+ }
+
+ if (pwct->wordv)
+ free(pwct->wordv);
+ pwct->wordv = (char **) calloc(pwct->wordc + 1, sizeof(char *));
+ if (!pwct->wordv)
+ fatal("Could not make word list for %s.", pwct->fname);
+
+ s = pwct->fimage;
+ i = 0;
+ for (wv = pwct->wordv, j = 0; j < pwct->wordc; wv++, j++) {
+ while (i < pwct->fsize && !s[i])
+ i++;
+ *wv = s + i;
+ while (i < pwct->fsize && s[i])
+ i++;
+ }
+ *wv = 0;
+}
+
+Wct *
+intern1Wct(char *fname)
+{
+ Wct *pwct;
+
+ pwct = read1Wct(fname);
+ burst1Wct(pwct);
+ return pwct;
+}
+
+void
+reintern1Wct(Wct *pwct)
+{
+ reread1Wct(pwct);
+ burst1Wct(pwct);
+}
+
+void
+sfatal(char *s)
+{
+ fatal("%s", s);
+}
+
+void
+fatal(char *fmt,char * s)
+{
+ static char fbuf[256];
+
+ sprintf(fbuf, fmt, s);
+
+ perror(fbuf);
+ exit(1);
+}
+
+
+
+/* load up the wct database */
+void
+load_wct_file(char *fname)
+{
+ pwct = nconcWct(intern1Wct(fname), pwct);
+}
+
+void
+skim_wct(void)
+{
+ skimWct(pwct);
+}
+
+/*
+ * This routine is called when a tab is hit. It simply takes the current
+ * buffer and tries to find a completion of the last word on the line in the
+ * data base.
+ */
+
+
+void
+rescan_wct(void)
+{
+ int b = curr_pntr - 1;
+ int old_len;
+ int new_len;
+ int diff;
+ int i;
+ int ncs = 0;
+
+ /*
+ * first thing I should do is find my way back to the beginning of the
+ * word
+ */
+ while (b && !Delimiter(buff[b]))
+ b--;
+ if (Delimiter(buff[b]))
+ b++;
+
+ old_len = curr_pntr - b;
+
+ pwix = rescanWct();
+
+ if (!pwix) {
+ putchar(_BELL);
+ fflush(stdout);
+ }
+ else {
+ Wct *pwct = pwix->pwct; /* start replacing it */
+
+ new_len = strlen(pwct->wordv[pwix->word]);
+ if (new_len > old_len) {
+
+ /*
+ * I have to just slide the characters forward a bit, stuff in
+ * the new characters, and then adjust curr_pntr
+ */
+ diff = new_len - old_len;
+ if (curr_pntr != buff_pntr) {
+ forwardcopy(&buff[curr_pntr + diff],
+ &buff[curr_pntr],
+ buff_pntr - curr_pntr);
+ forwardflag_cpy(&buff_flag[curr_pntr + diff],
+ &buff_flag[curr_pntr],
+ buff_pntr - curr_pntr);
+ }
+ buff_pntr += diff;
+ ncs = curr_pntr + diff;
+
+ /* Now insert the new word */
+ for (i = 0; i < new_len; i++)
+ buff[b + i] = (pwct->wordv[pwix->word])[i];
+
+ /* move cursor to the beginning of the word */
+ for (; curr_pntr != b; curr_pntr--)
+ putchar(_BKSPC);
+
+ /** now print the characters on the rest of the line **/
+ printbuff(curr_pntr, buff_pntr - curr_pntr);
+
+ /* now move bcak the number of characters I want to */
+ for (i = buff_pntr; i != ncs; i--)
+ putchar(_BKSPC);
+
+ fflush(stdout);
+
+ curr_pntr = ncs;
+ }
+ else if (new_len < old_len) {
+ /* this time I simply copy backwards and do the substituting */
+ diff = old_len - new_len;
+ strncpy(&buff[curr_pntr - diff],
+ &buff[curr_pntr],
+ buff_pntr - curr_pntr);
+ flagncpy(&buff_flag[curr_pntr - diff],
+ &buff_flag[curr_pntr],
+ buff_pntr - curr_pntr);
+ buff_pntr -= diff;
+ ncs = curr_pntr - diff;
+
+ /* Now insert the new word */
+ for (i = 0; i < new_len; i++)
+ buff[b + i] = (pwct->wordv[pwix->word])[i];
+
+ /* move cursor to the beginning of the word */
+ for (; curr_pntr != b; curr_pntr--)
+ putchar(_BKSPC);
+
+ /** now print the characters on the rest of the line **/
+ printbuff(b, buff_pntr - b);
+
+ /* now blank out the characters out on the end of this line */
+ for (i = 0; i < diff; i++)
+ myputchar(' ');
+
+ /* now move back the number of characters I want to */
+ for (i = buff_pntr + diff; i != ncs; i--)
+ putchar(_BKSPC);
+
+ fflush(stdout);
+
+ curr_pntr = ncs;
+ }
+ else {
+ diff = 0;
+ ncs = curr_pntr;
+ /* Now insert the new word */
+ for (i = 0; i < new_len; i++)
+ buff[b + i] = (pwct->wordv[pwix->word])[i];
+
+ /* move cursor to the beginning of the word */
+ for (; curr_pntr != b; curr_pntr--)
+ putchar(_BKSPC);
+
+ /** now print the characters on the rest of the line **/
+ printbuff(curr_pntr, buff_pntr - curr_pntr);
+
+ /* now move back the number of characters I want to */
+ for (i = buff_pntr; i != ncs; i--)
+ putchar(_BKSPC);
+
+ fflush(stdout);
+
+ curr_pntr = ncs;
+ }
+ }
+}
+
+void
+find_wct(void)
+{
+
+ char search_buff[100];
+ char *filler = search_buff;
+ int b = curr_pntr - 1;
+ int e = curr_pntr;
+ int ne = 0;
+ int st;
+ Wix *pwix;
+ int curr_len;
+ int new_len;
+ int diff;
+ int i;
+
+ /*
+ * First thing I do is try and construct the string to be searched for.
+ * Basically I just start from the curr_pntr and search backward until I
+ * find a blank. Once I find a blank I copy forward until I get back to
+ * curr_pntr;
+ */
+ if (!curr_pntr) {
+ putchar(_BELL);
+ return;
+ }
+ /* then get back to the first blank or back to the beginning */
+ while (b && !Delimiter(buff[b]))
+ b--;
+ if (Delimiter(buff[b]))
+ b++;
+
+ /* At the same time, let me find the end of the word */
+ while (e < buff_pntr && !Delimiter(buff[e])) {
+ e++;
+ ne++;
+ }
+
+ st = b;
+ curr_len = e - b;
+
+ /* now simply copy the text forward */
+ while (b < curr_pntr)
+ *filler++ = buff[b++];
+
+ *filler = '\0';
+
+ pwix = scanWct(pwct, search_buff);
+
+ /*
+ * else pwix = rescanWct();
+ */
+
+ if (!pwix) {
+ putchar(_BELL);
+ fflush(stdout);
+ }
+ else {
+ Wct *pwct = pwix->pwct;
+
+ /*
+ * printf("Found %s in file %s\n", pwct->wordv[pwix->word],
+ * pwct->fname);
+ */
+ /* copy them buffer into where it should be */
+ new_len = strlen(pwct->wordv[pwix->word]);
+ diff = new_len - curr_len;
+ if (curr_pntr != buff_pntr) {
+ forwardcopy(&buff[curr_pntr + diff],
+ &buff[curr_pntr],
+ buff_pntr - curr_pntr);
+ forwardflag_cpy(&buff_flag[curr_pntr + diff],
+ &buff_flag[curr_pntr],
+ buff_pntr - curr_pntr);
+ }
+ buff_pntr += diff;
+
+
+ /* Now insert the new characters */
+ for (i = new_len - diff; i < new_len; i++)
+ buff[st + i] = (pwct->wordv[pwix->word])[i];
+
+ /* Now move the cursor forward to the end of the word */
+ for (i = 0; i < diff; i++)
+ putchar(buff[curr_pntr++]);
+
+ /** now print the characters on the rest of the line **/
+ printbuff(curr_pntr, buff_pntr - curr_pntr);
+
+ /* now move bcak the number of characters I want to */
+ for (i = buff_pntr; i != e + diff; i--)
+ putchar(_BKSPC);
+
+ fflush(stdout);
+
+ curr_pntr = diff + e;
+
+ }
+
+
+}
+@
+\section{License}
+<<license>>=
+/*
+Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+@
+\newpage
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}