diff options
author | dos-reis <gdr@axiomatics.org> | 2007-08-14 05:14:52 +0000 |
---|---|---|
committer | dos-reis <gdr@axiomatics.org> | 2007-08-14 05:14:52 +0000 |
commit | ab8cc85adde879fb963c94d15675783f2cf4b183 (patch) | |
tree | c202482327f474583b750b2c45dedfc4e4312b1d /src/lib | |
download | open-axiom-ab8cc85adde879fb963c94d15675783f2cf4b183.tar.gz |
Initial population.
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/ChangeLog | 211 | ||||
-rw-r--r-- | src/lib/Makefile.in | 77 | ||||
-rw-r--r-- | src/lib/Makefile.pamphlet | 212 | ||||
-rw-r--r-- | src/lib/XDither.c.pamphlet | 254 | ||||
-rw-r--r-- | src/lib/XShade.c.pamphlet | 236 | ||||
-rw-r--r-- | src/lib/XSpadFill.c.pamphlet | 321 | ||||
-rw-r--r-- | src/lib/axiom.xpm.pamphlet | 163 | ||||
-rw-r--r-- | src/lib/bsdsignal.c.pamphlet | 320 | ||||
-rw-r--r-- | src/lib/cfuns-c.c.pamphlet | 285 | ||||
-rw-r--r-- | src/lib/cursor.c.pamphlet | 164 | ||||
-rw-r--r-- | src/lib/edin.c.pamphlet | 971 | ||||
-rw-r--r-- | src/lib/emupty.c.pamphlet | 242 | ||||
-rw-r--r-- | src/lib/fnct_key.c.pamphlet | 395 | ||||
-rw-r--r-- | src/lib/halloc.c.pamphlet | 79 | ||||
-rw-r--r-- | src/lib/hash.c.pamphlet | 240 | ||||
-rw-r--r-- | src/lib/openpty.c.pamphlet | 226 | ||||
-rw-r--r-- | src/lib/pixmap.c.pamphlet | 352 | ||||
-rw-r--r-- | src/lib/prt.c.pamphlet | 429 | ||||
-rw-r--r-- | src/lib/sockio-c.c.pamphlet | 1218 | ||||
-rw-r--r-- | src/lib/spadcolors.c.pamphlet | 618 | ||||
-rw-r--r-- | src/lib/util.c.pamphlet | 192 | ||||
-rw-r--r-- | src/lib/wct.c.pamphlet | 768 |
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} |