diff options
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} | 
