From 8531f4c74274b8aa99168d220738227557a9c418 Mon Sep 17 00:00:00 2001 From: dos-reis Date: Fri, 7 Mar 2008 15:19:01 +0000 Subject: * hyper/: De-pamphletize. --- configure | 18 +- configure.ac | 2 +- configure.ac.pamphlet | 2 +- src/ChangeLog | 4 + src/hyper/Makefile.in | 94 +-- src/hyper/ReadBitmap.c | 259 ++++++++ src/hyper/ReadBitmap.pamphlet | 296 --------- src/hyper/addfile.c | 309 +++++++++ src/hyper/addfile.h | 41 ++ src/hyper/addfile.pamphlet | 347 ---------- src/hyper/bitmaps.pamphlet | 143 ---- src/hyper/cond.c | 150 +++++ src/hyper/cond.pamphlet | 188 ------ src/hyper/debug.c | 48 ++ src/hyper/debug.pamphlet | 77 --- src/hyper/dialog.c | 1349 ++++++++++++++++++++++++++++++++++++++ src/hyper/dialog.pamphlet | 1388 --------------------------------------- src/hyper/display.c | 299 +++++++++ src/hyper/display.h | 44 ++ src/hyper/display.pamphlet | 337 ---------- src/hyper/event.c | 1062 ++++++++++++++++++++++++++++++ src/hyper/event.h | 44 ++ src/hyper/event.pamphlet | 1099 ------------------------------- src/hyper/ex2ht.c | 286 ++++++++ src/hyper/ex2ht.pamphlet | 310 --------- src/hyper/extent.h | 129 ++++ src/hyper/extent.pamphlet | 157 ----- src/hyper/extent1.c | 1371 +++++++++++++++++++++++++++++++++++++++ src/hyper/extent1.pamphlet | 1395 ---------------------------------------- src/hyper/extent2.c | 929 ++++++++++++++++++++++++++ src/hyper/extent2.pamphlet | 957 --------------------------- src/hyper/form-ext.c | 166 +++++ src/hyper/form-ext.pamphlet | 194 ------ src/hyper/group.c | 242 +++++++ src/hyper/group.h | 44 ++ src/hyper/group.pamphlet | 283 -------- src/hyper/halloc.c | 76 +++ src/hyper/halloc.pamphlet | 104 --- src/hyper/hash.c | 221 +++++++ src/hyper/hash.pamphlet | 249 ------- src/hyper/ht_icon | 22 + src/hyper/htadd.c | 537 ++++++++++++++++ src/hyper/htadd.pamphlet | 586 ----------------- src/hyper/hterror.c | 224 +++++++ src/hyper/hterror.h | 45 ++ src/hyper/hterror.pamphlet | 266 -------- src/hyper/hthits.c | 428 ++++++++++++ src/hyper/hthits.pamphlet | 474 -------------- src/hyper/htinp.c | 499 ++++++++++++++ src/hyper/htinp.pamphlet | 528 --------------- src/hyper/htsearch | 12 + src/hyper/hyper.c | 487 ++++++++++++++ src/hyper/hyper.h | 575 +++++++++++++++++ src/hyper/hyper.pamphlet | 1079 ------------------------------- src/hyper/initx.c | 1018 +++++++++++++++++++++++++++++ src/hyper/initx.h | 43 ++ src/hyper/initx.pamphlet | 1058 ------------------------------ src/hyper/input.c | 238 +++++++ src/hyper/input.pamphlet | 268 -------- src/hyper/item.c | 127 ++++ src/hyper/item.pamphlet | 155 ----- src/hyper/keyin.c | 286 ++++++++ src/hyper/keyin.h | 55 ++ src/hyper/keyin.pamphlet | 340 ---------- src/hyper/lex.c | 877 +++++++++++++++++++++++++ src/hyper/lex.h | 46 ++ src/hyper/lex.pamphlet | 933 --------------------------- src/hyper/macro.c | 392 +++++++++++ src/hyper/macro.pamphlet | 421 ------------ src/hyper/mem.c | 747 +++++++++++++++++++++ src/hyper/mem.pamphlet | 788 ----------------------- src/hyper/mouse11.bitmap | 8 + src/hyper/mouse11.mask | 6 + src/hyper/parse-aux.c | 630 ++++++++++++++++++ src/hyper/parse-aux.pamphlet | 670 ------------------- src/hyper/parse-input.c | 602 +++++++++++++++++ src/hyper/parse-input.pamphlet | 631 ------------------ src/hyper/parse-paste.c | 386 +++++++++++ src/hyper/parse-paste.h | 44 ++ src/hyper/parse-paste.pamphlet | 428 ------------ src/hyper/parse-types.c | 775 ++++++++++++++++++++++ src/hyper/parse-types.h | 47 ++ src/hyper/parse-types.pamphlet | 821 ----------------------- src/hyper/parse.c | 842 ++++++++++++++++++++++++ src/hyper/parse.h | 107 +++ src/hyper/parse.pamphlet | 947 --------------------------- src/hyper/presea | 27 + src/hyper/scrollbar.c | 706 ++++++++++++++++++++ src/hyper/scrollbar.h | 43 ++ src/hyper/scrollbar.pamphlet | 746 --------------------- src/hyper/sdown.bitmap | 9 + src/hyper/sdown3d.bitmap | 9 + src/hyper/sdown3dpr.bitmap | 9 + src/hyper/search.pamphlet | 67 -- src/hyper/show-types.c | 599 +++++++++++++++++ src/hyper/show-types.pamphlet | 639 ------------------ src/hyper/spadbuf.c | 258 ++++++++ src/hyper/spadbuf.pamphlet | 286 -------- src/hyper/spadint.c | 1259 ++++++++++++++++++++++++++++++++++++ src/hyper/spadint.pamphlet | 1289 ------------------------------------- src/hyper/sup.bitmap | 9 + src/hyper/sup3d.bitmap | 9 + src/hyper/sup3dpr.bitmap | 9 + src/hyper/titlebar.c | 356 ++++++++++ src/hyper/titlebar.h | 44 ++ src/hyper/titlebar.pamphlet | 398 ------------ src/hyper/token.h | 360 +++++++++++ src/hyper/token.pamphlet | 389 ----------- 108 files changed, 20914 insertions(+), 21817 deletions(-) create mode 100644 src/hyper/ReadBitmap.c delete mode 100644 src/hyper/ReadBitmap.pamphlet create mode 100644 src/hyper/addfile.c create mode 100644 src/hyper/addfile.h delete mode 100644 src/hyper/addfile.pamphlet delete mode 100644 src/hyper/bitmaps.pamphlet create mode 100644 src/hyper/cond.c delete mode 100644 src/hyper/cond.pamphlet create mode 100644 src/hyper/debug.c delete mode 100644 src/hyper/debug.pamphlet create mode 100644 src/hyper/dialog.c delete mode 100644 src/hyper/dialog.pamphlet create mode 100644 src/hyper/display.c create mode 100644 src/hyper/display.h delete mode 100644 src/hyper/display.pamphlet create mode 100644 src/hyper/event.c create mode 100644 src/hyper/event.h delete mode 100644 src/hyper/event.pamphlet create mode 100644 src/hyper/ex2ht.c delete mode 100644 src/hyper/ex2ht.pamphlet create mode 100644 src/hyper/extent.h delete mode 100644 src/hyper/extent.pamphlet create mode 100644 src/hyper/extent1.c delete mode 100644 src/hyper/extent1.pamphlet create mode 100644 src/hyper/extent2.c delete mode 100644 src/hyper/extent2.pamphlet create mode 100644 src/hyper/form-ext.c delete mode 100644 src/hyper/form-ext.pamphlet create mode 100644 src/hyper/group.c create mode 100644 src/hyper/group.h delete mode 100644 src/hyper/group.pamphlet create mode 100644 src/hyper/halloc.c delete mode 100644 src/hyper/halloc.pamphlet create mode 100644 src/hyper/hash.c delete mode 100644 src/hyper/hash.pamphlet create mode 100644 src/hyper/ht_icon create mode 100644 src/hyper/htadd.c delete mode 100644 src/hyper/htadd.pamphlet create mode 100644 src/hyper/hterror.c create mode 100644 src/hyper/hterror.h delete mode 100644 src/hyper/hterror.pamphlet create mode 100644 src/hyper/hthits.c delete mode 100644 src/hyper/hthits.pamphlet create mode 100644 src/hyper/htinp.c delete mode 100644 src/hyper/htinp.pamphlet create mode 100755 src/hyper/htsearch create mode 100644 src/hyper/hyper.c create mode 100644 src/hyper/hyper.h delete mode 100644 src/hyper/hyper.pamphlet create mode 100644 src/hyper/initx.c create mode 100644 src/hyper/initx.h delete mode 100644 src/hyper/initx.pamphlet create mode 100644 src/hyper/input.c delete mode 100644 src/hyper/input.pamphlet create mode 100644 src/hyper/item.c delete mode 100644 src/hyper/item.pamphlet create mode 100644 src/hyper/keyin.c create mode 100644 src/hyper/keyin.h delete mode 100644 src/hyper/keyin.pamphlet create mode 100644 src/hyper/lex.c create mode 100644 src/hyper/lex.h delete mode 100644 src/hyper/lex.pamphlet create mode 100644 src/hyper/macro.c delete mode 100644 src/hyper/macro.pamphlet create mode 100644 src/hyper/mem.c delete mode 100644 src/hyper/mem.pamphlet create mode 100644 src/hyper/mouse11.bitmap create mode 100644 src/hyper/mouse11.mask create mode 100644 src/hyper/parse-aux.c delete mode 100644 src/hyper/parse-aux.pamphlet create mode 100644 src/hyper/parse-input.c delete mode 100644 src/hyper/parse-input.pamphlet create mode 100644 src/hyper/parse-paste.c create mode 100644 src/hyper/parse-paste.h delete mode 100644 src/hyper/parse-paste.pamphlet create mode 100644 src/hyper/parse-types.c create mode 100644 src/hyper/parse-types.h delete mode 100644 src/hyper/parse-types.pamphlet create mode 100644 src/hyper/parse.c create mode 100644 src/hyper/parse.h delete mode 100644 src/hyper/parse.pamphlet create mode 100755 src/hyper/presea create mode 100644 src/hyper/scrollbar.c create mode 100644 src/hyper/scrollbar.h delete mode 100644 src/hyper/scrollbar.pamphlet create mode 100644 src/hyper/sdown.bitmap create mode 100644 src/hyper/sdown3d.bitmap create mode 100644 src/hyper/sdown3dpr.bitmap delete mode 100644 src/hyper/search.pamphlet create mode 100644 src/hyper/show-types.c delete mode 100644 src/hyper/show-types.pamphlet create mode 100644 src/hyper/spadbuf.c delete mode 100644 src/hyper/spadbuf.pamphlet create mode 100644 src/hyper/spadint.c delete mode 100644 src/hyper/spadint.pamphlet create mode 100644 src/hyper/sup.bitmap create mode 100644 src/hyper/sup3d.bitmap create mode 100644 src/hyper/sup3dpr.bitmap create mode 100644 src/hyper/titlebar.c create mode 100644 src/hyper/titlebar.h delete mode 100644 src/hyper/titlebar.pamphlet create mode 100644 src/hyper/token.h delete mode 100644 src/hyper/token.pamphlet diff --git a/configure b/configure index 201412d4..547c9326 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.60 for OpenAxiom 1.2.0-2008-03-05. +# Generated by GNU Autoconf 2.60 for OpenAxiom 1.2.0-2008-03-07. # # Report bugs to . # @@ -713,8 +713,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='OpenAxiom' PACKAGE_TARNAME='openaxiom' -PACKAGE_VERSION='1.2.0-2008-03-05' -PACKAGE_STRING='OpenAxiom 1.2.0-2008-03-05' +PACKAGE_VERSION='1.2.0-2008-03-07' +PACKAGE_STRING='OpenAxiom 1.2.0-2008-03-07' PACKAGE_BUGREPORT='open-axiom-bugs@lists.sf.net' ac_unique_file="src/Makefile.pamphlet" @@ -1387,7 +1387,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures OpenAxiom 1.2.0-2008-03-05 to adapt to many kinds of systems. +\`configure' configures OpenAxiom 1.2.0-2008-03-07 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1457,7 +1457,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of OpenAxiom 1.2.0-2008-03-05:";; + short | recursive ) echo "Configuration of OpenAxiom 1.2.0-2008-03-07:";; esac cat <<\_ACEOF @@ -1561,7 +1561,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -OpenAxiom configure 1.2.0-2008-03-05 +OpenAxiom configure 1.2.0-2008-03-07 generated by GNU Autoconf 2.60 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -1575,7 +1575,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by OpenAxiom $as_me 1.2.0-2008-03-05, which was +It was created by OpenAxiom $as_me 1.2.0-2008-03-07, which was generated by GNU Autoconf 2.60. Invocation command line was $ $0 $@ @@ -25230,7 +25230,7 @@ exec 6>&1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by OpenAxiom $as_me 1.2.0-2008-03-05, which was +This file was extended by OpenAxiom $as_me 1.2.0-2008-03-07, which was generated by GNU Autoconf 2.60. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -25279,7 +25279,7 @@ Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -OpenAxiom config.status 1.2.0-2008-03-05 +OpenAxiom config.status 1.2.0-2008-03-07 configured by $0, generated by GNU Autoconf 2.60, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" diff --git a/configure.ac b/configure.ac index c8e9c466..93d6b310 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ sinclude(config/open-axiom.m4) sinclude(config/aclocal.m4) -AC_INIT([OpenAxiom], [1.2.0-2008-03-05], +AC_INIT([OpenAxiom], [1.2.0-2008-03-07], [open-axiom-bugs@lists.sf.net]) AC_CONFIG_AUX_DIR(config) diff --git a/configure.ac.pamphlet b/configure.ac.pamphlet index f89a52ff..e85bfff8 100644 --- a/configure.ac.pamphlet +++ b/configure.ac.pamphlet @@ -1022,7 +1022,7 @@ information: <>= sinclude(config/open-axiom.m4) sinclude(config/aclocal.m4) -AC_INIT([OpenAxiom], [1.2.0-2008-03-05], +AC_INIT([OpenAxiom], [1.2.0-2008-03-07], [open-axiom-bugs@lists.sf.net]) @ diff --git a/src/ChangeLog b/src/ChangeLog index 6daa63eb..901055a9 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2008-03-07 Gabriel Dos Reis + + * hyper/: De-pamphletize. + 2008-03-05 Gabriel Dos Reis * interp/compiler.boot (compColon): Literal flag types are valid diff --git a/src/hyper/Makefile.in b/src/hyper/Makefile.in index 02cef2e8..f3896a99 100644 --- a/src/hyper/Makefile.in +++ b/src/hyper/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2007, Gabriel Dos Reis. +# Copyright (C) 2007-2008, Gabriel Dos Reis. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -53,15 +53,15 @@ SCRIPTS=${OUTLIB}/htsearch ${OUTLIB}/presea BINFILES= $(addprefix $(OUTLIB)/,$(bin_PROGRAMS)) -HEADERS = addfile.h cond.h dialog.h display.h event.h extent.h \ - group.h hterror.h hyper.h initx.h keyin.h lex.h mem.h \ - parse.h parse-aux.h parse-paste.h parse-types.h scrollbar.h \ - show-types.h titlebar.h token.h $(axiom_c_macros_h) +HEADERS = addfile.h display.h event.h extent.h \ + group.h hterror.h hyper.h initx.h keyin.h lex.h \ + parse.h parse-paste.h parse-types.h scrollbar.h \ + titlebar.h token.h $(axiom_c_macros_h) build_libdir = $(abs_top_builddir)/src/lib -hypertex_sources = addfile.c cond.c dialog.c display.c event.c extent1.c \ +hypertex_SOURCES = addfile.c cond.c dialog.c display.c event.c extent1.c \ extent2.c form-ext.c group.c halloc.c hash.c hterror.c \ htinp.c hyper.c initx.c input.c item.c keyin.c lex.c \ macro.c mem.c parse.c parse-aux.c parse-input.c \ @@ -70,41 +70,30 @@ hypertex_sources = addfile.c cond.c dialog.c display.c event.c extent1.c \ libspad_la = $(axiom_target_libdir)/libspad.la -hypertex_SOURCES = $(hypertex_sources:.c=.pamphlet) -hypertex_objects = $(hypertex_sources:.c=.lo) +hypertex_objects = $(hypertex_SOURCES:.c=.lo) hypertex_LDADD = $(libspad_la) hypertex_DEPENDENCIES = -htadd_sources = addfile.c halloc.c hash.c htadd.c hterror.c lex.c -htadd_SOURCES = $(htadd_sources:.c=.pamphlet) -htadd_objects = $(htadd_sources:.c=.lo) +htadd_SOURCES = addfile.c halloc.c hash.c htadd.c hterror.c lex.c +htadd_objects = $(htadd_SOURCES:.c=.lo) htadd_LDADD = $(libspad_la) htadd_DEPENDENCIES = -htsearch_SOURCES = search.pamphlet - -spadbuf_sources = spadbuf.c -spadbuf_SOURCES = $(spadbuf_sources:.c=.pamphlet) -spadbuf_objects = $(spadbuf_sources:.c=.lo) +spadbuf_SOURCES = spadbuf.c +spadbuf_objects = $(spadbuf_SOURCES:.c=.lo) spadbuf_LDADD = $(libspad_la) spadbuf_DEPENDENCIES = -hthits_sources = hthits.c -hthits_SOURCES = $(hthits_sources:.c=.pamphlet) -hthits_objects = $(hthits_sources:.c=.lo) +hthits_SOURCES = hthits.c +hthits_objects = $(hthits_SOURCES:.c=.lo) hthits_LDADD = $(libspad_la) hthits_DEPENDENCIES = -ex2ht_sources = ex2ht.c -ex2ht_SOURCES = $(ex2ht_sources:.c=.pamphlet) -ex2ht_objects = $(ex2ht_sources:.c=.lo) +ex2ht_SOURCES = ex2ht.c +ex2ht_objects = $(ex2ht_SOURCES:.c=.lo) ex2ht_LDADD = $(libspad_la) ex2ht_DEPENDENCIES = -pamphlets = Makefile.pamphlet $(hypertex_SOURCES) $(htadd_SOURCES) \ - $(htsearch_SOURCES) $(spadbuf_SOURCES) $(hthits_SOURCES) \ - $(ex2ht_SOURCES) - subdir = src/hyper/ .PHONY: all all-hyper @@ -124,58 +113,15 @@ mostclean-local: clean-local: mostclean-local -rm -f $(objects) - -rm -f $(hypertex_sources) - -rm -f $(htadd_sources) - -rm -f $(htsearch_sources) - -rm -f $(spadbuf_sources) - -rm -f $(hthits_sources) - -rm -f $(ex2ht_sources) -rm -f $(BINFILES) distclean-local: clean-local -.PRECIOUS: %.h - -$(HEADERS): %.h: $(srcdir)/%.pamphlet - $(axiom_build_document) --tangle=$*.h --output=$@ $< - .PRECIOUS: %.lo %.$(OBJEXT) -.PRECIOUS: %.c %.lo: %.c $(HEADERS) $(COMPILE) -o $@ $(CFLAGS) ${CCF} $(axiom_includes) $(AXIOM_X11_CFLAGS) -I. $< -%.c: $(srcdir)/%.pamphlet - $(axiom_build_document) --tangle --output=$@ $< - - -mouse11.bitmap: $(srcdir)/bitmaps.pamphlet - $(axiom_build_document) --tangle=mouse11.bitmap --output=$@ $< - -mouse11.mask: $(srcdir)/bitmaps.pamphlet - $(axiom_build_document) --tangle=mouse11.mask --output=$@ $< - -sdown3d.bitmap: $(srcdir)/bitmaps.pamphlet - $(axiom_build_document) --tangle=sdown3d.bitmap --output=$@ $< - -sdown3dpr.bitmap: $(srcdir)/bitmaps.pamphlet - $(axiom_build_document) --tangle=sdown3dpr.bitmap --output=$@ $< - -sdown.bitmap: $(srcdir)/bitmaps.pamphlet - $(axiom_build_document) --tangle=sdown.bitmap --output=$@ $< - -sup3d.bitmap: $(srcdir)/bitmaps.pamphlet - $(axiom_build_document) --tangle=sup3d.bitmap --output=$@ $< - -sup3dpr.bitmap: $(srcdir)/bitmaps.pamphlet - $(axiom_build_document) --tangle=sup3dpr.bitmap --output=$@ $< - -sup.bitmap: $(srcdir)/bitmaps.pamphlet - $(axiom_build_document) --tangle=sup.bitmap --output=$@ $< - -ht_icon: $(srcdir)/bitmaps.pamphlet - $(axiom_build_document) --tangle=hticon --output=$@ $< - ${HYPER}/pages/ht.db: $(HTADD) $(srcdir)/pages/*.ht $(srcdir)/pages/*.pht @echo making ${HYPER}/pages from $(axiom_src_srcdir)/pages directory @ mkdir -p ${HYPER}/pages @@ -191,13 +137,11 @@ ${HYPER}/pages/ht.db: $(HTADD) $(srcdir)/pages/*.ht $(srcdir)/pages/*.pht @ cp -pr $(srcdir)/viewports $(axiom_target_datadir) -${OUTLIB}/htsearch: $(srcdir)/search.pamphlet - $(axiom_build_document) --tangle=htsearch --output=$@ $< - chmod a+x ${OUTLIB}/htsearch +${OUTLIB}/htsearch: htsearch + $(INSTALL_PROGRAM) $< $@ -${OUTLIB}/presea: $(srcdir)/search.pamphlet - $(axiom_build_document) --tangle=presea --output=$@ $< - chmod a+x ${OUTLIB}/presea +${OUTLIB}/presea: presea + $(INSTALL_PROGRAM) $< $@ ${OUTLIB}/ex2ht$(EXEEXT): $(ex2ht_objects) $(ex2ht_DEPENDENCIES) ${LINK} -o $@ $(ex2ht_objects) $(ex2ht_LDADD) $(AXIOM_X11_LDFLAGS) -lm diff --git a/src/hyper/ReadBitmap.c b/src/hyper/ReadBitmap.c new file mode 100644 index 00000000..7eb09303 --- /dev/null +++ b/src/hyper/ReadBitmap.c @@ -0,0 +1,259 @@ +/* +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. +*/ + +#define _READBITMAP_C + +#include "axiom-c-macros.h" +#include "useproto.h" +#include "debug.h" +#include "hyper.h" + +#include "all_hyper_proto.H1" +#include "pixmap.H1" + +#define MAXLINE 256 + +/* + * This file was produced by J.M. Wiley with some help from the bitmap editor + * routine. It reads in a bitmap file, and calls XCreatePixmapFromBitmapData + * to transform it into a Pixmap. He did this because the routine + * XReadBitmapFile does not seeem to work to well (whatecer that means). + */ + +XImage * +HTReadBitmapFile(Display *display,int screen,char * filename, + int *width, int *height) +{ + XImage *image; + FILE *fd; + char Line[256], Buff[256]; + int num_chars; + char *ptr; + int rch; + int version; + int padding, chars_line, file_chars_line, file_chars; + int bytes; + int x_hot, y_hot; + + + image = XCreateImage(display, DefaultVisual(display, screen), 1, + XYBitmap, 0, NULL, 0, 0, 8, 0); + + + (image)->byte_order = LSBFirst; /* byte_order */ + (image)->bitmap_unit = 8; /* bitmap-unit */ + (image)->bitmap_bit_order = LSBFirst; /* bitmap-bit-order */ + + if (!(fd = zzopen(filename, "r"))) { + fprintf(stderr, "ReadBitmapFile: File >%s< not found\n", filename); + exit(-1); + } + + /* + * Once it is open, lets get the width and height + */ + + if ((read_w_and_h(fd, (unsigned int *)width,(unsigned int *) height)) < 0) { + fprintf(stderr, "ReadBitmapFile: Bad file format in %s\n", filename); + exit(-1); + } + + + /* + * Now get the next line, and see if it is hot spots or bits + */ + if (fgets(Line, MAXLINE, fd) == NULL) { + fprintf(stderr, "ReadBitmapFile: Bad file format in %s\n", filename); + exit(-1); + } + + /* + * Now check the first character to see if it is a # or an s + */ + + if (Line[0] == '#') { + if ((read_hot(fd, Line, &x_hot, &y_hot)) < 0) { + fprintf(stderr, "ReadBitmapFile: Bad file format in %s\n", filename); + exit(-1); + } + } + + (image)->width = *width; + (image)->height = *height; + + /* + * figure out what version + */ + + if (sscanf(Line, "static short %s = {", Buff) == 1) + version = 10; + else if (sscanf(Line, "static unsigned char %s = {", Buff) == 1) + version = 11; + else if (sscanf(Line, "static char %s = {", Buff) == 1) + version = 11; + else { + fprintf(stderr, "ReadBitmapFile: Bad file format in %s\n", filename); + exit(-1); + } + + padding = 0; + if ((*width % 16) && ((*width % 16) < 9) && (version == 10)) + padding = 1; + + (image)->bytes_per_line = chars_line = (*width + 7) / 8; + file_chars_line = chars_line + padding; + + num_chars = chars_line * (*height); + file_chars = file_chars_line * (*height); + (image)->data = (char *) halloc((image)->bytes_per_line * (image)->height, + "Read Pixmap--Image data"); + + /* + * Since we are just holding the first line of the declaration, we can + * just start reading from fd + */ + + if (version == 10) + for (bytes = 0, ptr = (image)->data; bytes < file_chars; (bytes += 2)) { + if (fscanf(fd, " 0x%x%*[,}]%*[ \n]", &rch) != 1) { + fprintf(stderr, "ReadBitmapFile: Bad file format in %s\n", filename); + exit(-1); + } + *(ptr++) = rch & 0xff; + if (!padding || ((bytes + 2) % file_chars_line)) + *(ptr++) = rch >> 8; + } + else + for (bytes = 0, ptr = (image)->data; bytes < file_chars; bytes++, ptr++) { + if (fscanf(fd, " 0x%x%*[,}]%*[ \n]", &rch) != 1) { + fprintf(stderr, "ReadBitmapFile: Bad file format in %s\n", filename); + exit(-1); + } + *ptr = rch; + } + + fclose(fd); + + return image; +} + +static int +read_hot(FILE *fd,char Line[],int *x_hot,int *y_hot) +{ + char Buff[256]; + + /* + * Works much the same as get width and height, just new variables + */ + + if (sscanf(Line, "#define %s %d", Buff, x_hot) != 2) + return -1; + + if (fgets(Line, MAXLINE, fd) == NULL) + return -1; + + if (sscanf(Line, "#define %s %d", Buff, y_hot) != 2) + return -1; + + if (fgets(Line, MAXLINE, fd) == NULL) + return -1; + return 1; +} + +static int +read_w_and_h(FILE *fd,unsigned int *width,unsigned int *height) +{ + char Line[256], Buff[256]; + + if (fgets(Line, MAXLINE, fd) == NULL) + return -1; + + /* + * Once we have the line, scan it for the width + */ + + if (sscanf(Line, "#define %s %d", Buff, width) != 2) + return -1; + + /* + * Hopefully we have the width, now get the height the same way + */ + + if (fgets(Line, MAXLINE, fd) == NULL) + return -1; + + + /* + * Once we have the line, scan it for the height + */ + + if (sscanf(Line, "#define %s %d", Buff, height) != 2) + return -1; + + return 1; +} + + +/* read a bitmap file into memory */ + +ImageStruct * +insert_image_struct(char *filename) +{ + int bm_width, bm_height; + XImage *im; + ImageStruct *image; + + if (*filename == ' ') + filename++; + if ((image = (ImageStruct *) hash_find(&gImageHashTable, filename)) == NULL) { + im = HTReadBitmapFile(gXDisplay, gXScreenNumber, filename, + &bm_width, &bm_height); + + /* + * now add the image to the gImageHashTable + */ + + image = (ImageStruct *) halloc(sizeof(ImageStruct), "ImageStruct"); + image->image.xi = im; + image->width = image->image.xi->width; + image->height = image->image.xi->height; + image->filename = (char *) halloc(sizeof(char) * strlen(filename) +1, + "insert_image--filename"); + + /* strcpy(image->filename, filename); */ + + sprintf(image->filename, "%s", filename); + hash_insert(&gImageHashTable,(char *) image, image->filename); + } + return image; +} diff --git a/src/hyper/ReadBitmap.pamphlet b/src/hyper/ReadBitmap.pamphlet deleted file mode 100644 index 9712f0e6..00000000 --- a/src/hyper/ReadBitmap.pamphlet +++ /dev/null @@ -1,296 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/ReadBitmap} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{ReadBitmap.c} -\subsection{zzopen change} -The [[zzopen]] function used to be called [[zopen]] but this name has -been picked up by Unix so we change it globally. -<>= - if (!(fd = zzopen(filename, "r"))) { - fprintf(stderr, "ReadBitmapFile: File >%s< not found\n", filename); - exit(-1); - } - -@ -\subsection{ReadBitmap.c} -<>= -#define _READBITMAP_C - -#include "axiom-c-macros.h" -#include "useproto.h" -#include "debug.h" -#include "hyper.h" - -#include "all_hyper_proto.H1" -#include "pixmap.H1" - -#define MAXLINE 256 - -/* - * This file was produced by J.M. Wiley with some help from the bitmap editor - * routine. It reads in a bitmap file, and calls XCreatePixmapFromBitmapData - * to transform it into a Pixmap. He did this because the routine - * XReadBitmapFile does not seeem to work to well (whatecer that means). - */ - -XImage * -HTReadBitmapFile(Display *display,int screen,char * filename, - int *width, int *height) -{ - XImage *image; - FILE *fd; - char Line[256], Buff[256]; - int num_chars; - char *ptr; - int rch; - int version; - int padding, chars_line, file_chars_line, file_chars; - int bytes; - int x_hot, y_hot; - - - image = XCreateImage(display, DefaultVisual(display, screen), 1, - XYBitmap, 0, NULL, 0, 0, 8, 0); - - - (image)->byte_order = LSBFirst; /* byte_order */ - (image)->bitmap_unit = 8; /* bitmap-unit */ - (image)->bitmap_bit_order = LSBFirst; /* bitmap-bit-order */ - -<> - /* - * Once it is open, lets get the width and height - */ - - if ((read_w_and_h(fd, (unsigned int *)width,(unsigned int *) height)) < 0) { - fprintf(stderr, "ReadBitmapFile: Bad file format in %s\n", filename); - exit(-1); - } - - - /* - * Now get the next line, and see if it is hot spots or bits - */ - if (fgets(Line, MAXLINE, fd) == NULL) { - fprintf(stderr, "ReadBitmapFile: Bad file format in %s\n", filename); - exit(-1); - } - - /* - * Now check the first character to see if it is a # or an s - */ - - if (Line[0] == '#') { - if ((read_hot(fd, Line, &x_hot, &y_hot)) < 0) { - fprintf(stderr, "ReadBitmapFile: Bad file format in %s\n", filename); - exit(-1); - } - } - - (image)->width = *width; - (image)->height = *height; - - /* - * figure out what version - */ - - if (sscanf(Line, "static short %s = {", Buff) == 1) - version = 10; - else if (sscanf(Line, "static unsigned char %s = {", Buff) == 1) - version = 11; - else if (sscanf(Line, "static char %s = {", Buff) == 1) - version = 11; - else { - fprintf(stderr, "ReadBitmapFile: Bad file format in %s\n", filename); - exit(-1); - } - - padding = 0; - if ((*width % 16) && ((*width % 16) < 9) && (version == 10)) - padding = 1; - - (image)->bytes_per_line = chars_line = (*width + 7) / 8; - file_chars_line = chars_line + padding; - - num_chars = chars_line * (*height); - file_chars = file_chars_line * (*height); - (image)->data = (char *) halloc((image)->bytes_per_line * (image)->height, - "Read Pixmap--Image data"); - - /* - * Since we are just holding the first line of the declaration, we can - * just start reading from fd - */ - - if (version == 10) - for (bytes = 0, ptr = (image)->data; bytes < file_chars; (bytes += 2)) { - if (fscanf(fd, " 0x%x%*[,}]%*[ \n]", &rch) != 1) { - fprintf(stderr, "ReadBitmapFile: Bad file format in %s\n", filename); - exit(-1); - } - *(ptr++) = rch & 0xff; - if (!padding || ((bytes + 2) % file_chars_line)) - *(ptr++) = rch >> 8; - } - else - for (bytes = 0, ptr = (image)->data; bytes < file_chars; bytes++, ptr++) { - if (fscanf(fd, " 0x%x%*[,}]%*[ \n]", &rch) != 1) { - fprintf(stderr, "ReadBitmapFile: Bad file format in %s\n", filename); - exit(-1); - } - *ptr = rch; - } - - fclose(fd); - - return image; -} - -static int -read_hot(FILE *fd,char Line[],int *x_hot,int *y_hot) -{ - char Buff[256]; - - /* - * Works much the same as get width and height, just new variables - */ - - if (sscanf(Line, "#define %s %d", Buff, x_hot) != 2) - return -1; - - if (fgets(Line, MAXLINE, fd) == NULL) - return -1; - - if (sscanf(Line, "#define %s %d", Buff, y_hot) != 2) - return -1; - - if (fgets(Line, MAXLINE, fd) == NULL) - return -1; - return 1; -} - -static int -read_w_and_h(FILE *fd,unsigned int *width,unsigned int *height) -{ - char Line[256], Buff[256]; - - if (fgets(Line, MAXLINE, fd) == NULL) - return -1; - - /* - * Once we have the line, scan it for the width - */ - - if (sscanf(Line, "#define %s %d", Buff, width) != 2) - return -1; - - /* - * Hopefully we have the width, now get the height the same way - */ - - if (fgets(Line, MAXLINE, fd) == NULL) - return -1; - - - /* - * Once we have the line, scan it for the height - */ - - if (sscanf(Line, "#define %s %d", Buff, height) != 2) - return -1; - - return 1; -} - - -/* read a bitmap file into memory */ - -ImageStruct * -insert_image_struct(char *filename) -{ - int bm_width, bm_height; - XImage *im; - ImageStruct *image; - - if (*filename == ' ') - filename++; - if ((image = (ImageStruct *) hash_find(&gImageHashTable, filename)) == NULL) { - im = HTReadBitmapFile(gXDisplay, gXScreenNumber, filename, - &bm_width, &bm_height); - - /* - * now add the image to the gImageHashTable - */ - - image = (ImageStruct *) halloc(sizeof(ImageStruct), "ImageStruct"); - image->image.xi = im; - image->width = image->image.xi->width; - image->height = image->image.xi->height; - image->filename = (char *) halloc(sizeof(char) * strlen(filename) +1, - "insert_image--filename"); - - /* strcpy(image->filename, filename); */ - - sprintf(image->filename, "%s", filename); - hash_insert(&gImageHashTable,(char *) image, image->filename); - } - return image; -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/addfile.c b/src/hyper/addfile.c new file mode 100644 index 00000000..c7df3f1a --- /dev/null +++ b/src/hyper/addfile.c @@ -0,0 +1,309 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +#define _ADDFILE_C +#include "useproto.h" +#include "debug.h" + +#include "hyper.h" +#include "addfile.h" + +#include +#include + +#include "all_hyper_proto.H1" + + +char *gDatabasePath = NULL; + +static int +strpostfix(char *s, char *t) +{ + int slen = strlen(s), tlen = strlen(t); + + if (tlen > slen) + return 0; + while (tlen > 0) + if (s[--slen] != t[--tlen]) + return 0; + return 1; +} + +/* extend_ht : just checks the name and adds a .ht if needed */ + +void +extend_ht(char *name) +{ + + if (!strpostfix(name, ".ht") && !strpostfix(name, ".pht")) + strcat(name, ".ht"); + return; +} + +#define cwd(n) ((n[0] == '.' && n[1] == '/')?(1):(0)) + +/* + * This procedure is sent a filename, and from it tries to build the full + * filename, this it returns in the fullname variable. If the file is not + * found, then it returns a -1. The fname is the fullpath name for the file, + * including the .ht extension. The aname is the filename minus the added .ht + * extension, and the pathname. + */ + +static int +build_ht_filename(char *fname, char *aname, char *name) +{ + char cdir[256]; + char *c_dir; + char *HTPATH; + char *trace; + char *trace2; + int ht_file; + + if (cwd(name)) { + /* user wants to use the current working directory */ + c_dir = (char *) getcwd(cdir, 254); + strcpy(fname, c_dir); + + /* Now add the rest of the filename */ + strcat(fname, "/"); + strcat(fname, &name[2]); + + /** now copy the actual file name to addname **/ + for (trace = &name[strlen(name)]; trace != name && + (*trace != '/'); trace--); + if (trace == name) { + fprintf(stderr, "ht_open_file: Didn't expect a filename like %s\n", + name); + exit(-1); + } + trace++; + strcpy(aname, trace); + + /** add the .ht extension if needed **/ + extend_ht(aname); + extend_ht(fname); + + /* Now just try to access the file */ + return (access(fname, R_OK)); + } + else if (pathname(name)) { + /* filename already has the path specified */ + strcpy(fname, name); + + /** now copy the actual file name to addname **/ + for (trace = &name[strlen(name)]; trace != name && + (*trace != '/'); trace--); + if (trace == name) { + fprintf(stderr, "ht_open_file: Didn't expect a filename like %s\n", + name); + exit(-1); + } + trace++; + strcpy(aname, trace); + + /** add the .ht extension if needed **/ + extend_ht(aname); + extend_ht(fname); + + /* Now just try to access the file */ + return (access(fname, R_OK)); + } + else {/** If not I am going to have to append path names to it **/ + HTPATH = (char *) getenv("HTPATH"); + if (HTPATH == NULL) { + /** The user does not have a HTPATH, so I will use the the directory + $AXIOM/share/hypertex/pages/ as the default path ***/ + char *spad = (char *) getenv("AXIOM"); + if (spad == NULL) { + fprintf(stderr, + "ht_file_open:Cannot find ht data base: setenv HTPATH or AXIOM\n"); + exit(-1); + } + HTPATH = (char *) halloc(1024 * sizeof(char), "HTPATH"); + strcpy(HTPATH, spad); + strcat(HTPATH, "/share/hypertex/pages"); + } + + /** Now that I have filled HTPATH, I should try to open a file by the + given name **/ + strcpy(aname, name); + extend_ht(aname); + for (ht_file = -1, trace2 = HTPATH; + ht_file == -1 && *trace2 != '\0';) { + for (trace = fname; *trace2 != '\0' && (*trace2 != ':');) + *trace++ = *trace2++; + *trace++ = '/'; + *trace = 0; + if (!strcmp(fname, "./")) { + /** The person wishes me to check the current directory too **/ + getcwd(fname, 256); + strcat(fname, "/"); + } + if (*trace2) + trace2++; + strcat(fname, aname); + ht_file = access(fname, R_OK); + } + return (ht_file); + } +} + +static int +pathname(char *name) +{ + while (*name) + if (*name++ == '/') + return 1; + + return 0; +} + +/** This procedure opens the proper HT file **/ + +FILE * +ht_file_open(char *fname, char *aname, char *name) +{ + FILE *ht_fp; + int ret_value; + + ret_value = build_ht_filename(fname, aname, name); + if (ret_value == -1) { + fprintf(stderr, "ht_file_open: Unknown file %s\n", fname); + exit(-1); + } + + ht_fp = fopen(fname, "r"); + if (ht_fp == NULL) { + perror("ht_file_open"); + exit(-1); + } + return (ht_fp); +} + +/* + * This function is responsible for actually opening the database file. For the + * moment it gets the $AXIOM environment variable, and appends to it + * "share/hypertex/ht.db", and then opens it + */ + +/* + * Modified on 12/3/89 to take a second argument. This argument tells the + * open routine whether it is reading the db file, or writing it. If writing + * is true, then I should check to insure I have proper write access. + * -JMW + */ + +/* + * Modified again on 12/9/89 so that it now uses HTPATH as the path name. Now + * it initially loads up the path name into a static variable. Then upon + * every trip, it gets the next ht.db found. It returns NULL when no ht.db is + * found. -JMW + */ + + +FILE * +db_file_open(char *db_file) +{ + static char *db_path_trace = NULL; + char *db_file_trace; + FILE *db_fp; + char *spad; + + /* + * The first time through is the only time this could be true. If so, then + * create the default HTPATH for gDatabasePath. + */ +/* fprintf(stderr,"addfile:db_file_open: entered db_file=%s\n",db_file);*/ + if (gDatabasePath == NULL) { + gDatabasePath = (char *) getenv("HTPATH"); + if (gDatabasePath == NULL) { + spad = (char *) getenv("AXIOM"); + if (spad == NULL) { +/* fprintf(stderr, + "addfile:db_file_open: Cannot find ht data base path:\n");*/ + exit(-1); + } + gDatabasePath = (char *) halloc(sizeof(char) * 1024, "db_file_open"); + strcpy(gDatabasePath, spad); + strcat(gDatabasePath, "/share/hypertex/pages"); + } + db_path_trace = gDatabasePath; + } +/*fprintf(stderr,"addfile:db_file_open: db_path_trace=%s\n",db_path_trace);*/ + /* + * Now Loop until I find one with okay filename + */ + + for (db_fp = NULL; db_fp == NULL && *db_path_trace != '\0';) { + for (db_file_trace = db_file; *db_path_trace != ':' && + *db_path_trace != '\0'; db_path_trace++) + *db_file_trace++ = *db_path_trace; + *db_file_trace = '\0'; + strcat(db_file_trace, "/ht.db"); +/*fprintf(stderr,"addfile:db_file_open: db_file_trace=%s\n",db_file_trace);*/ +/*fprintf(stderr,"addfile:db_file_open: db_file=%s\n",db_file);*/ + + db_fp = fopen(db_file, "r"); + + if (*db_path_trace != '\0') + db_path_trace++; + } +/* if (db_fp == NULL) + fprintf(stderr,"addfile:db_file_open: exit (null)\n"); + else + fprintf(stderr,"addfile:db_file_open: exit opened\n"); +*/ + return (db_fp); +} + + +FILE * +temp_file_open(char *temp_db_file) +{ + FILE *temp_db_fp; + + /** Just make the name and open it **/ + + strcpy(temp_db_file, temp_dir); + strcat(temp_db_file, "ht2.db" /* db_file_name */ ); + temp_db_fp = fopen(temp_db_file, "w"); + + if (temp_db_fp == NULL) { + perror("temp_file_open"); + exit(-1); + } + return temp_db_fp; +} diff --git a/src/hyper/addfile.h b/src/hyper/addfile.h new file mode 100644 index 00000000..fd6a14e0 --- /dev/null +++ b/src/hyper/addfile.h @@ -0,0 +1,41 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +#ifndef _ADDFILE_H_ +#define _ADDFILE_H_ 1 + +extern char *gDatabasePath; + +#endif diff --git a/src/hyper/addfile.pamphlet b/src/hyper/addfile.pamphlet deleted file mode 100644 index 4a1e15ae..00000000 --- a/src/hyper/addfile.pamphlet +++ /dev/null @@ -1,347 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/addfile} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{addfile.h} -<>= -<> -#ifndef _ADDFILE_H_ -#define _ADDFILE_H_ 1 - -extern char *gDatabasePath; - -#endif -@ -\section{addfile.c} -<>= -#define _ADDFILE_C -#include "useproto.h" -#include "debug.h" - -#include "hyper.h" -#include "addfile.h" - -#include -#include - -#include "all_hyper_proto.H1" - - -char *gDatabasePath = NULL; - -static int -strpostfix(char *s, char *t) -{ - int slen = strlen(s), tlen = strlen(t); - - if (tlen > slen) - return 0; - while (tlen > 0) - if (s[--slen] != t[--tlen]) - return 0; - return 1; -} - -/* extend_ht : just checks the name and adds a .ht if needed */ - -void -extend_ht(char *name) -{ - - if (!strpostfix(name, ".ht") && !strpostfix(name, ".pht")) - strcat(name, ".ht"); - return; -} - -#define cwd(n) ((n[0] == '.' && n[1] == '/')?(1):(0)) - -/* - * This procedure is sent a filename, and from it tries to build the full - * filename, this it returns in the fullname variable. If the file is not - * found, then it returns a -1. The fname is the fullpath name for the file, - * including the .ht extension. The aname is the filename minus the added .ht - * extension, and the pathname. - */ - -static int -build_ht_filename(char *fname, char *aname, char *name) -{ - char cdir[256]; - char *c_dir; - char *HTPATH; - char *trace; - char *trace2; - int ht_file; - - if (cwd(name)) { - /* user wants to use the current working directory */ - c_dir = (char *) getcwd(cdir, 254); - strcpy(fname, c_dir); - - /* Now add the rest of the filename */ - strcat(fname, "/"); - strcat(fname, &name[2]); - - /** now copy the actual file name to addname **/ - for (trace = &name[strlen(name)]; trace != name && - (*trace != '/'); trace--); - if (trace == name) { - fprintf(stderr, "ht_open_file: Didn't expect a filename like %s\n", - name); - exit(-1); - } - trace++; - strcpy(aname, trace); - - /** add the .ht extension if needed **/ - extend_ht(aname); - extend_ht(fname); - - /* Now just try to access the file */ - return (access(fname, R_OK)); - } - else if (pathname(name)) { - /* filename already has the path specified */ - strcpy(fname, name); - - /** now copy the actual file name to addname **/ - for (trace = &name[strlen(name)]; trace != name && - (*trace != '/'); trace--); - if (trace == name) { - fprintf(stderr, "ht_open_file: Didn't expect a filename like %s\n", - name); - exit(-1); - } - trace++; - strcpy(aname, trace); - - /** add the .ht extension if needed **/ - extend_ht(aname); - extend_ht(fname); - - /* Now just try to access the file */ - return (access(fname, R_OK)); - } - else {/** If not I am going to have to append path names to it **/ - HTPATH = (char *) getenv("HTPATH"); - if (HTPATH == NULL) { - /** The user does not have a HTPATH, so I will use the the directory - $AXIOM/share/hypertex/pages/ as the default path ***/ - char *spad = (char *) getenv("AXIOM"); - if (spad == NULL) { - fprintf(stderr, - "ht_file_open:Cannot find ht data base: setenv HTPATH or AXIOM\n"); - exit(-1); - } - HTPATH = (char *) halloc(1024 * sizeof(char), "HTPATH"); - strcpy(HTPATH, spad); - strcat(HTPATH, "/share/hypertex/pages"); - } - - /** Now that I have filled HTPATH, I should try to open a file by the - given name **/ - strcpy(aname, name); - extend_ht(aname); - for (ht_file = -1, trace2 = HTPATH; - ht_file == -1 && *trace2 != '\0';) { - for (trace = fname; *trace2 != '\0' && (*trace2 != ':');) - *trace++ = *trace2++; - *trace++ = '/'; - *trace = 0; - if (!strcmp(fname, "./")) { - /** The person wishes me to check the current directory too **/ - getcwd(fname, 256); - strcat(fname, "/"); - } - if (*trace2) - trace2++; - strcat(fname, aname); - ht_file = access(fname, R_OK); - } - return (ht_file); - } -} - -static int -pathname(char *name) -{ - while (*name) - if (*name++ == '/') - return 1; - - return 0; -} - -/** This procedure opens the proper HT file **/ - -FILE * -ht_file_open(char *fname, char *aname, char *name) -{ - FILE *ht_fp; - int ret_value; - - ret_value = build_ht_filename(fname, aname, name); - if (ret_value == -1) { - fprintf(stderr, "ht_file_open: Unknown file %s\n", fname); - exit(-1); - } - - ht_fp = fopen(fname, "r"); - if (ht_fp == NULL) { - perror("ht_file_open"); - exit(-1); - } - return (ht_fp); -} - -/* - * This function is responsible for actually opening the database file. For the - * moment it gets the $AXIOM environment variable, and appends to it - * "share/hypertex/ht.db", and then opens it - */ - -/* - * Modified on 12/3/89 to take a second argument. This argument tells the - * open routine whether it is reading the db file, or writing it. If writing - * is true, then I should check to insure I have proper write access. - * -JMW - */ - -/* - * Modified again on 12/9/89 so that it now uses HTPATH as the path name. Now - * it initially loads up the path name into a static variable. Then upon - * every trip, it gets the next ht.db found. It returns NULL when no ht.db is - * found. -JMW - */ - - -FILE * -db_file_open(char *db_file) -{ - static char *db_path_trace = NULL; - char *db_file_trace; - FILE *db_fp; - char *spad; - - /* - * The first time through is the only time this could be true. If so, then - * create the default HTPATH for gDatabasePath. - */ -/* fprintf(stderr,"addfile:db_file_open: entered db_file=%s\n",db_file);*/ - if (gDatabasePath == NULL) { - gDatabasePath = (char *) getenv("HTPATH"); - if (gDatabasePath == NULL) { - spad = (char *) getenv("AXIOM"); - if (spad == NULL) { -/* fprintf(stderr, - "addfile:db_file_open: Cannot find ht data base path:\n");*/ - exit(-1); - } - gDatabasePath = (char *) halloc(sizeof(char) * 1024, "db_file_open"); - strcpy(gDatabasePath, spad); - strcat(gDatabasePath, "/share/hypertex/pages"); - } - db_path_trace = gDatabasePath; - } -/*fprintf(stderr,"addfile:db_file_open: db_path_trace=%s\n",db_path_trace);*/ - /* - * Now Loop until I find one with okay filename - */ - - for (db_fp = NULL; db_fp == NULL && *db_path_trace != '\0';) { - for (db_file_trace = db_file; *db_path_trace != ':' && - *db_path_trace != '\0'; db_path_trace++) - *db_file_trace++ = *db_path_trace; - *db_file_trace = '\0'; - strcat(db_file_trace, "/ht.db"); -/*fprintf(stderr,"addfile:db_file_open: db_file_trace=%s\n",db_file_trace);*/ -/*fprintf(stderr,"addfile:db_file_open: db_file=%s\n",db_file);*/ - - db_fp = fopen(db_file, "r"); - - if (*db_path_trace != '\0') - db_path_trace++; - } -/* if (db_fp == NULL) - fprintf(stderr,"addfile:db_file_open: exit (null)\n"); - else - fprintf(stderr,"addfile:db_file_open: exit opened\n"); -*/ - return (db_fp); -} - - -FILE * -temp_file_open(char *temp_db_file) -{ - FILE *temp_db_fp; - - /** Just make the name and open it **/ - - strcpy(temp_db_file, temp_dir); - strcat(temp_db_file, "ht2.db" /* db_file_name */ ); - temp_db_fp = fopen(temp_db_file, "w"); - - if (temp_db_fp == NULL) { - perror("temp_file_open"); - exit(-1); - } - return temp_db_fp; -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/bitmaps.pamphlet b/src/hyper/bitmaps.pamphlet deleted file mode 100644 index 7e0a1dfb..00000000 --- a/src/hyper/bitmaps.pamphlet +++ /dev/null @@ -1,143 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/bitmaps} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{bitmaps.h} -<>= -<> -@ -\section{ht\_icon} -<>= -#define ht_icon_width 40 -#define ht_icon_height 40 -#define ht_icon_x_hot -1 -#define ht_icon_y_hot -1 -static char ht_icon_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xf7, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, - 0x00, 0xe7, 0x00, 0x00, 0x00, 0x00, 0xe7, 0xef, 0x7b, 0x3c, 0xe7, 0xff, - 0xef, 0x7f, 0x7e, 0xff, 0xff, 0xe7, 0xef, 0xe7, 0xfe, 0xe7, 0x6e, 0xe7, - 0xe7, 0xde, 0xe7, 0x7e, 0xe7, 0xff, 0x0e, 0xe7, 0x3c, 0xe7, 0x07, 0x0e, - 0xe7, 0x3c, 0xf7, 0xcf, 0x0e, 0xf7, 0x18, 0x7f, 0xfe, 0x1f, 0x00, 0x1c, - 0x3f, 0x7c, 0x1f, 0x00, 0x0e, 0x07, 0x00, 0x00, 0x00, 0x0f, 0x07, 0x00, - 0x00, 0x00, 0x87, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x00, - 0x00, 0x77, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x00, 0x00, 0x00, 0x77, 0x3e, 0xdc, 0x00, 0x00, 0x77, 0x7f, 0xfe, - 0x00, 0x00, 0xf7, 0xe3, 0xef, 0x00, 0x00, 0xf7, 0xe3, 0xc7, 0x00, 0x00, - 0xf7, 0xe3, 0x07, 0x00, 0x00, 0xf7, 0xe3, 0x07, 0x00, 0x00, 0xf7, 0xe3, - 0xcf, 0x00, 0x80, 0x7f, 0x7f, 0xfe, 0x00, 0x80, 0x3f, 0x3e, 0x7c, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -@ -\section{mouse11.bitmap} -<>= -#define mouseBitmap_width 16 -#define mouseBitmap_height 16 -#define mouseBitmap_x_hot 8 -#define mouseBitmap_y_hot 0 -static char mouseBitmap_bits[] = { - 0x00, 0x01, 0x00, 0x01, 0x80, 0x02, 0x40, 0x04, 0xc0, 0x06, 0x20, 0x08, - 0x20, 0x08, 0x30, 0x18, 0x50, 0x14, 0x58, 0x34, 0x90, 0x12, 0x20, 0x08, - 0xc0, 0x47, 0x00, 0x21, 0x80, 0x10, 0x00, 0x0f}; -@ -\section{mouse11.mask} -<>= -#define mouseMask_width 16 -#define mouseMask_height 16 -static char mouseMask_bits[] = { - 0x00, 0x01, 0x00, 0x01, 0x80, 0x03, 0xc0, 0x07, 0xc0, 0x07, 0xe0, 0x0f, - 0xe0, 0x0f, 0xf0, 0x1f, 0xf0, 0x1f, 0xf8, 0x3f, 0xf0, 0x1f, 0xe0, 0x0f, - 0xc0, 0x47, 0x00, 0x21, 0x80, 0x10, 0x00, 0x0f}; -@ -\section{sdown3d.bitmap} -<>= -#define sdown3d_width 21 -#define sdown3d_height 21 -static char sdown3d_bits[] = { - 0xaa, 0xaa, 0x0a, 0x55, 0x55, 0x15, 0x02, 0x00, 0x0c, 0x51, 0x55, 0x15, - 0xaa, 0xaa, 0x0e, 0x51, 0x5f, 0x15, 0xaa, 0xae, 0x0e, 0x51, 0x5f, 0x15, - 0xaa, 0xae, 0x0e, 0x51, 0x5f, 0x15, 0xea, 0xff, 0x0e, 0xd1, 0x7f, 0x15, - 0xaa, 0xbf, 0x0e, 0x51, 0x5f, 0x15, 0xaa, 0xae, 0x0e, 0x51, 0x55, 0x15, - 0xaa, 0xaa, 0x0e, 0x51, 0x55, 0x15, 0xfe, 0xff, 0x0f, 0x55, 0x55, 0x15, - 0xaa, 0xaa, 0x0a}; -@ -\section{sdown3dpr.bitmap} -<>= -#define sdown3dpr_width 21 -#define sdown3dpr_height 21 -static char sdown3dpr_bits[] = { - 0xaa, 0xaa, 0x0a, 0x55, 0x55, 0x15, 0xfe, 0xff, 0x0f, 0x55, 0x55, 0x11, - 0xae, 0xaa, 0x0a, 0x55, 0x55, 0x11, 0xae, 0xbe, 0x0a, 0x55, 0x5d, 0x11, - 0xae, 0xbe, 0x0a, 0x55, 0x5d, 0x11, 0xae, 0xbe, 0x0a, 0xd5, 0xff, 0x11, - 0xae, 0xff, 0x0a, 0x55, 0x7f, 0x11, 0xae, 0xbe, 0x0a, 0x55, 0x5d, 0x11, - 0xae, 0xaa, 0x0a, 0x55, 0x55, 0x11, 0x06, 0x00, 0x08, 0x55, 0x55, 0x15, - 0xaa, 0xaa, 0x0a}; -@ -\section{sdown.bitmap} -<>= -#define sdown_width 21 -#define sdown_height 21 -static char sdown_bits[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0xf0, - 0x03, 0x00, 0xf8, 0x07, 0x00, 0xfc, 0x0f, 0x00, 0xfe, 0x1f, 0x00, 0xff, - 0x3f, 0x80, 0xff, 0x7f, 0xc0, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xf1, 0xff, - 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff}; -@ -\section{sup3d.bitmap} -<>= -#define sup3d_width 21 -#define sup3d_height 21 -static char sup3d_bits[] = { - 0xaa, 0xaa, 0x0a, 0x55, 0x55, 0x15, 0x02, 0x00, 0x0c, 0x51, 0x55, 0x15, - 0xaa, 0xaa, 0x0e, 0x51, 0x55, 0x15, 0xaa, 0xae, 0x0e, 0x51, 0x5f, 0x15, - 0xaa, 0xbf, 0x0e, 0xd1, 0x7f, 0x15, 0xea, 0xff, 0x0e, 0x51, 0x5f, 0x15, - 0xaa, 0xae, 0x0e, 0x51, 0x5f, 0x15, 0xaa, 0xae, 0x0e, 0x51, 0x5f, 0x15, - 0xaa, 0xaa, 0x0e, 0x51, 0x55, 0x15, 0xfa, 0xff, 0x0f, 0x55, 0x55, 0x15, - 0xaa, 0xaa, 0x0a}; -@ -\section{sup3dpr.bitmap} -<>= -#define sup3dpr_width 21 -#define sup3dpr_height 21 -static char sup3dpr_bits[] = { - 0xaa, 0xaa, 0x0a, 0x55, 0x55, 0x15, 0xfe, 0xff, 0x0f, 0x55, 0x55, 0x11, - 0xae, 0xaa, 0x0a, 0x55, 0x55, 0x11, 0xae, 0xaa, 0x0a, 0x55, 0x5d, 0x11, - 0xae, 0xbe, 0x0a, 0x55, 0x7f, 0x11, 0xae, 0xff, 0x0a, 0xd5, 0xff, 0x11, - 0xae, 0xbe, 0x0a, 0x55, 0x5d, 0x11, 0xae, 0xbe, 0x0a, 0x55, 0x5d, 0x11, - 0xae, 0xbe, 0x0a, 0x55, 0x55, 0x11, 0x06, 0x00, 0x08, 0x55, 0x55, 0x15, - 0xaa, 0xaa, 0x0a}; -@ -\section{sup.bitmap} -<>= -#define sup_width 21 -#define sup_height 21 -static char sup_bits[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xfb, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xe0, 0xff, 0x7f, 0xc0, 0xff, - 0x3f, 0x80, 0xff, 0x1f, 0x00, 0xff, 0x0f, 0x00, 0xfe, 0x07, 0x00, 0xfc, - 0x03, 0x00, 0xf8, 0x01, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff}; -@ -<<*>>= -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/cond.c b/src/hyper/cond.c new file mode 100644 index 00000000..c619d9e0 --- /dev/null +++ b/src/hyper/cond.c @@ -0,0 +1,150 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +/****************************************************************************** + * + * cond.c: Routines for handling "cond" nodes. + * + * Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993. + * + ****************************************************************************/ +#define _COND_C +#include "axiom-c-macros.h" +#include "useproto.h" +#include "debug.h" + +#include "hyper.h" + +#include "all_hyper_proto.H1" +#include "sockio-c.H1" + + +void +insert_cond(char *label, char *cond) +{ + CondNode *condnode = (CondNode *) hash_find(gWindow->fCondHashTable, label); + + /* + * This routine creates a new cond node and inserts it into the + * current cond table + */ + if (condnode) { + fprintf(stderr, "Error: \\%s is declared twice \n", label); + print_page_and_filename(); + jump(); + } + condnode = alloc_condnode(); + condnode->label = halloc(strlen(label) + 1, "Condnode->label"); + condnode->cond = halloc(strlen(cond) + 1, "Condnode->cond"); + strcpy(condnode->label, label); + strcpy(condnode->cond, cond); + hash_insert(gWindow->fCondHashTable, (char *) condnode, condnode->label); +} + +void +change_cond(char *label, char *newcond) +{ + CondNode *condnode = (CondNode *) hash_find(gWindow->fCondHashTable, label); + + if (condnode == NULL) { + fprintf(stderr, "Error: Tried to set an uncreated cond %s\n", label); + } + else { + free(condnode->cond); + condnode->cond = halloc(strlen(newcond) + 1, "Condnode->cond"); + strcpy(condnode->cond, newcond); + } +} + +static int +check_memostack(TextNode *node) +{ + char *buffer; + int stackp = gWindow->fMemoStackIndex; + int found = 0; + HyperDocPage *page; + + buffer = print_to_string(node->data.node); + + /* + * Once we have done that much, search down the stack for the + * proper page + */ + + while (!found && stackp > 0) { + page = gWindow->fMemoStack[--stackp]; + if (!strcmp(page->name, buffer)) + found = 1; + } + return found; +} + +int +check_condition(TextNode *node) +{ + CondNode *cond; + InputBox *box; + int ret_val; + + /* checks the condition presented and returns a 1 or a 0 */ + switch (node->type) { + case Cond: + cond = (CondNode *) hash_find(gWindow->fCondHashTable, node->data.text); + if (!strcmp("0", cond->cond)) + return 0; + else + return 1; + case Boxcond: + box = (InputBox *) hash_find(gWindow->page->box_hash, node->data.text); + return (box->picked); + case Haslisp: + if (spad_socket != NULL) { + ret_val = send_int(spad_socket, TestLine); + return (ret_val + 1); + } + else + return 0; + case Hasup: + return need_up_button; + case Hasreturn: + return gWindow->fMemoStackIndex; + case Hasreturnto: + return (check_memostack(node)); + case Lastwindow: + return (gSessionHashTable.num_entries == 1 || gParentWindow == gWindow); + default: + return 0; + } +} diff --git a/src/hyper/cond.pamphlet b/src/hyper/cond.pamphlet deleted file mode 100644 index 6a698068..00000000 --- a/src/hyper/cond.pamphlet +++ /dev/null @@ -1,188 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/cond} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{cond.h} -<>= -<> -#ifndef _COND_H_ -#define _COND_H_ 1 - -#include "hyper.h" - -#endif -@ -\section{cond.c} -<>= -/****************************************************************************** - * - * cond.c: Routines for handling "cond" nodes. - * - * Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993. - * - ****************************************************************************/ -#define _COND_C -#include "axiom-c-macros.h" -#include "useproto.h" -#include "debug.h" - -#include "cond.h" - -#include "all_hyper_proto.H1" -#include "sockio-c.H1" - - -void -insert_cond(char *label, char *cond) -{ - CondNode *condnode = (CondNode *) hash_find(gWindow->fCondHashTable, label); - - /* - * This routine creates a new cond node and inserts it into the - * current cond table - */ - if (condnode) { - fprintf(stderr, "Error: \\%s is declared twice \n", label); - print_page_and_filename(); - jump(); - } - condnode = alloc_condnode(); - condnode->label = halloc(strlen(label) + 1, "Condnode->label"); - condnode->cond = halloc(strlen(cond) + 1, "Condnode->cond"); - strcpy(condnode->label, label); - strcpy(condnode->cond, cond); - hash_insert(gWindow->fCondHashTable, (char *) condnode, condnode->label); -} - -void -change_cond(char *label, char *newcond) -{ - CondNode *condnode = (CondNode *) hash_find(gWindow->fCondHashTable, label); - - if (condnode == NULL) { - fprintf(stderr, "Error: Tried to set an uncreated cond %s\n", label); - } - else { - free(condnode->cond); - condnode->cond = halloc(strlen(newcond) + 1, "Condnode->cond"); - strcpy(condnode->cond, newcond); - } -} - -static int -check_memostack(TextNode *node) -{ - char *buffer; - int stackp = gWindow->fMemoStackIndex; - int found = 0; - HyperDocPage *page; - - buffer = print_to_string(node->data.node); - - /* - * Once we have done that much, search down the stack for the - * proper page - */ - - while (!found && stackp > 0) { - page = gWindow->fMemoStack[--stackp]; - if (!strcmp(page->name, buffer)) - found = 1; - } - return found; -} - -int -check_condition(TextNode *node) -{ - CondNode *cond; - InputBox *box; - int ret_val; - - /* checks the condition presented and returns a 1 or a 0 */ - switch (node->type) { - case Cond: - cond = (CondNode *) hash_find(gWindow->fCondHashTable, node->data.text); - if (!strcmp("0", cond->cond)) - return 0; - else - return 1; - case Boxcond: - box = (InputBox *) hash_find(gWindow->page->box_hash, node->data.text); - return (box->picked); - case Haslisp: - if (spad_socket != NULL) { - ret_val = send_int(spad_socket, TestLine); - return (ret_val + 1); - } - else - return 0; - case Hasup: - return need_up_button; - case Hasreturn: - return gWindow->fMemoStackIndex; - case Hasreturnto: - return (check_memostack(node)); - case Lastwindow: - return (gSessionHashTable.num_entries == 1 || gParentWindow == gWindow); - default: - return 0; - } -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/debug.c b/src/hyper/debug.c new file mode 100644 index 00000000..98c7d3c8 --- /dev/null +++ b/src/hyper/debug.c @@ -0,0 +1,48 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following debugitions are + met: + + - Redistributions of source code must retain the above copyright + notice, this list of debugitions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of debugitions 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. +*/ + +#define _DEBUG_C +#include "axiom-c-macros.h" +#include "useproto.h" +#include "debug.h" + +#ifdef free +#undef free +hfree(char *p) +{ + free(p); +} +#endif + diff --git a/src/hyper/debug.pamphlet b/src/hyper/debug.pamphlet deleted file mode 100644 index 3ed9ac81..00000000 --- a/src/hyper/debug.pamphlet +++ /dev/null @@ -1,77 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/debug} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{debug.h} -\section{debug.c} -<>= -#define _DEBUG_C -#include "axiom-c-macros.h" -#include "useproto.h" -#include "debug.h" - -#ifdef free -#undef free -hfree(char *p) -{ - free(p); -} -#endif - -@ -\section{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 debugitions are -met: - - - Redistributions of source code must retain the above copyright - notice, this list of debugitions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of debugitions 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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/dialog.c b/src/hyper/dialog.c new file mode 100644 index 00000000..f955e783 --- /dev/null +++ b/src/hyper/dialog.c @@ -0,0 +1,1349 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +/****************************************************************************** + * + * dialog.c: + * + * Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993. + * + ****************************************************************************/ +#define _DIALOG_C +#include "axiom-c-macros.h" +#include "useproto.h" +#include "debug.h" + +#include "hyper.h" +#include "keyin.h" +#include "display.h" +#include "group.h" + +#include + +#define min(x,y) ( (xfMainWindow); + XUnmapSubwindows(gXDisplay, gWindow->fScrollWindow); + XFlush(gXDisplay); + show_page(gWindow->page); +} + +static char * +mystrncpy(char *buff1, char *buff2, int n) +{ + /* + * copies the characters from buff1 to buff2 starting at position buff2 + + * n and buff1 + n + */ + + int i; + + for (i = n - 1; i >= 0; i--) + *(buff1 + i) = *(buff2 + i); + return buff2; +} + +static void +inc_line_numbers(LineStruct *line) +{ + for (; line != NULL; line = line->next) + line->line_number++; +} + +static void +dec_line_numbers(LineStruct *line) +{ + for (; line != NULL; line = line->next) + line->line_number--; + return; +} + +static void +decrease_line_numbers(LineStruct *line, int am) +{ + for (; line != NULL; line = line->next) + line->line_number -= am; +} + +static void +overwrite_buffer(char *buffer, InputItem *item) +{ + LineStruct *newline; + LineStruct *addline = item->curr_line; + /*int bufflen = strlen(buffer);*/ + int nl = 0; + int cursor_y; + int size = item->size; + + /* add a single character */ + + cursor_y = (addline->line_number - 1) * line_height; + if (addline->buff_pntr == size) { + clear_cursor(item); + if (addline->len <= size) { + nl = 1; + addline->buffer[size] = '_'; + addline->buffer[size + 1] = 0; + addline->len = size + 1; + newline = (LineStruct *) alloc_inputline(size + 2); + newline->line_number = addline->line_number + 1; + inc_line_numbers(addline->next); + newline->next = addline->next; + newline->prev = addline; + if (addline->next) + addline->next->prev = newline; + addline->next = newline; + item->num_lines++; + cursor_y += line_height; + item->curr_line = addline = newline; + } + else { + item->curr_line = addline = addline->next; + } + addline->len = 1; + addline->buff_pntr = 1; + addline->buffer[0] = buffer[0]; + } + else { + addline->buffer[addline->buff_pntr] = buffer[0]; + clear_cursor(item); + if (++addline->buff_pntr > addline->len) + addline->len++; + } + + /* now set up the current line */ + if (item->curr_line->buff_pntr >= item->size && + item->curr_line->next != NULL && !item->curr_line->next->len) { + /* I should actually be on the next line */ + item->curr_line->buffer[item->size] = '_'; + item->curr_line->len = item->size + 1; + XDrawString(gXDisplay, item->win, gWindow->fInputGC, start_x, + cursor_y + start_y, + addline->buffer, + addline->len); + item->curr_line = item->curr_line->next; + item->curr_line->buff_pntr = 0; + item->curr_line->changed = 1; + } + + if (!nl) { + XDrawString(gXDisplay, item->win, gWindow->fInputGC, start_x, + cursor_y + start_y, + addline->buffer, + addline->len); + draw_cursor(item); + } + else + redraw_win(); +} + +/* + * This routine takes the current line and moves it num forward. The + * only way I have to move any other lines forward is if this line has length + * > size + */ + +static int +move_sym_forward(LineStruct *line, int num, int size, InputItem *sym) +{ + LineStruct *newline; + int diff; + int nl = 0; + + if (line->len > size) { + nl = move_sym_forward(line->next, num, size, sym); + strncpy(line->next->buffer, + &line->buffer[sym->size - num], line->len); + strncpy(&line->buffer[num], + line->buffer, num); + line->changed = 1; + return nl; + } + else { + if (line->len + num > size) { + diff = line->len + num - size; + newline = alloc_inputline(size); + newline->len = diff; + newline->line_number = line->line_number++; + inc_line_numbers(line->next); + sym->num_lines++; + newline->next = line->next; + newline->prev = line; + if (line->next) + line->next->prev = newline; + line->next = newline; + strncpy(newline->buffer, &line->buffer[size - diff], diff); + strncpy(&line->buffer[num], line->buffer, num); + line->buffer[size] = '_'; + line->buffer[size + 1] = 0; + line->len = size + 1; + return 1; + } + else { + strncpy(&line->buffer[num], line->buffer, line->len); + line->len += num; + line->changed = 1; + return 0; + } + } +} + +static void +clear_cursorline(InputItem *sym) +{ + XCharStruct extents; + int dir, asc, des; + int cursor_y; + + XTextExtents(gInputFont, sym->curr_line->buffer, + sym->curr_line->buff_pntr, + &dir, &asc, &des, &extents); + cursor_y = (sym->curr_line->line_number - 1) * line_height; + sym->cursor_x = start_x + extents.width; + XClearArea(gXDisplay, sym->win, sym->cursor_x, cursor_y, + gWindow->width, line_height, False); + XDrawString(gXDisplay, sym->win, gWindow->fInputGC, start_x, cursor_y + start_y, + sym->curr_line->buffer, + sym->curr_line->len); +} + +static void +insert_buffer(char *buffer, InputItem *sym) +{ + /*int num = strlen(buffer);*/ + LineStruct *line = sym->curr_line; + LineStruct *newline; + int nl = 0; + int size = sym->size; + + if (line->len < size) { + /* they will all fit where I am so just copy them forward */ + line->len++; + mystrncpy(&(line->buffer[line->buff_pntr + 1]), + &(line->buffer[line->buff_pntr]), + line->len - line->buff_pntr + 1); + line->buffer[line->buff_pntr] = buffer[0]; + clear_cursorline(sym); + line->buff_pntr++; + draw_cursor(sym); + return; + } + + if (line->len > sym->size) { + nl = move_sym_forward(line->next, 1, size, sym); + if (line->buff_pntr > size) { + line->changed = 1; + line = line->next; + line->buffer[0] = buffer[0]; + line->len++; + line->buff_pntr = 1; + line->changed = 1; + } + else { + line->next->buffer[0] = line->buffer[size - 1]; + line->changed = 1; + strncpy(&line->buffer[line->buff_pntr + 1], + &line->buffer[line->buff_pntr], size - line->buff_pntr - 1); + line->buffer[line->buff_pntr++] = buffer[0]; + line->changed = 1; + if (line->buff_pntr >= size) { + sym->curr_line = line->next; + sym->curr_line->buff_pntr = 0; + } + } + } + else { + nl = 1; + newline = alloc_inputline(size); + newline->line_number = line->line_number + 1; + inc_line_numbers(line->next); + sym->num_lines++; + newline->next = line->next; + newline->prev = line; + if (line->next) + line->next->prev = newline; + line->next = newline; + + /* + * was line->buff_pntr++; + */ + if (line->buff_pntr >= size) { + /* we are the leaders of the line */ + newline->buff_pntr = 1; + newline->buffer[0] = buffer[0]; + newline->len = 1; + sym->curr_line = newline; + } + else { + /* we are not the leaders */ + newline->buffer[0] = line->buffer[size - 1]; + newline->len = 1; + strncpy(&line->buffer[line->buff_pntr + 1], + &line->buffer[line->buff_pntr], size - line->buff_pntr); + if (line->buff_pntr < size - 1) { + line->buffer[line->buff_pntr++] = buffer[0]; + } + else { + line->buffer[line->buff_pntr] = buffer[0]; + newline->buff_pntr = 0; + sym->curr_line = newline; + } + + } + line->buffer[size] = '_'; + line->buffer[size + 1] = 0; + line->len = size + 1; + } + if (nl) + redraw_win(); + else + update_inputsymbol(sym); + +} + +void +add_buffer_to_sym(char *buffer,InputItem *sym) +{ + if (gInInsertMode) + insert_buffer(buffer, sym); + else + overwrite_buffer(buffer, sym); +} + +void +draw_inputsymbol(InputItem *sym) +{ + int y_spot = start_y; + LineStruct *cline; + XCharStruct extents; + int dir, asc, des; + + +#if 0 + int cursor_y; + cursor_y = (sym->curr_line->line_number - 1) * line_height; +#endif + + XClearWindow(gXDisplay, sym->win); + + XTextExtents(gInputFont, sym->curr_line->buffer, + sym->curr_line->buff_pntr, + &dir, &asc, &des, &extents); + sym->cursor_x = start_x + extents.width; + + /* + * While the list of input strings is not NULL, I should just keep + * drawing them + */ + for (cline = sym->lines; cline != NULL; + cline = cline->next, y_spot += line_height) { + /* Now I should draw the initial string ** */ + cline->changed = 0; + XDrawString(gXDisplay, sym->win, gWindow->fInputGC, start_x, y_spot, + cline->buffer, + cline->len); + + } + if (gWindow->page->current_item == sym) + draw_cursor(sym); +} + +void +update_inputsymbol(InputItem *sym) +{ + int y_spot = start_y; + LineStruct *cline; + XCharStruct extents; + int dir, asc, des; + /*int cleared = 0;*/ + int clear_y; + int clear_width; + int clear_height; + +#if 0 + int cursor_y; + cursor_y = (sym->curr_line->line_number - 1) * line_height; +#endif + + clear_width = (sym->size + 1) * gInputFont->max_bounds.width + 10; + clear_height = line_height; + clear_y = 0; + + + XTextExtents(gInputFont, sym->curr_line->buffer, + sym->curr_line->buff_pntr, + &dir, &asc, &des, &extents); + sym->cursor_x = start_x + extents.width; + + /* + * While the list of input strings is not NULL, I should just keep + * drawing them + */ + for (cline = sym->lines; cline != NULL; + cline = cline->next, y_spot += line_height, clear_y += line_height) + /* Now I should draw the initial string ** */ + if (cline->changed) { + cline->changed = 0; + XClearArea(gXDisplay, sym->win, 0, clear_y, + clear_width, clear_height, False); + XDrawString(gXDisplay, sym->win, gWindow->fInputGC, start_x, y_spot, + cline->buffer, + cline->len); + } + draw_cursor(sym); +} + + +static void +draw_cursor(InputItem *sym) +{ + int cursor_y; + XCharStruct extents; + int dir, asc, des; + + + cursor_y = (sym->curr_line->line_number - 1) * line_height; + XTextExtents(gInputFont, sym->curr_line->buffer, + sym->curr_line->buff_pntr, + &dir, &asc, &des, &extents); + sym->cursor_x = start_x + extents.width; + /* now draw the cursor */ + if (gInInsertMode) { + XFillRectangle(gXDisplay, sym->win, gWindow->fInputGC, + sym->cursor_x, + out_cursor_y + cursor_y, + out_cursor_width, + out_cursor_height); + + /* Now draw the character currently under the cursor */ + + XDrawString(gXDisplay, sym->win, gWindow->fCursorGC, + sym->cursor_x, cursor_y + start_y, + &sym->curr_line->buffer[sym->curr_line->buff_pntr], + 1); + } + else + XFillRectangle(gXDisplay, sym->win, gWindow->fInputGC, + sym->cursor_x, + in_cursor_y + cursor_y, + in_cursor_width, + in_cursor_height); +} + +static void +move_cursor_home(InputItem *sym) +{ + LineStruct *trace = sym->curr_line; + + /* now move the cursor to the beginning of the current line */ + clear_cursor(sym); + for (; trace && trace->prev && trace->prev->len > sym->size;) + trace = trace->prev; + sym->curr_line = trace; + trace->buff_pntr = 0; + draw_cursor(sym); +} + +static void +move_cursor_end(InputItem *sym) +{ + LineStruct *trace = sym->curr_line; + + /* now move the cursor to the beginning of the current line */ + clear_cursor(sym); + for (; trace && trace->next && trace->len > sym->size;) + trace = trace->next; + sym->curr_line = trace; + trace->buff_pntr = trace->len; + draw_cursor(sym); +} + +static void +move_cursor_forward(InputItem *sym) +{ + if (sym->curr_line->buff_pntr == sym->curr_line->len && + !sym->curr_line->next) { + BeepAtTheUser(); + return; + } + + + if (sym->curr_line->buff_pntr == sym->curr_line->len || + sym->curr_line->buff_pntr == sym->size - 1) + { + + /* I have to move down to a new line */ + + if (sym->curr_line->next == NULL) { + /* now where to move */ + BeepAtTheUser(); + return; + } + + /* move down line */ + + clear_cursor(sym); + sym->curr_line = sym->curr_line->next; + sym->curr_line->buff_pntr = 0; + } + else { + clear_cursor(sym); + sym->curr_line->buff_pntr++; + } + + draw_cursor(sym); +} + +static void +move_cursor_down(InputItem *sym) +{ + int bp = sym->curr_line->buff_pntr; + /*int size = sym->size;*/ + LineStruct *trace; + + /* get to the end of the current line */ + + for (trace = sym->curr_line; trace->len > sym->size; trace = trace->next) + ; + + if (!trace->next) + BeepAtTheUser(); + else { + clear_cursor(sym); + sym->curr_line = trace->next; + if (bp > sym->curr_line->len) + sym->curr_line->buff_pntr = sym->curr_line->len; + else + sym->curr_line->buff_pntr = bp; + draw_cursor(sym); + } +} + +static void +move_cursor_up(InputItem *sym) +{ + int bp = sym->curr_line->buff_pntr; + /*int size = sym->size;*/ + LineStruct *trace; + + /* get to the end of the current line */ + for (trace = sym->curr_line; + trace->prev && trace->prev->len > sym->size; + trace = trace->prev) + ; + + if (!trace->prev) + BeepAtTheUser(); + else { + clear_cursor(sym); + sym->curr_line = trace->prev; + if (bp > sym->curr_line->len) + sym->curr_line->buff_pntr = sym->curr_line->len; + else + sym->curr_line->buff_pntr = bp; + draw_cursor(sym); + } +} + +static void +clear_cursor(InputItem *sym) +{ + XCharStruct extents; + int dir, asc, des; + int cursor_y; + + XTextExtents(gInputFont, sym->curr_line->buffer, + sym->curr_line->buff_pntr, + &dir, &asc, &des, &extents); + cursor_y = (sym->curr_line->line_number - 1) * line_height; + sym->cursor_x = start_x + extents.width; + XClearArea(gXDisplay, sym->win, sym->cursor_x, cursor_y, + in_cursor_width, line_height, False); + + XDrawString(gXDisplay, sym->win, gWindow->fInputGC, + start_x, cursor_y + start_y, + sym->curr_line->buffer, + sym->curr_line->len); +} + +static void +move_cursor_backward(InputItem *sym) +{ + if (sym->curr_line->buff_pntr == 0) { + if (sym->curr_line->prev == NULL) { + /* now where to move */ + BeepAtTheUser(); + return; + } + else { + clear_cursor(sym); + /* move up to the previous line */ + sym->curr_line = sym->curr_line->prev; + if (sym->curr_line->len > sym->size) + sym->curr_line->buff_pntr = sym->size - 1; + else + sym->curr_line->buff_pntr = sym->curr_line->len; + } + } + else { /* just slide back a char. on the current + * line */ + clear_cursor(sym); + sym->curr_line->buff_pntr--; + } + draw_cursor(sym); +} + +static char +move_rest_back(LineStruct *line, int size) +{ + char c = '\000'; + + if (line != NULL && line->len != 0) + c = line->buffer[0]; + else + return c; + + while (line->next != NULL && line->len > size) { + strncpy(line->buffer, &(line->buffer[1]), size - 1); + line->buffer[size - 1] = line->next->buffer[0]; + line->changed = 1; + line = line->next; + } + + /* + * once I get here I should be one the last line, so I can just copy all + * the characters back one and then return from whence I came *** + */ + if (line->len > 0) { + line->changed = 1; + if (line->len > 1) + strncpy(line->buffer, &(line->buffer[1]), line->len - 1); + line->buffer[--line->len] = 0; + if (line->len == 0) { + /* I have to fix the previous line */ + line->prev->len = size; + line->prev->buffer[size] = 0; + } + } + return c; +} + +static void +delete_rest_of_line(InputItem *sym) +{ + LineStruct *curr_line = sym->curr_line; + LineStruct *line=NULL; + LineStruct *trash; + LineStruct *trace; + int num_changed = 0, i; + + if (curr_line->len > sym->size) { + for (line = curr_line->next, num_changed = 0; + line != NULL && line->len > 0 && line->len > sym->size; + line = line->next, num_changed++) { + line->len = 0; + line->buffer[0] = 0; + line->changed = 1; + } + num_changed++; + } + + if (num_changed == 0 && curr_line->buff_pntr == curr_line->len) { + if (curr_line->len == 0 && curr_line->next) { + curr_line->next->prev = curr_line->prev; + if (curr_line->prev) + curr_line->prev->next = curr_line->next; + else + sym->lines = curr_line->next; + dec_line_numbers(curr_line->next); + sym->num_lines--; + sym->curr_line = curr_line->next; + sym->curr_line->buff_pntr = 0; + free(curr_line->buffer); + free(curr_line); + redraw_win(); + } + else + BeepAtTheUser(); + return; + } + + curr_line->len = curr_line->buff_pntr; + + /* curr_line->buffer[curr_line->len] = NULL; */ + + for (i = curr_line->len; i <= sym->size + 2; i++) + curr_line->buffer[i] = 0; + + curr_line->changed = 1; + + if (num_changed) { + /* I should get rid of all these lines */ + trace = curr_line->next; + curr_line->next = line->next; + if (line->next) + line->next->prev = curr_line; + for (; trace && trace != line->next;) { + trash = trace; + trace = trace->next; + free(trash->buffer); + free(trash); + } + decrease_line_numbers(curr_line->next, num_changed); + sym->num_lines -= num_changed; + redraw_win(); + } + else + update_inputsymbol(sym); +} + +static void +back_over_eoln(InputItem *sym) +{ + /* + * This routine is very similar to a tough enter except it starts + * combining lines with sym->curr_line->pre + */ + + char buff[1024]; + LineStruct *trace; + LineStruct *last = NULL; + char *tr = buff; + int bp; + int size = sym->size; + + /* copy all the stuff into the buffer */ + for (trace = sym->curr_line; + trace->len > sym->size; trace = trace->next) + for (bp = 0; bp < size; bp++) + *tr++ = trace->buffer[bp]; + + /* copy the last line */ + for (bp = 0; bp < trace->len; bp++) + *tr++ = trace->buffer[bp]; + trace->len = 0; + *tr = 0; + + /* Now that I have the buffer, let's put it back where it belongs. */ + last = trace; + for (trace = sym->curr_line; trace != last; trace = trace->next); + trace = sym->curr_line = sym->curr_line->prev; + trace->buff_pntr = trace->len; + trace->changed = 1; + for (bp = trace->len, tr = buff; bp < size && *tr; bp++) + trace->buffer[bp] = *tr++; + + if (!*tr) { + trace->len = bp; + } + else { + trace->len = size + 1; + trace->buffer[size] = '_'; + trace->buffer[size + 1] = 0; + for (trace = trace->next; *tr;) { + for (bp = 0; bp < size && *tr; bp++) + trace->buffer[bp] = *tr++; + if (*tr) { + trace->len = size + 1; + trace->changed = 1; + trace->buffer[size + 1] = 0; + trace->buffer[size] = '_'; + trace = trace->next; + } + else { + trace->len = bp; + trace->buffer[bp] = 0; + } + } + } + /* Now once I am here, let me see if I can bag a line */ + if (last->len == 0) { + /* rid myself of this line */ + last->prev->next = last->next; + if (last->next) + last->next->prev = last->prev; + dec_line_numbers(last->next); + sym->num_lines--; + free(last->buffer); + free(last); + redraw_win(); + } + else + update_inputsymbol(sym); + +} + +static int +move_back_one_char(InputItem *sym) +{ + char c = '\000', d = '\000'; + int dl = 0; + + /* This routine moves all the characters back one */ + LineStruct *line = sym->curr_line; + + if (line->len > sym->size) + c = move_rest_back(line->next, sym->size); + + line->changed = 1; + + if (line->buff_pntr == 0) { /* I am at the front of the line */ + if (line->prev == 0) { + BeepAtTheUser(); + return 0; + } + else if (line->prev->len <= sym->size) { + back_over_eoln(sym); + return 1; + } + else if (line->len > 0) { + d = line->buffer[0]; + if (line->len <= sym->size) { + strncpy(line->buffer, &(line->buffer[1]), line->len - 1); + if (c == 0) { + line->len--; + line->buffer[line->len] = 0; + } + else + line->buffer[line->len - 1] = c; + } + else { + strncpy(line->buffer, &(line->buffer[1]), sym->size - 2); + if (c == 0) { + line->buffer[sym->size - 1] = 0; + line->len--; + } + else { + line->buffer[sym->size - 1] = c; + } + } + } + else { + /* the line is just going to be thrown away */ + if (line->next) + line->next->prev = line->prev; + line->prev->next = line->next; + dec_line_numbers(line->next); + sym->num_lines--; + free(line->buffer); + free(line); + dl = 1; + } + c = d; + sym->curr_line = line = line->prev; + line->changed = 1; + line->buff_pntr = sym->size; + } + + + if (line->len <= sym->size) { + strncpy(&line->buffer[line->buff_pntr - 1], + &(line->buffer[line->buff_pntr]), + line->len - line->buff_pntr); + if (c == 0) + line->buffer[--line->len] = 0; + else + line->buffer[line->len - 1] = c; + } + else { + strncpy(&(line->buffer[line->buff_pntr - 1]), + &(line->buffer[line->buff_pntr]), + sym->size - line->buff_pntr); + if (c == 0) { + line->buffer[sym->size - 1] = 0; + line->len = sym->size - 1; + } + else { + if (line->next->len == 0) { + line->buffer[sym->size] = 0; + line->len = sym->size; + } + line->buffer[sym->size - 1] = c; + } + } + line->buff_pntr--; + if (dl) + redraw_win(); + else + update_inputsymbol(sym); + return 1; +} + +static void +back_over_char(InputItem *sym) +{ + if (move_back_one_char(sym)) + update_inputsymbol(sym); +} + +static void +delete_eoln(InputItem *sym) +{ + /* much the same as back_over eoln except my perspective has changed */ + char buff[1024]; + LineStruct *trace; + LineStruct *last = 0; + char *tr = buff; + int bp; + int size = sym->size; + + /* copy all the stuff into the buffer */ + for (trace = sym->curr_line->next; + trace->len > sym->size; trace = trace->next) + for (bp = 0; bp < size; bp++) + *tr++ = trace->buffer[bp]; + + /* copy the last line */ + for (bp = 0; bp < trace->len; bp++) + *tr++ = trace->buffer[bp]; + trace->len = 0; + *tr = 0; + + /* Now that I have the buffer, let's put it back where it belongs. */ + last = trace; + trace = sym->curr_line; + trace->changed = 1; + for (bp = trace->len, tr = buff; bp < size && *tr; bp++) + trace->buffer[bp] = *tr++; + + if (!*tr) + trace->len = bp; + else { + trace->len = size + 1; + trace->buffer[size] = '_'; + trace->buffer[size + 1] = 0; + for (trace = trace->next; *tr;) { + for (bp = 0; bp < size && *tr; bp++) + trace->buffer[bp] = *tr++; + if (*tr) { + trace->len = size + 1; + trace->changed = 1; + trace->buffer[size + 1] = 0; + trace->buffer[size] = '_'; + trace = trace->next; + } + else { + trace->len = bp; + trace->buffer[bp] = 0; + } + } + } + /* Now once I am here, let me see if I can bag a line */ + if (last->len == 0) { + /* rid myself of this line */ + last->prev->next = last->next; + if (last->next) + last->next->prev = last->prev; + dec_line_numbers(last->next); + sym->num_lines--; + free(last->buffer); + free(last); + redraw_win(); + } + else + update_inputsymbol(sym); + +} + +static int +delete_one_char(InputItem *sym) +{ + char c = '\000'; + + /* This routine moves all the characters back one */ + LineStruct *line = sym->curr_line; + + if (line->len > sym->size) + c = move_rest_back(line->next, sym->size); + + if (c == 0 && line->len == line->buff_pntr) { + if (line->next == 0) { + BeepAtTheUser(); + return 0; + } + else { + delete_eoln(sym); + return 1; + } + } + + /* + * let me just try to do the copy and put the stupid character c if it + * exists at the end + */ + if (line->len <= sym->size) { + strncpy(&line->buffer[line->buff_pntr], + &(line->buffer[line->buff_pntr + 1]), + line->len - line->buff_pntr); + if (c == 0) + line->buffer[--line->len] = 0; + else + line->buffer[line->len - 1] = c; + } + else { + strncpy(&(line->buffer[line->buff_pntr]), + &(line->buffer[line->buff_pntr + 1]), + sym->size - line->buff_pntr); + if (c == 0) { + line->buffer[sym->size - 1] = 0; + line->len = sym->size - 1; + } + else { + if (line->next->len == 0) { + line->buffer[sym->size] = 0; + line->len = sym->size; + } + line->buffer[sym->size - 1] = c; + } + } + line->changed = 1; + return 1; +} + +static void +delete_char(InputItem *sym) +{ + if (delete_one_char(sym)) + update_inputsymbol(sym); +} + +static void +tough_enter(InputItem *sym) +{ + char buff[1024]; + + /* + * This routine takes all the characters from the current cursor + * on, and copies them into a temp buffer, from which they are recopied + * back starting at the next line. + */ + + LineStruct *trace; + LineStruct *last = 0; + LineStruct *newline; + char *tr = buff; + int bp = sym->curr_line->buff_pntr; + int size = sym->size; + + /* Copy the stuff from the current line */ + for (; bp < size; bp++) + *tr++ = sym->curr_line->buffer[bp]; + + /* now get the stuff from the rest of the lines */ + for (trace = sym->curr_line->next; + trace->len > sym->size; trace = trace->next) + for (bp = 0; bp < size; bp++) + *tr++ = trace->buffer[bp]; + + /* copy the last line */ + for (bp = 0; bp < trace->len; bp++) + *tr++ = trace->buffer[bp]; + *tr = 0; + + /* Now that I have the buffer, let's put it back where it belongs. */ + last = trace; + trace = sym->curr_line; + trace->len = trace->buff_pntr; + trace->buffer[trace->len] = 0; + trace->changed = 1; + + tr = buff; + for (trace = trace->next; trace != last; trace = trace->next) { + for (bp = 0; bp < size; bp++) + trace->buffer[bp] = *tr++; + trace->len = size + 1; + trace->buffer[size + 1] = 0; + trace->buffer[size] = '_'; + trace->changed = 1; + } + + /* Once I am here, I should be able to copy this last line */ + for (bp = 0; bp < size && *tr; bp++) + trace->buffer[bp] = *tr++; + trace->changed = 1; + + /* If I still have more to copy, then do so onto a new line */ + if (*tr) { + trace->len = size + 1; + trace->buffer[size + 1] = 0; + trace->buffer[size] = '_'; + newline = alloc_inputline(size); + sym->num_lines++; + newline->line_number = last->line_number + 1; + inc_line_numbers(newline->next); + for (bp = 0; *tr; bp++) + newline->buffer[bp] = *tr++; + newline->len = bp; + newline->next = last->next; + newline->prev = last; + last->next = newline; + if (newline->next) + newline->next->prev = newline; + } + else { + trace->len = bp; + trace->buffer[bp] = 0; + } + /* Last but not least change the curr_line */ + sym->curr_line = sym->curr_line->next; + sym->curr_line->buff_pntr = 0; +} + +static void +enter_new_line(InputItem *sym) +{ + LineStruct *newline; + LineStruct *trace; + LineStruct *prev; + LineStruct *line = sym->curr_line; + int bp = line->buff_pntr; + int l = line->len; + int size = sym->size; + + /* + * At this point the user has hit a return. Let me just be naive, and + * take everything from the current spot on, and put it on a new line + */ + + if (bp == 0) { + if (line->prev->len > size) { + /* just add a return to the end of the last line */ + prev = line->prev; + prev->buffer[size] = 0; + prev->len = size; + prev->changed = 1; + } + else { + newline = alloc_inputline(size); + newline->next = sym->curr_line; + newline->prev = sym->curr_line->prev; + line->prev = newline; + sym->num_lines++; + if (newline->prev) + newline->prev->next = newline; + newline->len = newline->buff_pntr = 0; + newline->line_number = line->line_number; + if (sym->curr_line == sym->lines) + sym->lines = newline; + for (trace = newline->next; trace != 0; trace = trace->next) + trace->line_number++; + } + } + else if (bp == size && + line->len > size) { + /* line->next; */ + newline = alloc_inputline(size); + if (line->next) + line->next->prev = newline; + newline->prev = sym->curr_line; + line->next = newline; + newline->len = 0; + newline->buff_pntr = 0; + sym->num_lines++; + sym->curr_line = newline; + newline->line_number = newline->prev->line_number + 1; + for (trace = newline->next; trace != 0; trace = trace->next) + trace->line_number++; + } + else { + if (line->len > size) + tough_enter(sym); + else { + newline = alloc_inputline(size); + strncpy(newline->buffer, &sym->curr_line->buffer[bp], l - bp); + sym->curr_line->len = bp; + sym->curr_line->buffer[bp] = '\0'; + newline->next = sym->curr_line->next; + if (sym->curr_line->next) + sym->curr_line->next->prev = newline; + newline->prev = sym->curr_line; + sym->curr_line->next = newline; + newline->len = l - bp; + newline->buff_pntr = 0; + sym->num_lines++; + sym->curr_line = newline; + newline->line_number = newline->prev->line_number + 1; + for (trace = newline->next; trace != 0; trace = trace->next) + trace->line_number++; + } + } + redraw_win(); +} + +void +dialog(XEvent *event, KeySym keysym, char *buffer) +{ + InputItem *item; + + item = gWindow->page->current_item; + if (item == 0) { + if (!((keysym >= XK_Shift_L) && (keysym <= XK_Hyper_R))) + /** if something other than a modifier key was hit **/ + BeepAtTheUser(); + return; + } + + + /* + * First check if the user had hit an enter key + */ + + if ((keysym == XK_Return) || (keysym == XK_KP_Enter)) + enter_new_line(item); + /* + * Else did the user actual type a character I can understand + */ + + else if (((keysym >= XK_KP_Space) && (keysym <= XK_KP_9)) + || ((keysym >= XK_space) && (keysym <= XK_asciitilde))) + { + /* only handle normal keys */ + + if (event->xkey.state & ShiftModMask) + BeepAtTheUser(); + else + add_buffer_to_sym(buffer, item); + } + + else if ((keysym >= XK_Shift_L) && (keysym <= XK_Hyper_R)) + ; + + /* + * do nothing, a modifier was hit + */ + + else if ((keysym >= XK_F2) && (keysym <= XK_F35)) { + + /* + * A function key was hit + */ + + if (strlen(buffer) == 0) + BeepAtTheUser(); + else + /* If I got characters then add it to the buffer */ + + add_buffer_to_sym(buffer, item); + } + else + switch (keysym) { + case XK_Escape: + if (event->xkey.state & ModifiersMask) + BeepAtTheUser(); + else { + move_cursor_home(item); + delete_rest_of_line(item); + } + break; + case XK_F1: + if (event->xkey.state & ModifiersMask) + BeepAtTheUser(); + else { + gWindow->page->helppage = alloc_string(InputAreaHelpPage); + helpForHyperDoc(); + } + break; + case XK_Up: + if (event->xkey.state & ModifiersMask) + BeepAtTheUser(); + else + move_cursor_up(item); + break; + case XK_Down: + if (event->xkey.state & ModifiersMask) + BeepAtTheUser(); + else + move_cursor_down(item); + break; + case XK_Delete: + if (event->xkey.state & ModifiersMask) + BeepAtTheUser(); + else + delete_char(item); + break; + case XK_BackSpace: + if (event->xkey.state & ModifiersMask) + BeepAtTheUser(); + else + back_over_char(item); + break; + case XK_Left: + if (event->xkey.state & ModifiersMask) + BeepAtTheUser(); + else + move_cursor_backward(item); + break; + case XK_Right: + if (event->xkey.state & ModifiersMask) + BeepAtTheUser(); + else + move_cursor_forward(item); + break; + case XK_Insert: + if (event->xkey.state & ModifiersMask) + BeepAtTheUser(); + else { + gInInsertMode = ((gInInsertMode) ? (0) : (1)); + item->curr_line->changed = 1; + update_inputsymbol(item); + } + break; + case XK_Home: + if (event->xkey.state & ModifiersMask) + BeepAtTheUser(); + else + move_cursor_home(item); + break; + case XK_End: + if (event->xkey.state & ControlMask) + /* delete from here to the end of the line */ + + delete_rest_of_line(item); + else if (event->xkey.state & ModifiersMask) + BeepAtTheUser(); + else + move_cursor_end(item); + break; + default: + BeepAtTheUser(); + break; + } +} diff --git a/src/hyper/dialog.pamphlet b/src/hyper/dialog.pamphlet deleted file mode 100644 index 82f67bda..00000000 --- a/src/hyper/dialog.pamphlet +++ /dev/null @@ -1,1388 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/dialog} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{dialog.h} -<>= -<> -#ifndef _DIALOG_H_ -#define _DIALOG_H_ 1 - -#include "hyper.h" - -#endif -@ -\section{dialog.c} -<>= -/****************************************************************************** - * - * dialog.c: - * - * Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993. - * - ****************************************************************************/ -#define _DIALOG_C -#include "axiom-c-macros.h" -#include "useproto.h" -#include "debug.h" - -#include "dialog.h" -#include "keyin.h" -#include "mem.h" -#include "display.h" -#include "group.h" - -#include - -#define min(x,y) ( (xfMainWindow); - XUnmapSubwindows(gXDisplay, gWindow->fScrollWindow); - XFlush(gXDisplay); - show_page(gWindow->page); -} - -static char * -mystrncpy(char *buff1, char *buff2, int n) -{ - /* - * copies the characters from buff1 to buff2 starting at position buff2 + - * n and buff1 + n - */ - - int i; - - for (i = n - 1; i >= 0; i--) - *(buff1 + i) = *(buff2 + i); - return buff2; -} - -static void -inc_line_numbers(LineStruct *line) -{ - for (; line != NULL; line = line->next) - line->line_number++; -} - -static void -dec_line_numbers(LineStruct *line) -{ - for (; line != NULL; line = line->next) - line->line_number--; - return; -} - -static void -decrease_line_numbers(LineStruct *line, int am) -{ - for (; line != NULL; line = line->next) - line->line_number -= am; -} - -static void -overwrite_buffer(char *buffer, InputItem *item) -{ - LineStruct *newline; - LineStruct *addline = item->curr_line; - /*int bufflen = strlen(buffer);*/ - int nl = 0; - int cursor_y; - int size = item->size; - - /* add a single character */ - - cursor_y = (addline->line_number - 1) * line_height; - if (addline->buff_pntr == size) { - clear_cursor(item); - if (addline->len <= size) { - nl = 1; - addline->buffer[size] = '_'; - addline->buffer[size + 1] = 0; - addline->len = size + 1; - newline = (LineStruct *) alloc_inputline(size + 2); - newline->line_number = addline->line_number + 1; - inc_line_numbers(addline->next); - newline->next = addline->next; - newline->prev = addline; - if (addline->next) - addline->next->prev = newline; - addline->next = newline; - item->num_lines++; - cursor_y += line_height; - item->curr_line = addline = newline; - } - else { - item->curr_line = addline = addline->next; - } - addline->len = 1; - addline->buff_pntr = 1; - addline->buffer[0] = buffer[0]; - } - else { - addline->buffer[addline->buff_pntr] = buffer[0]; - clear_cursor(item); - if (++addline->buff_pntr > addline->len) - addline->len++; - } - - /* now set up the current line */ - if (item->curr_line->buff_pntr >= item->size && - item->curr_line->next != NULL && !item->curr_line->next->len) { - /* I should actually be on the next line */ - item->curr_line->buffer[item->size] = '_'; - item->curr_line->len = item->size + 1; - XDrawString(gXDisplay, item->win, gWindow->fInputGC, start_x, - cursor_y + start_y, - addline->buffer, - addline->len); - item->curr_line = item->curr_line->next; - item->curr_line->buff_pntr = 0; - item->curr_line->changed = 1; - } - - if (!nl) { - XDrawString(gXDisplay, item->win, gWindow->fInputGC, start_x, - cursor_y + start_y, - addline->buffer, - addline->len); - draw_cursor(item); - } - else - redraw_win(); -} - -/* - * This routine takes the current line and moves it num forward. The - * only way I have to move any other lines forward is if this line has length - * > size - */ - -static int -move_sym_forward(LineStruct *line, int num, int size, InputItem *sym) -{ - LineStruct *newline; - int diff; - int nl = 0; - - if (line->len > size) { - nl = move_sym_forward(line->next, num, size, sym); - strncpy(line->next->buffer, - &line->buffer[sym->size - num], line->len); - strncpy(&line->buffer[num], - line->buffer, num); - line->changed = 1; - return nl; - } - else { - if (line->len + num > size) { - diff = line->len + num - size; - newline = alloc_inputline(size); - newline->len = diff; - newline->line_number = line->line_number++; - inc_line_numbers(line->next); - sym->num_lines++; - newline->next = line->next; - newline->prev = line; - if (line->next) - line->next->prev = newline; - line->next = newline; - strncpy(newline->buffer, &line->buffer[size - diff], diff); - strncpy(&line->buffer[num], line->buffer, num); - line->buffer[size] = '_'; - line->buffer[size + 1] = 0; - line->len = size + 1; - return 1; - } - else { - strncpy(&line->buffer[num], line->buffer, line->len); - line->len += num; - line->changed = 1; - return 0; - } - } -} - -static void -clear_cursorline(InputItem *sym) -{ - XCharStruct extents; - int dir, asc, des; - int cursor_y; - - XTextExtents(gInputFont, sym->curr_line->buffer, - sym->curr_line->buff_pntr, - &dir, &asc, &des, &extents); - cursor_y = (sym->curr_line->line_number - 1) * line_height; - sym->cursor_x = start_x + extents.width; - XClearArea(gXDisplay, sym->win, sym->cursor_x, cursor_y, - gWindow->width, line_height, False); - XDrawString(gXDisplay, sym->win, gWindow->fInputGC, start_x, cursor_y + start_y, - sym->curr_line->buffer, - sym->curr_line->len); -} - -static void -insert_buffer(char *buffer, InputItem *sym) -{ - /*int num = strlen(buffer);*/ - LineStruct *line = sym->curr_line; - LineStruct *newline; - int nl = 0; - int size = sym->size; - - if (line->len < size) { - /* they will all fit where I am so just copy them forward */ - line->len++; - mystrncpy(&(line->buffer[line->buff_pntr + 1]), - &(line->buffer[line->buff_pntr]), - line->len - line->buff_pntr + 1); - line->buffer[line->buff_pntr] = buffer[0]; - clear_cursorline(sym); - line->buff_pntr++; - draw_cursor(sym); - return; - } - - if (line->len > sym->size) { - nl = move_sym_forward(line->next, 1, size, sym); - if (line->buff_pntr > size) { - line->changed = 1; - line = line->next; - line->buffer[0] = buffer[0]; - line->len++; - line->buff_pntr = 1; - line->changed = 1; - } - else { - line->next->buffer[0] = line->buffer[size - 1]; - line->changed = 1; - strncpy(&line->buffer[line->buff_pntr + 1], - &line->buffer[line->buff_pntr], size - line->buff_pntr - 1); - line->buffer[line->buff_pntr++] = buffer[0]; - line->changed = 1; - if (line->buff_pntr >= size) { - sym->curr_line = line->next; - sym->curr_line->buff_pntr = 0; - } - } - } - else { - nl = 1; - newline = alloc_inputline(size); - newline->line_number = line->line_number + 1; - inc_line_numbers(line->next); - sym->num_lines++; - newline->next = line->next; - newline->prev = line; - if (line->next) - line->next->prev = newline; - line->next = newline; - - /* - * was line->buff_pntr++; - */ - if (line->buff_pntr >= size) { - /* we are the leaders of the line */ - newline->buff_pntr = 1; - newline->buffer[0] = buffer[0]; - newline->len = 1; - sym->curr_line = newline; - } - else { - /* we are not the leaders */ - newline->buffer[0] = line->buffer[size - 1]; - newline->len = 1; - strncpy(&line->buffer[line->buff_pntr + 1], - &line->buffer[line->buff_pntr], size - line->buff_pntr); - if (line->buff_pntr < size - 1) { - line->buffer[line->buff_pntr++] = buffer[0]; - } - else { - line->buffer[line->buff_pntr] = buffer[0]; - newline->buff_pntr = 0; - sym->curr_line = newline; - } - - } - line->buffer[size] = '_'; - line->buffer[size + 1] = 0; - line->len = size + 1; - } - if (nl) - redraw_win(); - else - update_inputsymbol(sym); - -} - -void -add_buffer_to_sym(char *buffer,InputItem *sym) -{ - if (gInInsertMode) - insert_buffer(buffer, sym); - else - overwrite_buffer(buffer, sym); -} - -void -draw_inputsymbol(InputItem *sym) -{ - int y_spot = start_y; - LineStruct *cline; - XCharStruct extents; - int dir, asc, des; - - -#if 0 - int cursor_y; - cursor_y = (sym->curr_line->line_number - 1) * line_height; -#endif - - XClearWindow(gXDisplay, sym->win); - - XTextExtents(gInputFont, sym->curr_line->buffer, - sym->curr_line->buff_pntr, - &dir, &asc, &des, &extents); - sym->cursor_x = start_x + extents.width; - - /* - * While the list of input strings is not NULL, I should just keep - * drawing them - */ - for (cline = sym->lines; cline != NULL; - cline = cline->next, y_spot += line_height) { - /* Now I should draw the initial string ** */ - cline->changed = 0; - XDrawString(gXDisplay, sym->win, gWindow->fInputGC, start_x, y_spot, - cline->buffer, - cline->len); - - } - if (gWindow->page->current_item == sym) - draw_cursor(sym); -} - -void -update_inputsymbol(InputItem *sym) -{ - int y_spot = start_y; - LineStruct *cline; - XCharStruct extents; - int dir, asc, des; - /*int cleared = 0;*/ - int clear_y; - int clear_width; - int clear_height; - -#if 0 - int cursor_y; - cursor_y = (sym->curr_line->line_number - 1) * line_height; -#endif - - clear_width = (sym->size + 1) * gInputFont->max_bounds.width + 10; - clear_height = line_height; - clear_y = 0; - - - XTextExtents(gInputFont, sym->curr_line->buffer, - sym->curr_line->buff_pntr, - &dir, &asc, &des, &extents); - sym->cursor_x = start_x + extents.width; - - /* - * While the list of input strings is not NULL, I should just keep - * drawing them - */ - for (cline = sym->lines; cline != NULL; - cline = cline->next, y_spot += line_height, clear_y += line_height) - /* Now I should draw the initial string ** */ - if (cline->changed) { - cline->changed = 0; - XClearArea(gXDisplay, sym->win, 0, clear_y, - clear_width, clear_height, False); - XDrawString(gXDisplay, sym->win, gWindow->fInputGC, start_x, y_spot, - cline->buffer, - cline->len); - } - draw_cursor(sym); -} - - -static void -draw_cursor(InputItem *sym) -{ - int cursor_y; - XCharStruct extents; - int dir, asc, des; - - - cursor_y = (sym->curr_line->line_number - 1) * line_height; - XTextExtents(gInputFont, sym->curr_line->buffer, - sym->curr_line->buff_pntr, - &dir, &asc, &des, &extents); - sym->cursor_x = start_x + extents.width; - /* now draw the cursor */ - if (gInInsertMode) { - XFillRectangle(gXDisplay, sym->win, gWindow->fInputGC, - sym->cursor_x, - out_cursor_y + cursor_y, - out_cursor_width, - out_cursor_height); - - /* Now draw the character currently under the cursor */ - - XDrawString(gXDisplay, sym->win, gWindow->fCursorGC, - sym->cursor_x, cursor_y + start_y, - &sym->curr_line->buffer[sym->curr_line->buff_pntr], - 1); - } - else - XFillRectangle(gXDisplay, sym->win, gWindow->fInputGC, - sym->cursor_x, - in_cursor_y + cursor_y, - in_cursor_width, - in_cursor_height); -} - -static void -move_cursor_home(InputItem *sym) -{ - LineStruct *trace = sym->curr_line; - - /* now move the cursor to the beginning of the current line */ - clear_cursor(sym); - for (; trace && trace->prev && trace->prev->len > sym->size;) - trace = trace->prev; - sym->curr_line = trace; - trace->buff_pntr = 0; - draw_cursor(sym); -} - -static void -move_cursor_end(InputItem *sym) -{ - LineStruct *trace = sym->curr_line; - - /* now move the cursor to the beginning of the current line */ - clear_cursor(sym); - for (; trace && trace->next && trace->len > sym->size;) - trace = trace->next; - sym->curr_line = trace; - trace->buff_pntr = trace->len; - draw_cursor(sym); -} - -static void -move_cursor_forward(InputItem *sym) -{ - if (sym->curr_line->buff_pntr == sym->curr_line->len && - !sym->curr_line->next) { - BeepAtTheUser(); - return; - } - - - if (sym->curr_line->buff_pntr == sym->curr_line->len || - sym->curr_line->buff_pntr == sym->size - 1) - { - - /* I have to move down to a new line */ - - if (sym->curr_line->next == NULL) { - /* now where to move */ - BeepAtTheUser(); - return; - } - - /* move down line */ - - clear_cursor(sym); - sym->curr_line = sym->curr_line->next; - sym->curr_line->buff_pntr = 0; - } - else { - clear_cursor(sym); - sym->curr_line->buff_pntr++; - } - - draw_cursor(sym); -} - -static void -move_cursor_down(InputItem *sym) -{ - int bp = sym->curr_line->buff_pntr; - /*int size = sym->size;*/ - LineStruct *trace; - - /* get to the end of the current line */ - - for (trace = sym->curr_line; trace->len > sym->size; trace = trace->next) - ; - - if (!trace->next) - BeepAtTheUser(); - else { - clear_cursor(sym); - sym->curr_line = trace->next; - if (bp > sym->curr_line->len) - sym->curr_line->buff_pntr = sym->curr_line->len; - else - sym->curr_line->buff_pntr = bp; - draw_cursor(sym); - } -} - -static void -move_cursor_up(InputItem *sym) -{ - int bp = sym->curr_line->buff_pntr; - /*int size = sym->size;*/ - LineStruct *trace; - - /* get to the end of the current line */ - for (trace = sym->curr_line; - trace->prev && trace->prev->len > sym->size; - trace = trace->prev) - ; - - if (!trace->prev) - BeepAtTheUser(); - else { - clear_cursor(sym); - sym->curr_line = trace->prev; - if (bp > sym->curr_line->len) - sym->curr_line->buff_pntr = sym->curr_line->len; - else - sym->curr_line->buff_pntr = bp; - draw_cursor(sym); - } -} - -static void -clear_cursor(InputItem *sym) -{ - XCharStruct extents; - int dir, asc, des; - int cursor_y; - - XTextExtents(gInputFont, sym->curr_line->buffer, - sym->curr_line->buff_pntr, - &dir, &asc, &des, &extents); - cursor_y = (sym->curr_line->line_number - 1) * line_height; - sym->cursor_x = start_x + extents.width; - XClearArea(gXDisplay, sym->win, sym->cursor_x, cursor_y, - in_cursor_width, line_height, False); - - XDrawString(gXDisplay, sym->win, gWindow->fInputGC, - start_x, cursor_y + start_y, - sym->curr_line->buffer, - sym->curr_line->len); -} - -static void -move_cursor_backward(InputItem *sym) -{ - if (sym->curr_line->buff_pntr == 0) { - if (sym->curr_line->prev == NULL) { - /* now where to move */ - BeepAtTheUser(); - return; - } - else { - clear_cursor(sym); - /* move up to the previous line */ - sym->curr_line = sym->curr_line->prev; - if (sym->curr_line->len > sym->size) - sym->curr_line->buff_pntr = sym->size - 1; - else - sym->curr_line->buff_pntr = sym->curr_line->len; - } - } - else { /* just slide back a char. on the current - * line */ - clear_cursor(sym); - sym->curr_line->buff_pntr--; - } - draw_cursor(sym); -} - -static char -move_rest_back(LineStruct *line, int size) -{ - char c = '\000'; - - if (line != NULL && line->len != 0) - c = line->buffer[0]; - else - return c; - - while (line->next != NULL && line->len > size) { - strncpy(line->buffer, &(line->buffer[1]), size - 1); - line->buffer[size - 1] = line->next->buffer[0]; - line->changed = 1; - line = line->next; - } - - /* - * once I get here I should be one the last line, so I can just copy all - * the characters back one and then return from whence I came *** - */ - if (line->len > 0) { - line->changed = 1; - if (line->len > 1) - strncpy(line->buffer, &(line->buffer[1]), line->len - 1); - line->buffer[--line->len] = 0; - if (line->len == 0) { - /* I have to fix the previous line */ - line->prev->len = size; - line->prev->buffer[size] = 0; - } - } - return c; -} - -static void -delete_rest_of_line(InputItem *sym) -{ - LineStruct *curr_line = sym->curr_line; - LineStruct *line=NULL; - LineStruct *trash; - LineStruct *trace; - int num_changed = 0, i; - - if (curr_line->len > sym->size) { - for (line = curr_line->next, num_changed = 0; - line != NULL && line->len > 0 && line->len > sym->size; - line = line->next, num_changed++) { - line->len = 0; - line->buffer[0] = 0; - line->changed = 1; - } - num_changed++; - } - - if (num_changed == 0 && curr_line->buff_pntr == curr_line->len) { - if (curr_line->len == 0 && curr_line->next) { - curr_line->next->prev = curr_line->prev; - if (curr_line->prev) - curr_line->prev->next = curr_line->next; - else - sym->lines = curr_line->next; - dec_line_numbers(curr_line->next); - sym->num_lines--; - sym->curr_line = curr_line->next; - sym->curr_line->buff_pntr = 0; - free(curr_line->buffer); - free(curr_line); - redraw_win(); - } - else - BeepAtTheUser(); - return; - } - - curr_line->len = curr_line->buff_pntr; - - /* curr_line->buffer[curr_line->len] = NULL; */ - - for (i = curr_line->len; i <= sym->size + 2; i++) - curr_line->buffer[i] = 0; - - curr_line->changed = 1; - - if (num_changed) { - /* I should get rid of all these lines */ - trace = curr_line->next; - curr_line->next = line->next; - if (line->next) - line->next->prev = curr_line; - for (; trace && trace != line->next;) { - trash = trace; - trace = trace->next; - free(trash->buffer); - free(trash); - } - decrease_line_numbers(curr_line->next, num_changed); - sym->num_lines -= num_changed; - redraw_win(); - } - else - update_inputsymbol(sym); -} - -static void -back_over_eoln(InputItem *sym) -{ - /* - * This routine is very similar to a tough enter except it starts - * combining lines with sym->curr_line->pre - */ - - char buff[1024]; - LineStruct *trace; - LineStruct *last = NULL; - char *tr = buff; - int bp; - int size = sym->size; - - /* copy all the stuff into the buffer */ - for (trace = sym->curr_line; - trace->len > sym->size; trace = trace->next) - for (bp = 0; bp < size; bp++) - *tr++ = trace->buffer[bp]; - - /* copy the last line */ - for (bp = 0; bp < trace->len; bp++) - *tr++ = trace->buffer[bp]; - trace->len = 0; - *tr = 0; - - /* Now that I have the buffer, let's put it back where it belongs. */ - last = trace; - for (trace = sym->curr_line; trace != last; trace = trace->next); - trace = sym->curr_line = sym->curr_line->prev; - trace->buff_pntr = trace->len; - trace->changed = 1; - for (bp = trace->len, tr = buff; bp < size && *tr; bp++) - trace->buffer[bp] = *tr++; - - if (!*tr) { - trace->len = bp; - } - else { - trace->len = size + 1; - trace->buffer[size] = '_'; - trace->buffer[size + 1] = 0; - for (trace = trace->next; *tr;) { - for (bp = 0; bp < size && *tr; bp++) - trace->buffer[bp] = *tr++; - if (*tr) { - trace->len = size + 1; - trace->changed = 1; - trace->buffer[size + 1] = 0; - trace->buffer[size] = '_'; - trace = trace->next; - } - else { - trace->len = bp; - trace->buffer[bp] = 0; - } - } - } - /* Now once I am here, let me see if I can bag a line */ - if (last->len == 0) { - /* rid myself of this line */ - last->prev->next = last->next; - if (last->next) - last->next->prev = last->prev; - dec_line_numbers(last->next); - sym->num_lines--; - free(last->buffer); - free(last); - redraw_win(); - } - else - update_inputsymbol(sym); - -} - -static int -move_back_one_char(InputItem *sym) -{ - char c = '\000', d = '\000'; - int dl = 0; - - /* This routine moves all the characters back one */ - LineStruct *line = sym->curr_line; - - if (line->len > sym->size) - c = move_rest_back(line->next, sym->size); - - line->changed = 1; - - if (line->buff_pntr == 0) { /* I am at the front of the line */ - if (line->prev == 0) { - BeepAtTheUser(); - return 0; - } - else if (line->prev->len <= sym->size) { - back_over_eoln(sym); - return 1; - } - else if (line->len > 0) { - d = line->buffer[0]; - if (line->len <= sym->size) { - strncpy(line->buffer, &(line->buffer[1]), line->len - 1); - if (c == 0) { - line->len--; - line->buffer[line->len] = 0; - } - else - line->buffer[line->len - 1] = c; - } - else { - strncpy(line->buffer, &(line->buffer[1]), sym->size - 2); - if (c == 0) { - line->buffer[sym->size - 1] = 0; - line->len--; - } - else { - line->buffer[sym->size - 1] = c; - } - } - } - else { - /* the line is just going to be thrown away */ - if (line->next) - line->next->prev = line->prev; - line->prev->next = line->next; - dec_line_numbers(line->next); - sym->num_lines--; - free(line->buffer); - free(line); - dl = 1; - } - c = d; - sym->curr_line = line = line->prev; - line->changed = 1; - line->buff_pntr = sym->size; - } - - - if (line->len <= sym->size) { - strncpy(&line->buffer[line->buff_pntr - 1], - &(line->buffer[line->buff_pntr]), - line->len - line->buff_pntr); - if (c == 0) - line->buffer[--line->len] = 0; - else - line->buffer[line->len - 1] = c; - } - else { - strncpy(&(line->buffer[line->buff_pntr - 1]), - &(line->buffer[line->buff_pntr]), - sym->size - line->buff_pntr); - if (c == 0) { - line->buffer[sym->size - 1] = 0; - line->len = sym->size - 1; - } - else { - if (line->next->len == 0) { - line->buffer[sym->size] = 0; - line->len = sym->size; - } - line->buffer[sym->size - 1] = c; - } - } - line->buff_pntr--; - if (dl) - redraw_win(); - else - update_inputsymbol(sym); - return 1; -} - -static void -back_over_char(InputItem *sym) -{ - if (move_back_one_char(sym)) - update_inputsymbol(sym); -} - -static void -delete_eoln(InputItem *sym) -{ - /* much the same as back_over eoln except my perspective has changed */ - char buff[1024]; - LineStruct *trace; - LineStruct *last = 0; - char *tr = buff; - int bp; - int size = sym->size; - - /* copy all the stuff into the buffer */ - for (trace = sym->curr_line->next; - trace->len > sym->size; trace = trace->next) - for (bp = 0; bp < size; bp++) - *tr++ = trace->buffer[bp]; - - /* copy the last line */ - for (bp = 0; bp < trace->len; bp++) - *tr++ = trace->buffer[bp]; - trace->len = 0; - *tr = 0; - - /* Now that I have the buffer, let's put it back where it belongs. */ - last = trace; - trace = sym->curr_line; - trace->changed = 1; - for (bp = trace->len, tr = buff; bp < size && *tr; bp++) - trace->buffer[bp] = *tr++; - - if (!*tr) - trace->len = bp; - else { - trace->len = size + 1; - trace->buffer[size] = '_'; - trace->buffer[size + 1] = 0; - for (trace = trace->next; *tr;) { - for (bp = 0; bp < size && *tr; bp++) - trace->buffer[bp] = *tr++; - if (*tr) { - trace->len = size + 1; - trace->changed = 1; - trace->buffer[size + 1] = 0; - trace->buffer[size] = '_'; - trace = trace->next; - } - else { - trace->len = bp; - trace->buffer[bp] = 0; - } - } - } - /* Now once I am here, let me see if I can bag a line */ - if (last->len == 0) { - /* rid myself of this line */ - last->prev->next = last->next; - if (last->next) - last->next->prev = last->prev; - dec_line_numbers(last->next); - sym->num_lines--; - free(last->buffer); - free(last); - redraw_win(); - } - else - update_inputsymbol(sym); - -} - -static int -delete_one_char(InputItem *sym) -{ - char c = '\000'; - - /* This routine moves all the characters back one */ - LineStruct *line = sym->curr_line; - - if (line->len > sym->size) - c = move_rest_back(line->next, sym->size); - - if (c == 0 && line->len == line->buff_pntr) { - if (line->next == 0) { - BeepAtTheUser(); - return 0; - } - else { - delete_eoln(sym); - return 1; - } - } - - /* - * let me just try to do the copy and put the stupid character c if it - * exists at the end - */ - if (line->len <= sym->size) { - strncpy(&line->buffer[line->buff_pntr], - &(line->buffer[line->buff_pntr + 1]), - line->len - line->buff_pntr); - if (c == 0) - line->buffer[--line->len] = 0; - else - line->buffer[line->len - 1] = c; - } - else { - strncpy(&(line->buffer[line->buff_pntr]), - &(line->buffer[line->buff_pntr + 1]), - sym->size - line->buff_pntr); - if (c == 0) { - line->buffer[sym->size - 1] = 0; - line->len = sym->size - 1; - } - else { - if (line->next->len == 0) { - line->buffer[sym->size] = 0; - line->len = sym->size; - } - line->buffer[sym->size - 1] = c; - } - } - line->changed = 1; - return 1; -} - -static void -delete_char(InputItem *sym) -{ - if (delete_one_char(sym)) - update_inputsymbol(sym); -} - -static void -tough_enter(InputItem *sym) -{ - char buff[1024]; - - /* - * This routine takes all the characters from the current cursor - * on, and copies them into a temp buffer, from which they are recopied - * back starting at the next line. - */ - - LineStruct *trace; - LineStruct *last = 0; - LineStruct *newline; - char *tr = buff; - int bp = sym->curr_line->buff_pntr; - int size = sym->size; - - /* Copy the stuff from the current line */ - for (; bp < size; bp++) - *tr++ = sym->curr_line->buffer[bp]; - - /* now get the stuff from the rest of the lines */ - for (trace = sym->curr_line->next; - trace->len > sym->size; trace = trace->next) - for (bp = 0; bp < size; bp++) - *tr++ = trace->buffer[bp]; - - /* copy the last line */ - for (bp = 0; bp < trace->len; bp++) - *tr++ = trace->buffer[bp]; - *tr = 0; - - /* Now that I have the buffer, let's put it back where it belongs. */ - last = trace; - trace = sym->curr_line; - trace->len = trace->buff_pntr; - trace->buffer[trace->len] = 0; - trace->changed = 1; - - tr = buff; - for (trace = trace->next; trace != last; trace = trace->next) { - for (bp = 0; bp < size; bp++) - trace->buffer[bp] = *tr++; - trace->len = size + 1; - trace->buffer[size + 1] = 0; - trace->buffer[size] = '_'; - trace->changed = 1; - } - - /* Once I am here, I should be able to copy this last line */ - for (bp = 0; bp < size && *tr; bp++) - trace->buffer[bp] = *tr++; - trace->changed = 1; - - /* If I still have more to copy, then do so onto a new line */ - if (*tr) { - trace->len = size + 1; - trace->buffer[size + 1] = 0; - trace->buffer[size] = '_'; - newline = alloc_inputline(size); - sym->num_lines++; - newline->line_number = last->line_number + 1; - inc_line_numbers(newline->next); - for (bp = 0; *tr; bp++) - newline->buffer[bp] = *tr++; - newline->len = bp; - newline->next = last->next; - newline->prev = last; - last->next = newline; - if (newline->next) - newline->next->prev = newline; - } - else { - trace->len = bp; - trace->buffer[bp] = 0; - } - /* Last but not least change the curr_line */ - sym->curr_line = sym->curr_line->next; - sym->curr_line->buff_pntr = 0; -} - -static void -enter_new_line(InputItem *sym) -{ - LineStruct *newline; - LineStruct *trace; - LineStruct *prev; - LineStruct *line = sym->curr_line; - int bp = line->buff_pntr; - int l = line->len; - int size = sym->size; - - /* - * At this point the user has hit a return. Let me just be naive, and - * take everything from the current spot on, and put it on a new line - */ - - if (bp == 0) { - if (line->prev->len > size) { - /* just add a return to the end of the last line */ - prev = line->prev; - prev->buffer[size] = 0; - prev->len = size; - prev->changed = 1; - } - else { - newline = alloc_inputline(size); - newline->next = sym->curr_line; - newline->prev = sym->curr_line->prev; - line->prev = newline; - sym->num_lines++; - if (newline->prev) - newline->prev->next = newline; - newline->len = newline->buff_pntr = 0; - newline->line_number = line->line_number; - if (sym->curr_line == sym->lines) - sym->lines = newline; - for (trace = newline->next; trace != 0; trace = trace->next) - trace->line_number++; - } - } - else if (bp == size && - line->len > size) { - /* line->next; */ - newline = alloc_inputline(size); - if (line->next) - line->next->prev = newline; - newline->prev = sym->curr_line; - line->next = newline; - newline->len = 0; - newline->buff_pntr = 0; - sym->num_lines++; - sym->curr_line = newline; - newline->line_number = newline->prev->line_number + 1; - for (trace = newline->next; trace != 0; trace = trace->next) - trace->line_number++; - } - else { - if (line->len > size) - tough_enter(sym); - else { - newline = alloc_inputline(size); - strncpy(newline->buffer, &sym->curr_line->buffer[bp], l - bp); - sym->curr_line->len = bp; - sym->curr_line->buffer[bp] = '\0'; - newline->next = sym->curr_line->next; - if (sym->curr_line->next) - sym->curr_line->next->prev = newline; - newline->prev = sym->curr_line; - sym->curr_line->next = newline; - newline->len = l - bp; - newline->buff_pntr = 0; - sym->num_lines++; - sym->curr_line = newline; - newline->line_number = newline->prev->line_number + 1; - for (trace = newline->next; trace != 0; trace = trace->next) - trace->line_number++; - } - } - redraw_win(); -} - -void -dialog(XEvent *event, KeySym keysym, char *buffer) -{ - InputItem *item; - - item = gWindow->page->current_item; - if (item == 0) { - if (!((keysym >= XK_Shift_L) && (keysym <= XK_Hyper_R))) - /** if something other than a modifier key was hit **/ - BeepAtTheUser(); - return; - } - - - /* - * First check if the user had hit an enter key - */ - - if ((keysym == XK_Return) || (keysym == XK_KP_Enter)) - enter_new_line(item); - /* - * Else did the user actual type a character I can understand - */ - - else if (((keysym >= XK_KP_Space) && (keysym <= XK_KP_9)) - || ((keysym >= XK_space) && (keysym <= XK_asciitilde))) - { - /* only handle normal keys */ - - if (event->xkey.state & ShiftModMask) - BeepAtTheUser(); - else - add_buffer_to_sym(buffer, item); - } - - else if ((keysym >= XK_Shift_L) && (keysym <= XK_Hyper_R)) - ; - - /* - * do nothing, a modifier was hit - */ - - else if ((keysym >= XK_F2) && (keysym <= XK_F35)) { - - /* - * A function key was hit - */ - - if (strlen(buffer) == 0) - BeepAtTheUser(); - else - /* If I got characters then add it to the buffer */ - - add_buffer_to_sym(buffer, item); - } - else - switch (keysym) { - case XK_Escape: - if (event->xkey.state & ModifiersMask) - BeepAtTheUser(); - else { - move_cursor_home(item); - delete_rest_of_line(item); - } - break; - case XK_F1: - if (event->xkey.state & ModifiersMask) - BeepAtTheUser(); - else { - gWindow->page->helppage = alloc_string(InputAreaHelpPage); - helpForHyperDoc(); - } - break; - case XK_Up: - if (event->xkey.state & ModifiersMask) - BeepAtTheUser(); - else - move_cursor_up(item); - break; - case XK_Down: - if (event->xkey.state & ModifiersMask) - BeepAtTheUser(); - else - move_cursor_down(item); - break; - case XK_Delete: - if (event->xkey.state & ModifiersMask) - BeepAtTheUser(); - else - delete_char(item); - break; - case XK_BackSpace: - if (event->xkey.state & ModifiersMask) - BeepAtTheUser(); - else - back_over_char(item); - break; - case XK_Left: - if (event->xkey.state & ModifiersMask) - BeepAtTheUser(); - else - move_cursor_backward(item); - break; - case XK_Right: - if (event->xkey.state & ModifiersMask) - BeepAtTheUser(); - else - move_cursor_forward(item); - break; - case XK_Insert: - if (event->xkey.state & ModifiersMask) - BeepAtTheUser(); - else { - gInInsertMode = ((gInInsertMode) ? (0) : (1)); - item->curr_line->changed = 1; - update_inputsymbol(item); - } - break; - case XK_Home: - if (event->xkey.state & ModifiersMask) - BeepAtTheUser(); - else - move_cursor_home(item); - break; - case XK_End: - if (event->xkey.state & ControlMask) - /* delete from here to the end of the line */ - - delete_rest_of_line(item); - else if (event->xkey.state & ModifiersMask) - BeepAtTheUser(); - else - move_cursor_end(item); - break; - default: - BeepAtTheUser(); - break; - } -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/display.c b/src/hyper/display.c new file mode 100644 index 00000000..9ffe6c96 --- /dev/null +++ b/src/hyper/display.c @@ -0,0 +1,299 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +/****************************************************************************** + * + * display.c: HyperDoc functions to format and display a page. + * + * Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993. + * + ****************************************************************************/ + +/* + * Notes: + * Display is performed in two steps. First the page is formatted + * assuming that we have an infinitely long window. In this stage + * we compute and store the coordinates of every text node. Next + * the page is actually drawn on the screen. In this process we + * use the value of page->y_off as an offset into the scrolling + * region to compute what is actually to be displayed on the page. + */ +#define _DISPLAY_C +#include "axiom-c-macros.h" +#include "useproto.h" +#include "debug.h" + + +#include "extent.h" +#include "hyper.h" +#include "display.h" +#include "group.h" +#include "scrollbar.h" +#include "titlebar.h" + +#include "all_hyper_proto.H1" + + +extern ItemStack *gTopOfItemStack; +short int gDisplayRegion = 0; +int gRegionOffset = 0; + + +/* Display a HyperDoc page in the top-level window */ + +void +show_page(HyperDocPage *page) +{ + XWindowChanges wc; + int doShowScrollBars = 1; + + init_top_group(); + + /* Clear the areas so we can rewrite the page */ + + XClearWindow(gXDisplay, gWindow->fMainWindow); + XClearWindow(gXDisplay, gWindow->fScrollWindow); + + /* Free the active button list */ + + free_button_list(page->s_button_list); + page->s_button_list = NULL; + free_button_list(page->button_list); + page->button_list = NULL; + + /* The compute the text extents */ + compute_title_extent(page); + compute_header_extent(page); + compute_footer_extent(page); + compute_scrolling_extent(page); + + /* + * Now that we have all the extents computed, reconfigure and map the + * scroll window + */ + + if (page->scrolling) { + int width, height; + calculateScrollBarMeasures(); + wc.x = 0; + wc.y = page->top_scroll_margin + scroll_top_margin; + + wc.height = gWindow->scrollheight; + if (gWindow->page->scrolling->height <= gWindow->scrollheight) { + gWindow->page->scroll_off = 0; + wc.width = gWindow->width; + } + else + wc.width = gWindow->width - gScrollbarWidth; + + getScrollBarMinimumSize(&width, &height); + if (height > wc.height) { + wc.height = gWindow->scrollheight = 1; + doShowScrollBars = 0; + } + else + gWindow->scrollwidth = wc.width; + + if (doShowScrollBars) { + XConfigureWindow(gXDisplay, gWindow->fScrollWindow, CWX | CWY | CWHeight | CWWidth, &wc); + XMapWindow(gXDisplay, gWindow->fScrollWindow); + } + else { + XUnmapWindow(gXDisplay, gWindow->fScrollWindow); + hideScrollBars(gWindow); + } + } + /* clear the group stack */ + + while (pop_group_stack() >= 0) + ; + + /* Now start displaying all the text */ + + gWindow->fDisplayedWindow = gWindow->fMainWindow; + gRegionOffset = 0; + y_off = 0; + gDisplayRegion = Header; + show_text(page->header->next, Endheader); + + if (doShowScrollBars && page->scrolling) { + /* Show the footer */ + if (page->footer->next) { + gDisplayRegion = Footer; + gRegionOffset = gWindow->page->bot_scroll_margin + + (!((gWindow->page->page_flags & NOLINES)) ? ((int) line_height / 2) : (0)); + show_text(page->footer->next, Endfooter); + /* Show the scrolling region */ + if (page->scrolling->next) + gDisplayRegion = Scrolling; + gRegionOffset = 0; + gWindow->fDisplayedWindow = gWindow->fScrollWindow; + y_off = gWindow->page->scroll_off; + show_text(page->scrolling->next, Endscrolling); + showScrollBars(gWindow); + } + drawScrollLines(); + } + if (gTopOfItemStack != NULL) { + fprintf(stderr, "warning: unbalanced \\beginitems .. \\enditems\n"); + gTopOfItemStack = NULL; + } + showTitleBar(); + XFlush(gXDisplay); +} + +void +expose_page(HyperDocPage *page) +{ + int width, height, doShowScrollBars = 1; + init_top_group(); + + /* + * Now start displaying all the text + */ + + y_off = 0; + gWindow->fDisplayedWindow = gWindow->fMainWindow; + gRegionOffset = 0; + gDisplayRegion = Header; + show_text(page->header->next, Endheader); + getScrollBarMinimumSize(&width, &height); + + /* + * Now see If I have anything left to display + */ + if (page->scrolling) { + if (page->footer->next) { + gDisplayRegion = Footer; + gRegionOffset = gWindow->page->bot_scroll_margin + + (!((gWindow->page->page_flags & NOLINES)) ? ((int) line_height / 2) : (0)); + show_text(page->footer->next, Endfooter); + } + + if (height > gWindow->scrollheight) { + gWindow->scrollheight = 1; + doShowScrollBars = 0; + XUnmapWindow(gXDisplay, gWindow->fScrollWindow); + hideScrollBars(gWindow); + } + + if (page->scrolling->next) { + gRegionOffset = page->top_scroll_margin; + gDisplayRegion = Scrolling; + gRegionOffset = 0; + gWindow->fDisplayedWindow = gWindow->fScrollWindow; + y_off = gWindow->page->scroll_off; + show_text(page->scrolling->next, Endscrolling); + if (doShowScrollBars) + showScrollBars(gWindow); + } + if (doShowScrollBars) + drawScrollLines(); + } + showTitleBar(); + XFlush(gXDisplay); +} + +void +scroll_page(HyperDocPage *page) +{ + init_top_group(); + /* free the active button list */ + free_button_list(page->s_button_list); + page->s_button_list = NULL; + /** Clear the scrolling area */ + XUnmapSubwindows(gXDisplay, gWindow->fScrollWindow); + gDisplayRegion = Scrolling; + gRegionOffset = 0; + gWindow->fDisplayedWindow = gWindow->fScrollWindow; + y_off = gWindow->page->scroll_off; + show_text(page->scrolling->next, Endscrolling); + moveScroller(gWindow); + XFlush(gXDisplay); +} + +void +paste_page(TextNode *node) +{ + int width, height; + int old_off = gWindow->page->scroll_off; + + /* free the active button list */ + free_button_list(gWindow->page->s_button_list); + gWindow->page->s_button_list = NULL; + free_button_list(gWindow->page->button_list); + gWindow->page->button_list = NULL; + XUnmapSubwindows(gXDisplay, gWindow->fScrollWindow); + + init_top_group(); + + /* recompute the extent of the scrolling region */ + + compute_scrolling_extent(gWindow->page); + + calculateScrollBarMeasures(); + getScrollBarMinimumSize(&width, &height); + + /* get ready to show the scrolling area */ + gRegionOffset = 0; + y_off = gWindow->page->scroll_off; + gDisplayRegion = Scrolling; + gWindow->fDisplayedWindow = gWindow->fScrollWindow; + if (gWindow->page->scroll_off == old_off) { + XClearArea(gXDisplay, gWindow->fScrollWindow, 0, + node->y - line_height + gRegionOffset + y_off, + gWindow->width, + gWindow->scrollheight - node->y + line_height - y_off, + False); + XFlush(gXDisplay); + } + else + XClearWindow(gXDisplay, gWindow->fScrollWindow); + + show_text(gWindow->page->scrolling->next, Endscrolling); + XFlush(gXDisplay); + hideScrollBars(gWindow); + + if (height > gWindow->scrollheight) { + gWindow->scrollheight = 1; + XUnmapWindow(gXDisplay, gWindow->fScrollWindow); + } + else { + showScrollBars(gWindow); + drawScrollLines(); + /* moveScroller(); */ + } + XFlush(gXDisplay); +} diff --git a/src/hyper/display.h b/src/hyper/display.h new file mode 100644 index 00000000..39bcf2a7 --- /dev/null +++ b/src/hyper/display.h @@ -0,0 +1,44 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +#ifndef _DISPLAY_H_ +#define _DISPLAY_H_ 1 + +#include "hyper.h" + +extern short int gDisplayRegion; +extern int gRegionOffset; + +#endif diff --git a/src/hyper/display.pamphlet b/src/hyper/display.pamphlet deleted file mode 100644 index 8bbf3cfc..00000000 --- a/src/hyper/display.pamphlet +++ /dev/null @@ -1,337 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/display} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{display.h} -<>= -<> -#ifndef _DISPLAY_H_ -#define _DISPLAY_H_ 1 - -#include "hyper.h" - -extern short int gDisplayRegion; -extern int gRegionOffset; - -#endif -@ -\section{display.c} -<>= -/****************************************************************************** - * - * display.c: HyperDoc functions to format and display a page. - * - * Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993. - * - ****************************************************************************/ - -/* - * Notes: - * Display is performed in two steps. First the page is formatted - * assuming that we have an infinitely long window. In this stage - * we compute and store the coordinates of every text node. Next - * the page is actually drawn on the screen. In this process we - * use the value of page->y_off as an offset into the scrolling - * region to compute what is actually to be displayed on the page. - */ -#define _DISPLAY_C -#include "axiom-c-macros.h" -#include "useproto.h" -#include "debug.h" - - -#include "extent.h" -#include "mem.h" -#include "display.h" -#include "group.h" -#include "scrollbar.h" -#include "titlebar.h" -#include "show-types.h" - -#include "all_hyper_proto.H1" - - -extern ItemStack *gTopOfItemStack; -short int gDisplayRegion = 0; -int gRegionOffset = 0; - - -/* Display a HyperDoc page in the top-level window */ - -void -show_page(HyperDocPage *page) -{ - XWindowChanges wc; - int doShowScrollBars = 1; - - init_top_group(); - - /* Clear the areas so we can rewrite the page */ - - XClearWindow(gXDisplay, gWindow->fMainWindow); - XClearWindow(gXDisplay, gWindow->fScrollWindow); - - /* Free the active button list */ - - free_button_list(page->s_button_list); - page->s_button_list = NULL; - free_button_list(page->button_list); - page->button_list = NULL; - - /* The compute the text extents */ - compute_title_extent(page); - compute_header_extent(page); - compute_footer_extent(page); - compute_scrolling_extent(page); - - /* - * Now that we have all the extents computed, reconfigure and map the - * scroll window - */ - - if (page->scrolling) { - int width, height; - calculateScrollBarMeasures(); - wc.x = 0; - wc.y = page->top_scroll_margin + scroll_top_margin; - - wc.height = gWindow->scrollheight; - if (gWindow->page->scrolling->height <= gWindow->scrollheight) { - gWindow->page->scroll_off = 0; - wc.width = gWindow->width; - } - else - wc.width = gWindow->width - gScrollbarWidth; - - getScrollBarMinimumSize(&width, &height); - if (height > wc.height) { - wc.height = gWindow->scrollheight = 1; - doShowScrollBars = 0; - } - else - gWindow->scrollwidth = wc.width; - - if (doShowScrollBars) { - XConfigureWindow(gXDisplay, gWindow->fScrollWindow, CWX | CWY | CWHeight | CWWidth, &wc); - XMapWindow(gXDisplay, gWindow->fScrollWindow); - } - else { - XUnmapWindow(gXDisplay, gWindow->fScrollWindow); - hideScrollBars(gWindow); - } - } - /* clear the group stack */ - - while (pop_group_stack() >= 0) - ; - - /* Now start displaying all the text */ - - gWindow->fDisplayedWindow = gWindow->fMainWindow; - gRegionOffset = 0; - y_off = 0; - gDisplayRegion = Header; - show_text(page->header->next, Endheader); - - if (doShowScrollBars && page->scrolling) { - /* Show the footer */ - if (page->footer->next) { - gDisplayRegion = Footer; - gRegionOffset = gWindow->page->bot_scroll_margin + - (!((gWindow->page->page_flags & NOLINES)) ? ((int) line_height / 2) : (0)); - show_text(page->footer->next, Endfooter); - /* Show the scrolling region */ - if (page->scrolling->next) - gDisplayRegion = Scrolling; - gRegionOffset = 0; - gWindow->fDisplayedWindow = gWindow->fScrollWindow; - y_off = gWindow->page->scroll_off; - show_text(page->scrolling->next, Endscrolling); - showScrollBars(gWindow); - } - drawScrollLines(); - } - if (gTopOfItemStack != NULL) { - fprintf(stderr, "warning: unbalanced \\beginitems .. \\enditems\n"); - gTopOfItemStack = NULL; - } - showTitleBar(); - XFlush(gXDisplay); -} - -void -expose_page(HyperDocPage *page) -{ - int width, height, doShowScrollBars = 1; - init_top_group(); - - /* - * Now start displaying all the text - */ - - y_off = 0; - gWindow->fDisplayedWindow = gWindow->fMainWindow; - gRegionOffset = 0; - gDisplayRegion = Header; - show_text(page->header->next, Endheader); - getScrollBarMinimumSize(&width, &height); - - /* - * Now see If I have anything left to display - */ - if (page->scrolling) { - if (page->footer->next) { - gDisplayRegion = Footer; - gRegionOffset = gWindow->page->bot_scroll_margin + - (!((gWindow->page->page_flags & NOLINES)) ? ((int) line_height / 2) : (0)); - show_text(page->footer->next, Endfooter); - } - - if (height > gWindow->scrollheight) { - gWindow->scrollheight = 1; - doShowScrollBars = 0; - XUnmapWindow(gXDisplay, gWindow->fScrollWindow); - hideScrollBars(gWindow); - } - - if (page->scrolling->next) { - gRegionOffset = page->top_scroll_margin; - gDisplayRegion = Scrolling; - gRegionOffset = 0; - gWindow->fDisplayedWindow = gWindow->fScrollWindow; - y_off = gWindow->page->scroll_off; - show_text(page->scrolling->next, Endscrolling); - if (doShowScrollBars) - showScrollBars(gWindow); - } - if (doShowScrollBars) - drawScrollLines(); - } - showTitleBar(); - XFlush(gXDisplay); -} - -void -scroll_page(HyperDocPage *page) -{ - init_top_group(); - /* free the active button list */ - free_button_list(page->s_button_list); - page->s_button_list = NULL; - /** Clear the scrolling area */ - XUnmapSubwindows(gXDisplay, gWindow->fScrollWindow); - gDisplayRegion = Scrolling; - gRegionOffset = 0; - gWindow->fDisplayedWindow = gWindow->fScrollWindow; - y_off = gWindow->page->scroll_off; - show_text(page->scrolling->next, Endscrolling); - moveScroller(gWindow); - XFlush(gXDisplay); -} - -void -paste_page(TextNode *node) -{ - int width, height; - int old_off = gWindow->page->scroll_off; - - /* free the active button list */ - free_button_list(gWindow->page->s_button_list); - gWindow->page->s_button_list = NULL; - free_button_list(gWindow->page->button_list); - gWindow->page->button_list = NULL; - XUnmapSubwindows(gXDisplay, gWindow->fScrollWindow); - - init_top_group(); - - /* recompute the extent of the scrolling region */ - - compute_scrolling_extent(gWindow->page); - - calculateScrollBarMeasures(); - getScrollBarMinimumSize(&width, &height); - - /* get ready to show the scrolling area */ - gRegionOffset = 0; - y_off = gWindow->page->scroll_off; - gDisplayRegion = Scrolling; - gWindow->fDisplayedWindow = gWindow->fScrollWindow; - if (gWindow->page->scroll_off == old_off) { - XClearArea(gXDisplay, gWindow->fScrollWindow, 0, - node->y - line_height + gRegionOffset + y_off, - gWindow->width, - gWindow->scrollheight - node->y + line_height - y_off, - False); - XFlush(gXDisplay); - } - else - XClearWindow(gXDisplay, gWindow->fScrollWindow); - - show_text(gWindow->page->scrolling->next, Endscrolling); - XFlush(gXDisplay); - hideScrollBars(gWindow); - - if (height > gWindow->scrollheight) { - gWindow->scrollheight = 1; - XUnmapWindow(gXDisplay, gWindow->fScrollWindow); - } - else { - showScrollBars(gWindow); - drawScrollLines(); - /* moveScroller(); */ - } - XFlush(gXDisplay); -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} diff --git a/src/hyper/event.c b/src/hyper/event.c new file mode 100644 index 00000000..5066fc1e --- /dev/null +++ b/src/hyper/event.c @@ -0,0 +1,1062 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +#define _EVENT_C +#include "axiom-c-macros.h" +#include "useproto.h" +#include "debug.h" + + +#include "hyper.h" + +#include +#include +#include +#include +#include +#include +#include + +#ifdef SGIplatform +#include +#endif + +#include "event.h" +#include "keyin.h" +#include "hyper.h" +#include "display.h" +#include "parse.h" +#include "parse-paste.h" +#include "initx.h" +#include "scrollbar.h" +#include "group.h" + +#include "all_hyper_proto.H1" +#include "sockio-c.H1" + +jmp_buf env; +Window gActiveWindow; +int motion = 0; +int gNeedIconName = 0; +unsigned long bigmask= 0xffffffff; +static HyperLink *gSavedInputAreaLink = NULL; + + + +/* + * This is the main X loop. It keeps grabbing events. Since the only way the + * window can die is through an event, it never actually end. One of the + * subroutines it calls is responsible for killing everything + */ + +void +mainEventLoop(void) +{ + XEvent event; + int Xcon; + fd_set rd, dum1, dum2; + motion = 0; + gActiveWindow = -1; + set_error_handlers(); + Xcon = ConnectionNumber(gXDisplay); + + while (1) { +/* fprintf(stderr,"event:mainEventLoop: loop top\n");*/ + while (gSessionHashTable.num_entries == 0) + pause(); + + /* XFlush(gXDisplay); */ + + if (!motion) + init_cursor_states(); + motion = 0; + + if (!spad_socket == 0) { + FD_ZERO(&rd); + FD_ZERO(&dum1); + FD_ZERO(&dum2); + FD_CLR(0, &dum1); + FD_CLR(0, &dum2); + FD_CLR(0, &rd); + FD_SET(spad_socket->socket, &rd); + FD_SET(Xcon, &rd); + if (!session_server == 0) { + FD_SET(session_server->socket, &rd); + } + if (XEventsQueued(gXDisplay, QueuedAlready)) { + XNextEvent(gXDisplay, &event); + handle_event(&event); + } + else { + select(FD_SETSIZE,(void *)&rd,(void *)&dum1,(void *)&dum2,NULL); + if (FD_ISSET(Xcon, &rd) || + XEventsQueued(gXDisplay, QueuedAfterFlush)) { + XNextEvent(gXDisplay, &event); + handle_event(&event); + } + else if FD_ISSET + (spad_socket->socket, &rd) + /* + * Axiom Socket do what handle_event does The 100 is + * $SpadStuff in hypertex.boot + */ + { + if (100 == get_int(spad_socket)) { + set_window(gParentWindow->fMainWindow); + make_busy_cursors(); + get_new_window(); + } + } + /* + * Session Socket Telling us about the death of a spadbuf + * (plus maybe more later) service_session_socket in + * spadint.c + */ + else + if (session_server && FD_ISSET(session_server->socket, &rd)) { + service_session_socket(); + } + } + } + else { + XNextEvent(gXDisplay, &event); + handle_event(&event); + } + } +} + +static void +handle_event(XEvent * event) +{ + XWindowAttributes wa; +/* fprintf(stderr,"event:handle_event entered\n");*/ + set_window(event->xany.window); + if (event->type == MotionNotify) { +/* fprintf(stderr,"event:handle_event type=MotionNotify\n");*/ + handle_motion_event((XMotionEvent *)event); + motion = 1; + return; + } + make_busy_cursors(); + switch (event->type) { + case DestroyNotify: +/* fprintf(stderr,"event:handle_event type=DestroyNotify\n");*/ + break; + case Expose: +/* fprintf(stderr,"event:handle_event type=Expose\n");*/ + XGetWindowAttributes(gXDisplay, gWindow->fMainWindow, &wa); + if ((gWindow->width == 0 && gWindow->height == 0) || + (wa.width != gWindow->width || wa.height != gWindow->height)) { + gWindow->width = wa.width; + gWindow->height = wa.height; + display_page(gWindow->page); + gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; + } + else /** just redraw the thing **/ + expose_page(gWindow->page); + XFlush(gXDisplay); + clear_exposures(gWindow->fMainWindow); + clear_exposures(gWindow->fScrollWindow); + break; + case ButtonPress: +/* fprintf(stderr,"event:handle_event type=ButtonPress\n");*/ + handle_button(event->xbutton.button, (XButtonEvent *)event); + XFlush(gXDisplay); + if (gWindow) { + while (XCheckTypedWindowEvent(gXDisplay, gWindow->fMainWindow, + Expose, event)); + while (XCheckTypedWindowEvent(gXDisplay, gWindow->fScrollWindow, + Expose, event)); + } + break; + case KeyPress: +/* fprintf(stderr,"event:handle_event type=KeyPress\n");*/ + handle_key(event); + if (gWindow) { + while (XCheckTypedWindowEvent(gXDisplay, gWindow->fMainWindow, + Expose, event)); + while (XCheckTypedWindowEvent(gXDisplay, gWindow->fScrollWindow, + Expose, event)); + } + break; + case MapNotify: +/* fprintf(stderr,"event:handle_event type=MapNotify\n");*/ + create_window(); + break; + + case SelectionNotify: +/* fprintf(stderr,"event:handle_event type=SelectionNotify\n");*/ + /* this is in response to a previous request in an input area */ + if ( gSavedInputAreaLink ) { + XSelectionEvent *pSelEvent; + Atom dataProperty; + pSelEvent = (XSelectionEvent *) event; + dataProperty = XInternAtom(gXDisplay, "PASTE_SELECTION", False); + /* change the input focus */ + + /* change_input_focus(gSavedInputAreaLink); */ + + /* try to get the selection as a window property */ + + if ( pSelEvent->requestor == gWindow->fMainWindow && + pSelEvent->selection == XA_PRIMARY && + /* pSelEvent->time == CurrentTime && */ + pSelEvent->target == XA_STRING && + pSelEvent->property == dataProperty ) + { + Atom actual_type; + int actual_format; + unsigned long nitems, leftover; + char *pSelection = NULL; + + if (Success == XGetWindowProperty(gXDisplay, + gWindow->fMainWindow, + pSelEvent->property, 0L, 100000000L, True, + AnyPropertyType, &actual_type, &actual_format, + &nitems, &leftover, (unsigned char **) &pSelection) ) + { + char *pBuffer; + InputItem *item = gSavedInputAreaLink->reference.string; + + for (pBuffer = pSelection; *pBuffer; ++pBuffer) + add_buffer_to_sym(pBuffer, item); + + XFree(pSelection); + } + } + + /* clear the link info */ + + gSavedInputAreaLink = NULL; + } + break; + + default: +/* fprintf(stderr,"event:handle_event type=default\n");*/ + break; + } + +} + +static void +create_window(void) +{ + XWindowAttributes wa; + + XGetWindowAttributes(gXDisplay, gWindow->fMainWindow, &wa); + + gWindow->width = wa.width; + gWindow->height = wa.height; + display_page(gWindow->page); + gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; + + /* then select for the events I normally would like to catch */ + XSelectInput(gXDisplay, gWindow->fMainWindow, ButtonPress | KeyPressMask | + PointerMotionMask | + ExposureMask /* | EnterWindowMask | LeaveWindowMask */ ); + XSelectInput(gXDisplay, gWindow->fScrollWindow, ExposureMask); + +} + +/* + * This routine is called when the quitbutton is hit. For the moment I am + * just going to leave it all behind + */ + +void +quitHyperDoc(void) +{ + HyperDocPage *page; + + if (gSessionHashTable.num_entries == 1 || gParentWindow == gWindow) { + if (!strcmp(gWindow->page->name, "ProtectedQuitPage")){ + exitHyperDoc(); + } + page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, "ProtectedQuitPage"); + if (page == NULL) { + fprintf(stderr, "Unknown page name %s\n", "ProtectedQuitPage"); + exitHyperDoc(); + return; + } + if (gWindow->fDownLinkStackIndex == MaxDownlinkDepth) + fprintf(stderr, "exceeded maximum link nesting level\n"); + else + gWindow->fDownLinkStack[gWindow->fDownLinkStackIndex++] = gWindow->page; + gWindow->page = page; + display_page(gWindow->page); + gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; + } + else + exitHyperDoc(); +} + + +/* + * find_page takes as an argument the HyperDoc for a page name and returns + * the associated page + */ + +static HyperDocPage * +find_page(TextNode * node) +{ + char *page_name; + HyperDocPage *page; + + /* try and find the page name */ + page_name = print_to_string(node); + page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, page_name); + + if (page == NULL) { + /* try to find the unknown page */ + page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, "UnknownPage"); + if (page == NULL) { + /* Yikes, Even that could not be found */ + fprintf(stderr, "Unknown page name %s\n", page_name); + } + else { + if (page->type == UnloadedPageType) + page->type = UlUnknownPage; + else + page->type = UnknownPage; + } + } + return page; +} + +/* + * These are macros for taking care of the downlink stack, and the memolink + * stack. + */ + +#define NotSpecial(t) ((t == Quitbutton || t == Returnbutton || \ + t == Upbutton || t == UnknownPage || \ + t == UlUnknownPage || t == ErrorPage) ?(0):(1)) + +/* pushes a page onto the down link stack */ + +static void +downlink(void) +{ + if (gWindow->fDownLinkStackIndex == MaxDownlinkDepth) + fprintf(stderr, "exceeded maximum link nesting level\n"); + else + gWindow->fDownLinkStack[gWindow->fDownLinkStackIndex++] = gWindow->page; +} + +static void +memolink(void) +{ + if (gWindow->fMemoStackIndex == MaxMemoDepth) + fprintf(stderr, "exceeded maximum link nesting level\n"); + else { + gWindow->fMemoStack[gWindow->fMemoStackIndex] = gWindow->page; + gWindow->fDownLinkStackTop[gWindow->fMemoStackIndex++] = gWindow->fDownLinkStackIndex; + } +} + +static void +killAxiomPage(HyperDocPage * page) +{ + char command[512]; + + sprintf(command, "(|htpDestroyPage| '%s)", page->name); + send_lisp_command(command); +} + +static void +kill_page(HyperDocPage * page) +{ + page->scroll_off = 0; + if (page->type == SpadGen) { + hash_delete(gWindow->fPageHashTable, page->name); + killAxiomPage(page); + free_page(page); + } +} + +/* pops the memo stack */ + +static HyperDocPage * +returnlink(void) +{ + int i; + + if (gWindow->fMemoStackIndex == 0) { + BeepAtTheUser(); + return NULL; + } + else { + kill_page(gWindow->page); + for (i = gWindow->fDownLinkStackIndex - 1; + i >= gWindow->fDownLinkStackTop[gWindow->fMemoStackIndex - 1]; + i--) + { + kill_page(gWindow->fDownLinkStack[i]); + } + gWindow->fDownLinkStackIndex = + gWindow->fDownLinkStackTop[--gWindow->fMemoStackIndex]; + return (gWindow->fMemoStack[gWindow->fMemoStackIndex]); + } +} + +/* pops a page if it can from the downlink stack */ + +static HyperDocPage * +uplink(void) +{ + if (gWindow->fDownLinkStackIndex == 0) + return returnlink(); + else { + kill_page(gWindow->page); + return (gWindow->fDownLinkStack[--gWindow->fDownLinkStackIndex]); + } +} + +static void +windowlink_handler(TextNode * node) +{ + char *page_name; + + /* first try and find the page */ + page_name = print_to_string(node); + + if (init_top_window(page_name) == -1) { + return; + } +/* gWindow->fWindowHashTable = gWindow->page->fLinkHashTable;*/ +} + +void +make_window_link(char *name) +{ + if (init_top_window(name) != -1) +{}/* gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; */ +} + + +static void +lispwindowlink_handler(HyperLink * link) +{ + + /* + * Since we are popping up a new window, then we had better change all + * the cursors right away. We won't get another chance at it. + */ + + if (init_top_window(NULL) != -1) { + HyperDocPage *page = NULL; + int frame = gWindow->fAxiomFrame; + + page = issue_server_command(link); + gWindow->fAxiomFrame = frame; + gWindow->page = page; +/* gWindow->fWindowHashTable = gWindow->page->fLinkHashTable;*/ + } +} + +static HyperDocPage * +paste_button(PasteNode * paste) +{ + HyperDocPage *page = NULL; + int pastewhere=paste->where; + + + if ( paste->end_node ==NULL || paste->begin_node==NULL || paste->arg_node==NULL ){ + BeepAtTheUser(); + return NULL; + } + + page=parse_patch(paste); +/* paste has changed after this call so use pastewhere*/ + + if (pastewhere && page ) { + if (0 == strcmp(page->name, "ErrorPage")) + page = NULL; + } + else + BeepAtTheUser(); + + return page; +} + +void +helpForHyperDoc(void) +{ + HyperDocPage *page = NULL; + + /* do not do anything if we are already at the "no more help" page */ + + if (0 == strcmp(gWindow->page->name, NoMoreHelpPage)) + return; + + /* if no help page recorded, use the standard "no more help" page */ + + if (!gWindow->page->helppage) + gWindow->page->helppage = alloc_string(NoMoreHelpPage); + + /* if we are on the main help page, use "no more help" page */ + + if (0 == strcmp(gWindow->page->name, TopLevelHelpPage)) + gWindow->page->helppage = alloc_string(NoMoreHelpPage); + + page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, gWindow->page->helppage); + + if (page) + make_window_link(gWindow->page->helppage); + else + BeepAtTheUser(); +} + +static HyperLink * +findButtonInList(HDWindow * window, int x, int y) +{ + ButtonList *bl; + + if (!window || window->page->type == UnloadedPageType) + return NULL; + for (bl = window->page->s_button_list; bl != NULL; bl = bl->next) + if (x >= bl->x0 && x <= bl->x1 && y >= bl->y0 && y <= bl->y1) + return bl->link; + for (bl = window->page->button_list; bl != NULL; bl = bl->next) + if (x >= bl->x0 && x <= bl->x1 && y >= bl->y0 && y <= bl->y1) + return bl->link; + return NULL; +} + +static HyperLink * +get_hyper_link(XButtonEvent * event) +{ + HyperLink *l1, *l2; + + l1 = (HyperLink *) hash_find(gWindow->fWindowHashTable, (char *)&(event->window)); + if (l1) + return l1; + l2 = findButtonInList(gWindow, event->x, event->y); + return l2; +} + +/* + * Handle a button pressed event. window is the subwindow in which the event + * occured, and button is the button which was pressed + */ + +static void +handle_button(int button, XButtonEvent * event) +{ + HyperLink *link; + HyperDocPage *page = NULL; + char *page_name; + + /* find page name from sub-window handle */ + + link = get_hyper_link(event); + + if (link == NULL) { /* user clicked on an inactive area */ +/* BeepAtTheUser(); */ /* I always thought this was annoying. RSS */ + return; + } + + switch (link->type) { + case Pastebutton: + page = paste_button(link->reference.paste); + break; + case Link: + page_name = print_to_string(link->reference.node); + page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, page_name); + break; + case Helpbutton: + helpForHyperDoc(); + page = NULL; + break; + case Scrollbar: + scrollScroller(event); + break; + case Scrollupbutton: + scrollUp(); + break; + case Scrolldownbutton: + scrollDown(); + break; + + case Inputstring: + /* We must be changing input focus or getting a selection */ + + change_input_focus(link); + if ( button == Button2 ) { + XConvertSelection(gXDisplay, XA_PRIMARY, XA_STRING, + XInternAtom(gXDisplay, "PASTE_SELECTION", False), + gWindow->fMainWindow, CurrentTime); + gSavedInputAreaLink = link; + } + break; + + case SimpleBox: + page = NULL; + toggle_input_box(link); + break; + case Radiobox: + page = NULL; + toggle_radio_box(link); + break; + case Quitbutton: + quitHyperDoc(); + break; + case Returnbutton: /* pop memo information */ + page = returnlink(); + break; + case Upbutton: /* pop downlink information */ + page = uplink(); + break; + case Downlink: + page = find_page(link->reference.node); + if (page && NotSpecial(page->type)) + downlink(); + break; + case Memolink: + page = find_page(link->reference.node); + if (page && NotSpecial(page->type)) + memolink(); + break; + case Windowlink: + page = find_page(link->reference.node); + if (page && NotSpecial(page->type)) { + windowlink_handler(link->reference.node); + gNeedIconName = 1; + page = NULL; + } + break; + case Lispwindowlink: + lispwindowlink_handler(link); + gNeedIconName = 1; + page = NULL; + break; + case LispMemoLink: + case Spadmemolink: + page = issue_server_command(link); + if (page && NotSpecial(page->type)) + memolink(); + break; + case LispDownLink: + case Spaddownlink: + page = issue_server_command(link); + if (page && NotSpecial(page->type)) + downlink(); + break; + case Spadlink: + case Lisplink: + page = issue_server_command(link); + break; + case Lispcommand: + case Qspadcall: + case Spadcall: + page = issue_server_command(link); + break; + case Lispcommandquit: + case Spadcallquit: + case Qspadcallquit: + page = issue_server_command(link); + exitHyperDoc(); + break; + case Spadcommand: + case Spadgraph: + case Spadsrc: + issue_spadcommand(gWindow->page, link->reference.node, + button == Button1, link->type); + break; + case Unixlink: + page = issue_unixlink(link->reference.node); + if (page && NotSpecial(page->type)) { + downlink(); + } + break; + case Unixcommand: + issue_unixcommand(link->reference.node); + break; + default: + break; + } + + if (page) { + switch (page->type) { /* check for special button types */ + case Quitbutton: + exitHyperDoc(); + return; + case Returnbutton: + gWindow->page = returnlink(); + break; + case Upbutton: + gWindow->page = uplink(); + break; + case ErrorPage: + case UnknownPage: + case UlUnknownPage: + if (page->type == UlUnknownPage) + page->type = UnloadedPageType; + downlink(); + gWindow->page = page; + break; + default: /* a normal link */ + gWindow->page = page; + break; + } + if (link->type != Pastebutton) + display_page(gWindow->page); + gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; /* reset the window hash */ + } +} + + +void +exitHyperDoc(void) +{ + XEvent event; + + + if (gSessionHashTable.num_entries == 1 || gParentWindow == gWindow) { + free_hd_window(gWindow); + exit(0); + } + hash_delete(&gSessionHashTable, (char *)&gWindow->fMainWindow); + + /* + * Now we quickly want to flush all the events associated with this + * window from existence + */ + + XFlush(gXDisplay); + while (XCheckWindowEvent(gXDisplay, gWindow->fMainWindow, bigmask, &event)) { + } + while (XCheckWindowEvent(gXDisplay, gWindow->fScrollWindow,bigmask, &event)) { + } + while (XCheckWindowEvent(gXDisplay, gWindow->fDisplayedWindow, bigmask, &event)) { + } + while (XCheckWindowEvent(gXDisplay, gWindow->fScrollUpWindow, bigmask, &event)) { + } + while (XCheckWindowEvent(gXDisplay, gWindow->fScrollDownWindow, bigmask, &event)) { + } + while (XCheckWindowEvent(gXDisplay, gWindow->scrollbar, bigmask, &event)) { + } + while (XCheckWindowEvent(gXDisplay, gWindow->scroller, bigmask, &event)) { + } + + XDestroyWindow(gXDisplay, gWindow->fMainWindow); + free_hd_window(gWindow); + gWindow = NULL; + gActiveWindow = -1; + XFlush(gXDisplay); +} + +static int +set_window(Window window) +{ + Window root, parent, *children, grandparent,myarg; + HDWindow *htw; + unsigned int nchildren; + int st; + + myarg=window; + nchildren = 0; + htw = (HDWindow *) hash_find(&gSessionHashTable, (char *)&myarg); + if (htw != NULL) { + gWindow = htw; + return 1; + } + st = XQueryTree(gXDisplay, myarg, &root, &parent, &children, &nchildren); + if (st==0) goto ERROR; + if (nchildren > 0) + XFree(children); + htw = (HDWindow *) hash_find(&gSessionHashTable, (char *)&parent); + if (htw != NULL) { + gWindow = htw; + return 1; + + } + else { + /* check for a grandparent */ + st = XQueryTree(gXDisplay, parent, &root, &grandparent, &children, &nchildren); + if (st==0) goto ERROR; + if (nchildren > 0) + XFree(children); + htw = (HDWindow *) hash_find(&gSessionHashTable, (char *)&grandparent); + if (htw != NULL) { + gWindow = htw; + return 1; + } + } + + /* + * fprintf(stderr, "window(%d) and it's parent(%d) aren't in + * gSessionHashTable\n", window, parent); + + we never found that window. this happens if (not iff) we exit from + an unfocused non-main window under certain wm's and click-to-type. the program returns here with + the window handle that was just destroyed. So let's set the global gWindow + to the main window. + */ + +ERROR: + gWindow=gParentWindow; + return 0; +} + +/* + * This procedure whips thru the stack and clears all expose events for the + * given routine + */ +static void +clear_exposures(Window w) +{ + XEvent report; + + XFlush(gXDisplay); + while (XCheckTypedWindowEvent(gXDisplay, w, Expose, &report)); +} +void +get_new_window(void) +{ + + int val; + char buf[128]; + int frame; + Window wid; + HDWindow *htw; + HyperDocPage *hpage; + + + /* + * If I am going to try and start a new window, then I should make sure I + * have a coonection to listen on + * + * BUT This code is entered when a socket selects + * + * if (spad_socket == NULL) { spad_socket = + * connect_to_local_server(SpadServer, MenuServer, 10); if (spad_socket + * == NULL) { fprintf(stderr, "Get_new_window: Couldn't Connect to + * SpadServer\n"); return -1; } } + * + */ + + + frame = get_int(spad_socket); + val = get_int(spad_socket); + switch (val) { + case StartPage: + init_top_window(NULL); + val = get_int(spad_socket); + init_scanner(); + input_type = FromSpadSocket; + input_string = ""; + gWindow->page = parse_page_from_socket(); + gWindow->fAxiomFrame = frame; + XFlush(gXDisplay); + break; + case LinkToPage: + get_string_buf(spad_socket, buf, 128); + if (init_top_window(buf) == -1) { + fprintf(stderr, "get_new_window: Did not find page %s\n", buf); + /* return -1; */ + } + gWindow->fAxiomFrame = frame; + break; + case PopUpPage: + val = get_int(spad_socket); + init_form_window(NULL, val); + send_int(spad_socket, gWindow->fMainWindow); + init_scanner(); + input_type = FromSpadSocket; + input_string = ""; + gWindow->page = parse_page_from_socket(); + compute_form_page(gWindow->page); + + XMapWindow(gXDisplay, gWindow->fMainWindow); + + gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; + gWindow->fAxiomFrame = frame; + XFlush(gXDisplay); + break; + case PopUpNamedPage: + val = get_int(spad_socket); + get_string_buf(spad_socket, buf, 128); + + if (init_form_window(buf, val) == -1) { + send_int(spad_socket, -1); + break; + } + load_page(gWindow->page); + compute_form_page(gWindow->page); + + XMapWindow(gXDisplay, gWindow->fMainWindow); + + gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; + gWindow->fAxiomFrame = frame; + XFlush(gXDisplay); + send_int(spad_socket, gWindow->fMainWindow); + /* fprintf(stderr, "Window Id was %d\n", gWindow->fMainWindow); */ + break; + case ReplaceNamedPage: + wid = (Window) get_int(spad_socket); + get_string_buf(spad_socket, buf, 128); + + htw = (HDWindow *) hash_find(&gSessionHashTable,(char *)&wid); + if (htw == NULL) break; + hpage = (HyperDocPage *) hash_find(gWindow->fPageHashTable, buf); + if (hpage == NULL) break; + gWindow = htw; + gWindow->page = hpage; + display_page(gWindow->page); + gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; + clear_exposures(gWindow->fMainWindow); + clear_exposures(gWindow->fScrollWindow); + XFlush(gXDisplay); + break; + case ReplacePage: + wid = (Window) get_int(spad_socket); + set_window(wid); + init_scanner(); + input_type = FromSpadSocket; + input_string = ""; + gWindow->page = parse_page_from_socket(); + display_page(gWindow->page); + gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; + clear_exposures(gWindow->fMainWindow); + clear_exposures(gWindow->fScrollWindow); + XFlush(gXDisplay); + break; + case KillPage: + /* Here the user wishes to kill the page */ + wid = (Window) get_int(spad_socket); + htw = (HDWindow *) hash_find(&gSessionHashTable,(char *)&wid); + if (htw !=NULL) { + gWindow = htw; + exitHyperDoc(); + break; + } + break; + } + } +static void +set_cursor(HDWindow *window,Cursor state) +{ + if (state == gBusyCursor) + XDefineCursor(gXDisplay, window->fMainWindow, gBusyCursor); + else if (state == gActiveCursor) + XDefineCursor(gXDisplay, window->fMainWindow, gActiveCursor); + else + XDefineCursor(gXDisplay, window->fMainWindow, gNormalCursor); + XFlush(gXDisplay); +} + +static void +change_cursor(Cursor state, HDWindow *window) +{ + if (window->fDisplayedCursor == state) + return; + window->fDisplayedCursor = state; + set_cursor(window, state); +} + +static void +handle_motion_event(XMotionEvent *event) +{ + if (!gWindow) + return; + if (findButtonInList(gWindow, event->x, event->y) != NULL) + change_cursor(gActiveCursor, gWindow); + else + change_cursor(gNormalCursor, gWindow); +} + +static void +init_cursor_state(HDWindow *window) +{ + if (window) { + int x, y, rx, ry, but; + Window r, c; + + XQueryPointer(gXDisplay, window->fMainWindow, + &r, &c, &rx, &ry, &x, &y,(unsigned int *) &but); + if (findButtonInList(window, x, y) != NULL) + change_cursor(gActiveCursor, window); + else + change_cursor(gNormalCursor, window); + } +} + +static void +init_cursor_states(void) +{ + hash_map(&gSessionHashTable,(MappableFunction) init_cursor_state); +} + + +static void +make_busy_cursor(HDWindow *window) +{ + change_cursor(gBusyCursor, window); +} + +static void +make_busy_cursors(void) +{ + hash_map(&gSessionHashTable, (MappableFunction)make_busy_cursor); +} + +static int +HyperDocErrorHandler(Display *display, XErrorEvent *xe) +{ + if (xe->request_code != 15) { + char buf[1024]; + + XGetErrorText(display, xe->error_code, buf, sizeof(buf)); + + fprintf(stderr, "error code = %d\n", xe->error_code); + fprintf(stderr, "major op code = %d\n", xe->request_code); + fprintf(stderr, "minor op code = %d\n", xe->minor_code); + fprintf(stderr, "XID = %ld\n", xe->resourceid); + fprintf(stderr, "%s\n", buf); + + if (xe->request_code != 15) + exit(-1); + } + return(0); +} + + + +static void +set_error_handlers(void) +{ + XSetErrorHandler(HyperDocErrorHandler); +} diff --git a/src/hyper/event.h b/src/hyper/event.h new file mode 100644 index 00000000..517fc3ea --- /dev/null +++ b/src/hyper/event.h @@ -0,0 +1,44 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + All rights reserbed. + + 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. +*/ + +#ifndef _EVENT_H_ +#define _EVENT_H_ 1 + +#include "hyper.h" + +extern Window gActiveWindow; +extern int gNeedIconName; + +#endif diff --git a/src/hyper/event.pamphlet b/src/hyper/event.pamphlet deleted file mode 100644 index 3dcb69ff..00000000 --- a/src/hyper/event.pamphlet +++ /dev/null @@ -1,1099 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/event} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{event.h} -<>= -<> -#ifndef _EVENT_H_ -#define _EVENT_H_ 1 - -#include "hyper.h" - -extern Window gActiveWindow; -extern int gNeedIconName; - -#endif -@ -\section{event.c} -<>= -#define _EVENT_C -#include "axiom-c-macros.h" -#include "useproto.h" -#include "debug.h" - - -#include "hyper.h" - -#include -#include -#include -#include -#include -#include -#include - -#ifdef SGIplatform -#include -#endif - -#include "event.h" -#include "keyin.h" -#include "mem.h" -#include "display.h" -#include "parse.h" -#include "parse-paste.h" -#include "initx.h" -#include "scrollbar.h" -#include "group.h" - -#include "all_hyper_proto.H1" -#include "sockio-c.H1" - -jmp_buf env; -Window gActiveWindow; -int motion = 0; -int gNeedIconName = 0; -unsigned long bigmask= 0xffffffff; -static HyperLink *gSavedInputAreaLink = NULL; - - - -/* - * This is the main X loop. It keeps grabbing events. Since the only way the - * window can die is through an event, it never actually end. One of the - * subroutines it calls is responsible for killing everything - */ - -void -mainEventLoop(void) -{ - XEvent event; - int Xcon; - fd_set rd, dum1, dum2; - motion = 0; - gActiveWindow = -1; - set_error_handlers(); - Xcon = ConnectionNumber(gXDisplay); - - while (1) { -/* fprintf(stderr,"event:mainEventLoop: loop top\n");*/ - while (gSessionHashTable.num_entries == 0) - pause(); - - /* XFlush(gXDisplay); */ - - if (!motion) - init_cursor_states(); - motion = 0; - - if (!spad_socket == 0) { - FD_ZERO(&rd); - FD_ZERO(&dum1); - FD_ZERO(&dum2); - FD_CLR(0, &dum1); - FD_CLR(0, &dum2); - FD_CLR(0, &rd); - FD_SET(spad_socket->socket, &rd); - FD_SET(Xcon, &rd); - if (!session_server == 0) { - FD_SET(session_server->socket, &rd); - } - if (XEventsQueued(gXDisplay, QueuedAlready)) { - XNextEvent(gXDisplay, &event); - handle_event(&event); - } - else { - select(FD_SETSIZE,(void *)&rd,(void *)&dum1,(void *)&dum2,NULL); - if (FD_ISSET(Xcon, &rd) || - XEventsQueued(gXDisplay, QueuedAfterFlush)) { - XNextEvent(gXDisplay, &event); - handle_event(&event); - } - else if FD_ISSET - (spad_socket->socket, &rd) - /* - * Axiom Socket do what handle_event does The 100 is - * $SpadStuff in hypertex.boot - */ - { - if (100 == get_int(spad_socket)) { - set_window(gParentWindow->fMainWindow); - make_busy_cursors(); - get_new_window(); - } - } - /* - * Session Socket Telling us about the death of a spadbuf - * (plus maybe more later) service_session_socket in - * spadint.c - */ - else - if (session_server && FD_ISSET(session_server->socket, &rd)) { - service_session_socket(); - } - } - } - else { - XNextEvent(gXDisplay, &event); - handle_event(&event); - } - } -} - -static void -handle_event(XEvent * event) -{ - XWindowAttributes wa; -/* fprintf(stderr,"event:handle_event entered\n");*/ - set_window(event->xany.window); - if (event->type == MotionNotify) { -/* fprintf(stderr,"event:handle_event type=MotionNotify\n");*/ - handle_motion_event((XMotionEvent *)event); - motion = 1; - return; - } - make_busy_cursors(); - switch (event->type) { - case DestroyNotify: -/* fprintf(stderr,"event:handle_event type=DestroyNotify\n");*/ - break; - case Expose: -/* fprintf(stderr,"event:handle_event type=Expose\n");*/ - XGetWindowAttributes(gXDisplay, gWindow->fMainWindow, &wa); - if ((gWindow->width == 0 && gWindow->height == 0) || - (wa.width != gWindow->width || wa.height != gWindow->height)) { - gWindow->width = wa.width; - gWindow->height = wa.height; - display_page(gWindow->page); - gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; - } - else /** just redraw the thing **/ - expose_page(gWindow->page); - XFlush(gXDisplay); - clear_exposures(gWindow->fMainWindow); - clear_exposures(gWindow->fScrollWindow); - break; - case ButtonPress: -/* fprintf(stderr,"event:handle_event type=ButtonPress\n");*/ - handle_button(event->xbutton.button, (XButtonEvent *)event); - XFlush(gXDisplay); - if (gWindow) { - while (XCheckTypedWindowEvent(gXDisplay, gWindow->fMainWindow, - Expose, event)); - while (XCheckTypedWindowEvent(gXDisplay, gWindow->fScrollWindow, - Expose, event)); - } - break; - case KeyPress: -/* fprintf(stderr,"event:handle_event type=KeyPress\n");*/ - handle_key(event); - if (gWindow) { - while (XCheckTypedWindowEvent(gXDisplay, gWindow->fMainWindow, - Expose, event)); - while (XCheckTypedWindowEvent(gXDisplay, gWindow->fScrollWindow, - Expose, event)); - } - break; - case MapNotify: -/* fprintf(stderr,"event:handle_event type=MapNotify\n");*/ - create_window(); - break; - - case SelectionNotify: -/* fprintf(stderr,"event:handle_event type=SelectionNotify\n");*/ - /* this is in response to a previous request in an input area */ - if ( gSavedInputAreaLink ) { - XSelectionEvent *pSelEvent; - Atom dataProperty; - pSelEvent = (XSelectionEvent *) event; - dataProperty = XInternAtom(gXDisplay, "PASTE_SELECTION", False); - /* change the input focus */ - - /* change_input_focus(gSavedInputAreaLink); */ - - /* try to get the selection as a window property */ - - if ( pSelEvent->requestor == gWindow->fMainWindow && - pSelEvent->selection == XA_PRIMARY && - /* pSelEvent->time == CurrentTime && */ - pSelEvent->target == XA_STRING && - pSelEvent->property == dataProperty ) - { - Atom actual_type; - int actual_format; - unsigned long nitems, leftover; - char *pSelection = NULL; - - if (Success == XGetWindowProperty(gXDisplay, - gWindow->fMainWindow, - pSelEvent->property, 0L, 100000000L, True, - AnyPropertyType, &actual_type, &actual_format, - &nitems, &leftover, (unsigned char **) &pSelection) ) - { - char *pBuffer; - InputItem *item = gSavedInputAreaLink->reference.string; - - for (pBuffer = pSelection; *pBuffer; ++pBuffer) - add_buffer_to_sym(pBuffer, item); - - XFree(pSelection); - } - } - - /* clear the link info */ - - gSavedInputAreaLink = NULL; - } - break; - - default: -/* fprintf(stderr,"event:handle_event type=default\n");*/ - break; - } - -} - -static void -create_window(void) -{ - XWindowAttributes wa; - - XGetWindowAttributes(gXDisplay, gWindow->fMainWindow, &wa); - - gWindow->width = wa.width; - gWindow->height = wa.height; - display_page(gWindow->page); - gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; - - /* then select for the events I normally would like to catch */ - XSelectInput(gXDisplay, gWindow->fMainWindow, ButtonPress | KeyPressMask | - PointerMotionMask | - ExposureMask /* | EnterWindowMask | LeaveWindowMask */ ); - XSelectInput(gXDisplay, gWindow->fScrollWindow, ExposureMask); - -} - -/* - * This routine is called when the quitbutton is hit. For the moment I am - * just going to leave it all behind - */ - -void -quitHyperDoc(void) -{ - HyperDocPage *page; - - if (gSessionHashTable.num_entries == 1 || gParentWindow == gWindow) { - if (!strcmp(gWindow->page->name, "ProtectedQuitPage")){ - exitHyperDoc(); - } - page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, "ProtectedQuitPage"); - if (page == NULL) { - fprintf(stderr, "Unknown page name %s\n", "ProtectedQuitPage"); - exitHyperDoc(); - return; - } - if (gWindow->fDownLinkStackIndex == MaxDownlinkDepth) - fprintf(stderr, "exceeded maximum link nesting level\n"); - else - gWindow->fDownLinkStack[gWindow->fDownLinkStackIndex++] = gWindow->page; - gWindow->page = page; - display_page(gWindow->page); - gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; - } - else - exitHyperDoc(); -} - - -/* - * find_page takes as an argument the HyperDoc for a page name and returns - * the associated page - */ - -static HyperDocPage * -find_page(TextNode * node) -{ - char *page_name; - HyperDocPage *page; - - /* try and find the page name */ - page_name = print_to_string(node); - page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, page_name); - - if (page == NULL) { - /* try to find the unknown page */ - page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, "UnknownPage"); - if (page == NULL) { - /* Yikes, Even that could not be found */ - fprintf(stderr, "Unknown page name %s\n", page_name); - } - else { - if (page->type == UnloadedPageType) - page->type = UlUnknownPage; - else - page->type = UnknownPage; - } - } - return page; -} - -/* - * These are macros for taking care of the downlink stack, and the memolink - * stack. - */ - -#define NotSpecial(t) ((t == Quitbutton || t == Returnbutton || \ - t == Upbutton || t == UnknownPage || \ - t == UlUnknownPage || t == ErrorPage) ?(0):(1)) - -/* pushes a page onto the down link stack */ - -static void -downlink(void) -{ - if (gWindow->fDownLinkStackIndex == MaxDownlinkDepth) - fprintf(stderr, "exceeded maximum link nesting level\n"); - else - gWindow->fDownLinkStack[gWindow->fDownLinkStackIndex++] = gWindow->page; -} - -static void -memolink(void) -{ - if (gWindow->fMemoStackIndex == MaxMemoDepth) - fprintf(stderr, "exceeded maximum link nesting level\n"); - else { - gWindow->fMemoStack[gWindow->fMemoStackIndex] = gWindow->page; - gWindow->fDownLinkStackTop[gWindow->fMemoStackIndex++] = gWindow->fDownLinkStackIndex; - } -} - -static void -killAxiomPage(HyperDocPage * page) -{ - char command[512]; - - sprintf(command, "(|htpDestroyPage| '%s)", page->name); - send_lisp_command(command); -} - -static void -kill_page(HyperDocPage * page) -{ - page->scroll_off = 0; - if (page->type == SpadGen) { - hash_delete(gWindow->fPageHashTable, page->name); - killAxiomPage(page); - free_page(page); - } -} - -/* pops the memo stack */ - -static HyperDocPage * -returnlink(void) -{ - int i; - - if (gWindow->fMemoStackIndex == 0) { - BeepAtTheUser(); - return NULL; - } - else { - kill_page(gWindow->page); - for (i = gWindow->fDownLinkStackIndex - 1; - i >= gWindow->fDownLinkStackTop[gWindow->fMemoStackIndex - 1]; - i--) - { - kill_page(gWindow->fDownLinkStack[i]); - } - gWindow->fDownLinkStackIndex = - gWindow->fDownLinkStackTop[--gWindow->fMemoStackIndex]; - return (gWindow->fMemoStack[gWindow->fMemoStackIndex]); - } -} - -/* pops a page if it can from the downlink stack */ - -static HyperDocPage * -uplink(void) -{ - if (gWindow->fDownLinkStackIndex == 0) - return returnlink(); - else { - kill_page(gWindow->page); - return (gWindow->fDownLinkStack[--gWindow->fDownLinkStackIndex]); - } -} - -static void -windowlink_handler(TextNode * node) -{ - char *page_name; - - /* first try and find the page */ - page_name = print_to_string(node); - - if (init_top_window(page_name) == -1) { - return; - } -/* gWindow->fWindowHashTable = gWindow->page->fLinkHashTable;*/ -} - -void -make_window_link(char *name) -{ - if (init_top_window(name) != -1) -{}/* gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; */ -} - - -static void -lispwindowlink_handler(HyperLink * link) -{ - - /* - * Since we are popping up a new window, then we had better change all - * the cursors right away. We won't get another chance at it. - */ - - if (init_top_window(NULL) != -1) { - HyperDocPage *page = NULL; - int frame = gWindow->fAxiomFrame; - - page = issue_server_command(link); - gWindow->fAxiomFrame = frame; - gWindow->page = page; -/* gWindow->fWindowHashTable = gWindow->page->fLinkHashTable;*/ - } -} - -static HyperDocPage * -paste_button(PasteNode * paste) -{ - HyperDocPage *page = NULL; - int pastewhere=paste->where; - - - if ( paste->end_node ==NULL || paste->begin_node==NULL || paste->arg_node==NULL ){ - BeepAtTheUser(); - return NULL; - } - - page=parse_patch(paste); -/* paste has changed after this call so use pastewhere*/ - - if (pastewhere && page ) { - if (0 == strcmp(page->name, "ErrorPage")) - page = NULL; - } - else - BeepAtTheUser(); - - return page; -} - -void -helpForHyperDoc(void) -{ - HyperDocPage *page = NULL; - - /* do not do anything if we are already at the "no more help" page */ - - if (0 == strcmp(gWindow->page->name, NoMoreHelpPage)) - return; - - /* if no help page recorded, use the standard "no more help" page */ - - if (!gWindow->page->helppage) - gWindow->page->helppage = alloc_string(NoMoreHelpPage); - - /* if we are on the main help page, use "no more help" page */ - - if (0 == strcmp(gWindow->page->name, TopLevelHelpPage)) - gWindow->page->helppage = alloc_string(NoMoreHelpPage); - - page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, gWindow->page->helppage); - - if (page) - make_window_link(gWindow->page->helppage); - else - BeepAtTheUser(); -} - -static HyperLink * -findButtonInList(HDWindow * window, int x, int y) -{ - ButtonList *bl; - - if (!window || window->page->type == UnloadedPageType) - return NULL; - for (bl = window->page->s_button_list; bl != NULL; bl = bl->next) - if (x >= bl->x0 && x <= bl->x1 && y >= bl->y0 && y <= bl->y1) - return bl->link; - for (bl = window->page->button_list; bl != NULL; bl = bl->next) - if (x >= bl->x0 && x <= bl->x1 && y >= bl->y0 && y <= bl->y1) - return bl->link; - return NULL; -} - -static HyperLink * -get_hyper_link(XButtonEvent * event) -{ - HyperLink *l1, *l2; - - l1 = (HyperLink *) hash_find(gWindow->fWindowHashTable, (char *)&(event->window)); - if (l1) - return l1; - l2 = findButtonInList(gWindow, event->x, event->y); - return l2; -} - -/* - * Handle a button pressed event. window is the subwindow in which the event - * occured, and button is the button which was pressed - */ - -static void -handle_button(int button, XButtonEvent * event) -{ - HyperLink *link; - HyperDocPage *page = NULL; - char *page_name; - - /* find page name from sub-window handle */ - - link = get_hyper_link(event); - - if (link == NULL) { /* user clicked on an inactive area */ -/* BeepAtTheUser(); */ /* I always thought this was annoying. RSS */ - return; - } - - switch (link->type) { - case Pastebutton: - page = paste_button(link->reference.paste); - break; - case Link: - page_name = print_to_string(link->reference.node); - page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, page_name); - break; - case Helpbutton: - helpForHyperDoc(); - page = NULL; - break; - case Scrollbar: - scrollScroller(event); - break; - case Scrollupbutton: - scrollUp(); - break; - case Scrolldownbutton: - scrollDown(); - break; - - case Inputstring: - /* We must be changing input focus or getting a selection */ - - change_input_focus(link); - if ( button == Button2 ) { - XConvertSelection(gXDisplay, XA_PRIMARY, XA_STRING, - XInternAtom(gXDisplay, "PASTE_SELECTION", False), - gWindow->fMainWindow, CurrentTime); - gSavedInputAreaLink = link; - } - break; - - case SimpleBox: - page = NULL; - toggle_input_box(link); - break; - case Radiobox: - page = NULL; - toggle_radio_box(link); - break; - case Quitbutton: - quitHyperDoc(); - break; - case Returnbutton: /* pop memo information */ - page = returnlink(); - break; - case Upbutton: /* pop downlink information */ - page = uplink(); - break; - case Downlink: - page = find_page(link->reference.node); - if (page && NotSpecial(page->type)) - downlink(); - break; - case Memolink: - page = find_page(link->reference.node); - if (page && NotSpecial(page->type)) - memolink(); - break; - case Windowlink: - page = find_page(link->reference.node); - if (page && NotSpecial(page->type)) { - windowlink_handler(link->reference.node); - gNeedIconName = 1; - page = NULL; - } - break; - case Lispwindowlink: - lispwindowlink_handler(link); - gNeedIconName = 1; - page = NULL; - break; - case LispMemoLink: - case Spadmemolink: - page = issue_server_command(link); - if (page && NotSpecial(page->type)) - memolink(); - break; - case LispDownLink: - case Spaddownlink: - page = issue_server_command(link); - if (page && NotSpecial(page->type)) - downlink(); - break; - case Spadlink: - case Lisplink: - page = issue_server_command(link); - break; - case Lispcommand: - case Qspadcall: - case Spadcall: - page = issue_server_command(link); - break; - case Lispcommandquit: - case Spadcallquit: - case Qspadcallquit: - page = issue_server_command(link); - exitHyperDoc(); - break; - case Spadcommand: - case Spadgraph: - case Spadsrc: - issue_spadcommand(gWindow->page, link->reference.node, - button == Button1, link->type); - break; - case Unixlink: - page = issue_unixlink(link->reference.node); - if (page && NotSpecial(page->type)) { - downlink(); - } - break; - case Unixcommand: - issue_unixcommand(link->reference.node); - break; - default: - break; - } - - if (page) { - switch (page->type) { /* check for special button types */ - case Quitbutton: - exitHyperDoc(); - return; - case Returnbutton: - gWindow->page = returnlink(); - break; - case Upbutton: - gWindow->page = uplink(); - break; - case ErrorPage: - case UnknownPage: - case UlUnknownPage: - if (page->type == UlUnknownPage) - page->type = UnloadedPageType; - downlink(); - gWindow->page = page; - break; - default: /* a normal link */ - gWindow->page = page; - break; - } - if (link->type != Pastebutton) - display_page(gWindow->page); - gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; /* reset the window hash */ - } -} - - -void -exitHyperDoc(void) -{ - XEvent event; - - - if (gSessionHashTable.num_entries == 1 || gParentWindow == gWindow) { - free_hd_window(gWindow); - exit(0); - } - hash_delete(&gSessionHashTable, (char *)&gWindow->fMainWindow); - - /* - * Now we quickly want to flush all the events associated with this - * window from existence - */ - - XFlush(gXDisplay); - while (XCheckWindowEvent(gXDisplay, gWindow->fMainWindow, bigmask, &event)) { - } - while (XCheckWindowEvent(gXDisplay, gWindow->fScrollWindow,bigmask, &event)) { - } - while (XCheckWindowEvent(gXDisplay, gWindow->fDisplayedWindow, bigmask, &event)) { - } - while (XCheckWindowEvent(gXDisplay, gWindow->fScrollUpWindow, bigmask, &event)) { - } - while (XCheckWindowEvent(gXDisplay, gWindow->fScrollDownWindow, bigmask, &event)) { - } - while (XCheckWindowEvent(gXDisplay, gWindow->scrollbar, bigmask, &event)) { - } - while (XCheckWindowEvent(gXDisplay, gWindow->scroller, bigmask, &event)) { - } - - XDestroyWindow(gXDisplay, gWindow->fMainWindow); - free_hd_window(gWindow); - gWindow = NULL; - gActiveWindow = -1; - XFlush(gXDisplay); -} - -static int -set_window(Window window) -{ - Window root, parent, *children, grandparent,myarg; - HDWindow *htw; - unsigned int nchildren; - int st; - - myarg=window; - nchildren = 0; - htw = (HDWindow *) hash_find(&gSessionHashTable, (char *)&myarg); - if (htw != NULL) { - gWindow = htw; - return 1; - } - st = XQueryTree(gXDisplay, myarg, &root, &parent, &children, &nchildren); - if (st==0) goto ERROR; - if (nchildren > 0) - XFree(children); - htw = (HDWindow *) hash_find(&gSessionHashTable, (char *)&parent); - if (htw != NULL) { - gWindow = htw; - return 1; - - } - else { - /* check for a grandparent */ - st = XQueryTree(gXDisplay, parent, &root, &grandparent, &children, &nchildren); - if (st==0) goto ERROR; - if (nchildren > 0) - XFree(children); - htw = (HDWindow *) hash_find(&gSessionHashTable, (char *)&grandparent); - if (htw != NULL) { - gWindow = htw; - return 1; - } - } - - /* - * fprintf(stderr, "window(%d) and it's parent(%d) aren't in - * gSessionHashTable\n", window, parent); - - we never found that window. this happens if (not iff) we exit from - an unfocused non-main window under certain wm's and click-to-type. the program returns here with - the window handle that was just destroyed. So let's set the global gWindow - to the main window. - */ - -ERROR: - gWindow=gParentWindow; - return 0; -} - -/* - * This procedure whips thru the stack and clears all expose events for the - * given routine - */ -static void -clear_exposures(Window w) -{ - XEvent report; - - XFlush(gXDisplay); - while (XCheckTypedWindowEvent(gXDisplay, w, Expose, &report)); -} -void -get_new_window(void) -{ - - int val; - char buf[128]; - int frame; - Window wid; - HDWindow *htw; - HyperDocPage *hpage; - - - /* - * If I am going to try and start a new window, then I should make sure I - * have a coonection to listen on - * - * BUT This code is entered when a socket selects - * - * if (spad_socket == NULL) { spad_socket = - * connect_to_local_server(SpadServer, MenuServer, 10); if (spad_socket - * == NULL) { fprintf(stderr, "Get_new_window: Couldn't Connect to - * SpadServer\n"); return -1; } } - * - */ - - - frame = get_int(spad_socket); - val = get_int(spad_socket); - switch (val) { - case StartPage: - init_top_window(NULL); - val = get_int(spad_socket); - init_scanner(); - input_type = FromSpadSocket; - input_string = ""; - gWindow->page = parse_page_from_socket(); - gWindow->fAxiomFrame = frame; - XFlush(gXDisplay); - break; - case LinkToPage: - get_string_buf(spad_socket, buf, 128); - if (init_top_window(buf) == -1) { - fprintf(stderr, "get_new_window: Did not find page %s\n", buf); - /* return -1; */ - } - gWindow->fAxiomFrame = frame; - break; - case PopUpPage: - val = get_int(spad_socket); - init_form_window(NULL, val); - send_int(spad_socket, gWindow->fMainWindow); - init_scanner(); - input_type = FromSpadSocket; - input_string = ""; - gWindow->page = parse_page_from_socket(); - compute_form_page(gWindow->page); - - XMapWindow(gXDisplay, gWindow->fMainWindow); - - gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; - gWindow->fAxiomFrame = frame; - XFlush(gXDisplay); - break; - case PopUpNamedPage: - val = get_int(spad_socket); - get_string_buf(spad_socket, buf, 128); - - if (init_form_window(buf, val) == -1) { - send_int(spad_socket, -1); - break; - } - load_page(gWindow->page); - compute_form_page(gWindow->page); - - XMapWindow(gXDisplay, gWindow->fMainWindow); - - gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; - gWindow->fAxiomFrame = frame; - XFlush(gXDisplay); - send_int(spad_socket, gWindow->fMainWindow); - /* fprintf(stderr, "Window Id was %d\n", gWindow->fMainWindow); */ - break; - case ReplaceNamedPage: - wid = (Window) get_int(spad_socket); - get_string_buf(spad_socket, buf, 128); - - htw = (HDWindow *) hash_find(&gSessionHashTable,(char *)&wid); - if (htw == NULL) break; - hpage = (HyperDocPage *) hash_find(gWindow->fPageHashTable, buf); - if (hpage == NULL) break; - gWindow = htw; - gWindow->page = hpage; - display_page(gWindow->page); - gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; - clear_exposures(gWindow->fMainWindow); - clear_exposures(gWindow->fScrollWindow); - XFlush(gXDisplay); - break; - case ReplacePage: - wid = (Window) get_int(spad_socket); - set_window(wid); - init_scanner(); - input_type = FromSpadSocket; - input_string = ""; - gWindow->page = parse_page_from_socket(); - display_page(gWindow->page); - gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; - clear_exposures(gWindow->fMainWindow); - clear_exposures(gWindow->fScrollWindow); - XFlush(gXDisplay); - break; - case KillPage: - /* Here the user wishes to kill the page */ - wid = (Window) get_int(spad_socket); - htw = (HDWindow *) hash_find(&gSessionHashTable,(char *)&wid); - if (htw !=NULL) { - gWindow = htw; - exitHyperDoc(); - break; - } - break; - } - } -static void -set_cursor(HDWindow *window,Cursor state) -{ - if (state == gBusyCursor) - XDefineCursor(gXDisplay, window->fMainWindow, gBusyCursor); - else if (state == gActiveCursor) - XDefineCursor(gXDisplay, window->fMainWindow, gActiveCursor); - else - XDefineCursor(gXDisplay, window->fMainWindow, gNormalCursor); - XFlush(gXDisplay); -} - -static void -change_cursor(Cursor state, HDWindow *window) -{ - if (window->fDisplayedCursor == state) - return; - window->fDisplayedCursor = state; - set_cursor(window, state); -} - -static void -handle_motion_event(XMotionEvent *event) -{ - if (!gWindow) - return; - if (findButtonInList(gWindow, event->x, event->y) != NULL) - change_cursor(gActiveCursor, gWindow); - else - change_cursor(gNormalCursor, gWindow); -} - -static void -init_cursor_state(HDWindow *window) -{ - if (window) { - int x, y, rx, ry, but; - Window r, c; - - XQueryPointer(gXDisplay, window->fMainWindow, - &r, &c, &rx, &ry, &x, &y,(unsigned int *) &but); - if (findButtonInList(window, x, y) != NULL) - change_cursor(gActiveCursor, window); - else - change_cursor(gNormalCursor, window); - } -} - -static void -init_cursor_states(void) -{ - hash_map(&gSessionHashTable,(MappableFunction) init_cursor_state); -} - - -static void -make_busy_cursor(HDWindow *window) -{ - change_cursor(gBusyCursor, window); -} - -static void -make_busy_cursors(void) -{ - hash_map(&gSessionHashTable, (MappableFunction)make_busy_cursor); -} - -static int -HyperDocErrorHandler(Display *display, XErrorEvent *xe) -{ - if (xe->request_code != 15) { - char buf[1024]; - - XGetErrorText(display, xe->error_code, buf, sizeof(buf)); - - fprintf(stderr, "error code = %d\n", xe->error_code); - fprintf(stderr, "major op code = %d\n", xe->request_code); - fprintf(stderr, "minor op code = %d\n", xe->minor_code); - fprintf(stderr, "XID = %ld\n", xe->resourceid); - fprintf(stderr, "%s\n", buf); - - if (xe->request_code != 15) - exit(-1); - } - return(0); -} - - - -static void -set_error_handlers(void) -{ - XSetErrorHandler(HyperDocErrorHandler); -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} diff --git a/src/hyper/ex2ht.c b/src/hyper/ex2ht.c new file mode 100644 index 00000000..e09106bb --- /dev/null +++ b/src/hyper/ex2ht.c @@ -0,0 +1,286 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +/* ex2ht creates a cover page for structured HyperDoc example pages */ + + +#define _EX2HT_C +#include "axiom-c-macros.h" +#include "useproto.h" +#include "debug.h" +#include +#include +#include +#include +#include +#include +#include + + + +#if defined(SUN4OS5platform)||defined(SGIplatform) +/* can't find a prototype anywhere */ +extern int utimes(const char *, const struct timeval [2]); +#endif + + +#define MaxLineLength 512 +#define MaxFiles 100 + +char *files[MaxFiles]; +int numFiles = 0; +struct timeval latest_date[2] ={{0,0},{0,0}}; + +#include "ex2ht.H1" + + +int +main(int argc, char **argv) +{ + int i; + + if (argc == 1) { + fprintf(stderr, "usage: %s exfile.ht ...\n", argv[0]); + return (-1); + } + openCoverPage(); + for (i = 1; i < argc; i++) + exToHt(argv[i]); + closeCoverPage(); + for (i = 0; i < numFiles; i++) + addFile(files[i]); + closeCoverFile(); + return 0; +} + +char * +allocString(char *s) +{ + char *t = (char *) malloc(strlen(s) + 1); + + strcpy(t, s); + return t; +} + +char * +strPrefix(char *prefix, char *s) +{ + while (*prefix != '\0' && *prefix == *s) { + prefix++; + s++; + } + if (*prefix == '\0') + return s; + return NULL; +} + +char * +getExTitle(FILE *inFile, char *line) +{ + char *title; + + while (fgets(line, MaxLineLength, inFile) != NULL) + if ((title = strPrefix("% Title: ", line))) { + title[strlen(title) - 1] = '\0'; + return title; + } + fprintf(stderr, "No Title title line in the file!\n"); + return NULL; +} + +void +exToHt(char *filename) +{ + char line[MaxLineLength], *line2; + char *title, *pagename; + FILE *inFile = fopen(filename, "r"); + FILE *outFile; + int len, i; + struct timeval tvp; + struct stat buf; + + if (inFile == NULL) { + fprintf(stderr, "couldn't open %s for reading.\n", filename); + return; + } + strcpy(line, "Menu"); + strcat(line, filename); + len = strlen(line); + for (i = 0; i < len; i++) + if (line[i] == '.') { + line[i] = '\0'; + break; + } + outFile = fopen(line, "w"); + if (outFile == NULL) { + fprintf(stderr, "couldn't open %s for writing.\n", line); + return; + } + pagename = allocString(line); + title = getExTitle(inFile, line); + if (title == NULL) { + return; + } + files[numFiles++] = pagename; + emitCoverLink(pagename, title); + emitHeader(outFile, pagename, title); + while (fgets(line, MaxLineLength, inFile) != NULL) { + if ((line2 = strPrefix("\\begin{page}{", line))) + emitMenuEntry(line2, outFile); + else if ((line2 = strPrefix("\\spadcommand{", line))) + emitSpadCommand(line2, "\\spadcommand{", outFile); + else if ((line2 = strPrefix("\\spadpaste{", line))) + emitSpadCommand(line2, "\\spadpaste{", outFile); + else if ((line2 = strPrefix("\\example{", line))) + emitSpadCommand(line2, "\\example{", outFile); + else if ((line2 = strPrefix("\\graphpaste{", line))) + emitSpadCommand(line2, "\\graphpaste{", outFile); + } + emitFooter(outFile); + fclose(inFile); + fclose(outFile); + stat(filename,&buf); + tvp.tv_sec =buf.st_mtime; + tvp.tv_usec =0; + if timercmp(&tvp,&latest_date[1],>){ + latest_date[1].tv_sec=buf.st_mtime; + } +} + +void +emitHeader(FILE *outFile, char *pageName, char *pageTitle) +{ + fprintf(outFile, "\\begin{page}{%s}{%s}\n", pageName, pageTitle); + fprintf(outFile, "\\beginscroll\\beginmenu\n"); +} + +void +emitFooter(FILE *outFile) +{ + fprintf(outFile, "\\endmenu\\endscroll\\end{page}\n"); +} + +/* s is pageName}{title} */ +void +emitMenuEntry(char *line, FILE *outFile) +{ + char pageName[MaxLineLength], title[MaxLineLength]; + char *p = pageName, *t = title; + + while (*line != '}') + *p++ = *line++; + *p = '\0'; + line++; + while (*line != '}') + *t++ = *line++; + *t = '\0'; + fprintf(outFile, "\\menudownlink%s}{%s}\n", title, pageName); +} + +void +emitSpadCommand(char *line, char *prefix, FILE *outFile) +{ + int braceCount = 1; + char command[MaxLineLength], *t = command; + + while (1) { + if (*line == '}') + braceCount--; + if (braceCount == 0) + break; + if (*line == '{') + braceCount++; + *t++ = *line++; + } + *t = '\0'; + fprintf(outFile, "%s%s}\n", prefix, command); +} + +/* cover page functions */ + +FILE *coverFile; + +void +openCoverPage(void) +{ + coverFile = fopen("coverex.ht", "w"); + if (coverFile == NULL) { + fprintf(stderr, "couldn't open coverex.ht for writing\n"); + exit(-1); + } + fprintf(coverFile, "%% DO NOT EDIT! Created by ex2ht.\n\n"); + fprintf(coverFile, "\\begin{page}{ExampleCoverPage}{Examples Of AXIOM Commands}\n"); + fprintf(coverFile, "\\beginscroll\\table{\n"); +} + +void +closeCoverPage(void) +{ + fprintf(coverFile, "}\\endscroll\\end{page}\n\n"); +} + +void +closeCoverFile(void) +{ + fclose(coverFile); +#ifdef HP9platform + times("coverex.ht",latest_date); +#else + utimes("coverex.ht",latest_date); +#endif +} + +void +emitCoverLink(char *name, char *title) +{ + fprintf(coverFile, "{\\downlink{%s}{%s}}\n", title, name); +} + +void +addFile(char *filename) +{ + FILE *file = fopen(filename, "r"); + int c; + + if (file == NULL) { + fprintf(stderr, "Couln't open %s for reading\n", filename); + exit(-1); + } + while ((c = getc(file)) != EOF) + putc(c, coverFile); + putc('\n', coverFile); + fclose(file); + unlink(filename); +} diff --git a/src/hyper/ex2ht.pamphlet b/src/hyper/ex2ht.pamphlet deleted file mode 100644 index c26c26b0..00000000 --- a/src/hyper/ex2ht.pamphlet +++ /dev/null @@ -1,310 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/ex2ht} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{ex2ht.c} -<>= -/* ex2ht creates a cover page for structured HyperDoc example pages */ - - -#define _EX2HT_C -#include "axiom-c-macros.h" -#include "useproto.h" -#include "debug.h" -#include -#include -#include -#include -#include -#include -#include - - - -#if defined(SUN4OS5platform)||defined(SGIplatform) -/* can't find a prototype anywhere */ -extern int utimes(const char *, const struct timeval [2]); -#endif - - -#define MaxLineLength 512 -#define MaxFiles 100 - -char *files[MaxFiles]; -int numFiles = 0; -struct timeval latest_date[2] ={{0,0},{0,0}}; - -#include "ex2ht.H1" - - -int -main(int argc, char **argv) -{ - int i; - - if (argc == 1) { - fprintf(stderr, "usage: %s exfile.ht ...\n", argv[0]); - return (-1); - } - openCoverPage(); - for (i = 1; i < argc; i++) - exToHt(argv[i]); - closeCoverPage(); - for (i = 0; i < numFiles; i++) - addFile(files[i]); - closeCoverFile(); - return 0; -} - -char * -allocString(char *s) -{ - char *t = (char *) malloc(strlen(s) + 1); - - strcpy(t, s); - return t; -} - -char * -strPrefix(char *prefix, char *s) -{ - while (*prefix != '\0' && *prefix == *s) { - prefix++; - s++; - } - if (*prefix == '\0') - return s; - return NULL; -} - -char * -getExTitle(FILE *inFile, char *line) -{ - char *title; - - while (fgets(line, MaxLineLength, inFile) != NULL) - if ((title = strPrefix("% Title: ", line))) { - title[strlen(title) - 1] = '\0'; - return title; - } - fprintf(stderr, "No Title title line in the file!\n"); - return NULL; -} - -void -exToHt(char *filename) -{ - char line[MaxLineLength], *line2; - char *title, *pagename; - FILE *inFile = fopen(filename, "r"); - FILE *outFile; - int len, i; - struct timeval tvp; - struct stat buf; - - if (inFile == NULL) { - fprintf(stderr, "couldn't open %s for reading.\n", filename); - return; - } - strcpy(line, "Menu"); - strcat(line, filename); - len = strlen(line); - for (i = 0; i < len; i++) - if (line[i] == '.') { - line[i] = '\0'; - break; - } - outFile = fopen(line, "w"); - if (outFile == NULL) { - fprintf(stderr, "couldn't open %s for writing.\n", line); - return; - } - pagename = allocString(line); - title = getExTitle(inFile, line); - if (title == NULL) { - return; - } - files[numFiles++] = pagename; - emitCoverLink(pagename, title); - emitHeader(outFile, pagename, title); - while (fgets(line, MaxLineLength, inFile) != NULL) { - if ((line2 = strPrefix("\\begin{page}{", line))) - emitMenuEntry(line2, outFile); - else if ((line2 = strPrefix("\\spadcommand{", line))) - emitSpadCommand(line2, "\\spadcommand{", outFile); - else if ((line2 = strPrefix("\\spadpaste{", line))) - emitSpadCommand(line2, "\\spadpaste{", outFile); - else if ((line2 = strPrefix("\\example{", line))) - emitSpadCommand(line2, "\\example{", outFile); - else if ((line2 = strPrefix("\\graphpaste{", line))) - emitSpadCommand(line2, "\\graphpaste{", outFile); - } - emitFooter(outFile); - fclose(inFile); - fclose(outFile); - stat(filename,&buf); - tvp.tv_sec =buf.st_mtime; - tvp.tv_usec =0; - if timercmp(&tvp,&latest_date[1],>){ - latest_date[1].tv_sec=buf.st_mtime; - } -} - -void -emitHeader(FILE *outFile, char *pageName, char *pageTitle) -{ - fprintf(outFile, "\\begin{page}{%s}{%s}\n", pageName, pageTitle); - fprintf(outFile, "\\beginscroll\\beginmenu\n"); -} - -void -emitFooter(FILE *outFile) -{ - fprintf(outFile, "\\endmenu\\endscroll\\end{page}\n"); -} - -/* s is pageName}{title} */ -void -emitMenuEntry(char *line, FILE *outFile) -{ - char pageName[MaxLineLength], title[MaxLineLength]; - char *p = pageName, *t = title; - - while (*line != '}') - *p++ = *line++; - *p = '\0'; - line++; - while (*line != '}') - *t++ = *line++; - *t = '\0'; - fprintf(outFile, "\\menudownlink%s}{%s}\n", title, pageName); -} - -void -emitSpadCommand(char *line, char *prefix, FILE *outFile) -{ - int braceCount = 1; - char command[MaxLineLength], *t = command; - - while (1) { - if (*line == '}') - braceCount--; - if (braceCount == 0) - break; - if (*line == '{') - braceCount++; - *t++ = *line++; - } - *t = '\0'; - fprintf(outFile, "%s%s}\n", prefix, command); -} - -/* cover page functions */ - -FILE *coverFile; - -void -openCoverPage(void) -{ - coverFile = fopen("coverex.ht", "w"); - if (coverFile == NULL) { - fprintf(stderr, "couldn't open coverex.ht for writing\n"); - exit(-1); - } - fprintf(coverFile, "%% DO NOT EDIT! Created by ex2ht.\n\n"); - fprintf(coverFile, "\\begin{page}{ExampleCoverPage}{Examples Of AXIOM Commands}\n"); - fprintf(coverFile, "\\beginscroll\\table{\n"); -} - -void -closeCoverPage(void) -{ - fprintf(coverFile, "}\\endscroll\\end{page}\n\n"); -} - -void -closeCoverFile(void) -{ - fclose(coverFile); -#ifdef HP9platform - times("coverex.ht",latest_date); -#else - utimes("coverex.ht",latest_date); -#endif -} - -void -emitCoverLink(char *name, char *title) -{ - fprintf(coverFile, "{\\downlink{%s}{%s}}\n", title, name); -} - -void -addFile(char *filename) -{ - FILE *file = fopen(filename, "r"); - int c; - - if (file == NULL) { - fprintf(stderr, "Couln't open %s for reading\n", filename); - exit(-1); - } - while ((c = getc(file)) != EOF) - putc(c, coverFile); - putc('\n', coverFile); - fclose(file); - unlink(filename); -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} diff --git a/src/hyper/extent.h b/src/hyper/extent.h new file mode 100644 index 00000000..cebf6049 --- /dev/null +++ b/src/hyper/extent.h @@ -0,0 +1,129 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +#ifndef _EXTENT_H_ +#define _EXTENT_H_ 1 + +#include "axiom-c-macros.h" +#include "hyper.h" + +/* + * This file contains global macros extern declarations for the extent + * computation routines found in extent1.c and extent2.c. + */ + +/* + * Definitions of standard text formatting dimensions, etc. + * dimensions given in pixels + */ + +#define left_margin 20 +#define non_scroll_right_margin_space 20 +#define scroll_right_margin_space 40 +#define bottom_margin 15 +#define top_margin 5 +#define scroll_top_margin top_margin +#define scrollingTopMargin 5 +#define inter_line_space 5 +#define inter_word_space 5 +#define term_punct_space 5 +#define paragraph_space 30 +#define box_space 3 +#define horiz_line_space 3 +#define spadcom_indent 30 +#define min_inter_column_space 10 +#define box_width 3 +#define dash_width 5 +#define dash_y 4 + + +/* next two from display.h. Reorg! */ + +extern short int gDisplayRegion; +extern int gRegionOffset; + +#define not_in_scroll (!(gDisplayRegion == Scrolling)) + +#define visible(y, h) \ + (not_in_scroll || ((y) + gRegionOffset + gWindow->page->scroll_off \ + <= gWindow->scrollheight && \ + (y) + gRegionOffset + gWindow->page->scroll_off - (h) >= 0)) + +#define pix_visible(y, h) \ + (not_in_scroll || ((y) + gRegionOffset + gWindow->page->scroll_off - h + \ + line_height < gWindow->page->bot_scroll_margin \ + - gWindow->page->top_scroll_margin && \ + (y) + gRegionOffset + gWindow->page->scroll_off >= 0)) + +#define above(y) ((y) + gWindow->page->scroll_off < gWindow->page->top_scroll_margin) +#define below(y) ((y) + gWindow->page->scroll_off >= gWindow->page->bot_scroll_margin) + + +/* Variables for the formatting state */ + +extern int right_margin_space; +extern int right_margin; +extern int indent; +extern int item_indent; +extern int text_x; +extern int text_y; +extern int y_off; +extern int scroll_bot; +extern int need_scroll_up_button; +extern int need_scroll_down_button; +extern int item_space; +extern int present_line_height; +extern int past_line_height; +extern int line_height; /* space between lines */ +extern int normal_text_height; /* space between lines */ +extern int space_width; /* the maximum width of a character */ +extern int word_off_height; /* the diff between text height and */ + + +/* + * externs from extent1.c + */ + +extern short int gExtentRegion; + +extern short int gInAxiomCommand; /* true iff we are in a \spadcommand */ +extern short int gInDesc; +extern short int gInItem; /* true iff we are in a \item */ +extern short int gInLine; /* true iff there have been words printed */ +extern short int gInTable; + +extern TextNode *gLineNode; + +#endif diff --git a/src/hyper/extent.pamphlet b/src/hyper/extent.pamphlet deleted file mode 100644 index 801689f7..00000000 --- a/src/hyper/extent.pamphlet +++ /dev/null @@ -1,157 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/extent} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{extent.h} -<>= -<> -#ifndef _EXTENT_H_ -#define _EXTENT_H_ 1 - -#include "axiom-c-macros.h" -#include "hyper.h" - -/* - * This file contains global macros extern declarations for the extent - * computation routines found in extent1.c and extent2.c. - */ - -/* - * Definitions of standard text formatting dimensions, etc. - * dimensions given in pixels - */ - -#define left_margin 20 -#define non_scroll_right_margin_space 20 -#define scroll_right_margin_space 40 -#define bottom_margin 15 -#define top_margin 5 -#define scroll_top_margin top_margin -#define scrollingTopMargin 5 -#define inter_line_space 5 -#define inter_word_space 5 -#define term_punct_space 5 -#define paragraph_space 30 -#define box_space 3 -#define horiz_line_space 3 -#define spadcom_indent 30 -#define min_inter_column_space 10 -#define box_width 3 -#define dash_width 5 -#define dash_y 4 - - -/* next two from display.h. Reorg! */ - -extern short int gDisplayRegion; -extern int gRegionOffset; - -#define not_in_scroll (!(gDisplayRegion == Scrolling)) - -#define visible(y, h) \ - (not_in_scroll || ((y) + gRegionOffset + gWindow->page->scroll_off \ - <= gWindow->scrollheight && \ - (y) + gRegionOffset + gWindow->page->scroll_off - (h) >= 0)) - -#define pix_visible(y, h) \ - (not_in_scroll || ((y) + gRegionOffset + gWindow->page->scroll_off - h + \ - line_height < gWindow->page->bot_scroll_margin \ - - gWindow->page->top_scroll_margin && \ - (y) + gRegionOffset + gWindow->page->scroll_off >= 0)) - -#define above(y) ((y) + gWindow->page->scroll_off < gWindow->page->top_scroll_margin) -#define below(y) ((y) + gWindow->page->scroll_off >= gWindow->page->bot_scroll_margin) - - -/* Variables for the formatting state */ - -extern int right_margin_space; -extern int right_margin; -extern int indent; -extern int item_indent; -extern int text_x; -extern int text_y; -extern int y_off; -extern int scroll_bot; -extern int need_scroll_up_button; -extern int need_scroll_down_button; -extern int item_space; -extern int present_line_height; -extern int past_line_height; -extern int line_height; /* space between lines */ -extern int normal_text_height; /* space between lines */ -extern int space_width; /* the maximum width of a character */ -extern int word_off_height; /* the diff between text height and */ - - -/* - * externs from extent1.c - */ - -extern short int gExtentRegion; - -extern short int gInAxiomCommand; /* true iff we are in a \spadcommand */ -extern short int gInDesc; -extern short int gInItem; /* true iff we are in a \item */ -extern short int gInLine; /* true iff there have been words printed */ -extern short int gInTable; - -extern TextNode *gLineNode; - -#endif -@ -\section{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. -*/ - -@ -<<*>>= -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/extent1.c b/src/hyper/extent1.c new file mode 100644 index 00000000..a18dbfd8 --- /dev/null +++ b/src/hyper/extent1.c @@ -0,0 +1,1371 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +/****************************************************************************** + * + * extent1.h: HyperDoc extent computation routines + * + * Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993. + * + ****************************************************************************/ +#define _EXTENT1_C +#include "axiom-c-macros.h" +#include "useproto.h" +#include "debug.h" + + +#include "extent.h" +#include "hyper.h" +#include "group.h" +#include "titlebar.h" +#include "scrollbar.h" + +#include "all_hyper_proto.H1" + + +/* + * Now we declare all the values which are shared among the extent routines + * and the showing routines + */ + +int noop_count; + +TextNode *link_node = NULL; +TextNode *paste_node = NULL; +TextNode *spad_node = NULL; +TextNode *if_node = NULL; + + +short int gExtentRegion; + + +short int gInDesc; +short int gInLine; /* true iff there have been words printed */ +short int gInItem; /* true iff we are in a \item */ +short int gInAxiomCommand; /* true iff we are in a \spadcommand */ +short int gInTable; + +/* Variables for the formatting state */ + +int right_margin_space; +int right_margin; +int indent; +int item_indent; +int text_x; +int text_y; +int y_off; +int scroll_bot; +int need_scroll_up_button; +int need_scroll_down_button; +int item_space; +int present_line_height; +int past_line_height; +int line_height; /* space between lines */ +int normal_text_height; /* space between lines */ +int space_width; /* the maximum width of a character */ +int word_off_height; /* the diff between text height and */ + +TextNode *gLineNode; + +/* + * Computes the extent of the input string or box + */ + +static void +compute_input_extent(TextNode * node) +{ + InputItem *item; + int t_width; + int num_lines; + + /* search the symbol table for the proper entry */ + + item = node->link->reference.string; + num_lines = item->num_lines; + + /* + * Once we have gotten this far, we should just be able to calculate the + * width using the normal font + */ + + t_width = (item->size + 1) * gInputFont->max_bounds.width + 10; + + if (gInLine) + text_x += inter_word_space; + + if (text_x + t_width > right_margin) { + start_newline(present_line_height, node); + text_x = indent; + } + node->x = text_x; + + /* now figure out the height of the current window */ + + node->height = line_height * (num_lines); + node->y = text_y - line_height + node->height - 1; + if (node->height > present_line_height) + present_line_height = plh(node->height); + node->width = t_width; + gInLine = 1; + text_x += t_width; +} + +static void +compute_punctuation_extent(TextNode * node) +{ + int twidth; + int nextwidth; + int incwidth; + + node->height = normal_text_height; + node->width = strlen(node->data.text); + incwidth = twidth = XTextWidth(gTopOfGroupStack->cur_font, node->data.text, + node->width); + + /* always check to see if there was some space in front of us */ + + if (gInLine && (node->space & FRONTSPACE)) + twidth += inter_word_space; + + /* + * now calcualte the width of the next one if it needs to be considered + */ + + if (!(node->space & BACKSPACE)) + nextwidth = total_width(node->next, Endtokens); + else + nextwidth = 0; + + if ((!(node->space & BACKSPACE)) && + (text_x + twidth + nextwidth > right_margin) && gInLine) { + start_newline(present_line_height, node); + if (gInAxiomCommand) { + text_x = indent + spadcom_indent; + } + else + text_x = indent; + } + + if (node->space & FRONTSPACE) + text_x += inter_word_space; + + node->x = text_x; + + /* + * Now try to see if we should leave space after myself. Always leave + * space when there is space + */ + + if (node->space & BACKSPACE) { + switch (node->data.text[0]) { + case '.': + case '?': + case '!': + text_x += term_punct_space; + break; + } + } + + text_x += incwidth; + node->y = text_y - word_off_height; + gInLine = 1; +} + +static void +compute_word_extent(TextNode * node) +{ + int twidth; + int nextwidth; + int incwidth; + + node->height = normal_text_height; + node->width = strlen(node->data.text); + incwidth = twidth = XTextWidth(gTopOfGroupStack->cur_font, node->data.text, + node->width); + + /* + * Now if we should drop some space in front of me, then add it to twidth + */ + + if (gInLine && node->space) + twidth += inter_word_space; + + /* + * Now what we should do is find all the things after us that have no + * space in front and add there width on. + */ + + nextwidth = total_width(node->next, Endtokens); + + + /* + * Should we start a new line? + */ + + if (text_x + twidth + nextwidth > right_margin && gInLine) { + start_newline(present_line_height, node); + if (gInAxiomCommand) { + text_x = indent + spadcom_indent; + } + else + text_x = indent; + } + + /* + * Now see if we am on the beginning of a line, and if not add some space + * if we need to + */ + + if (gInLine && node->space) + text_x += inter_word_space; + + node->x = text_x; + node->y = text_y - word_off_height; + text_x += incwidth; + gInLine = 1; +} + +static void +compute_verbatim_extent(TextNode *node) +{ + node->height = normal_text_height; + node->width = strlen(node->data.text); + + node->x = text_x; + node->y = text_y - word_off_height; + gInLine = 1; + return; +} + +static void +compute_spadsrctxt_extent(TextNode *node) +{ + node->height = normal_text_height; + node->width = strlen(node->data.text); + + if (gInLine) { + start_newline(present_line_height, node); + text_x = indent; + } + node->x = text_x; + node->y = text_y - word_off_height; + gInLine = 1; + return; +} + +static void +compute_dash_extent(TextNode *node) +{ + int num_dashes; + int twidth; + int nextwidth; + + node->height = normal_text_height; + + num_dashes = strlen(node->data.text); + + if (num_dashes > 1) + twidth = node->width = num_dashes * dash_width; + else + twidth = node->width = XTextWidth(gTopOfGroupStack->cur_font, + node->data.text, 1); + + if (gInLine && node->space) + twidth += inter_word_space; + + /* + * Now what we should do is find all the things after us that have no + * space in front and add there width on. + */ + + nextwidth = total_width(node->next, Endtokens); + + /* + * Should we start a new line? + */ + + if (text_x + twidth + nextwidth > right_margin) { + start_newline(present_line_height, node); + if (gInAxiomCommand) { + text_x = indent + spadcom_indent; + } + else + text_x = indent; + } + + /* + * Now see if we am on the beginning of a line, and if not add some space + * if we need to + */ + + if (gInLine && node->space) + text_x += inter_word_space; + + node->x = text_x; + if (num_dashes > 1) + node->y = text_y - dash_y; + else + node->y = text_y - word_off_height; + text_x += node->width; + gInLine = 1; + return; +} + +void +compute_text_extent(TextNode *node) +{ + for (; node != NULL; node = node->next) { + switch (node->type) { + case Endpastebutton: + endpastebutton_extent(node); + break; + case Paste: + compute_paste_extent(node); + break; + case Endpaste: + if (gInLine) { + start_newline(present_line_height, node); + text_x = indent; + } + break; + case Pastebutton: + compute_pastebutton_extent(node); + break; + case Ifcond: + compute_ifcond_extent(node); + break; + case Fi: + break; + case Endif: + if (if_node == NULL) { + return; + } + else + endif_extent(node); + break; + case Endcenter: + start_newline(present_line_height, node->next); + pop_group_stack(); + text_x = indent; + break; + case Pound: + case Macro: + /* check to see if we had space in front of me, if so add it */ + + if (node->space && gInLine) + text_x += inter_word_space; + break; + case Punctuation: + compute_punctuation_extent(node); + break; + case Endmath: + break; + case Endverbatim: + if (gInLine) { + start_newline(present_line_height, node); + text_x = indent; + } + break; + case Spadsrctxt: + compute_spadsrctxt_extent(node); + break; + case Math: + compute_word_extent(node); + break; + case Verbatim: + compute_verbatim_extent(node); + break; + case WindowId: + case Word: + case Lsquarebrace: + case Rsquarebrace: + compute_word_extent(node); + break; + case Dash: + compute_dash_extent(node); + break; + case HSpace: + node->height = line_height; + node->x = text_x; + node->y = text_y; + if (gInLine) { + text_x += + (node->data.node != NULL ? atoi(node->data.node->data.text) : 1); + } + break; + case VSpace: + node->height = line_height; + node->x = text_x; + node->y = text_y + present_line_height;; + text_y += + (node->data.node != NULL ? atoi(node->data.node->data.text) : 1) + + present_line_height; + past_line_height = (node->data.node != NULL ? + atoi(node->data.node->data.text) : 1) + + present_line_height; + + present_line_height = line_height; + break; + case Space: + node->height = line_height; + node->x = text_x; + node->y = text_y; + text_x += (gTopOfGroupStack->cur_font->max_bounds.width) * + (node->data.node != NULL ? atoi(node->data.node->data.text) : 1); + break; + case Tab: + node->height = line_height; + text_x = indent + (gTopOfGroupStack->cur_font->max_bounds.width) * + (node->data.node != NULL ? atoi(node->data.node->data.text) : 1); + gInLine = 0; + break; + case Par: + node->height = line_height; + if (gInItem) + text_x = indent; + else + text_x = indent + paragraph_space; + if (gInLine) { + start_newline(present_line_height, node); + } + break; + case Newline: + if (gInLine) { + start_newline(present_line_height, node); + text_x = indent; + } + break; + case Horizontalline: + if (gInLine) { + start_newline(present_line_height, node); + text_x = indent; + } + node->height = line_height; + gInLine = 0; + node->y = text_y - line_height / 2; + node->x = text_x; + start_newline(present_line_height, node); + break; + case Center: + compute_center_extent(node); + break; + case Box: + compute_box_extent(node); + break; + case Mbox: + compute_mbox_extent(node); + break; + case Beginitems: + case Begintitems: + compute_begin_items_extent(node); + break; + case Enditems: + case Endtitems: + pop_item_stack(); + if (gInLine) { + start_newline(present_line_height, node); + } + text_x = indent; + break; + case Titem: + if (gInLine) { + start_newline(present_line_height, node); + } + text_x = indent - item_space; + break; + case Item: + compute_item_extent(node); + break; + case Mitem: + compute_mitem_extent(node); + break; + case Upbutton: + case Returnbutton: + case Memolink: + case Downlink: + case Link: + case Windowlink: + compute_button_extent(node); + break; + case Unixlink: + case Lisplink: + case Lispwindowlink: + case Spadcall: + case Spadcallquit: + case Qspadcall: + case Qspadcallquit: + case LispDownLink: + case LispMemoLink: + case Lispcommand: + case Lispcommandquit: + case Spadlink: + case Spaddownlink: + case Spadmemolink: + case Unixcommand: + compute_button_extent(node); + break; + case Endbutton: + endbutton_extent(node); + break; + case Endlink: + if (link_node == NULL) + return; + else + endbutton_extent(node); + break; + case Spadsrc: + compute_spadsrc_extent(node); + break; + case Spadcommand: + case Spadgraph: + compute_spadcommand_extent(node); + break; + case Endspadsrc: + end_spadsrc_extent(node); + break; + case Endspadcommand: + end_spadcommand_extent(node); + break; + case Indent: + indent = left_margin + + atoi(node->data.node->data.text) * + (gTopOfGroupStack->cur_font->max_bounds.width); + if (!gInLine) + text_x = indent; + break; + case Indentrel: + indent += atoi(node->data.node->data.text) * + (gTopOfGroupStack->cur_font->max_bounds.width); + if (!gInLine) + text_x = indent; + break; + case Group: + push_group_stack(); + node->y = text_y; + if (gInLine && node->space) + text_x += inter_word_space; + break; + case Endgroup: + pop_group_stack(); + break; + case Tableitem: + push_group_stack(); + node->y = text_y; + if (gInLine && node->space) + text_x += inter_word_space; + break; + case Endtableitem: + pop_group_stack(); + return; + case Controlbitmap: + case Inputbitmap: + if (node->width == -1) + insert_bitmap_file(node); + compute_image_extent(node); + break; + case Inputpixmap: + if (node->width == -1) + insert_pixmap_file(node); + compute_image_extent(node); + break; + case Table: + compute_table_extent(&node); + break; + case BoldFace: + compute_bf_extent(node); + break; + case Emphasize: + compute_em_extent(node); + break; + case It: + compute_it_extent(node); + break; + case Rm: + case Sl: + case Tt: + compute_rm_extent(node); + break; + case Inputstring: + compute_input_extent(node); + break; + case SimpleBox: + case Radiobox: + compute_ir_extent(node); + break; + case Endbox: + text_x += box_width; + break; + case Endmacro: + case Endparameter: + break; + case Description: + bf_top_group(); + break; + case Enddescription: + pop_group_stack(); + if (gInDesc) + return; + break; + case Endscrolling: + + /* + * What we should do here is if we am in the middle of a line, we + * should end it here an now. + */ + + if (gInLine) + start_newline(present_line_height, node); + break; + case Noop: + noop_count++; + break; + case Endinputbox: + case Endheader: + case Endtitle: + case Endfooter: + case Rbrace: + case Free: + case Bound: + case Beep: + case 0: + break; + default: + fprintf(stderr, "Compute_text_extent: Unknown node type %d\n", + node->type); + break; + } + } +} + +static void +compute_begin_items_extent(TextNode * node) +{ + int store_x, store_y, lh; + + /* + * This routine pushes the current item_stack, and then tries to set the + * item_indent, and the indent level. It checks for an optional argument + * to begin{items} and if found uses its width. + */ + if (gInLine) { + start_newline(present_line_height, node); + } + store_x = text_x, store_y = text_y, lh = present_line_height; + text_x = indent; + push_item_stack(); + gInItem++; + item_indent = indent; + if (node->data.node != NULL) { + /* we have a desc */ + gInDesc = 1; + compute_text_extent(node->data.node); + gInDesc = 0; + item_space = text_width(node->data.node, Enddescription); + text_x = store_x; + text_y = store_y; + present_line_height = lh; + indent = item_indent + item_space; + } + else + indent = item_indent + 30; + gInLine = 0; +} + +static void +compute_item_extent(TextNode * node) +{ + if (gInLine) + start_newline(present_line_height, node); + text_x = item_indent; +} + +static void +compute_mitem_extent(TextNode *node) +{ + if (gInLine) { + start_newline(present_line_height, node); + } + text_x = item_indent; +} + +static void +endif_extent(TextNode *node) +{ + /* + * This node has the responsibilty for updating text_x and text_y so that + * they are the maxaimum width of teh else and then statements + */ + + text_x = if_node->x; + text_y = if_node->y; + if_node = NULL; +} + +static void +compute_ifcond_extent(TextNode *node) +{ + TextNode *condnode = node->data.ifnode->cond; + TextNode *tln = gLineNode; + int store_x = text_x, store_y = text_y, lh = present_line_height; + int then_x, then_y; + + /* + * This routine checks the value of the condition and swaps in the else + * or the then depending + */ + + /* + * we have to compute the maximum width and height of the rest of the + * text and stuff + */ + push_group_stack(); + if (gInLine && node->space) + text_x += inter_word_space; + compute_text_extent(node->data.ifnode->thennode); + then_x = text_x; + then_y = text_y; + text_x = store_x; + text_y = store_y; + present_line_height = lh; + gLineNode = tln; + if (gInLine && node->space) + text_x += inter_word_space; + compute_text_extent(node->data.ifnode->elsenode); + /* Now choose the best one that is biggest and put it into ifnode */ + if (then_y > text_y) { + node->y = then_y; + node->x = then_x; + } + else if (text_y > then_y) { + node->y = text_y; + node->x = text_x; + } + else if (text_x > then_x) { + node->y = text_y; + node->x = text_x; + } + else { + node->y = then_y; + node->x = then_x; + } + /* restore everything */ + text_x = store_x; + text_y = store_y; + present_line_height = lh; + gLineNode = tln; + node->width = 0; + + if_node = node; + if (gInLine && node->space) + text_x += inter_word_space; + if (check_condition(condnode)) { + node->next = node->data.ifnode->thennode; + } + else { + node->next = node->data.ifnode->elsenode; + } + pop_group_stack(); +} + +static void +compute_center_extent(TextNode * node) +{ + if (gInLine) + start_newline(present_line_height, node); + + center_top_group(); + + if (gLineNode) + text_x = indent; + else { + fprintf(stderr, "(HyperDoc) Internal error: unexpected state in compute_center_extent.\n"); + exit(-1); + } +} + +static void +compute_bf_extent(TextNode *node) +{ + if (gInLine && node->space) + text_x += inter_word_space; + node->x = text_x; + node->y = text_y; + bf_top_group(); +} + +static void +compute_em_extent(TextNode *node) +{ + if (gInLine && node->space) + text_x += inter_word_space; + node->x = text_x; + node->y = text_y; + if (gTopOfGroupStack->cur_font == gEmFont) + rm_top_group(); + else + em_top_group(); +} + +static void +compute_it_extent(TextNode *node) +{ + if (gInLine && node->space) + text_x += inter_word_space; + node->x = text_x; + node->y = text_y; +} + +static void +compute_rm_extent(TextNode *node) +{ + if (gInLine && node->space) + text_x += inter_word_space; + node->x = text_x; + node->y = text_y; + rm_top_group(); +} + +static void +compute_button_extent(TextNode *node) +{ + int twidth; + /*int store_x = text_x;*/ + /*int store_y = text_y;*/ + /*int lh = present_line_height;*/ + + push_active_group(); + + /* First see if we should leave a little space in front of myself * */ + if (gInLine && node->space) + text_x += inter_word_space; + + twidth = text_width(node->next, Endbutton); + if (gInLine && node->space) + text_x += inter_word_space; + if (text_x + twidth > right_margin && gInLine) { + start_newline(present_line_height, node); + text_x = indent; + } + node->x = text_x; + node->y = text_y; + link_node = node; +} + +static void +endbutton_extent(TextNode *node) +{ + int temp; + int height; + int twidth; + int y; + int maxx; + + maxx = max_x(link_node, Endbutton); + link_node->width = twidth = text_width(link_node->next, Endbutton); + height = link_node->y; + temp = text_height(link_node->next, Endbutton); + link_node->height = temp - link_node->y + line_height; + + if (gInLine) + y = text_y; + else + y = text_y - past_line_height; + if (y > height) { + link_node->y = temp; /* height + link_node->height - + * normal_text_height; */ + link_node->width = maxx - indent; + if (gInLine) { + start_newline(present_line_height, node); + text_x = indent; + } + } + else { + link_node->width = twidth; + link_node->y = text_y + link_node->height - line_height; + } + pop_group_stack(); + link_node = NULL; +} + +static void +compute_pastebutton_extent(TextNode *node) +{ + int twidth; + + push_active_group(); + + /* + First see if we should leave a little space in front of myself * */ + + if (gInLine && node->space) + text_x += inter_word_space; + + twidth = text_width(node->next, Endpastebutton); + if (gInLine && node->space) + text_x += inter_word_space; + if (text_x + twidth > right_margin && gInLine) { + start_newline(present_line_height, node); + text_x = indent; + } + node->x = text_x; + node->y = text_y; + paste_node = node; + return; +} + +static void +endpastebutton_extent(TextNode *node) +{ + int temp; + int height; + int twidth; + + paste_node->width = twidth = text_width(paste_node->next, Endpastebutton); + height = paste_node->y; + temp = text_height(paste_node->next, Endpastebutton); + paste_node->height = temp - paste_node->y + line_height; + if (text_y > height) { + paste_node->y = temp; + paste_node->width = right_margin - indent; + if (gInLine) { + start_newline(present_line_height, node); + text_x = indent; + } + } + else { + paste_node->width = twidth; + paste_node->y = text_y + paste_node->height - line_height; + } + pop_group_stack(); + paste_node = NULL; + gInLine = 1; +} + +static void +compute_paste_extent(TextNode *node) +{ + if (gInLine) { + start_newline(present_line_height, node); + text_x = indent; + } + node->x = text_x; + node->y = text_y; + node->height = line_height; +} + +/* Compute the text extent of a spadcommand node */ + +static void +compute_spadcommand_extent(TextNode *node) +{ + /* + * From now on if there is an example which will take over a line, then + * it will start and end with a newline + */ + + /*int height;*/ + int t_width; + /*int store_x = text_x;*/ + /*int store_y = text_y;*/ + /*int lh = present_line_height;*/ + + gInAxiomCommand = 1; + + push_spad_group(); + + /* Check to see if we should space in front of myself */ + if (gInLine && node->space) + text_x += inter_word_space; + t_width = text_width(node->next, Endspadcommand); + if (gInLine && ((text_x + t_width) > right_margin)) { + start_newline(present_line_height, node); + text_x = indent; + } + node->x = text_x; + node->y = text_y; + spad_node = node; + +} + +static void +compute_spadsrc_extent(TextNode *node) +{ + /* + * From now on if there is an example which will take over a line, then + * it will start and end with a newline + */ + + /*int store_x = text_x;*/ + /*int store_y = text_y;*/ + /*int lh = present_line_height;*/ + + gInAxiomCommand = 1; + + push_spad_group(); + + if (gInLine) { + start_newline(present_line_height, node); + text_x = indent; + } + node->x = text_x; + node->y = text_y; + spad_node = node; + +} + +static void +end_spadcommand_extent(TextNode *node) +{ + int temp; + int height; + int twidth; + int maxx; + /*int y = (gInLine) ? (text_y) : (text_y - past_line_height);*/ + + maxx = max_x(spad_node, Endspadcommand); + twidth = spad_node->width = text_width(spad_node->next, Endspadcommand); + height = spad_node->y; + temp = text_height(spad_node->next, Endspadcommand); + + spad_node->height = temp - height + line_height; + if (text_y > height && gInLine) { + spad_node->y = temp; + spad_node->width = maxx - indent; + start_newline(present_line_height, node); + text_x = indent; + } + else { + spad_node->width = twidth; + spad_node->y = text_y - line_height + spad_node->height; + } + pop_group_stack(); + gInAxiomCommand = 0; + spad_node = NULL; +} + +static void +end_spadsrc_extent(TextNode *node) +{ + int temp; + int height; + int twidth; + int maxx; + int y = (gInLine) ? (text_y) : (text_y - past_line_height); + + maxx = max_x(spad_node, Endspadsrc); + + twidth = spad_node->width = text_width(spad_node->next, Endspadsrc); + height = spad_node->y; + temp = text_height(spad_node->next, Endspadsrc); + spad_node->height = temp - height + line_height; + if (y > height && gInLine) { + spad_node->y = temp; + spad_node->width = maxx - indent; + start_newline(present_line_height, node); + text_x = indent; + } + else { + spad_node->width = twidth; + spad_node->y = text_y - line_height + spad_node->height; + } + pop_group_stack(); + gInAxiomCommand = 0; + spad_node = NULL; +} + +static void +compute_mbox_extent(TextNode *node) +{ + + node->width = text_width(node->next, Endmbox); + if (node->space) + text_x += inter_word_space; + if (text_x + node->width > right_margin) { + start_newline(present_line_height, node); + text_x = indent; + } + node->x = text_x; + node->y = text_y; +} + +static void +compute_box_extent(TextNode *node) +{ + int t_width; + + /* + * First thing we do is see if we need to skip some space in front of the + * word + */ + + if (gInLine && node->space) + text_x += inter_word_space; + + /* Calculate the actual width of the box */ + + t_width = text_width(node->next, Endbox) + 2 * box_width; + + if (text_x + t_width > right_margin) { + start_newline(present_line_height, node); + text_x = indent; + } + node->x = text_x; + text_x = text_x + box_width; + node->y = text_y - 2; + node->width = t_width; + node->height = line_height - 2; + gInLine = 1; +} + +static void +compute_ir_extent(TextNode *node) +{ + int t_width; + + /* + * First thing we do is see if we need to skip some space in front of the + * word + */ + + if (gInLine && node->space) + text_x += inter_word_space; + + /* Calculate the actual width of the box */ + + t_width = node->width; + + if (text_x + t_width > right_margin) { + start_newline(present_line_height, node); + text_x = indent; + } + node->x = text_x; + if (node->height > line_height) { + node->height = present_line_height = plh(node->height + inter_line_space); + node->y = text_y + node->height - normal_text_height; + } + else { + node->y = text_y - line_height + node->height; + } + gInLine = 1; + text_x += node->width; +} + +/* read a bitmap file into memory */ + +static void +compute_image_extent(TextNode *node) +{ + if (text_x + node->width > right_margin) { + start_newline(present_line_height, node); + text_x = indent; + } + node->x = text_x; + if (node->height > line_height) { + present_line_height = plh(node->height + inter_line_space); + node->y = text_y + node->height - line_height; + } + else { + node->y = text_y - line_height + node->height; + } + text_x += node->width; + gInLine = 1; +} + +/* + * compute the coordinates of the entries in a table + */ + +static void +compute_table_extent(TextNode **node) +{ + int num_cols, num_lines; + int max_width = 0, node_width, col_width; + int x, y, num_entries = 0,/* n=0, */ screen_width, table_top; + TextNode *front = *node; + TextNode *tn; + + gInTable = 1; + front->x = text_x; + front->y = text_y; + for (tn = front->next; tn->type != Endtable; num_entries++, tn = tn->next) { + /* Now we need to scan the table group by group */ + node_width = text_width(tn->next, Endtableitem); + if (node_width > max_width) + max_width = node_width; + /* Get to the beginning og the next group */ + for (; tn->type != Endtableitem; tn = tn->next); + } + col_width = max_width + min_inter_column_space; + screen_width = gWindow->width - right_margin_space - indent; + num_cols = screen_width / col_width; + if (num_cols == 0) + num_cols = 1; + num_lines = num_entries / num_cols; + if (num_entries % num_cols != 0) + ++num_lines; + if (gInLine) { + start_newline(present_line_height, *node); + } + table_top = text_y; + num_cols = num_entries / num_lines; + if (num_entries % num_lines != 0) + ++num_cols; + col_width = screen_width / num_cols; + for (tn = front->next, x = 0; x < num_cols; x++) + for (y = 0; y < num_lines && tn->type != Endtable; y++) { + if (num_cols == 1 && y > 0) + text_y += line_height; + else + text_y = table_top + y * line_height; + text_x = indent + x * col_width; + gInLine = 0; + compute_text_extent(tn->next); + for (; tn->type != Endtableitem; tn = tn->next); + tn = tn->next; + } + front->height = num_lines * line_height; + front->width = screen_width; + text_x = indent; + if (num_cols == 1) + text_y += line_height; + else + text_y = table_top + front->height; + *node = tn; + gInLine = 0; +} + +void +compute_title_extent(HyperDocPage *page) +{ + right_margin_space = non_scroll_right_margin_space; + page->title->height = twheight + gWindow->border_width; + page->title->x = gWindow->border_width + 2 * twwidth + (int) gWindow->border_width / 2; + gLineNode = page->title->next; + init_title_extents(page); + text_y = top_margin + line_height; + compute_text_extent(page->title->next); + page->title->height = max(text_height(page->title->next, Endtitle), + twheight); +} + +void +compute_header_extent(HyperDocPage *page) +{ + + /* + * Hopefully we will soon be able to actually compute the needed height + * for the header here + */ + + int ty; /* UNUSED */ + + gExtentRegion = Header; + right_margin_space = non_scroll_right_margin_space; + init_extents(); + ty = text_y = 3 * top_margin + line_height + max(page->title->height, twheight); + gLineNode = page->header->next; + compute_text_extent(page->header->next); + page->header->height = text_height(page->header->next, Endheader); + if (page->header->height) { + page->header->height += 1 / 2 * line_height; + page->top_scroll_margin = (gInLine) ? text_y : text_y - past_line_height; + if (!(page->page_flags & NOLINES)) + page->top_scroll_margin += (int) line_height / 2; + page->top_scroll_margin += gWindow->border_width + 2 * top_margin; + } + else { + page->top_scroll_margin = page->title->height + gWindow->border_width + + 2 * scroll_top_margin; + } +} + +void +compute_footer_extent(HyperDocPage * page) +{ + if (page->footer) { + gExtentRegion = Footer; + right_margin_space = non_scroll_right_margin_space; + init_extents(); + present_line_height = line_height; + text_y = line_height; + gLineNode = page->footer->next; + compute_text_extent(page->footer->next); + page->footer->height = text_height(page->footer->next, Endfooter); + if (page->footer->height) { + if ((!page->page_flags & NOLINES)) + page->footer->height += (int) line_height / 2; + page->bot_scroll_margin = gWindow->height - + page->footer->height - bottom_margin + - gWindow->border_width + top_margin; + } + else + page->bot_scroll_margin = gWindow->height; + } +} + +void +compute_scrolling_extent(HyperDocPage *page) +{ + /* Check to see if there is a scrolling region */ + + if (!page->scrolling) { + return; + } + noop_count = 0; + + /* If there is then compute all the proper locations */ + gExtentRegion = Scrolling; + right_margin_space = non_scroll_right_margin_space + gScrollbarWidth; + init_extents(); + text_y = line_height; + gLineNode = page->scrolling->next; + compute_text_extent(page->scrolling->next); + + /* + * the following is an attempt to fix the bug where one cannot scroll + * down to a bitmap that is opened at the bottom of a page. + */ + + /* + * TTT trial if(!gInLine) + */ + if (0) { + text_y = text_y - past_line_height; + } + else if (present_line_height > line_height) + text_y = text_y + present_line_height - line_height; + page->scrolling->height = text_y; + +} diff --git a/src/hyper/extent1.pamphlet b/src/hyper/extent1.pamphlet deleted file mode 100644 index a7263f5e..00000000 --- a/src/hyper/extent1.pamphlet +++ /dev/null @@ -1,1395 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/extent1} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{extent1.c} -<>= -/****************************************************************************** - * - * extent1.h: HyperDoc extent computation routines - * - * Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993. - * - ****************************************************************************/ -#define _EXTENT1_C -#include "axiom-c-macros.h" -#include "useproto.h" -#include "debug.h" - - -#include "extent.h" -#include "cond.h" -#include "group.h" -#include "titlebar.h" -#include "scrollbar.h" - -#include "all_hyper_proto.H1" - - -/* - * Now we declare all the values which are shared among the extent routines - * and the showing routines - */ - -int noop_count; - -TextNode *link_node = NULL; -TextNode *paste_node = NULL; -TextNode *spad_node = NULL; -TextNode *if_node = NULL; - - -short int gExtentRegion; - - -short int gInDesc; -short int gInLine; /* true iff there have been words printed */ -short int gInItem; /* true iff we are in a \item */ -short int gInAxiomCommand; /* true iff we are in a \spadcommand */ -short int gInTable; - -/* Variables for the formatting state */ - -int right_margin_space; -int right_margin; -int indent; -int item_indent; -int text_x; -int text_y; -int y_off; -int scroll_bot; -int need_scroll_up_button; -int need_scroll_down_button; -int item_space; -int present_line_height; -int past_line_height; -int line_height; /* space between lines */ -int normal_text_height; /* space between lines */ -int space_width; /* the maximum width of a character */ -int word_off_height; /* the diff between text height and */ - -TextNode *gLineNode; - -/* - * Computes the extent of the input string or box - */ - -static void -compute_input_extent(TextNode * node) -{ - InputItem *item; - int t_width; - int num_lines; - - /* search the symbol table for the proper entry */ - - item = node->link->reference.string; - num_lines = item->num_lines; - - /* - * Once we have gotten this far, we should just be able to calculate the - * width using the normal font - */ - - t_width = (item->size + 1) * gInputFont->max_bounds.width + 10; - - if (gInLine) - text_x += inter_word_space; - - if (text_x + t_width > right_margin) { - start_newline(present_line_height, node); - text_x = indent; - } - node->x = text_x; - - /* now figure out the height of the current window */ - - node->height = line_height * (num_lines); - node->y = text_y - line_height + node->height - 1; - if (node->height > present_line_height) - present_line_height = plh(node->height); - node->width = t_width; - gInLine = 1; - text_x += t_width; -} - -static void -compute_punctuation_extent(TextNode * node) -{ - int twidth; - int nextwidth; - int incwidth; - - node->height = normal_text_height; - node->width = strlen(node->data.text); - incwidth = twidth = XTextWidth(gTopOfGroupStack->cur_font, node->data.text, - node->width); - - /* always check to see if there was some space in front of us */ - - if (gInLine && (node->space & FRONTSPACE)) - twidth += inter_word_space; - - /* - * now calcualte the width of the next one if it needs to be considered - */ - - if (!(node->space & BACKSPACE)) - nextwidth = total_width(node->next, Endtokens); - else - nextwidth = 0; - - if ((!(node->space & BACKSPACE)) && - (text_x + twidth + nextwidth > right_margin) && gInLine) { - start_newline(present_line_height, node); - if (gInAxiomCommand) { - text_x = indent + spadcom_indent; - } - else - text_x = indent; - } - - if (node->space & FRONTSPACE) - text_x += inter_word_space; - - node->x = text_x; - - /* - * Now try to see if we should leave space after myself. Always leave - * space when there is space - */ - - if (node->space & BACKSPACE) { - switch (node->data.text[0]) { - case '.': - case '?': - case '!': - text_x += term_punct_space; - break; - } - } - - text_x += incwidth; - node->y = text_y - word_off_height; - gInLine = 1; -} - -static void -compute_word_extent(TextNode * node) -{ - int twidth; - int nextwidth; - int incwidth; - - node->height = normal_text_height; - node->width = strlen(node->data.text); - incwidth = twidth = XTextWidth(gTopOfGroupStack->cur_font, node->data.text, - node->width); - - /* - * Now if we should drop some space in front of me, then add it to twidth - */ - - if (gInLine && node->space) - twidth += inter_word_space; - - /* - * Now what we should do is find all the things after us that have no - * space in front and add there width on. - */ - - nextwidth = total_width(node->next, Endtokens); - - - /* - * Should we start a new line? - */ - - if (text_x + twidth + nextwidth > right_margin && gInLine) { - start_newline(present_line_height, node); - if (gInAxiomCommand) { - text_x = indent + spadcom_indent; - } - else - text_x = indent; - } - - /* - * Now see if we am on the beginning of a line, and if not add some space - * if we need to - */ - - if (gInLine && node->space) - text_x += inter_word_space; - - node->x = text_x; - node->y = text_y - word_off_height; - text_x += incwidth; - gInLine = 1; -} - -static void -compute_verbatim_extent(TextNode *node) -{ - node->height = normal_text_height; - node->width = strlen(node->data.text); - - node->x = text_x; - node->y = text_y - word_off_height; - gInLine = 1; - return; -} - -static void -compute_spadsrctxt_extent(TextNode *node) -{ - node->height = normal_text_height; - node->width = strlen(node->data.text); - - if (gInLine) { - start_newline(present_line_height, node); - text_x = indent; - } - node->x = text_x; - node->y = text_y - word_off_height; - gInLine = 1; - return; -} - -static void -compute_dash_extent(TextNode *node) -{ - int num_dashes; - int twidth; - int nextwidth; - - node->height = normal_text_height; - - num_dashes = strlen(node->data.text); - - if (num_dashes > 1) - twidth = node->width = num_dashes * dash_width; - else - twidth = node->width = XTextWidth(gTopOfGroupStack->cur_font, - node->data.text, 1); - - if (gInLine && node->space) - twidth += inter_word_space; - - /* - * Now what we should do is find all the things after us that have no - * space in front and add there width on. - */ - - nextwidth = total_width(node->next, Endtokens); - - /* - * Should we start a new line? - */ - - if (text_x + twidth + nextwidth > right_margin) { - start_newline(present_line_height, node); - if (gInAxiomCommand) { - text_x = indent + spadcom_indent; - } - else - text_x = indent; - } - - /* - * Now see if we am on the beginning of a line, and if not add some space - * if we need to - */ - - if (gInLine && node->space) - text_x += inter_word_space; - - node->x = text_x; - if (num_dashes > 1) - node->y = text_y - dash_y; - else - node->y = text_y - word_off_height; - text_x += node->width; - gInLine = 1; - return; -} - -void -compute_text_extent(TextNode *node) -{ - for (; node != NULL; node = node->next) { - switch (node->type) { - case Endpastebutton: - endpastebutton_extent(node); - break; - case Paste: - compute_paste_extent(node); - break; - case Endpaste: - if (gInLine) { - start_newline(present_line_height, node); - text_x = indent; - } - break; - case Pastebutton: - compute_pastebutton_extent(node); - break; - case Ifcond: - compute_ifcond_extent(node); - break; - case Fi: - break; - case Endif: - if (if_node == NULL) { - return; - } - else - endif_extent(node); - break; - case Endcenter: - start_newline(present_line_height, node->next); - pop_group_stack(); - text_x = indent; - break; - case Pound: - case Macro: - /* check to see if we had space in front of me, if so add it */ - - if (node->space && gInLine) - text_x += inter_word_space; - break; - case Punctuation: - compute_punctuation_extent(node); - break; - case Endmath: - break; - case Endverbatim: - if (gInLine) { - start_newline(present_line_height, node); - text_x = indent; - } - break; - case Spadsrctxt: - compute_spadsrctxt_extent(node); - break; - case Math: - compute_word_extent(node); - break; - case Verbatim: - compute_verbatim_extent(node); - break; - case WindowId: - case Word: - case Lsquarebrace: - case Rsquarebrace: - compute_word_extent(node); - break; - case Dash: - compute_dash_extent(node); - break; - case HSpace: - node->height = line_height; - node->x = text_x; - node->y = text_y; - if (gInLine) { - text_x += - (node->data.node != NULL ? atoi(node->data.node->data.text) : 1); - } - break; - case VSpace: - node->height = line_height; - node->x = text_x; - node->y = text_y + present_line_height;; - text_y += - (node->data.node != NULL ? atoi(node->data.node->data.text) : 1) + - present_line_height; - past_line_height = (node->data.node != NULL ? - atoi(node->data.node->data.text) : 1) - + present_line_height; - - present_line_height = line_height; - break; - case Space: - node->height = line_height; - node->x = text_x; - node->y = text_y; - text_x += (gTopOfGroupStack->cur_font->max_bounds.width) * - (node->data.node != NULL ? atoi(node->data.node->data.text) : 1); - break; - case Tab: - node->height = line_height; - text_x = indent + (gTopOfGroupStack->cur_font->max_bounds.width) * - (node->data.node != NULL ? atoi(node->data.node->data.text) : 1); - gInLine = 0; - break; - case Par: - node->height = line_height; - if (gInItem) - text_x = indent; - else - text_x = indent + paragraph_space; - if (gInLine) { - start_newline(present_line_height, node); - } - break; - case Newline: - if (gInLine) { - start_newline(present_line_height, node); - text_x = indent; - } - break; - case Horizontalline: - if (gInLine) { - start_newline(present_line_height, node); - text_x = indent; - } - node->height = line_height; - gInLine = 0; - node->y = text_y - line_height / 2; - node->x = text_x; - start_newline(present_line_height, node); - break; - case Center: - compute_center_extent(node); - break; - case Box: - compute_box_extent(node); - break; - case Mbox: - compute_mbox_extent(node); - break; - case Beginitems: - case Begintitems: - compute_begin_items_extent(node); - break; - case Enditems: - case Endtitems: - pop_item_stack(); - if (gInLine) { - start_newline(present_line_height, node); - } - text_x = indent; - break; - case Titem: - if (gInLine) { - start_newline(present_line_height, node); - } - text_x = indent - item_space; - break; - case Item: - compute_item_extent(node); - break; - case Mitem: - compute_mitem_extent(node); - break; - case Upbutton: - case Returnbutton: - case Memolink: - case Downlink: - case Link: - case Windowlink: - compute_button_extent(node); - break; - case Unixlink: - case Lisplink: - case Lispwindowlink: - case Spadcall: - case Spadcallquit: - case Qspadcall: - case Qspadcallquit: - case LispDownLink: - case LispMemoLink: - case Lispcommand: - case Lispcommandquit: - case Spadlink: - case Spaddownlink: - case Spadmemolink: - case Unixcommand: - compute_button_extent(node); - break; - case Endbutton: - endbutton_extent(node); - break; - case Endlink: - if (link_node == NULL) - return; - else - endbutton_extent(node); - break; - case Spadsrc: - compute_spadsrc_extent(node); - break; - case Spadcommand: - case Spadgraph: - compute_spadcommand_extent(node); - break; - case Endspadsrc: - end_spadsrc_extent(node); - break; - case Endspadcommand: - end_spadcommand_extent(node); - break; - case Indent: - indent = left_margin + - atoi(node->data.node->data.text) * - (gTopOfGroupStack->cur_font->max_bounds.width); - if (!gInLine) - text_x = indent; - break; - case Indentrel: - indent += atoi(node->data.node->data.text) * - (gTopOfGroupStack->cur_font->max_bounds.width); - if (!gInLine) - text_x = indent; - break; - case Group: - push_group_stack(); - node->y = text_y; - if (gInLine && node->space) - text_x += inter_word_space; - break; - case Endgroup: - pop_group_stack(); - break; - case Tableitem: - push_group_stack(); - node->y = text_y; - if (gInLine && node->space) - text_x += inter_word_space; - break; - case Endtableitem: - pop_group_stack(); - return; - case Controlbitmap: - case Inputbitmap: - if (node->width == -1) - insert_bitmap_file(node); - compute_image_extent(node); - break; - case Inputpixmap: - if (node->width == -1) - insert_pixmap_file(node); - compute_image_extent(node); - break; - case Table: - compute_table_extent(&node); - break; - case BoldFace: - compute_bf_extent(node); - break; - case Emphasize: - compute_em_extent(node); - break; - case It: - compute_it_extent(node); - break; - case Rm: - case Sl: - case Tt: - compute_rm_extent(node); - break; - case Inputstring: - compute_input_extent(node); - break; - case SimpleBox: - case Radiobox: - compute_ir_extent(node); - break; - case Endbox: - text_x += box_width; - break; - case Endmacro: - case Endparameter: - break; - case Description: - bf_top_group(); - break; - case Enddescription: - pop_group_stack(); - if (gInDesc) - return; - break; - case Endscrolling: - - /* - * What we should do here is if we am in the middle of a line, we - * should end it here an now. - */ - - if (gInLine) - start_newline(present_line_height, node); - break; - case Noop: - noop_count++; - break; - case Endinputbox: - case Endheader: - case Endtitle: - case Endfooter: - case Rbrace: - case Free: - case Bound: - case Beep: - case 0: - break; - default: - fprintf(stderr, "Compute_text_extent: Unknown node type %d\n", - node->type); - break; - } - } -} - -static void -compute_begin_items_extent(TextNode * node) -{ - int store_x, store_y, lh; - - /* - * This routine pushes the current item_stack, and then tries to set the - * item_indent, and the indent level. It checks for an optional argument - * to begin{items} and if found uses its width. - */ - if (gInLine) { - start_newline(present_line_height, node); - } - store_x = text_x, store_y = text_y, lh = present_line_height; - text_x = indent; - push_item_stack(); - gInItem++; - item_indent = indent; - if (node->data.node != NULL) { - /* we have a desc */ - gInDesc = 1; - compute_text_extent(node->data.node); - gInDesc = 0; - item_space = text_width(node->data.node, Enddescription); - text_x = store_x; - text_y = store_y; - present_line_height = lh; - indent = item_indent + item_space; - } - else - indent = item_indent + 30; - gInLine = 0; -} - -static void -compute_item_extent(TextNode * node) -{ - if (gInLine) - start_newline(present_line_height, node); - text_x = item_indent; -} - -static void -compute_mitem_extent(TextNode *node) -{ - if (gInLine) { - start_newline(present_line_height, node); - } - text_x = item_indent; -} - -static void -endif_extent(TextNode *node) -{ - /* - * This node has the responsibilty for updating text_x and text_y so that - * they are the maxaimum width of teh else and then statements - */ - - text_x = if_node->x; - text_y = if_node->y; - if_node = NULL; -} - -static void -compute_ifcond_extent(TextNode *node) -{ - TextNode *condnode = node->data.ifnode->cond; - TextNode *tln = gLineNode; - int store_x = text_x, store_y = text_y, lh = present_line_height; - int then_x, then_y; - - /* - * This routine checks the value of the condition and swaps in the else - * or the then depending - */ - - /* - * we have to compute the maximum width and height of the rest of the - * text and stuff - */ - push_group_stack(); - if (gInLine && node->space) - text_x += inter_word_space; - compute_text_extent(node->data.ifnode->thennode); - then_x = text_x; - then_y = text_y; - text_x = store_x; - text_y = store_y; - present_line_height = lh; - gLineNode = tln; - if (gInLine && node->space) - text_x += inter_word_space; - compute_text_extent(node->data.ifnode->elsenode); - /* Now choose the best one that is biggest and put it into ifnode */ - if (then_y > text_y) { - node->y = then_y; - node->x = then_x; - } - else if (text_y > then_y) { - node->y = text_y; - node->x = text_x; - } - else if (text_x > then_x) { - node->y = text_y; - node->x = text_x; - } - else { - node->y = then_y; - node->x = then_x; - } - /* restore everything */ - text_x = store_x; - text_y = store_y; - present_line_height = lh; - gLineNode = tln; - node->width = 0; - - if_node = node; - if (gInLine && node->space) - text_x += inter_word_space; - if (check_condition(condnode)) { - node->next = node->data.ifnode->thennode; - } - else { - node->next = node->data.ifnode->elsenode; - } - pop_group_stack(); -} - -static void -compute_center_extent(TextNode * node) -{ - if (gInLine) - start_newline(present_line_height, node); - - center_top_group(); - - if (gLineNode) - text_x = indent; - else { - fprintf(stderr, "(HyperDoc) Internal error: unexpected state in compute_center_extent.\n"); - exit(-1); - } -} - -static void -compute_bf_extent(TextNode *node) -{ - if (gInLine && node->space) - text_x += inter_word_space; - node->x = text_x; - node->y = text_y; - bf_top_group(); -} - -static void -compute_em_extent(TextNode *node) -{ - if (gInLine && node->space) - text_x += inter_word_space; - node->x = text_x; - node->y = text_y; - if (gTopOfGroupStack->cur_font == gEmFont) - rm_top_group(); - else - em_top_group(); -} - -static void -compute_it_extent(TextNode *node) -{ - if (gInLine && node->space) - text_x += inter_word_space; - node->x = text_x; - node->y = text_y; -} - -static void -compute_rm_extent(TextNode *node) -{ - if (gInLine && node->space) - text_x += inter_word_space; - node->x = text_x; - node->y = text_y; - rm_top_group(); -} - -static void -compute_button_extent(TextNode *node) -{ - int twidth; - /*int store_x = text_x;*/ - /*int store_y = text_y;*/ - /*int lh = present_line_height;*/ - - push_active_group(); - - /* First see if we should leave a little space in front of myself * */ - if (gInLine && node->space) - text_x += inter_word_space; - - twidth = text_width(node->next, Endbutton); - if (gInLine && node->space) - text_x += inter_word_space; - if (text_x + twidth > right_margin && gInLine) { - start_newline(present_line_height, node); - text_x = indent; - } - node->x = text_x; - node->y = text_y; - link_node = node; -} - -static void -endbutton_extent(TextNode *node) -{ - int temp; - int height; - int twidth; - int y; - int maxx; - - maxx = max_x(link_node, Endbutton); - link_node->width = twidth = text_width(link_node->next, Endbutton); - height = link_node->y; - temp = text_height(link_node->next, Endbutton); - link_node->height = temp - link_node->y + line_height; - - if (gInLine) - y = text_y; - else - y = text_y - past_line_height; - if (y > height) { - link_node->y = temp; /* height + link_node->height - - * normal_text_height; */ - link_node->width = maxx - indent; - if (gInLine) { - start_newline(present_line_height, node); - text_x = indent; - } - } - else { - link_node->width = twidth; - link_node->y = text_y + link_node->height - line_height; - } - pop_group_stack(); - link_node = NULL; -} - -static void -compute_pastebutton_extent(TextNode *node) -{ - int twidth; - - push_active_group(); - - /* - First see if we should leave a little space in front of myself * */ - - if (gInLine && node->space) - text_x += inter_word_space; - - twidth = text_width(node->next, Endpastebutton); - if (gInLine && node->space) - text_x += inter_word_space; - if (text_x + twidth > right_margin && gInLine) { - start_newline(present_line_height, node); - text_x = indent; - } - node->x = text_x; - node->y = text_y; - paste_node = node; - return; -} - -static void -endpastebutton_extent(TextNode *node) -{ - int temp; - int height; - int twidth; - - paste_node->width = twidth = text_width(paste_node->next, Endpastebutton); - height = paste_node->y; - temp = text_height(paste_node->next, Endpastebutton); - paste_node->height = temp - paste_node->y + line_height; - if (text_y > height) { - paste_node->y = temp; - paste_node->width = right_margin - indent; - if (gInLine) { - start_newline(present_line_height, node); - text_x = indent; - } - } - else { - paste_node->width = twidth; - paste_node->y = text_y + paste_node->height - line_height; - } - pop_group_stack(); - paste_node = NULL; - gInLine = 1; -} - -static void -compute_paste_extent(TextNode *node) -{ - if (gInLine) { - start_newline(present_line_height, node); - text_x = indent; - } - node->x = text_x; - node->y = text_y; - node->height = line_height; -} - -/* Compute the text extent of a spadcommand node */ - -static void -compute_spadcommand_extent(TextNode *node) -{ - /* - * From now on if there is an example which will take over a line, then - * it will start and end with a newline - */ - - /*int height;*/ - int t_width; - /*int store_x = text_x;*/ - /*int store_y = text_y;*/ - /*int lh = present_line_height;*/ - - gInAxiomCommand = 1; - - push_spad_group(); - - /* Check to see if we should space in front of myself */ - if (gInLine && node->space) - text_x += inter_word_space; - t_width = text_width(node->next, Endspadcommand); - if (gInLine && ((text_x + t_width) > right_margin)) { - start_newline(present_line_height, node); - text_x = indent; - } - node->x = text_x; - node->y = text_y; - spad_node = node; - -} - -static void -compute_spadsrc_extent(TextNode *node) -{ - /* - * From now on if there is an example which will take over a line, then - * it will start and end with a newline - */ - - /*int store_x = text_x;*/ - /*int store_y = text_y;*/ - /*int lh = present_line_height;*/ - - gInAxiomCommand = 1; - - push_spad_group(); - - if (gInLine) { - start_newline(present_line_height, node); - text_x = indent; - } - node->x = text_x; - node->y = text_y; - spad_node = node; - -} - -static void -end_spadcommand_extent(TextNode *node) -{ - int temp; - int height; - int twidth; - int maxx; - /*int y = (gInLine) ? (text_y) : (text_y - past_line_height);*/ - - maxx = max_x(spad_node, Endspadcommand); - twidth = spad_node->width = text_width(spad_node->next, Endspadcommand); - height = spad_node->y; - temp = text_height(spad_node->next, Endspadcommand); - - spad_node->height = temp - height + line_height; - if (text_y > height && gInLine) { - spad_node->y = temp; - spad_node->width = maxx - indent; - start_newline(present_line_height, node); - text_x = indent; - } - else { - spad_node->width = twidth; - spad_node->y = text_y - line_height + spad_node->height; - } - pop_group_stack(); - gInAxiomCommand = 0; - spad_node = NULL; -} - -static void -end_spadsrc_extent(TextNode *node) -{ - int temp; - int height; - int twidth; - int maxx; - int y = (gInLine) ? (text_y) : (text_y - past_line_height); - - maxx = max_x(spad_node, Endspadsrc); - - twidth = spad_node->width = text_width(spad_node->next, Endspadsrc); - height = spad_node->y; - temp = text_height(spad_node->next, Endspadsrc); - spad_node->height = temp - height + line_height; - if (y > height && gInLine) { - spad_node->y = temp; - spad_node->width = maxx - indent; - start_newline(present_line_height, node); - text_x = indent; - } - else { - spad_node->width = twidth; - spad_node->y = text_y - line_height + spad_node->height; - } - pop_group_stack(); - gInAxiomCommand = 0; - spad_node = NULL; -} - -static void -compute_mbox_extent(TextNode *node) -{ - - node->width = text_width(node->next, Endmbox); - if (node->space) - text_x += inter_word_space; - if (text_x + node->width > right_margin) { - start_newline(present_line_height, node); - text_x = indent; - } - node->x = text_x; - node->y = text_y; -} - -static void -compute_box_extent(TextNode *node) -{ - int t_width; - - /* - * First thing we do is see if we need to skip some space in front of the - * word - */ - - if (gInLine && node->space) - text_x += inter_word_space; - - /* Calculate the actual width of the box */ - - t_width = text_width(node->next, Endbox) + 2 * box_width; - - if (text_x + t_width > right_margin) { - start_newline(present_line_height, node); - text_x = indent; - } - node->x = text_x; - text_x = text_x + box_width; - node->y = text_y - 2; - node->width = t_width; - node->height = line_height - 2; - gInLine = 1; -} - -static void -compute_ir_extent(TextNode *node) -{ - int t_width; - - /* - * First thing we do is see if we need to skip some space in front of the - * word - */ - - if (gInLine && node->space) - text_x += inter_word_space; - - /* Calculate the actual width of the box */ - - t_width = node->width; - - if (text_x + t_width > right_margin) { - start_newline(present_line_height, node); - text_x = indent; - } - node->x = text_x; - if (node->height > line_height) { - node->height = present_line_height = plh(node->height + inter_line_space); - node->y = text_y + node->height - normal_text_height; - } - else { - node->y = text_y - line_height + node->height; - } - gInLine = 1; - text_x += node->width; -} - -/* read a bitmap file into memory */ - -static void -compute_image_extent(TextNode *node) -{ - if (text_x + node->width > right_margin) { - start_newline(present_line_height, node); - text_x = indent; - } - node->x = text_x; - if (node->height > line_height) { - present_line_height = plh(node->height + inter_line_space); - node->y = text_y + node->height - line_height; - } - else { - node->y = text_y - line_height + node->height; - } - text_x += node->width; - gInLine = 1; -} - -/* - * compute the coordinates of the entries in a table - */ - -static void -compute_table_extent(TextNode **node) -{ - int num_cols, num_lines; - int max_width = 0, node_width, col_width; - int x, y, num_entries = 0,/* n=0, */ screen_width, table_top; - TextNode *front = *node; - TextNode *tn; - - gInTable = 1; - front->x = text_x; - front->y = text_y; - for (tn = front->next; tn->type != Endtable; num_entries++, tn = tn->next) { - /* Now we need to scan the table group by group */ - node_width = text_width(tn->next, Endtableitem); - if (node_width > max_width) - max_width = node_width; - /* Get to the beginning og the next group */ - for (; tn->type != Endtableitem; tn = tn->next); - } - col_width = max_width + min_inter_column_space; - screen_width = gWindow->width - right_margin_space - indent; - num_cols = screen_width / col_width; - if (num_cols == 0) - num_cols = 1; - num_lines = num_entries / num_cols; - if (num_entries % num_cols != 0) - ++num_lines; - if (gInLine) { - start_newline(present_line_height, *node); - } - table_top = text_y; - num_cols = num_entries / num_lines; - if (num_entries % num_lines != 0) - ++num_cols; - col_width = screen_width / num_cols; - for (tn = front->next, x = 0; x < num_cols; x++) - for (y = 0; y < num_lines && tn->type != Endtable; y++) { - if (num_cols == 1 && y > 0) - text_y += line_height; - else - text_y = table_top + y * line_height; - text_x = indent + x * col_width; - gInLine = 0; - compute_text_extent(tn->next); - for (; tn->type != Endtableitem; tn = tn->next); - tn = tn->next; - } - front->height = num_lines * line_height; - front->width = screen_width; - text_x = indent; - if (num_cols == 1) - text_y += line_height; - else - text_y = table_top + front->height; - *node = tn; - gInLine = 0; -} - -void -compute_title_extent(HyperDocPage *page) -{ - right_margin_space = non_scroll_right_margin_space; - page->title->height = twheight + gWindow->border_width; - page->title->x = gWindow->border_width + 2 * twwidth + (int) gWindow->border_width / 2; - gLineNode = page->title->next; - init_title_extents(page); - text_y = top_margin + line_height; - compute_text_extent(page->title->next); - page->title->height = max(text_height(page->title->next, Endtitle), - twheight); -} - -void -compute_header_extent(HyperDocPage *page) -{ - - /* - * Hopefully we will soon be able to actually compute the needed height - * for the header here - */ - - int ty; /* UNUSED */ - - gExtentRegion = Header; - right_margin_space = non_scroll_right_margin_space; - init_extents(); - ty = text_y = 3 * top_margin + line_height + max(page->title->height, twheight); - gLineNode = page->header->next; - compute_text_extent(page->header->next); - page->header->height = text_height(page->header->next, Endheader); - if (page->header->height) { - page->header->height += 1 / 2 * line_height; - page->top_scroll_margin = (gInLine) ? text_y : text_y - past_line_height; - if (!(page->page_flags & NOLINES)) - page->top_scroll_margin += (int) line_height / 2; - page->top_scroll_margin += gWindow->border_width + 2 * top_margin; - } - else { - page->top_scroll_margin = page->title->height + gWindow->border_width + - 2 * scroll_top_margin; - } -} - -void -compute_footer_extent(HyperDocPage * page) -{ - if (page->footer) { - gExtentRegion = Footer; - right_margin_space = non_scroll_right_margin_space; - init_extents(); - present_line_height = line_height; - text_y = line_height; - gLineNode = page->footer->next; - compute_text_extent(page->footer->next); - page->footer->height = text_height(page->footer->next, Endfooter); - if (page->footer->height) { - if ((!page->page_flags & NOLINES)) - page->footer->height += (int) line_height / 2; - page->bot_scroll_margin = gWindow->height - - page->footer->height - bottom_margin - - gWindow->border_width + top_margin; - } - else - page->bot_scroll_margin = gWindow->height; - } -} - -void -compute_scrolling_extent(HyperDocPage *page) -{ - /* Check to see if there is a scrolling region */ - - if (!page->scrolling) { - return; - } - noop_count = 0; - - /* If there is then compute all the proper locations */ - gExtentRegion = Scrolling; - right_margin_space = non_scroll_right_margin_space + gScrollbarWidth; - init_extents(); - text_y = line_height; - gLineNode = page->scrolling->next; - compute_text_extent(page->scrolling->next); - - /* - * the following is an attempt to fix the bug where one cannot scroll - * down to a bitmap that is opened at the bottom of a page. - */ - - /* - * TTT trial if(!gInLine) - */ - if (0) { - text_y = text_y - past_line_height; - } - else if (present_line_height > line_height) - text_y = text_y + present_line_height - line_height; - page->scrolling->height = text_y; - -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} diff --git a/src/hyper/extent2.c b/src/hyper/extent2.c new file mode 100644 index 00000000..5a7a6848 --- /dev/null +++ b/src/hyper/extent2.c @@ -0,0 +1,929 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +/****************************************************************************** + * + * extent2.h: HyperDoc extent computation routines + * + * Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993. + * + ****************************************************************************/ +#define _EXTENT2_C +#include "axiom-c-macros.h" +#include "useproto.h" +#include "debug.h" + + +#include "extent.h" +#include "group.h" +#include "titlebar.h" + +#include "all_hyper_proto.H1" +#include "pixmap.H1" + + +static int cur_height = 0; +static int max_x_value = 0; + +/* + * start_newline updates the current header node, and also allocates if needed + * memory for the next Line Header. It also assigns the first TextNode on the + * line to the structure, because this is the last time I will be able to do + * this + */ + +void +start_newline(int distance, TextNode * node) +{ + if (gLineNode != NULL) { + if (gTopOfGroupStack->center) + center_nodes(gLineNode, node); + gLineNode = node; + } + text_y += distance; + past_line_height = distance; + present_line_height = line_height; + gInLine = 0; +} + +/* + * center_nodes goes through and centers all the text between the two + * given nodes. + */ + +static void +center_nodes(TextNode * begin_node, TextNode * end_node) +{ + int begin_x, end_x, wmid_x, offset, mid_x; + TextNode *node; + + end_x = text_x; + begin_x = x_value(begin_node); + mid_x = (int) (end_x + begin_x) / 2; + wmid_x = (int) (right_margin + indent) / 2; + + if (mid_x > wmid_x) + offset = 0; + else + offset = wmid_x - mid_x; + + for (node = begin_node; node != end_node; node = node->next) + if (node->x > 0) + node->x += offset; +} + +static int +punctuation_width(TextNode * node) +{ + int twidth, width = strlen(node->data.text); + + twidth = XTextWidth(gTopOfGroupStack->cur_font, node->data.text, width); + + /* check to see if there was some space in front */ + + if (gInLine && (node->space & FRONTSPACE)) + twidth += inter_word_space; + +# if 0 + if (node->space & BACKSPACE) { + switch (node->data.text[0]) { + case '.': + case '?': + case '!': + twidth += term_punct_space; + break; + } + } +#endif + + return twidth; +} + +static int +input_string_width(TextNode * node) +{ + InputItem *item; + int t_width; + + /** search the symbol table for the proper entry **/ + + item = node->link->reference.string; + + /** Once I have gotten this far, I should just be able to calculate + the width using the normal font **/ + + t_width = (item->size + 1) * gInputFont->max_bounds.width + 10; + return t_width; + +} + +static int +word_width(TextNode * node) +{ + int twidth, len = strlen(node->data.text); + + twidth = XTextWidth(gTopOfGroupStack->cur_font, node->data.text, len); + if (node->space & FRONTSPACE) + twidth += inter_word_space; + + return twidth; +} + +static int +verbatim_width(TextNode * node) +{ + int twidth, len = strlen(node->data.text); + + twidth = XTextWidth(gTopOfGroupStack->cur_font, node->data.text, len); + if (node->space) + twidth += inter_word_space; + + return twidth; +} + +static int +width_of_dash(TextNode * node) +{ + int num_dashes, twidth; + + num_dashes = strlen(node->data.text); + if (num_dashes > 1) + twidth = node->width = num_dashes * dash_width; + else + twidth = node->width = XTextWidth(gTopOfGroupStack->cur_font, + node->data.text, 1); + if (node->space) + twidth += inter_word_space; + return twidth; +} + +/* + * return the gWindow->width in pixels of the given text node, when + * displayed + */ + +int +text_width(TextNode * node, int Ender) +{ + int twidth = 0, num_words; + + for (num_words = 0; node != NULL; num_words++, node = node->next) { + if (Ender == Endtokens) { + if (node->type == Endtokens) + return twidth; + } + else if (node->type == Ender) + return twidth; + + switch (node->type) { + case Macro: + case Pound: + if (node->space && gInLine) + twidth += inter_word_space; + break; + case Punctuation: + twidth += punctuation_width(node); + break; + case Dash: + if (gInLine && node->space) + twidth += inter_word_space; + twidth += width_of_dash(node); + break; + case Verbatim: + case Spadsrctxt: + twidth += verbatim_width(node); + break; + case Lsquarebrace: + case Rsquarebrace: + case Word: + twidth += word_width(node); + break; + case Box: + twidth += 2 * box_space; + break; + case Link: + case Downlink: + case Memolink: + case Windowlink: + case LispMemoLink: + case Lispwindowlink: + case Lisplink: + case Unixlink: + case Spadcall: + case Spadcallquit: + case Qspadcall: + case Qspadcallquit: + case LispDownLink: + case Lispcommand: + case Lispcommandquit: + case Spadlink: + case Spaddownlink: + case Spadmemolink: + case Unixcommand: + case Upbutton: + case Returnbutton: + case Description: + push_active_group(); + break; + case Endbutton: + case Endspadcommand: + case Enddescription: + pop_group_stack(); + break; + case Endlink: + pop_group_stack(); + break; + case Inputstring: + twidth += input_string_width(node); + break; + case SimpleBox: + case Radiobox: + twidth += node->width + ((node->space) ? inter_word_space : 0); + break; + case Spadcommand: + case Spadgraph: + push_spad_group(); + break; + case VSpace: + break; + case HSpace: + twidth += + (node->data.node != NULL ? atoi(node->data.node->data.text) : 1); + break; + case Space: + twidth += (gTopOfGroupStack->cur_font->max_bounds.width) * + (node->data.node != NULL ? atoi(node->data.node->data.text) : 1); + break; + case Tab: + twidth = (gTopOfGroupStack->cur_font->max_bounds.width) * + (node->data.node != NULL ? atoi(node->data.node->data.text) : 1); + break; + case Table: + twidth = gWindow->width - left_margin - right_margin_space; + break; + case Tableitem: + case Group: + twidth += (node->space) ? inter_word_space : 0; + push_group_stack(); + break; + case BoldFace: + if (node->space) + twidth += inter_word_space; + bf_top_group(); + break; + case Emphasize: + if (node->space) + twidth += inter_word_space; + if (gTopOfGroupStack->cur_font == gRmFont) + em_top_group(); + else + rm_top_group(); + break; + case It: + if (node->space) + twidth += inter_word_space; + em_top_group(); + break; + case Rm: + case Sl: + case Tt: + if (node->space) + twidth += inter_word_space; + rm_top_group(); + break; + case Endgroup: + pop_group_stack(); + break; + case Controlbitmap: + case Inputbitmap: + if (node->width == -1) + insert_bitmap_file(node); + twidth += node->width; + break; + case Inputpixmap: + if (node->width == -1) + insert_pixmap_file(node); + twidth += node->width; + break; + case Mbox: + case Indent: + case Endmacro: + case Free: + case Bound: + case Beep: + case Item: + case Titem: + case Beginitems: + case Noop: + case Endinputbox: + case Fi: + case Ifcond: + case Endif: + case Begintitems: + case Enditems: + case Endtitems: + case Endtableitem: + case Endtable: + case Endparameter: + case Endbox: + case Endheader: + case Endfooter: + case Endscrolling: + case Endverbatim: + case Endspadsrc: + break; + case Newline: + /* WOw, I guess I should ertunr a really big number */ + twidth += gWindow->width; + break; + default: + + /* + * fprintf(stderr, "Unknown nodetype %d in text_width\n", + * node->type); + */ + break; + } + } + return twidth; +} + +/* + * total_width traces through the nodes, until it finds a blank space. It is + * used by compute_word_extent, and compute_punctuation extent to determine + * How far we go before we actually see white space. + */ + +int +total_width(TextNode * node, int Ender) +{ + int twidth = 0; + + for (; (node != NULL); node = node->next) { + if (Ender == Endtokens) { + if (node->type >= Endtokens) + return twidth; + } + else if (node->type == Ender) + return twidth; + + /* + * The first thing we check for is to see if there was space in front + * of the current node, if so we are done + */ + + if (node->space) + return twidth; + + /*** Else depending on the node type ***/ + + switch (node->type) { + case Noop: + case Endinputbox: + case Pound: + case Ifcond: + case Fi: + case Endif: + break; + case Rsquarebrace: + case Punctuation: + case Word: + case Dash: + twidth += XTextWidth(gTopOfGroupStack->cur_font, node->data.text, + strlen(node->data.text)); + break; + case Box: + case Link: + case Downlink: + case Memolink: + case Windowlink: + case LispMemoLink: + case Lispwindowlink: + case Lisplink: + case Unixlink: + case Spadcall: + case Spadcallquit: + case Qspadcall: + case Qspadcallquit: + case LispDownLink: + case Lispcommand: + case Lispcommandquit: + case Spadlink: + case Spaddownlink: + case Spadmemolink: + case Unixcommand: + case Inputstring: + case SimpleBox: + case Radiobox: + case Upbutton: + case Returnbutton: + case Spadcommand: + case Spadgraph: + case VSpace: + case HSpace: + case Space: + case Table: + case Group: + case Controlbitmap: + case Inputbitmap: + case Inputpixmap: + case Free: + case Beep: + case Bound: + case Lsquarebrace: + case BoldFace: + case Emphasize: + case It: + case Rm: + case Sl: + case Tt: + case Newline: + case Verbatim: + case Spadsrctxt: + return twidth; + default: + break; + } + } + return twidth; +} + +/* + * init_extents initialize some text size variables + */ + +void +init_extents(void) +{ + present_line_height = line_height; + gInLine = 0; + gInItem = 0; + gInAxiomCommand = 0; + item_indent = 0; + gInDesc = 0; + indent = left_margin; + text_x = indent; + gTopOfGroupStack->cur_font = gRmFont; + gTopOfGroupStack->cur_color = gRmColor; + right_margin = gWindow->width - right_margin_space; + clear_item_stack(); +} + +/* + * init_title_extents initialize some title text size variables + */ + +void +init_title_extents(HyperDocPage * page) +{ + present_line_height = line_height; + gInLine = 0; + gInAxiomCommand = 0; + item_indent = 0; + gInDesc = 0; + indent = left_margin + page->title->x; + text_x = indent; + gTopOfGroupStack->cur_font = gRmFont; + gTopOfGroupStack->cur_color = gRmColor; + right_margin = gWindow->width - right_margin_space - gWindow->border_width - + 2 * twwidth; + clear_item_stack(); +} + +/* + * init_text initialize some text size variables + */ + +void +init_text(void) +{ + normal_text_height = gRmFont->ascent + gRmFont->descent; + line_height = gRmFont->ascent + gRmFont->descent + inter_line_space; + word_off_height = line_height - normal_text_height; + space_width = gRmFont->max_bounds.width; +} + +/* + * text_height returns the height of a piece of formatted text in pixels + */ + +int +text_height(TextNode * node, int Ender) +{ + cur_height = 0; + return text_height1(node, Ender); +} + +/* + * text_height1 is the recursive part of text_height + */ + +static int +text_height1(TextNode * node, int Ender) +{ + for (; node != NULL; node = node->next) { + if (Ender == Endtokens) { + if (node->type > -Endtokens) + return cur_height; + } + else if (node->type == Ender) + return cur_height; + switch (node->type) { + case Center: + case Downlink: + case Link: + case Spadcommand: + case Spadgraph: + case Upbutton: + case Returnbutton: + case Windowlink: + case Memolink: + case Lispwindowlink: + case Lisplink: + case Unixlink: + case Spadcall: + case Spadcallquit: + case Qspadcall: + case Qspadcallquit: + case LispDownLink: + case LispMemoLink: + case Lispcommand: + case Lispcommandquit: + case Spadlink: + case Spaddownlink: + case Spadmemolink: + case Unixcommand: + case SimpleBox: + case Radiobox: + case Group: + case Box: + case Controlbitmap: + case Inputbitmap: + case Inputpixmap: + case Horizontalline: + case Punctuation: + case Lsquarebrace: + case Rsquarebrace: + case Word: + case Verbatim: + case Math: + case Spadsrctxt: + case Dash: + case Inputstring: + cur_height = max(node->y, cur_height); + break; + case Mbox: + case Macro: + case Pound: + case Emphasize: + case BoldFace: + case It: + case Rm: + case Sl: + case Tt: + case Endparameter: + case Description: + case Enddescription: + case Noop: + case Fi: + case Ifcond: + case Endif: + case Endinputbox: + case Tab: + case Newline: + case Space: + case VSpace: + case HSpace: + case Beginitems: + case Begintitems: + case Endtitems: + case Titem: + case Enditems: + case Endtable: + case Endtableitem: + case Item: + case Par: + case Beep: + case Free: + case Bound: + case Endgroup: + case Endcenter: + case Endbutton: + case Endmacro: + case Tableitem: + case Endlink: + case Endspadcommand: + case Indent: + case Indentrel: + case Endbox: + case Endmbox: + case Table: + case Endverbatim: + case Endmath: + case Spadsrc: + case Endspadsrc: + break; + case Beginscroll: + case Endscroll: + break; + case Endscrolling: + return cur_height; + default: + + /* + * fprintf(stderr, "Text_height1: Unknown Node Type %d\n", + * node->type); + */ + break; + } + } + return cur_height; +} + +/* + * max_x returns the height of a piece of formatted text in pixels + */ + +int +max_x(TextNode * node, int Ender) +{ + max_x_value = 0; + for (; node != NULL; node = node->next) { + if (Ender == Endtokens) { + if (node->type >= Endtokens) + return max_x_value; + } + else if (node->type == Ender) + return max_x_value; + switch (node->type) { + case Lsquarebrace: + case Rsquarebrace: + case Word: + max_x_value = max(max_x_value, node->x + word_width(node)); + break; + case Verbatim: + case Spadsrctxt: + max_x_value = max(max_x_value, node->x + verbatim_width(node)); + break; + case Punctuation: + max_x_value = max(max_x_value, node->x + punctuation_width(node)); + break; + case Dash: + max_x_value = max(max_x_value, node->x + width_of_dash(node)); + break; + case HSpace: + max_x_value = max(max_x_value, node->x + + (node->data.node != NULL ? atoi(node->data.node->data.text) : 1)); + break; + case Space: + max_x_value = max(max_x_value, node->x + + (gTopOfGroupStack->cur_font->max_bounds.width) * + (node->data.node != NULL ? atoi(node->data.node->data.text) : 1)); + break; + case Group: + push_group_stack(); + break; + case BoldFace: + bf_top_group(); + break; + case Emphasize: + if (gTopOfGroupStack->cur_font == gRmFont) + em_top_group(); + else + rm_top_group(); + break; + case It: + em_top_group(); + break; + case Rm: + case Sl: + case Tt: + rm_top_group(); + break; + case Endgroup: + pop_group_stack(); + break; + case Controlbitmap: + case Inputbitmap: + if (node->width == -1) + insert_bitmap_file(node); + max_x_value = max(max_x_value, node->x + node->width); + break; + case Inputpixmap: + if (node->width == -1) + insert_pixmap_file(node); + max_x_value = max(max_x_value, node->y + node->width); + break; + default: + break; + } + } + return cur_height; +} + +static int +x_value(TextNode * node) +{ + for (; node != NULL; node = node->next) { + switch (node->type) { + case Controlbitmap: + case Inputbitmap: + case Inputpixmap: + case Lsquarebrace: + case Rsquarebrace: + case Word: + case Verbatim: + case Spadsrctxt: + case Dash: + case Punctuation: + case VSpace: + case HSpace: + case Horizontalline: + case Box: + case Downlink: + case Link: + case Lispwindowlink: + case Lisplink: + case Unixlink: + case Spadcall: + case Spadcallquit: + case Qspadcall: + case Qspadcallquit: + case LispDownLink: + case LispMemoLink: + case Lispcommand: + case Lispcommandquit: + case Spadlink: + case Spaddownlink: + case Spadmemolink: + case Spadcommand: + case Spadgraph: + case Unixcommand: + case Space: + case SimpleBox: + case Radiobox: + return node->x; + default: +#ifdef DEBUG + fprintf(stderr, "X_value did not know x value of type %d\n", node->type); +#endif + return x_value(node->next); + } + } + return 0; +} + +/* + * trailing_space computes the length of the trailing spaces of a node + */ + +int +trailing_space(TextNode * node) +{ + int space = 0; + + for (; node->type < Endtokens; node = node->next); + if (node->type == Space) + space += inter_word_space * + (node->data.node != NULL ? atoi(node->data.node->data.text) : 1); + return space; +} + +/* + * insert_bitmap_file reads a bitmap file into memory + */ + +void +insert_bitmap_file(TextNode * node) +{ + char *filename = node->data.text; + int bm_width, bm_height; + XImage *im; + ImageStruct *image; + + if (*filename == ' ') + filename++; + if (node->image.pm == 0) { + if ( + ((image = (ImageStruct *) hash_find(&gImageHashTable, filename)) == NULL) + || (getenv("HTCACHE"))) { + + /* + * read the bitmap if not already in memory or if the environment + * variable HTCACHE is set (NAG addition). + */ + + im = HTReadBitmapFile(gXDisplay, gXScreenNumber, filename, + &bm_width, &bm_height); + + /** now add the image to the gImageHashTable **/ + image = (ImageStruct *) halloc(sizeof(ImageStruct), "ImageStruct"); + image->image.xi = im; + image->width = image->image.xi->width; + image->height = image->image.xi->height; + image->filename = (char *) halloc(sizeof(char) * strlen(filename) +1,"Image Filename"); + /* strcpy(image->filename, filename); */ + sprintf(image->filename, "%s", filename); + hash_insert(&gImageHashTable, (char *)image, image->filename); + } + node->width = image->width; + node->height = image->height; + node->image.xi = image->image.xi; + } +} + +/* + * insert_pixmap_file reads a pixmap file into memory + */ + +void +insert_pixmap_file(TextNode * node) +{ + char *filename = node->data.text; + int bm_width, bm_height, ret_val; + XImage *xi; + ImageStruct *image; + + if (*filename == ' ') + filename++; + if (node->image.xi == 0) { + if ((image = (ImageStruct *) hash_find(&gImageHashTable, filename)) == NULL) { + ret_val = read_pixmap_file(gXDisplay, gXScreenNumber, filename, &xi, + &bm_width, &bm_height); + switch (ret_val) { + case(-1): + gSwitch_to_mono = 1; + return; + case BitmapFileInvalid: + fprintf(stderr, "File %s contains invalid bitmap data\n", filename); + return; + case BitmapOpenFailed: + fprintf(stderr, "couldn't open bitmap file %s\n", filename); + return; + case BitmapNoMemory: + fprintf(stderr, "not enough memory to store bitmap\n"); + return; + } + image = (ImageStruct *) halloc(sizeof(ImageStruct), "ImageStruct"); + image->width = bm_width; + image->height = bm_height; + image->filename = (char *) halloc(sizeof(char) * strlen(filename) +1, + "insert_pixmap--filename"); + /* strcpy(image->filename, filename); */ + sprintf(image->filename, "%s", filename); + image->image.xi = xi; + hash_insert(&gImageHashTable, (char *)image, image->filename); + } + node->width = image->width; + node->height = plh(image->height + inter_line_space); + node->image.xi = image->image.xi; + } +} + +/* + * plh calculates the closet value of line_height > height + */ + +int +plh(int height) +{ + int rheight = height; + + if (gExtentRegion == Scrolling) { + for (rheight = line_height; rheight < height; rheight += line_height) + ; + } + return rheight; +} diff --git a/src/hyper/extent2.pamphlet b/src/hyper/extent2.pamphlet deleted file mode 100644 index d553a73e..00000000 --- a/src/hyper/extent2.pamphlet +++ /dev/null @@ -1,957 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/extent2} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{extent2.c} -<>= -/****************************************************************************** - * - * extent2.h: HyperDoc extent computation routines - * - * Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993. - * - ****************************************************************************/ -#define _EXTENT2_C -#include "axiom-c-macros.h" -#include "useproto.h" -#include "debug.h" - - -#include "extent.h" -#include "group.h" -#include "titlebar.h" - -#include "all_hyper_proto.H1" -#include "pixmap.H1" - - -static int cur_height = 0; -static int max_x_value = 0; - -/* - * start_newline updates the current header node, and also allocates if needed - * memory for the next Line Header. It also assigns the first TextNode on the - * line to the structure, because this is the last time I will be able to do - * this - */ - -void -start_newline(int distance, TextNode * node) -{ - if (gLineNode != NULL) { - if (gTopOfGroupStack->center) - center_nodes(gLineNode, node); - gLineNode = node; - } - text_y += distance; - past_line_height = distance; - present_line_height = line_height; - gInLine = 0; -} - -/* - * center_nodes goes through and centers all the text between the two - * given nodes. - */ - -static void -center_nodes(TextNode * begin_node, TextNode * end_node) -{ - int begin_x, end_x, wmid_x, offset, mid_x; - TextNode *node; - - end_x = text_x; - begin_x = x_value(begin_node); - mid_x = (int) (end_x + begin_x) / 2; - wmid_x = (int) (right_margin + indent) / 2; - - if (mid_x > wmid_x) - offset = 0; - else - offset = wmid_x - mid_x; - - for (node = begin_node; node != end_node; node = node->next) - if (node->x > 0) - node->x += offset; -} - -static int -punctuation_width(TextNode * node) -{ - int twidth, width = strlen(node->data.text); - - twidth = XTextWidth(gTopOfGroupStack->cur_font, node->data.text, width); - - /* check to see if there was some space in front */ - - if (gInLine && (node->space & FRONTSPACE)) - twidth += inter_word_space; - -# if 0 - if (node->space & BACKSPACE) { - switch (node->data.text[0]) { - case '.': - case '?': - case '!': - twidth += term_punct_space; - break; - } - } -#endif - - return twidth; -} - -static int -input_string_width(TextNode * node) -{ - InputItem *item; - int t_width; - - /** search the symbol table for the proper entry **/ - - item = node->link->reference.string; - - /** Once I have gotten this far, I should just be able to calculate - the width using the normal font **/ - - t_width = (item->size + 1) * gInputFont->max_bounds.width + 10; - return t_width; - -} - -static int -word_width(TextNode * node) -{ - int twidth, len = strlen(node->data.text); - - twidth = XTextWidth(gTopOfGroupStack->cur_font, node->data.text, len); - if (node->space & FRONTSPACE) - twidth += inter_word_space; - - return twidth; -} - -static int -verbatim_width(TextNode * node) -{ - int twidth, len = strlen(node->data.text); - - twidth = XTextWidth(gTopOfGroupStack->cur_font, node->data.text, len); - if (node->space) - twidth += inter_word_space; - - return twidth; -} - -static int -width_of_dash(TextNode * node) -{ - int num_dashes, twidth; - - num_dashes = strlen(node->data.text); - if (num_dashes > 1) - twidth = node->width = num_dashes * dash_width; - else - twidth = node->width = XTextWidth(gTopOfGroupStack->cur_font, - node->data.text, 1); - if (node->space) - twidth += inter_word_space; - return twidth; -} - -/* - * return the gWindow->width in pixels of the given text node, when - * displayed - */ - -int -text_width(TextNode * node, int Ender) -{ - int twidth = 0, num_words; - - for (num_words = 0; node != NULL; num_words++, node = node->next) { - if (Ender == Endtokens) { - if (node->type == Endtokens) - return twidth; - } - else if (node->type == Ender) - return twidth; - - switch (node->type) { - case Macro: - case Pound: - if (node->space && gInLine) - twidth += inter_word_space; - break; - case Punctuation: - twidth += punctuation_width(node); - break; - case Dash: - if (gInLine && node->space) - twidth += inter_word_space; - twidth += width_of_dash(node); - break; - case Verbatim: - case Spadsrctxt: - twidth += verbatim_width(node); - break; - case Lsquarebrace: - case Rsquarebrace: - case Word: - twidth += word_width(node); - break; - case Box: - twidth += 2 * box_space; - break; - case Link: - case Downlink: - case Memolink: - case Windowlink: - case LispMemoLink: - case Lispwindowlink: - case Lisplink: - case Unixlink: - case Spadcall: - case Spadcallquit: - case Qspadcall: - case Qspadcallquit: - case LispDownLink: - case Lispcommand: - case Lispcommandquit: - case Spadlink: - case Spaddownlink: - case Spadmemolink: - case Unixcommand: - case Upbutton: - case Returnbutton: - case Description: - push_active_group(); - break; - case Endbutton: - case Endspadcommand: - case Enddescription: - pop_group_stack(); - break; - case Endlink: - pop_group_stack(); - break; - case Inputstring: - twidth += input_string_width(node); - break; - case SimpleBox: - case Radiobox: - twidth += node->width + ((node->space) ? inter_word_space : 0); - break; - case Spadcommand: - case Spadgraph: - push_spad_group(); - break; - case VSpace: - break; - case HSpace: - twidth += - (node->data.node != NULL ? atoi(node->data.node->data.text) : 1); - break; - case Space: - twidth += (gTopOfGroupStack->cur_font->max_bounds.width) * - (node->data.node != NULL ? atoi(node->data.node->data.text) : 1); - break; - case Tab: - twidth = (gTopOfGroupStack->cur_font->max_bounds.width) * - (node->data.node != NULL ? atoi(node->data.node->data.text) : 1); - break; - case Table: - twidth = gWindow->width - left_margin - right_margin_space; - break; - case Tableitem: - case Group: - twidth += (node->space) ? inter_word_space : 0; - push_group_stack(); - break; - case BoldFace: - if (node->space) - twidth += inter_word_space; - bf_top_group(); - break; - case Emphasize: - if (node->space) - twidth += inter_word_space; - if (gTopOfGroupStack->cur_font == gRmFont) - em_top_group(); - else - rm_top_group(); - break; - case It: - if (node->space) - twidth += inter_word_space; - em_top_group(); - break; - case Rm: - case Sl: - case Tt: - if (node->space) - twidth += inter_word_space; - rm_top_group(); - break; - case Endgroup: - pop_group_stack(); - break; - case Controlbitmap: - case Inputbitmap: - if (node->width == -1) - insert_bitmap_file(node); - twidth += node->width; - break; - case Inputpixmap: - if (node->width == -1) - insert_pixmap_file(node); - twidth += node->width; - break; - case Mbox: - case Indent: - case Endmacro: - case Free: - case Bound: - case Beep: - case Item: - case Titem: - case Beginitems: - case Noop: - case Endinputbox: - case Fi: - case Ifcond: - case Endif: - case Begintitems: - case Enditems: - case Endtitems: - case Endtableitem: - case Endtable: - case Endparameter: - case Endbox: - case Endheader: - case Endfooter: - case Endscrolling: - case Endverbatim: - case Endspadsrc: - break; - case Newline: - /* WOw, I guess I should ertunr a really big number */ - twidth += gWindow->width; - break; - default: - - /* - * fprintf(stderr, "Unknown nodetype %d in text_width\n", - * node->type); - */ - break; - } - } - return twidth; -} - -/* - * total_width traces through the nodes, until it finds a blank space. It is - * used by compute_word_extent, and compute_punctuation extent to determine - * How far we go before we actually see white space. - */ - -int -total_width(TextNode * node, int Ender) -{ - int twidth = 0; - - for (; (node != NULL); node = node->next) { - if (Ender == Endtokens) { - if (node->type >= Endtokens) - return twidth; - } - else if (node->type == Ender) - return twidth; - - /* - * The first thing we check for is to see if there was space in front - * of the current node, if so we are done - */ - - if (node->space) - return twidth; - - /*** Else depending on the node type ***/ - - switch (node->type) { - case Noop: - case Endinputbox: - case Pound: - case Ifcond: - case Fi: - case Endif: - break; - case Rsquarebrace: - case Punctuation: - case Word: - case Dash: - twidth += XTextWidth(gTopOfGroupStack->cur_font, node->data.text, - strlen(node->data.text)); - break; - case Box: - case Link: - case Downlink: - case Memolink: - case Windowlink: - case LispMemoLink: - case Lispwindowlink: - case Lisplink: - case Unixlink: - case Spadcall: - case Spadcallquit: - case Qspadcall: - case Qspadcallquit: - case LispDownLink: - case Lispcommand: - case Lispcommandquit: - case Spadlink: - case Spaddownlink: - case Spadmemolink: - case Unixcommand: - case Inputstring: - case SimpleBox: - case Radiobox: - case Upbutton: - case Returnbutton: - case Spadcommand: - case Spadgraph: - case VSpace: - case HSpace: - case Space: - case Table: - case Group: - case Controlbitmap: - case Inputbitmap: - case Inputpixmap: - case Free: - case Beep: - case Bound: - case Lsquarebrace: - case BoldFace: - case Emphasize: - case It: - case Rm: - case Sl: - case Tt: - case Newline: - case Verbatim: - case Spadsrctxt: - return twidth; - default: - break; - } - } - return twidth; -} - -/* - * init_extents initialize some text size variables - */ - -void -init_extents(void) -{ - present_line_height = line_height; - gInLine = 0; - gInItem = 0; - gInAxiomCommand = 0; - item_indent = 0; - gInDesc = 0; - indent = left_margin; - text_x = indent; - gTopOfGroupStack->cur_font = gRmFont; - gTopOfGroupStack->cur_color = gRmColor; - right_margin = gWindow->width - right_margin_space; - clear_item_stack(); -} - -/* - * init_title_extents initialize some title text size variables - */ - -void -init_title_extents(HyperDocPage * page) -{ - present_line_height = line_height; - gInLine = 0; - gInAxiomCommand = 0; - item_indent = 0; - gInDesc = 0; - indent = left_margin + page->title->x; - text_x = indent; - gTopOfGroupStack->cur_font = gRmFont; - gTopOfGroupStack->cur_color = gRmColor; - right_margin = gWindow->width - right_margin_space - gWindow->border_width - - 2 * twwidth; - clear_item_stack(); -} - -/* - * init_text initialize some text size variables - */ - -void -init_text(void) -{ - normal_text_height = gRmFont->ascent + gRmFont->descent; - line_height = gRmFont->ascent + gRmFont->descent + inter_line_space; - word_off_height = line_height - normal_text_height; - space_width = gRmFont->max_bounds.width; -} - -/* - * text_height returns the height of a piece of formatted text in pixels - */ - -int -text_height(TextNode * node, int Ender) -{ - cur_height = 0; - return text_height1(node, Ender); -} - -/* - * text_height1 is the recursive part of text_height - */ - -static int -text_height1(TextNode * node, int Ender) -{ - for (; node != NULL; node = node->next) { - if (Ender == Endtokens) { - if (node->type > -Endtokens) - return cur_height; - } - else if (node->type == Ender) - return cur_height; - switch (node->type) { - case Center: - case Downlink: - case Link: - case Spadcommand: - case Spadgraph: - case Upbutton: - case Returnbutton: - case Windowlink: - case Memolink: - case Lispwindowlink: - case Lisplink: - case Unixlink: - case Spadcall: - case Spadcallquit: - case Qspadcall: - case Qspadcallquit: - case LispDownLink: - case LispMemoLink: - case Lispcommand: - case Lispcommandquit: - case Spadlink: - case Spaddownlink: - case Spadmemolink: - case Unixcommand: - case SimpleBox: - case Radiobox: - case Group: - case Box: - case Controlbitmap: - case Inputbitmap: - case Inputpixmap: - case Horizontalline: - case Punctuation: - case Lsquarebrace: - case Rsquarebrace: - case Word: - case Verbatim: - case Math: - case Spadsrctxt: - case Dash: - case Inputstring: - cur_height = max(node->y, cur_height); - break; - case Mbox: - case Macro: - case Pound: - case Emphasize: - case BoldFace: - case It: - case Rm: - case Sl: - case Tt: - case Endparameter: - case Description: - case Enddescription: - case Noop: - case Fi: - case Ifcond: - case Endif: - case Endinputbox: - case Tab: - case Newline: - case Space: - case VSpace: - case HSpace: - case Beginitems: - case Begintitems: - case Endtitems: - case Titem: - case Enditems: - case Endtable: - case Endtableitem: - case Item: - case Par: - case Beep: - case Free: - case Bound: - case Endgroup: - case Endcenter: - case Endbutton: - case Endmacro: - case Tableitem: - case Endlink: - case Endspadcommand: - case Indent: - case Indentrel: - case Endbox: - case Endmbox: - case Table: - case Endverbatim: - case Endmath: - case Spadsrc: - case Endspadsrc: - break; - case Beginscroll: - case Endscroll: - break; - case Endscrolling: - return cur_height; - default: - - /* - * fprintf(stderr, "Text_height1: Unknown Node Type %d\n", - * node->type); - */ - break; - } - } - return cur_height; -} - -/* - * max_x returns the height of a piece of formatted text in pixels - */ - -int -max_x(TextNode * node, int Ender) -{ - max_x_value = 0; - for (; node != NULL; node = node->next) { - if (Ender == Endtokens) { - if (node->type >= Endtokens) - return max_x_value; - } - else if (node->type == Ender) - return max_x_value; - switch (node->type) { - case Lsquarebrace: - case Rsquarebrace: - case Word: - max_x_value = max(max_x_value, node->x + word_width(node)); - break; - case Verbatim: - case Spadsrctxt: - max_x_value = max(max_x_value, node->x + verbatim_width(node)); - break; - case Punctuation: - max_x_value = max(max_x_value, node->x + punctuation_width(node)); - break; - case Dash: - max_x_value = max(max_x_value, node->x + width_of_dash(node)); - break; - case HSpace: - max_x_value = max(max_x_value, node->x + - (node->data.node != NULL ? atoi(node->data.node->data.text) : 1)); - break; - case Space: - max_x_value = max(max_x_value, node->x + - (gTopOfGroupStack->cur_font->max_bounds.width) * - (node->data.node != NULL ? atoi(node->data.node->data.text) : 1)); - break; - case Group: - push_group_stack(); - break; - case BoldFace: - bf_top_group(); - break; - case Emphasize: - if (gTopOfGroupStack->cur_font == gRmFont) - em_top_group(); - else - rm_top_group(); - break; - case It: - em_top_group(); - break; - case Rm: - case Sl: - case Tt: - rm_top_group(); - break; - case Endgroup: - pop_group_stack(); - break; - case Controlbitmap: - case Inputbitmap: - if (node->width == -1) - insert_bitmap_file(node); - max_x_value = max(max_x_value, node->x + node->width); - break; - case Inputpixmap: - if (node->width == -1) - insert_pixmap_file(node); - max_x_value = max(max_x_value, node->y + node->width); - break; - default: - break; - } - } - return cur_height; -} - -static int -x_value(TextNode * node) -{ - for (; node != NULL; node = node->next) { - switch (node->type) { - case Controlbitmap: - case Inputbitmap: - case Inputpixmap: - case Lsquarebrace: - case Rsquarebrace: - case Word: - case Verbatim: - case Spadsrctxt: - case Dash: - case Punctuation: - case VSpace: - case HSpace: - case Horizontalline: - case Box: - case Downlink: - case Link: - case Lispwindowlink: - case Lisplink: - case Unixlink: - case Spadcall: - case Spadcallquit: - case Qspadcall: - case Qspadcallquit: - case LispDownLink: - case LispMemoLink: - case Lispcommand: - case Lispcommandquit: - case Spadlink: - case Spaddownlink: - case Spadmemolink: - case Spadcommand: - case Spadgraph: - case Unixcommand: - case Space: - case SimpleBox: - case Radiobox: - return node->x; - default: -#ifdef DEBUG - fprintf(stderr, "X_value did not know x value of type %d\n", node->type); -#endif - return x_value(node->next); - } - } - return 0; -} - -/* - * trailing_space computes the length of the trailing spaces of a node - */ - -int -trailing_space(TextNode * node) -{ - int space = 0; - - for (; node->type < Endtokens; node = node->next); - if (node->type == Space) - space += inter_word_space * - (node->data.node != NULL ? atoi(node->data.node->data.text) : 1); - return space; -} - -/* - * insert_bitmap_file reads a bitmap file into memory - */ - -void -insert_bitmap_file(TextNode * node) -{ - char *filename = node->data.text; - int bm_width, bm_height; - XImage *im; - ImageStruct *image; - - if (*filename == ' ') - filename++; - if (node->image.pm == 0) { - if ( - ((image = (ImageStruct *) hash_find(&gImageHashTable, filename)) == NULL) - || (getenv("HTCACHE"))) { - - /* - * read the bitmap if not already in memory or if the environment - * variable HTCACHE is set (NAG addition). - */ - - im = HTReadBitmapFile(gXDisplay, gXScreenNumber, filename, - &bm_width, &bm_height); - - /** now add the image to the gImageHashTable **/ - image = (ImageStruct *) halloc(sizeof(ImageStruct), "ImageStruct"); - image->image.xi = im; - image->width = image->image.xi->width; - image->height = image->image.xi->height; - image->filename = (char *) halloc(sizeof(char) * strlen(filename) +1,"Image Filename"); - /* strcpy(image->filename, filename); */ - sprintf(image->filename, "%s", filename); - hash_insert(&gImageHashTable, (char *)image, image->filename); - } - node->width = image->width; - node->height = image->height; - node->image.xi = image->image.xi; - } -} - -/* - * insert_pixmap_file reads a pixmap file into memory - */ - -void -insert_pixmap_file(TextNode * node) -{ - char *filename = node->data.text; - int bm_width, bm_height, ret_val; - XImage *xi; - ImageStruct *image; - - if (*filename == ' ') - filename++; - if (node->image.xi == 0) { - if ((image = (ImageStruct *) hash_find(&gImageHashTable, filename)) == NULL) { - ret_val = read_pixmap_file(gXDisplay, gXScreenNumber, filename, &xi, - &bm_width, &bm_height); - switch (ret_val) { - case(-1): - gSwitch_to_mono = 1; - return; - case BitmapFileInvalid: - fprintf(stderr, "File %s contains invalid bitmap data\n", filename); - return; - case BitmapOpenFailed: - fprintf(stderr, "couldn't open bitmap file %s\n", filename); - return; - case BitmapNoMemory: - fprintf(stderr, "not enough memory to store bitmap\n"); - return; - } - image = (ImageStruct *) halloc(sizeof(ImageStruct), "ImageStruct"); - image->width = bm_width; - image->height = bm_height; - image->filename = (char *) halloc(sizeof(char) * strlen(filename) +1, - "insert_pixmap--filename"); - /* strcpy(image->filename, filename); */ - sprintf(image->filename, "%s", filename); - image->image.xi = xi; - hash_insert(&gImageHashTable, (char *)image, image->filename); - } - node->width = image->width; - node->height = plh(image->height + inter_line_space); - node->image.xi = image->image.xi; - } -} - -/* - * plh calculates the closet value of line_height > height - */ - -int -plh(int height) -{ - int rheight = height; - - if (gExtentRegion == Scrolling) { - for (rheight = line_height; rheight < height; rheight += line_height) - ; - } - return rheight; -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/form-ext.c b/src/hyper/form-ext.c new file mode 100644 index 00000000..f33babfd --- /dev/null +++ b/src/hyper/form-ext.c @@ -0,0 +1,166 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +#define _FORM_EXT_C +#include "axiom-c-macros.h" +#include "useproto.h" +#include "debug.h" + +#include "extent.h" +#include "group.h" +#include "scrollbar.h" + +#include "all_hyper_proto.H1" + + + +/* + * A few routines used to help with form extents + */ + +void +compute_form_page(HyperDocPage *page) +{ + + /* + * To solve the problem of improperly nested \em, I will have to keep and + * always initialize the top of the stack + */ + while (pop_group_stack() >= 0); + + /* + * The compute the text extents + */ + form_header_extent(page); + form_footer_extent(page); + form_scrolling_extent(page); + gWindow->height = window_height(gWindow->page); + +} + +/* + * A simple function that returns the width needed to store show the number + * of columns given + */ +int +window_width(int cols) +{ + return (left_margin + cols * space_width + non_scroll_right_margin_space); +} + + +static int +window_height(HyperDocPage *page) +{ + int temp; + + temp = page->header->height + top_margin + bottom_margin; + + if (page->scrolling) + temp += page->scrolling->height + page->footer->height; + + return (temp); +} + + +static void +form_header_extent(HyperDocPage *page) +{ + + /* + * Hopefully I will soon be able to actually compute the needed height + * for the header here + */ + gExtentRegion = Header; + right_margin_space = non_scroll_right_margin_space; + init_extents(); + text_y = top_margin + line_height; + compute_text_extent(page->header->next); + page->header->height = (gInLine) ? text_y : text_y - past_line_height; + if (!(page->page_flags & NOLINES)) + page->header->height += (int) line_height / 2; + page->header->height += gWindow->border_width; +} + +static void +form_footer_extent(HyperDocPage *page) +{ + if (page->footer) { + gExtentRegion = Footer; + right_margin_space = non_scroll_right_margin_space; + init_extents(); + + compute_text_extent(page->footer->next); + + /* + * I inserted the 2nd arg to text_height below because it + * was missing. Perhaps there is a better value for it. + */ + + page->footer->height = text_height(page->footer->next, + page->footer->next->type); + if ((!page->page_flags & NOLINES)) + page->footer->height += (int) line_height / 2; + } +} + +static void +form_scrolling_extent(HyperDocPage *page) +{ + + /* + * Check to see if there is a scrolling region + */ + + if (page->scrolling) { + /* + * If there is then compute all the proper locations + */ + + gExtentRegion = Scrolling; + right_margin_space = non_scroll_right_margin_space + gScrollbarWidth; + init_extents(); + text_y = line_height; + compute_text_extent(page->scrolling->next); + if (!gInLine) + text_y = text_y - past_line_height; + else if (present_line_height > line_height) + text_y = text_y + present_line_height - line_height; + page->scrolling->height = text_y; + } +} + + + diff --git a/src/hyper/form-ext.pamphlet b/src/hyper/form-ext.pamphlet deleted file mode 100644 index 158447c6..00000000 --- a/src/hyper/form-ext.pamphlet +++ /dev/null @@ -1,194 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/form-ext} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{form-ext.c} -<>= -#define _FORM_EXT_C -#include "axiom-c-macros.h" -#include "useproto.h" -#include "debug.h" - -#include "extent.h" -#include "group.h" -#include "scrollbar.h" - -#include "all_hyper_proto.H1" - - - -/* - * A few routines used to help with form extents - */ - -void -compute_form_page(HyperDocPage *page) -{ - - /* - * To solve the problem of improperly nested \em, I will have to keep and - * always initialize the top of the stack - */ - while (pop_group_stack() >= 0); - - /* - * The compute the text extents - */ - form_header_extent(page); - form_footer_extent(page); - form_scrolling_extent(page); - gWindow->height = window_height(gWindow->page); - -} - -/* - * A simple function that returns the width needed to store show the number - * of columns given - */ -int -window_width(int cols) -{ - return (left_margin + cols * space_width + non_scroll_right_margin_space); -} - - -static int -window_height(HyperDocPage *page) -{ - int temp; - - temp = page->header->height + top_margin + bottom_margin; - - if (page->scrolling) - temp += page->scrolling->height + page->footer->height; - - return (temp); -} - - -static void -form_header_extent(HyperDocPage *page) -{ - - /* - * Hopefully I will soon be able to actually compute the needed height - * for the header here - */ - gExtentRegion = Header; - right_margin_space = non_scroll_right_margin_space; - init_extents(); - text_y = top_margin + line_height; - compute_text_extent(page->header->next); - page->header->height = (gInLine) ? text_y : text_y - past_line_height; - if (!(page->page_flags & NOLINES)) - page->header->height += (int) line_height / 2; - page->header->height += gWindow->border_width; -} - -static void -form_footer_extent(HyperDocPage *page) -{ - if (page->footer) { - gExtentRegion = Footer; - right_margin_space = non_scroll_right_margin_space; - init_extents(); - - compute_text_extent(page->footer->next); - - /* - * I inserted the 2nd arg to text_height below because it - * was missing. Perhaps there is a better value for it. - */ - - page->footer->height = text_height(page->footer->next, - page->footer->next->type); - if ((!page->page_flags & NOLINES)) - page->footer->height += (int) line_height / 2; - } -} - -static void -form_scrolling_extent(HyperDocPage *page) -{ - - /* - * Check to see if there is a scrolling region - */ - - if (page->scrolling) { - /* - * If there is then compute all the proper locations - */ - - gExtentRegion = Scrolling; - right_margin_space = non_scroll_right_margin_space + gScrollbarWidth; - init_extents(); - text_y = line_height; - compute_text_extent(page->scrolling->next); - if (!gInLine) - text_y = text_y - past_line_height; - else if (present_line_height > line_height) - text_y = text_y + present_line_height - line_height; - page->scrolling->height = text_y; - } -} - - - -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/group.c b/src/hyper/group.c new file mode 100644 index 00000000..700ba42e --- /dev/null +++ b/src/hyper/group.c @@ -0,0 +1,242 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +/****************************************************************************** + * + * group.c: Routines for managing the HyperDoc group stack. + * + * Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993. + * + ****************************************************************************/ +#define _GROUP_C +#include "useproto.h" +#include "debug.h" + + +#include "group.h" +#include "initx.h" + +#include "all_hyper_proto.H1" + +GroupItem *gTopOfGroupStack = NULL; + + + +int +pop_group_stack(void) +{ + /* This routine pops the top of the current group stack */ + GroupItem *junk; + + /* + * If the the stack has only a single item, then pop it anyway so the + * user can see the problem + */ + if (! gTopOfGroupStack->next) + return -1; + + /* Else, Pop the thing */ + + junk = gTopOfGroupStack; + gTopOfGroupStack = gTopOfGroupStack->next; + junk->next = NULL; + + free(junk); + + /* Now change the font to the cur_font and the cur_color */ + + change_text(gTopOfGroupStack->cur_color, gTopOfGroupStack->cur_font); + return 1; + +} + +void +push_group_stack(void) +{ + /* + * This routine makes room by pushing a new item on the stack + */ + GroupItem *newgp; + + newgp = (GroupItem *) halloc(sizeof(GroupItem), "Push Group Stack"); + newgp->cur_font = gTopOfGroupStack->cur_font; + newgp->cur_color = gTopOfGroupStack->cur_color; + newgp->center = gTopOfGroupStack->center; + newgp->next = gTopOfGroupStack; + + gTopOfGroupStack = newgp; +} + +void +init_group_stack(void) +{ + gTopOfGroupStack = (GroupItem *) halloc(sizeof(GroupItem), "Push Group Stack"); + gTopOfGroupStack->center = 0; + gTopOfGroupStack->next = NULL; + gTopOfGroupStack->cur_color = 0; + gTopOfGroupStack->cur_font = NULL; +} + +void +em_top_group(void) +{ + if (! gTopOfGroupStack->next) + push_group_stack(); + gTopOfGroupStack->cur_color = gEmColor; + gTopOfGroupStack->cur_font = gEmFont; + change_text(gTopOfGroupStack->cur_color, gTopOfGroupStack->cur_font); +} + +void +rm_top_group(void) +{ + if (! gTopOfGroupStack->next) + push_group_stack(); + gTopOfGroupStack->cur_color = gRmColor; + gTopOfGroupStack->cur_font = gRmFont; + change_text(gTopOfGroupStack->cur_color, gTopOfGroupStack->cur_font); + +} + +void +line_top_group(void) +{ + if (! gTopOfGroupStack->next) + push_group_stack(); + gTopOfGroupStack->cur_color = gBorderColor; + gTopOfGroupStack->cur_font = gRmFont; + change_text(gTopOfGroupStack->cur_color, gTopOfGroupStack->cur_font); + +} + +void +bf_top_group(void) +{ + /* + * Just in case the person is tryin a \em without a grouping + */ + + if (! gTopOfGroupStack->next) + push_group_stack(); + gTopOfGroupStack->cur_color = gBfColor; + gTopOfGroupStack->cur_font = gBfFont; + change_text(gTopOfGroupStack->cur_color, gTopOfGroupStack->cur_font); +} + +void +tt_top_group(void) +{ + if (! gTopOfGroupStack->next) + push_group_stack(); + gTopOfGroupStack->cur_color = gTtColor; + gTopOfGroupStack->cur_font = gTtFont; + change_text(gTopOfGroupStack->cur_color, gTopOfGroupStack->cur_font); +} + +void +push_active_group(void) +{ + push_group_stack(); + gTopOfGroupStack->cur_font = gActiveFont; + gTopOfGroupStack->cur_color = gActiveColor; + change_text(gTopOfGroupStack->cur_color, gTopOfGroupStack->cur_font); +} + +void +push_spad_group(void) +{ + push_group_stack(); + gTopOfGroupStack->cur_font = gAxiomFont; + gTopOfGroupStack->cur_color = gAxiomColor; + change_text(gTopOfGroupStack->cur_color, gTopOfGroupStack->cur_font); +} + +void +init_top_group(void) +{ + /* clear the group stack */ + while (pop_group_stack() >= 0) + ; + + /* then set the colors to be normal */ + + gTopOfGroupStack->cur_color = gRmColor; + gTopOfGroupStack->cur_font = gRmFont; + change_text(gTopOfGroupStack->cur_color, gTopOfGroupStack->cur_font); +} + +void +center_top_group(void) +{ + push_group_stack(); + gTopOfGroupStack->center = 1; +} + +GroupItem * +copy_group_stack(void) +{ + GroupItem *newgp = NULL; + GroupItem *first = NULL; + GroupItem *prev = NULL; + GroupItem *trace = gTopOfGroupStack; + + while (trace) { + newgp = (GroupItem *) halloc(sizeof(GroupItem), "Copy Group Stack"); + newgp->cur_font = trace->cur_font; + newgp->cur_color = trace->cur_color; + newgp->center = trace->center; + if (!first) + first = newgp; + else + prev->next = newgp; + prev = newgp; + trace = trace->next; + } + if (newgp) + newgp->next = NULL; + return first; +} + +void +free_group_stack(GroupItem *g) +{ + GroupItem *trace = g; + + while (trace) { + GroupItem *junk = trace; + trace = trace->next; + free(junk); + } +} diff --git a/src/hyper/group.h b/src/hyper/group.h new file mode 100644 index 00000000..ce2ee5dd --- /dev/null +++ b/src/hyper/group.h @@ -0,0 +1,44 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +#ifndef _GROUP_H_ +#define _GROUP_H_ 1 + +#include "axiom-c-macros.h" +#include "hyper.h" + +extern GroupItem *gTopOfGroupStack; + +#endif diff --git a/src/hyper/group.pamphlet b/src/hyper/group.pamphlet deleted file mode 100644 index 0cc6377a..00000000 --- a/src/hyper/group.pamphlet +++ /dev/null @@ -1,283 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/group} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{group.h} -<>= -<> -#ifndef _GROUP_H_ -#define _GROUP_H_ 1 - -#include "axiom-c-macros.h" -#include "hyper.h" - -extern GroupItem *gTopOfGroupStack; - -#endif -@ -\section{group.c} -<>= -/****************************************************************************** - * - * group.c: Routines for managing the HyperDoc group stack. - * - * Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993. - * - ****************************************************************************/ -#define _GROUP_C -#include "useproto.h" -#include "debug.h" - - -#include "group.h" -#include "initx.h" - -#include "all_hyper_proto.H1" - -GroupItem *gTopOfGroupStack = NULL; - - - -int -pop_group_stack(void) -{ - /* This routine pops the top of the current group stack */ - GroupItem *junk; - - /* - * If the the stack has only a single item, then pop it anyway so the - * user can see the problem - */ - if (! gTopOfGroupStack->next) - return -1; - - /* Else, Pop the thing */ - - junk = gTopOfGroupStack; - gTopOfGroupStack = gTopOfGroupStack->next; - junk->next = NULL; - - free(junk); - - /* Now change the font to the cur_font and the cur_color */ - - change_text(gTopOfGroupStack->cur_color, gTopOfGroupStack->cur_font); - return 1; - -} - -void -push_group_stack(void) -{ - /* - * This routine makes room by pushing a new item on the stack - */ - GroupItem *newgp; - - newgp = (GroupItem *) halloc(sizeof(GroupItem), "Push Group Stack"); - newgp->cur_font = gTopOfGroupStack->cur_font; - newgp->cur_color = gTopOfGroupStack->cur_color; - newgp->center = gTopOfGroupStack->center; - newgp->next = gTopOfGroupStack; - - gTopOfGroupStack = newgp; -} - -void -init_group_stack(void) -{ - gTopOfGroupStack = (GroupItem *) halloc(sizeof(GroupItem), "Push Group Stack"); - gTopOfGroupStack->center = 0; - gTopOfGroupStack->next = NULL; - gTopOfGroupStack->cur_color = 0; - gTopOfGroupStack->cur_font = NULL; -} - -void -em_top_group(void) -{ - if (! gTopOfGroupStack->next) - push_group_stack(); - gTopOfGroupStack->cur_color = gEmColor; - gTopOfGroupStack->cur_font = gEmFont; - change_text(gTopOfGroupStack->cur_color, gTopOfGroupStack->cur_font); -} - -void -rm_top_group(void) -{ - if (! gTopOfGroupStack->next) - push_group_stack(); - gTopOfGroupStack->cur_color = gRmColor; - gTopOfGroupStack->cur_font = gRmFont; - change_text(gTopOfGroupStack->cur_color, gTopOfGroupStack->cur_font); - -} - -void -line_top_group(void) -{ - if (! gTopOfGroupStack->next) - push_group_stack(); - gTopOfGroupStack->cur_color = gBorderColor; - gTopOfGroupStack->cur_font = gRmFont; - change_text(gTopOfGroupStack->cur_color, gTopOfGroupStack->cur_font); - -} - -void -bf_top_group(void) -{ - /* - * Just in case the person is tryin a \em without a grouping - */ - - if (! gTopOfGroupStack->next) - push_group_stack(); - gTopOfGroupStack->cur_color = gBfColor; - gTopOfGroupStack->cur_font = gBfFont; - change_text(gTopOfGroupStack->cur_color, gTopOfGroupStack->cur_font); -} - -void -tt_top_group(void) -{ - if (! gTopOfGroupStack->next) - push_group_stack(); - gTopOfGroupStack->cur_color = gTtColor; - gTopOfGroupStack->cur_font = gTtFont; - change_text(gTopOfGroupStack->cur_color, gTopOfGroupStack->cur_font); -} - -void -push_active_group(void) -{ - push_group_stack(); - gTopOfGroupStack->cur_font = gActiveFont; - gTopOfGroupStack->cur_color = gActiveColor; - change_text(gTopOfGroupStack->cur_color, gTopOfGroupStack->cur_font); -} - -void -push_spad_group(void) -{ - push_group_stack(); - gTopOfGroupStack->cur_font = gAxiomFont; - gTopOfGroupStack->cur_color = gAxiomColor; - change_text(gTopOfGroupStack->cur_color, gTopOfGroupStack->cur_font); -} - -void -init_top_group(void) -{ - /* clear the group stack */ - while (pop_group_stack() >= 0) - ; - - /* then set the colors to be normal */ - - gTopOfGroupStack->cur_color = gRmColor; - gTopOfGroupStack->cur_font = gRmFont; - change_text(gTopOfGroupStack->cur_color, gTopOfGroupStack->cur_font); -} - -void -center_top_group(void) -{ - push_group_stack(); - gTopOfGroupStack->center = 1; -} - -GroupItem * -copy_group_stack(void) -{ - GroupItem *newgp = NULL; - GroupItem *first = NULL; - GroupItem *prev = NULL; - GroupItem *trace = gTopOfGroupStack; - - while (trace) { - newgp = (GroupItem *) halloc(sizeof(GroupItem), "Copy Group Stack"); - newgp->cur_font = trace->cur_font; - newgp->cur_color = trace->cur_color; - newgp->center = trace->center; - if (!first) - first = newgp; - else - prev->next = newgp; - prev = newgp; - trace = trace->next; - } - if (newgp) - newgp->next = NULL; - return first; -} - -void -free_group_stack(GroupItem *g) -{ - GroupItem *trace = g; - - while (trace) { - GroupItem *junk = trace; - trace = trace->next; - free(junk); - } -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/halloc.c b/src/hyper/halloc.c new file mode 100644 index 00000000..2c923850 --- /dev/null +++ b/src/hyper/halloc.c @@ -0,0 +1,76 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +#define _HALLOC_C +#include "axiom-c-macros.h" +#include "useproto.h" +#include "debug.h" +#include +#include +#if !defined(BSDplatform) +#include +#endif + +FILE *fp; + +#include "halloc.H1" + +/* allocate memory and bomb if none left (HyperDoc alloc) */ + +char * +halloc(int bytes, char *msg) +{ + static char buf[200]; + char *result; + +#ifdef DEBUG + static int first = 1; + + if (first) { + fp = fopen("/tmp/hallocs", "w"); + first = 0; + } +#endif + result = (char *) malloc(bytes); +#ifdef DEBUG + fprintf(fp, "%d\tAlocating %d Bytes for %s\n", result,bytes, msg); +#endif + if (result == NULL) { + sprintf(buf, "Ran out of memory allocating %s.\b", msg); + fprintf(stderr, "%s\n", buf); + exit(-1); + } + return result; +} diff --git a/src/hyper/halloc.pamphlet b/src/hyper/halloc.pamphlet deleted file mode 100644 index 66931187..00000000 --- a/src/hyper/halloc.pamphlet +++ /dev/null @@ -1,104 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/halloc} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{halloc.c} -<>= -#define _HALLOC_C -#include "axiom-c-macros.h" -#include "useproto.h" -#include "debug.h" -#include -#include -#if !defined(BSDplatform) -#include -#endif - -FILE *fp; - -#include "halloc.H1" - -/* allocate memory and bomb if none left (HyperDoc alloc) */ - -char * -halloc(int bytes, char *msg) -{ - static char buf[200]; - char *result; - -#ifdef DEBUG - static int first = 1; - - if (first) { - fp = fopen("/tmp/hallocs", "w"); - first = 0; - } -#endif - result = (char *) malloc(bytes); -#ifdef DEBUG - fprintf(fp, "%d\tAlocating %d Bytes for %s\n", result,bytes, msg); -#endif - if (result == NULL) { - sprintf(buf, "Ran out of memory allocating %s.\b", msg); - fprintf(stderr, "%s\n", buf); - exit(-1); - } - return result; -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/hash.c b/src/hyper/hash.c new file mode 100644 index 00000000..515c935c --- /dev/null +++ b/src/hyper/hash.c @@ -0,0 +1,221 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + All rights resrved. + + 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. +*/ + +#define _HASH_C +#include "axiom-c-macros.h" +#include "useproto.h" +#include "debug.h" + +#include +#include +#include +#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); +} diff --git a/src/hyper/hash.pamphlet b/src/hyper/hash.pamphlet deleted file mode 100644 index b1104820..00000000 --- a/src/hyper/hash.pamphlet +++ /dev/null @@ -1,249 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/hash} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{hash.c} -<>= -#define _HASH_C -#include "axiom-c-macros.h" -#include "useproto.h" -#include "debug.h" - -#include -#include -#include -#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); -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/ht_icon b/src/hyper/ht_icon new file mode 100644 index 00000000..859e0fe2 --- /dev/null +++ b/src/hyper/ht_icon @@ -0,0 +1,22 @@ +#define ht_icon_width 40 +#define ht_icon_height 40 +#define ht_icon_x_hot -1 +#define ht_icon_y_hot -1 +static char ht_icon_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xf7, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, + 0x00, 0xe7, 0x00, 0x00, 0x00, 0x00, 0xe7, 0xef, 0x7b, 0x3c, 0xe7, 0xff, + 0xef, 0x7f, 0x7e, 0xff, 0xff, 0xe7, 0xef, 0xe7, 0xfe, 0xe7, 0x6e, 0xe7, + 0xe7, 0xde, 0xe7, 0x7e, 0xe7, 0xff, 0x0e, 0xe7, 0x3c, 0xe7, 0x07, 0x0e, + 0xe7, 0x3c, 0xf7, 0xcf, 0x0e, 0xf7, 0x18, 0x7f, 0xfe, 0x1f, 0x00, 0x1c, + 0x3f, 0x7c, 0x1f, 0x00, 0x0e, 0x07, 0x00, 0x00, 0x00, 0x0f, 0x07, 0x00, + 0x00, 0x00, 0x87, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x00, + 0x00, 0x77, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x00, 0x00, 0x00, 0x77, 0x3e, 0xdc, 0x00, 0x00, 0x77, 0x7f, 0xfe, + 0x00, 0x00, 0xf7, 0xe3, 0xef, 0x00, 0x00, 0xf7, 0xe3, 0xc7, 0x00, 0x00, + 0xf7, 0xe3, 0x07, 0x00, 0x00, 0xf7, 0xe3, 0x07, 0x00, 0x00, 0xf7, 0xe3, + 0xcf, 0x00, 0x80, 0x7f, 0x7f, 0xfe, 0x00, 0x80, 0x3f, 0x3e, 0x7c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/src/hyper/htadd.c b/src/hyper/htadd.c new file mode 100644 index 00000000..02ec8f84 --- /dev/null +++ b/src/hyper/htadd.c @@ -0,0 +1,537 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +/* HyperDoc database file manager */ + + +#define _HTADD_C +#include "axiom-c-macros.h" +#include "useproto.h" +#include "hyper.h" +#include +#include +#include + +#include "lex.h" + +#include "htadd.H1" +#include "addfile.H1" +#include "halloc.H1" +#include "hash.H1" +#include "hterror.H1" +#include "lex.H1" + + + + +/* + * These are variables that htadd needs to have declared because it shares + * the lexical analyzer with HyperDoc + */ + +int gTtFontIs850=0; +HDWindow *gWindow = NULL; +extern int line_number; /* keeps track of which line a page starts on + * in a file. This way someone can start + * including a line number counter into + * HyperDoc. */ +/* for compatibility with HyperDoc */ +Sock *spad_socket = NULL; +Sock *session_server = NULL; +int MenuServerOpened; +Display *gXDisplay; +int gXScreenNumber; +int fresh = 0; + +#define Delete 1 +#define System 2 +#define Current 4 +#define Named 8 + +#define usage "usage: htadd [-s|-l|-f db-directory] [-d|-n] filenames" + + +int +main(int argc, char **argv) +{ + /*int i;*/ + char db_dir[256]; /* the directory where the db file is */ + char dbfilename[256]; /* the database filename */ + char *filenames[1000]; /* the files to be added */ + char **fnames = filenames; + short flag; /* flag for deleting or adding */ + + parse_args(argv, db_dir, filenames, &flag); + + if (!filenames[0]) { + fprintf(stderr, "%s\n", usage); + return -1; + } + + parser_init(); + + build_db_filename(flag, db_dir, dbfilename); + + if (fresh) + unlink(dbfilename); + + if (flag & Delete) + while (*fnames) + delete_file(dbfilename, *fnames++); + else + while (*fnames) + add_file(dbfilename, *fnames++, fresh); + return 0; +} + +/* + * This routine parses the command line arguments. It parses + * the command line arguments. It returns a flag which tells the calling + * routine what database file to use, and whether or not to delete files. + */ + + +static void +parse_args(char **argv, char *db_dir, char **filenames, short *fl) +{ + *fl = 0; + + while (*++argv) { + if (!strcmp(*argv, "-d")) + *fl |= Delete; + else if (!strcmp(*argv, "-s")) { + if (*fl & Current || *fl & Named) { + fprintf(stderr, "%s\n", usage); + exit(-1); + } + *fl |= System; + } + else if (!strcmp(*argv, "-n")) { + fresh = 1; + } + else if (!strcmp(*argv, "-l")) { + if (*fl & System || *fl & Named) { + fprintf(stderr, "%s\n", usage); + exit(-1); + } + *fl |= Current; + } + else if (!strcmp(*argv, "-f")) { + if (*fl & System || *fl & Current) { + fprintf(stderr, "%s\n", usage); + exit(-1); + } + *fl |= Named; + strcpy(db_dir, *++argv); + } + else + *filenames++ = *argv; + } + + *filenames = NULL; +} + + + +static int +writable(struct stat buff) +{ +#ifdef DEBUG + unsigned short uid = geteuid(), gid = getegid(); + + fprintf(stderr, "Uid = %d and Gid = %d\n", uid, gid); +#endif + + /* + * Checks the status structure sent against the user id, and goup id + */ + if ((buff.st_uid == geteuid()) && (buff.st_mode & S_IWUSR)) + return 1; + else if ((buff.st_gid == getegid()) && (buff.st_mode & S_IWGRP)) + return 1; + else if ((buff.st_mode & S_IWOTH)) + return 1; + return 0; +} + +/* check to see if the user has permission */ + +/* + * This procedure builds the db filename. Subsequently, it is passed onto all + * the add files that are called. + */ + + +static int +build_db_filename(short flag, char *db_dir, char *dbfilename) +{ + int ret_status; + struct stat buff; + char *SPAD; + char path[256]; + + + if (flag & System) { + SPAD = (char *) getenv("AXIOM"); + if (SPAD == NULL) { + fprintf(stderr, + "Build_db_filename: Defaulting on $AXIOM\n"); + SPAD = (char *) def_spad; + } + sprintf(dbfilename, "%s/share/hypertex/pages/%s", SPAD, db_file_name); + sprintf(path, "%s/share/hypertex/pages", SPAD); + } + else if (flag & Named) { + sprintf(dbfilename, "%s/%s", db_dir, db_file_name); + strcpy(path, db_dir); + } + else { /* use the current directory */ + sprintf(dbfilename, "./%s", db_file_name); + sprintf(path, "./"); + } +/* fprintf(stderr,"htadd:build_db_filename:dbfilename=%s\n",dbfilename);*/ + /* Now see if I can write to the file */ + ret_status = stat(dbfilename, &buff); + if (ret_status == -1) { + if (errno == ENOENT) { + /* If the file does not exist, then check it's path */ + ret_status = stat(path, &buff); + } + if (ret_status == -1) { + perror("build_db_file"); + exit(-1); + } + } + + /* check the status */ + + if (writable(buff)) + return 1; + + fprintf(stderr, "build_db_filename: Database file name is not writable\n"); + exit(-1); + return 0; +} + + +/*** + + This procedure now works as follows: + (1) It adds the files to the db_file without full pathnames. + Two names are going to be used when adding a file - + addname <-- The name without any paths + fullname <-- The name with a path prepended to it + (2) If the user specifies a pathname, then it is the path name that + is used. If the user does not dpecify a path name, then possible + paths are found as follows: + (i) If the user has an environment variable HTPATH set, the + paths mentioned are used. + (ii) If not, then the $AXIOM environment variable is used. +****/ + +static void +add_file(char *dbname, char *name, int fresh) +{ + char fullname[256]; + char temp_db_file[256]; + FILE *db_fp = NULL; + FILE *temp_db_fp = NULL; + FILE *ht_fp = NULL; + char addname[100]; + /*char *HTPATH;*/ + /*char *trace;*/ + /*char *spad;*/ + + + /** First thing I should do is find the proper file and open it **/ + ht_fp = ht_file_open(fullname, addname, name); + + /* + * Now I should try to open the two database files. The one to work with, + * and the temporary one; Send it a 1 so it checks for write access + */ + if (fresh) { + if ((db_fp = fopen(dbname, "a")) == NULL) { + fprintf(stderr, "Can't open database: %s file for appending\n", dbname); + exit(-1); + } + } + else { + if ((db_fp = fopen(dbname, "r")) == NULL) { + } + } + if (!fresh) + temp_db_fp = temp_file_open(temp_db_file); + + /** Now actually update the file by adding the changes ***/ + update_db(db_fp, temp_db_fp, ht_fp, addname, fullname, fresh); + + if (!fresh) + fclose(temp_db_fp); + fclose(ht_fp); + if (db_fp != NULL) + fclose(db_fp); + if (!fresh) { + copy_file(temp_db_file, dbname); + unlink(temp_db_file); + } +} + +static void +update_db(FILE *db, FILE *temp_db, FILE *new_file, + char *addname, char *fullname, int fresh) +{ + char *fname; + int c, file_there = 0, mtime; + + if (fresh) { + add_new_pages(db, new_file, addname, fullname); + return; + } + if (db == NULL) { + add_new_pages(temp_db, new_file, addname, fullname); + return; + } + init_scanner(); + cfile = db; + c = get_char(); + do { + if (c == '\t') { + get_filename(); + fname = alloc_string(token.id); + get_token(); + mtime = atoi(token.id); + if (strcmp(fname, addname) == 0) { + save_scanner_state(); + add_new_pages(temp_db, new_file, addname, fullname); + restore_scanner_state(); + file_there = 1; + while ((c = get_char()) != EOF) { + if (c == '\t') + break; + } + } + else { + fprintf(temp_db, "\t%s %d", fname, mtime); + while ((c = get_char()) != EOF) { + if (c == '\t') + break; + putc(c, temp_db); + } + } + free(fname); + } + else + c = get_char(); + } while (c != EOF); + if (!file_there) { + add_new_pages(temp_db, new_file, addname, fullname); + } +} + +#define Special(t) (( t == Page || t == NewCommand || t == Patch )?(1):(0)) +#define ptype(c, t) (strcpy(c, t)); + +static void +add_new_pages(FILE *temp_db, FILE *new_file, char *addname, char *fullname) +{ + char type[15]; + int pos; + int present_type; + int pages = 0; + struct stat fstats; + + stat(fullname, &fstats); + fprintf(temp_db, "\t%s %d\n", addname, (int)fstats.st_mtime); + cfile = new_file; + init_scanner(); + while (get_token() != EOF) { + if (Special(token.type)) { + ptype(type, token.id); + present_type = token.type; + pos = keyword_fpos; + get_token(); + if (token.type != Lbrace) { + fprintf(stderr, "missing left brace after a page, macro or patch \ + declaration\n"); + fprintf(stderr, "In the file %s on line %d\n", fullname, line_number); + exit(-1); + } + get_token(); + if (present_type == Page && token.type != Word) { + fprintf(stderr, "missing page name after \\begin{page}\n"); + fprintf(stderr, "In the file %s on line %d\n", fullname, line_number); + exit(-1); + } + else if (present_type == Macro && token.type != Macro) { + fprintf(stderr, "Expected a \\macro name after newcommand, got %s\n", + token.id); + fprintf(stderr, "In the file %s on line %d\n", fullname, line_number); + exit(-1); + } + else if (present_type == Patch && token.type != Word) { + fprintf(stderr, "Missing patch name after a \\begin{patch}\n"); + fprintf(stderr, "In the file %s on line %d\n", fullname, line_number); + exit(-1); + } + fprintf(temp_db, "\\%s %s %d %d\n", type, + token.id, pos, line_number); + pages++; + } + } + printf("Added %3d pages and/or macros from %s\n", pages, addname); +} + +static void +copy_file(char *f1, char *f2) +{ + FILE *fp1, *fp2; + int c; + + fp1 = fopen(f1, "r"); + fp2 = fopen(f2, "w"); + while ((c = getc(fp1)) != EOF) { + putc(c, fp2); + } + fclose(fp2); + fclose(fp1); +} + + + +#define whitespace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n') +#define delim(c) \ + (whitespace(c) ) + + +static void +get_filename(void) +{ + int c, ws; + static char buffer[256]; + char *buf = buffer; + + do { + keyword_fpos = fpos; + c = get_char(); + ws = whitespace(c); + } while (ws); + switch (c) { + case EOF: + fprintf(stderr, "Error trying to read ht.db, unexpected EOF\n"); + exit(-1); + case '%': + case '\\': + case '{': + case '}': + fprintf(stderr, "Error unexpexted character %c\n",c); + exit(-1); + default: + do { + *buf++ = c; + } while ((c = get_char()) != EOF && !delim(c)); + unget_char(c); + *buf = '\0'; + token.type = Word; + token.id = buffer; + break; + } +} + +static int +delete_file(char *dbname, char *name) +{ + char temp_db_file[256]; + FILE *db_fp, *temp_db_fp; + char dname[256]; + + + strcpy(dname, name); + extend_ht(dname); + + /* Open both the tmp database and the real one */ + if ((db_fp = fopen(dbname, "r")) == NULL) { + fprintf(stderr, "database file is empty, nothing to delete\n"); + return 1; + } + + temp_db_fp = temp_file_open(temp_db_file); + + /** Now actually update the file by deleting the pages */ + delete_db(db_fp, temp_db_fp, dname); + + fclose(temp_db_fp); + if (db_fp != NULL) + fclose(db_fp); + copy_file(temp_db_file, dbname); + unlink(temp_db_file); + return 0; +} + +static void +delete_db(FILE *db, FILE *temp_db, char *name) +{ + char *fname; + int c/*, file_there = 0*/, mtime; + + init_scanner(); + cfile = db; + c = get_char(); + do { + if (c == '\t') { + get_filename(); + fname = alloc_string(token.id); + get_token(); + mtime = atoi(token.id); + if (strcmp(fname, name) == 0) { + while ((c = get_char()) != EOF) { + if (c == '\t') + break; + } + } + else { + fprintf(temp_db, "\t%s %d", fname, mtime); + while ((c = get_char()) != EOF) { + if (c == '\t') + break; + putc(c, temp_db); + } + } + free(fname); + } + else + c = get_char(); + } while (c != EOF); +} diff --git a/src/hyper/htadd.pamphlet b/src/hyper/htadd.pamphlet deleted file mode 100644 index 657864c2..00000000 --- a/src/hyper/htadd.pamphlet +++ /dev/null @@ -1,586 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/htadd} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{htadd.c} -The [[htadd]] function can manipulate the database of hypertex pages. -To rebuild the hypertex database changes to the [[$AXIOM/share/hypertex]] -subdirectory and type: -\begin{verbatim} -htadd -f pages -n pages/* -\end{verbatim} -This will create a file called [[pages/ht.db]] which contains entries -similar to: -\begin{verbatim} - algebra.ht 1102052108 -\page AlgebraPage 216 9 -\page NumberTheoryPage 763 28 - ALIST.ht 1102052108 -\newcommand AssociationListXmpTitle 140 3 -\newcommand AssociationListXmpNumber 195 4 -\page AssociationListXmpPage 313 7 - ALIST.pht 1102052108 -\patch AssociationListXmpPagePatch1 0 1 -\patch AssociationListXmpPageEmpty1 447 11 -... -\end{verbatim} -<>= -/* HyperDoc database file manager */ - - -#define _HTADD_C -#include "axiom-c-macros.h" -#include "useproto.h" -#include "hyper.h" -#include -#include -#include - -#include "lex.h" - -#include "htadd.H1" -#include "addfile.H1" -#include "halloc.H1" -#include "hash.H1" -#include "hterror.H1" -#include "lex.H1" - - - - -/* - * These are variables that htadd needs to have declared because it shares - * the lexical analyzer with HyperDoc - */ - -int gTtFontIs850=0; -HDWindow *gWindow = NULL; -extern int line_number; /* keeps track of which line a page starts on - * in a file. This way someone can start - * including a line number counter into - * HyperDoc. */ -/* for compatibility with HyperDoc */ -Sock *spad_socket = NULL; -Sock *session_server = NULL; -int MenuServerOpened; -Display *gXDisplay; -int gXScreenNumber; -int fresh = 0; - -#define Delete 1 -#define System 2 -#define Current 4 -#define Named 8 - -#define usage "usage: htadd [-s|-l|-f db-directory] [-d|-n] filenames" - - -int -main(int argc, char **argv) -{ - /*int i;*/ - char db_dir[256]; /* the directory where the db file is */ - char dbfilename[256]; /* the database filename */ - char *filenames[1000]; /* the files to be added */ - char **fnames = filenames; - short flag; /* flag for deleting or adding */ - - parse_args(argv, db_dir, filenames, &flag); - - if (!filenames[0]) { - fprintf(stderr, "%s\n", usage); - return -1; - } - - parser_init(); - - build_db_filename(flag, db_dir, dbfilename); - - if (fresh) - unlink(dbfilename); - - if (flag & Delete) - while (*fnames) - delete_file(dbfilename, *fnames++); - else - while (*fnames) - add_file(dbfilename, *fnames++, fresh); - return 0; -} - -/* - * This routine parses the command line arguments. It parses - * the command line arguments. It returns a flag which tells the calling - * routine what database file to use, and whether or not to delete files. - */ - - -static void -parse_args(char **argv, char *db_dir, char **filenames, short *fl) -{ - *fl = 0; - - while (*++argv) { - if (!strcmp(*argv, "-d")) - *fl |= Delete; - else if (!strcmp(*argv, "-s")) { - if (*fl & Current || *fl & Named) { - fprintf(stderr, "%s\n", usage); - exit(-1); - } - *fl |= System; - } - else if (!strcmp(*argv, "-n")) { - fresh = 1; - } - else if (!strcmp(*argv, "-l")) { - if (*fl & System || *fl & Named) { - fprintf(stderr, "%s\n", usage); - exit(-1); - } - *fl |= Current; - } - else if (!strcmp(*argv, "-f")) { - if (*fl & System || *fl & Current) { - fprintf(stderr, "%s\n", usage); - exit(-1); - } - *fl |= Named; - strcpy(db_dir, *++argv); - } - else - *filenames++ = *argv; - } - - *filenames = NULL; -} - - - -static int -writable(struct stat buff) -{ -#ifdef DEBUG - unsigned short uid = geteuid(), gid = getegid(); - - fprintf(stderr, "Uid = %d and Gid = %d\n", uid, gid); -#endif - - /* - * Checks the status structure sent against the user id, and goup id - */ - if ((buff.st_uid == geteuid()) && (buff.st_mode & S_IWUSR)) - return 1; - else if ((buff.st_gid == getegid()) && (buff.st_mode & S_IWGRP)) - return 1; - else if ((buff.st_mode & S_IWOTH)) - return 1; - return 0; -} - -/* check to see if the user has permission */ - -/* - * This procedure builds the db filename. Subsequently, it is passed onto all - * the add files that are called. - */ - - -static int -build_db_filename(short flag, char *db_dir, char *dbfilename) -{ - int ret_status; - struct stat buff; - char *SPAD; - char path[256]; - - - if (flag & System) { - SPAD = (char *) getenv("AXIOM"); - if (SPAD == NULL) { - fprintf(stderr, - "Build_db_filename: Defaulting on $AXIOM\n"); - SPAD = (char *) def_spad; - } - sprintf(dbfilename, "%s/share/hypertex/pages/%s", SPAD, db_file_name); - sprintf(path, "%s/share/hypertex/pages", SPAD); - } - else if (flag & Named) { - sprintf(dbfilename, "%s/%s", db_dir, db_file_name); - strcpy(path, db_dir); - } - else { /* use the current directory */ - sprintf(dbfilename, "./%s", db_file_name); - sprintf(path, "./"); - } -/* fprintf(stderr,"htadd:build_db_filename:dbfilename=%s\n",dbfilename);*/ - /* Now see if I can write to the file */ - ret_status = stat(dbfilename, &buff); - if (ret_status == -1) { - if (errno == ENOENT) { - /* If the file does not exist, then check it's path */ - ret_status = stat(path, &buff); - } - if (ret_status == -1) { - perror("build_db_file"); - exit(-1); - } - } - - /* check the status */ - - if (writable(buff)) - return 1; - - fprintf(stderr, "build_db_filename: Database file name is not writable\n"); - exit(-1); - return 0; -} - - -/*** - - This procedure now works as follows: - (1) It adds the files to the db_file without full pathnames. - Two names are going to be used when adding a file - - addname <-- The name without any paths - fullname <-- The name with a path prepended to it - (2) If the user specifies a pathname, then it is the path name that - is used. If the user does not dpecify a path name, then possible - paths are found as follows: - (i) If the user has an environment variable HTPATH set, the - paths mentioned are used. - (ii) If not, then the $AXIOM environment variable is used. -****/ - -static void -add_file(char *dbname, char *name, int fresh) -{ - char fullname[256]; - char temp_db_file[256]; - FILE *db_fp = NULL; - FILE *temp_db_fp = NULL; - FILE *ht_fp = NULL; - char addname[100]; - /*char *HTPATH;*/ - /*char *trace;*/ - /*char *spad;*/ - - - /** First thing I should do is find the proper file and open it **/ - ht_fp = ht_file_open(fullname, addname, name); - - /* - * Now I should try to open the two database files. The one to work with, - * and the temporary one; Send it a 1 so it checks for write access - */ - if (fresh) { - if ((db_fp = fopen(dbname, "a")) == NULL) { - fprintf(stderr, "Can't open database: %s file for appending\n", dbname); - exit(-1); - } - } - else { - if ((db_fp = fopen(dbname, "r")) == NULL) { - } - } - if (!fresh) - temp_db_fp = temp_file_open(temp_db_file); - - /** Now actually update the file by adding the changes ***/ - update_db(db_fp, temp_db_fp, ht_fp, addname, fullname, fresh); - - if (!fresh) - fclose(temp_db_fp); - fclose(ht_fp); - if (db_fp != NULL) - fclose(db_fp); - if (!fresh) { - copy_file(temp_db_file, dbname); - unlink(temp_db_file); - } -} - -static void -update_db(FILE *db, FILE *temp_db, FILE *new_file, - char *addname, char *fullname, int fresh) -{ - char *fname; - int c, file_there = 0, mtime; - - if (fresh) { - add_new_pages(db, new_file, addname, fullname); - return; - } - if (db == NULL) { - add_new_pages(temp_db, new_file, addname, fullname); - return; - } - init_scanner(); - cfile = db; - c = get_char(); - do { - if (c == '\t') { - get_filename(); - fname = alloc_string(token.id); - get_token(); - mtime = atoi(token.id); - if (strcmp(fname, addname) == 0) { - save_scanner_state(); - add_new_pages(temp_db, new_file, addname, fullname); - restore_scanner_state(); - file_there = 1; - while ((c = get_char()) != EOF) { - if (c == '\t') - break; - } - } - else { - fprintf(temp_db, "\t%s %d", fname, mtime); - while ((c = get_char()) != EOF) { - if (c == '\t') - break; - putc(c, temp_db); - } - } - free(fname); - } - else - c = get_char(); - } while (c != EOF); - if (!file_there) { - add_new_pages(temp_db, new_file, addname, fullname); - } -} - -#define Special(t) (( t == Page || t == NewCommand || t == Patch )?(1):(0)) -#define ptype(c, t) (strcpy(c, t)); - -static void -add_new_pages(FILE *temp_db, FILE *new_file, char *addname, char *fullname) -{ - char type[15]; - int pos; - int present_type; - int pages = 0; - struct stat fstats; - - stat(fullname, &fstats); - fprintf(temp_db, "\t%s %d\n", addname, (int)fstats.st_mtime); - cfile = new_file; - init_scanner(); - while (get_token() != EOF) { - if (Special(token.type)) { - ptype(type, token.id); - present_type = token.type; - pos = keyword_fpos; - get_token(); - if (token.type != Lbrace) { - fprintf(stderr, "missing left brace after a page, macro or patch \ - declaration\n"); - fprintf(stderr, "In the file %s on line %d\n", fullname, line_number); - exit(-1); - } - get_token(); - if (present_type == Page && token.type != Word) { - fprintf(stderr, "missing page name after \\begin{page}\n"); - fprintf(stderr, "In the file %s on line %d\n", fullname, line_number); - exit(-1); - } - else if (present_type == Macro && token.type != Macro) { - fprintf(stderr, "Expected a \\macro name after newcommand, got %s\n", - token.id); - fprintf(stderr, "In the file %s on line %d\n", fullname, line_number); - exit(-1); - } - else if (present_type == Patch && token.type != Word) { - fprintf(stderr, "Missing patch name after a \\begin{patch}\n"); - fprintf(stderr, "In the file %s on line %d\n", fullname, line_number); - exit(-1); - } - fprintf(temp_db, "\\%s %s %d %d\n", type, - token.id, pos, line_number); - pages++; - } - } - printf("Added %3d pages and/or macros from %s\n", pages, addname); -} - -static void -copy_file(char *f1, char *f2) -{ - FILE *fp1, *fp2; - int c; - - fp1 = fopen(f1, "r"); - fp2 = fopen(f2, "w"); - while ((c = getc(fp1)) != EOF) { - putc(c, fp2); - } - fclose(fp2); - fclose(fp1); -} - - - -#define whitespace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n') -#define delim(c) \ - (whitespace(c) ) - - -static void -get_filename(void) -{ - int c, ws; - static char buffer[256]; - char *buf = buffer; - - do { - keyword_fpos = fpos; - c = get_char(); - ws = whitespace(c); - } while (ws); - switch (c) { - case EOF: - fprintf(stderr, "Error trying to read ht.db, unexpected EOF\n"); - exit(-1); - case '%': - case '\\': - case '{': - case '}': - fprintf(stderr, "Error unexpexted character %c\n",c); - exit(-1); - default: - do { - *buf++ = c; - } while ((c = get_char()) != EOF && !delim(c)); - unget_char(c); - *buf = '\0'; - token.type = Word; - token.id = buffer; - break; - } -} - -static int -delete_file(char *dbname, char *name) -{ - char temp_db_file[256]; - FILE *db_fp, *temp_db_fp; - char dname[256]; - - - strcpy(dname, name); - extend_ht(dname); - - /* Open both the tmp database and the real one */ - if ((db_fp = fopen(dbname, "r")) == NULL) { - fprintf(stderr, "database file is empty, nothing to delete\n"); - return 1; - } - - temp_db_fp = temp_file_open(temp_db_file); - - /** Now actually update the file by deleting the pages */ - delete_db(db_fp, temp_db_fp, dname); - - fclose(temp_db_fp); - if (db_fp != NULL) - fclose(db_fp); - copy_file(temp_db_file, dbname); - unlink(temp_db_file); - return 0; -} - -static void -delete_db(FILE *db, FILE *temp_db, char *name) -{ - char *fname; - int c/*, file_there = 0*/, mtime; - - init_scanner(); - cfile = db; - c = get_char(); - do { - if (c == '\t') { - get_filename(); - fname = alloc_string(token.id); - get_token(); - mtime = atoi(token.id); - if (strcmp(fname, name) == 0) { - while ((c = get_char()) != EOF) { - if (c == '\t') - break; - } - } - else { - fprintf(temp_db, "\t%s %d", fname, mtime); - while ((c = get_char()) != EOF) { - if (c == '\t') - break; - putc(c, temp_db); - } - } - free(fname); - } - else - c = get_char(); - } while (c != EOF); -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/hterror.c b/src/hyper/hterror.c new file mode 100644 index 00000000..8cd1e665 --- /dev/null +++ b/src/hyper/hterror.c @@ -0,0 +1,224 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + All right 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. +*/ + +#define _HTERROR_C +#define HTERROR + +#include "axiom-c-macros.h" +#include "useproto.h" +#include "debug.h" + +#include "lex.h" +#include "parse.h" + +#include "all_hyper_proto.H1" + +char ebuffer[128]; +jmp_buf jmpbuf; + +/* + * This file is the error handling routine in AXIOM. The main routine is + * called htperror(): arguments: msg - like perror it accepts an error + * message to be printed errno - the errno which occurred. This is so an + * appropriate error message can be printed. + * + * The prints out the page name, and then the filename in which the error + * occurred. If possible it also tries to print out the next ten tokens. + */ + +void +jump(void) +{ + if (gWindow == NULL) + exit(-1); + longjmp(jmpbuf, 1); + fprintf(stderr, "(HyperDoc) Long Jump failed, Exiting\n"); + exit(-1); +} + +void +print_page_and_filename(void) +{ + char obuff[128]; + + if (gPageBeingParsed->type == Normal) { + + /* + * Now try to inform the user as close to possible where the error + * occurred + */ + sprintf(obuff, "(HyperDoc) While parsing %s on line %d\n\tin the file %s\n", + gPageBeingParsed->name, line_number, + gPageBeingParsed->filename); + } + else if (gPageBeingParsed->type == SpadGen) { + sprintf(obuff, "While parsing %s from the Spad socket\n", + gPageBeingParsed->name); + } + else if (gPageBeingParsed->type == Unixfd) { + sprintf(obuff, "While parsing %s from a Unixpipe\n", + gPageBeingParsed->name); + } + else { + /* Unknown page type */ + sprintf(obuff, "While parsing %s\n", gPageBeingParsed->name); + } + fprintf(stderr, "%s", obuff); +} + + +void +print_next_ten_tokens(void) +{ + int i; + int v; + + fprintf(stderr, "Trying to print the next ten tokens\n"); + for (i = 0; i < 10; i++) { + v = get_token(); + if (v == EOF) + break; + print_token(); + } + fprintf(stderr, "\n"); +} + +/* print out a token value */ +void +print_token(void) +{ + if (token.type == Word) + printf("%s ", token.id); + else { + token_name(token.type); + printf("\\%s ", ebuffer); + } + fflush(stdout); +} + + +void +token_name(int type) +{ + if (type <= NumberUserTokens) + strcpy(ebuffer, token_table[type]); + else { + switch (type) { + case Lbrace: + strcpy(ebuffer, "{"); + break; + case Rbrace: + strcpy(ebuffer, "}"); + break; + case Macro: + strcpy(ebuffer, token.id); + break; + case Group: + strcpy(ebuffer, "{"); + break; + case Pound: + strcpy(ebuffer, "#"); + break; + case Lsquarebrace: + strcpy(ebuffer, "["); + break; + case Rsquarebrace: + strcpy(ebuffer, "]"); + break; + case Punctuation: + strcpy(ebuffer, token.id); + break; + case Dash: + strcpy(ebuffer, token.id); + break; + case Verbatim: + strcpy(ebuffer, "\\begin{verbatim}"); + break; + case Scroll: + strcpy(ebuffer, "\\begin{scroll}"); + break; + case Dollar: + strcpy(ebuffer, "$"); + break; + case Percent: + strcpy(ebuffer, "%"); + break; + case Carrot: + strcpy(ebuffer, "^"); + break; + case Underscore: + strcpy(ebuffer, "_"); + break; + case Tilde: + strcpy(ebuffer, "~"); + break; + case Cond: + sprintf(ebuffer, "\\%s", token.id); + break; + case Icorrection: + strcpy(ebuffer, "\\/"); + break; + case Paste: + strcpy(ebuffer, "\\begin{paste}"); + break; + case Patch: + strcpy(ebuffer, "\\begin{patch}"); + break; + default: + sprintf(ebuffer, " %d ", type); + } + /*return 1;*/ + } +} +void +htperror(char *msg, int errno) +{ + char obuff[256]; + + /* The first thing I do is create the error message */ + + if (errno <= Numerrors) { + sprintf(obuff, "%s:%s\n", msg, errmess[errno]); + } + else { + sprintf(obuff, "%s:\n", msg); + fprintf(stderr, "Unknown error type %d\n", errno); + } + fprintf(stderr, "%s", obuff); + + print_page_and_filename(); + + print_next_ten_tokens(); +} diff --git a/src/hyper/hterror.h b/src/hyper/hterror.h new file mode 100644 index 00000000..1ecf63d1 --- /dev/null +++ b/src/hyper/hterror.h @@ -0,0 +1,45 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +#define HTCONDNODE 1 /* unrecognized condition node */ +#define KEYTYPE 2 /* unrecognized keyword found in lex.c */ +#define Numerrors 2 + +#ifdef HTERROR +char *errmess[] = { + "place holder", + "parsing condition node", + "unrecognized keyword" }; +#endif diff --git a/src/hyper/hterror.pamphlet b/src/hyper/hterror.pamphlet deleted file mode 100644 index f2bdddf6..00000000 --- a/src/hyper/hterror.pamphlet +++ /dev/null @@ -1,266 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/hterror} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{hterror.h} -<>= -<> -#define HTCONDNODE 1 /* unrecognized condition node */ -#define KEYTYPE 2 /* unrecognized keyword found in lex.c */ -#define Numerrors 2 - -#ifdef HTERROR -char *errmess[] = { - "place holder", - "parsing condition node", - "unrecognized keyword" }; -#endif -@ -\section{hterror.c} -<>= -#define _HTERROR_C -#define HTERROR - -#include "axiom-c-macros.h" -#include "useproto.h" -#include "debug.h" - -#include "lex.h" -#include "parse.h" - -#include "all_hyper_proto.H1" - -char ebuffer[128]; -jmp_buf jmpbuf; - -/* - * This file is the error handling routine in AXIOM. The main routine is - * called htperror(): arguments: msg - like perror it accepts an error - * message to be printed errno - the errno which occurred. This is so an - * appropriate error message can be printed. - * - * The prints out the page name, and then the filename in which the error - * occurred. If possible it also tries to print out the next ten tokens. - */ - -void -jump(void) -{ - if (gWindow == NULL) - exit(-1); - longjmp(jmpbuf, 1); - fprintf(stderr, "(HyperDoc) Long Jump failed, Exiting\n"); - exit(-1); -} - -void -print_page_and_filename(void) -{ - char obuff[128]; - - if (gPageBeingParsed->type == Normal) { - - /* - * Now try to inform the user as close to possible where the error - * occurred - */ - sprintf(obuff, "(HyperDoc) While parsing %s on line %d\n\tin the file %s\n", - gPageBeingParsed->name, line_number, - gPageBeingParsed->filename); - } - else if (gPageBeingParsed->type == SpadGen) { - sprintf(obuff, "While parsing %s from the Spad socket\n", - gPageBeingParsed->name); - } - else if (gPageBeingParsed->type == Unixfd) { - sprintf(obuff, "While parsing %s from a Unixpipe\n", - gPageBeingParsed->name); - } - else { - /* Unknown page type */ - sprintf(obuff, "While parsing %s\n", gPageBeingParsed->name); - } - fprintf(stderr, "%s", obuff); -} - - -void -print_next_ten_tokens(void) -{ - int i; - int v; - - fprintf(stderr, "Trying to print the next ten tokens\n"); - for (i = 0; i < 10; i++) { - v = get_token(); - if (v == EOF) - break; - print_token(); - } - fprintf(stderr, "\n"); -} - -/* print out a token value */ -void -print_token(void) -{ - if (token.type == Word) - printf("%s ", token.id); - else { - token_name(token.type); - printf("\\%s ", ebuffer); - } - fflush(stdout); -} - - -void -token_name(int type) -{ - if (type <= NumberUserTokens) - strcpy(ebuffer, token_table[type]); - else { - switch (type) { - case Lbrace: - strcpy(ebuffer, "{"); - break; - case Rbrace: - strcpy(ebuffer, "}"); - break; - case Macro: - strcpy(ebuffer, token.id); - break; - case Group: - strcpy(ebuffer, "{"); - break; - case Pound: - strcpy(ebuffer, "#"); - break; - case Lsquarebrace: - strcpy(ebuffer, "["); - break; - case Rsquarebrace: - strcpy(ebuffer, "]"); - break; - case Punctuation: - strcpy(ebuffer, token.id); - break; - case Dash: - strcpy(ebuffer, token.id); - break; - case Verbatim: - strcpy(ebuffer, "\\begin{verbatim}"); - break; - case Scroll: - strcpy(ebuffer, "\\begin{scroll}"); - break; - case Dollar: - strcpy(ebuffer, "$"); - break; - case Percent: - strcpy(ebuffer, "%"); - break; - case Carrot: - strcpy(ebuffer, "^"); - break; - case Underscore: - strcpy(ebuffer, "_"); - break; - case Tilde: - strcpy(ebuffer, "~"); - break; - case Cond: - sprintf(ebuffer, "\\%s", token.id); - break; - case Icorrection: - strcpy(ebuffer, "\\/"); - break; - case Paste: - strcpy(ebuffer, "\\begin{paste}"); - break; - case Patch: - strcpy(ebuffer, "\\begin{patch}"); - break; - default: - sprintf(ebuffer, " %d ", type); - } - /*return 1;*/ - } -} -void -htperror(char *msg, int errno) -{ - char obuff[256]; - - /* The first thing I do is create the error message */ - - if (errno <= Numerrors) { - sprintf(obuff, "%s:%s\n", msg, errmess[errno]); - } - else { - sprintf(obuff, "%s:\n", msg); - fprintf(stderr, "Unknown error type %d\n", errno); - } - fprintf(stderr, "%s", obuff); - - print_page_and_filename(); - - print_next_ten_tokens(); -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/hthits.c b/src/hyper/hthits.c new file mode 100644 index 00000000..b3e24774 --- /dev/null +++ b/src/hyper/hthits.c @@ -0,0 +1,428 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +/* + * hthits pattern htdb-file + * + * Scan HyperDoc files for a given pattern. + * + * The output contains lines of the form: + * + * page-name`title`n + * + * The title and body of each page are scanned but the name is not. It is + * possible that the title matches but not any lines. The number of matches + * in the page (n) is given last. + * + * SMW Feb 91 + */ +#define _HTHITS_C +#include "axiom-c-macros.h" + +#include "debug.h" + +#include +#include +#include +#include +#include +#include +#include + +/* + * For fixed-size arrays. + */ +#define MAX_HTDB_LINE 1024 +#define MAX_ENTRY_TYPE 30 /* I.e. \page \newcommand \patch ... */ +#define MAX_ENTRY_NAME 1024 /* E.g. DifferentialCalculusPage */ +#define MAX_COMP_REGEX 1024 + +typedef struct pgInfo { + char name[MAX_ENTRY_NAME]; + long start, size; +} PgInfo ; + +#include "hthits.H1" + +/* + * Global variables set according to the command line. + */ + +char *progName; +char *pattern; +char *htdbFName; +int gverifydates=0; +regex_t reg_pattern; + +int +main(int argc,char ** argv) +{ + cmdline(argc, argv); + + regcomp(®_pattern, pattern, REG_NEWLINE); + + handleHtdb(); + return(0); +} + +void +cmdline(int argc,char ** argv) +{ + progName = argv[0]; + + if (argc != 3) { + fprintf(stderr, "Usage: %s pattern htdb-file\n", progName); + exit(1); + } + + pattern = argv[1]; + htdbFName = argv[2]; +} + +void +handleHtdb(void) +{ + FILE *htdbFile; + int c; + + htdbFile = fopen(htdbFName, "r"); + if (htdbFile == NULL) + badDB(); + + while ((c = getc(htdbFile)) != EOF) { + if (c != '\t') + badDB(); + ungetc(c, htdbFile); + + handleFile(htdbFile); + } + fclose(htdbFile); +} + + +void +handleFile(FILE *htdbFile) +{ + static PgInfo *pgInfoV = 0; + static int pgInfoC = 0; + + char htdbLine[MAX_HTDB_LINE]; + char htfname[MAX_HTDB_LINE]; + time_t httime; + long htsize; + struct stat htstat; + + long fstart, fend; + int rc, i, npages; + + char entname[MAX_ENTRY_NAME], enttype[MAX_ENTRY_TYPE]; + long entoffset, entlineno; + + fgets(htdbLine, MAX_HTDB_LINE, htdbFile); + + sscanf(htdbLine, " %s %ld", htfname, &httime); + + /* + * 1. Verify file: get size and check modification time. + */ + rc = stat(htfname, &htstat); + if (rc == -1) { + fprintf(stderr, "%s: Cannot access %s\n", progName, htfname); + exit(1); + } + if (gverifydates && (htstat.st_mtime != httime)) { + + fprintf(stderr, "%s: Out of date file %s\n", progName, htfname); + exit(1); + } + htsize = htstat.st_size; + + /* + * 2. Count the pages in the file. + */ + npages = 0; + fstart = ftell(htdbFile); + fend = ftell(htdbFile); + + while (fgets(htdbLine, MAX_HTDB_LINE, htdbFile) != NULL) { + if (htdbLine[0] == '\t') + break; + if (!strncmp(htdbLine, "\\page", 5)) + npages++; + fend = ftell(htdbFile); + } + + /* + * 3. Find offset and size of each \page (skipping \newcommands etc.) + */ + if (npages > pgInfoC) { + if (pgInfoV) + free(pgInfoV); + + pgInfoC = npages; + pgInfoV = (PgInfo *) + malloc(npages * sizeof(PgInfo)); + + if (!pgInfoV) { + fprintf(stderr, "%s: out of memory\n", progName); + exit(1); + } + } + + fseek(htdbFile, fstart, 0); + + for (i = 0; fgets(htdbLine, MAX_HTDB_LINE, htdbFile) != NULL;) { + if (htdbLine[0] == '\t') + break; + + sscanf(htdbLine, "%s %s %ld %ld", + enttype, entname, &entoffset, &entlineno); + + if (i > 0 && pgInfoV[i - 1].size == -1) + pgInfoV[i - 1].size = entoffset - pgInfoV[i - 1].start; + + if (!strcmp(enttype, "\\page")) { + strncpy(pgInfoV[i].name, entname, MAX_ENTRY_NAME); + pgInfoV[i].start = entoffset; + pgInfoV[i].size = -1; + + i++; + } + } + if (i > 0 && pgInfoV[i - 1].size == -1) + pgInfoV[i - 1].size = htsize - pgInfoV[i - 1].start; + + if (i != npages) + badDB(); + + /* + * 4. Position database input to read next file-description + */ + fseek(htdbFile, fend, 0); + + /* + * 5. Process the pages of the file. + */ + handleFilePages(htfname, npages, pgInfoV); +} + +void +handleFilePages(char *fname, int pgc, PgInfo *pgv) +{ + FILE *infile; + int i; + + infile = fopen(fname, "r"); + if (infile == NULL) { + fprintf(stderr, "%s: Cannot read file %s\n", progName, fname); + exit(1); + } + + + for (i = 0; i < pgc; i++) + handlePage(infile, pgv + i); + + fclose(infile); + +} + +void +handlePage(FILE *infile,PgInfo * pg) +{ + static char *pgBuf = 0; + static int pgBufSize = 0; + + char *title, *body; + + if (pg->size > pgBufSize - 1) { + if (pgBuf) + free(pgBuf); + pgBufSize = pg->size + 20000; + pgBuf = (char *)malloc(pgBufSize); + + if (!pgBuf) { + fprintf(stderr,"%s: Out of memory\n", progName); + exit(1); + } + } + + fseek(infile, pg->start, 0); + fread(pgBuf, pg->size, 1, infile); + pgBuf[pg->size] = 0; + + splitpage(pgBuf, &title, &body); + /*untexbuf(title);*/ + untexbuf(body); + +#ifdef DEBUG + printf("-------------- %s -------------\n%s", pg->name, pgBuf); + printf("============== %s =============\n", title); + printf("%s", body); +#endif + + searchPage(pg->name, title, body); + +} + +void +searchPage(char *pgname,char * pgtitle,char * pgbody) +{ + char *bodyrest; + regmatch_t match_pos; + int nhits = 0; + + if (!regexec(®_pattern, pgtitle, 1, &match_pos, 0)) + nhits++; + + bodyrest = pgbody; + while (!regexec(®_pattern, bodyrest, 1, &match_pos, 0)) { + nhits++; + bodyrest += match_pos.rm_eo; + } + if (nhits) { + printf("\\newsearchresultentry{%d}{%s}",nhits, pgtitle); + squirt(pgname, strlen(pgname)); + printf("\n"); + } +} + +/* + * Given string s and length n, output ` followed by the first n characters + * of s with ` and newline converted to blanks. This function destructively + * modifies s. + */ + +void +squirt(char *s, int n) +{ + register char *t, *e; + int c; + + c = s[n]; + + for (t = s, e = s + n; t < e; t++) + if (*t == '`' || *t == '\n') + *t = ' '; + + if (s[n] != 0) { + s[n] = 0; + } + printf("{%.*s}", n, s); + s[n] = c; +} + +/* + * Any newlines and separator characters in the title are changed to blanks. + */ +void +splitpage(char *buf, char **ptitle, char **pbody) +{ + int n, depth, tno; + char *s; + + switch (buf[1]) { + case 'p': + tno = 2; + break; /* \page{Name}{Title} */ + case 'b': + tno = 3; + break; /* \begin{page}{Name}{Title} */ + default: + fprintf(stderr, "%s: Invalid page format: %s\n", progName, buf); + exit(1); + } + + n = 0; + depth = 0; + + for (s = buf; *s; s++) { + if (*s == '{') + if (++depth == 1 && ++n == tno) + *ptitle = s + 1; + if (*s == '}') + if (depth-- == 1 && n == tno) { + *s = 0; + *pbody = s + 1; + break; + } + } +} + + +void +untexbuf(register char *s) +{ + register char *d = s; + + while (*s) + switch (*s) { + case '\\': + *d++ = ' '; + s++; + if (*s != '%') + while (isalpha(*s)) + s++; + break; + case '%': + *d++ = ' '; + s++; + while (*s && *s != '\n') + s++; + break; + case '{': + case '}': + case '#': + *d++ = ' '; + s++; + break; + default: + *d++ = *s++; + } + *d = 0; +} + +void +badDB(void) +{ + fprintf(stderr, "%s: bad database file %s\n", progName, htdbFName); + exit(1); +} + +void +regerr(int code) +{ + fprintf(stderr, "%s: regular expression error %d for \"%s\"\n", + progName, code, pattern); +} diff --git a/src/hyper/hthits.pamphlet b/src/hyper/hthits.pamphlet deleted file mode 100644 index c3dc4e1b..00000000 --- a/src/hyper/hthits.pamphlet +++ /dev/null @@ -1,474 +0,0 @@ -\documentclass{article} -\usepackage{axiom} - -\title{\$SPAD/src/hthits} -\author{The Axiom Team} - -\begin{document} -\maketitle - -\begin{abstract} -\end{abstract} -\eject - -\tableofcontents -\eject - -\section{hthits.c} - -This source file implements HyperDoc's ability to scan files for a -given pattern. For that purpose it needs a ``regex'' for string -pattern matching. - -This source file used to rely on [[]], -which was originally part of the X/Open System Interface and Headers -Issue 2. However, since then, it has been withdrawn and no longer -always available on newer platfroms. Consequently, -we need to use a different, portable regex library. The POSIX -definition provides one, namely through [[]]. That is what we -use now. Its availability is tested at configure time. - -<>= -/* - * hthits pattern htdb-file - * - * Scan HyperDoc files for a given pattern. - * - * The output contains lines of the form: - * - * page-name`title`n - * - * The title and body of each page are scanned but the name is not. It is - * possible that the title matches but not any lines. The number of matches - * in the page (n) is given last. - * - * SMW Feb 91 - */ -#define _HTHITS_C -#include "axiom-c-macros.h" - -#include "debug.h" - -#include -#include -#include -#include -#include -#include -#include - -/* - * For fixed-size arrays. - */ -#define MAX_HTDB_LINE 1024 -#define MAX_ENTRY_TYPE 30 /* I.e. \page \newcommand \patch ... */ -#define MAX_ENTRY_NAME 1024 /* E.g. DifferentialCalculusPage */ -#define MAX_COMP_REGEX 1024 - -typedef struct pgInfo { - char name[MAX_ENTRY_NAME]; - long start, size; -} PgInfo ; - -#include "hthits.H1" - -/* - * Global variables set according to the command line. - */ - -char *progName; -char *pattern; -char *htdbFName; -int gverifydates=0; -regex_t reg_pattern; - -int -main(int argc,char ** argv) -{ - cmdline(argc, argv); - - regcomp(®_pattern, pattern, REG_NEWLINE); - - handleHtdb(); - return(0); -} - -void -cmdline(int argc,char ** argv) -{ - progName = argv[0]; - - if (argc != 3) { - fprintf(stderr, "Usage: %s pattern htdb-file\n", progName); - exit(1); - } - - pattern = argv[1]; - htdbFName = argv[2]; -} - -void -handleHtdb(void) -{ - FILE *htdbFile; - int c; - - htdbFile = fopen(htdbFName, "r"); - if (htdbFile == NULL) - badDB(); - - while ((c = getc(htdbFile)) != EOF) { - if (c != '\t') - badDB(); - ungetc(c, htdbFile); - - handleFile(htdbFile); - } - fclose(htdbFile); -} - - -void -handleFile(FILE *htdbFile) -{ - static PgInfo *pgInfoV = 0; - static int pgInfoC = 0; - - char htdbLine[MAX_HTDB_LINE]; - char htfname[MAX_HTDB_LINE]; - time_t httime; - long htsize; - struct stat htstat; - - long fstart, fend; - int rc, i, npages; - - char entname[MAX_ENTRY_NAME], enttype[MAX_ENTRY_TYPE]; - long entoffset, entlineno; - - fgets(htdbLine, MAX_HTDB_LINE, htdbFile); - - sscanf(htdbLine, " %s %ld", htfname, &httime); - - /* - * 1. Verify file: get size and check modification time. - */ - rc = stat(htfname, &htstat); - if (rc == -1) { - fprintf(stderr, "%s: Cannot access %s\n", progName, htfname); - exit(1); - } - if (gverifydates && (htstat.st_mtime != httime)) { - - fprintf(stderr, "%s: Out of date file %s\n", progName, htfname); - exit(1); - } - htsize = htstat.st_size; - - /* - * 2. Count the pages in the file. - */ - npages = 0; - fstart = ftell(htdbFile); - fend = ftell(htdbFile); - - while (fgets(htdbLine, MAX_HTDB_LINE, htdbFile) != NULL) { - if (htdbLine[0] == '\t') - break; - if (!strncmp(htdbLine, "\\page", 5)) - npages++; - fend = ftell(htdbFile); - } - - /* - * 3. Find offset and size of each \page (skipping \newcommands etc.) - */ - if (npages > pgInfoC) { - if (pgInfoV) - free(pgInfoV); - - pgInfoC = npages; - pgInfoV = (PgInfo *) - malloc(npages * sizeof(PgInfo)); - - if (!pgInfoV) { - fprintf(stderr, "%s: out of memory\n", progName); - exit(1); - } - } - - fseek(htdbFile, fstart, 0); - - for (i = 0; fgets(htdbLine, MAX_HTDB_LINE, htdbFile) != NULL;) { - if (htdbLine[0] == '\t') - break; - - sscanf(htdbLine, "%s %s %ld %ld", - enttype, entname, &entoffset, &entlineno); - - if (i > 0 && pgInfoV[i - 1].size == -1) - pgInfoV[i - 1].size = entoffset - pgInfoV[i - 1].start; - - if (!strcmp(enttype, "\\page")) { - strncpy(pgInfoV[i].name, entname, MAX_ENTRY_NAME); - pgInfoV[i].start = entoffset; - pgInfoV[i].size = -1; - - i++; - } - } - if (i > 0 && pgInfoV[i - 1].size == -1) - pgInfoV[i - 1].size = htsize - pgInfoV[i - 1].start; - - if (i != npages) - badDB(); - - /* - * 4. Position database input to read next file-description - */ - fseek(htdbFile, fend, 0); - - /* - * 5. Process the pages of the file. - */ - handleFilePages(htfname, npages, pgInfoV); -} - -void -handleFilePages(char *fname, int pgc, PgInfo *pgv) -{ - FILE *infile; - int i; - - infile = fopen(fname, "r"); - if (infile == NULL) { - fprintf(stderr, "%s: Cannot read file %s\n", progName, fname); - exit(1); - } - - - for (i = 0; i < pgc; i++) - handlePage(infile, pgv + i); - - fclose(infile); - -} - -void -handlePage(FILE *infile,PgInfo * pg) -{ - static char *pgBuf = 0; - static int pgBufSize = 0; - - char *title, *body; - - if (pg->size > pgBufSize - 1) { - if (pgBuf) - free(pgBuf); - pgBufSize = pg->size + 20000; - pgBuf = (char *)malloc(pgBufSize); - - if (!pgBuf) { - fprintf(stderr,"%s: Out of memory\n", progName); - exit(1); - } - } - - fseek(infile, pg->start, 0); - fread(pgBuf, pg->size, 1, infile); - pgBuf[pg->size] = 0; - - splitpage(pgBuf, &title, &body); - /*untexbuf(title);*/ - untexbuf(body); - -#ifdef DEBUG - printf("-------------- %s -------------\n%s", pg->name, pgBuf); - printf("============== %s =============\n", title); - printf("%s", body); -#endif - - searchPage(pg->name, title, body); - -} - -void -searchPage(char *pgname,char * pgtitle,char * pgbody) -{ - char *bodyrest; - regmatch_t match_pos; - int nhits = 0; - - if (!regexec(®_pattern, pgtitle, 1, &match_pos, 0)) - nhits++; - - bodyrest = pgbody; - while (!regexec(®_pattern, bodyrest, 1, &match_pos, 0)) { - nhits++; - bodyrest += match_pos.rm_eo; - } - if (nhits) { - printf("\\newsearchresultentry{%d}{%s}",nhits, pgtitle); - squirt(pgname, strlen(pgname)); - printf("\n"); - } -} - -/* - * Given string s and length n, output ` followed by the first n characters - * of s with ` and newline converted to blanks. This function destructively - * modifies s. - */ - -void -squirt(char *s, int n) -{ - register char *t, *e; - int c; - - c = s[n]; - - for (t = s, e = s + n; t < e; t++) - if (*t == '`' || *t == '\n') - *t = ' '; - - if (s[n] != 0) { - s[n] = 0; - } - printf("{%.*s}", n, s); - s[n] = c; -} - -/* - * Any newlines and separator characters in the title are changed to blanks. - */ -void -splitpage(char *buf, char **ptitle, char **pbody) -{ - int n, depth, tno; - char *s; - - switch (buf[1]) { - case 'p': - tno = 2; - break; /* \page{Name}{Title} */ - case 'b': - tno = 3; - break; /* \begin{page}{Name}{Title} */ - default: - fprintf(stderr, "%s: Invalid page format: %s\n", progName, buf); - exit(1); - } - - n = 0; - depth = 0; - - for (s = buf; *s; s++) { - if (*s == '{') - if (++depth == 1 && ++n == tno) - *ptitle = s + 1; - if (*s == '}') - if (depth-- == 1 && n == tno) { - *s = 0; - *pbody = s + 1; - break; - } - } -} - - -void -untexbuf(register char *s) -{ - register char *d = s; - - while (*s) - switch (*s) { - case '\\': - *d++ = ' '; - s++; - if (*s != '%') - while (isalpha(*s)) - s++; - break; - case '%': - *d++ = ' '; - s++; - while (*s && *s != '\n') - s++; - break; - case '{': - case '}': - case '#': - *d++ = ' '; - s++; - break; - default: - *d++ = *s++; - } - *d = 0; -} - -void -badDB(void) -{ - fprintf(stderr, "%s: bad database file %s\n", progName, htdbFName); - exit(1); -} - -void -regerr(int code) -{ - fprintf(stderr, "%s: regular expression error %d for \"%s\"\n", - progName, code, pattern); -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/htinp.c b/src/hyper/htinp.c new file mode 100644 index 00000000..30d975ad --- /dev/null +++ b/src/hyper/htinp.c @@ -0,0 +1,499 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +#define _HTINP_C +#include "axiom-c-macros.h" +#include "useproto.h" +#include "debug.h" + +#include +#include +#include + +#include "hyper.h" +#include "group.h" +#include "parse.h" +#include "bsdsignal.h" + +#include "all_hyper_proto.H1" +#include "sockio-c.H1" +#include "bsdsignal.H1" + +extern char **input_file_list; +extern int input_file_count; +extern int make_patch_files; +extern int kill_spad; +extern jmp_buf jmpbuf; + + +#define MaxInputFiles 256 +char *active_file_list[MaxInputFiles]; +int num_active_files = 0; +char *inactive_file_list[MaxInputFiles]; +int num_inactive_files = 0; +int include_bf = 0; +char buf_for_record_commands[256]; + + + +void +make_record(void) +{ + int i; + for (i=0;ifPageHashTable; + make_input_file_list(); + for (i = 0; i < table->size; i++) + for (entry = table->table[i]; entry != NULL; entry = entry->next) + make_the_input_file((UnloadedPage *) entry->data); + if (kill_spad){ + i = connect_spad(); + if (i != NotConnected && i != SpadBusy) + send_int(spad_socket, KillLispSystem); + } +} + +static char * +make_input_file_name(char *buf, char *filename) +{ + char *b, *c; + + strcpy(buf, filename); + for (b = buf + strlen(buf) - 1; b != buf && *b != '/'; b--); + if (b != buf) + b = b + 1; + for (c = b; *c != '.' || c[1] != 'h' || c[2] != 't'; c++); + strcpy(c, ".input"); + return b; +} + +static char * +make_paste_file_name(char *buf, char *filename) +{ + char *b, *c; + + strcpy(buf, filename); + for (b = buf + strlen(buf) - 1; b != buf && *b != '/'; b--); + if (b != buf) + b = b + 1; + for (c = b; *c != '.' || c[1] != 'h' || c[2] != 't'; c++); + strcpy(c, ".pht"); + return b; +} + +static void +make_the_input_file(UnloadedPage *page) +{ + char buf[1024], *b; + + if (!page->fpos.name) + return; + b = make_input_file_name(buf, page->fpos.name); + if (inListAndNewer(b, page->fpos.name)) { + printf("parsing: %s\n", page->name); + if (setjmp(jmpbuf)) { + printf("Syntax error!\n"); + } + else { + load_page((HyperDocPage *)page); + make_input_file_from_page(gWindow->page); + } + } +} + +int example_number; + +static void +make_input_file_from_page(HyperDocPage *page) +{ + TextNode *node; + int starting_file = 1,/* i,*/ /*len,*/ ret_val; + char *buf, buf2[1024], buf3[1024]; + char *b, *c, *com; + FILE *file = NULL; + FILE *pfile = NULL; + static HyperDocPage *op = NULL; + + if (op == page) + return; + op = page; + if (page == NULL) + return; + b = make_input_file_name(buf2, page->filename); + c = make_paste_file_name(buf3, page->filename); + if (inListAndNewer(b, page->filename)) { + /* open and prepare the input file */ + file = fopen(b, "a"); + if (file == NULL) { + fprintf(stderr, "couldn't open output file %s\n", b); + exit(-1); + } + fprintf(file, "\n-- Input for page %s\n", page->name); + fprintf(file, ")clear all\n\n"); + + for (node = page->scrolling; node != NULL; node = node->next) + if (node->type == Spadcommand || node->type == Spadgraph + || node->type == Spadsrc) { + if (starting_file) { + example_number = 1; + if (make_patch_files) { + send_lisp_command("(|clearCmdAll|)"); + send_lisp_command("(|resetWorkspaceVariables|)"); + send_lisp_command("(setq $linelength 55)"); + send_lisp_command("(|setOutputCharacters| '(default))"); + send_lisp_command("(setq |$printLoadMsgs| NIL)"); + send_lisp_command("(setq |$UserLevel| '|development|)"); + send_lisp_command("(verbos 0)"); + } + if (make_patch_files) { + pfile = fopen(c, "a"); + if (pfile == NULL) { + fprintf(stderr, "couldn't open output file %s\n", c); + exit(-1); + } + } + starting_file = 0; + } + else + example_number++; + buf = print_to_string(node->next); + com = alloc_string(buf); + fprintf(file, "%s\n", buf); + fflush(file); + fprintf(stderr, "writing:\t%s\n", buf); + include_bf = 1; + buf = print_to_string(node->next); + include_bf = 0; + if (make_patch_files) { + if (node->type == Spadcommand || node->type == Spadsrc) + print_paste(pfile, com, buf, page->name, node->type); + else + print_graph_paste(pfile, com, buf, page->name, node->type); + } + } + if (!starting_file && make_patch_files) { + ret_val = fclose(pfile); + if (ret_val == -1) { + fprintf(stderr, "couldn't close file %s\n", b); + exit(-1); + } + } + ret_val = fclose(file); + if (ret_val == -1) { + fprintf(stderr, "couldn't close file %s\n", b); + exit(-1); + } + } +} + +char * +strCopy(char *s) +{ + char *b = halloc(strlen(s) + 1,"String"); + + strcat(b, s); + return b; +} + +static int +inListAndNewer(char *inputFile, char *htFile) +{ + int ret_val, found = 0, i; + struct stat htBuf, inputBuf; + + for (i = 0; i < num_active_files; i++) { + if (strcmp(active_file_list[i], inputFile) == 0) { + found = 1; + break; + } + } + if (found) + return 1; + found = 0; + for (i = 0; i < num_inactive_files; i++) + if (strcmp(inactive_file_list[i], inputFile) == 0) { + found = 1; + break; + } + if (found) + return 0; + found = 0; + for (i = 0; i < input_file_count; i++) + if (strcmp(input_file_list[i], inputFile) == 0) { + found = 1; + break; + } + if (!found) { + inactive_file_list[num_inactive_files++] = strCopy(inputFile); + return 0; + } + ret_val = stat(inputFile, &inputBuf); + if (ret_val == -1) { + active_file_list[num_active_files++] = input_file_list[i]; + printf("making %s\n", inputFile); + return 1; + } + ret_val = stat(htFile, &htBuf); + if (ret_val == -1) { + inactive_file_list[num_inactive_files++] = strCopy(inputFile); + return 0; + } + ret_val = htBuf.st_mtime > inputBuf.st_mtime; + ret_val = 1; + if (ret_val) { + active_file_list[num_active_files++] = input_file_list[i]; + printf("making %s\n", inputFile); + unlink(inputFile); + } + else + inactive_file_list[num_inactive_files++] = input_file_list[i]; + return ret_val; +} + +static void +make_input_file_list(void) +{ + int i; + char buf[256], *name; + + for (i = 0; i < input_file_count; i++) { + name = make_input_file_name(buf, input_file_list[i]); + input_file_list[i] = (char *) halloc(strlen(name) + 1,"Input Filename"); + strcpy(input_file_list[i], name); + } +} + +void +print_paste_line(FILE *pfile,char *str) +{ + char *free = "\\free", *bound = "\\bound", *f = free, *b = bound; + int justSaw = 0; + + for (; *str; str++) { + if (*f == '\0') + justSaw = 2; + if (*b == '\0') + justSaw = 2; + if (*b == *str) + b++; + else + b = bound; + if (*f == *str) + f++; + else + f = free; + if (*str == '%' || *str == '{' || *str == '}' || *str == '#') { + if (*str == '{' && justSaw) + justSaw--; + else if (*str == '}' && justSaw) + justSaw--; + else + putc('\\', pfile); + } + putc(*str, pfile); + } +} + + + +void +get_spad_output(FILE *pfile,char *command,int com_type) +{ + int n, i; + char buf[1024]; + + send_command(command, com_type); + n = get_int(spad_socket); + for (i = 0; i < n; i++) { + get_string_buf(spad_socket, buf, 1024); + fprintf(pfile, "%s\n", buf); + } + unescape_string(command); +} + +/* + * THEMOS says: There is a problem here in that we issue the (|close|) and + * then go on. If this is the last command ,we will soon send a SIGTERM and + * the whole thing will collapse maybe BEFORE the writing out has finished. + * Fix: Call a Lisp function that checks (with \axiomOp{key} ps and grep) the + * health of the viewport. We do this after the (|close|). + */ +void +get_graph_output(char *command,char *pagename,int com_type) +{ + int n, i; + char buf[1024]; + + send_command(command, com_type); + n = get_int(spad_socket); + for (i = 0; i < n; i++) { + get_string_buf(spad_socket, buf, 1024); + } + unescape_string(command); + sprintf(buf, "(|processInteractive| '(|write| |%s| \"%s%d\" \"image\") NIL)", "%", + pagename, example_number); + send_lisp_command(buf); + send_lisp_command("(|setViewportProcess|)"); + send_lisp_command("(|processInteractive| '(|close| (|%%| -3)) NIL)"); + send_lisp_command("(|waitForViewport|)"); + get_int(spad_socket); +} +static void +send_command(char *command,int com_type) +{ + char buf[1024]; + + if (com_type != Spadsrc) { + escape_string(command); + sprintf(buf, "(|parseAndEvalToHypertex| '\"%s\")", command); + send_lisp_command(buf); + } + else { + FILE *f; + char name[512], str[512]/*, *c*/; + + sprintf(name, "/tmp/hyper%s.input", getenv("SPADNUM")); + f = fopen(name, "w"); + if (f == NULL) { + fprintf(stderr, "Can't open temporary input file %s\n", name); + return; + } + fprintf(f, "%s", command); + fclose(f); + sprintf(str, "(|parseAndEvalToHypertex| '\")read %s\")", name); + send_lisp_command(str); + } +} + +static void +print_paste(FILE *pfile,char *realcom,char *command,char *pagename,int com_type) +{ + fprintf(pfile, "\\begin{patch}{%sPatch%d}\n", pagename, example_number); + fprintf(pfile, "\\begin{paste}{%sFull%d}{%sEmpty%d}\n", + pagename, example_number, pagename, example_number); + fprintf(pfile, "\\pastebutton{%sFull%d}{\\hidepaste}\n", + pagename, example_number); + fprintf(pfile, "\\tab{5}\\spadcommand{"); + print_paste_line(pfile, command); + fprintf(pfile, "}\n"); + fprintf(pfile, "\\indentrel{3}\\begin{verbatim}\n"); + get_spad_output(pfile, realcom, com_type); + fprintf(pfile, "\\end{verbatim}\n"); + fprintf(pfile, "\\indentrel{-3}\\end{paste}\\end{patch}\n\n"); + + fprintf(pfile, "\\begin{patch}{%sEmpty%d}\n", pagename, example_number); + fprintf(pfile, "\\begin{paste}{%sEmpty%d}{%sPatch%d}\n", + pagename, example_number, pagename, example_number); + fprintf(pfile, "\\pastebutton{%sEmpty%d}{\\showpaste}\n", + pagename, example_number); + fprintf(pfile, "\\tab{5}\\spadcommand{"); + print_paste_line(pfile, command); + fprintf(pfile, "}\n"); + fprintf(pfile, "\\end{paste}\\end{patch}\n\n"); + fflush(pfile); +} +static void +print_graph_paste(FILE *pfile,char *realcom,char *command,char *pagename,int com_type) +{ + fprintf(pfile, "\\begin{patch}{%sPatch%d}\n", pagename, example_number); + fprintf(pfile, "\\begin{paste}{%sFull%d}{%sEmpty%d}\n", + pagename, example_number, pagename, example_number); + fprintf(pfile, "\\pastebutton{%sFull%d}{\\hidepaste}\n", + pagename, example_number); + fprintf(pfile, "\\tab{5}\\spadgraph{"); + print_paste_line(pfile, command); + fprintf(pfile, "}\n"); + fprintf(pfile, "\\center{\\unixcommand{\\inputimage{\\env{AXIOM}/share/viewports/%s%d.VIEW/image}}{viewAlone\\space{1} \\env{AXIOM}/share/viewports/%s%d}}\n", pagename, example_number, pagename, example_number); + get_graph_output(realcom, pagename, com_type); + fprintf(pfile, "\\end{paste}\\end{patch}\n\n"); + + fprintf(pfile, "\\begin{patch}{%sEmpty%d}\n", pagename, example_number); + fprintf(pfile, "\\begin{paste}{%sEmpty%d}{%sPatch%d}\n", + pagename, example_number, pagename, example_number); + fprintf(pfile, "\\pastebutton{%sEmpty%d}{\\showpaste}\n", + pagename, example_number); + fprintf(pfile, "\\tab{5}\\spadgraph{"); + print_paste_line(pfile, command); + fprintf(pfile, "}\n"); + fprintf(pfile, "\\end{paste}\\end{patch}\n\n"); + fflush(pfile); +} diff --git a/src/hyper/htinp.pamphlet b/src/hyper/htinp.pamphlet deleted file mode 100644 index 0b2a12c9..00000000 --- a/src/hyper/htinp.pamphlet +++ /dev/null @@ -1,528 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/htinp} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{htinp.c} -<>= -#define _HTINP_C -#include "axiom-c-macros.h" -#include "useproto.h" -#include "debug.h" - -#include -#include -#include - -#include "hyper.h" -#include "mem.h" -#include "group.h" -#include "parse.h" -#include "bsdsignal.h" - -#include "all_hyper_proto.H1" -#include "sockio-c.H1" -#include "bsdsignal.H1" - -extern char **input_file_list; -extern int input_file_count; -extern int make_patch_files; -extern int kill_spad; -extern jmp_buf jmpbuf; - - -#define MaxInputFiles 256 -char *active_file_list[MaxInputFiles]; -int num_active_files = 0; -char *inactive_file_list[MaxInputFiles]; -int num_inactive_files = 0; -int include_bf = 0; -char buf_for_record_commands[256]; - - - -void -make_record(void) -{ - int i; - for (i=0;ifPageHashTable; - make_input_file_list(); - for (i = 0; i < table->size; i++) - for (entry = table->table[i]; entry != NULL; entry = entry->next) - make_the_input_file((UnloadedPage *) entry->data); - if (kill_spad){ - i = connect_spad(); - if (i != NotConnected && i != SpadBusy) - send_int(spad_socket, KillLispSystem); - } -} - -static char * -make_input_file_name(char *buf, char *filename) -{ - char *b, *c; - - strcpy(buf, filename); - for (b = buf + strlen(buf) - 1; b != buf && *b != '/'; b--); - if (b != buf) - b = b + 1; - for (c = b; *c != '.' || c[1] != 'h' || c[2] != 't'; c++); - strcpy(c, ".input"); - return b; -} - -static char * -make_paste_file_name(char *buf, char *filename) -{ - char *b, *c; - - strcpy(buf, filename); - for (b = buf + strlen(buf) - 1; b != buf && *b != '/'; b--); - if (b != buf) - b = b + 1; - for (c = b; *c != '.' || c[1] != 'h' || c[2] != 't'; c++); - strcpy(c, ".pht"); - return b; -} - -static void -make_the_input_file(UnloadedPage *page) -{ - char buf[1024], *b; - - if (!page->fpos.name) - return; - b = make_input_file_name(buf, page->fpos.name); - if (inListAndNewer(b, page->fpos.name)) { - printf("parsing: %s\n", page->name); - if (setjmp(jmpbuf)) { - printf("Syntax error!\n"); - } - else { - load_page((HyperDocPage *)page); - make_input_file_from_page(gWindow->page); - } - } -} - -int example_number; - -static void -make_input_file_from_page(HyperDocPage *page) -{ - TextNode *node; - int starting_file = 1,/* i,*/ /*len,*/ ret_val; - char *buf, buf2[1024], buf3[1024]; - char *b, *c, *com; - FILE *file = NULL; - FILE *pfile = NULL; - static HyperDocPage *op = NULL; - - if (op == page) - return; - op = page; - if (page == NULL) - return; - b = make_input_file_name(buf2, page->filename); - c = make_paste_file_name(buf3, page->filename); - if (inListAndNewer(b, page->filename)) { - /* open and prepare the input file */ - file = fopen(b, "a"); - if (file == NULL) { - fprintf(stderr, "couldn't open output file %s\n", b); - exit(-1); - } - fprintf(file, "\n-- Input for page %s\n", page->name); - fprintf(file, ")clear all\n\n"); - - for (node = page->scrolling; node != NULL; node = node->next) - if (node->type == Spadcommand || node->type == Spadgraph - || node->type == Spadsrc) { - if (starting_file) { - example_number = 1; - if (make_patch_files) { - send_lisp_command("(|clearCmdAll|)"); - send_lisp_command("(|resetWorkspaceVariables|)"); - send_lisp_command("(setq $linelength 55)"); - send_lisp_command("(|setOutputCharacters| '(default))"); - send_lisp_command("(setq |$printLoadMsgs| NIL)"); - send_lisp_command("(setq |$UserLevel| '|development|)"); - send_lisp_command("(verbos 0)"); - } - if (make_patch_files) { - pfile = fopen(c, "a"); - if (pfile == NULL) { - fprintf(stderr, "couldn't open output file %s\n", c); - exit(-1); - } - } - starting_file = 0; - } - else - example_number++; - buf = print_to_string(node->next); - com = alloc_string(buf); - fprintf(file, "%s\n", buf); - fflush(file); - fprintf(stderr, "writing:\t%s\n", buf); - include_bf = 1; - buf = print_to_string(node->next); - include_bf = 0; - if (make_patch_files) { - if (node->type == Spadcommand || node->type == Spadsrc) - print_paste(pfile, com, buf, page->name, node->type); - else - print_graph_paste(pfile, com, buf, page->name, node->type); - } - } - if (!starting_file && make_patch_files) { - ret_val = fclose(pfile); - if (ret_val == -1) { - fprintf(stderr, "couldn't close file %s\n", b); - exit(-1); - } - } - ret_val = fclose(file); - if (ret_val == -1) { - fprintf(stderr, "couldn't close file %s\n", b); - exit(-1); - } - } -} - -char * -strCopy(char *s) -{ - char *b = halloc(strlen(s) + 1,"String"); - - strcat(b, s); - return b; -} - -static int -inListAndNewer(char *inputFile, char *htFile) -{ - int ret_val, found = 0, i; - struct stat htBuf, inputBuf; - - for (i = 0; i < num_active_files; i++) { - if (strcmp(active_file_list[i], inputFile) == 0) { - found = 1; - break; - } - } - if (found) - return 1; - found = 0; - for (i = 0; i < num_inactive_files; i++) - if (strcmp(inactive_file_list[i], inputFile) == 0) { - found = 1; - break; - } - if (found) - return 0; - found = 0; - for (i = 0; i < input_file_count; i++) - if (strcmp(input_file_list[i], inputFile) == 0) { - found = 1; - break; - } - if (!found) { - inactive_file_list[num_inactive_files++] = strCopy(inputFile); - return 0; - } - ret_val = stat(inputFile, &inputBuf); - if (ret_val == -1) { - active_file_list[num_active_files++] = input_file_list[i]; - printf("making %s\n", inputFile); - return 1; - } - ret_val = stat(htFile, &htBuf); - if (ret_val == -1) { - inactive_file_list[num_inactive_files++] = strCopy(inputFile); - return 0; - } - ret_val = htBuf.st_mtime > inputBuf.st_mtime; - ret_val = 1; - if (ret_val) { - active_file_list[num_active_files++] = input_file_list[i]; - printf("making %s\n", inputFile); - unlink(inputFile); - } - else - inactive_file_list[num_inactive_files++] = input_file_list[i]; - return ret_val; -} - -static void -make_input_file_list(void) -{ - int i; - char buf[256], *name; - - for (i = 0; i < input_file_count; i++) { - name = make_input_file_name(buf, input_file_list[i]); - input_file_list[i] = (char *) halloc(strlen(name) + 1,"Input Filename"); - strcpy(input_file_list[i], name); - } -} - -void -print_paste_line(FILE *pfile,char *str) -{ - char *free = "\\free", *bound = "\\bound", *f = free, *b = bound; - int justSaw = 0; - - for (; *str; str++) { - if (*f == '\0') - justSaw = 2; - if (*b == '\0') - justSaw = 2; - if (*b == *str) - b++; - else - b = bound; - if (*f == *str) - f++; - else - f = free; - if (*str == '%' || *str == '{' || *str == '}' || *str == '#') { - if (*str == '{' && justSaw) - justSaw--; - else if (*str == '}' && justSaw) - justSaw--; - else - putc('\\', pfile); - } - putc(*str, pfile); - } -} - - - -void -get_spad_output(FILE *pfile,char *command,int com_type) -{ - int n, i; - char buf[1024]; - - send_command(command, com_type); - n = get_int(spad_socket); - for (i = 0; i < n; i++) { - get_string_buf(spad_socket, buf, 1024); - fprintf(pfile, "%s\n", buf); - } - unescape_string(command); -} - -/* - * THEMOS says: There is a problem here in that we issue the (|close|) and - * then go on. If this is the last command ,we will soon send a SIGTERM and - * the whole thing will collapse maybe BEFORE the writing out has finished. - * Fix: Call a Lisp function that checks (with \axiomOp{key} ps and grep) the - * health of the viewport. We do this after the (|close|). - */ -void -get_graph_output(char *command,char *pagename,int com_type) -{ - int n, i; - char buf[1024]; - - send_command(command, com_type); - n = get_int(spad_socket); - for (i = 0; i < n; i++) { - get_string_buf(spad_socket, buf, 1024); - } - unescape_string(command); - sprintf(buf, "(|processInteractive| '(|write| |%s| \"%s%d\" \"image\") NIL)", "%", - pagename, example_number); - send_lisp_command(buf); - send_lisp_command("(|setViewportProcess|)"); - send_lisp_command("(|processInteractive| '(|close| (|%%| -3)) NIL)"); - send_lisp_command("(|waitForViewport|)"); - get_int(spad_socket); -} -static void -send_command(char *command,int com_type) -{ - char buf[1024]; - - if (com_type != Spadsrc) { - escape_string(command); - sprintf(buf, "(|parseAndEvalToHypertex| '\"%s\")", command); - send_lisp_command(buf); - } - else { - FILE *f; - char name[512], str[512]/*, *c*/; - - sprintf(name, "/tmp/hyper%s.input", getenv("SPADNUM")); - f = fopen(name, "w"); - if (f == NULL) { - fprintf(stderr, "Can't open temporary input file %s\n", name); - return; - } - fprintf(f, "%s", command); - fclose(f); - sprintf(str, "(|parseAndEvalToHypertex| '\")read %s\")", name); - send_lisp_command(str); - } -} - -static void -print_paste(FILE *pfile,char *realcom,char *command,char *pagename,int com_type) -{ - fprintf(pfile, "\\begin{patch}{%sPatch%d}\n", pagename, example_number); - fprintf(pfile, "\\begin{paste}{%sFull%d}{%sEmpty%d}\n", - pagename, example_number, pagename, example_number); - fprintf(pfile, "\\pastebutton{%sFull%d}{\\hidepaste}\n", - pagename, example_number); - fprintf(pfile, "\\tab{5}\\spadcommand{"); - print_paste_line(pfile, command); - fprintf(pfile, "}\n"); - fprintf(pfile, "\\indentrel{3}\\begin{verbatim}\n"); - get_spad_output(pfile, realcom, com_type); - fprintf(pfile, "\\end{verbatim}\n"); - fprintf(pfile, "\\indentrel{-3}\\end{paste}\\end{patch}\n\n"); - - fprintf(pfile, "\\begin{patch}{%sEmpty%d}\n", pagename, example_number); - fprintf(pfile, "\\begin{paste}{%sEmpty%d}{%sPatch%d}\n", - pagename, example_number, pagename, example_number); - fprintf(pfile, "\\pastebutton{%sEmpty%d}{\\showpaste}\n", - pagename, example_number); - fprintf(pfile, "\\tab{5}\\spadcommand{"); - print_paste_line(pfile, command); - fprintf(pfile, "}\n"); - fprintf(pfile, "\\end{paste}\\end{patch}\n\n"); - fflush(pfile); -} -static void -print_graph_paste(FILE *pfile,char *realcom,char *command,char *pagename,int com_type) -{ - fprintf(pfile, "\\begin{patch}{%sPatch%d}\n", pagename, example_number); - fprintf(pfile, "\\begin{paste}{%sFull%d}{%sEmpty%d}\n", - pagename, example_number, pagename, example_number); - fprintf(pfile, "\\pastebutton{%sFull%d}{\\hidepaste}\n", - pagename, example_number); - fprintf(pfile, "\\tab{5}\\spadgraph{"); - print_paste_line(pfile, command); - fprintf(pfile, "}\n"); - fprintf(pfile, "\\center{\\unixcommand{\\inputimage{\\env{AXIOM}/share/viewports/%s%d.VIEW/image}}{viewAlone\\space{1} \\env{AXIOM}/share/viewports/%s%d}}\n", pagename, example_number, pagename, example_number); - get_graph_output(realcom, pagename, com_type); - fprintf(pfile, "\\end{paste}\\end{patch}\n\n"); - - fprintf(pfile, "\\begin{patch}{%sEmpty%d}\n", pagename, example_number); - fprintf(pfile, "\\begin{paste}{%sEmpty%d}{%sPatch%d}\n", - pagename, example_number, pagename, example_number); - fprintf(pfile, "\\pastebutton{%sEmpty%d}{\\showpaste}\n", - pagename, example_number); - fprintf(pfile, "\\tab{5}\\spadgraph{"); - print_paste_line(pfile, command); - fprintf(pfile, "}\n"); - fprintf(pfile, "\\end{paste}\\end{patch}\n\n"); - fflush(pfile); -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/htsearch b/src/hyper/htsearch new file mode 100755 index 00000000..84e272c7 --- /dev/null +++ b/src/hyper/htsearch @@ -0,0 +1,12 @@ +#!/bin/sh + +htbindir=$AXIOM/lib +htpagedir=$AXIOM/share/hypertex/pages + + +if test -z "$1" +then + echo ""|$htbindir/presea case=1 - +else +( cd $htpagedir; $htbindir/hthits "$1" $htpagedir/ht.db |sort -r -n +0.22 |$htbindir/presea case=0 expr="$1" -) +fi diff --git a/src/hyper/hyper.c b/src/hyper/hyper.c new file mode 100644 index 00000000..627c3ca3 --- /dev/null +++ b/src/hyper/hyper.c @@ -0,0 +1,487 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +/* + * This is the main module of the HyperDoc program. It contains the main + * routine which initializes all the X stuff, and the tables. Then it passes + * control over to the main event loop. + */ + +/* #define DEBUG 1 */ + +/* Include all the needed include files */ +#define _HYPER_C +#include "useproto.h" +#include "debug.h" + + +#include "hyper.h" + +#include +#include +#include +#include +#include + +#include "keyin.h" +#include "initx.h" +#include "event.h" +#include "hyper.h" +#include "bsdsignal.h" + +#include "all_hyper_proto.H1" +#include "sockio-c.H1" +#include "bsdsignal.H1" +/* + * Here is a flag used to tell me whether I made a good connection to the + * menu server. Needed so I don't send spad commands when I should not + */ + +int MenuServerOpened = 1; + +/* include icon bitmap data */ + +#define BITMAPDEPTH 1 + +/* X11 display and screen variables */ + +Display *gXDisplay; +int gXScreenNumber; + +/* + * Information about the top level HyperDoc window + */ + +HDWindow *gWindow = NULL; /* the current window */ +HDWindow *gParentWindow =NULL; /* the parent window. The one that appears + * when you first start HyperDoc */ + +HashTable gSessionHashTable; /* hash table of HD windows */ +HashTable init_page_hash; /* initial hash table of HD pages */ +HashTable init_macro_hash; /* initial hash table of HD macros */ +HashTable init_patch_hash; /* initial hash table of HD patches */ + +/* The various Cursors we use */ + +Cursor gNormalCursor; /* The normal mouse cursor */ +Cursor gActiveCursor; /* The cursor in active regions */ +Cursor gBusyCursor; /* The clock cursor for when I am busy */ + + +HashTable gFileHashTable; /* hash table of HyperDoc files */ +HashTable gImageHashTable; /* hash table for images */ + + +/* Some things needed for Handling interupts properly */ + +int gIsEndOfOutput; /* set to true when spad has finished output */ +int received_window_request = 0;/* true iff Spad wants a pop-up */ +int in_next_event = 0; /* true when in XNextEvent */ +int make_input_file = 0; /* true when making input files from ht */ +int make_patch_files = 0; /* true when making patch files from ht */ +int gmake_record_file= 0; /* true when making record files from ht */ +int gverify_record_file = 0; /* true when verifying record files from ht */ +int gverify_dates = 0; /* true when we want hypertex to verify ht.db dates */ + +Sock *session_server; /* socket connecting to session manager */ + +int gIsAxiomServer = 0; /* true iff HyperDoc is acting as a */ + /* an Axiom server */ + +int kill_spad = 0; /* kill spad when finished with paste file */ + +int gSwitch_to_mono=0; /* will be set to 1 if at any time we don't have + enough colours for the images. We will know this + when read_pixmap_file returns -1. We will use this + when deciding what to do in case of \inputimage */ + +int gTtFontIs850=0; /* a flag that tells us if the Tt font is a IBM pagecode 850 + font and hence supports the graphics chars + set when the TtFont is opened*/ + +/* + * Global copies of the command line arguments, so they never have to be + * passed as parameters. This is also so any child process starting up also + * has the same values. + */ + +int gArgc; +char **gArgv; + +char **input_file_list; +int input_file_count; + +/* + * SIGUSR2 is raised by the spadbuf program when it is done with the current + * command + */ + +void +sigusr2_handler(int sig) +{ + gIsEndOfOutput = 1; + return ; +} + +void +sigcld_handler(int sig) +{ + + /* why were we waiting after the child had already died ?? + because we don't want zombies */ + + int x; + wait(&x); + +} + +extern jmp_buf env; + + +/* Clean up spad sockets on exit */ +void +clean_socket(void ) +{ + char name[256]; + + make_server_name(name, MenuServerName); + unlink(name); +} + +/* + * initialize hash tables, signal handlers and windows, then call the main + * event handling loop + */ + +int +main(int argc, char **argv) +{ + int ret_status; + + /* Initialize some global values */ +/* fprintf(stderr,"hyper:main:entered\n");*/ + gArgc = argc; + gArgv = argv; + gIsEndOfOutput = 1; + +/* fprintf(stderr,"hyper:main:calling check_arguments\n");*/ + check_arguments(); +/* fprintf(stderr,"hyper:main:returned check_arguments\n");*/ + + /* + * initialize the hash tables for the files and the windows and images + */ +/* fprintf(stderr,"hyper:main:calling init_hash\n");*/ + init_hash(); +/* fprintf(stderr,"hyper:main:returned init_hash\n");*/ + + /* + * initialize the parser keyword hash table + */ +/* fprintf(stderr,"hyper:main:calling parser_init\n");*/ + parser_init(); +/* fprintf(stderr,"hyper:main:returned parser_init\n");*/ + +/* fprintf(stderr,"hyper:main:calling read_ht_db\n");*/ + read_ht_db(&init_page_hash, &init_macro_hash, &init_patch_hash); +/* fprintf(stderr,"hyper:main:returned read_ht_db\n");*/ + + /* + * Now initialize x. This includes opening the display, setting the + * screen and display global values, and also gets all the fonts and + * colors we will need. + */ + + if (!make_input_file && !gmake_record_file && !gverify_record_file) { +/* fprintf(stderr,"hyper:main:calling initializeWindowSystem\n");*/ + initializeWindowSystem(); +/* fprintf(stderr,"hyper:main:returned initializeWindowSystem\n");*/ + + /* + * Initialize some of the global values used by the input string + * routines + */ +/* fprintf(stderr,"hyper:main:calling init_keyin\n");*/ + init_keyin(); +/* fprintf(stderr,"hyper:main:returned init_keyin\n");*/ + + /* + * regardless of what else happened, we should always pop up an + * initial window. + */ + +/* fprintf(stderr,"hyper:main:calling init_top_window\n");*/ + ret_status = init_top_window("RootPage"); +/* fprintf(stderr,"hyper:main:returned init_top_window\n");*/ + gParentWindow = gWindow; + if (ret_status == -1) { + fprintf(stderr, + "(HyperDoc) Could not find RootPage for top-level window.\n"); + exit(-1); + } + + /* + * Tell it how to handle the user defined signals I may get + */ + bsdSignal(SIGUSR2, sigusr2_handler,RestartSystemCalls); + bsdSignal(SIGUSR1, SIG_IGN,RestartSystemCalls); +#if defined(BSDplatform) || defined(MACOSXplatform) + bsdSignal(SIGCHLD, sigcld_handler,RestartSystemCalls); +#else + bsdSignal(SIGCLD, sigcld_handler,RestartSystemCalls); +#endif + bsdSignal(SIGINT, SIG_IGN,RestartSystemCalls); + + /* + * Now go to the main event loop. I will never return, so just end + * the main routine after that + */ + + /* + * make an input file if requested + */ + } + else { + + /* + * Try to establish all the socket connections I need. If I am an + * gIsAxiomServer and the routine fails, it will exit for me + */ +/* fprintf(stderr,"hyper:main:in else case\n");*/ +/* fprintf(stderr,"hyper:main:calling make_server_connections\n");*/ + make_server_connections(); +/* fprintf(stderr,"hyper:main:returned make_server_connections\n");*/ + + + if (make_input_file) ht2_input(); + if (gmake_record_file) make_record(); + if (gverify_record_file) verify_record(); + exit(0); + } + + /* + * Try to establish all the socket connections I need. If I am an + * gIsAxiomServer and the routine fails, it will exit for me + */ +/* fprintf(stderr,"hyper:main:calling make_server_connections\n");*/ + make_server_connections(); +/* fprintf(stderr,"hyper:main:returned make_server_connections\n");*/ + + +/* fprintf(stderr,"hyper:main:calling mainEventLoop\n");*/ + mainEventLoop(); +/* fprintf(stderr,"hyper:main:returned mainEventLoop\n");*/ + + return 0; +} + +/* + * Initializes the hash table for Files, and Windows + */ + +static void +init_hash(void) +{ + hash_init(&gFileHashTable, + FileHashSize, + (EqualFunction)string_equal, + (HashcodeFunction) string_hash); + hash_init(&gSessionHashTable, + SessionHashSize, + (EqualFunction) window_equal, + (HashcodeFunction) window_code); + hash_init(&gImageHashTable, + ImageHashSize, + (EqualFunction) string_equal, + (HashcodeFunction) string_hash); +} + +/* initialize the HyperDoc page hierarchy data structures */ + +void +init_page_structs(HDWindow *w) +{ + int i; + + w->fMemoStackIndex = 0; + for (i = 0; i < MaxMemoDepth; i++) { + w->fMemoStack[i] = NULL; + w->fDownLinkStackTop[i] = 0; + } + w->fDownLinkStackIndex = 0; + for (i = 0; i < MaxDownlinkDepth; i++) + w->fDownLinkStack[i] = NULL; +} + +static void +check_arguments(void) +{ + int i; + + /* + * Now check the command line arguments, to see if I am supposed to be a + * server or not + */ + for (i = 1; i < gArgc; i++) { + if (gArgv[i][0] == '-') + switch (gArgv[i][1]) { + case 'p': + gverify_dates=1; + break; + case 's': + if (!MenuServerOpened) { + fprintf(stderr, "(HyperDoc) Server already in use.\n"); + exit(-1); + } + gIsAxiomServer = 1; + break; + case 'i': + if (gArgv[i][2] == 'p') + make_patch_files = 1; + make_input_file = 1; + input_file_list = gArgv + i + 1; + input_file_count = gArgc - i - 1; + break; + case 'k': + kill_spad = 1; + break; + case 'r': + if (gArgv[i][2] == 'm') + gmake_record_file=1; + else if (gArgv[i][2] == 'v') + gverify_record_file=1; + else + fprintf(stderr, "(HyperDoc) v or m must follow -r\n"); + input_file_list = gArgv + i + 1; + input_file_count = gArgc - i - 1; + break; + default: + fprintf(stderr, "(HyperDoc) Unexpected Command Line Argument %s\n", gArgv[i]); + fprintf(stderr, " Usage: hypertex [-s]\n"); + break; + } + } +} + +static void +make_server_connections(void) +{ + int i, wait_time; + + /* + * Try to open the menuserver socket, if I can not, then set a flag + */ + + if (open_server(MenuServerName) == -2) { + fprintf(stderr, "(HyperDoc) Warning: Not connected to AXIOM Server!\n"); + MenuServerOpened = 0; + } else { + atexit(&clean_socket); + MenuServerOpened = 1; + } + + + /* + * If I have opened the MenuServer socket, then I should also try to open + * the SpadServer socket, so I can send stuff right to SPAD. + */ + + if (MenuServerOpened) { + + /* + * If I am a ht server, then I should not continue on unless I + * establish some sort of connection + */ + + /* + * Modified on 11/20 so that it prints an error message every ten for + * ten tries at opeing the socket. If it fails all ten times, it + * gives up and exits. + */ + + if (!gIsAxiomServer) + wait_time = 2; + else + wait_time = 1000; + + for (i = 0, spad_socket = NULL; i < 2 && spad_socket == NULL; i++) { + spad_socket = connect_to_local_server(SpadServer, + MenuServer, wait_time); + if (gIsAxiomServer && spad_socket == NULL) + fprintf(stderr, "(HyperDoc) Error opening AXIOM server. Retrying ...\n"); + else + i = 11; + } + if (! spad_socket) { + fprintf(stderr, "(HyperDoc) Couldn't connect to AXIOM server!\n"); + if (!gIsAxiomServer) + MenuServerOpened = 0; + else { + fprintf(stderr, "(HyperDoc) Couldn't connect to AXIOM server!\n"); + exit(-1); + } + } + else { + + /* + * Do the same thing for the SessionServer + */ + + for (i = 0, session_server = NULL; i < 2 && session_server == NULL + ; i++) { + session_server = + connect_to_local_server(SessionServer, MenuServer, + wait_time); + if (gIsAxiomServer && session_server == NULL) { + fprintf(stderr, + "(HyperDoc) Error opening SessionServer, Retrying ...\n"); + } + else + i = 11; + } + if (session_server == NULL) { + fprintf(stderr, "(HyperDoc) Connection attempt to session manager timed out.\n"); + if (gIsAxiomServer) { + fprintf(stderr, + "(HyperDoc) Server unable to connect to session server\n"); + exit(-1); + } + else { + MenuServerOpened = 0; + } + } + } + } +} diff --git a/src/hyper/hyper.h b/src/hyper/hyper.h new file mode 100644 index 00000000..1a9a53e1 --- /dev/null +++ b/src/hyper/hyper.h @@ -0,0 +1,575 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +#ifndef _HYPER_H_ +#define _HYPER_H_ 1 + +#include "axiom-c-macros.h" +#include +#include +#include +#include + +#include +#include +#include + +#include "com.h" +#include "token.h" +#include "hash.h" + +#define boolean unsigned short int + +#ifndef TRUE +#define TRUE ((boolean) 0x1) +#endif +#ifndef FALSE +#define FALSE ((boolean) 0x0) +#endif + +/* Struct forward declarations */ + +struct text_node; +struct input_box; +struct input_window; +struct paste_node; +struct radio_boxes; +struct group_item; + +#define Scrollupbutton 1 +#define Scrolldownbutton 2 +#define Noopbutton 6 + +#define Scrolling 1 +#define Header 2 +#define Footer 3 +#define Title 4 + +#ifndef HTADD +extern int MenuServerOpened; + +/* These are all the colors one can use in HyperDoc. */ + +extern int gActiveColor, + gAxiomColor, + gBackgroundColor, + gBfColor, + gControlBackgroundColor, + gControlForegroundColor, + gEmColor, + gInputBackgroundColor, + gInputForegroundColor, + gItColor, + gRmColor, + gSlColor, + gTtColor; + +/* These are all the different fonts one can use in HyperDoc. */ + +extern XFontStruct *gActiveFont, + *gAxiomFont, + *gBfFont, + *gEmFont, + *gInputFont, + *gItFont, + *gRmFont, + *gSlFont, + *gTitleFont, + *gTtFont; + + +#endif + + +/** I am implementing a state node stack, this is the structure I store **/ + +typedef struct state_node { + int last_ch, last_token, input_type; + long fpos, keyword_fpos; + long page_start_fpos; + Token token; + char *input_string; + FILE *cfile; + int keyword; + struct state_node *next; +} StateNode; + +#ifndef HTADD +/** pointer to the top of the state node graph **/ +extern StateNode *top_state_node; +#endif + + +/* structure for a hyper text link */ +typedef struct hyper_link { + int type; /* Memolink, Spadlink, Downlink etc. */ + Window win; /* X11 window containing active area */ + union { + struct text_node *node; /* ID of link to which link refers */ + struct input_box *box; + struct input_window *string; + struct paste_node *paste; /* the paste node area */ + } reference; + int x,y; /* relative position inside page */ +} HyperLink; + + +typedef struct if_node { + struct text_node *cond; /* the condition nodes*/ + struct text_node *thennode; + struct text_node *elsenode; +} IfNode; + +typedef struct item_stack { + int indent; + int item_indent; + int in_item; + struct item_stack *next; +} ItemStack; + +typedef struct paste_node { + char *name; + int where; /* where should I be parsing from? */ + short int hasbutton; + short int haspaste; + struct group_item *group; + ItemStack *item_stack; + struct text_node *arg_node; + struct text_node *end_node; + struct text_node *begin_node; + struct input_window *paste_item; +} PasteNode; + +/* Structure for formatted hypertext */ + +typedef struct text_node { + short type; /* type of node (text, link, etc.) */ + int x,y, width, height; /* relative location on screen */ + int space; /* was there space in front of me ? */ + union { + char *text; /* piece of text to display */ + struct text_node *node; /* argument text */ + struct if_node *ifnode; + } data; + HyperLink *link; /* link for active text */ + union { + Pixmap pm; /* pixmap for bit images */ + XImage *xi; /* pixmap image */ + } image; + struct text_node *next; /* next node in formatted text */ +} TextNode; + +/** Structure used to store pixmaps and bitmaps **/ + +typedef struct image_struct { + int width,height; /** It's width and height **/ + union { + Pixmap pm; + XImage *xi; + } image; + char *filename; /** The filename used to reference it **/ +} ImageStruct; + +/* Structure for locating HyperDoc pages in a source file */ + +typedef struct { + char *name; /* file name */ + long pos; /* position in file */ + int ln; /* the line number */ +} FilePosition; + +/*** The structure needed for storing a macro **/ + +typedef struct macro_store { + short int loaded; + FilePosition fpos; + char *name; + char *macro_string; + short number_parameters; +} MacroStore; + + +/** Structure needed for storing a patch **/ +typedef struct patch_store { + short int loaded; + FilePosition fpos; + char *name; + char *string; +} PatchStore; + +/* Here are the structures needed for doing input to HyperDoc windows. */ + +typedef struct line_struct { + char *buffer; + int changed; /* Has the line changed */ + int line_number; + int buff_pntr; + int len; + struct line_struct *prev, *next; +} LineStruct; + +typedef struct input_window { + char *name; /* symbol name **/ + int size; /* the length of the window **/ + int cursor_x; /* x-coordinate for the cursor **/ + int entered; /* tells me whether I have typed here + before */ + int num_lines; /* number of lines needed to store + buffer */ + LineStruct *lines; + LineStruct *curr_line; /* the current line on which the cursor */ + Window win; + struct input_window *next; +} InputItem; + + +/* structure for storing input boxes **/ +typedef struct input_box { + char *name; + ImageStruct *selected, *unselected; + short int picked; + struct input_box *next; + struct radio_boxes *rbs; + Window win; +} InputBox; + +typedef struct radio_boxes { + char *name; + InputBox *boxes; + ImageStruct *selected, *unselected; + int width, height; + struct radio_boxes *next; +} RadioBoxes; + +/* Structure for spadcommand dependencies hash table entries */ +typedef struct spadcom_depend { + char *label; /* dependency label */ + TextNode *spadcom; /* spadcommand defining the label */ + short executed; /* true iff spadcommand has benn executed */ +} SpadcomDepend; + +typedef struct button_list { + int x0,y0,x1,y1; + HyperLink *link; + Window win; + struct button_list *next; +} ButtonList; + +/* Stucture for unformatted hyper text page */ + +typedef struct hyperdoc_page { + short type; /* Normal, Quitbutton, Upbutton etc. */ + char *name; /* ID of page */ + char *filename; /* The name of the file in which the page + occurs, Null if not */ + int scroll_off; /* The offset in the scrolling region */ + int bot_scroll_margin; /* bottom of the scrolling region */ + int top_scroll_margin; /* top of the scrolling region */ + TextNode *title; /* the title of the page */ + TextNode *header; /* formatted version of page */ + TextNode *scrolling; /* Top of scrolling region */ + TextNode *footer; /* top of non-scrolling region at bottom */ + Sock *sock; /* socket connection for spad buffer */ + HashTable *fLinkHashTable; /* active link hash table */ + ButtonList *s_button_list; /* active buttons on page */ + ButtonList *button_list; /* active buttons on page */ + HashTable *depend_hash; /* Hash tables of spadcommand dependencies */ + InputItem *input_list; /* List of input structures */ + InputItem *current_item; /* a pntr to the currently active item */ + HashTable *box_hash; /* place where all the boxes are stored */ + RadioBoxes *radio_boxes; /* a linked list of radio boxes */ + short page_flags; /* A list of flags for the page */ + char *helppage; /* the name of the helppage */ +} HyperDocPage; + +/* Structure for an unloaded page */ + +typedef struct unloaded_page { + short type; /* indicator of unloaded page */ + char *name; /* name of page */ + FilePosition fpos; /* where to find the page */ +} UnloadedPage; + +/* Structure for a HyperDoc Window */ + +typedef struct { + Window fMainWindow; /* The main text field window. */ + Window fScrollWindow; /* The scrolling area of the window */ + Window fDisplayedWindow; /* The current window of the above two, */ + /* being filled by display */ + + Window fScrollUpWindow; /* Window for scrolling up a line */ + Window fScrollDownWindow; /* Window for scrolling down a line */ + + Window scrollbar; /* the window for scrolling */ + Window scroller; /* the scroller window */ + + Window fTitleBarButton1; /* 1st titlebar bitmap button */ + Window fTitleBarButton2; /* 2nd titlebar bitmap button */ + Window fTitleBarButton3; /* 3rd titlebar bitmap button */ + Window fTitleBarButton4; /* 4th titlebar bitmap button */ + + int fScrollerTopPos; /* where the top of the scroller is */ + int fScrollerHeight; /* the height of the scroller */ + int fScrollBarHeight; /* the height for the scrollbar */ + + int scrollwidth; /* the width of the scrolling area */ + int scrollheight; /* the height of the scrolling area */ + int scrollupy; /* Current y position of the scroll up */ + /* button */ + int scrolldowny; /* Current y position of the scroll */ + /* downbutton */ + int scrollbary; /* Current y position of teh scrollbar */ + int scrollx; /* X coordinates for all of the above */ + int border_width; /* Width of the border */ + HyperDocPage *page; /* currently displayed page */ + int width, height; /* in pixels */ + int columns; /* Width in characters, only setable */ + /* for form pages */ + HyperDocPage **fMemoStack; /* stack of memo links */ + HyperDocPage **fDownLinkStack;/* stack of down links */ + + int *fDownLinkStackTop; /* stack of down links */ + int fMemoStackIndex; /* memo stack pointer */ + int fDownLinkStackIndex; /* downlink stack pointer */ + + HashTable *fWindowHashTable; /* hash table of active subwindows */ + HashTable *fPageHashTable; /* hash table of HyperDoc pages */ + HashTable *fPasteHashTable; /* hash table for paste in areas */ + HashTable *fMacroHashTable; /* hash table of HyperDoc macros */ + HashTable *fCondHashTable; /* hash table for values */ + HashTable *fPatchHashTable; /* hash table for patch locations */ + + int fAxiomFrame; /* Axiom frame number initializing window */ + GC fStandardGC; /* Graphics context for window */ + GC fInputGC; /* Graphics context for the input windows */ + GC fCursorGC; /* Graphics context for the cursors */ + GC fControlGC; /* Graphics context for the buttons */ + Cursor fDisplayedCursor; /* The currently displayed cursor */ +} HDWindow; + +/* Structure for identifying appropriate link hash tables */ + +typedef struct { + int code; /* code of active area */ + HyperDocPage *page; /* page for which hash table applies */ +} LinkHashID; + +/*** Flags for the page ***/ + +#define NOLINES 0000001 /* Ibid, for the bottom of the page ***/ + + +/* external variables and functions. See the source file for a description + of their purposes */ + +extern HashTable gSessionHashTable; /* hash table of HD windows */ + +extern HDWindow *gParentWindow; /* the parent window. The one that + * appears when you first start HD */ + +extern HyperLink *quitLink; /** a special link to the protected quit page **/ + + +#ifndef HTADD +/* From hyper.c */ +extern int gXScreenNumber; +extern Display *gXDisplay; +extern int gSwitch_to_mono; +extern unsigned long * spadColors; +extern int gIsEndOfOutput; +extern HDWindow *gWindow; +extern Sock *session_server; +extern Sock *spad_socket; +extern HashTable gFileHashTable; +extern HashTable gImageHashTable; /* A global hash table for images */ +extern Cursor gNormalCursor; /* The normal mouse cursor */ +extern Cursor gActiveCursor; /* The cursor in active regions */ +extern Cursor gBusyCursor; /* The clock cursor for when I am busy */ +extern int gIsAxiomServer; /* true iff HyperDoc is acting as an Axiom server */ +extern int gArgc; /* original argc from main */ +extern char **gArgv; /* original argv from main */ +/* from lex.c */ +extern long fpos, keyword_fpos; +extern Token token; +extern int last_token, input_type, last_ch; +extern char *input_string; +extern FILE *cfile; +/* from input.c */ +extern XImage *picked; +extern int picked_height; +extern int picked_width; +extern XImage *unpicked; +extern int unpicked_height; +extern int unpicked_width; +/* from display.c */ +extern int line_height; +extern int need_scroll_up_button; +extern int scrolling; +extern int need_scroll_down_button; +extern int space_width; +#endif + +/* Here are some of the functions and constants declared and needed in + htadd.c ******/ + +#define NoChar -9999 +#define temp_dir "/tmp/" +#define db_file_name "ht.db" +#define def_spad "/usr/local/axiom" + + +/* Types of HyperDoc pages */ + +#define UlUnknownPage 9993 /*I hate this hack, but I have to know whether*/ +#define UnknownPage 9994 /*this page has been loaded or not. */ +#define ErrorPage 9995 +#define Unixfd 9996 +#define SpadGen 9997 +#define Normal 9998 +#define UnloadedPageType 9999 + +/* Commands from Axiom */ + +#define EndOfPage 99 +#define SendLine 98 +#define StartPage 97 /* A normal HyperDoc page */ +#define LinkToPage 96 +#define PopUpPage 95 /* A pop-up page */ +#define PopUpNamedPage 94 +#define KillPage 93 +#define ReplacePage 92 +#define ReplaceNamedPage 91 +#define SpadError 90 + +/* Constants declaring size of page stacks */ + +#define MaxMemoDepth 25 /* max nesting level for memolinks */ +#define MaxDownlinkDepth 50 /* max downlink nesting depth */ + +/* Constants defining the size of various hash tables */ + +#define PageHashSize 1000 +#define FileHashSize 30 +#define SessionHashSize 10 +#define MacroHashSize 100 +#define ImageHashSize 100 +#define CondHashSize 100 +#define BoxHashSize 20 +#define PasteHashSize 100 +#define PatchHashSize 100 + +/* A couple of macros for memo and down links */ + +#define need_up_button \ + (gWindow->fMemoStackIndex ? gWindow->fDownLinkStackIndex >= \ + gWindow->fDownLinkStackTop[gWindow->fMemoStackIndex-1] \ + : gWindow->fDownLinkStackIndex) + +#define need_return_button (gWindow->fMemoStackIndex) + +#define need_help_button (gWindow->page->helppage != NULL) + +#define max(x,y) ((x) > (y) ? (x) : (y)) + + +#define pick_box(box) fill_box(box->win, box->selected) +#define unpick_box(box) fill_box(box->win, box->unselected) + +#define TopLevelHelpPage "ugHyperPage" +#define NoMoreHelpPage "NoMoreHelpPage" +#define KeyDefsHelpPage "ugHyperKeysPage" +#define InputAreaHelpPage "ugHyperInputPage" + +/* definitions for connecting to the Axiom server */ + +#define Connected 0 +#define NotConnected 1 +#define SpadBusy 2 + +/* some GUI-dependent stuff */ + +#define BeepAtTheUser() /* (XBell(gXDisplay, 5)) */ +#define LoudBeepAtTheUser() /* (XBell(gXDisplay, 50)) */ + + +/*** default fonts ***/ + +#if defined(RTplatform) || defined(PS2platform) || defined(RIOSplatform) || defined(AIX370platform) +#define RmFontDefault "Rom14" +#define TtFontDefault "Erg14" +#define ActiveFontDefault "Bld14" +#define AxiomFontDefault "Erg14" +#define EmphasizeFontDefault "Itl14" +#define BoldFontDefault "Bld14" +#endif + +#if defined(SUNplatform) || defined (SUN4OS5platform) || defined(SGIplatform) || defined (HP9platform) || defined(HP10platform) || defined (ALPHAplatform) || defined(LINUXplatform) || defined(MACOSXplatform) || defined(BSDplatform) +#define RmFontDefault "-adobe-courier-medium-r-normal--18-*-*-*-m-*-iso8859-1" +#define TtFontDefault "-adobe-courier-medium-r-normal--18-*-*-*-m-*-iso8859-1" +#define ActiveFontDefault "-adobe-courier-bold-r-normal--18-*-*-*-m-*-iso8859-1" +#define AxiomFontDefault "-adobe-courier-bold-o-normal--18-*-*-*-m-*-iso8859-1" +#define EmphasizeFontDefault "-adobe-courier-medium-o-normal--18-*-*-*-m-*-iso8859-1" +#define BoldFontDefault "-adobe-courier-bold-r-normal--18-*-*-*-m-*-iso8859-1" +#endif + + + + + + +typedef struct group_item { + int cur_color; + XFontStruct *cur_font; + int center; + struct group_item *next; +} GroupItem; + + +extern GroupItem *gTopOfGroupStack; + + +typedef struct cond_node { + char *label; + char *cond; +} CondNode; + +typedef struct parameter_list_type { + char **list; /** The parameters in string form **/ + short number; /** How many parameters are there **/ + struct parameter_list_type *next; +} *ParameterList; + +#endif diff --git a/src/hyper/hyper.pamphlet b/src/hyper/hyper.pamphlet deleted file mode 100644 index 8f514af8..00000000 --- a/src/hyper/hyper.pamphlet +++ /dev/null @@ -1,1079 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/hyper} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{hyper.h} -The [[hypertex]] function, of which this is the top level, is a browser -for Axiom information. It works off a database of pages. The pages are -stored in the [[$AXIOM/share/hypertex/pages]] subdirectory and there is -a key file called [[ht.db]] in that subdirectory which contains -critical information about each page. If you add or delete pages you -must rerun the [[htadd]] command. -(See the [[htadd]] command in [[src/hyper/htadd.pamphlet]].) - -Generally, if you add or delete pages you can recreate a proper -[[pages/ht.db]] file by doing: -\begin{verbatim} -cd $AXIOM/share/hypertex -htadd -f pages -n pages/* -\end{verbatim} - - -The [[hypertex]] function looks in [[$AXIOM/share/hypertex/pages]] by -default. This can be over-ridden by setting the [[HTPATH]] shell -variable to point to the desired directory containing the pages and -the ht.db file. -<>= -<> -#ifndef _HYPER_H_ -#define _HYPER_H_ 1 - -#include "axiom-c-macros.h" -#include -#include -#include -#include - -#include -#include -#include - -#include "com.h" -#include "token.h" -#include "hash.h" - -#define boolean unsigned short int - -#ifndef TRUE -#define TRUE ((boolean) 0x1) -#endif -#ifndef FALSE -#define FALSE ((boolean) 0x0) -#endif - -/* Struct forward declarations */ - -struct text_node; -struct input_box; -struct input_window; -struct paste_node; -struct radio_boxes; -struct group_item; - -#define Scrollupbutton 1 -#define Scrolldownbutton 2 -#define Noopbutton 6 - -#define Scrolling 1 -#define Header 2 -#define Footer 3 -#define Title 4 - -#ifndef HTADD -extern int MenuServerOpened; - -/* These are all the colors one can use in HyperDoc. */ - -extern int gActiveColor, - gAxiomColor, - gBackgroundColor, - gBfColor, - gControlBackgroundColor, - gControlForegroundColor, - gEmColor, - gInputBackgroundColor, - gInputForegroundColor, - gItColor, - gRmColor, - gSlColor, - gTtColor; - -/* These are all the different fonts one can use in HyperDoc. */ - -extern XFontStruct *gActiveFont, - *gAxiomFont, - *gBfFont, - *gEmFont, - *gInputFont, - *gItFont, - *gRmFont, - *gSlFont, - *gTitleFont, - *gTtFont; - - -#endif - - -/** I am implementing a state node stack, this is the structure I store **/ - -typedef struct state_node { - int last_ch, last_token, input_type; - long fpos, keyword_fpos; - long page_start_fpos; - Token token; - char *input_string; - FILE *cfile; - int keyword; - struct state_node *next; -} StateNode; - -#ifndef HTADD -/** pointer to the top of the state node graph **/ -extern StateNode *top_state_node; -#endif - - -/* structure for a hyper text link */ -typedef struct hyper_link { - int type; /* Memolink, Spadlink, Downlink etc. */ - Window win; /* X11 window containing active area */ - union { - struct text_node *node; /* ID of link to which link refers */ - struct input_box *box; - struct input_window *string; - struct paste_node *paste; /* the paste node area */ - } reference; - int x,y; /* relative position inside page */ -} HyperLink; - - -typedef struct if_node { - struct text_node *cond; /* the condition nodes*/ - struct text_node *thennode; - struct text_node *elsenode; -} IfNode; - -typedef struct item_stack { - int indent; - int item_indent; - int in_item; - struct item_stack *next; -} ItemStack; - -typedef struct paste_node { - char *name; - int where; /* where should I be parsing from? */ - short int hasbutton; - short int haspaste; - struct group_item *group; - ItemStack *item_stack; - struct text_node *arg_node; - struct text_node *end_node; - struct text_node *begin_node; - struct input_window *paste_item; -} PasteNode; - -/* Structure for formatted hypertext */ - -typedef struct text_node { - short type; /* type of node (text, link, etc.) */ - int x,y, width, height; /* relative location on screen */ - int space; /* was there space in front of me ? */ - union { - char *text; /* piece of text to display */ - struct text_node *node; /* argument text */ - struct if_node *ifnode; - } data; - HyperLink *link; /* link for active text */ - union { - Pixmap pm; /* pixmap for bit images */ - XImage *xi; /* pixmap image */ - } image; - struct text_node *next; /* next node in formatted text */ -} TextNode; - -/** Structure used to store pixmaps and bitmaps **/ - -typedef struct image_struct { - int width,height; /** It's width and height **/ - union { - Pixmap pm; - XImage *xi; - } image; - char *filename; /** The filename used to reference it **/ -} ImageStruct; - -/* Structure for locating HyperDoc pages in a source file */ - -typedef struct { - char *name; /* file name */ - long pos; /* position in file */ - int ln; /* the line number */ -} FilePosition; - -/*** The structure needed for storing a macro **/ - -typedef struct macro_store { - short int loaded; - FilePosition fpos; - char *name; - char *macro_string; - short number_parameters; -} MacroStore; - - -/** Structure needed for storing a patch **/ -typedef struct patch_store { - short int loaded; - FilePosition fpos; - char *name; - char *string; -} PatchStore; - -/* Here are the structures needed for doing input to HyperDoc windows. */ - -typedef struct line_struct { - char *buffer; - int changed; /* Has the line changed */ - int line_number; - int buff_pntr; - int len; - struct line_struct *prev, *next; -} LineStruct; - -typedef struct input_window { - char *name; /* symbol name **/ - int size; /* the length of the window **/ - int cursor_x; /* x-coordinate for the cursor **/ - int entered; /* tells me whether I have typed here - before */ - int num_lines; /* number of lines needed to store - buffer */ - LineStruct *lines; - LineStruct *curr_line; /* the current line on which the cursor */ - Window win; - struct input_window *next; -} InputItem; - - -/* structure for storing input boxes **/ -typedef struct input_box { - char *name; - ImageStruct *selected, *unselected; - short int picked; - struct input_box *next; - struct radio_boxes *rbs; - Window win; -} InputBox; - -typedef struct radio_boxes { - char *name; - InputBox *boxes; - ImageStruct *selected, *unselected; - int width, height; - struct radio_boxes *next; -} RadioBoxes; - -/* Structure for spadcommand dependencies hash table entries */ -typedef struct spadcom_depend { - char *label; /* dependency label */ - TextNode *spadcom; /* spadcommand defining the label */ - short executed; /* true iff spadcommand has benn executed */ -} SpadcomDepend; - -typedef struct button_list { - int x0,y0,x1,y1; - HyperLink *link; - Window win; - struct button_list *next; -} ButtonList; - -/* Stucture for unformatted hyper text page */ - -typedef struct hyperdoc_page { - short type; /* Normal, Quitbutton, Upbutton etc. */ - char *name; /* ID of page */ - char *filename; /* The name of the file in which the page - occurs, Null if not */ - int scroll_off; /* The offset in the scrolling region */ - int bot_scroll_margin; /* bottom of the scrolling region */ - int top_scroll_margin; /* top of the scrolling region */ - TextNode *title; /* the title of the page */ - TextNode *header; /* formatted version of page */ - TextNode *scrolling; /* Top of scrolling region */ - TextNode *footer; /* top of non-scrolling region at bottom */ - Sock *sock; /* socket connection for spad buffer */ - HashTable *fLinkHashTable; /* active link hash table */ - ButtonList *s_button_list; /* active buttons on page */ - ButtonList *button_list; /* active buttons on page */ - HashTable *depend_hash; /* Hash tables of spadcommand dependencies */ - InputItem *input_list; /* List of input structures */ - InputItem *current_item; /* a pntr to the currently active item */ - HashTable *box_hash; /* place where all the boxes are stored */ - RadioBoxes *radio_boxes; /* a linked list of radio boxes */ - short page_flags; /* A list of flags for the page */ - char *helppage; /* the name of the helppage */ -} HyperDocPage; - -/* Structure for an unloaded page */ - -typedef struct unloaded_page { - short type; /* indicator of unloaded page */ - char *name; /* name of page */ - FilePosition fpos; /* where to find the page */ -} UnloadedPage; - -/* Structure for a HyperDoc Window */ - -typedef struct { - Window fMainWindow; /* The main text field window. */ - Window fScrollWindow; /* The scrolling area of the window */ - Window fDisplayedWindow; /* The current window of the above two, */ - /* being filled by display */ - - Window fScrollUpWindow; /* Window for scrolling up a line */ - Window fScrollDownWindow; /* Window for scrolling down a line */ - - Window scrollbar; /* the window for scrolling */ - Window scroller; /* the scroller window */ - - Window fTitleBarButton1; /* 1st titlebar bitmap button */ - Window fTitleBarButton2; /* 2nd titlebar bitmap button */ - Window fTitleBarButton3; /* 3rd titlebar bitmap button */ - Window fTitleBarButton4; /* 4th titlebar bitmap button */ - - int fScrollerTopPos; /* where the top of the scroller is */ - int fScrollerHeight; /* the height of the scroller */ - int fScrollBarHeight; /* the height for the scrollbar */ - - int scrollwidth; /* the width of the scrolling area */ - int scrollheight; /* the height of the scrolling area */ - int scrollupy; /* Current y position of the scroll up */ - /* button */ - int scrolldowny; /* Current y position of the scroll */ - /* downbutton */ - int scrollbary; /* Current y position of teh scrollbar */ - int scrollx; /* X coordinates for all of the above */ - int border_width; /* Width of the border */ - HyperDocPage *page; /* currently displayed page */ - int width, height; /* in pixels */ - int columns; /* Width in characters, only setable */ - /* for form pages */ - HyperDocPage **fMemoStack; /* stack of memo links */ - HyperDocPage **fDownLinkStack;/* stack of down links */ - - int *fDownLinkStackTop; /* stack of down links */ - int fMemoStackIndex; /* memo stack pointer */ - int fDownLinkStackIndex; /* downlink stack pointer */ - - HashTable *fWindowHashTable; /* hash table of active subwindows */ - HashTable *fPageHashTable; /* hash table of HyperDoc pages */ - HashTable *fPasteHashTable; /* hash table for paste in areas */ - HashTable *fMacroHashTable; /* hash table of HyperDoc macros */ - HashTable *fCondHashTable; /* hash table for values */ - HashTable *fPatchHashTable; /* hash table for patch locations */ - - int fAxiomFrame; /* Axiom frame number initializing window */ - GC fStandardGC; /* Graphics context for window */ - GC fInputGC; /* Graphics context for the input windows */ - GC fCursorGC; /* Graphics context for the cursors */ - GC fControlGC; /* Graphics context for the buttons */ - Cursor fDisplayedCursor; /* The currently displayed cursor */ -} HDWindow; - -/* Structure for identifying appropriate link hash tables */ - -typedef struct { - int code; /* code of active area */ - HyperDocPage *page; /* page for which hash table applies */ -} LinkHashID; - -/*** Flags for the page ***/ - -#define NOLINES 0000001 /* Ibid, for the bottom of the page ***/ - - -/* external variables and functions. See the source file for a description - of their purposes */ - -extern HashTable gSessionHashTable; /* hash table of HD windows */ - -extern HDWindow *gParentWindow; /* the parent window. The one that - * appears when you first start HD */ - -extern HyperLink *quitLink; /** a special link to the protected quit page **/ - - -#ifndef HTADD -/* From hyper.c */ -extern int gXScreenNumber; -extern Display *gXDisplay; -extern int gSwitch_to_mono; -extern unsigned long * spadColors; -extern int gIsEndOfOutput; -extern HDWindow *gWindow; -extern Sock *session_server; -extern Sock *spad_socket; -extern HashTable gFileHashTable; -extern HashTable gImageHashTable; /* A global hash table for images */ -extern Cursor gNormalCursor; /* The normal mouse cursor */ -extern Cursor gActiveCursor; /* The cursor in active regions */ -extern Cursor gBusyCursor; /* The clock cursor for when I am busy */ -extern int gIsAxiomServer; /* true iff HyperDoc is acting as an Axiom server */ -extern int gArgc; /* original argc from main */ -extern char **gArgv; /* original argv from main */ -/* from lex.c */ -extern long fpos, keyword_fpos; -extern Token token; -extern int last_token, input_type, last_ch; -extern char *input_string; -extern FILE *cfile; -/* from input.c */ -extern XImage *picked; -extern int picked_height; -extern int picked_width; -extern XImage *unpicked; -extern int unpicked_height; -extern int unpicked_width; -/* from display.c */ -extern int line_height; -extern int need_scroll_up_button; -extern int scrolling; -extern int need_scroll_down_button; -extern int space_width; -#endif - -/* Here are some of the functions and constants declared and needed in - htadd.c ******/ - -#define NoChar -9999 -#define temp_dir "/tmp/" -#define db_file_name "ht.db" -#define def_spad "/usr/local/axiom" - - -/* Types of HyperDoc pages */ - -#define UlUnknownPage 9993 /*I hate this hack, but I have to know whether*/ -#define UnknownPage 9994 /*this page has been loaded or not. */ -#define ErrorPage 9995 -#define Unixfd 9996 -#define SpadGen 9997 -#define Normal 9998 -#define UnloadedPageType 9999 - -/* Commands from Axiom */ - -#define EndOfPage 99 -#define SendLine 98 -#define StartPage 97 /* A normal HyperDoc page */ -#define LinkToPage 96 -#define PopUpPage 95 /* A pop-up page */ -#define PopUpNamedPage 94 -#define KillPage 93 -#define ReplacePage 92 -#define ReplaceNamedPage 91 -#define SpadError 90 - -/* Constants declaring size of page stacks */ - -#define MaxMemoDepth 25 /* max nesting level for memolinks */ -#define MaxDownlinkDepth 50 /* max downlink nesting depth */ - -/* Constants defining the size of various hash tables */ - -#define PageHashSize 1000 -#define FileHashSize 30 -#define SessionHashSize 10 -#define MacroHashSize 100 -#define ImageHashSize 100 -#define CondHashSize 100 -#define BoxHashSize 20 -#define PasteHashSize 100 -#define PatchHashSize 100 - -/* A couple of macros for memo and down links */ - -#define need_up_button \ - (gWindow->fMemoStackIndex ? gWindow->fDownLinkStackIndex >= \ - gWindow->fDownLinkStackTop[gWindow->fMemoStackIndex-1] \ - : gWindow->fDownLinkStackIndex) - -#define need_return_button (gWindow->fMemoStackIndex) - -#define need_help_button (gWindow->page->helppage != NULL) - -#define max(x,y) ((x) > (y) ? (x) : (y)) - - -#define pick_box(box) fill_box(box->win, box->selected) -#define unpick_box(box) fill_box(box->win, box->unselected) - -#define TopLevelHelpPage "ugHyperPage" -#define NoMoreHelpPage "NoMoreHelpPage" -#define KeyDefsHelpPage "ugHyperKeysPage" -#define InputAreaHelpPage "ugHyperInputPage" - -/* definitions for connecting to the Axiom server */ - -#define Connected 0 -#define NotConnected 1 -#define SpadBusy 2 - -/* some GUI-dependent stuff */ - -#define BeepAtTheUser() /* (XBell(gXDisplay, 5)) */ -#define LoudBeepAtTheUser() /* (XBell(gXDisplay, 50)) */ - - -/*** default fonts ***/ - -#if defined(RTplatform) || defined(PS2platform) || defined(RIOSplatform) || defined(AIX370platform) -#define RmFontDefault "Rom14" -#define TtFontDefault "Erg14" -#define ActiveFontDefault "Bld14" -#define AxiomFontDefault "Erg14" -#define EmphasizeFontDefault "Itl14" -#define BoldFontDefault "Bld14" -#endif - -#if defined(SUNplatform) || defined (SUN4OS5platform) || defined(SGIplatform) || defined (HP9platform) || defined(HP10platform) || defined (ALPHAplatform) || defined(LINUXplatform) || defined(MACOSXplatform) || defined(BSDplatform) -#define RmFontDefault "-adobe-courier-medium-r-normal--18-*-*-*-m-*-iso8859-1" -#define TtFontDefault "-adobe-courier-medium-r-normal--18-*-*-*-m-*-iso8859-1" -#define ActiveFontDefault "-adobe-courier-bold-r-normal--18-*-*-*-m-*-iso8859-1" -#define AxiomFontDefault "-adobe-courier-bold-o-normal--18-*-*-*-m-*-iso8859-1" -#define EmphasizeFontDefault "-adobe-courier-medium-o-normal--18-*-*-*-m-*-iso8859-1" -#define BoldFontDefault "-adobe-courier-bold-r-normal--18-*-*-*-m-*-iso8859-1" -#endif - - - - - - -typedef struct group_item { - int cur_color; - XFontStruct *cur_font; - int center; - struct group_item *next; -} GroupItem; - - -extern GroupItem *gTopOfGroupStack; - - -typedef struct cond_node { - char *label; - char *cond; -} CondNode; - -typedef struct parameter_list_type { - char **list; /** The parameters in string form **/ - short number; /** How many parameters are there **/ - struct parameter_list_type *next; -} *ParameterList; - -#endif -@ -\section{hyper.c} -<>= -/* - * This is the main module of the HyperDoc program. It contains the main - * routine which initializes all the X stuff, and the tables. Then it passes - * control over to the main event loop. - */ - -/* #define DEBUG 1 */ - -/* Include all the needed include files */ -#define _HYPER_C -#include "useproto.h" -#include "debug.h" - - -#include "hyper.h" - -#include -#include -#include -#include -#include - -#include "keyin.h" -#include "initx.h" -#include "event.h" -#include "parse-aux.h" -#include "bsdsignal.h" - -#include "all_hyper_proto.H1" -#include "sockio-c.H1" -#include "bsdsignal.H1" -/* - * Here is a flag used to tell me whether I made a good connection to the - * menu server. Needed so I don't send spad commands when I should not - */ - -int MenuServerOpened = 1; - -/* include icon bitmap data */ - -#define BITMAPDEPTH 1 - -/* X11 display and screen variables */ - -Display *gXDisplay; -int gXScreenNumber; - -/* - * Information about the top level HyperDoc window - */ - -HDWindow *gWindow = NULL; /* the current window */ -HDWindow *gParentWindow =NULL; /* the parent window. The one that appears - * when you first start HyperDoc */ - -HashTable gSessionHashTable; /* hash table of HD windows */ -HashTable init_page_hash; /* initial hash table of HD pages */ -HashTable init_macro_hash; /* initial hash table of HD macros */ -HashTable init_patch_hash; /* initial hash table of HD patches */ - -/* The various Cursors we use */ - -Cursor gNormalCursor; /* The normal mouse cursor */ -Cursor gActiveCursor; /* The cursor in active regions */ -Cursor gBusyCursor; /* The clock cursor for when I am busy */ - - -HashTable gFileHashTable; /* hash table of HyperDoc files */ -HashTable gImageHashTable; /* hash table for images */ - - -/* Some things needed for Handling interupts properly */ - -int gIsEndOfOutput; /* set to true when spad has finished output */ -int received_window_request = 0;/* true iff Spad wants a pop-up */ -int in_next_event = 0; /* true when in XNextEvent */ -int make_input_file = 0; /* true when making input files from ht */ -int make_patch_files = 0; /* true when making patch files from ht */ -int gmake_record_file= 0; /* true when making record files from ht */ -int gverify_record_file = 0; /* true when verifying record files from ht */ -int gverify_dates = 0; /* true when we want hypertex to verify ht.db dates */ - -Sock *session_server; /* socket connecting to session manager */ - -int gIsAxiomServer = 0; /* true iff HyperDoc is acting as a */ - /* an Axiom server */ - -int kill_spad = 0; /* kill spad when finished with paste file */ - -int gSwitch_to_mono=0; /* will be set to 1 if at any time we don't have - enough colours for the images. We will know this - when read_pixmap_file returns -1. We will use this - when deciding what to do in case of \inputimage */ - -int gTtFontIs850=0; /* a flag that tells us if the Tt font is a IBM pagecode 850 - font and hence supports the graphics chars - set when the TtFont is opened*/ - -/* - * Global copies of the command line arguments, so they never have to be - * passed as parameters. This is also so any child process starting up also - * has the same values. - */ - -int gArgc; -char **gArgv; - -char **input_file_list; -int input_file_count; - -/* - * SIGUSR2 is raised by the spadbuf program when it is done with the current - * command - */ - -void -sigusr2_handler(int sig) -{ - gIsEndOfOutput = 1; - return ; -} - -void -sigcld_handler(int sig) -{ - - /* why were we waiting after the child had already died ?? - because we don't want zombies */ - - int x; - wait(&x); - -} - -extern jmp_buf env; - - -/* Clean up spad sockets on exit */ -void -clean_socket(void ) -{ - char name[256]; - - make_server_name(name, MenuServerName); - unlink(name); -} - -/* - * initialize hash tables, signal handlers and windows, then call the main - * event handling loop - */ - -int -main(int argc, char **argv) -{ - int ret_status; - - /* Initialize some global values */ -/* fprintf(stderr,"hyper:main:entered\n");*/ - gArgc = argc; - gArgv = argv; - gIsEndOfOutput = 1; - -/* fprintf(stderr,"hyper:main:calling check_arguments\n");*/ - check_arguments(); -/* fprintf(stderr,"hyper:main:returned check_arguments\n");*/ - - /* - * initialize the hash tables for the files and the windows and images - */ -/* fprintf(stderr,"hyper:main:calling init_hash\n");*/ - init_hash(); -/* fprintf(stderr,"hyper:main:returned init_hash\n");*/ - - /* - * initialize the parser keyword hash table - */ -/* fprintf(stderr,"hyper:main:calling parser_init\n");*/ - parser_init(); -/* fprintf(stderr,"hyper:main:returned parser_init\n");*/ - -/* fprintf(stderr,"hyper:main:calling read_ht_db\n");*/ - read_ht_db(&init_page_hash, &init_macro_hash, &init_patch_hash); -/* fprintf(stderr,"hyper:main:returned read_ht_db\n");*/ - - /* - * Now initialize x. This includes opening the display, setting the - * screen and display global values, and also gets all the fonts and - * colors we will need. - */ - - if (!make_input_file && !gmake_record_file && !gverify_record_file) { -/* fprintf(stderr,"hyper:main:calling initializeWindowSystem\n");*/ - initializeWindowSystem(); -/* fprintf(stderr,"hyper:main:returned initializeWindowSystem\n");*/ - - /* - * Initialize some of the global values used by the input string - * routines - */ -/* fprintf(stderr,"hyper:main:calling init_keyin\n");*/ - init_keyin(); -/* fprintf(stderr,"hyper:main:returned init_keyin\n");*/ - - /* - * regardless of what else happened, we should always pop up an - * initial window. - */ - -/* fprintf(stderr,"hyper:main:calling init_top_window\n");*/ - ret_status = init_top_window("RootPage"); -/* fprintf(stderr,"hyper:main:returned init_top_window\n");*/ - gParentWindow = gWindow; - if (ret_status == -1) { - fprintf(stderr, - "(HyperDoc) Could not find RootPage for top-level window.\n"); - exit(-1); - } - - /* - * Tell it how to handle the user defined signals I may get - */ - bsdSignal(SIGUSR2, sigusr2_handler,RestartSystemCalls); - bsdSignal(SIGUSR1, SIG_IGN,RestartSystemCalls); -#if defined(BSDplatform) || defined(MACOSXplatform) - bsdSignal(SIGCHLD, sigcld_handler,RestartSystemCalls); -#else - bsdSignal(SIGCLD, sigcld_handler,RestartSystemCalls); -#endif - bsdSignal(SIGINT, SIG_IGN,RestartSystemCalls); - - /* - * Now go to the main event loop. I will never return, so just end - * the main routine after that - */ - - /* - * make an input file if requested - */ - } - else { - - /* - * Try to establish all the socket connections I need. If I am an - * gIsAxiomServer and the routine fails, it will exit for me - */ -/* fprintf(stderr,"hyper:main:in else case\n");*/ -/* fprintf(stderr,"hyper:main:calling make_server_connections\n");*/ - make_server_connections(); -/* fprintf(stderr,"hyper:main:returned make_server_connections\n");*/ - - - if (make_input_file) ht2_input(); - if (gmake_record_file) make_record(); - if (gverify_record_file) verify_record(); - exit(0); - } - - /* - * Try to establish all the socket connections I need. If I am an - * gIsAxiomServer and the routine fails, it will exit for me - */ -/* fprintf(stderr,"hyper:main:calling make_server_connections\n");*/ - make_server_connections(); -/* fprintf(stderr,"hyper:main:returned make_server_connections\n");*/ - - -/* fprintf(stderr,"hyper:main:calling mainEventLoop\n");*/ - mainEventLoop(); -/* fprintf(stderr,"hyper:main:returned mainEventLoop\n");*/ - - return 0; -} - -/* - * Initializes the hash table for Files, and Windows - */ - -static void -init_hash(void) -{ - hash_init(&gFileHashTable, - FileHashSize, - (EqualFunction)string_equal, - (HashcodeFunction) string_hash); - hash_init(&gSessionHashTable, - SessionHashSize, - (EqualFunction) window_equal, - (HashcodeFunction) window_code); - hash_init(&gImageHashTable, - ImageHashSize, - (EqualFunction) string_equal, - (HashcodeFunction) string_hash); -} - -/* initialize the HyperDoc page hierarchy data structures */ - -void -init_page_structs(HDWindow *w) -{ - int i; - - w->fMemoStackIndex = 0; - for (i = 0; i < MaxMemoDepth; i++) { - w->fMemoStack[i] = NULL; - w->fDownLinkStackTop[i] = 0; - } - w->fDownLinkStackIndex = 0; - for (i = 0; i < MaxDownlinkDepth; i++) - w->fDownLinkStack[i] = NULL; -} - -static void -check_arguments(void) -{ - int i; - - /* - * Now check the command line arguments, to see if I am supposed to be a - * server or not - */ - for (i = 1; i < gArgc; i++) { - if (gArgv[i][0] == '-') - switch (gArgv[i][1]) { - case 'p': - gverify_dates=1; - break; - case 's': - if (!MenuServerOpened) { - fprintf(stderr, "(HyperDoc) Server already in use.\n"); - exit(-1); - } - gIsAxiomServer = 1; - break; - case 'i': - if (gArgv[i][2] == 'p') - make_patch_files = 1; - make_input_file = 1; - input_file_list = gArgv + i + 1; - input_file_count = gArgc - i - 1; - break; - case 'k': - kill_spad = 1; - break; - case 'r': - if (gArgv[i][2] == 'm') - gmake_record_file=1; - else if (gArgv[i][2] == 'v') - gverify_record_file=1; - else - fprintf(stderr, "(HyperDoc) v or m must follow -r\n"); - input_file_list = gArgv + i + 1; - input_file_count = gArgc - i - 1; - break; - default: - fprintf(stderr, "(HyperDoc) Unexpected Command Line Argument %s\n", gArgv[i]); - fprintf(stderr, " Usage: hypertex [-s]\n"); - break; - } - } -} - -static void -make_server_connections(void) -{ - int i, wait_time; - - /* - * Try to open the menuserver socket, if I can not, then set a flag - */ - - if (open_server(MenuServerName) == -2) { - fprintf(stderr, "(HyperDoc) Warning: Not connected to AXIOM Server!\n"); - MenuServerOpened = 0; - } else { - atexit(&clean_socket); - MenuServerOpened = 1; - } - - - /* - * If I have opened the MenuServer socket, then I should also try to open - * the SpadServer socket, so I can send stuff right to SPAD. - */ - - if (MenuServerOpened) { - - /* - * If I am a ht server, then I should not continue on unless I - * establish some sort of connection - */ - - /* - * Modified on 11/20 so that it prints an error message every ten for - * ten tries at opeing the socket. If it fails all ten times, it - * gives up and exits. - */ - - if (!gIsAxiomServer) - wait_time = 2; - else - wait_time = 1000; - - for (i = 0, spad_socket = NULL; i < 2 && spad_socket == NULL; i++) { - spad_socket = connect_to_local_server(SpadServer, - MenuServer, wait_time); - if (gIsAxiomServer && spad_socket == NULL) - fprintf(stderr, "(HyperDoc) Error opening AXIOM server. Retrying ...\n"); - else - i = 11; - } - if (! spad_socket) { - fprintf(stderr, "(HyperDoc) Couldn't connect to AXIOM server!\n"); - if (!gIsAxiomServer) - MenuServerOpened = 0; - else { - fprintf(stderr, "(HyperDoc) Couldn't connect to AXIOM server!\n"); - exit(-1); - } - } - else { - - /* - * Do the same thing for the SessionServer - */ - - for (i = 0, session_server = NULL; i < 2 && session_server == NULL - ; i++) { - session_server = - connect_to_local_server(SessionServer, MenuServer, - wait_time); - if (gIsAxiomServer && session_server == NULL) { - fprintf(stderr, - "(HyperDoc) Error opening SessionServer, Retrying ...\n"); - } - else - i = 11; - } - if (session_server == NULL) { - fprintf(stderr, "(HyperDoc) Connection attempt to session manager timed out.\n"); - if (gIsAxiomServer) { - fprintf(stderr, - "(HyperDoc) Server unable to connect to session server\n"); - exit(-1); - } - else { - MenuServerOpened = 0; - } - } - } - } -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/initx.c b/src/hyper/initx.c new file mode 100644 index 00000000..b2f85e59 --- /dev/null +++ b/src/hyper/initx.c @@ -0,0 +1,1018 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +/**************************************************************** + * + * initx.h: HyperDoc X Window window initialization code + * + * Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993. + * + ****************************************************************************/ + +/* #define DEBUG 1 */ + +#define _INITX_C +#include "axiom-c-macros.h" +#include "useproto.h" +#include "debug.h" + +#include "initx.h" + +#include +#include +#include +#include +#include +#include + +#ifdef SUN4OS5platform +extern int gethostname(char *, int ); +#endif + +#include "ht_icon" +#include "extent.h" +#include "group.h" +#include "hyper.h" +#include "scrollbar.h" +#include "titlebar.h" + +#include "all_hyper_proto.H1" +#include "util.H1" + +#include "spadcolors.h" +#include "spadcolors.H1" + + +#include "mouse11.bitmap" +#include "mouse11.mask" + + +static GContext server_font; +unsigned long *spadColors; +int scrn; /* used in spad_colors */ + +extern int received_window_request; /* true iff Spad wants a pop-up */ +extern int in_next_event; /* true when in XNextEvent */ + +extern int gTtFontIs850; + +#define MIN_WINDOW_SIZE 300 + + +int gActiveColor, + gAxiomColor, + gBackgroundColor, + gBfColor, + gControlBackgroundColor, + gControlForegroundColor, + gEmColor, + gInputBackgroundColor, + gInputForegroundColor, + gItColor, + gRmColor, + gSlColor, + gTtColor; + +XFontStruct *gAxiomFont, + *gActiveFont, + *gBfFont, + *gEmFont, + *gInputFont, + *gItFont, + *gRmFont, + *gSlFont, + *gTitleFont, + *gTtFont; + +XrmDatabase rDB; +int gBorderColor; /* The Border Color */ + +/* Initialize the X Window System */ + +void +initializeWindowSystem(void) +{ + char *display_name = NULL; + XColor fg, bg; +#if 0 + XColor rgbdef; +#endif + Colormap cmap; + Pixmap mousebits, mousemask; +/* fprintf(stderr,"initx:initializeWindowSystem:entered\n");*/ + /* Try to open the display */ +/* fprintf(stderr,"initx:initializeWindowSystem:XOpenDisplay\n");*/ + if ((gXDisplay = XOpenDisplay(display_name)) == NULL) { + fprintf(stderr, "(HyperDoc) Cannot connect to the X11 server!\n"); + exit(-1); + } + + /* Get the screen */ +/* fprintf(stderr,"initx:initializeWindowSystem:DefaultScreen\n");*/ + gXScreenNumber = scrn = DefaultScreen(gXDisplay); +/* fprintf(stderr,"initx:initializeWindowSystem:XGContextFromGC\n");*/ + server_font =XGContextFromGC(DefaultGC(gXDisplay, gXScreenNumber)); + + /* Get the cursors we need. */ + +/* fprintf(stderr,"initx:initializeWindowSystem:DefaultColormap\n");*/ + cmap = DefaultColormap(gXDisplay, gXScreenNumber); +/* fprintf(stderr,"initx:initializeWindowSystem:WhitePixel\n");*/ + fg.pixel = WhitePixel(gXDisplay,gXScreenNumber); +/* fprintf(stderr,"initx:initializeWindowSystem:XQueryColor\n");*/ + XQueryColor(gXDisplay, cmap, &fg ); +/* fprintf(stderr,"initx:initializeWindowSystem:BlackPixel\n");*/ + bg.pixel = BlackPixel(gXDisplay,gXScreenNumber); +/* fprintf(stderr,"initx:initializeWindowSystem:XQueryColor2\n");*/ + XQueryColor(gXDisplay, cmap, &bg ); +#if 0 + XAllocNamedColor(gXDisplay, cmap, "Black", &fg, &rgbdef); + XAllocNamedColor(gXDisplay, cmap, "White", &bg, &rgbdef); +#endif + +#ifdef USE_BORING_OLD_CURSORS + gActiveCursor = XCreateFontCursor(gXDisplay, XC_circle); + gNormalCursor = XCreateFontCursor(gXDisplay, XC_dot); +#else +/* fprintf(stderr,"initx:initializeWindowSystem:XCreateBitmapFromData 1\n");*/ + mousebits = XCreateBitmapFromData(gXDisplay, + RootWindow(gXDisplay, gXScreenNumber), + mouseBitmap_bits, mouseBitmap_width,mouseBitmap_height); +/* fprintf(stderr,"initx:initializeWindowSystem:XCreateBitmapFromData 2\n");*/ + mousemask = XCreateBitmapFromData(gXDisplay, + RootWindow(gXDisplay, gXScreenNumber), + mouseMask_bits, mouseMask_width,mouseMask_height); +/* fprintf(stderr,"initx:initializeWindowSystem:XCreateBitmapFromData 2\n");*/ + gActiveCursor = XCreatePixmapCursor(gXDisplay, + mousebits, mousemask, &fg, &bg, + mouseBitmap_x_hot,mouseBitmap_y_hot); + +/* fprintf(stderr,"initx:initializeWindowSystem:XCreateFontCursor\n");*/ + gNormalCursor = XCreateFontCursor(gXDisplay, XC_left_ptr); +#endif + +/* fprintf(stderr,"initx:initializeWindowSystem:XCreateFontCursor 2\n");*/ + gBusyCursor = XCreateFontCursor(gXDisplay, XC_watch); + + /* Now initialize all the colors and fonts */ + +/* fprintf(stderr,"initx:initializeWindowSystem:ingItColors_and_fonts\n");*/ + ingItColors_and_fonts(); +/* fprintf(stderr,"initx:initializeWindowSystem:init_text\n");*/ + init_text(); +/* fprintf(stderr,"initx:initializeWindowSystem:exited\n");*/ + +} + +/* + * This routine is responsible for initializing a HyperDoc Window. At this + * point, all the fonts have been loaded, and X has been initialized. All I + * need worry about is starting up the window, and creating some of its + * children. + */ + + +/* + * init_top_window tries to start up a window with the page name. If the + * page name is NULL, + * it doesn't try to find it in the Hash Table, but rather just allocates a + * page of no name + */ + +int +init_top_window(char *name) +{ + HyperDocPage *page; + XSetWindowAttributes wa; /* The X attributes structure */ + HDWindow *old_win = gWindow; + + gWindow = alloc_hd_window(); + + if (name == NULL) { + /** Then allocate an empty page, and assign it to gWindow->page */ + page = alloc_page((char *) NULL); + } + else { + /* Try to find the page in the page hash table */ + page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, name); + if (page == NULL) { + fprintf(stderr, "(HyperDoc) Couldn\'t find page %s in page hash table \n", + name); + if (gParentWindow == NULL) + /* Gaak, This is a start up error */ + exit(-1); + else { + gWindow = old_win; + return -1; + } + } + } + + /* First allocate memory for the new window structure */ + gWindow->page = page; + + if (old_win == NULL) + open_window(0); + else + open_window(old_win->fMainWindow); + + get_GCs(gWindow); + XMapWindow(gXDisplay, gWindow->fMainWindow); + hash_insert(&gSessionHashTable, (char *)gWindow,(char *) &gWindow->fMainWindow); + + change_text(gRmColor, gRmFont); + wa.background_pixel = gBackgroundColor; + XChangeWindowAttributes(gXDisplay, gWindow->fMainWindow, CWBackPixel, &wa); + XChangeWindowAttributes(gXDisplay, gWindow->fScrollWindow, CWBackPixel,&wa); + return 1; +} + +/* Create and initialize a form HyperDoc window */ + +static void +open_form_window(void) +{ + int x, y, width, height; + unsigned int fwidth = 0, fheight = 0; + unsigned int xadder = 0, yadder = 0; + /*char *window_name = "HyperDoc";*/ + /*char *icon_name = "HT";*/ + XrmValue value; + char *str_type[50]; + XSizeHints size_hints; + int userSpecified = 0; + + char userdefaults[50], progdefaults[50]; + + strcpy(progdefaults, "=950x450+0+0"); + if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.FormGeometry", + "OpenAxiom.hyperdoc.FormGeometry", str_type, &value) == True) + { + strncpy(userdefaults, value.addr, (int) value.size); + userSpecified = 1; + } + else + strcpy(userdefaults, progdefaults); + + XGeometry(gXDisplay, gXScreenNumber, userdefaults, progdefaults, + 0, fwidth, fheight, xadder, yadder, + &x, &y, &width, &height); + + gWindow->border_width = get_border_properties(); + + gWindow->width = 1; + gWindow->height = 1; + + gWindow->fMainWindow = XCreateSimpleWindow(gXDisplay, RootWindow(gXDisplay, gXScreenNumber), + x, y, width, height, gWindow->border_width, + gBorderColor, + WhitePixel(gXDisplay, gXScreenNumber)); + gWindow->fScrollWindow = XCreateSimpleWindow(gXDisplay, gWindow->fMainWindow, + 1, 1, 1, 1, 0, + BlackPixel(gXDisplay, gXScreenNumber), + WhitePixel(gXDisplay, gXScreenNumber)); + makeScrollBarWindows(); + makeTitleBarWindows(); + + set_name_and_icon(); + + XSelectInput(gXDisplay, gWindow->fScrollWindow, PointerMotionMask); + XSelectInput(gXDisplay, gWindow->fMainWindow, StructureNotifyMask | PointerMotionMask); + XDefineCursor(gXDisplay, gWindow->fMainWindow, gNormalCursor); + + /* now give the window manager some hints */ + + size_hints.flags = 0; + + size_hints.min_width = width; + size_hints.min_height = height; + size_hints.flags |= PMinSize; + + size_hints.width = width; + size_hints.height = height; + size_hints.flags |= (userSpecified ? USSize : PSize); + + size_hints.x = x; + size_hints.y = y; + size_hints.flags |= (userSpecified ? USPosition : PPosition); + + XSetNormalHints(gXDisplay, gWindow->fMainWindow, &size_hints); + XFlush(gXDisplay); +} + + +int +init_form_window(char *name, int cols) +{ + XSetWindowAttributes wa; /* The X attributes structure */ + + /* First allocate memory for the new window structure */ + + gWindow = alloc_hd_window(); + open_form_window(); + gWindow->width = window_width(cols); + + if (name == NULL) { + /** Then allocate an empty page, and assign it to gWindow->page */ + gWindow->page = alloc_page((char *) NULL); + } + else { + /* Try to find the page in the page hash table */ + gWindow->page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, name); + if (gWindow->page == NULL) { + fprintf(stderr, "Couldn't find page %s\n", name); + return (-1); + } + } + + get_GCs(gWindow); + hash_insert(&gSessionHashTable, (char *)gWindow,(char *) &gWindow->fMainWindow); + + wa.background_pixel = gBackgroundColor; + XChangeWindowAttributes(gXDisplay, gWindow->fMainWindow, CWBackPixel, &wa); + XChangeWindowAttributes(gXDisplay, gWindow->fScrollWindow, CWBackPixel,&wa); + return 1; +} + + +static void +set_name_and_icon(void) +{ + char *icon_name = "HyperDoc"; + char *s; + Pixmap icon_pixmap; + XWMHints wmhints; + XClassHint ch; + + ch.res_name = "HyperDoc"; + ch.res_class = gArgv[0]; + for (s = gArgv[0] + strlen(gArgv[0]) - 1; s != gArgv[0]; s--) { + if (*s == '/') { + ch.res_class = s + 1; + break; + } + } + XSetClassHint(gXDisplay, gWindow->fMainWindow, &ch); + + XStoreName(gXDisplay, gWindow->fMainWindow, "HyperDoc"); + + /* define and assign the pixmap for the icon */ + icon_pixmap = XCreateBitmapFromData(gXDisplay, gWindow->fMainWindow, ht_icon_bits, + ht_icon_width, ht_icon_height); + wmhints.icon_pixmap = icon_pixmap; + wmhints.flags = IconPixmapHint; + + XSetWMHints(gXDisplay, gWindow->fMainWindow, &wmhints); + + /* name the icon */ + XSetIconName(gXDisplay, gWindow->fMainWindow, icon_name); +} + +static int +get_border_properties(void) +{ + char *bwidth; + /*char *bc = NULL;*/ + int bw; + /*XColor color_def, color_db;*/ + Colormap cmap; + /*int ret_val;*/ + + + bwidth = "2"; /* XGetDefault(gXDisplay, "Axiom.hyperdoc", "BorderWidth") */ + + if (bwidth == NULL) + bw = 1; + else { + bw = atoi(bwidth); + if (bw < 1) { + fprintf(stderr, + "%s: The line width value must be greater than zero\n", "OpenAxiom.hyperdoc"); + bw = 1; + } + } + + /* Now try to find the user preferred border color */ + + if (DisplayPlanes(gXDisplay, gXScreenNumber) == 1) + gBorderColor = BlackPixel(gXDisplay, gXScreenNumber); + else { + cmap = DefaultColormap(gXDisplay, gXScreenNumber); + gBorderColor = get_color("BorderColor", "Foreground", + BlackPixel(gXDisplay, gXScreenNumber), &cmap); + } + return bw; +} + + +/* Create and initialize the HyperDoc window */ + +static void +open_window(Window w) +{ + int x = 0, y = 0; + /*int border_width = 2;*/ + unsigned int width = 1; + unsigned int height = 1; + unsigned int fwidth = 0, fheight = 0; + unsigned int xadder = 0, yadder = 0; + char *str_type[50]; + XrmValue value; + + char userdefaults[50], progdefaults[50]; + + strcpy(progdefaults, "=700x450+0+0"); + if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.Geometry", + "OpenAxiom.hyperdoc.Geometry", str_type, &value) == True) + { + strncpy(userdefaults, value.addr, (int) value.size); + } + else + strcpy(userdefaults, progdefaults); + + XGeometry(gXDisplay, gXScreenNumber, userdefaults, progdefaults, + 0, fwidth, fheight, xadder, yadder, + &x, &y, ( int *)&width,( int *) &height); + + gWindow->border_width = get_border_properties(); + + gWindow->fMainWindow = XCreateSimpleWindow(gXDisplay, RootWindow(gXDisplay, gXScreenNumber), + x, y, width, height, gWindow->border_width, + gBorderColor, + WhitePixel(gXDisplay, gXScreenNumber)); + + gWindow->fScrollWindow = XCreateSimpleWindow(gXDisplay, gWindow->fMainWindow, + 1, 1, 1, 1, 0, + gBorderColor, + WhitePixel(gXDisplay, gXScreenNumber)); + + + makeScrollBarWindows(); + makeTitleBarWindows(); + + /* Now set all the little properties for the top level window */ + + set_name_and_icon(); + set_size_hints(w); + XSelectInput(gXDisplay, gWindow->fScrollWindow, PointerMotionMask); + XSelectInput(gXDisplay, gWindow->fMainWindow, StructureNotifyMask | PointerMotionMask); + XDefineCursor(gXDisplay, gWindow->fMainWindow, gNormalCursor); +} + +/*** + This routine gets and sets the size for a new window. If the w paramter + is null, it means that this is the initial window. Thus the user + preferences are checked. If this is not the first window, then the + window w is used as a guidline, and the new window is placed on top of + it. + ***/ + +static void +set_size_hints(Window w) +{ + int x, y; + unsigned int width, height; + char userdefaults[50]; + char progdefaults[50]; + char *str_type[50]; + unsigned int fwidth = 0, fheight = 0; + unsigned int xadder = 0, yadder = 0; + int geo = 0; /* return flag from XGetGeometry */ + unsigned int depth, bw=0; + Window root; + XSizeHints size_hints; + XPoint xp; + XrmValue value; + + size_hints.flags = 0; + + strcpy(progdefaults, "=600x450+0+0"); + + if (w) { + /* + * The window should be queried for it's size and position. Then the + * new window should be given almost the same locations + */ + + if (XGetGeometry(gXDisplay, w, &root, &x, &y, &width, &height, &bw, &depth)) + { + xp = getWindowPositionXY(gXDisplay, w); + x = xp.x + 40; + y = xp.y + 40; + if (x < 0) + x = 0; + if (y < 0) + y = 0; + size_hints.flags |= (USSize | USPosition); + } + else { + fprintf(stderr, "(HyperDoc) Error Querying window configuration: %ld.\n", w); + x = y = 0; + width = 600; + height = 450; + size_hints.flags |= (PSize | PPosition); + } + } + else { + /* this is the first window, so lets try to find a nice spot for it */ + + if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.Geometry", "OpenAxiom.hyperdoc.Geometry", + str_type, &value) == True) + { + strncpy(userdefaults, value.addr, (int) value.size); + geo = XParseGeometry(userdefaults, &x, &y, &width, &height); + } + else + strcpy(userdefaults, progdefaults); + + size_hints.flags |= (geo & (WidthValue | HeightValue)) ? USSize : PSize; + size_hints.flags |= (geo & (XValue | YValue)) ? USPosition : PPosition; + + geo = XGeometry(gXDisplay, gXScreenNumber, userdefaults, progdefaults, + bw, fwidth, fheight, xadder, yadder, + &x, &y, (int *)&width, (int *)&height); + } + + size_hints.x = x; + size_hints.y = y; + size_hints.width = width; + size_hints.height = height; + + getTitleBarMinimumSize(&(size_hints.min_width), &(size_hints.min_height)); +#if 0 + size_hints.min_width = MIN_WINDOW_SIZE; + size_hints.min_height = MIN_WINDOW_SIZE; +#endif + size_hints.flags |= PMinSize; + + XSetNormalHints(gXDisplay, gWindow->fMainWindow, &size_hints); + /* just in case a hint isn't enough ... */ + XFlush(gXDisplay); +/* XMoveResizeWindow(gXDisplay, gWindow->fMainWindow, x, y, width, height); */ +} + +#define stipple_width 4 +#define stipple_height 4 +static char stipple_bits[] = { + 0xff, 0xff, 0xff, 0xff}; +Pixmap stipple; + +/* Create the graphics contexts to be used for all drawing operations */ + +static void +get_GCs(HDWindow *window) +{ + /*unsigned long valuemask = 0;*/ + XGCValues values; + + values.background = gBackgroundColor; + window->fStandardGC = XCreateGC(gXDisplay, window->fMainWindow, GCBackground, &values); + + XSetLineAttributes(gXDisplay, window->fStandardGC, window->border_width, + LineSolid, CapButt, JoinMiter); + + + /* create the stipple for the gc */ + + stipple = XCreateBitmapFromData(gXDisplay, + RootWindow(gXDisplay, gXScreenNumber), + stipple_bits, stipple_width, stipple_height); + + values.background = gInputBackgroundColor; + values.foreground = gInputForegroundColor; + + values.font = gInputFont->fid; + + if (values.font == server_font ) + window->fInputGC = XCreateGC(gXDisplay, window->fMainWindow, + GCBackground | GCForeground, &values); + else { + window->fInputGC = XCreateGC(gXDisplay, window->fMainWindow, + GCBackground | GCForeground | GCFont, &values); + } + + window->fCursorGC = XCreateGC(gXDisplay, window->fMainWindow, 0, NULL); + + if (values.font != server_font) + XSetFont(gXDisplay, window->fCursorGC, gInputFont->fid); + + XSetBackground(gXDisplay, window->fCursorGC, gInputForegroundColor); + XSetForeground(gXDisplay, window->fCursorGC, gInputBackgroundColor); + + window->fControlGC = XCreateGC(gXDisplay, window->fMainWindow, 0, NULL); + XSetBackground(gXDisplay, window->fControlGC, gControlBackgroundColor); + XSetForeground(gXDisplay, window->fControlGC, gControlForegroundColor); +} + +/* Load a font and store the information in the font_info parameter */ + +static void +load_font(XFontStruct **font_info, char *fontname) +{ + if ((*font_info = XLoadQueryFont(gXDisplay, fontname)) == NULL) { + fprintf(stderr, "(HyperDoc) Cannot load font %s ; using default.\n", + fontname); + + if ((*font_info = XQueryFont(gXDisplay, + XGContextFromGC(DefaultGC(gXDisplay, gXScreenNumber)))) == NULL) + { + fprintf(stderr, "(HyperDoc) Cannot get default font ; exiting.\n"); + exit(-1); + } + } +} + + +/* + * This routine initializes all the colors and fonts that the user wishes to + * use. It checks for all the following properties in $HOME/.Xdefaults. + * + * OpenAxiom.hyperdoc.ActiveColor: + * OpenAxiom.hyperdoc.Background: + * OpenAxiom.hyperdoc.EmphasizeColor: + * OpenAxiom.hyperdoc.EmphasizeFont: + * OpenAxiom.hyperdoc.Foreground: + * OpenAxiom.hyperdoc.InputBackground: + * OpenAxiom.hyperdoc.InputForeground: + * OpenAxiom.hyperdoc.SpadColor: + * OpenAxiom.hyperdoc.SpadFont: + */ + +static void +ingItColors_and_fonts(void) +{ + char property[256]; + char *prop = &property[0]; + char *str_type[50]; + XrmValue value; + Colormap cmap; + int ts; + + /** get the color map for the display **/ +/* fprintf(stderr,"initx:ingItColors_and_fonts:entered\n");*/ + +/* fprintf(stderr,"initx:ingItColors_and_fonts:DefaultColorMap\n");*/ + cmap = DefaultColormap(gXDisplay, gXScreenNumber); + +/* fprintf(stderr,"initx:ingItColors_and_fonts:init_group_stack\n");*/ + init_group_stack(); + + + /** then start getting the fonts **/ + +/* fprintf(stderr,"initx:ingItColors_and_fonts:mergeDatabases\n");*/ + mergeDatabases(); + +/* fprintf(stderr,"initx:ingItColors_and_fonts:XrmGetResource\n");*/ + if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.RmFont", + "OpenAxiom.hyperdoc.Font", str_type, &value) == True) + (void) strncpy(prop, value.addr, (int) value.size); + else + (void) strcpy(prop, RmFontDefault); + +/* fprintf(stderr,"initx:ingItColors_and_fonts:load_font 1\n");*/ + load_font(&gRmFont, prop); +/* fprintf(stderr,"initx:ingItColors_and_fonts:load_font 2\n");*/ + load_font(&gInputFont, prop); + + +/* fprintf(stderr,"initx:ingItColors_and_fonts:XrmGetResource 2\n");*/ + if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.TtFont", + "OpenAxiom.hyperdoc.Font", str_type, &value) == True) + (void) strncpy(prop, value.addr, (int) value.size); + else + (void) strcpy(prop, TtFontDefault); + +/* fprintf(stderr,"initx:ingItColors_and_fonts:load_font 3\n");*/ + load_font(&gTtFont, prop); +/* fprintf(stderr,"initx:ingItColors_and_fonts:is_it_850\n");*/ + gTtFontIs850=is_it_850(gTtFont); + +/* fprintf(stderr,"initx:ingItColors_and_fonts:XrmGetResource 5\n");*/ + if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.ActiveFont", + "OpenAxiom.hyperdoc.Font", str_type, &value) == True) + (void) strncpy(prop, value.addr, (int) value.size); + else + (void) strcpy(prop, ActiveFontDefault); + +/* fprintf(stderr,"initx:ingItColors_and_fonts:load_font 4\n");*/ + load_font(&gActiveFont, prop); + + /* maintain backwards compatibility */ + +/* fprintf(stderr,"initx:ingItColors_and_fonts:XrmGetResource 6\n");*/ + if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.AxiomFont", + "OpenAxiom.hyperdoc.Font", str_type, &value) == True) + (void) strncpy(prop, value.addr, (int) value.size); + else { + if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.SpadFont", + "OpenAxiom.hyperdoc.Font", str_type, &value) == True) + { + (void) strncpy(prop, value.addr, (int) value.size); + } + else { + (void) strcpy(prop, AxiomFontDefault); + } + } + +/* fprintf(stderr,"initx:ingItColors_and_fonts:load_font 5\n");*/ + load_font(&gAxiomFont, prop); + +/* fprintf(stderr,"initx:ingItColors_and_fonts:XrmGetResource 7\n");*/ + if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.EmphasizeFont", + "OpenAxiom.hyperdoc.Font", str_type, &value) == True) + { + (void) strncpy(prop, value.addr, (int) value.size); + } + else { + (void) strcpy(prop, EmphasizeFontDefault); + } +/* fprintf(stderr,"initx:ingItColors_and_fonts:load_font 6\n");*/ + load_font(&gEmFont, prop); + +/* fprintf(stderr,"initx:ingItColors_and_fonts:XrmGetResource 8\n");*/ + if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.BoldFont", + "OpenAxiom.hyperdoc.Font", str_type, &value) == True) + { + (void) strncpy(prop, value.addr, (int) value.size); + } + else { + (void) strcpy(prop, BoldFontDefault); + } +/* fprintf(stderr,"initx:ingItColors_and_fonts:load_font 7\n");*/ + load_font(&gBfFont, prop); + + + /* + * If we are on a monochrome screen, then we ignore user preferences, and + * set the foreground and background as I wish + */ + +/* fprintf(stderr,"initx:ingItColors_and_fonts:DisplayPlanes\n");*/ + if (DisplayPlanes(gXDisplay, gXScreenNumber) == 1) { + gActiveColor = gAxiomColor + = gControlBackgroundColor + = gInputBackgroundColor + = gBfColor + = gEmColor + = gRmColor + = gSlColor + = gTtColor + = BlackPixel(gXDisplay, gXScreenNumber); + + gBackgroundColor = gInputForegroundColor + = gControlForegroundColor + = WhitePixel(gXDisplay, gXScreenNumber); + } + else { + + /* + * If I have gotten here, then we must be on a color screen, so see + * what the user likes, and set it up + */ + +/* fprintf(stderr,"initx:ingItColors_and_fonts:get_color 1\n");*/ + gRmColor = + get_color("RmColor", "Foreground", + BlackPixel(gXDisplay, gXScreenNumber), &cmap); +/* fprintf(stderr,"initx:ingItColors_and_fonts:get_color 2\n");*/ + gBackgroundColor = + get_color("Background", "Background", + WhitePixel(gXDisplay, gXScreenNumber), &cmap); +/* fprintf(stderr,"initx:ingItColors_and_fonts:get_color 3\n");*/ + gActiveColor = + get_color("ActiveColor", "Foreground", + BlackPixel(gXDisplay, gXScreenNumber), &cmap); + + /* + * for next two, I want name arg = class arg, ie do not want + * Background and Foreground. + */ + +/* fprintf(stderr,"initx:ingItColors_and_fonts:get_color 4\n");*/ + gControlBackgroundColor = get_color("ControlBackground", + "ControlBackground", WhitePixel(gXDisplay, gXScreenNumber), &cmap); +/* fprintf(stderr,"initx:ingItColors_and_fonts:get_color 5\n");*/ + gControlForegroundColor = get_color("ControlForeground", + "ControlForeground", BlackPixel(gXDisplay, gXScreenNumber), &cmap); + + /* maintain backwards compatibility */ + +/* fprintf(stderr,"initx:ingItColors_and_fonts:get_color 6\n");*/ + gAxiomColor = get_color("OpenAxiomColor", "Foreground", 0, &cmap); +/* fprintf(stderr,"initx:ingItColors_and_fonts:get_color 7\n");*/ + if (gAxiomColor == 0) + gAxiomColor = get_color("SpadColor", "Foreground", + BlackPixel(gXDisplay, gXScreenNumber), &cmap); + +/* fprintf(stderr,"initx:ingItColors_and_fonts:get_color 8\n");*/ + gInputBackgroundColor = + get_color("InputBackground", "Foreground", gRmColor, &cmap); +/* fprintf(stderr,"initx:ingItColors_and_fonts:get_color 9\n");*/ + gInputForegroundColor = + get_color("InputForeground", "Background", gBackgroundColor, &cmap); + +/* fprintf(stderr,"initx:ingItColors_and_fonts:get_color 10\n");*/ + gEmColor = + get_color("EmphasizeColor", "Foreground", gRmColor, &cmap); +/* fprintf(stderr,"initx:ingItColors_and_fonts:get_color 11\n");*/ + gTtColor = + get_color("TtColor", "Foreground", gRmColor, &cmap); +/* fprintf(stderr,"initx:ingItColors_and_fonts:get_color 12\n");*/ + gSlColor = + get_color("EmphasizeColor", "Foreground", gRmColor, &cmap); +/* fprintf(stderr,"initx:ingItColors_and_fonts:get_color 13\n");*/ + gBfColor = + get_color("BoldColor", "Foreground", gRmColor, &cmap); + } + +/* fprintf(stderr,"initx:ingItColors_and_fonts:makeColors\n");*/ + makeColors(gXDisplay, gXScreenNumber, &cmap, &spadColors, &ts); + /* + * Now set the current color and font, so I never have to do it again + */ + + gTopOfGroupStack->cur_color = gRmColor; + gTopOfGroupStack->cur_font = gRmFont; +/* fprintf(stderr,"initx:ingItColors_and_fonts:exited\n");*/ +} + +void +change_text(int color, XFontStruct *font) +{ + if (font) { + XGCValues gcv; + gcv.foreground = color; + gcv.background = gBackgroundColor; + + XChangeGC(gXDisplay, gWindow->fStandardGC, GCForeground | GCBackground , &gcv); + + if (font->fid != server_font) + XSetFont(gXDisplay, gWindow->fStandardGC, font->fid); + } +} + +/* + * This routine checks the .Xdefaults file of the user for the + * specified color. If found it allocates a place in the color map for it. If + * not found, or if an error occurrs, it writes an error message, and + * uses the given default value + */ + +static int +get_color(char *name, char *class, int def, Colormap *map) +{ + char fullname[256]; + char fullclass[256]; + char property[256]; + char *prop = &property[0]; + char *str_type[50]; + XrmValue value; + int ret_val; + XColor color_def, color_db; + +#ifdef DEBUG + printf("get_color: %s %s %d -> ", name, class, def); +#endif + + strcpy(fullname, "OpenAxiom.hyperdoc."); + strcat(fullname, name); + strcpy(fullclass,"OpenAxiom.hyperdoc."); + strcat(fullclass,class); + + if (XrmGetResource(rDB, fullname, fullclass, str_type, &value) == True) { + (void) strncpy(prop, value.addr, (int) value.size); + ret_val = XAllocNamedColor(gXDisplay, *map, prop, &color_def, &color_db); + if (ret_val) { +#ifdef DEBUG + printf("%d\n", color_def.pixel); +#endif + return (color_def.pixel); + } + else { + fprintf(stderr, + "(HyperDoc) Defaulting on color for %s. Unknown color is %s.\n", + name, prop); +#ifdef DEBUG + printf("%d\n", def); +#endif + return (def); + } + } + else { +#ifdef DEBUG + printf("%d\n", def); +#endif + return (def); + } +} + + +static void +mergeDatabases(void) +{ + XrmDatabase homeDB, serverDB, applicationDB; + char filenamebuf[1024]; + char *filename = &filenamebuf[0]; + char *classname = "OpenAxiom"; + char name[255]; + +/* fprintf(stderr,"initx:mergeDatabases:entered\n");*/ +/* fprintf(stderr,"initx:mergeDatabases:XrmInitialize\n");*/ + (void) XrmInitialize(); + (void) strcpy(name, "/usr/lib/X11/app-defaults/"); + (void) strcat(name, classname); +/* fprintf(stderr,"initx:mergeDatabases:XrmGetFileDatabase name=%s\n",name);*/ + applicationDB = XrmGetFileDatabase(name); +/* fprintf(stderr,"initx:mergeDatabases:XrmMergeDatabases\n");*/ + (void) XrmMergeDatabases(applicationDB, &rDB); + +/* fprintf(stderr,"initx:mergeDatabases:XrmGetStringDatabase\n");*/ + if (XResourceManagerString(gXDisplay) != NULL) { + serverDB = XrmGetStringDatabase(XResourceManagerString(gXDisplay)); + } + else { + (void) strcpy(filename, getenv("HOME")); + (void) strcat(filename, "/.Xdefaults"); +/* fprintf(stderr,"initx:mergeDatabases:XrmGetFileDatase\n");*/ + serverDB = XrmGetFileDatabase(filename); + } +/* fprintf(stderr,"initx:mergeDatabases:XrmMergeDatabases 2\n");*/ + XrmMergeDatabases(serverDB, &rDB); + if (getenv("XENVIRONMENT") == NULL) { + int len; + + (void) strcpy(filename, getenv("HOME")); + (void) strcat(filename, "/.Xdefaults-"); + len = strlen(filename); + (void) gethostname(filename + len, 1024 - len); + } + else { + (void) strcpy(filename, getenv("XENVIRONMENT")); + } +/* fprintf(stderr,"initx:mergeDatabases:filename=%s\n",filename);*/ + homeDB = XrmGetFileDatabase(filename); +/* fprintf(stderr,"initx:mergeDatabases:XrmMergeDatabases 3\n");*/ + XrmMergeDatabases(homeDB, &rDB); +} + + + +int +is_it_850(XFontStruct *fontarg) +{ + char *s; + int i,val; + static struct { + char *name; + Atom format; + Atom atom; + } proptbl = { "CHARSET_ENCODING", XA_ATOM }; + proptbl.atom = XInternAtom(gXDisplay,proptbl.name,0); + for (i=0;in_properties;i++) + { + if (fontarg->properties[i].name != proptbl.atom) continue; + + +/* return 1 if it is 850 */ + + s = XGetAtomName(gXDisplay,(Atom)fontarg->properties[i].card32); + val = !( strcmp("850",s) * strcmp("ibm-850",s)); + XFree(s); + return( val ); + } + return(0); +} + diff --git a/src/hyper/initx.h b/src/hyper/initx.h new file mode 100644 index 00000000..7533fe78 --- /dev/null +++ b/src/hyper/initx.h @@ -0,0 +1,43 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +#ifndef _INITX_H_ +#define _INITX_H_ 1 + +#include "hyper.h" + +extern int gBorderColor; + +#endif diff --git a/src/hyper/initx.pamphlet b/src/hyper/initx.pamphlet deleted file mode 100644 index 1efef762..00000000 --- a/src/hyper/initx.pamphlet +++ /dev/null @@ -1,1058 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/initx} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{initx.h} -<>= -<> -#ifndef _INITX_H_ -#define _INITX_H_ 1 - -#include "hyper.h" - -extern int gBorderColor; - -#endif -@ -\section{initx.c} -<>= -/**************************************************************** - * - * initx.h: HyperDoc X Window window initialization code - * - * Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993. - * - ****************************************************************************/ - -/* #define DEBUG 1 */ - -#define _INITX_C -#include "axiom-c-macros.h" -#include "useproto.h" -#include "debug.h" - -#include "initx.h" - -#include -#include -#include -#include -#include -#include - -#ifdef SUN4OS5platform -extern int gethostname(char *, int ); -#endif - -#include "ht_icon" -#include "extent.h" -#include "group.h" -#include "mem.h" -#include "scrollbar.h" -#include "titlebar.h" - -#include "all_hyper_proto.H1" -#include "util.H1" - -#include "spadcolors.h" -#include "spadcolors.H1" - - -#include "mouse11.bitmap" -#include "mouse11.mask" - - -static GContext server_font; -unsigned long *spadColors; -int scrn; /* used in spad_colors */ - -extern int received_window_request; /* true iff Spad wants a pop-up */ -extern int in_next_event; /* true when in XNextEvent */ - -extern int gTtFontIs850; - -#define MIN_WINDOW_SIZE 300 - - -int gActiveColor, - gAxiomColor, - gBackgroundColor, - gBfColor, - gControlBackgroundColor, - gControlForegroundColor, - gEmColor, - gInputBackgroundColor, - gInputForegroundColor, - gItColor, - gRmColor, - gSlColor, - gTtColor; - -XFontStruct *gAxiomFont, - *gActiveFont, - *gBfFont, - *gEmFont, - *gInputFont, - *gItFont, - *gRmFont, - *gSlFont, - *gTitleFont, - *gTtFont; - -XrmDatabase rDB; -int gBorderColor; /* The Border Color */ - -/* Initialize the X Window System */ - -void -initializeWindowSystem(void) -{ - char *display_name = NULL; - XColor fg, bg; -#if 0 - XColor rgbdef; -#endif - Colormap cmap; - Pixmap mousebits, mousemask; -/* fprintf(stderr,"initx:initializeWindowSystem:entered\n");*/ - /* Try to open the display */ -/* fprintf(stderr,"initx:initializeWindowSystem:XOpenDisplay\n");*/ - if ((gXDisplay = XOpenDisplay(display_name)) == NULL) { - fprintf(stderr, "(HyperDoc) Cannot connect to the X11 server!\n"); - exit(-1); - } - - /* Get the screen */ -/* fprintf(stderr,"initx:initializeWindowSystem:DefaultScreen\n");*/ - gXScreenNumber = scrn = DefaultScreen(gXDisplay); -/* fprintf(stderr,"initx:initializeWindowSystem:XGContextFromGC\n");*/ - server_font =XGContextFromGC(DefaultGC(gXDisplay, gXScreenNumber)); - - /* Get the cursors we need. */ - -/* fprintf(stderr,"initx:initializeWindowSystem:DefaultColormap\n");*/ - cmap = DefaultColormap(gXDisplay, gXScreenNumber); -/* fprintf(stderr,"initx:initializeWindowSystem:WhitePixel\n");*/ - fg.pixel = WhitePixel(gXDisplay,gXScreenNumber); -/* fprintf(stderr,"initx:initializeWindowSystem:XQueryColor\n");*/ - XQueryColor(gXDisplay, cmap, &fg ); -/* fprintf(stderr,"initx:initializeWindowSystem:BlackPixel\n");*/ - bg.pixel = BlackPixel(gXDisplay,gXScreenNumber); -/* fprintf(stderr,"initx:initializeWindowSystem:XQueryColor2\n");*/ - XQueryColor(gXDisplay, cmap, &bg ); -#if 0 - XAllocNamedColor(gXDisplay, cmap, "Black", &fg, &rgbdef); - XAllocNamedColor(gXDisplay, cmap, "White", &bg, &rgbdef); -#endif - -#ifdef USE_BORING_OLD_CURSORS - gActiveCursor = XCreateFontCursor(gXDisplay, XC_circle); - gNormalCursor = XCreateFontCursor(gXDisplay, XC_dot); -#else -/* fprintf(stderr,"initx:initializeWindowSystem:XCreateBitmapFromData 1\n");*/ - mousebits = XCreateBitmapFromData(gXDisplay, - RootWindow(gXDisplay, gXScreenNumber), - mouseBitmap_bits, mouseBitmap_width,mouseBitmap_height); -/* fprintf(stderr,"initx:initializeWindowSystem:XCreateBitmapFromData 2\n");*/ - mousemask = XCreateBitmapFromData(gXDisplay, - RootWindow(gXDisplay, gXScreenNumber), - mouseMask_bits, mouseMask_width,mouseMask_height); -/* fprintf(stderr,"initx:initializeWindowSystem:XCreateBitmapFromData 2\n");*/ - gActiveCursor = XCreatePixmapCursor(gXDisplay, - mousebits, mousemask, &fg, &bg, - mouseBitmap_x_hot,mouseBitmap_y_hot); - -/* fprintf(stderr,"initx:initializeWindowSystem:XCreateFontCursor\n");*/ - gNormalCursor = XCreateFontCursor(gXDisplay, XC_left_ptr); -#endif - -/* fprintf(stderr,"initx:initializeWindowSystem:XCreateFontCursor 2\n");*/ - gBusyCursor = XCreateFontCursor(gXDisplay, XC_watch); - - /* Now initialize all the colors and fonts */ - -/* fprintf(stderr,"initx:initializeWindowSystem:ingItColors_and_fonts\n");*/ - ingItColors_and_fonts(); -/* fprintf(stderr,"initx:initializeWindowSystem:init_text\n");*/ - init_text(); -/* fprintf(stderr,"initx:initializeWindowSystem:exited\n");*/ - -} - -/* - * This routine is responsible for initializing a HyperDoc Window. At this - * point, all the fonts have been loaded, and X has been initialized. All I - * need worry about is starting up the window, and creating some of its - * children. - */ - - -/* - * init_top_window tries to start up a window with the page name. If the - * page name is NULL, - * it doesn't try to find it in the Hash Table, but rather just allocates a - * page of no name - */ - -int -init_top_window(char *name) -{ - HyperDocPage *page; - XSetWindowAttributes wa; /* The X attributes structure */ - HDWindow *old_win = gWindow; - - gWindow = alloc_hd_window(); - - if (name == NULL) { - /** Then allocate an empty page, and assign it to gWindow->page */ - page = alloc_page((char *) NULL); - } - else { - /* Try to find the page in the page hash table */ - page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, name); - if (page == NULL) { - fprintf(stderr, "(HyperDoc) Couldn\'t find page %s in page hash table \n", - name); - if (gParentWindow == NULL) - /* Gaak, This is a start up error */ - exit(-1); - else { - gWindow = old_win; - return -1; - } - } - } - - /* First allocate memory for the new window structure */ - gWindow->page = page; - - if (old_win == NULL) - open_window(0); - else - open_window(old_win->fMainWindow); - - get_GCs(gWindow); - XMapWindow(gXDisplay, gWindow->fMainWindow); - hash_insert(&gSessionHashTable, (char *)gWindow,(char *) &gWindow->fMainWindow); - - change_text(gRmColor, gRmFont); - wa.background_pixel = gBackgroundColor; - XChangeWindowAttributes(gXDisplay, gWindow->fMainWindow, CWBackPixel, &wa); - XChangeWindowAttributes(gXDisplay, gWindow->fScrollWindow, CWBackPixel,&wa); - return 1; -} - -/* Create and initialize a form HyperDoc window */ - -static void -open_form_window(void) -{ - int x, y, width, height; - unsigned int fwidth = 0, fheight = 0; - unsigned int xadder = 0, yadder = 0; - /*char *window_name = "HyperDoc";*/ - /*char *icon_name = "HT";*/ - XrmValue value; - char *str_type[50]; - XSizeHints size_hints; - int userSpecified = 0; - - char userdefaults[50], progdefaults[50]; - - strcpy(progdefaults, "=950x450+0+0"); - if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.FormGeometry", - "OpenAxiom.hyperdoc.FormGeometry", str_type, &value) == True) - { - strncpy(userdefaults, value.addr, (int) value.size); - userSpecified = 1; - } - else - strcpy(userdefaults, progdefaults); - - XGeometry(gXDisplay, gXScreenNumber, userdefaults, progdefaults, - 0, fwidth, fheight, xadder, yadder, - &x, &y, &width, &height); - - gWindow->border_width = get_border_properties(); - - gWindow->width = 1; - gWindow->height = 1; - - gWindow->fMainWindow = XCreateSimpleWindow(gXDisplay, RootWindow(gXDisplay, gXScreenNumber), - x, y, width, height, gWindow->border_width, - gBorderColor, - WhitePixel(gXDisplay, gXScreenNumber)); - gWindow->fScrollWindow = XCreateSimpleWindow(gXDisplay, gWindow->fMainWindow, - 1, 1, 1, 1, 0, - BlackPixel(gXDisplay, gXScreenNumber), - WhitePixel(gXDisplay, gXScreenNumber)); - makeScrollBarWindows(); - makeTitleBarWindows(); - - set_name_and_icon(); - - XSelectInput(gXDisplay, gWindow->fScrollWindow, PointerMotionMask); - XSelectInput(gXDisplay, gWindow->fMainWindow, StructureNotifyMask | PointerMotionMask); - XDefineCursor(gXDisplay, gWindow->fMainWindow, gNormalCursor); - - /* now give the window manager some hints */ - - size_hints.flags = 0; - - size_hints.min_width = width; - size_hints.min_height = height; - size_hints.flags |= PMinSize; - - size_hints.width = width; - size_hints.height = height; - size_hints.flags |= (userSpecified ? USSize : PSize); - - size_hints.x = x; - size_hints.y = y; - size_hints.flags |= (userSpecified ? USPosition : PPosition); - - XSetNormalHints(gXDisplay, gWindow->fMainWindow, &size_hints); - XFlush(gXDisplay); -} - - -int -init_form_window(char *name, int cols) -{ - XSetWindowAttributes wa; /* The X attributes structure */ - - /* First allocate memory for the new window structure */ - - gWindow = alloc_hd_window(); - open_form_window(); - gWindow->width = window_width(cols); - - if (name == NULL) { - /** Then allocate an empty page, and assign it to gWindow->page */ - gWindow->page = alloc_page((char *) NULL); - } - else { - /* Try to find the page in the page hash table */ - gWindow->page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, name); - if (gWindow->page == NULL) { - fprintf(stderr, "Couldn't find page %s\n", name); - return (-1); - } - } - - get_GCs(gWindow); - hash_insert(&gSessionHashTable, (char *)gWindow,(char *) &gWindow->fMainWindow); - - wa.background_pixel = gBackgroundColor; - XChangeWindowAttributes(gXDisplay, gWindow->fMainWindow, CWBackPixel, &wa); - XChangeWindowAttributes(gXDisplay, gWindow->fScrollWindow, CWBackPixel,&wa); - return 1; -} - - -static void -set_name_and_icon(void) -{ - char *icon_name = "HyperDoc"; - char *s; - Pixmap icon_pixmap; - XWMHints wmhints; - XClassHint ch; - - ch.res_name = "HyperDoc"; - ch.res_class = gArgv[0]; - for (s = gArgv[0] + strlen(gArgv[0]) - 1; s != gArgv[0]; s--) { - if (*s == '/') { - ch.res_class = s + 1; - break; - } - } - XSetClassHint(gXDisplay, gWindow->fMainWindow, &ch); - - XStoreName(gXDisplay, gWindow->fMainWindow, "HyperDoc"); - - /* define and assign the pixmap for the icon */ - icon_pixmap = XCreateBitmapFromData(gXDisplay, gWindow->fMainWindow, ht_icon_bits, - ht_icon_width, ht_icon_height); - wmhints.icon_pixmap = icon_pixmap; - wmhints.flags = IconPixmapHint; - - XSetWMHints(gXDisplay, gWindow->fMainWindow, &wmhints); - - /* name the icon */ - XSetIconName(gXDisplay, gWindow->fMainWindow, icon_name); -} - -static int -get_border_properties(void) -{ - char *bwidth; - /*char *bc = NULL;*/ - int bw; - /*XColor color_def, color_db;*/ - Colormap cmap; - /*int ret_val;*/ - - - bwidth = "2"; /* XGetDefault(gXDisplay, "Axiom.hyperdoc", "BorderWidth") */ - - if (bwidth == NULL) - bw = 1; - else { - bw = atoi(bwidth); - if (bw < 1) { - fprintf(stderr, - "%s: The line width value must be greater than zero\n", "OpenAxiom.hyperdoc"); - bw = 1; - } - } - - /* Now try to find the user preferred border color */ - - if (DisplayPlanes(gXDisplay, gXScreenNumber) == 1) - gBorderColor = BlackPixel(gXDisplay, gXScreenNumber); - else { - cmap = DefaultColormap(gXDisplay, gXScreenNumber); - gBorderColor = get_color("BorderColor", "Foreground", - BlackPixel(gXDisplay, gXScreenNumber), &cmap); - } - return bw; -} - - -/* Create and initialize the HyperDoc window */ - -static void -open_window(Window w) -{ - int x = 0, y = 0; - /*int border_width = 2;*/ - unsigned int width = 1; - unsigned int height = 1; - unsigned int fwidth = 0, fheight = 0; - unsigned int xadder = 0, yadder = 0; - char *str_type[50]; - XrmValue value; - - char userdefaults[50], progdefaults[50]; - - strcpy(progdefaults, "=700x450+0+0"); - if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.Geometry", - "OpenAxiom.hyperdoc.Geometry", str_type, &value) == True) - { - strncpy(userdefaults, value.addr, (int) value.size); - } - else - strcpy(userdefaults, progdefaults); - - XGeometry(gXDisplay, gXScreenNumber, userdefaults, progdefaults, - 0, fwidth, fheight, xadder, yadder, - &x, &y, ( int *)&width,( int *) &height); - - gWindow->border_width = get_border_properties(); - - gWindow->fMainWindow = XCreateSimpleWindow(gXDisplay, RootWindow(gXDisplay, gXScreenNumber), - x, y, width, height, gWindow->border_width, - gBorderColor, - WhitePixel(gXDisplay, gXScreenNumber)); - - gWindow->fScrollWindow = XCreateSimpleWindow(gXDisplay, gWindow->fMainWindow, - 1, 1, 1, 1, 0, - gBorderColor, - WhitePixel(gXDisplay, gXScreenNumber)); - - - makeScrollBarWindows(); - makeTitleBarWindows(); - - /* Now set all the little properties for the top level window */ - - set_name_and_icon(); - set_size_hints(w); - XSelectInput(gXDisplay, gWindow->fScrollWindow, PointerMotionMask); - XSelectInput(gXDisplay, gWindow->fMainWindow, StructureNotifyMask | PointerMotionMask); - XDefineCursor(gXDisplay, gWindow->fMainWindow, gNormalCursor); -} - -/*** - This routine gets and sets the size for a new window. If the w paramter - is null, it means that this is the initial window. Thus the user - preferences are checked. If this is not the first window, then the - window w is used as a guidline, and the new window is placed on top of - it. - ***/ - -static void -set_size_hints(Window w) -{ - int x, y; - unsigned int width, height; - char userdefaults[50]; - char progdefaults[50]; - char *str_type[50]; - unsigned int fwidth = 0, fheight = 0; - unsigned int xadder = 0, yadder = 0; - int geo = 0; /* return flag from XGetGeometry */ - unsigned int depth, bw=0; - Window root; - XSizeHints size_hints; - XPoint xp; - XrmValue value; - - size_hints.flags = 0; - - strcpy(progdefaults, "=600x450+0+0"); - - if (w) { - /* - * The window should be queried for it's size and position. Then the - * new window should be given almost the same locations - */ - - if (XGetGeometry(gXDisplay, w, &root, &x, &y, &width, &height, &bw, &depth)) - { - xp = getWindowPositionXY(gXDisplay, w); - x = xp.x + 40; - y = xp.y + 40; - if (x < 0) - x = 0; - if (y < 0) - y = 0; - size_hints.flags |= (USSize | USPosition); - } - else { - fprintf(stderr, "(HyperDoc) Error Querying window configuration: %ld.\n", w); - x = y = 0; - width = 600; - height = 450; - size_hints.flags |= (PSize | PPosition); - } - } - else { - /* this is the first window, so lets try to find a nice spot for it */ - - if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.Geometry", "OpenAxiom.hyperdoc.Geometry", - str_type, &value) == True) - { - strncpy(userdefaults, value.addr, (int) value.size); - geo = XParseGeometry(userdefaults, &x, &y, &width, &height); - } - else - strcpy(userdefaults, progdefaults); - - size_hints.flags |= (geo & (WidthValue | HeightValue)) ? USSize : PSize; - size_hints.flags |= (geo & (XValue | YValue)) ? USPosition : PPosition; - - geo = XGeometry(gXDisplay, gXScreenNumber, userdefaults, progdefaults, - bw, fwidth, fheight, xadder, yadder, - &x, &y, (int *)&width, (int *)&height); - } - - size_hints.x = x; - size_hints.y = y; - size_hints.width = width; - size_hints.height = height; - - getTitleBarMinimumSize(&(size_hints.min_width), &(size_hints.min_height)); -#if 0 - size_hints.min_width = MIN_WINDOW_SIZE; - size_hints.min_height = MIN_WINDOW_SIZE; -#endif - size_hints.flags |= PMinSize; - - XSetNormalHints(gXDisplay, gWindow->fMainWindow, &size_hints); - /* just in case a hint isn't enough ... */ - XFlush(gXDisplay); -/* XMoveResizeWindow(gXDisplay, gWindow->fMainWindow, x, y, width, height); */ -} - -#define stipple_width 4 -#define stipple_height 4 -static char stipple_bits[] = { - 0xff, 0xff, 0xff, 0xff}; -Pixmap stipple; - -/* Create the graphics contexts to be used for all drawing operations */ - -static void -get_GCs(HDWindow *window) -{ - /*unsigned long valuemask = 0;*/ - XGCValues values; - - values.background = gBackgroundColor; - window->fStandardGC = XCreateGC(gXDisplay, window->fMainWindow, GCBackground, &values); - - XSetLineAttributes(gXDisplay, window->fStandardGC, window->border_width, - LineSolid, CapButt, JoinMiter); - - - /* create the stipple for the gc */ - - stipple = XCreateBitmapFromData(gXDisplay, - RootWindow(gXDisplay, gXScreenNumber), - stipple_bits, stipple_width, stipple_height); - - values.background = gInputBackgroundColor; - values.foreground = gInputForegroundColor; - - values.font = gInputFont->fid; - - if (values.font == server_font ) - window->fInputGC = XCreateGC(gXDisplay, window->fMainWindow, - GCBackground | GCForeground, &values); - else { - window->fInputGC = XCreateGC(gXDisplay, window->fMainWindow, - GCBackground | GCForeground | GCFont, &values); - } - - window->fCursorGC = XCreateGC(gXDisplay, window->fMainWindow, 0, NULL); - - if (values.font != server_font) - XSetFont(gXDisplay, window->fCursorGC, gInputFont->fid); - - XSetBackground(gXDisplay, window->fCursorGC, gInputForegroundColor); - XSetForeground(gXDisplay, window->fCursorGC, gInputBackgroundColor); - - window->fControlGC = XCreateGC(gXDisplay, window->fMainWindow, 0, NULL); - XSetBackground(gXDisplay, window->fControlGC, gControlBackgroundColor); - XSetForeground(gXDisplay, window->fControlGC, gControlForegroundColor); -} - -/* Load a font and store the information in the font_info parameter */ - -static void -load_font(XFontStruct **font_info, char *fontname) -{ - if ((*font_info = XLoadQueryFont(gXDisplay, fontname)) == NULL) { - fprintf(stderr, "(HyperDoc) Cannot load font %s ; using default.\n", - fontname); - - if ((*font_info = XQueryFont(gXDisplay, - XGContextFromGC(DefaultGC(gXDisplay, gXScreenNumber)))) == NULL) - { - fprintf(stderr, "(HyperDoc) Cannot get default font ; exiting.\n"); - exit(-1); - } - } -} - - -/* - * This routine initializes all the colors and fonts that the user wishes to - * use. It checks for all the following properties in $HOME/.Xdefaults. - * - * OpenAxiom.hyperdoc.ActiveColor: - * OpenAxiom.hyperdoc.Background: - * OpenAxiom.hyperdoc.EmphasizeColor: - * OpenAxiom.hyperdoc.EmphasizeFont: - * OpenAxiom.hyperdoc.Foreground: - * OpenAxiom.hyperdoc.InputBackground: - * OpenAxiom.hyperdoc.InputForeground: - * OpenAxiom.hyperdoc.SpadColor: - * OpenAxiom.hyperdoc.SpadFont: - */ - -static void -ingItColors_and_fonts(void) -{ - char property[256]; - char *prop = &property[0]; - char *str_type[50]; - XrmValue value; - Colormap cmap; - int ts; - - /** get the color map for the display **/ -/* fprintf(stderr,"initx:ingItColors_and_fonts:entered\n");*/ - -/* fprintf(stderr,"initx:ingItColors_and_fonts:DefaultColorMap\n");*/ - cmap = DefaultColormap(gXDisplay, gXScreenNumber); - -/* fprintf(stderr,"initx:ingItColors_and_fonts:init_group_stack\n");*/ - init_group_stack(); - - - /** then start getting the fonts **/ - -/* fprintf(stderr,"initx:ingItColors_and_fonts:mergeDatabases\n");*/ - mergeDatabases(); - -/* fprintf(stderr,"initx:ingItColors_and_fonts:XrmGetResource\n");*/ - if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.RmFont", - "OpenAxiom.hyperdoc.Font", str_type, &value) == True) - (void) strncpy(prop, value.addr, (int) value.size); - else - (void) strcpy(prop, RmFontDefault); - -/* fprintf(stderr,"initx:ingItColors_and_fonts:load_font 1\n");*/ - load_font(&gRmFont, prop); -/* fprintf(stderr,"initx:ingItColors_and_fonts:load_font 2\n");*/ - load_font(&gInputFont, prop); - - -/* fprintf(stderr,"initx:ingItColors_and_fonts:XrmGetResource 2\n");*/ - if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.TtFont", - "OpenAxiom.hyperdoc.Font", str_type, &value) == True) - (void) strncpy(prop, value.addr, (int) value.size); - else - (void) strcpy(prop, TtFontDefault); - -/* fprintf(stderr,"initx:ingItColors_and_fonts:load_font 3\n");*/ - load_font(&gTtFont, prop); -/* fprintf(stderr,"initx:ingItColors_and_fonts:is_it_850\n");*/ - gTtFontIs850=is_it_850(gTtFont); - -/* fprintf(stderr,"initx:ingItColors_and_fonts:XrmGetResource 5\n");*/ - if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.ActiveFont", - "OpenAxiom.hyperdoc.Font", str_type, &value) == True) - (void) strncpy(prop, value.addr, (int) value.size); - else - (void) strcpy(prop, ActiveFontDefault); - -/* fprintf(stderr,"initx:ingItColors_and_fonts:load_font 4\n");*/ - load_font(&gActiveFont, prop); - - /* maintain backwards compatibility */ - -/* fprintf(stderr,"initx:ingItColors_and_fonts:XrmGetResource 6\n");*/ - if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.AxiomFont", - "OpenAxiom.hyperdoc.Font", str_type, &value) == True) - (void) strncpy(prop, value.addr, (int) value.size); - else { - if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.SpadFont", - "OpenAxiom.hyperdoc.Font", str_type, &value) == True) - { - (void) strncpy(prop, value.addr, (int) value.size); - } - else { - (void) strcpy(prop, AxiomFontDefault); - } - } - -/* fprintf(stderr,"initx:ingItColors_and_fonts:load_font 5\n");*/ - load_font(&gAxiomFont, prop); - -/* fprintf(stderr,"initx:ingItColors_and_fonts:XrmGetResource 7\n");*/ - if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.EmphasizeFont", - "OpenAxiom.hyperdoc.Font", str_type, &value) == True) - { - (void) strncpy(prop, value.addr, (int) value.size); - } - else { - (void) strcpy(prop, EmphasizeFontDefault); - } -/* fprintf(stderr,"initx:ingItColors_and_fonts:load_font 6\n");*/ - load_font(&gEmFont, prop); - -/* fprintf(stderr,"initx:ingItColors_and_fonts:XrmGetResource 8\n");*/ - if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.BoldFont", - "OpenAxiom.hyperdoc.Font", str_type, &value) == True) - { - (void) strncpy(prop, value.addr, (int) value.size); - } - else { - (void) strcpy(prop, BoldFontDefault); - } -/* fprintf(stderr,"initx:ingItColors_and_fonts:load_font 7\n");*/ - load_font(&gBfFont, prop); - - - /* - * If we are on a monochrome screen, then we ignore user preferences, and - * set the foreground and background as I wish - */ - -/* fprintf(stderr,"initx:ingItColors_and_fonts:DisplayPlanes\n");*/ - if (DisplayPlanes(gXDisplay, gXScreenNumber) == 1) { - gActiveColor = gAxiomColor - = gControlBackgroundColor - = gInputBackgroundColor - = gBfColor - = gEmColor - = gRmColor - = gSlColor - = gTtColor - = BlackPixel(gXDisplay, gXScreenNumber); - - gBackgroundColor = gInputForegroundColor - = gControlForegroundColor - = WhitePixel(gXDisplay, gXScreenNumber); - } - else { - - /* - * If I have gotten here, then we must be on a color screen, so see - * what the user likes, and set it up - */ - -/* fprintf(stderr,"initx:ingItColors_and_fonts:get_color 1\n");*/ - gRmColor = - get_color("RmColor", "Foreground", - BlackPixel(gXDisplay, gXScreenNumber), &cmap); -/* fprintf(stderr,"initx:ingItColors_and_fonts:get_color 2\n");*/ - gBackgroundColor = - get_color("Background", "Background", - WhitePixel(gXDisplay, gXScreenNumber), &cmap); -/* fprintf(stderr,"initx:ingItColors_and_fonts:get_color 3\n");*/ - gActiveColor = - get_color("ActiveColor", "Foreground", - BlackPixel(gXDisplay, gXScreenNumber), &cmap); - - /* - * for next two, I want name arg = class arg, ie do not want - * Background and Foreground. - */ - -/* fprintf(stderr,"initx:ingItColors_and_fonts:get_color 4\n");*/ - gControlBackgroundColor = get_color("ControlBackground", - "ControlBackground", WhitePixel(gXDisplay, gXScreenNumber), &cmap); -/* fprintf(stderr,"initx:ingItColors_and_fonts:get_color 5\n");*/ - gControlForegroundColor = get_color("ControlForeground", - "ControlForeground", BlackPixel(gXDisplay, gXScreenNumber), &cmap); - - /* maintain backwards compatibility */ - -/* fprintf(stderr,"initx:ingItColors_and_fonts:get_color 6\n");*/ - gAxiomColor = get_color("OpenAxiomColor", "Foreground", 0, &cmap); -/* fprintf(stderr,"initx:ingItColors_and_fonts:get_color 7\n");*/ - if (gAxiomColor == 0) - gAxiomColor = get_color("SpadColor", "Foreground", - BlackPixel(gXDisplay, gXScreenNumber), &cmap); - -/* fprintf(stderr,"initx:ingItColors_and_fonts:get_color 8\n");*/ - gInputBackgroundColor = - get_color("InputBackground", "Foreground", gRmColor, &cmap); -/* fprintf(stderr,"initx:ingItColors_and_fonts:get_color 9\n");*/ - gInputForegroundColor = - get_color("InputForeground", "Background", gBackgroundColor, &cmap); - -/* fprintf(stderr,"initx:ingItColors_and_fonts:get_color 10\n");*/ - gEmColor = - get_color("EmphasizeColor", "Foreground", gRmColor, &cmap); -/* fprintf(stderr,"initx:ingItColors_and_fonts:get_color 11\n");*/ - gTtColor = - get_color("TtColor", "Foreground", gRmColor, &cmap); -/* fprintf(stderr,"initx:ingItColors_and_fonts:get_color 12\n");*/ - gSlColor = - get_color("EmphasizeColor", "Foreground", gRmColor, &cmap); -/* fprintf(stderr,"initx:ingItColors_and_fonts:get_color 13\n");*/ - gBfColor = - get_color("BoldColor", "Foreground", gRmColor, &cmap); - } - -/* fprintf(stderr,"initx:ingItColors_and_fonts:makeColors\n");*/ - makeColors(gXDisplay, gXScreenNumber, &cmap, &spadColors, &ts); - /* - * Now set the current color and font, so I never have to do it again - */ - - gTopOfGroupStack->cur_color = gRmColor; - gTopOfGroupStack->cur_font = gRmFont; -/* fprintf(stderr,"initx:ingItColors_and_fonts:exited\n");*/ -} - -void -change_text(int color, XFontStruct *font) -{ - if (font) { - XGCValues gcv; - gcv.foreground = color; - gcv.background = gBackgroundColor; - - XChangeGC(gXDisplay, gWindow->fStandardGC, GCForeground | GCBackground , &gcv); - - if (font->fid != server_font) - XSetFont(gXDisplay, gWindow->fStandardGC, font->fid); - } -} - -/* - * This routine checks the .Xdefaults file of the user for the - * specified color. If found it allocates a place in the color map for it. If - * not found, or if an error occurrs, it writes an error message, and - * uses the given default value - */ - -static int -get_color(char *name, char *class, int def, Colormap *map) -{ - char fullname[256]; - char fullclass[256]; - char property[256]; - char *prop = &property[0]; - char *str_type[50]; - XrmValue value; - int ret_val; - XColor color_def, color_db; - -#ifdef DEBUG - printf("get_color: %s %s %d -> ", name, class, def); -#endif - - strcpy(fullname, "OpenAxiom.hyperdoc."); - strcat(fullname, name); - strcpy(fullclass,"OpenAxiom.hyperdoc."); - strcat(fullclass,class); - - if (XrmGetResource(rDB, fullname, fullclass, str_type, &value) == True) { - (void) strncpy(prop, value.addr, (int) value.size); - ret_val = XAllocNamedColor(gXDisplay, *map, prop, &color_def, &color_db); - if (ret_val) { -#ifdef DEBUG - printf("%d\n", color_def.pixel); -#endif - return (color_def.pixel); - } - else { - fprintf(stderr, - "(HyperDoc) Defaulting on color for %s. Unknown color is %s.\n", - name, prop); -#ifdef DEBUG - printf("%d\n", def); -#endif - return (def); - } - } - else { -#ifdef DEBUG - printf("%d\n", def); -#endif - return (def); - } -} - - -static void -mergeDatabases(void) -{ - XrmDatabase homeDB, serverDB, applicationDB; - char filenamebuf[1024]; - char *filename = &filenamebuf[0]; - char *classname = "OpenAxiom"; - char name[255]; - -/* fprintf(stderr,"initx:mergeDatabases:entered\n");*/ -/* fprintf(stderr,"initx:mergeDatabases:XrmInitialize\n");*/ - (void) XrmInitialize(); - (void) strcpy(name, "/usr/lib/X11/app-defaults/"); - (void) strcat(name, classname); -/* fprintf(stderr,"initx:mergeDatabases:XrmGetFileDatabase name=%s\n",name);*/ - applicationDB = XrmGetFileDatabase(name); -/* fprintf(stderr,"initx:mergeDatabases:XrmMergeDatabases\n");*/ - (void) XrmMergeDatabases(applicationDB, &rDB); - -/* fprintf(stderr,"initx:mergeDatabases:XrmGetStringDatabase\n");*/ - if (XResourceManagerString(gXDisplay) != NULL) { - serverDB = XrmGetStringDatabase(XResourceManagerString(gXDisplay)); - } - else { - (void) strcpy(filename, getenv("HOME")); - (void) strcat(filename, "/.Xdefaults"); -/* fprintf(stderr,"initx:mergeDatabases:XrmGetFileDatase\n");*/ - serverDB = XrmGetFileDatabase(filename); - } -/* fprintf(stderr,"initx:mergeDatabases:XrmMergeDatabases 2\n");*/ - XrmMergeDatabases(serverDB, &rDB); - if (getenv("XENVIRONMENT") == NULL) { - int len; - - (void) strcpy(filename, getenv("HOME")); - (void) strcat(filename, "/.Xdefaults-"); - len = strlen(filename); - (void) gethostname(filename + len, 1024 - len); - } - else { - (void) strcpy(filename, getenv("XENVIRONMENT")); - } -/* fprintf(stderr,"initx:mergeDatabases:filename=%s\n",filename);*/ - homeDB = XrmGetFileDatabase(filename); -/* fprintf(stderr,"initx:mergeDatabases:XrmMergeDatabases 3\n");*/ - XrmMergeDatabases(homeDB, &rDB); -} - - - -int -is_it_850(XFontStruct *fontarg) -{ - char *s; - int i,val; - static struct { - char *name; - Atom format; - Atom atom; - } proptbl = { "CHARSET_ENCODING", XA_ATOM }; - proptbl.atom = XInternAtom(gXDisplay,proptbl.name,0); - for (i=0;in_properties;i++) - { - if (fontarg->properties[i].name != proptbl.atom) continue; - - -/* return 1 if it is 850 */ - - s = XGetAtomName(gXDisplay,(Atom)fontarg->properties[i].card32); - val = !( strcmp("850",s) * strcmp("ibm-850",s)); - XFree(s); - return( val ); - } - return(0); -} - -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/input.c b/src/hyper/input.c new file mode 100644 index 00000000..725b9ace --- /dev/null +++ b/src/hyper/input.c @@ -0,0 +1,238 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +#define _INPUT_C +#include "axiom-c-macros.h" +#include "useproto.h" +#include "debug.h" + +#include "hyper.h" + +#include "all_hyper_proto.H1" + + +void +fill_box(Window w,ImageStruct * image) +{ + XClearWindow(gXDisplay, w); + XPutImage(gXDisplay, w, gWindow->fControlGC, + image->image.xi, 0, 0, 0, 0, + image->width, + image->height); +} + +void +toggle_input_box(HyperLink *link) +{ + InputBox *box; + + box = link->reference.box; + + if (box->picked) { + box->picked = 0; + unpick_box(box); + } + else { + box->picked = 1; + pick_box(box); + } + +} +void +toggle_radio_box(HyperLink *link) +{ + InputBox *box; + + box = link->reference.box; + + if (box->picked) { + + /* + * box->picked = 0; unpick_box(box); + */ + } + else { + /* the first thing I do is clear his buddies */ + clear_rbs(box->rbs->boxes); + box->picked = 1; + pick_box(box); + } +} + +static void +clear_rbs(InputBox *list) +{ + InputBox *trace = list; + + while (trace && !trace->picked) + trace = trace->next; + + if (trace != NULL) { + trace->picked = 0; + unpick_box(trace); + } +} +void +change_input_focus(HyperLink *link) +{ + InputItem *new_item = link->reference.string; + InputItem *old_item = gWindow->page->current_item; + XWindowChanges wc; + + /** first thing I should do is see if the user has clicked in the same + window that I am in ****/ + if (old_item == new_item) + return; + + /** Now change the current pointer **/ + gWindow->page->current_item = new_item; + + /** Now I have to change the border width of the selected input window **/ + wc.border_width = 1; + XConfigureWindow(gXDisplay, new_item->win, + CWBorderWidth, + &wc); + + wc.border_width = 0; + XConfigureWindow(gXDisplay, new_item->win, + CWBorderWidth, + &wc); + update_inputsymbol(old_item); + update_inputsymbol(new_item); +} +void +next_input_focus(void) +{ + InputItem *old_item = gWindow->page->current_item, *new_item, *trace; + + if (gWindow->page->current_item == NULL || + (gWindow->page->current_item->next == NULL + && gWindow->page->current_item == gWindow->page->input_list)) { + BeepAtTheUser(); + return; + } + + /* + * Now I should find the new item + */ + new_item = NULL; + trace = old_item->next; + + if (trace == NULL) + new_item = gWindow->page->input_list; + else + new_item = trace; + + gWindow->page->current_item = new_item; + draw_inputsymbol(old_item); + draw_inputsymbol(new_item); +} +void +prev_input_focus(void) +{ + InputItem *old_item = gWindow->page->current_item, *new_item, *trace; + + if (gWindow->page->current_item == NULL) { + BeepAtTheUser(); + return; + } + + /* + * Now I should find the new item + */ + new_item = NULL; + trace = gWindow->page->input_list; + + if (trace == old_item) { + + /* + * I started at the front of the list, so move forward until I hit + * the end + */ + while (trace->next != NULL) + trace = trace->next; + new_item = trace; + } + else { + while (trace->next != old_item) + trace = trace->next; + new_item = trace; + } + + gWindow->page->current_item = new_item; + draw_inputsymbol(old_item); + draw_inputsymbol(new_item); + +} + +InputItem * +return_item(char *name) +{ + InputItem *list; + + list = gWindow->page->input_list; + while (list != NULL) { + if (!strcmp(name, list->name)) + return list; + list = list->next; + } + return NULL; +} +int +delete_item(char *name) +{ + InputItem *list; + InputItem *prev = NULL; + + list = gWindow->page->input_list; + while (list != NULL) { + if (!strcmp(name, list->name)) { + if (prev) + prev->next = list->next; + else + gWindow->page->input_list = list->next; + if (gWindow->page->current_item == list) + gWindow->page->current_item = gWindow->page->input_list; + free_input_item(list, 1); + free(list); + return 1; + } + prev = list; + list = list->next; + } + fprintf(stderr, "Can't delete input item %s\n", name); + return 0; +} + diff --git a/src/hyper/input.pamphlet b/src/hyper/input.pamphlet deleted file mode 100644 index aa916d68..00000000 --- a/src/hyper/input.pamphlet +++ /dev/null @@ -1,268 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/input} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{input.c} -<>= -#define _INPUT_C -#include "axiom-c-macros.h" -#include "useproto.h" -#include "debug.h" - -#include "hyper.h" -#include "dialog.h" -#include "mem.h" - -#include "all_hyper_proto.H1" - - -void -fill_box(Window w,ImageStruct * image) -{ - XClearWindow(gXDisplay, w); - XPutImage(gXDisplay, w, gWindow->fControlGC, - image->image.xi, 0, 0, 0, 0, - image->width, - image->height); -} - -void -toggle_input_box(HyperLink *link) -{ - InputBox *box; - - box = link->reference.box; - - if (box->picked) { - box->picked = 0; - unpick_box(box); - } - else { - box->picked = 1; - pick_box(box); - } - -} -void -toggle_radio_box(HyperLink *link) -{ - InputBox *box; - - box = link->reference.box; - - if (box->picked) { - - /* - * box->picked = 0; unpick_box(box); - */ - } - else { - /* the first thing I do is clear his buddies */ - clear_rbs(box->rbs->boxes); - box->picked = 1; - pick_box(box); - } -} - -static void -clear_rbs(InputBox *list) -{ - InputBox *trace = list; - - while (trace && !trace->picked) - trace = trace->next; - - if (trace != NULL) { - trace->picked = 0; - unpick_box(trace); - } -} -void -change_input_focus(HyperLink *link) -{ - InputItem *new_item = link->reference.string; - InputItem *old_item = gWindow->page->current_item; - XWindowChanges wc; - - /** first thing I should do is see if the user has clicked in the same - window that I am in ****/ - if (old_item == new_item) - return; - - /** Now change the current pointer **/ - gWindow->page->current_item = new_item; - - /** Now I have to change the border width of the selected input window **/ - wc.border_width = 1; - XConfigureWindow(gXDisplay, new_item->win, - CWBorderWidth, - &wc); - - wc.border_width = 0; - XConfigureWindow(gXDisplay, new_item->win, - CWBorderWidth, - &wc); - update_inputsymbol(old_item); - update_inputsymbol(new_item); -} -void -next_input_focus(void) -{ - InputItem *old_item = gWindow->page->current_item, *new_item, *trace; - - if (gWindow->page->current_item == NULL || - (gWindow->page->current_item->next == NULL - && gWindow->page->current_item == gWindow->page->input_list)) { - BeepAtTheUser(); - return; - } - - /* - * Now I should find the new item - */ - new_item = NULL; - trace = old_item->next; - - if (trace == NULL) - new_item = gWindow->page->input_list; - else - new_item = trace; - - gWindow->page->current_item = new_item; - draw_inputsymbol(old_item); - draw_inputsymbol(new_item); -} -void -prev_input_focus(void) -{ - InputItem *old_item = gWindow->page->current_item, *new_item, *trace; - - if (gWindow->page->current_item == NULL) { - BeepAtTheUser(); - return; - } - - /* - * Now I should find the new item - */ - new_item = NULL; - trace = gWindow->page->input_list; - - if (trace == old_item) { - - /* - * I started at the front of the list, so move forward until I hit - * the end - */ - while (trace->next != NULL) - trace = trace->next; - new_item = trace; - } - else { - while (trace->next != old_item) - trace = trace->next; - new_item = trace; - } - - gWindow->page->current_item = new_item; - draw_inputsymbol(old_item); - draw_inputsymbol(new_item); - -} - -InputItem * -return_item(char *name) -{ - InputItem *list; - - list = gWindow->page->input_list; - while (list != NULL) { - if (!strcmp(name, list->name)) - return list; - list = list->next; - } - return NULL; -} -int -delete_item(char *name) -{ - InputItem *list; - InputItem *prev = NULL; - - list = gWindow->page->input_list; - while (list != NULL) { - if (!strcmp(name, list->name)) { - if (prev) - prev->next = list->next; - else - gWindow->page->input_list = list->next; - if (gWindow->page->current_item == list) - gWindow->page->current_item = gWindow->page->input_list; - free_input_item(list, 1); - free(list); - return 1; - } - prev = list; - list = list->next; - } - fprintf(stderr, "Can't delete input item %s\n", name); - return 0; -} - -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/item.c b/src/hyper/item.c new file mode 100644 index 00000000..18311ec8 --- /dev/null +++ b/src/hyper/item.c @@ -0,0 +1,127 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +#include "axiom-c-macros.h" +#include "useproto.h" +#define _ITEM_C +#include "debug.h" +#include "extent.h" + +#include "all_hyper_proto.H1" + +/* + * Here are structures needed for manipulating the item stack + */ +ItemStack *gTopOfItemStack = NULL; + + +void +push_item_stack(void) +{ + ItemStack *is = (ItemStack *) halloc(sizeof(ItemStack), "Item stack"); + + is->indent = indent; + is->item_indent = item_indent; + is->next = gTopOfItemStack; + is->in_item = gInItem; + gTopOfItemStack = is; + return; +} +void +clear_item_stack(void) +{ + ItemStack *is = gTopOfItemStack, *chuck; + + while (is != NULL) { + chuck = is; + is = is->next; + free(chuck); + } + return; +} +void +pop_item_stack(void) +{ + ItemStack *chuck; + + if (gTopOfItemStack == NULL) { + fprintf(stderr, "Tried to pop an empty item stack\n"); + return; + } + chuck = gTopOfItemStack; + gTopOfItemStack = gTopOfItemStack->next; + indent = chuck->indent; + item_indent = chuck->item_indent; + gInItem = chuck->in_item; + free(chuck); +} + +ItemStack * +copy_item_stack(void) +{ + ItemStack *new = NULL; + ItemStack *prev = NULL; + ItemStack *trace = gTopOfItemStack; + ItemStack *first = NULL; + + while (trace) { + new = (ItemStack *) halloc(sizeof(ItemStack), "Item stack"); + new->indent = trace->indent; + new->item_indent = trace->item_indent; + new->in_item = gInItem; + if (!first) + first = new; + else + prev->next = new; + prev = new; + trace = trace->next; + } + if (new) + new->next = NULL; + return first; +} + +void +free_item_stack(ItemStack *is) +{ + ItemStack *junk = NULL; + ItemStack *trace = is; + + while (trace) { + junk = trace; + trace = trace->next; + free(junk); + } +} diff --git a/src/hyper/item.pamphlet b/src/hyper/item.pamphlet deleted file mode 100644 index f65a69f3..00000000 --- a/src/hyper/item.pamphlet +++ /dev/null @@ -1,155 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/item} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{item.c} -<>= -#include "axiom-c-macros.h" -#include "useproto.h" -#define _ITEM_C -#include "debug.h" -#include "extent.h" - -#include "all_hyper_proto.H1" - -/* - * Here are structures needed for manipulating the item stack - */ -ItemStack *gTopOfItemStack = NULL; - - -void -push_item_stack(void) -{ - ItemStack *is = (ItemStack *) halloc(sizeof(ItemStack), "Item stack"); - - is->indent = indent; - is->item_indent = item_indent; - is->next = gTopOfItemStack; - is->in_item = gInItem; - gTopOfItemStack = is; - return; -} -void -clear_item_stack(void) -{ - ItemStack *is = gTopOfItemStack, *chuck; - - while (is != NULL) { - chuck = is; - is = is->next; - free(chuck); - } - return; -} -void -pop_item_stack(void) -{ - ItemStack *chuck; - - if (gTopOfItemStack == NULL) { - fprintf(stderr, "Tried to pop an empty item stack\n"); - return; - } - chuck = gTopOfItemStack; - gTopOfItemStack = gTopOfItemStack->next; - indent = chuck->indent; - item_indent = chuck->item_indent; - gInItem = chuck->in_item; - free(chuck); -} - -ItemStack * -copy_item_stack(void) -{ - ItemStack *new = NULL; - ItemStack *prev = NULL; - ItemStack *trace = gTopOfItemStack; - ItemStack *first = NULL; - - while (trace) { - new = (ItemStack *) halloc(sizeof(ItemStack), "Item stack"); - new->indent = trace->indent; - new->item_indent = trace->item_indent; - new->in_item = gInItem; - if (!first) - first = new; - else - prev->next = new; - prev = new; - trace = trace->next; - } - if (new) - new->next = NULL; - return first; -} - -void -free_item_stack(ItemStack *is) -{ - ItemStack *junk = NULL; - ItemStack *trace = is; - - while (trace) { - junk = trace; - trace = trace->next; - free(junk); - } -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/keyin.c b/src/hyper/keyin.c new file mode 100644 index 00000000..b6d2004e --- /dev/null +++ b/src/hyper/keyin.c @@ -0,0 +1,286 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +/****************************************************************************** + * + * keyin.c: + * + * Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993. + * + ****************************************************************************/ +#define _KEYIN_C +#include "axiom-c-macros.h" +#include "useproto.h" +#include "debug.h" + + +#include "hyper.h" +#include "keyin.h" +#include "event.h" +#include "parse.h" +#include "scrollbar.h" + +#include "all_hyper_proto.H1" +#include + + +#define min(x,y) ( (xxkey.state & ShiftMask) { + name = gWindow->page->name; + filename = gWindow->page->filename; + sprintf(buffer, "htadd -l %s\n", filename); + system(buffer); + filehandle = (FILE *) hash_find(&gFileHashTable, filename); + fclose(filehandle); + hash_delete(&gFileHashTable, filename); + gWindow->fMacroHashTable = + (HashTable *) halloc(sizeof(HashTable), "macro hash"); + hash_init( + gWindow->fMacroHashTable, + MacroHashSize, + (EqualFunction ) string_equal, + (HashcodeFunction) string_hash); + gWindow->fPatchHashTable = (HashTable *) halloc(sizeof(HashTable), "patch hash"); + hash_init( + gWindow->fPatchHashTable, + PatchHashSize, + (EqualFunction ) string_equal, + (HashcodeFunction) string_hash); + gWindow->fPasteHashTable = (HashTable *) halloc(sizeof(HashTable), "paste hash"); + hash_init(gWindow->fPasteHashTable, + PasteHashSize, + (EqualFunction ) string_equal, + (HashcodeFunction) string_hash); + gWindow->fCondHashTable = (HashTable *) halloc(sizeof(HashTable), "cond hash"); + hash_init( + gWindow->fCondHashTable, + CondHashSize, + (EqualFunction ) string_equal, + (HashcodeFunction) string_hash); + gWindow->fPageHashTable = (HashTable *) halloc(sizeof(HashTable), "page hash"); + hash_init( + gWindow->fPageHashTable, + PageHashSize, + (EqualFunction ) string_equal, + (HashcodeFunction) string_hash); + make_special_pages(gWindow->fPageHashTable); + read_ht_db( + gWindow->fPageHashTable, + gWindow->fMacroHashTable, + gWindow->fPatchHashTable); + gWindow->page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, name); + if (gWindow->page == NULL) { + fprintf(stderr, "lose...gWindow->page for %s is null\n", name); + exit(-1); + } + display_again = 1; + } + break; + case XK_F9: + make_window_link(KeyDefsHelpPage); + break; + case XK_Tab: + if (event->xkey.state & ShiftMask) + prev_input_focus(); + else if (event->xkey.state & ModifiersMask) + BeepAtTheUser(); + else + next_input_focus(); + break; + case XK_Return: + if (!(event->xkey.state & ShiftMask)) { + next_input_focus(); + break; + } + + /* next ones fall through to input area handling */ + + case XK_Escape: + if (!gWindow->page->current_item) + break; + case XK_F1: + if (!gWindow->page->current_item) { + gWindow->page->helppage = alloc_string(NoMoreHelpPage); + helpForHyperDoc(); + break; + } + case XK_Home: + if (!gWindow->page->current_item) { + scrollToFirstPage(); + break; + } + case XK_Up: + if (!gWindow->page->current_item) { + scrollUp(); + break; + } + case XK_Down: + if (!gWindow->page->current_item) { + scrollDown(); + break; + } + + default: + display_again = 0; + dialog(event, keysym, key_buffer); + XFlush(gXDisplay); + break; + } + + if (display_again) { + display_page(gWindow->page); + gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; + } +} + + +/* + * This routine initializes some of the variables needed by the input + * strings, and boxes. + */ + +void +init_keyin(void) +{ + char *prop; + + /* + * First set all the values for when the active cursor is in the window + */ + + in_cursor_height = 2; + in_cursor_y = gInputFont->max_bounds.ascent + + gInputFont->max_bounds.descent; + in_cursor_width = gInputFont->max_bounds.width; + + /* + * Now for when the cursor is empty + */ + + out_cursor_height = gInputFont->max_bounds.ascent + + gInputFont->max_bounds.descent; + out_cursor_y = 2; + out_cursor_width = in_cursor_width; + + start_x = 5; + + start_y = gInputFont->max_bounds.ascent; + + /* + * Find out How big I should make the simple boxes + */ + + simple_box_width = XTextWidth(gInputFont, "X", 1) + 5; + + prop = XGetDefault(gXDisplay, gArgv[0], "ProtectedQuit"); + + if (prop == NULL) { + protected_quit = (char *) halloc(strlen("ProtectedPage") + 1, + "protected_quit"); + strcpy(protected_quit, "ProtectedPage"); + } + else { + protected_quit = (char *) halloc(strlen(prop) + 1, "protected_quit"); + strcpy(protected_quit, prop); + } + + +} diff --git a/src/hyper/keyin.h b/src/hyper/keyin.h new file mode 100644 index 00000000..e1bc564c --- /dev/null +++ b/src/hyper/keyin.h @@ -0,0 +1,55 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +#ifndef _KEYIN_H_ +#define _KEYIN_H_ 1 + +extern int in_cursor_height; +extern int in_cursor_width; +extern int out_cursor_height; +extern int out_cursor_width; +extern int in_cursor_y; +extern int out_cursor_y; +extern int start_x; +extern int start_y; +extern int simple_box_width; + +extern int gInInsertMode; + +extern unsigned int ModifiersMask; +extern unsigned int ShiftModMask; + + +#endif diff --git a/src/hyper/keyin.pamphlet b/src/hyper/keyin.pamphlet deleted file mode 100644 index c1e5f267..00000000 --- a/src/hyper/keyin.pamphlet +++ /dev/null @@ -1,340 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/keyin} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{keyin.h} -<>= -<> -#ifndef _KEYIN_H_ -#define _KEYIN_H_ 1 - -extern int in_cursor_height; -extern int in_cursor_width; -extern int out_cursor_height; -extern int out_cursor_width; -extern int in_cursor_y; -extern int out_cursor_y; -extern int start_x; -extern int start_y; -extern int simple_box_width; - -extern int gInInsertMode; - -extern unsigned int ModifiersMask; -extern unsigned int ShiftModMask; - - -#endif -@ -\section{keyin.c} -<>= -/****************************************************************************** - * - * keyin.c: - * - * Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993. - * - ****************************************************************************/ -#define _KEYIN_C -#include "axiom-c-macros.h" -#include "useproto.h" -#include "debug.h" - - -#include "hyper.h" -#include "keyin.h" -#include "event.h" -#include "dialog.h" -#include "parse.h" -#include "parse-aux.h" -#include "scrollbar.h" - -#include "all_hyper_proto.H1" -#include - - -#define min(x,y) ( (xxkey.state & ShiftMask) { - name = gWindow->page->name; - filename = gWindow->page->filename; - sprintf(buffer, "htadd -l %s\n", filename); - system(buffer); - filehandle = (FILE *) hash_find(&gFileHashTable, filename); - fclose(filehandle); - hash_delete(&gFileHashTable, filename); - gWindow->fMacroHashTable = - (HashTable *) halloc(sizeof(HashTable), "macro hash"); - hash_init( - gWindow->fMacroHashTable, - MacroHashSize, - (EqualFunction ) string_equal, - (HashcodeFunction) string_hash); - gWindow->fPatchHashTable = (HashTable *) halloc(sizeof(HashTable), "patch hash"); - hash_init( - gWindow->fPatchHashTable, - PatchHashSize, - (EqualFunction ) string_equal, - (HashcodeFunction) string_hash); - gWindow->fPasteHashTable = (HashTable *) halloc(sizeof(HashTable), "paste hash"); - hash_init(gWindow->fPasteHashTable, - PasteHashSize, - (EqualFunction ) string_equal, - (HashcodeFunction) string_hash); - gWindow->fCondHashTable = (HashTable *) halloc(sizeof(HashTable), "cond hash"); - hash_init( - gWindow->fCondHashTable, - CondHashSize, - (EqualFunction ) string_equal, - (HashcodeFunction) string_hash); - gWindow->fPageHashTable = (HashTable *) halloc(sizeof(HashTable), "page hash"); - hash_init( - gWindow->fPageHashTable, - PageHashSize, - (EqualFunction ) string_equal, - (HashcodeFunction) string_hash); - make_special_pages(gWindow->fPageHashTable); - read_ht_db( - gWindow->fPageHashTable, - gWindow->fMacroHashTable, - gWindow->fPatchHashTable); - gWindow->page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, name); - if (gWindow->page == NULL) { - fprintf(stderr, "lose...gWindow->page for %s is null\n", name); - exit(-1); - } - display_again = 1; - } - break; - case XK_F9: - make_window_link(KeyDefsHelpPage); - break; - case XK_Tab: - if (event->xkey.state & ShiftMask) - prev_input_focus(); - else if (event->xkey.state & ModifiersMask) - BeepAtTheUser(); - else - next_input_focus(); - break; - case XK_Return: - if (!(event->xkey.state & ShiftMask)) { - next_input_focus(); - break; - } - - /* next ones fall through to input area handling */ - - case XK_Escape: - if (!gWindow->page->current_item) - break; - case XK_F1: - if (!gWindow->page->current_item) { - gWindow->page->helppage = alloc_string(NoMoreHelpPage); - helpForHyperDoc(); - break; - } - case XK_Home: - if (!gWindow->page->current_item) { - scrollToFirstPage(); - break; - } - case XK_Up: - if (!gWindow->page->current_item) { - scrollUp(); - break; - } - case XK_Down: - if (!gWindow->page->current_item) { - scrollDown(); - break; - } - - default: - display_again = 0; - dialog(event, keysym, key_buffer); - XFlush(gXDisplay); - break; - } - - if (display_again) { - display_page(gWindow->page); - gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; - } -} - - -/* - * This routine initializes some of the variables needed by the input - * strings, and boxes. - */ - -void -init_keyin(void) -{ - char *prop; - - /* - * First set all the values for when the active cursor is in the window - */ - - in_cursor_height = 2; - in_cursor_y = gInputFont->max_bounds.ascent + - gInputFont->max_bounds.descent; - in_cursor_width = gInputFont->max_bounds.width; - - /* - * Now for when the cursor is empty - */ - - out_cursor_height = gInputFont->max_bounds.ascent + - gInputFont->max_bounds.descent; - out_cursor_y = 2; - out_cursor_width = in_cursor_width; - - start_x = 5; - - start_y = gInputFont->max_bounds.ascent; - - /* - * Find out How big I should make the simple boxes - */ - - simple_box_width = XTextWidth(gInputFont, "X", 1) + 5; - - prop = XGetDefault(gXDisplay, gArgv[0], "ProtectedQuit"); - - if (prop == NULL) { - protected_quit = (char *) halloc(strlen("ProtectedPage") + 1, - "protected_quit"); - strcpy(protected_quit, "ProtectedPage"); - } - else { - protected_quit = (char *) halloc(strlen(prop) + 1, "protected_quit"); - strcpy(protected_quit, prop); - } - - -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/lex.c b/src/hyper/lex.c new file mode 100644 index 00000000..6b4bf6d5 --- /dev/null +++ b/src/hyper/lex.c @@ -0,0 +1,877 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +/* + * Lexical analyzer stuff. Exported functions: parser_init() -- + * initialize the parser tables with keywords init_scanner() -- + * initialize scanner for reading a new page get_token() -- + * sets the "token" variable to be the next -- token in the current input + * stream save_scanner_state( ) -- save the current state of scanner so + * that -- the scanner input mode may be switched restore_scanner_state() -- + * undo the saved state + * + * Note: The scanner reads from three seperate input locations depending on the + * value of the variable "input_type". If this variable is: + * + * FromFile -- it read from the file pointed to by "cfile". FromString + * -- It reads from the string "input_string". FromSpadSocket -- It reads + * from the socket pointed to by spad_socket FromFD -- It reads from a + * file descriptor + * + * + * New variable useAscii -- tells us if we we should translate + * graphics characters on the fly + * initialised in init_scanner + * + */ +#define _LEX_C +#include "axiom-c-macros.h" +#include "useproto.h" +#include "debug.h" + +int useAscii; + +#define PARSER 1 + +#include "hyper.h" +#include "hterror.h" +#include "lex.h" + +#include "all_hyper_proto.H1" +#include "sockio-c.H1" + + +#include +#include + +extern int gTtFontIs850; + + +StateNode *top_state_node; +HyperDocPage *gPageBeingParsed; /* page currently being parsed */ +extern jmp_buf jmpbuf; +extern char ebuffer[]; +short int gInSpadsrc = 0; +short int gInVerbatim; + +/* Parser variables */ +long fpos; /* Position of pointer in file in characters */ +long page_start_fpos; /* where the current pages fpos started */ +long keyword_fpos; /* fpos of beginning of most recent keyword */ +Token token; /* most recently read token */ +int last_token; /* most recently read token for unget_token */ +int input_type; /* indicates where to read input */ +char *input_string; /* input string read when from_string is true */ +int last_ch; /* last character read, for unget_char */ +int last_command; /* the last socket command */ +int keyword; /* the last command was a keyword, or a group */ +int cfd; /* current file decriptor */ +FILE *cfile; /* currently active file pointer */ +FILE *unixfd; +int line_number; + +char sock_buf[1024]; /* buffer for socket input */ + +#define TokenHashSize 100 + +static HashTable tokenHashTable; /* hash table of parser tokens */ + +void +dumpToken(char *caller, Token t) +{ fprintf(stderr,"%s:dumpToken type=%s id=%s\n", + caller,token_table[t.type],t.id); +} + + +/* initialize the parser keyword hash table */ +void +parser_init(void) +{ + int i; + Token *toke; + + /* First I initialize the hash table for the tokens */ + + hash_init( + &tokenHashTable, + TokenHashSize, + (EqualFunction)string_equal, + (HashcodeFunction)string_hash); + for (i = 2; i <= NumberUserTokens; i++) { + toke = (Token *) halloc(sizeof(Token), "Token"); + toke->type = i; + toke->id = token_table[i]; + hash_insert(&tokenHashTable, (char *)toke, toke->id); + } + +} + +/* initialize the lexical scanner to read from a file */ +void +init_scanner(void) +{ + if (getenv("HTASCII")) { + useAscii = (strcmp(getenv("HTASCII"), "yes") == 0); + } + else { + if(gTtFontIs850==1) useAscii = 0; + else useAscii = 1; + } + keyword = 0; + last_ch = NoChar; + last_token = 0; + input_type = FromFile; + fpos = 0; + keyword_fpos = 0; + last_command = -1; + line_number = 1; +} + +/* + * variables to save current state of scanner. Currently only one level of + * saving is allowed. In the future we should allow nested saves + */ + +/* save the current state of the scanner */ +void +save_scanner_state(void) +{ + StateNode *new_item = (StateNode *) halloc((sizeof(StateNode)), "StateNode"); + + new_item->page_start_fpos = page_start_fpos; + new_item->fpos = fpos; + new_item->keyword_fpos = keyword_fpos; + new_item->last_ch = last_ch; + new_item->last_token = last_token; + new_item->token = token; + new_item->input_type = input_type; + new_item->input_string = input_string; + new_item->cfile = cfile; + new_item->next = top_state_node; + new_item->keyword = keyword; + top_state_node = new_item; +} + +/* restore the saved scanner state */ +void +restore_scanner_state(void) +{ + StateNode *x = top_state_node; + + if (top_state_node == NULL) { + fprintf(stderr, "Restore Scanner State: State empty\n"); + exit(-1); + } + top_state_node = top_state_node->next; + page_start_fpos = x->page_start_fpos; + fpos = x->fpos; + keyword_fpos = x->keyword_fpos; + last_ch = x->last_ch; + last_token = x->last_token; + token = x->token; + input_type = x->input_type; + input_string = x->input_string; + cfile = x->cfile; + keyword = x->keyword; + if (cfile != NULL) + fseek(cfile, fpos + page_start_fpos, 0); + /** Once that is done, lets throw away some memory **/ + free(x); +} + +/* return the character to the input stream. */ +void +unget_char(int c) +{ + if (c == '\n') + line_number--; + last_ch = c; +} + +int +get_char(void) +{ + int c; + + c = get_char1(); + if (useAscii) { + switch (c) { + case 'Ä': + c = '-'; + break; + case 'Ú': + c = '+'; + break; + case 'Ã': + c = '['; + break; + case 'À': + c = '+'; + break; + case 'Â': + c = '-'; + break; + case 'Å': + c = '+'; + break; + case 'Á': + c = '-'; + break; + case '¿': + c = '+'; + break; + case '´': + c = ']'; + break; + case 'Ù': + c = '+'; + break; + case '³': + c = '|'; + break; + default: + break; + } + } + return c; +} + +char * read_again = 0; + +/* return the next character in the input stream */ +static int +get_char1(void) +{ + int c; + int cmd; + + if (last_ch != NoChar) { + c = last_ch; + last_ch = NoChar; + if (c == '\n') + line_number++; + return c; + } + switch (input_type) { + case FromUnixFD: + c = getc(unixfd); + if (c == '\n') + line_number++; + return c; + case FromString: + c = (*input_string ? *input_string++ : EOF); + if (c == '\n') + line_number++; + return c; + case FromFile: + c = getc(cfile); + fpos++; + if (c == '\n') + line_number++; + return c; + case FromSpadSocket: +AGAIN: + if (*input_string) { + /* this should never happen for the first character */ + c = *input_string++; + if (c == '\n') + line_number++; + return c; + } + if (last_command == EndOfPage) + return EOF; + if (read_again == NULL) { + last_command = cmd = get_int(spad_socket); + if (cmd == EndOfPage) + return EOF; +#ifndef HTADD + if (cmd == SpadError) + spad_error_handler(); +#endif + } + read_again = get_string_buf(spad_socket, sock_buf, 1023); + /* this will be null if this is the last time*/ + input_string = sock_buf; + goto AGAIN; + default: + fprintf(stderr, "Get Char: Unknown type of input: %d\n", input_type); + return -1; + } +} + + +#define special(c) ((c) == '{' || (c) == '}' || (c) == '#' || (c) == '%' || \ + (c) == '\\' || (c) == '[' || (c) == ']' || (c) == '_' || \ + (c) == ' ' || (c) == '$' || (c) == '~' || (c) == '^' || \ + (c) == '&') + +#define punctuation(c) ((c)== '`' || (c) == '\'' || (c) == ',' || \ + (c) == '.' || (c) == '?' || (c) == '"' || \ + (c) == ';' || (c) == ':' || (c) == '-') + +#define whitespace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n') +#define delim(c) \ + (whitespace(c) || special(c) || punctuation(c)) + + + +Token unget_toke; + +/* return current token to the input stream */ +void +unget_token(void) +{ + last_token = 1; + unget_toke.type = token.type; + unget_toke.id = alloc_string(token.id - 1); +} + + +int +get_token(void) +{ + int c, ws; + int nls = 0; + static int seen_white = 0; + static char buffer[1024]; + char *buf = buffer; + + if (last_token) { + last_token = 0; + token.type = unget_toke.type; + strcpy(buffer, unget_toke.id); + free(unget_toke.id); + token.id = buffer + 1; + if (token.type == EOF) + return EOF; + else + return 0; + } + seen_white = nls = 0; + do { + c = get_char(); + ws = whitespace(c); + if (ws) + seen_white++; + if (c == '\n') { + if (nls) { + token.type = Par; + return 0; + } + else + nls++; + } + } while (ws); + + /* first character of string indicates number of spaces before token */ + + if (!keyword) + *buf++ = seen_white; + else + *buf++ = 0; + + keyword = 0; + if (input_type != FromSpadSocket && c == '%') { + while ((c = get_char()) != '\n' && c != EOF); +/* trying to fix the comment problem: a comment line forces words on either side together*/ +/* try returning the eol */ + unget_char(c); + return get_token(); + } + if (input_type == FromFile && c == '$') { + token.type = Dollar; + return 0; + } + switch (c) { + case EOF: + token.type = -1; + return EOF; + case '\\': + keyword_fpos = fpos - 1; + c = get_char(); + if (!isalpha(c)) { + *buf++ = c; + token.type = Word; + *buf = '\0'; + seen_white = 0; + } + else { + do { + *buf++ = c; + } while ((c = get_char()) != EOF && isalpha(c)); + + unget_char(c); + *buf = '\0'; + keyword = 1; + token.id = buffer + 1; + return (keyword_type()); + } + break; + case '{': + token.type = Lbrace; + break; + case '}': + token.type = Rbrace; + break; + case '[': + token.type = Lsquarebrace; + *buf++ = c; + *buf = '\0'; + token.id = buffer + 1; + break; + case ']': + token.type = Rsquarebrace; + *buf++ = c; + *buf = '\0'; + token.id = buffer + 1; + break; + case '#': + token.type = Pound; + + /* + * if I get a pound then what I do is parse until I get something + * that is not an integer + */ + c = get_char(); + while (isdigit(c) && (c != EOF)) { + *buf++ = c; + c = get_char(); + } + unget_char(c); + *buf = '\0'; + token.id = buffer + 1; + break; + case '`': + case '\'': + case ',': + case '.': + case '!': + case '?': + case '"': + case ':': + case ';': + token.type = Punctuation; + *buf++ = c; + *buf = '\0'; + /** Now I should set the buffer[0] as my flag for whether I had + white-space in front of me, and whether I had white space + behind me **/ + if (buffer[0]) + buffer[0] = FRONTSPACE; + c = get_char(); + if (whitespace(c)) + buffer[0] |= BACKSPACE; + unget_char(c); + token.id = buffer + 1; + break; + case '-': + do { + *buf++ = c; + } while (((c = get_char()) != EOF) && (c == '-')); + unget_char(c); + *buf = '\0'; + token.type = Dash; + token.id = buffer + 1; + break; + default: + do { + *buf++ = c; + } while ((c = get_char()) != EOF && !delim(c)); + unget_char(c); + *buf = '\0'; + token.type = Word; + token.id = buffer + 1; + break; + } +/* dumpToken("get_token",token);*/ + return 0; +} + + +/* + * Here are the structures and stuff needed for the begin and end routines. + * The stack stores the begin types that have been seen and the end + * pops them off and checks to insure that they are reversed properly. + */ + +typedef struct be_struct { + int type; + char *id; + struct be_struct *next; +} BeStruct; + +BeStruct *top_be_stack; + + +void +push_be_stack(int type,char * id) +{ + BeStruct *be = (BeStruct *) halloc(sizeof(BeStruct), "BeginENd stack"); + + if (gWindow != NULL) { + be->type = type; + be->next = top_be_stack; + be->id = alloc_string(id); + top_be_stack = be; + } + return; +} +void +check_and_pop_be_stack(int type,char * id) +{ + BeStruct *x; + + /* + * this routine pops the be stack and compares types. If they are + * the same then I am okay and return a 1. Else I return a two and try to + * print a meaningful message + */ + if (gWindow == NULL) + return; + if (top_be_stack == NULL) { /* tried to pop when I shouldn't have */ + fprintf(stderr, "Unexpected \\end{%s} \n", token.id); + print_page_and_filename(); + print_next_ten_tokens(); + jump(); + } + x = top_be_stack; + if (x->type == type) { + top_be_stack = top_be_stack->next; + free(x->id); + free(x); + return; + } + /* else I didn't have a match. Lets try to write a sensible message */ + fprintf(stderr, "\\begin{%s} ended with \\end{%s} \n", x->id, id); + print_page_and_filename(); + print_next_ten_tokens(); + jump(); +} + +int +clear_be_stack(void) +{ + BeStruct *x = top_be_stack, *y; + + top_be_stack = NULL; + while (x != NULL) { + y = x->next; + free(x); + x = y; + } + return 1; +} + +int +be_type(char *which) +{ + Token store; + + get_expected_token(Lbrace); + get_expected_token(Word); + switch (token.id[0]) { + case 't': + if (!strcmp(token.id, "titems")) { + token.type = Begintitems; + } + else { + return -1; + } + break; + case 'p': + if (!strcmp(token.id, "page")) { + token.type = Page; + } + else if (!strcmp(token.id, "paste")) { + token.type = Paste; + } + else if (!strcmp(token.id, "patch")) { + token.type = Patch; + } + else { + return -1; + } + break; + case 'v': /* possibly a verbatim mode */ + if (!strcmp(token.id, "verbatim")) { + token.type = Verbatim; + } + else { + return -1; + } + break; + case 's': /* possibly a scroll mode */ + if (!strcmp("scroll", token.id)) { + token.type = Beginscroll; + } + else if (!strcmp(token.id, "spadsrc")) { + token.type = Spadsrc; + } + else { + return -1; + } + break; + case 'i': /* possibly a item */ + if (!strcmp("items", token.id)) { + token.type = Beginitems; + } + else { + return -1; + } + break; + default: + return -1; + } + store.type = token.type; + /* store.id = alloc_string(token.id); */ + get_expected_token(Rbrace); + token.type = store.type; + + /* + * strcpy(token.id, store.id); free(store.id); + */ + return 0; + +} +int +begin_type(void) +{ + /*Token store;*/ + int ret_val; + + /* + * This routine parses a statement of the form \begin{word}. Once it has + * read the word it tries to assign it a type. Once that is done it sends + * the word id, and the type to push_be_stack and then returns the type. + * For the moment I amnot even going to use a has_table, although in the + * future this may be needed + */ + ret_val = be_type("begin"); + if (ret_val == -1) { + if (gWindow == NULL || gInVerbatim) + return 1; + else { + fprintf(stderr, "Unknown begin type \\begin{%s} \n", token.id); + print_page_and_filename(); + print_next_ten_tokens(); + jump(); + } + } + else { + if (gWindow != NULL && !gInVerbatim && token.type != Verbatim + && token.type != Spadsrc) { + /* Now here I should push the needed info and then get */ + push_be_stack(token.type, token.id); + } + return 1; + } + return 1; +} + + +int +end_type(void) +{ + int ret; + + /* + * This routine gets the end type just as the begin_type routine does, + * But then it checks to see if recieved the proper end_type. By a clever + * trick, the proper end type is 3000 + type. When environments this will + * have to change + */ + ret = be_type("end"); + if (ret == -1) { + /* unrecognized end token */ + if (gWindow == NULL || gInVerbatim) { + return 1; + } + else { + fprintf(stderr, "Unknown begin type \\begin{%s} \n", token.id); + print_page_and_filename(); + print_next_ten_tokens(); + jump(); + } + } + else { + if (gWindow != NULL && !gInVerbatim) { + check_and_pop_be_stack(token.type, token.id); + token.type += 3000; + return 1; + } + else { + if (gWindow != NULL && ((gInVerbatim && token.type == Verbatim) || + (gInSpadsrc && token.type == Spadsrc))) { + check_and_pop_be_stack(token.type, token.id); + token.type += 3000; + return 1; + } + else { + token.type += 3000; + return 1; + } + } + } + return 1; +} + + + +static int +keyword_type(void) +{ + Token *token_ent; + + /* first check to see if it is a reserved token */ + token_ent = (Token *) hash_find(&tokenHashTable, token.id); + if (token_ent != NULL) { + token.type = token_ent->type; + + /* + * if I am a keyword I also have to check to see if I am a begin or + * an end + */ + if (token.type == Begin) + return begin_type(); + if (token.type == End) + return end_type(); + /* next check to see if it is a macro */ + } + else if (gWindow != NULL) { + if (hash_find(gWindow->fMacroHashTable, token.id) != NULL) + token.type = Macro; + else if (gPageBeingParsed->box_hash != NULL && + hash_find(gPageBeingParsed->box_hash, token.id) != NULL) + { + token.type = Boxcond; + } + else if (hash_find(gWindow->fCondHashTable, token.id) != NULL) + token.type = Cond; + else /* We have no idea what we've got */ + token.type = Unkeyword; + } + else { /* We am probably in htadd so just return. It + * is only concerned with pages anyway */ + token.type = Unkeyword; + } + return 0; +} + +/* read a token, and report a syntax error if it has the wrong type */ +void +get_expected_token(int type) +{ + get_token(); + if (token.type != type) { + token_name(type); + fprintf(stderr, "syntax error: expected a %s\n", ebuffer); + if (token.type == EOF) { + print_page_and_filename(); + fprintf(stderr, "Unexpected EOF\n"); + } + else { + token_name(token.type); + fprintf(stderr, "not a %s\n", ebuffer); + print_page_and_filename(); + print_next_ten_tokens(); + } + longjmp(jmpbuf, 1); + fprintf(stderr, "Could not jump to Error Page\n"); + exit(-1); + } +} + + +#ifndef HTADD +static void +spad_error_handler(void) +{ + /* fprintf(stderr, "got a spad error\n"); */ + longjmp(jmpbuf, 1); + fprintf(stderr, "(HyperDoc) Fatal Error: Could not jump to Error Page.\n"); + exit(-1); +} + +extern int still_reading, str_len; +void +reset_connection(void) +{ + if (spad_socket) { + FD_CLR(spad_socket->socket, &socket_mask); + purpose_table[spad_socket->purpose] = NULL; + close(spad_socket->socket); + spad_socket->socket = 0; + spad_socket = NULL; + if (input_string) + input_string[0] = '\0'; + read_again = 0; + str_len = 0; + still_reading = 0; + connect_spad(); + } +} +#endif + + +/* returns true if spad is currently computing */ +int +spad_busy(void) +{ + if (session_server == NULL) + return 1; + send_int(session_server, QuerySpad); + return get_int(session_server); +} + +/* connect to AXIOM , return 0 if succesful, 1 if not */ +int +connect_spad(void) +{ + if (!MenuServerOpened) { + fprintf(stderr, "(HyperDoc) Warning: Not connected to AXIOM Server!\n"); + LoudBeepAtTheUser(); + return NotConnected; + } + if (spad_socket == NULL) { + spad_socket = connect_to_local_server(SpadServer, MenuServer, Forever); + if (spad_socket == NULL) { + fprintf(stderr, "(HyperDoc) Warning: Could not connect to AXIOM Server!\n"); + LoudBeepAtTheUser(); + return NotConnected; + } + } + /* if (spad_busy()) return SpadBusy; */ + return Connected; +} diff --git a/src/hyper/lex.h b/src/hyper/lex.h new file mode 100644 index 00000000..8cb3cf0a --- /dev/null +++ b/src/hyper/lex.h @@ -0,0 +1,46 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +#ifndef _LEX_H_ +#define _LEX_H_ 1 + +#include "hyper.h" + +extern HyperDocPage *gPageBeingParsed; + +extern short int gInSpadsrc; +extern short int gInVerbatim; + +#endif diff --git a/src/hyper/lex.pamphlet b/src/hyper/lex.pamphlet deleted file mode 100644 index df161580..00000000 --- a/src/hyper/lex.pamphlet +++ /dev/null @@ -1,933 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/lex} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{dumpToken function} -We need a function to print the token object for debugging. - -To use this function the caller provides its own name and the -token to be printed. For instance, a call would look like: -\begin{verbatim} -dumpToken("fnname",token) -\end{verbatim} -There is no return value. -<>= -void -dumpToken(char *caller, Token t) -{ fprintf(stderr,"%s:dumpToken type=%s id=%s\n", - caller,token_table[t.type],t.id); -} - -@ - -\section{lex.h} -<>= -<> -#ifndef _LEX_H_ -#define _LEX_H_ 1 - -#include "hyper.h" - -extern HyperDocPage *gPageBeingParsed; - -extern short int gInSpadsrc; -extern short int gInVerbatim; - -#endif -@ -\section{lex.c} -<>= -/* - * Lexical analyzer stuff. Exported functions: parser_init() -- - * initialize the parser tables with keywords init_scanner() -- - * initialize scanner for reading a new page get_token() -- - * sets the "token" variable to be the next -- token in the current input - * stream save_scanner_state( ) -- save the current state of scanner so - * that -- the scanner input mode may be switched restore_scanner_state() -- - * undo the saved state - * - * Note: The scanner reads from three seperate input locations depending on the - * value of the variable "input_type". If this variable is: - * - * FromFile -- it read from the file pointed to by "cfile". FromString - * -- It reads from the string "input_string". FromSpadSocket -- It reads - * from the socket pointed to by spad_socket FromFD -- It reads from a - * file descriptor - * - * - * New variable useAscii -- tells us if we we should translate - * graphics characters on the fly - * initialised in init_scanner - * - */ -#define _LEX_C -#include "axiom-c-macros.h" -#include "useproto.h" -#include "debug.h" - -int useAscii; - -#define PARSER 1 - -#include "hyper.h" -#include "hterror.h" -#include "lex.h" - -#include "all_hyper_proto.H1" -#include "sockio-c.H1" - - -#include -#include - -extern int gTtFontIs850; - - -StateNode *top_state_node; -HyperDocPage *gPageBeingParsed; /* page currently being parsed */ -extern jmp_buf jmpbuf; -extern char ebuffer[]; -short int gInSpadsrc = 0; -short int gInVerbatim; - -/* Parser variables */ -long fpos; /* Position of pointer in file in characters */ -long page_start_fpos; /* where the current pages fpos started */ -long keyword_fpos; /* fpos of beginning of most recent keyword */ -Token token; /* most recently read token */ -int last_token; /* most recently read token for unget_token */ -int input_type; /* indicates where to read input */ -char *input_string; /* input string read when from_string is true */ -int last_ch; /* last character read, for unget_char */ -int last_command; /* the last socket command */ -int keyword; /* the last command was a keyword, or a group */ -int cfd; /* current file decriptor */ -FILE *cfile; /* currently active file pointer */ -FILE *unixfd; -int line_number; - -char sock_buf[1024]; /* buffer for socket input */ - -#define TokenHashSize 100 - -static HashTable tokenHashTable; /* hash table of parser tokens */ - -<> - -/* initialize the parser keyword hash table */ -void -parser_init(void) -{ - int i; - Token *toke; - - /* First I initialize the hash table for the tokens */ - - hash_init( - &tokenHashTable, - TokenHashSize, - (EqualFunction)string_equal, - (HashcodeFunction)string_hash); - for (i = 2; i <= NumberUserTokens; i++) { - toke = (Token *) halloc(sizeof(Token), "Token"); - toke->type = i; - toke->id = token_table[i]; - hash_insert(&tokenHashTable, (char *)toke, toke->id); - } - -} - -/* initialize the lexical scanner to read from a file */ -void -init_scanner(void) -{ - if (getenv("HTASCII")) { - useAscii = (strcmp(getenv("HTASCII"), "yes") == 0); - } - else { - if(gTtFontIs850==1) useAscii = 0; - else useAscii = 1; - } - keyword = 0; - last_ch = NoChar; - last_token = 0; - input_type = FromFile; - fpos = 0; - keyword_fpos = 0; - last_command = -1; - line_number = 1; -} - -/* - * variables to save current state of scanner. Currently only one level of - * saving is allowed. In the future we should allow nested saves - */ - -/* save the current state of the scanner */ -void -save_scanner_state(void) -{ - StateNode *new_item = (StateNode *) halloc((sizeof(StateNode)), "StateNode"); - - new_item->page_start_fpos = page_start_fpos; - new_item->fpos = fpos; - new_item->keyword_fpos = keyword_fpos; - new_item->last_ch = last_ch; - new_item->last_token = last_token; - new_item->token = token; - new_item->input_type = input_type; - new_item->input_string = input_string; - new_item->cfile = cfile; - new_item->next = top_state_node; - new_item->keyword = keyword; - top_state_node = new_item; -} - -/* restore the saved scanner state */ -void -restore_scanner_state(void) -{ - StateNode *x = top_state_node; - - if (top_state_node == NULL) { - fprintf(stderr, "Restore Scanner State: State empty\n"); - exit(-1); - } - top_state_node = top_state_node->next; - page_start_fpos = x->page_start_fpos; - fpos = x->fpos; - keyword_fpos = x->keyword_fpos; - last_ch = x->last_ch; - last_token = x->last_token; - token = x->token; - input_type = x->input_type; - input_string = x->input_string; - cfile = x->cfile; - keyword = x->keyword; - if (cfile != NULL) - fseek(cfile, fpos + page_start_fpos, 0); - /** Once that is done, lets throw away some memory **/ - free(x); -} - -/* return the character to the input stream. */ -void -unget_char(int c) -{ - if (c == '\n') - line_number--; - last_ch = c; -} - -int -get_char(void) -{ - int c; - - c = get_char1(); - if (useAscii) { - switch (c) { - case 'Ä': - c = '-'; - break; - case 'Ú': - c = '+'; - break; - case 'Ã': - c = '['; - break; - case 'À': - c = '+'; - break; - case 'Â': - c = '-'; - break; - case 'Å': - c = '+'; - break; - case 'Á': - c = '-'; - break; - case '¿': - c = '+'; - break; - case '´': - c = ']'; - break; - case 'Ù': - c = '+'; - break; - case '³': - c = '|'; - break; - default: - break; - } - } - return c; -} - -char * read_again = 0; - -/* return the next character in the input stream */ -static int -get_char1(void) -{ - int c; - int cmd; - - if (last_ch != NoChar) { - c = last_ch; - last_ch = NoChar; - if (c == '\n') - line_number++; - return c; - } - switch (input_type) { - case FromUnixFD: - c = getc(unixfd); - if (c == '\n') - line_number++; - return c; - case FromString: - c = (*input_string ? *input_string++ : EOF); - if (c == '\n') - line_number++; - return c; - case FromFile: - c = getc(cfile); - fpos++; - if (c == '\n') - line_number++; - return c; - case FromSpadSocket: -AGAIN: - if (*input_string) { - /* this should never happen for the first character */ - c = *input_string++; - if (c == '\n') - line_number++; - return c; - } - if (last_command == EndOfPage) - return EOF; - if (read_again == NULL) { - last_command = cmd = get_int(spad_socket); - if (cmd == EndOfPage) - return EOF; -#ifndef HTADD - if (cmd == SpadError) - spad_error_handler(); -#endif - } - read_again = get_string_buf(spad_socket, sock_buf, 1023); - /* this will be null if this is the last time*/ - input_string = sock_buf; - goto AGAIN; - default: - fprintf(stderr, "Get Char: Unknown type of input: %d\n", input_type); - return -1; - } -} - - -#define special(c) ((c) == '{' || (c) == '}' || (c) == '#' || (c) == '%' || \ - (c) == '\\' || (c) == '[' || (c) == ']' || (c) == '_' || \ - (c) == ' ' || (c) == '$' || (c) == '~' || (c) == '^' || \ - (c) == '&') - -#define punctuation(c) ((c)== '`' || (c) == '\'' || (c) == ',' || \ - (c) == '.' || (c) == '?' || (c) == '"' || \ - (c) == ';' || (c) == ':' || (c) == '-') - -#define whitespace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n') -#define delim(c) \ - (whitespace(c) || special(c) || punctuation(c)) - - - -Token unget_toke; - -/* return current token to the input stream */ -void -unget_token(void) -{ - last_token = 1; - unget_toke.type = token.type; - unget_toke.id = alloc_string(token.id - 1); -} - - -int -get_token(void) -{ - int c, ws; - int nls = 0; - static int seen_white = 0; - static char buffer[1024]; - char *buf = buffer; - - if (last_token) { - last_token = 0; - token.type = unget_toke.type; - strcpy(buffer, unget_toke.id); - free(unget_toke.id); - token.id = buffer + 1; - if (token.type == EOF) - return EOF; - else - return 0; - } - seen_white = nls = 0; - do { - c = get_char(); - ws = whitespace(c); - if (ws) - seen_white++; - if (c == '\n') { - if (nls) { - token.type = Par; - return 0; - } - else - nls++; - } - } while (ws); - - /* first character of string indicates number of spaces before token */ - - if (!keyword) - *buf++ = seen_white; - else - *buf++ = 0; - - keyword = 0; - if (input_type != FromSpadSocket && c == '%') { - while ((c = get_char()) != '\n' && c != EOF); -/* trying to fix the comment problem: a comment line forces words on either side together*/ -/* try returning the eol */ - unget_char(c); - return get_token(); - } - if (input_type == FromFile && c == '$') { - token.type = Dollar; - return 0; - } - switch (c) { - case EOF: - token.type = -1; - return EOF; - case '\\': - keyword_fpos = fpos - 1; - c = get_char(); - if (!isalpha(c)) { - *buf++ = c; - token.type = Word; - *buf = '\0'; - seen_white = 0; - } - else { - do { - *buf++ = c; - } while ((c = get_char()) != EOF && isalpha(c)); - - unget_char(c); - *buf = '\0'; - keyword = 1; - token.id = buffer + 1; - return (keyword_type()); - } - break; - case '{': - token.type = Lbrace; - break; - case '}': - token.type = Rbrace; - break; - case '[': - token.type = Lsquarebrace; - *buf++ = c; - *buf = '\0'; - token.id = buffer + 1; - break; - case ']': - token.type = Rsquarebrace; - *buf++ = c; - *buf = '\0'; - token.id = buffer + 1; - break; - case '#': - token.type = Pound; - - /* - * if I get a pound then what I do is parse until I get something - * that is not an integer - */ - c = get_char(); - while (isdigit(c) && (c != EOF)) { - *buf++ = c; - c = get_char(); - } - unget_char(c); - *buf = '\0'; - token.id = buffer + 1; - break; - case '`': - case '\'': - case ',': - case '.': - case '!': - case '?': - case '"': - case ':': - case ';': - token.type = Punctuation; - *buf++ = c; - *buf = '\0'; - /** Now I should set the buffer[0] as my flag for whether I had - white-space in front of me, and whether I had white space - behind me **/ - if (buffer[0]) - buffer[0] = FRONTSPACE; - c = get_char(); - if (whitespace(c)) - buffer[0] |= BACKSPACE; - unget_char(c); - token.id = buffer + 1; - break; - case '-': - do { - *buf++ = c; - } while (((c = get_char()) != EOF) && (c == '-')); - unget_char(c); - *buf = '\0'; - token.type = Dash; - token.id = buffer + 1; - break; - default: - do { - *buf++ = c; - } while ((c = get_char()) != EOF && !delim(c)); - unget_char(c); - *buf = '\0'; - token.type = Word; - token.id = buffer + 1; - break; - } -/* dumpToken("get_token",token);*/ - return 0; -} - - -/* - * Here are the structures and stuff needed for the begin and end routines. - * The stack stores the begin types that have been seen and the end - * pops them off and checks to insure that they are reversed properly. - */ - -typedef struct be_struct { - int type; - char *id; - struct be_struct *next; -} BeStruct; - -BeStruct *top_be_stack; - - -void -push_be_stack(int type,char * id) -{ - BeStruct *be = (BeStruct *) halloc(sizeof(BeStruct), "BeginENd stack"); - - if (gWindow != NULL) { - be->type = type; - be->next = top_be_stack; - be->id = alloc_string(id); - top_be_stack = be; - } - return; -} -void -check_and_pop_be_stack(int type,char * id) -{ - BeStruct *x; - - /* - * this routine pops the be stack and compares types. If they are - * the same then I am okay and return a 1. Else I return a two and try to - * print a meaningful message - */ - if (gWindow == NULL) - return; - if (top_be_stack == NULL) { /* tried to pop when I shouldn't have */ - fprintf(stderr, "Unexpected \\end{%s} \n", token.id); - print_page_and_filename(); - print_next_ten_tokens(); - jump(); - } - x = top_be_stack; - if (x->type == type) { - top_be_stack = top_be_stack->next; - free(x->id); - free(x); - return; - } - /* else I didn't have a match. Lets try to write a sensible message */ - fprintf(stderr, "\\begin{%s} ended with \\end{%s} \n", x->id, id); - print_page_and_filename(); - print_next_ten_tokens(); - jump(); -} - -int -clear_be_stack(void) -{ - BeStruct *x = top_be_stack, *y; - - top_be_stack = NULL; - while (x != NULL) { - y = x->next; - free(x); - x = y; - } - return 1; -} - -int -be_type(char *which) -{ - Token store; - - get_expected_token(Lbrace); - get_expected_token(Word); - switch (token.id[0]) { - case 't': - if (!strcmp(token.id, "titems")) { - token.type = Begintitems; - } - else { - return -1; - } - break; - case 'p': - if (!strcmp(token.id, "page")) { - token.type = Page; - } - else if (!strcmp(token.id, "paste")) { - token.type = Paste; - } - else if (!strcmp(token.id, "patch")) { - token.type = Patch; - } - else { - return -1; - } - break; - case 'v': /* possibly a verbatim mode */ - if (!strcmp(token.id, "verbatim")) { - token.type = Verbatim; - } - else { - return -1; - } - break; - case 's': /* possibly a scroll mode */ - if (!strcmp("scroll", token.id)) { - token.type = Beginscroll; - } - else if (!strcmp(token.id, "spadsrc")) { - token.type = Spadsrc; - } - else { - return -1; - } - break; - case 'i': /* possibly a item */ - if (!strcmp("items", token.id)) { - token.type = Beginitems; - } - else { - return -1; - } - break; - default: - return -1; - } - store.type = token.type; - /* store.id = alloc_string(token.id); */ - get_expected_token(Rbrace); - token.type = store.type; - - /* - * strcpy(token.id, store.id); free(store.id); - */ - return 0; - -} -int -begin_type(void) -{ - /*Token store;*/ - int ret_val; - - /* - * This routine parses a statement of the form \begin{word}. Once it has - * read the word it tries to assign it a type. Once that is done it sends - * the word id, and the type to push_be_stack and then returns the type. - * For the moment I amnot even going to use a has_table, although in the - * future this may be needed - */ - ret_val = be_type("begin"); - if (ret_val == -1) { - if (gWindow == NULL || gInVerbatim) - return 1; - else { - fprintf(stderr, "Unknown begin type \\begin{%s} \n", token.id); - print_page_and_filename(); - print_next_ten_tokens(); - jump(); - } - } - else { - if (gWindow != NULL && !gInVerbatim && token.type != Verbatim - && token.type != Spadsrc) { - /* Now here I should push the needed info and then get */ - push_be_stack(token.type, token.id); - } - return 1; - } - return 1; -} - - -int -end_type(void) -{ - int ret; - - /* - * This routine gets the end type just as the begin_type routine does, - * But then it checks to see if recieved the proper end_type. By a clever - * trick, the proper end type is 3000 + type. When environments this will - * have to change - */ - ret = be_type("end"); - if (ret == -1) { - /* unrecognized end token */ - if (gWindow == NULL || gInVerbatim) { - return 1; - } - else { - fprintf(stderr, "Unknown begin type \\begin{%s} \n", token.id); - print_page_and_filename(); - print_next_ten_tokens(); - jump(); - } - } - else { - if (gWindow != NULL && !gInVerbatim) { - check_and_pop_be_stack(token.type, token.id); - token.type += 3000; - return 1; - } - else { - if (gWindow != NULL && ((gInVerbatim && token.type == Verbatim) || - (gInSpadsrc && token.type == Spadsrc))) { - check_and_pop_be_stack(token.type, token.id); - token.type += 3000; - return 1; - } - else { - token.type += 3000; - return 1; - } - } - } - return 1; -} - - - -static int -keyword_type(void) -{ - Token *token_ent; - - /* first check to see if it is a reserved token */ - token_ent = (Token *) hash_find(&tokenHashTable, token.id); - if (token_ent != NULL) { - token.type = token_ent->type; - - /* - * if I am a keyword I also have to check to see if I am a begin or - * an end - */ - if (token.type == Begin) - return begin_type(); - if (token.type == End) - return end_type(); - /* next check to see if it is a macro */ - } - else if (gWindow != NULL) { - if (hash_find(gWindow->fMacroHashTable, token.id) != NULL) - token.type = Macro; - else if (gPageBeingParsed->box_hash != NULL && - hash_find(gPageBeingParsed->box_hash, token.id) != NULL) - { - token.type = Boxcond; - } - else if (hash_find(gWindow->fCondHashTable, token.id) != NULL) - token.type = Cond; - else /* We have no idea what we've got */ - token.type = Unkeyword; - } - else { /* We am probably in htadd so just return. It - * is only concerned with pages anyway */ - token.type = Unkeyword; - } - return 0; -} - -/* read a token, and report a syntax error if it has the wrong type */ -void -get_expected_token(int type) -{ - get_token(); - if (token.type != type) { - token_name(type); - fprintf(stderr, "syntax error: expected a %s\n", ebuffer); - if (token.type == EOF) { - print_page_and_filename(); - fprintf(stderr, "Unexpected EOF\n"); - } - else { - token_name(token.type); - fprintf(stderr, "not a %s\n", ebuffer); - print_page_and_filename(); - print_next_ten_tokens(); - } - longjmp(jmpbuf, 1); - fprintf(stderr, "Could not jump to Error Page\n"); - exit(-1); - } -} - - -#ifndef HTADD -static void -spad_error_handler(void) -{ - /* fprintf(stderr, "got a spad error\n"); */ - longjmp(jmpbuf, 1); - fprintf(stderr, "(HyperDoc) Fatal Error: Could not jump to Error Page.\n"); - exit(-1); -} - -extern int still_reading, str_len; -void -reset_connection(void) -{ - if (spad_socket) { - FD_CLR(spad_socket->socket, &socket_mask); - purpose_table[spad_socket->purpose] = NULL; - close(spad_socket->socket); - spad_socket->socket = 0; - spad_socket = NULL; - if (input_string) - input_string[0] = '\0'; - read_again = 0; - str_len = 0; - still_reading = 0; - connect_spad(); - } -} -#endif - - -/* returns true if spad is currently computing */ -int -spad_busy(void) -{ - if (session_server == NULL) - return 1; - send_int(session_server, QuerySpad); - return get_int(session_server); -} - -/* connect to AXIOM , return 0 if succesful, 1 if not */ -int -connect_spad(void) -{ - if (!MenuServerOpened) { - fprintf(stderr, "(HyperDoc) Warning: Not connected to AXIOM Server!\n"); - LoudBeepAtTheUser(); - return NotConnected; - } - if (spad_socket == NULL) { - spad_socket = connect_to_local_server(SpadServer, MenuServer, Forever); - if (spad_socket == NULL) { - fprintf(stderr, "(HyperDoc) Warning: Could not connect to AXIOM Server!\n"); - LoudBeepAtTheUser(); - return NotConnected; - } - } - /* if (spad_busy()) return SpadBusy; */ - return Connected; -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/macro.c b/src/hyper/macro.c new file mode 100644 index 00000000..80bd3dc6 --- /dev/null +++ b/src/hyper/macro.c @@ -0,0 +1,392 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +#define _MACRO_C +#include "axiom-c-macros.h" +#include "useproto.h" +#include "debug.h" + +#include "parse.h" +#include "hyper.h" + +#include "all_hyper_proto.H1" + + +/* #define DEBUG 1 */ +extern FILE *cfile; + + +/* + * This routine keeps scanning until it reaches it pops off 1 more + * right brace then left brace + */ +void +scan_HyperDoc(void) +{ + HDWindow *twin = gWindow; + int ret_val; + int number_of_left_braces = 1; + + gWindow = NULL; + while (number_of_left_braces) { + ret_val = get_token(); + if (ret_val == EOF && number_of_left_braces) { + fprintf(stderr, "Scan_Hypertex: Unexpected End of File\n"); + longjmp(jmpbuf, 1); + } + switch (token.type) { + case Page: + fprintf(stderr, "scan_HyperDoc: Unexpected Page Declaration\n"); + break; + case NewCommand: + fprintf(stderr, "scan_HyperDoc: Unexpected Macro Declaration\n"); + break; + case Lbrace: + number_of_left_braces++; + break; + case Endpatch: + case Rbrace: + number_of_left_braces--; + break; + default: + break; + } + } + gWindow = twin; +} + +int +number(char *str) +{ + char *t = str; + + while (*t) + if (!isdigit(*t++)) + return 0; + return 1; +} + +/* Parse a given macro given the pointer to the unlaoded macro ** */ + +static char * +load_macro(MacroStore *macro) +{ + int ret_val; + long start_fpos; + int size = 0; + char *trace; + char *macro_buff; + + save_scanner_state(); + cfile = find_fp(macro->fpos); + + + init_scanner(); + + /** First thing I should do is make sure that the name is correct ***/ + get_expected_token(NewCommand); + get_expected_token(Lbrace); + get_expected_token(Macro); + if (strcmp(token.id, macro->name)) { + /** WOW, Somehow I had the location of the wrong macro **/ + fprintf(stderr, "Expected macro name %s got insted %s in load_macro\n", + macro->name, token.id); + longjmp(jmpbuf, 1); + } + get_expected_token(Rbrace); + + /** Next I should check to see if I have any parameters **/ + get_token(); + if (token.type == Lsquarebrace) { + /** The person is telling me the number of macros he is going to use **/ + get_expected_token(Word); + if (!number(token.id)) { + fprintf(stderr, "load_macro: Expected A Value Instead Got %s\n", + token.id); + longjmp(jmpbuf, 1); + } + /** if it is a number, then I should store it in the parameter number + member of the macro structure **/ + macro->number_parameters = atoi(token.id); +#ifdef DEBUG + fprintf(stderr, + "The number of parameters is %d\n", macro->number_parameters); +#endif + get_expected_token(Rsquarebrace); + get_token(); + } + else + macro->number_parameters = 0; + + /*** Now I should be able to check the token, and insure that I have read + a leftbrace, then the string will follow ****/ + if (token.type != Lbrace) { + /** The macro is not in a group, uh oh **/ + fprintf(stderr, "load_macro:Expected a Left Brace got type %d\n", + token.type); + longjmp(jmpbuf, 1); + } + start_fpos = fpos; + scan_HyperDoc(); + ret_val = fseek(cfile, macro->fpos.pos + start_fpos, 0); + size = fpos - start_fpos; + macro_buff = (char *) halloc((size + 1) * sizeof(char), "Macro_buf"); + for (size = 0, trace = macro_buff; size < fpos - (start_fpos) - 1; size++) + *trace++ = getc(cfile); + *trace = '\0'; + macro->loaded = 1; + restore_scanner_state(); + return macro_buff; +} + + +/** Here are the functions and declarations for the parameter stack **/ +ParameterList parameters = NULL; + +ParameterList +init_parameter_elem(int number) +{ + ParameterList new; + int count; + + /** allocate the space neeeded **/ + new = (ParameterList) halloc(sizeof(struct parameter_list_type), + "ParameterList"); + /** now allocate the memeory for the pointers to the parameters **/ + if (number) { + new->list = (char **) halloc(number * sizeof(char *), "Parameter List"); + + /** initialize my pointers **/ + for (count = 0; count < number; count++) + (new->list)[count] = NULL; + } + new->number = number; + return new; +} + +int +push_parameters(ParameterList new) +{ + + if (new == NULL) { + fprintf(stderr, "Tried pushing a null list onto the parameter stack\n"); + longjmp(jmpbuf, 1); + } + + new->next = parameters; + parameters = new; + return 1; +} +int +pop_parameters(void) +{ + /** Simply pops the top of the parameter list, being good and freeing + all the memory **/ + ParameterList old; + int count; + + if (!parameters) { + return 0; + } + + old = parameters; + parameters = old->next; + + /** Free the parameter text and pointers **/ + if (old->number >0) { + for (count = 0; count < old->number; count++) + if ( (old->list)[count] ) free((char *) (old->list)[count]); + free(old->list); + } + + free(old); /** free the parameter **/ + + return 1; +} + +int +parse_macro(void) +{ + + /* + * This routine loads a macro if needed, and then parses it from the + * string + */ + MacroStore *macro; + int s; + + curr_node->type = Macro; + curr_node->space = token.id[-1]; + curr_node->next = alloc_node(); + curr_node = curr_node->next; + macro = (MacroStore *) hash_find(gWindow->fMacroHashTable, token.id); + if (macro != NULL) { + if (!macro->loaded) + macro->macro_string = load_macro(macro); + get_parameter_strings(macro->number_parameters, macro->name); + parse_from_string(macro->macro_string); + if (gEndedPage) { + s = curr_node->type; + curr_node->type = Endmacro; + curr_node->next = alloc_node(); + curr_node = curr_node->next; + curr_node->type = s; + } + else + curr_node->type = Endmacro; + if (pop_parameters()) + return 1; + else { + fprintf(stderr, + "parse_macro: Tried to pop an empty paramter stack\n"); + longjmp(jmpbuf, 1); + } + } + else { + fprintf(stderr, "parse_macro: Unknown keyword %s\n", token.id); + longjmp(jmpbuf, 1); + } +} + +#define numeric(c) ((c >= '0' && c <= '9')?1:0) + +static void +get_parameter_strings(int number,char * macro_name) +{ + static char buffer[4096]; + char *buffer_pntr; + int count; + int lbrace_counter; + char c; + int size; + ParameterList new = init_parameter_elem(number); + int pnum; + char pnum_chars[5]; + int pc; + + if (!number) { /* nothing to be done */ + push_parameters(new); + return; + } + for (count = 0; count < number; count++) { + get_token(); + if (token.type != Lbrace) { + /** The macro is not in a group, uh oh **/ + fprintf(stderr, "Wrong number of arguments to the macro %s\n", + macro_name); + jump(); + } + for (lbrace_counter = 1, buffer_pntr = buffer; + lbrace_counter;) { + switch (c = get_char()) { + case EOF: + fprintf(stderr, "GetParameterStrings: Unexpected EOF\n"); + longjmp(jmpbuf, 1); + case '}': + lbrace_counter--; + if (lbrace_counter) + *buffer_pntr++ = c; + break; + case '{': + lbrace_counter++; + *buffer_pntr++ = c; + break; + case '#': + /* uh oh, I have a paramter reference inside a paramter */ + /* get the number */ + if (parameters == NULL) { + *buffer_pntr++ = c; + break; + } + if ( + ((buffer_pntr > buffer + 1) && + *(buffer_pntr - 1) == '\\' && + *(buffer_pntr - 2) != '\\') || + ((buffer_pntr > buffer) && + *(buffer_pntr - 1) == '\\')) { + /* I had a \# */ + *buffer_pntr++ = c; + } + else { + c = get_char(); + for (pc = 0; numeric(c); pc++) { + pnum_chars[pc] = c; + c = get_char(); + } + unget_char(c); + pnum_chars[pc] = '\0'; + pnum = atoi(pnum_chars); + pc = 0; + /* Now copy the paramter */ + while ((parameters->list)[pnum - 1][pc] != '\0') + *buffer_pntr++ = (parameters->list)[pnum - 1][pc++]; + } + break; + default: + *buffer_pntr++ = c; + break; + } + } + *buffer_pntr = '\0'; + /*** Now add it to the current parameter list **/ + size = strlen(buffer) + 1; + new->list[count] = (char *) halloc(size, "Parameter Strings"); + strcpy(new->list[count], buffer); + } + push_parameters(new); + return ; +} +void +parse_parameters(void) +{ + int value; + + if (!number(token.id)) { + fprintf(stderr, + "Parse_parameter: Error Expected a number, got %s instead\n", token.id); + longjmp(jmpbuf, 1); + } + + if ((value = atoi(token.id)) > parameters->number) { + /** had a bad parameter number **/ + fprintf(stderr, + "Parse_parameter: Had a bad parameter number %d\n", value); + longjmp(jmpbuf, 1); + } + + parse_from_string((parameters->list)[value - 1]); + curr_node->type = Endparameter; + return; +} diff --git a/src/hyper/macro.pamphlet b/src/hyper/macro.pamphlet deleted file mode 100644 index 43b7ef8d..00000000 --- a/src/hyper/macro.pamphlet +++ /dev/null @@ -1,421 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/macro} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{macro.c} -<>= -#define _MACRO_C -#include "axiom-c-macros.h" -#include "useproto.h" -#include "debug.h" - -#include "parse.h" -#include "parse-aux.h" -#include "mem.h" - -#include "all_hyper_proto.H1" - - -/* #define DEBUG 1 */ -extern FILE *cfile; - - -/* - * This routine keeps scanning until it reaches it pops off 1 more - * right brace then left brace - */ -void -scan_HyperDoc(void) -{ - HDWindow *twin = gWindow; - int ret_val; - int number_of_left_braces = 1; - - gWindow = NULL; - while (number_of_left_braces) { - ret_val = get_token(); - if (ret_val == EOF && number_of_left_braces) { - fprintf(stderr, "Scan_Hypertex: Unexpected End of File\n"); - longjmp(jmpbuf, 1); - } - switch (token.type) { - case Page: - fprintf(stderr, "scan_HyperDoc: Unexpected Page Declaration\n"); - break; - case NewCommand: - fprintf(stderr, "scan_HyperDoc: Unexpected Macro Declaration\n"); - break; - case Lbrace: - number_of_left_braces++; - break; - case Endpatch: - case Rbrace: - number_of_left_braces--; - break; - default: - break; - } - } - gWindow = twin; -} - -int -number(char *str) -{ - char *t = str; - - while (*t) - if (!isdigit(*t++)) - return 0; - return 1; -} - -/* Parse a given macro given the pointer to the unlaoded macro ** */ - -static char * -load_macro(MacroStore *macro) -{ - int ret_val; - long start_fpos; - int size = 0; - char *trace; - char *macro_buff; - - save_scanner_state(); - cfile = find_fp(macro->fpos); - - - init_scanner(); - - /** First thing I should do is make sure that the name is correct ***/ - get_expected_token(NewCommand); - get_expected_token(Lbrace); - get_expected_token(Macro); - if (strcmp(token.id, macro->name)) { - /** WOW, Somehow I had the location of the wrong macro **/ - fprintf(stderr, "Expected macro name %s got insted %s in load_macro\n", - macro->name, token.id); - longjmp(jmpbuf, 1); - } - get_expected_token(Rbrace); - - /** Next I should check to see if I have any parameters **/ - get_token(); - if (token.type == Lsquarebrace) { - /** The person is telling me the number of macros he is going to use **/ - get_expected_token(Word); - if (!number(token.id)) { - fprintf(stderr, "load_macro: Expected A Value Instead Got %s\n", - token.id); - longjmp(jmpbuf, 1); - } - /** if it is a number, then I should store it in the parameter number - member of the macro structure **/ - macro->number_parameters = atoi(token.id); -#ifdef DEBUG - fprintf(stderr, - "The number of parameters is %d\n", macro->number_parameters); -#endif - get_expected_token(Rsquarebrace); - get_token(); - } - else - macro->number_parameters = 0; - - /*** Now I should be able to check the token, and insure that I have read - a leftbrace, then the string will follow ****/ - if (token.type != Lbrace) { - /** The macro is not in a group, uh oh **/ - fprintf(stderr, "load_macro:Expected a Left Brace got type %d\n", - token.type); - longjmp(jmpbuf, 1); - } - start_fpos = fpos; - scan_HyperDoc(); - ret_val = fseek(cfile, macro->fpos.pos + start_fpos, 0); - size = fpos - start_fpos; - macro_buff = (char *) halloc((size + 1) * sizeof(char), "Macro_buf"); - for (size = 0, trace = macro_buff; size < fpos - (start_fpos) - 1; size++) - *trace++ = getc(cfile); - *trace = '\0'; - macro->loaded = 1; - restore_scanner_state(); - return macro_buff; -} - - -/** Here are the functions and declarations for the parameter stack **/ -ParameterList parameters = NULL; - -ParameterList -init_parameter_elem(int number) -{ - ParameterList new; - int count; - - /** allocate the space neeeded **/ - new = (ParameterList) halloc(sizeof(struct parameter_list_type), - "ParameterList"); - /** now allocate the memeory for the pointers to the parameters **/ - if (number) { - new->list = (char **) halloc(number * sizeof(char *), "Parameter List"); - - /** initialize my pointers **/ - for (count = 0; count < number; count++) - (new->list)[count] = NULL; - } - new->number = number; - return new; -} - -int -push_parameters(ParameterList new) -{ - - if (new == NULL) { - fprintf(stderr, "Tried pushing a null list onto the parameter stack\n"); - longjmp(jmpbuf, 1); - } - - new->next = parameters; - parameters = new; - return 1; -} -int -pop_parameters(void) -{ - /** Simply pops the top of the parameter list, being good and freeing - all the memory **/ - ParameterList old; - int count; - - if (!parameters) { - return 0; - } - - old = parameters; - parameters = old->next; - - /** Free the parameter text and pointers **/ - if (old->number >0) { - for (count = 0; count < old->number; count++) - if ( (old->list)[count] ) free((char *) (old->list)[count]); - free(old->list); - } - - free(old); /** free the parameter **/ - - return 1; -} - -int -parse_macro(void) -{ - - /* - * This routine loads a macro if needed, and then parses it from the - * string - */ - MacroStore *macro; - int s; - - curr_node->type = Macro; - curr_node->space = token.id[-1]; - curr_node->next = alloc_node(); - curr_node = curr_node->next; - macro = (MacroStore *) hash_find(gWindow->fMacroHashTable, token.id); - if (macro != NULL) { - if (!macro->loaded) - macro->macro_string = load_macro(macro); - get_parameter_strings(macro->number_parameters, macro->name); - parse_from_string(macro->macro_string); - if (gEndedPage) { - s = curr_node->type; - curr_node->type = Endmacro; - curr_node->next = alloc_node(); - curr_node = curr_node->next; - curr_node->type = s; - } - else - curr_node->type = Endmacro; - if (pop_parameters()) - return 1; - else { - fprintf(stderr, - "parse_macro: Tried to pop an empty paramter stack\n"); - longjmp(jmpbuf, 1); - } - } - else { - fprintf(stderr, "parse_macro: Unknown keyword %s\n", token.id); - longjmp(jmpbuf, 1); - } -} - -#define numeric(c) ((c >= '0' && c <= '9')?1:0) - -static void -get_parameter_strings(int number,char * macro_name) -{ - static char buffer[4096]; - char *buffer_pntr; - int count; - int lbrace_counter; - char c; - int size; - ParameterList new = init_parameter_elem(number); - int pnum; - char pnum_chars[5]; - int pc; - - if (!number) { /* nothing to be done */ - push_parameters(new); - return; - } - for (count = 0; count < number; count++) { - get_token(); - if (token.type != Lbrace) { - /** The macro is not in a group, uh oh **/ - fprintf(stderr, "Wrong number of arguments to the macro %s\n", - macro_name); - jump(); - } - for (lbrace_counter = 1, buffer_pntr = buffer; - lbrace_counter;) { - switch (c = get_char()) { - case EOF: - fprintf(stderr, "GetParameterStrings: Unexpected EOF\n"); - longjmp(jmpbuf, 1); - case '}': - lbrace_counter--; - if (lbrace_counter) - *buffer_pntr++ = c; - break; - case '{': - lbrace_counter++; - *buffer_pntr++ = c; - break; - case '#': - /* uh oh, I have a paramter reference inside a paramter */ - /* get the number */ - if (parameters == NULL) { - *buffer_pntr++ = c; - break; - } - if ( - ((buffer_pntr > buffer + 1) && - *(buffer_pntr - 1) == '\\' && - *(buffer_pntr - 2) != '\\') || - ((buffer_pntr > buffer) && - *(buffer_pntr - 1) == '\\')) { - /* I had a \# */ - *buffer_pntr++ = c; - } - else { - c = get_char(); - for (pc = 0; numeric(c); pc++) { - pnum_chars[pc] = c; - c = get_char(); - } - unget_char(c); - pnum_chars[pc] = '\0'; - pnum = atoi(pnum_chars); - pc = 0; - /* Now copy the paramter */ - while ((parameters->list)[pnum - 1][pc] != '\0') - *buffer_pntr++ = (parameters->list)[pnum - 1][pc++]; - } - break; - default: - *buffer_pntr++ = c; - break; - } - } - *buffer_pntr = '\0'; - /*** Now add it to the current parameter list **/ - size = strlen(buffer) + 1; - new->list[count] = (char *) halloc(size, "Parameter Strings"); - strcpy(new->list[count], buffer); - } - push_parameters(new); - return ; -} -void -parse_parameters(void) -{ - int value; - - if (!number(token.id)) { - fprintf(stderr, - "Parse_parameter: Error Expected a number, got %s instead\n", token.id); - longjmp(jmpbuf, 1); - } - - if ((value = atoi(token.id)) > parameters->number) { - /** had a bad parameter number **/ - fprintf(stderr, - "Parse_parameter: Had a bad parameter number %d\n", value); - longjmp(jmpbuf, 1); - } - - parse_from_string((parameters->list)[value - 1]); - curr_node->type = Endparameter; - return; -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/mem.c b/src/hyper/mem.c new file mode 100644 index 00000000..6f2cb646 --- /dev/null +++ b/src/hyper/mem.c @@ -0,0 +1,747 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + All rights reversed. + + 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. +*/ + +/****************************************************************************** + * + * mem.c: HyperDoc Memory Management Routines. + * + * Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993. + * + ****************************************************************************/ +#define _MEM_C +#include "useproto.h" +#include "debug.h" + + +#include "hyper.h" +#include "group.h" +#include "event.h" + +#include "all_hyper_proto.H1" + + + +extern HashTable init_page_hash; +extern HashTable init_macro_hash; +extern HashTable init_patch_hash; + + +static void +free_if_non_NULL(void *p) +{ + if (p){ + free(p); + } +} + + +/* allocate an HDWindow Structure and initialize it */ + +HDWindow * +alloc_hd_window(void) +{ + HDWindow *w = (HDWindow *) halloc(sizeof(HDWindow), "HDWindow"); + /*char haslisp[10];*/ + + w->fMemoStack = (HyperDocPage **) + halloc(MaxMemoDepth * sizeof(HyperDocPage *), "Memo Stack"); + w->fDownLinkStack = (HyperDocPage **) + halloc(MaxDownlinkDepth * sizeof(HyperDocPage *), "downlink stack"); + w->fDownLinkStackTop = + (int *) halloc(MaxDownlinkDepth * sizeof(int), "top downlink stack"); + w->fAxiomFrame = 0; + init_page_structs(w); + + /* Now I initialize the hash tables for the page */ + w->fCondHashTable = (HashTable *) halloc(sizeof(HashTable), "cond hash"); + hash_init( + w->fCondHashTable, + CondHashSize, + (EqualFunction) string_equal, + (HashcodeFunction) string_hash); + + w->fPasteHashTable = (HashTable *) halloc(sizeof(HashTable), "paste hash"); + hash_init( + w->fPasteHashTable, + PasteHashSize, + (EqualFunction) string_equal, + (HashcodeFunction) string_hash); + w->fPageHashTable = hash_copy_table(&init_page_hash); + w->fPatchHashTable = hash_copy_table(&init_patch_hash); + w->fMacroHashTable = hash_copy_table(&init_macro_hash); + + gWindow = w; + /*sprintf(haslisp, "%1d\0", MenuServerOpened);*/ + make_special_pages(w->fPageHashTable); + w->fDisplayedCursor = 0; + return w; +} + +void +free_hd_window(HDWindow *w) +{ + if (w) { + free(w->fMemoStack); + free(w->fDownLinkStack); + free(w->fDownLinkStackTop); + /* + free(w->fWindowHashTable); will be taken care of by freeing + free_hash(w->fPageHashTable, free_page); below + cf free_page + */ + free_hash(w->fMacroHashTable, (FreeFunction)dont_free); + free_hash(w->fPasteHashTable, (FreeFunction)dont_free); + free_hash(w->fPatchHashTable, (FreeFunction)dont_free); + + free_hash(w->fCondHashTable, (FreeFunction)free_cond); + free_hash(w->fPageHashTable, (FreeFunction)free_page); + free(w->fPageHashTable); + free(w->fPatchHashTable); + free(w->fMacroHashTable); + XFreeGC(gXDisplay, w->fStandardGC); + XFreeGC(gXDisplay, w->fInputGC); + XFreeGC(gXDisplay, w->fCursorGC); + XFreeGC(gXDisplay, w->fControlGC); + free(w); + } +} + + +/* Allocate an empty text node */ + +TextNode * +alloc_node(void) +{ + TextNode *temp_node; + + temp_node = (TextNode *) halloc(sizeof(TextNode), "Text Node"); + temp_node->type = 0; + temp_node->space = 0; + temp_node->height = 0; + temp_node->width = 0; + temp_node->x = -1; + temp_node->y = -1; + temp_node->data.node = NULL; + temp_node->next = NULL; + temp_node->link = NULL; + temp_node->image.pm = 0; + return temp_node; +} + +void +free_node(TextNode *node, short int des) +{ + + if (node == NULL) + return; + + switch (node->type) { + case Paste: + free_pastearea(node, des); + free_node(node->next, des); + break; + case Pastebutton: + free_pastebutton(node, des); + free_node(node->next, des); + break; + case Ifcond: + free_node(node->data.ifnode->cond, des); + free_node(node->data.ifnode->thennode, des); + free_node(node->data.ifnode->elsenode, des); + break; + case Dash: + case Lsquarebrace: + case Word: + case WindowId: + case Punctuation: + case Lbrace: + case Rbrace: + case SimpleBox: + case Verbatim: + case Math: + case Spadsrctxt: + case Spadsrc: + free_if_non_NULL(node->data.text); + free_node(node->next, des); + break; + case Inputstring: + if (des) + delete_item(node->data.text); + free_if_non_NULL(node->data.text); + free_node(node->next, des); + break; + case It: + case Sl: + case Tt: + case Rm: + case Emphasize: + case Beep: + case BoldFace: + case Par: + case Newline: + case Horizontalline: + case Item: + case Beginscroll: + case Endscroll: + case Group: + case Table: + case Macro: + case Pound: + case Center: + case Box: + case Mbox: + case Tableitem: + case Scrollingnode: + case Headernode: + case Titlenode: + case Footernode: + case Controlbitmap: + case Fi: + case Description: + case Rsquarebrace: + case Endpaste: + case Endpastebutton: + free_node(node->next, des); + break; + case Inputbitmap: + case Inputpixmap: + free_if_non_NULL(node->data.text); + free_node(node->next, des); + break; + case Quitbutton: + case Helpbutton: + case Upbutton: + case Returnbutton: + if (des && node->link->win) { + hash_delete(gWindow->page->fLinkHashTable,(char *) &node->link->win); + XDestroyWindow(gXDisplay, node->link->win); + } + free_if_non_NULL(node->link); + free_node(node->next, des); + break; + case Memolink: + case Downlink: + case Windowlink: + case Link: + case Lisplink: + case Lispwindowlink: + case Spadcall: + case Spadcallquit: + case LispMemoLink: + case Lispcommand: + case Lispcommandquit: + case LispDownLink: + case Unixlink: + case Spadlink: + case Spadmemolink: + case Spaddownlink: + case Unixcommand: + case Spadcommand: + case Spadgraph: + if (des && node->link->win) { + hash_delete(gWindow->page->fLinkHashTable,(char *) &node->link->win); + XDestroyWindow(gXDisplay, node->link->win); + } + /* TTT don't free the link before freeing nodes off it */ + /* free_node(node->link->reference.node);*/ + free_if_non_NULL(node->link); + free_node(node->next, des); + break; + case Free: + case Indent: + case Indentrel: + case HSpace: + case Space: + case VSpace: + case Button: + case Bound: + case Tab: + free_node(node->next, des); + free_node(node->data.node, des); + break; + case End: + case Endcenter: + case Endlink: + case Endgroup: + case Endbox: + case Endmbox: + case Endspadcommand: + case Endpix: + case Endmacro: + case Endparameter: + case Endtable: + case Endtableitem: + case Noop: + case Endinputbox: + case Enddescription: + case Endif: + case Endtitems: + case Enditems: + case Endverbatim: + case Endmath: + case Endspadsrc: + free_node(node->next, des); + break; + case Endheader: + case Endtitle: + case Endfooter: + case Endscrolling: + case Endarg: + break; + case Endbutton: + case Beginitems: + free_if_non_NULL(node->data.text); + free_node(node->next, des); + break; + + default: + + /* printf("don't know how to free type %d\n", node->type); */ + return; + } + free(node); +} + +IfNode * +alloc_ifnode(void) +{ + IfNode *tempif; + + tempif = (IfNode *) halloc(sizeof(struct if_node), "IfNode"); + tempif->thennode = tempif->elsenode = tempif->cond = NULL; + return tempif; +} + +CondNode * +alloc_condnode(void) +{ + CondNode *temp; + + temp = (CondNode *) halloc(sizeof(struct cond_node), "Cond Node"); + temp->cond = temp->label = NULL; + return temp; +} + +static void +free_cond(CondNode *cond) +{ + if (cond) { + free(cond->label); + if (cond->cond) + free(cond->cond); + free(cond); + } +} + +/* Allocate a new HyperDoc page */ + +HyperDocPage * +alloc_page(char *name) +{ + HyperDocPage *page; + + page = (HyperDocPage *) halloc(sizeof(HyperDocPage), "HyperDocPage"); + page->name = name; + page->header = page->scrolling = page->footer = page->title = NULL; + page->scroll_off = 0; + page->sock = NULL; + page->box_hash = page->depend_hash = NULL; + page->fLinkHashTable = (HashTable *) halloc(sizeof(HashTable), "Page->fLinkHashTable"); + page->input_list = page->current_item = NULL; + page->page_flags = 0000000; + page->filename = NULL; + page->helppage = alloc_string(TopLevelHelpPage); + page->radio_boxes = NULL; + page->button_list = NULL; + page->s_button_list = NULL; + return page; +} + +void +free_page(HyperDocPage *page) +{ + /* + * This routine now checks for an environment variable NOFREE. If found + * it returns. + */ + + if (page == NULL) + return; + + switch (page->type) { + case UlUnknownPage: + case UnknownPage: + case ErrorPage: + case Unixfd: + case SpadGen: + case Normal: + + /* + * if(page->name) free(page->name); if(page->filename) + * free(page->filename); + */ + free_node(page->scrolling, 0); + free_node(page->header, 0); + free_node(page->footer, 0); + free_node(page->title, 0); + free_button_list(page->s_button_list); + free_button_list(page->button_list); +/* + if (page->sock != NULL) + free(page->sock); +*/ + free_hash(page->depend_hash, (FreeFunction)free_depend); + /* TTT line below causes freeing of freed memory and freed memory reads + links should have been freed by the recursive free_node's above (cf.free_node) + this is apparently because we are called from free_hd_window + and we had made a call to free w->fWindowHashTable which is made + to point to the same thing + so we do it HERE not THERE + */ + free_hash(page->fLinkHashTable, (FreeFunction)dont_free); + free_hash(page->box_hash, (FreeFunction)free_input_box); + free_input_list(page->input_list); + free_radio_boxes(page->radio_boxes); + free(page->helppage); + free(page); + break; + case UnloadedPageType: + break; + default: + /* fprintf(stderr, "Unknown Page type: %d\n", page->type); */ + break; + } +} + +static void +free_paste(PasteNode *paste, short int des) +{ + if (paste) { + free_group_stack(paste->group); + free_item_stack(paste->item_stack); + free_node(paste->arg_node, des); + free(paste); + } +} + +static void +free_pastebutton(TextNode *node, short int des) +{ + /* + * if I am freeing from within parse patch, then I have to do some + * special things first + */ + + + /* the following seems to be unused */ + if (gActiveWindow == node->link->win) + gActiveWindow = -1; + + + + if (des) { + PasteNode *paste; + paste = (PasteNode *) hash_find(gWindow->fPasteHashTable, node->data.text); + + if (!paste->haspaste) { + /* squash this thing */ + + hash_delete(gWindow->fPasteHashTable, (char *)node->data.text); + free_paste(paste, des); + hash_delete(gWindow->page->fLinkHashTable,(char *) &node->link->win); + + XDestroyWindow(gXDisplay, node->link->win); + } + else + paste->hasbutton = 0; + } + + free_if_non_NULL(node->data.text); + +} + +static void +free_pastearea(TextNode *node, short int des) +{ + if (des) { + PasteNode *paste; + paste = (PasteNode *) hash_find(gWindow->fPasteHashTable, node->data.text); + if (paste) { + if (!paste->hasbutton) { + /* squash this thing */ + hash_delete(gWindow->fPasteHashTable, node->data.text); + free_paste(paste, des); + } + else + paste->haspaste = 0; + } + } + + free_if_non_NULL(node->data.text); +} + + +void +free_string(char *str) +{ + free_if_non_NULL(str); +} + +static void +free_depend(SpadcomDepend *sd) +{ + free_if_non_NULL((char *) sd); +} + +static void +dont_free(void *link) +{ + return; +} + +#if 0 +----------- NOT USED +static void +free_link(HyperLink *link) +{ + printf("Link type %d\n",link->type); + free_if_non_NULL((char *) link); +} +----------- NOT USED +#endif + +static void +free_lines(LineStruct *lines) +{ + if (lines->prev != NULL) + lines->prev->next = NULL; + while (lines != NULL) { + LineStruct *del; + del = lines; + lines = lines->next; + free(del->buffer); + free(del); + } +} + +void +free_input_item(InputItem *sym, short int des) +{ + free_if_non_NULL(sym->name); + free_lines(sym->lines); + if (des) + XDestroyWindow(gXDisplay, sym->win); +} + +void +free_input_list(InputItem *il) +{ + while (il) { + InputItem *trash = il; + il = il->next; + free_input_item(trash, 0); + free(trash); + } +} + +static void +free_input_box(InputBox *box) +{ + if (box) { + free_if_non_NULL(box->name); + free(box); + } +} + +static void +free_radio_boxes(RadioBoxes *radio) +{ + if (radio) { + free_radio_boxes(radio->next); + free_if_non_NULL(radio->name); + free(radio); + } +} + +#if 0 +--------------- NOT USED +static void +free_image(ImageStruct *image) +{ + free(image->image.xi->data); + free(image->image.xi); + free(image); +} +--------------- NOT USED +#endif + +#if 0 +--------------- NOT USED +static void +free_macro(MacroStore *macro) +{ + if (macro) { + free(macro->name); + if (macro->macro_string) + free(macro->macro_string); + free(macro); + } +} +--------------- NOT USED +#endif + + + +LineStruct * +alloc_inputline(int size) +{ + int i; + LineStruct *line = + (LineStruct *) halloc(sizeof(LineStruct), "Line Structure"); + + line->prev = line->next = NULL; + line->buffer = (char *) halloc(sizeof(char) * size + 2, "symbol buffer"); + for (i = 0; i < size + 2; i++) + line->buffer[i] = 0; + line->buff_pntr = line->len = 0; + return line; +} + +PasteNode * +alloc_paste_node(char *name) +{ + PasteNode *pastenode = + (PasteNode *) halloc(sizeof(PasteNode), "PasteNode"); + + pastenode->group = NULL; + pastenode->item_stack = NULL; + pastenode->arg_node = NULL; + pastenode->end_node = NULL; + pastenode->name = alloc_string(name); + pastenode->haspaste = pastenode->hasbutton = 0; + return pastenode; +} + +PatchStore * +alloc_patchstore(void) +{ + PatchStore *p = (PatchStore *) halloc(sizeof(PatchStore), "PatchStore"); + + p->loaded = 0; + p->string = NULL; + return p; +} + +void +free_patch(PatchStore *p) +{ + if (p) { + if (p->name) + free(p->name); + if (p->fpos.name) + free(p->fpos.name); + if (p->string) + free(p->string); + free(p); + } +} + +InputBox * +alloc_inputbox(void) +{ + InputBox *box = (InputBox *) halloc(sizeof(InputBox), "InputBox"); + + box->picked = 0; + box->next = NULL; + box->rbs = NULL; + return box; +} + +RadioBoxes * +alloc_rbs(void) +{ + RadioBoxes *newrb = (RadioBoxes *) halloc(sizeof(RadioBoxes), "Radio Boxes"); + + newrb->next = NULL; + newrb->boxes = NULL; + return newrb; +} + +ButtonList * +alloc_button_list(void) +{ + ButtonList *newbl = (ButtonList *) halloc(sizeof(ButtonList), "Button List"); + + newbl->link = NULL; + newbl->x0 = newbl->y0 = newbl->x1 = newbl->y1 = 0; + newbl->next = NULL; + return newbl; +} + +void +free_button_list(ButtonList *bl) +{ + while (bl) { + ButtonList *nbl = bl->next; + free(bl); + bl = nbl; + } +} + + +/* resizable static buffers */ + +#define BufferSlop 0 + +char * +resizeBuffer(int size, char *oldBuf, int *oldSize) +{ + char *newBuf; + int newSize; + + if (size <= *oldSize) + return oldBuf; + + newSize = size + BufferSlop; + newBuf = (char *) halloc(newSize,"Buffer"); + memset(newBuf,'\0',newSize); + if (oldBuf) { + memcpy(newBuf, oldBuf, *oldSize); + free(oldBuf); + } + *oldSize = newSize; + + return newBuf; +} diff --git a/src/hyper/mem.pamphlet b/src/hyper/mem.pamphlet deleted file mode 100644 index 7f98b0ef..00000000 --- a/src/hyper/mem.pamphlet +++ /dev/null @@ -1,788 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/mem} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{mem.h} -<>= -<> -#ifndef _MEM_H_ -#define _MEM_H_ 1 - -#include "hyper.h" -#include "cond.h" - - -#endif -@ -\section{mem.c} -<>= -/****************************************************************************** - * - * mem.c: HyperDoc Memory Management Routines. - * - * Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993. - * - ****************************************************************************/ -#define _MEM_C -#include "useproto.h" -#include "debug.h" - - -#include "mem.h" -#include "group.h" -#include "event.h" -#include "parse-aux.h" - -#include "all_hyper_proto.H1" - - - -extern HashTable init_page_hash; -extern HashTable init_macro_hash; -extern HashTable init_patch_hash; - - -static void -free_if_non_NULL(void *p) -{ - if (p){ - free(p); - } -} - - -/* allocate an HDWindow Structure and initialize it */ - -HDWindow * -alloc_hd_window(void) -{ - HDWindow *w = (HDWindow *) halloc(sizeof(HDWindow), "HDWindow"); - /*char haslisp[10];*/ - - w->fMemoStack = (HyperDocPage **) - halloc(MaxMemoDepth * sizeof(HyperDocPage *), "Memo Stack"); - w->fDownLinkStack = (HyperDocPage **) - halloc(MaxDownlinkDepth * sizeof(HyperDocPage *), "downlink stack"); - w->fDownLinkStackTop = - (int *) halloc(MaxDownlinkDepth * sizeof(int), "top downlink stack"); - w->fAxiomFrame = 0; - init_page_structs(w); - - /* Now I initialize the hash tables for the page */ - w->fCondHashTable = (HashTable *) halloc(sizeof(HashTable), "cond hash"); - hash_init( - w->fCondHashTable, - CondHashSize, - (EqualFunction) string_equal, - (HashcodeFunction) string_hash); - - w->fPasteHashTable = (HashTable *) halloc(sizeof(HashTable), "paste hash"); - hash_init( - w->fPasteHashTable, - PasteHashSize, - (EqualFunction) string_equal, - (HashcodeFunction) string_hash); - w->fPageHashTable = hash_copy_table(&init_page_hash); - w->fPatchHashTable = hash_copy_table(&init_patch_hash); - w->fMacroHashTable = hash_copy_table(&init_macro_hash); - - gWindow = w; - /*sprintf(haslisp, "%1d\0", MenuServerOpened);*/ - make_special_pages(w->fPageHashTable); - w->fDisplayedCursor = 0; - return w; -} - -void -free_hd_window(HDWindow *w) -{ - if (w) { - free(w->fMemoStack); - free(w->fDownLinkStack); - free(w->fDownLinkStackTop); - /* - free(w->fWindowHashTable); will be taken care of by freeing - free_hash(w->fPageHashTable, free_page); below - cf free_page - */ - free_hash(w->fMacroHashTable, (FreeFunction)dont_free); - free_hash(w->fPasteHashTable, (FreeFunction)dont_free); - free_hash(w->fPatchHashTable, (FreeFunction)dont_free); - - free_hash(w->fCondHashTable, (FreeFunction)free_cond); - free_hash(w->fPageHashTable, (FreeFunction)free_page); - free(w->fPageHashTable); - free(w->fPatchHashTable); - free(w->fMacroHashTable); - XFreeGC(gXDisplay, w->fStandardGC); - XFreeGC(gXDisplay, w->fInputGC); - XFreeGC(gXDisplay, w->fCursorGC); - XFreeGC(gXDisplay, w->fControlGC); - free(w); - } -} - - -/* Allocate an empty text node */ - -TextNode * -alloc_node(void) -{ - TextNode *temp_node; - - temp_node = (TextNode *) halloc(sizeof(TextNode), "Text Node"); - temp_node->type = 0; - temp_node->space = 0; - temp_node->height = 0; - temp_node->width = 0; - temp_node->x = -1; - temp_node->y = -1; - temp_node->data.node = NULL; - temp_node->next = NULL; - temp_node->link = NULL; - temp_node->image.pm = 0; - return temp_node; -} - -void -free_node(TextNode *node, short int des) -{ - - if (node == NULL) - return; - - switch (node->type) { - case Paste: - free_pastearea(node, des); - free_node(node->next, des); - break; - case Pastebutton: - free_pastebutton(node, des); - free_node(node->next, des); - break; - case Ifcond: - free_node(node->data.ifnode->cond, des); - free_node(node->data.ifnode->thennode, des); - free_node(node->data.ifnode->elsenode, des); - break; - case Dash: - case Lsquarebrace: - case Word: - case WindowId: - case Punctuation: - case Lbrace: - case Rbrace: - case SimpleBox: - case Verbatim: - case Math: - case Spadsrctxt: - case Spadsrc: - free_if_non_NULL(node->data.text); - free_node(node->next, des); - break; - case Inputstring: - if (des) - delete_item(node->data.text); - free_if_non_NULL(node->data.text); - free_node(node->next, des); - break; - case It: - case Sl: - case Tt: - case Rm: - case Emphasize: - case Beep: - case BoldFace: - case Par: - case Newline: - case Horizontalline: - case Item: - case Beginscroll: - case Endscroll: - case Group: - case Table: - case Macro: - case Pound: - case Center: - case Box: - case Mbox: - case Tableitem: - case Scrollingnode: - case Headernode: - case Titlenode: - case Footernode: - case Controlbitmap: - case Fi: - case Description: - case Rsquarebrace: - case Endpaste: - case Endpastebutton: - free_node(node->next, des); - break; - case Inputbitmap: - case Inputpixmap: - free_if_non_NULL(node->data.text); - free_node(node->next, des); - break; - case Quitbutton: - case Helpbutton: - case Upbutton: - case Returnbutton: - if (des && node->link->win) { - hash_delete(gWindow->page->fLinkHashTable,(char *) &node->link->win); - XDestroyWindow(gXDisplay, node->link->win); - } - free_if_non_NULL(node->link); - free_node(node->next, des); - break; - case Memolink: - case Downlink: - case Windowlink: - case Link: - case Lisplink: - case Lispwindowlink: - case Spadcall: - case Spadcallquit: - case LispMemoLink: - case Lispcommand: - case Lispcommandquit: - case LispDownLink: - case Unixlink: - case Spadlink: - case Spadmemolink: - case Spaddownlink: - case Unixcommand: - case Spadcommand: - case Spadgraph: - if (des && node->link->win) { - hash_delete(gWindow->page->fLinkHashTable,(char *) &node->link->win); - XDestroyWindow(gXDisplay, node->link->win); - } - /* TTT don't free the link before freeing nodes off it */ - /* free_node(node->link->reference.node);*/ - free_if_non_NULL(node->link); - free_node(node->next, des); - break; - case Free: - case Indent: - case Indentrel: - case HSpace: - case Space: - case VSpace: - case Button: - case Bound: - case Tab: - free_node(node->next, des); - free_node(node->data.node, des); - break; - case End: - case Endcenter: - case Endlink: - case Endgroup: - case Endbox: - case Endmbox: - case Endspadcommand: - case Endpix: - case Endmacro: - case Endparameter: - case Endtable: - case Endtableitem: - case Noop: - case Endinputbox: - case Enddescription: - case Endif: - case Endtitems: - case Enditems: - case Endverbatim: - case Endmath: - case Endspadsrc: - free_node(node->next, des); - break; - case Endheader: - case Endtitle: - case Endfooter: - case Endscrolling: - case Endarg: - break; - case Endbutton: - case Beginitems: - free_if_non_NULL(node->data.text); - free_node(node->next, des); - break; - - default: - - /* printf("don't know how to free type %d\n", node->type); */ - return; - } - free(node); -} - -IfNode * -alloc_ifnode(void) -{ - IfNode *tempif; - - tempif = (IfNode *) halloc(sizeof(struct if_node), "IfNode"); - tempif->thennode = tempif->elsenode = tempif->cond = NULL; - return tempif; -} - -CondNode * -alloc_condnode(void) -{ - CondNode *temp; - - temp = (CondNode *) halloc(sizeof(struct cond_node), "Cond Node"); - temp->cond = temp->label = NULL; - return temp; -} - -static void -free_cond(CondNode *cond) -{ - if (cond) { - free(cond->label); - if (cond->cond) - free(cond->cond); - free(cond); - } -} - -/* Allocate a new HyperDoc page */ - -HyperDocPage * -alloc_page(char *name) -{ - HyperDocPage *page; - - page = (HyperDocPage *) halloc(sizeof(HyperDocPage), "HyperDocPage"); - page->name = name; - page->header = page->scrolling = page->footer = page->title = NULL; - page->scroll_off = 0; - page->sock = NULL; - page->box_hash = page->depend_hash = NULL; - page->fLinkHashTable = (HashTable *) halloc(sizeof(HashTable), "Page->fLinkHashTable"); - page->input_list = page->current_item = NULL; - page->page_flags = 0000000; - page->filename = NULL; - page->helppage = alloc_string(TopLevelHelpPage); - page->radio_boxes = NULL; - page->button_list = NULL; - page->s_button_list = NULL; - return page; -} - -void -free_page(HyperDocPage *page) -{ - /* - * This routine now checks for an environment variable NOFREE. If found - * it returns. - */ - - if (page == NULL) - return; - - switch (page->type) { - case UlUnknownPage: - case UnknownPage: - case ErrorPage: - case Unixfd: - case SpadGen: - case Normal: - - /* - * if(page->name) free(page->name); if(page->filename) - * free(page->filename); - */ - free_node(page->scrolling, 0); - free_node(page->header, 0); - free_node(page->footer, 0); - free_node(page->title, 0); - free_button_list(page->s_button_list); - free_button_list(page->button_list); -/* - if (page->sock != NULL) - free(page->sock); -*/ - free_hash(page->depend_hash, (FreeFunction)free_depend); - /* TTT line below causes freeing of freed memory and freed memory reads - links should have been freed by the recursive free_node's above (cf.free_node) - this is apparently because we are called from free_hd_window - and we had made a call to free w->fWindowHashTable which is made - to point to the same thing - so we do it HERE not THERE - */ - free_hash(page->fLinkHashTable, (FreeFunction)dont_free); - free_hash(page->box_hash, (FreeFunction)free_input_box); - free_input_list(page->input_list); - free_radio_boxes(page->radio_boxes); - free(page->helppage); - free(page); - break; - case UnloadedPageType: - break; - default: - /* fprintf(stderr, "Unknown Page type: %d\n", page->type); */ - break; - } -} - -static void -free_paste(PasteNode *paste, short int des) -{ - if (paste) { - free_group_stack(paste->group); - free_item_stack(paste->item_stack); - free_node(paste->arg_node, des); - free(paste); - } -} - -static void -free_pastebutton(TextNode *node, short int des) -{ - /* - * if I am freeing from within parse patch, then I have to do some - * special things first - */ - - - /* the following seems to be unused */ - if (gActiveWindow == node->link->win) - gActiveWindow = -1; - - - - if (des) { - PasteNode *paste; - paste = (PasteNode *) hash_find(gWindow->fPasteHashTable, node->data.text); - - if (!paste->haspaste) { - /* squash this thing */ - - hash_delete(gWindow->fPasteHashTable, (char *)node->data.text); - free_paste(paste, des); - hash_delete(gWindow->page->fLinkHashTable,(char *) &node->link->win); - - XDestroyWindow(gXDisplay, node->link->win); - } - else - paste->hasbutton = 0; - } - - free_if_non_NULL(node->data.text); - -} - -static void -free_pastearea(TextNode *node, short int des) -{ - if (des) { - PasteNode *paste; - paste = (PasteNode *) hash_find(gWindow->fPasteHashTable, node->data.text); - if (paste) { - if (!paste->hasbutton) { - /* squash this thing */ - hash_delete(gWindow->fPasteHashTable, node->data.text); - free_paste(paste, des); - } - else - paste->haspaste = 0; - } - } - - free_if_non_NULL(node->data.text); -} - - -void -free_string(char *str) -{ - free_if_non_NULL(str); -} - -static void -free_depend(SpadcomDepend *sd) -{ - free_if_non_NULL((char *) sd); -} - -static void -dont_free(void *link) -{ - return; -} - -#if 0 ------------ NOT USED -static void -free_link(HyperLink *link) -{ - printf("Link type %d\n",link->type); - free_if_non_NULL((char *) link); -} ------------ NOT USED -#endif - -static void -free_lines(LineStruct *lines) -{ - if (lines->prev != NULL) - lines->prev->next = NULL; - while (lines != NULL) { - LineStruct *del; - del = lines; - lines = lines->next; - free(del->buffer); - free(del); - } -} - -void -free_input_item(InputItem *sym, short int des) -{ - free_if_non_NULL(sym->name); - free_lines(sym->lines); - if (des) - XDestroyWindow(gXDisplay, sym->win); -} - -void -free_input_list(InputItem *il) -{ - while (il) { - InputItem *trash = il; - il = il->next; - free_input_item(trash, 0); - free(trash); - } -} - -static void -free_input_box(InputBox *box) -{ - if (box) { - free_if_non_NULL(box->name); - free(box); - } -} - -static void -free_radio_boxes(RadioBoxes *radio) -{ - if (radio) { - free_radio_boxes(radio->next); - free_if_non_NULL(radio->name); - free(radio); - } -} - -#if 0 ---------------- NOT USED -static void -free_image(ImageStruct *image) -{ - free(image->image.xi->data); - free(image->image.xi); - free(image); -} ---------------- NOT USED -#endif - -#if 0 ---------------- NOT USED -static void -free_macro(MacroStore *macro) -{ - if (macro) { - free(macro->name); - if (macro->macro_string) - free(macro->macro_string); - free(macro); - } -} ---------------- NOT USED -#endif - - - -LineStruct * -alloc_inputline(int size) -{ - int i; - LineStruct *line = - (LineStruct *) halloc(sizeof(LineStruct), "Line Structure"); - - line->prev = line->next = NULL; - line->buffer = (char *) halloc(sizeof(char) * size + 2, "symbol buffer"); - for (i = 0; i < size + 2; i++) - line->buffer[i] = 0; - line->buff_pntr = line->len = 0; - return line; -} - -PasteNode * -alloc_paste_node(char *name) -{ - PasteNode *pastenode = - (PasteNode *) halloc(sizeof(PasteNode), "PasteNode"); - - pastenode->group = NULL; - pastenode->item_stack = NULL; - pastenode->arg_node = NULL; - pastenode->end_node = NULL; - pastenode->name = alloc_string(name); - pastenode->haspaste = pastenode->hasbutton = 0; - return pastenode; -} - -PatchStore * -alloc_patchstore(void) -{ - PatchStore *p = (PatchStore *) halloc(sizeof(PatchStore), "PatchStore"); - - p->loaded = 0; - p->string = NULL; - return p; -} - -void -free_patch(PatchStore *p) -{ - if (p) { - if (p->name) - free(p->name); - if (p->fpos.name) - free(p->fpos.name); - if (p->string) - free(p->string); - free(p); - } -} - -InputBox * -alloc_inputbox(void) -{ - InputBox *box = (InputBox *) halloc(sizeof(InputBox), "InputBox"); - - box->picked = 0; - box->next = NULL; - box->rbs = NULL; - return box; -} - -RadioBoxes * -alloc_rbs(void) -{ - RadioBoxes *newrb = (RadioBoxes *) halloc(sizeof(RadioBoxes), "Radio Boxes"); - - newrb->next = NULL; - newrb->boxes = NULL; - return newrb; -} - -ButtonList * -alloc_button_list(void) -{ - ButtonList *newbl = (ButtonList *) halloc(sizeof(ButtonList), "Button List"); - - newbl->link = NULL; - newbl->x0 = newbl->y0 = newbl->x1 = newbl->y1 = 0; - newbl->next = NULL; - return newbl; -} - -void -free_button_list(ButtonList *bl) -{ - while (bl) { - ButtonList *nbl = bl->next; - free(bl); - bl = nbl; - } -} - - -/* resizable static buffers */ - -#define BufferSlop 0 - -char * -resizeBuffer(int size, char *oldBuf, int *oldSize) -{ - char *newBuf; - int newSize; - - if (size <= *oldSize) - return oldBuf; - - newSize = size + BufferSlop; - newBuf = (char *) halloc(newSize,"Buffer"); - memset(newBuf,'\0',newSize); - if (oldBuf) { - memcpy(newBuf, oldBuf, *oldSize); - free(oldBuf); - } - *oldSize = newSize; - - return newBuf; -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/mouse11.bitmap b/src/hyper/mouse11.bitmap new file mode 100644 index 00000000..231c6630 --- /dev/null +++ b/src/hyper/mouse11.bitmap @@ -0,0 +1,8 @@ +#define mouseBitmap_width 16 +#define mouseBitmap_height 16 +#define mouseBitmap_x_hot 8 +#define mouseBitmap_y_hot 0 +static char mouseBitmap_bits[] = { + 0x00, 0x01, 0x00, 0x01, 0x80, 0x02, 0x40, 0x04, 0xc0, 0x06, 0x20, 0x08, + 0x20, 0x08, 0x30, 0x18, 0x50, 0x14, 0x58, 0x34, 0x90, 0x12, 0x20, 0x08, + 0xc0, 0x47, 0x00, 0x21, 0x80, 0x10, 0x00, 0x0f}; diff --git a/src/hyper/mouse11.mask b/src/hyper/mouse11.mask new file mode 100644 index 00000000..6e5621f4 --- /dev/null +++ b/src/hyper/mouse11.mask @@ -0,0 +1,6 @@ +#define mouseMask_width 16 +#define mouseMask_height 16 +static char mouseMask_bits[] = { + 0x00, 0x01, 0x00, 0x01, 0x80, 0x03, 0xc0, 0x07, 0xc0, 0x07, 0xe0, 0x0f, + 0xe0, 0x0f, 0xf0, 0x1f, 0xf0, 0x1f, 0xf8, 0x3f, 0xf0, 0x1f, 0xe0, 0x0f, + 0xc0, 0x47, 0x00, 0x21, 0x80, 0x10, 0x00, 0x0f}; diff --git a/src/hyper/parse-aux.c b/src/hyper/parse-aux.c new file mode 100644 index 00000000..09972872 --- /dev/null +++ b/src/hyper/parse-aux.c @@ -0,0 +1,630 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + All rights reverved. + + 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. +*/ + +#include "axiom-c-macros.h" +#define _PARSE_AUX_C +#include "useproto.h" +#include "debug.h" + +#include "parse.h" +#include "addfile.h" +#include "lex.h" +#include "hyper.h" + +#include "all_hyper_proto.H1" + + +extern FILE *cfile; +extern int make_input_file; +extern int gverify_dates; + +InputBox *rb_list; +InputBox *end_rb_list; + +HashTable ht_gFileHashTable; + +#define htfhSize 100 + +/* Hash functions for active link windows */ + +int +window_equal(Window *w1, Window *w2) +{ + return *w1 == *w2; +} + +/* hash code for a window */ + +int +window_code(Window *w, int size) +{ + return (*w) % size; +} + +char * +window_id(Window w) +{ + char *ret; + char buff[32]; + int length; + + sprintf(buff, "%ld", w); + length = strlen(buff); + ret = (char *) halloc(length * sizeof(char) + 1, "windowid"); + strcpy(ret, buff); + return (ret); +} + +/* + * This procedure reads the ht database. It makes repeated calls to + * db_file_open, and while the returned pointer is not null, it continues to + * read the presented data base files + */ +void +read_ht_db(HashTable *page_hash, HashTable *macro_hash, HashTable *patch_hash) +{ + FILE *db_fp; + char db_file[256]; + int i = 0; + + gDatabasePath = NULL; + + hash_init( + page_hash, + PageHashSize, + (EqualFunction) string_equal, + (HashcodeFunction) string_hash); + hash_init( + macro_hash, + MacroHashSize, + (EqualFunction) string_equal, + (HashcodeFunction) string_hash); + hash_init( + patch_hash, + PatchHashSize, + (EqualFunction) string_equal, + (HashcodeFunction) string_hash); + + /* Lets initialize the FileHashTable */ + hash_init( + &ht_gFileHashTable, + htfhSize, + (EqualFunction) string_equal, + (HashcodeFunction) string_hash); + + while ((db_fp = db_file_open(db_file)) != NULL) { + i++; + read_ht_file(page_hash, macro_hash, patch_hash, db_fp, db_file); + fclose(db_fp); + } + + if (!i) { + fprintf(stderr, + "(HyperDoc) read_ht_db: No %s file found\n", db_file_name); + exit(-1); + } + + free_hash(&ht_gFileHashTable, (FreeFunction)free_string); +} + +/* + * This procedure reads a single HyperDoc database file. It is passed an already + * initilaized file pointer. It reads the whole file, updating the + * page hash, or the macro hash only when a previous entry with the same name + * is not found + */ + +static void +read_ht_file(HashTable *page_hash, HashTable *macro_hash, + HashTable *patch_hash, FILE *db_fp, char *db_file) +{ + char filename[256]; + char *fullname = filename; + UnloadedPage *page; + MacroStore *macro; + PatchStore *patch; + int pages = 0, c, mtime, ret_val; + struct stat fstats; + /*short time_ok = 1;*/ +/* fprintf(stderr,"parse_aux:read_ht_file: dp_file=%s\n",db_file);*/ + cfile = db_fp; + init_scanner(); + ret_val = strlen(db_file) - 1; + for (; ret_val >= 0; ret_val--) + if (db_file[ret_val] == '/') { + db_file[ret_val] = '\0'; + break; + } + c = getc(db_fp); + do { + if (c == '\t') { + get_filename(); + fullname = alloc_string(token.id); + if (fullname[0] != '/') { + strcpy(filename, db_file); + strcat(filename, "/"); + strcat(filename, fullname); + free(fullname); + fullname = alloc_string(filename); + } + + /* + * Until I get a filename that I have not seen before, just keep + * reading + */ + while (hash_find(&ht_gFileHashTable, fullname) != NULL) { + do { + c = getc(db_fp); + } while ((c != EOF) && (c != '\t')); + if (c == EOF) + return; + get_filename(); + fullname = alloc_string(token.id); + if (fullname[0] != '/') { + strcpy(filename, db_file); + strcat(filename, "/"); + strcat(filename, fullname); + free(fullname); + fullname = alloc_string(filename); + } + } +/* fprintf(stderr,"parse_aux:read_ht_file: fullname=%s\n",fullname);*/ + /* If I got here, then I must have a good filename */ + hash_insert(&ht_gFileHashTable, fullname, fullname); + + ret_val = stat(fullname, &fstats); + if (ret_val == -1) { + char buffer[300]; + + sprintf(buffer, "(HyperDoc) read_ht_db: Unable To Open %s :", fullname); + perror(buffer); + exit(-1); + } + get_token(); + mtime = atoi(token.id); + if (gverify_dates & (fstats.st_mtime > mtime)) { + fprintf(stderr, "(HyperDoc) read_ht_file: HyperDoc file %s has been updated\n", + + fullname); + fprintf(stderr, "(HyperDoc) Issue htadd %s to update database\n", fullname); + exit(-1); + } + while ((c = getc(db_fp)) != EOF) { + if (c == '\t') + break; + ungetc(c, db_fp); + get_token(); + switch (token.type) { + case Page: + get_token(); + + /* + * now check to see if the page has already been + * loaded + */ + page = (UnloadedPage *) halloc(sizeof(UnloadedPage), + "UnloadedPage"); + page->fpos.name = alloc_string(fullname); + page->name = alloc_string(token.id); + get_token(); + if (hash_find(page_hash, page->name) != NULL) { + fprintf(stderr, "(HyperDoc) Page name %s occurred twice\n", page->name); + fprintf(stderr, "(HyperDoc) The Version in %s is being ignored \n", + page->fpos.name); + free(page); + get_token(); + break; + } + page->fpos.pos = atoi(token.id); + get_token(); + page->fpos.ln = atoi(token.id); + page->type = UnloadedPageType; + hash_insert(page_hash, (char *)page, page->name); + pages++; + break; + case NewCommand: + get_token(); + macro = (MacroStore *) halloc(sizeof(MacroStore), "MacroStore"); + macro->fpos.name = alloc_string(fullname); + macro->name = alloc_string(token.id); + macro->macro_string = NULL; + get_token(); + if (hash_find(macro_hash, macro->name) != NULL) { + if (strcmp(macro->name, "localinfo") != 0) { + fprintf(stderr, "(HyperDoc) Macro name %s occurred twice\n", + macro->name); + fprintf(stderr, "(HyperDoc) The Version in %s is being ignored \n", + macro->fpos.name); + } + get_token(); + free(macro); + break; + } + macro->fpos.pos = atoi(token.id); + get_token(); + macro->fpos.ln = atoi(token.id); + macro->loaded = 0; + hash_insert(macro_hash, (char *)macro, macro->name); + break; + case Patch: + get_token(); + patch = (PatchStore *) alloc_patchstore(); + patch->fpos.name = alloc_string(fullname); + patch->name = alloc_string(token.id); + get_token(); + patch->fpos.pos = atoi(token.id); + get_token(); + patch->fpos.ln = atoi(token.id); + if (hash_find(patch_hash, patch->name) != NULL) { + fprintf(stderr, "(HyperDoc) Patch name %s occurred twice\n", patch->name); + fprintf(stderr, "(HyperDoc) The version in %s is being ignored \n", + patch->fpos.name); + free_patch(patch); + break; + } + hash_insert(patch_hash, (char *)patch, patch->name); + break; + default: + fprintf(stderr, "(HyperDoc) read_ht_db: Unknown type %s in ht.db\n", token.id); + exit(-1); + break; + } + } + } + else + c = getc(db_fp); + } while (c != EOF); +/* fprintf(stderr, + "parse_aux:read_ht_file:read %d pages from database\n", pages); */ +} + + +/* create an unmapped input-only window for an active screen area */ + +HyperLink * +make_link_window(TextNode *link_node, int type, int isSubWin) +{ + HyperLink *link; + XSetWindowAttributes at; + + if (make_input_file) + switch (type) { + case Downlink: + case Memolink: + case Windowlink:{ + char *name; + HyperDocPage *p; + + name = print_to_string(link_node); + p = (HyperDocPage *) hash_find(gWindow->fPageHashTable, name); + if (!p) + printf("undefined link to %s\n", name); + break; + } + } + else { + link = (HyperLink *) halloc(sizeof(HyperLink), "HyperLink"); + if (link == NULL) { + fprintf(stderr, "(HyperDoc) Ran out of memory allocating a hypertext link!\n"); + exit(-1); + } + at.cursor = gActiveCursor; + at.event_mask = ButtonPress; + if (isSubWin) + link->win = XCreateWindow(gXDisplay, gWindow->fDisplayedWindow, 0, 0, 100, 100, 0, + 0, InputOnly, CopyFromParent, + CWEventMask | CWCursor, &at); + else + link->win = 0; + link->type = type; + link->x = link->y = 0; + link->reference.node = link_node; + hash_insert(gLinkHashTable, (char *)link,(char *)&link->win); + return link; + } + return 0; +} + +HyperLink * +make_paste_window(PasteNode *paste) +{ + HyperLink *link; + XSetWindowAttributes at; + + if (!make_input_file) { + link = (HyperLink *) halloc(sizeof(HyperLink), "HyperLink"); + if (link == NULL) { + fprintf(stderr, "(HyperDoc) Ran out of memory allocating a hypertext link!\n"); + exit(-1); + } + at.cursor = gActiveCursor; + at.event_mask = ButtonPress; + link->win = XCreateWindow(gXDisplay, gWindow->fDisplayedWindow, + 0, 0, 100, 100, 0, + 0, InputOnly, CopyFromParent, + CWEventMask | CWCursor, &at); + link->type = Pastebutton; + link->x = link->y = 0; + link->reference.paste = paste; + hash_insert(gLinkHashTable, (char *)link,(char *) &link->win); + return link; + } + return 0; +} + + + +/* create a HyperDoc page structure with the given type and name */ + +static HyperDocPage * +make_special_page(int type, char *name) +{ + HyperDocPage *page = alloc_page(name); + + if (page == NULL) { + fprintf(stderr, "(HyperDoc) Ran out of memory allocating page.\n"); + exit(-1); + } + page->type = type; + free(page->fLinkHashTable); + page->fLinkHashTable = NULL; + return page; +} + + +/* insert the special button page types into the page hash table */ + +void +make_special_pages(HashTable *pageHashTable) +{ + hash_insert(pageHashTable, (char *)make_special_page(Quitbutton, "QuitPage"), + "QuitPage"); + hash_insert(pageHashTable, (char *)make_special_page(Returnbutton, "ReturnPage"), + "ReturnPage"); + hash_insert(pageHashTable, (char *)make_special_page(Upbutton, "UpPage"), + "UpPage"); +} + + +/* Here is where I put the item into the pages linked list */ + +/* Parse the \bound{varlist} command, and add vars to dependency table */ + +void +add_dependencies(void) +{ + TextNode *bound_node = curr_node; + TextNode *node; + SpadcomDepend *depend; + + if (cur_spadcom == NULL) { + fprintf(stderr, "(HyperDoc) \\bound occuring outside a \\spadcom\n"); + print_page_and_filename(); + exit(-1); + } + curr_node->type = Bound; + curr_node->data.node = alloc_node(); + curr_node = curr_node->data.node; + get_expected_token(Lbrace); + parse_HyperDoc(); + curr_node->type = Endarg; + curr_node = bound_node; + + if (gPageBeingParsed->depend_hash == NULL) { + gPageBeingParsed->depend_hash = + (HashTable *) halloc(sizeof(HashTable), "Hash Table"); + hash_init( + gPageBeingParsed->depend_hash, + DependHashSize, + (EqualFunction) string_equal, + (HashcodeFunction) string_hash); + } + for (node = bound_node->data.node; node->type != Endarg; node = node->next) { + if (node->type == Word) { + depend = (SpadcomDepend *) halloc(sizeof(SpadcomDepend), "SpadcomDepend"); + depend->label = alloc_string(node->data.text); + depend->spadcom = cur_spadcom; + depend->executed = 0; + hash_insert(gPageBeingParsed->depend_hash, (char *)depend, depend->label); + } + } +} + +/* Returns true iff the TextNode contains a single integer */ + +int +is_number(char * str) +{ + char *s; + + for (s = str; *s != '\0'; s++) { + if (!(isdigit(*s) || *s == '-')) + return 0; + } + return 1; +} +void +parser_error(char *str) +{ + /** this procedure is called by the parser when an error occurs. It prints + the error message, followed by the next 10 tokens to ease finding the + error for the user. *****/ + + int i, v; + + fprintf(stderr, " %s\n", str); + fprintf(stderr, "Here are the next 10 tokens:\n"); + for (i = 0; i < 10; i++) { + v = get_token(); + if (v == EOF) + break; + print_token(); + } + fprintf(stderr, "\n"); + exit(-1); +} + + +#define whitespace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n') +#define delim(c) \ + (whitespace(c)) + + +/* advance token to the next token in the input stream. */ +int +get_filename(void) +{ + int c, ws; + static int seen_white = 0; /*UNUSED */ + static char buffer[256]; + char *buf = buffer; + + if (last_token) { + last_token = 0; + return 0; + } + do { + keyword_fpos = fpos; + c = get_char(); + ws = whitespace(c); + if (ws) + seen_white = 1; + } while (ws); + switch (c) { + case EOF: + fprintf(stderr, "(HyperDoc) Error trying to read %s, unexpected end-of-file.\n",db_file_name); + exit(-1); + case '%': + case '\\': + case '{': + case '}': + fprintf(stderr, "(HyperDoc) Error unexpected character %c.\n",c); + exit(-1); + default: + do { + *buf++ = c; + } while ((c = get_char()) != EOF && !delim(c)); + unget_char(c); + *buf = '\0'; + token.type = Word; + token.id = buffer; + seen_white = 0; + break; + } + return 1; +} + +char * +get_input_string(void) +{ + char *string; + TextNode *string_node,*save_node; + + save_node = curr_node; + /* Get the nodes that make up the string */ + string_node = alloc_node(); + curr_node = string_node; + parse_HyperDoc(); + curr_node->type = Endarg; + + /* Once here we print to string to get the actual name */ + string = print_to_string(string_node); + free_node(string_node, 0); + curr_node=save_node; + return string; +} + +/* + * tries to determine if there is an optional argument for where I should be + * parsing from. If so it then tries to determine which + */ +int +get_where(void) +{ + int tw; + + get_token(); + if (token.type != Word) + return -1; + + /* Now try to determine if it is a good type */ + if (!strcmp(token.id, "lisp")) { + tw = FromSpadSocket; + } + else if (!strcmp(token.id, "unix")) { + tw = FromUnixFD; + } + else if (!strcmp(token.id, "ht")) { + tw = FromFile; + } + else { + return -1; + } + + /* now check to see if I got a closing square brace */ + get_token(); + if (token.type != Rsquarebrace) + return -1; + + return tw; +} + + +FILE * +find_fp(FilePosition fp) +{ + FILE *lfile; + char fullname[256], addname[256]; + int ret_val; + + /* find the source file in the file hash table, if not there, open it */ + lfile = (FILE *) hash_find(&gFileHashTable, fp.name); + if (lfile == NULL) { + lfile = ht_file_open(fullname, addname, fp.name); + hash_insert(&gFileHashTable, (char *)lfile, fp.name); + } + + /* seek to beginning fp.pos */ + ret_val = fseek(lfile, fp.pos, 0); + if (ret_val == -1) { + perror("fseeking to a page"); + longjmp(jmpbuf, 1); + } + + /* now set some global values */ + page_start_fpos = fp.pos; + line_number = fp.ln; + return lfile; +} diff --git a/src/hyper/parse-aux.pamphlet b/src/hyper/parse-aux.pamphlet deleted file mode 100644 index e6809680..00000000 --- a/src/hyper/parse-aux.pamphlet +++ /dev/null @@ -1,670 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/parse-aux} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{parse-aux.h} -<>= -<> -#ifndef _PARSE_AUX_H_ -#define _PARSE_AUX_H_ 1 - -#include "hyper.h" - - -#endif -@ -\section{parse-aux.c} -<>= -#include "axiom-c-macros.h" -#define _PARSE_AUX_C -#include "useproto.h" -#include "debug.h" - -#include "parse.h" -#include "parse-aux.h" -#include "addfile.h" -#include "lex.h" -#include "mem.h" - -#include "all_hyper_proto.H1" - - -extern FILE *cfile; -extern int make_input_file; -extern int gverify_dates; - -InputBox *rb_list; -InputBox *end_rb_list; - -HashTable ht_gFileHashTable; - -#define htfhSize 100 - -/* Hash functions for active link windows */ - -int -window_equal(Window *w1, Window *w2) -{ - return *w1 == *w2; -} - -/* hash code for a window */ - -int -window_code(Window *w, int size) -{ - return (*w) % size; -} - -char * -window_id(Window w) -{ - char *ret; - char buff[32]; - int length; - - sprintf(buff, "%ld", w); - length = strlen(buff); - ret = (char *) halloc(length * sizeof(char) + 1, "windowid"); - strcpy(ret, buff); - return (ret); -} - -/* - * This procedure reads the ht database. It makes repeated calls to - * db_file_open, and while the returned pointer is not null, it continues to - * read the presented data base files - */ -void -read_ht_db(HashTable *page_hash, HashTable *macro_hash, HashTable *patch_hash) -{ - FILE *db_fp; - char db_file[256]; - int i = 0; - - gDatabasePath = NULL; - - hash_init( - page_hash, - PageHashSize, - (EqualFunction) string_equal, - (HashcodeFunction) string_hash); - hash_init( - macro_hash, - MacroHashSize, - (EqualFunction) string_equal, - (HashcodeFunction) string_hash); - hash_init( - patch_hash, - PatchHashSize, - (EqualFunction) string_equal, - (HashcodeFunction) string_hash); - - /* Lets initialize the FileHashTable */ - hash_init( - &ht_gFileHashTable, - htfhSize, - (EqualFunction) string_equal, - (HashcodeFunction) string_hash); - - while ((db_fp = db_file_open(db_file)) != NULL) { - i++; - read_ht_file(page_hash, macro_hash, patch_hash, db_fp, db_file); - fclose(db_fp); - } - - if (!i) { - fprintf(stderr, - "(HyperDoc) read_ht_db: No %s file found\n", db_file_name); - exit(-1); - } - - free_hash(&ht_gFileHashTable, (FreeFunction)free_string); -} - -/* - * This procedure reads a single HyperDoc database file. It is passed an already - * initilaized file pointer. It reads the whole file, updating the - * page hash, or the macro hash only when a previous entry with the same name - * is not found - */ - -static void -read_ht_file(HashTable *page_hash, HashTable *macro_hash, - HashTable *patch_hash, FILE *db_fp, char *db_file) -{ - char filename[256]; - char *fullname = filename; - UnloadedPage *page; - MacroStore *macro; - PatchStore *patch; - int pages = 0, c, mtime, ret_val; - struct stat fstats; - /*short time_ok = 1;*/ -/* fprintf(stderr,"parse_aux:read_ht_file: dp_file=%s\n",db_file);*/ - cfile = db_fp; - init_scanner(); - ret_val = strlen(db_file) - 1; - for (; ret_val >= 0; ret_val--) - if (db_file[ret_val] == '/') { - db_file[ret_val] = '\0'; - break; - } - c = getc(db_fp); - do { - if (c == '\t') { - get_filename(); - fullname = alloc_string(token.id); - if (fullname[0] != '/') { - strcpy(filename, db_file); - strcat(filename, "/"); - strcat(filename, fullname); - free(fullname); - fullname = alloc_string(filename); - } - - /* - * Until I get a filename that I have not seen before, just keep - * reading - */ - while (hash_find(&ht_gFileHashTable, fullname) != NULL) { - do { - c = getc(db_fp); - } while ((c != EOF) && (c != '\t')); - if (c == EOF) - return; - get_filename(); - fullname = alloc_string(token.id); - if (fullname[0] != '/') { - strcpy(filename, db_file); - strcat(filename, "/"); - strcat(filename, fullname); - free(fullname); - fullname = alloc_string(filename); - } - } -/* fprintf(stderr,"parse_aux:read_ht_file: fullname=%s\n",fullname);*/ - /* If I got here, then I must have a good filename */ - hash_insert(&ht_gFileHashTable, fullname, fullname); - - ret_val = stat(fullname, &fstats); - if (ret_val == -1) { - char buffer[300]; - - sprintf(buffer, "(HyperDoc) read_ht_db: Unable To Open %s :", fullname); - perror(buffer); - exit(-1); - } - get_token(); - mtime = atoi(token.id); - if (gverify_dates & (fstats.st_mtime > mtime)) { - fprintf(stderr, "(HyperDoc) read_ht_file: HyperDoc file %s has been updated\n", - - fullname); - fprintf(stderr, "(HyperDoc) Issue htadd %s to update database\n", fullname); - exit(-1); - } - while ((c = getc(db_fp)) != EOF) { - if (c == '\t') - break; - ungetc(c, db_fp); - get_token(); - switch (token.type) { - case Page: - get_token(); - - /* - * now check to see if the page has already been - * loaded - */ - page = (UnloadedPage *) halloc(sizeof(UnloadedPage), - "UnloadedPage"); - page->fpos.name = alloc_string(fullname); - page->name = alloc_string(token.id); - get_token(); - if (hash_find(page_hash, page->name) != NULL) { - fprintf(stderr, "(HyperDoc) Page name %s occurred twice\n", page->name); - fprintf(stderr, "(HyperDoc) The Version in %s is being ignored \n", - page->fpos.name); - free(page); - get_token(); - break; - } - page->fpos.pos = atoi(token.id); - get_token(); - page->fpos.ln = atoi(token.id); - page->type = UnloadedPageType; - hash_insert(page_hash, (char *)page, page->name); - pages++; - break; - case NewCommand: - get_token(); - macro = (MacroStore *) halloc(sizeof(MacroStore), "MacroStore"); - macro->fpos.name = alloc_string(fullname); - macro->name = alloc_string(token.id); - macro->macro_string = NULL; - get_token(); - if (hash_find(macro_hash, macro->name) != NULL) { - if (strcmp(macro->name, "localinfo") != 0) { - fprintf(stderr, "(HyperDoc) Macro name %s occurred twice\n", - macro->name); - fprintf(stderr, "(HyperDoc) The Version in %s is being ignored \n", - macro->fpos.name); - } - get_token(); - free(macro); - break; - } - macro->fpos.pos = atoi(token.id); - get_token(); - macro->fpos.ln = atoi(token.id); - macro->loaded = 0; - hash_insert(macro_hash, (char *)macro, macro->name); - break; - case Patch: - get_token(); - patch = (PatchStore *) alloc_patchstore(); - patch->fpos.name = alloc_string(fullname); - patch->name = alloc_string(token.id); - get_token(); - patch->fpos.pos = atoi(token.id); - get_token(); - patch->fpos.ln = atoi(token.id); - if (hash_find(patch_hash, patch->name) != NULL) { - fprintf(stderr, "(HyperDoc) Patch name %s occurred twice\n", patch->name); - fprintf(stderr, "(HyperDoc) The version in %s is being ignored \n", - patch->fpos.name); - free_patch(patch); - break; - } - hash_insert(patch_hash, (char *)patch, patch->name); - break; - default: - fprintf(stderr, "(HyperDoc) read_ht_db: Unknown type %s in ht.db\n", token.id); - exit(-1); - break; - } - } - } - else - c = getc(db_fp); - } while (c != EOF); -/* fprintf(stderr, - "parse_aux:read_ht_file:read %d pages from database\n", pages); */ -} - - -/* create an unmapped input-only window for an active screen area */ - -HyperLink * -make_link_window(TextNode *link_node, int type, int isSubWin) -{ - HyperLink *link; - XSetWindowAttributes at; - - if (make_input_file) - switch (type) { - case Downlink: - case Memolink: - case Windowlink:{ - char *name; - HyperDocPage *p; - - name = print_to_string(link_node); - p = (HyperDocPage *) hash_find(gWindow->fPageHashTable, name); - if (!p) - printf("undefined link to %s\n", name); - break; - } - } - else { - link = (HyperLink *) halloc(sizeof(HyperLink), "HyperLink"); - if (link == NULL) { - fprintf(stderr, "(HyperDoc) Ran out of memory allocating a hypertext link!\n"); - exit(-1); - } - at.cursor = gActiveCursor; - at.event_mask = ButtonPress; - if (isSubWin) - link->win = XCreateWindow(gXDisplay, gWindow->fDisplayedWindow, 0, 0, 100, 100, 0, - 0, InputOnly, CopyFromParent, - CWEventMask | CWCursor, &at); - else - link->win = 0; - link->type = type; - link->x = link->y = 0; - link->reference.node = link_node; - hash_insert(gLinkHashTable, (char *)link,(char *)&link->win); - return link; - } - return 0; -} - -HyperLink * -make_paste_window(PasteNode *paste) -{ - HyperLink *link; - XSetWindowAttributes at; - - if (!make_input_file) { - link = (HyperLink *) halloc(sizeof(HyperLink), "HyperLink"); - if (link == NULL) { - fprintf(stderr, "(HyperDoc) Ran out of memory allocating a hypertext link!\n"); - exit(-1); - } - at.cursor = gActiveCursor; - at.event_mask = ButtonPress; - link->win = XCreateWindow(gXDisplay, gWindow->fDisplayedWindow, - 0, 0, 100, 100, 0, - 0, InputOnly, CopyFromParent, - CWEventMask | CWCursor, &at); - link->type = Pastebutton; - link->x = link->y = 0; - link->reference.paste = paste; - hash_insert(gLinkHashTable, (char *)link,(char *) &link->win); - return link; - } - return 0; -} - - - -/* create a HyperDoc page structure with the given type and name */ - -static HyperDocPage * -make_special_page(int type, char *name) -{ - HyperDocPage *page = alloc_page(name); - - if (page == NULL) { - fprintf(stderr, "(HyperDoc) Ran out of memory allocating page.\n"); - exit(-1); - } - page->type = type; - free(page->fLinkHashTable); - page->fLinkHashTable = NULL; - return page; -} - - -/* insert the special button page types into the page hash table */ - -void -make_special_pages(HashTable *pageHashTable) -{ - hash_insert(pageHashTable, (char *)make_special_page(Quitbutton, "QuitPage"), - "QuitPage"); - hash_insert(pageHashTable, (char *)make_special_page(Returnbutton, "ReturnPage"), - "ReturnPage"); - hash_insert(pageHashTable, (char *)make_special_page(Upbutton, "UpPage"), - "UpPage"); -} - - -/* Here is where I put the item into the pages linked list */ - -/* Parse the \bound{varlist} command, and add vars to dependency table */ - -void -add_dependencies(void) -{ - TextNode *bound_node = curr_node; - TextNode *node; - SpadcomDepend *depend; - - if (cur_spadcom == NULL) { - fprintf(stderr, "(HyperDoc) \\bound occuring outside a \\spadcom\n"); - print_page_and_filename(); - exit(-1); - } - curr_node->type = Bound; - curr_node->data.node = alloc_node(); - curr_node = curr_node->data.node; - get_expected_token(Lbrace); - parse_HyperDoc(); - curr_node->type = Endarg; - curr_node = bound_node; - - if (gPageBeingParsed->depend_hash == NULL) { - gPageBeingParsed->depend_hash = - (HashTable *) halloc(sizeof(HashTable), "Hash Table"); - hash_init( - gPageBeingParsed->depend_hash, - DependHashSize, - (EqualFunction) string_equal, - (HashcodeFunction) string_hash); - } - for (node = bound_node->data.node; node->type != Endarg; node = node->next) { - if (node->type == Word) { - depend = (SpadcomDepend *) halloc(sizeof(SpadcomDepend), "SpadcomDepend"); - depend->label = alloc_string(node->data.text); - depend->spadcom = cur_spadcom; - depend->executed = 0; - hash_insert(gPageBeingParsed->depend_hash, (char *)depend, depend->label); - } - } -} - -/* Returns true iff the TextNode contains a single integer */ - -int -is_number(char * str) -{ - char *s; - - for (s = str; *s != '\0'; s++) { - if (!(isdigit(*s) || *s == '-')) - return 0; - } - return 1; -} -void -parser_error(char *str) -{ - /** this procedure is called by the parser when an error occurs. It prints - the error message, followed by the next 10 tokens to ease finding the - error for the user. *****/ - - int i, v; - - fprintf(stderr, " %s\n", str); - fprintf(stderr, "Here are the next 10 tokens:\n"); - for (i = 0; i < 10; i++) { - v = get_token(); - if (v == EOF) - break; - print_token(); - } - fprintf(stderr, "\n"); - exit(-1); -} - - -#define whitespace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n') -#define delim(c) \ - (whitespace(c)) - - -/* advance token to the next token in the input stream. */ -int -get_filename(void) -{ - int c, ws; - static int seen_white = 0; /*UNUSED */ - static char buffer[256]; - char *buf = buffer; - - if (last_token) { - last_token = 0; - return 0; - } - do { - keyword_fpos = fpos; - c = get_char(); - ws = whitespace(c); - if (ws) - seen_white = 1; - } while (ws); - switch (c) { - case EOF: - fprintf(stderr, "(HyperDoc) Error trying to read %s, unexpected end-of-file.\n",db_file_name); - exit(-1); - case '%': - case '\\': - case '{': - case '}': - fprintf(stderr, "(HyperDoc) Error unexpected character %c.\n",c); - exit(-1); - default: - do { - *buf++ = c; - } while ((c = get_char()) != EOF && !delim(c)); - unget_char(c); - *buf = '\0'; - token.type = Word; - token.id = buffer; - seen_white = 0; - break; - } - return 1; -} - -char * -get_input_string(void) -{ - char *string; - TextNode *string_node,*save_node; - - save_node = curr_node; - /* Get the nodes that make up the string */ - string_node = alloc_node(); - curr_node = string_node; - parse_HyperDoc(); - curr_node->type = Endarg; - - /* Once here we print to string to get the actual name */ - string = print_to_string(string_node); - free_node(string_node, 0); - curr_node=save_node; - return string; -} - -/* - * tries to determine if there is an optional argument for where I should be - * parsing from. If so it then tries to determine which - */ -int -get_where(void) -{ - int tw; - - get_token(); - if (token.type != Word) - return -1; - - /* Now try to determine if it is a good type */ - if (!strcmp(token.id, "lisp")) { - tw = FromSpadSocket; - } - else if (!strcmp(token.id, "unix")) { - tw = FromUnixFD; - } - else if (!strcmp(token.id, "ht")) { - tw = FromFile; - } - else { - return -1; - } - - /* now check to see if I got a closing square brace */ - get_token(); - if (token.type != Rsquarebrace) - return -1; - - return tw; -} - - -FILE * -find_fp(FilePosition fp) -{ - FILE *lfile; - char fullname[256], addname[256]; - int ret_val; - - /* find the source file in the file hash table, if not there, open it */ - lfile = (FILE *) hash_find(&gFileHashTable, fp.name); - if (lfile == NULL) { - lfile = ht_file_open(fullname, addname, fp.name); - hash_insert(&gFileHashTable, (char *)lfile, fp.name); - } - - /* seek to beginning fp.pos */ - ret_val = fseek(lfile, fp.pos, 0); - if (ret_val == -1) { - perror("fseeking to a page"); - longjmp(jmpbuf, 1); - } - - /* now set some global values */ - page_start_fpos = fp.pos; - line_number = fp.ln; - return lfile; -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/parse-input.c b/src/hyper/parse-input.c new file mode 100644 index 00000000..bdaee8da --- /dev/null +++ b/src/hyper/parse-input.c @@ -0,0 +1,602 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +#include "axiom-c-macros.h" +#define _PARSE_INPUT_C +/*** + Contains all the code needed to parse input items, + InputString + SimpleBox + RadioBox. + ****/ + +#include "useproto.h" +#include "debug.h" + +#include "parse.h" +#include "lex.h" +#include "hyper.h" + +#include "all_hyper_proto.H1" + +/* create an unmapped input window for getting strings * */ +extern int make_input_file; + +HyperLink * +make_input_window(InputItem * item) +{ + HyperLink *link; + XSetWindowAttributes at; + + if (!make_input_file) { + link = (HyperLink *) halloc(sizeof(HyperLink), "HyperLink"); + if (link == NULL) { + fprintf(stderr, "Ran out of memory allocating a hyper link!\n"); + exit(-1); + } + at.cursor = gActiveCursor; + at.background_pixel = gInputBackgroundColor; + at.border_pixel = gActiveColor; + link->win = XCreateWindow(gXDisplay, gWindow->fDisplayedWindow, 0, 0, 100, 100, 0, + 0, InputOutput, CopyFromParent, + CWCursor | CWBackPixel | CWBorderPixel, &at); + XSelectInput(gXDisplay, link->win, ButtonPressMask); + link->type = Inputstring; + link->x = link->y = 0; + /** This way when I click in an input window, I need only use reference + to get a pointer to the item ***/ + link->reference.string = item; + hash_insert(gLinkHashTable,(char *) link,(char *) &link->win); + + return link; + } + return 0; +} + +/* create an unmapped input window for boxes */ +HyperLink * +make_box_window(InputBox * box, int type) +{ + HyperLink *link = 0; + XSetWindowAttributes at; + + if (!make_input_file) { + link = (HyperLink *) halloc(sizeof(HyperLink), "Make_box_window"); + if (link == NULL) { + fprintf(stderr, "Ran out of memory allocating a hyper link!\n"); + exit(-1); + } + at.cursor = gActiveCursor; + at.background_pixel = gInputBackgroundColor; + link->win = XCreateWindow(gXDisplay, gWindow->fDisplayedWindow, + 0, 0, 100, 100, 0, + 0, InputOutput, CopyFromParent, + CWCursor | CWBackPixel, &at); + XSelectInput(gXDisplay, link->win, ButtonPressMask); + link->type = type; + link->x = link->y = 0; + /** This way when I click in an input window, I need only use reference + to get a pointer to the item ***/ + link->reference.box = box; + hash_insert(gLinkHashTable, (char *)link,(char *) &link->win); + } + + return link; +} + +void +initialize_default(InputItem *item,char * buff) +{ + LineStruct *newline; + LineStruct *curr_line; + int size = item->size; + int bp; + + item->curr_line = item->lines = alloc_inputline(size); + curr_line = item->lines; + item->num_lines = 1; + curr_line->line_number = 1; + /* while I still have lines to fill */ + for (bp = 0; *buff;) { + if (*buff == '\n') { + curr_line->len = bp; + curr_line->buffer[bp] = 0; + newline = alloc_inputline(size); + newline->line_number = ++(item->num_lines); + curr_line->next = newline; + newline->prev = curr_line; + curr_line = newline; + bp = 0; + buff++; + } + else if (bp == size) { + curr_line->len = size + 1; + curr_line->buffer[size] = '_'; + curr_line->buffer[size + 1] = 0; + newline = alloc_inputline(size); + newline->line_number = ++(item->num_lines); + curr_line->next = newline; + newline->prev = curr_line; + bp = 0; + curr_line = newline; + } + else { + curr_line->buffer[bp++] = *buff++; + } + } + curr_line->buff_pntr = curr_line->len = bp; + item->curr_line = curr_line; +} + + + +/* Parse the input string statement * */ +void +parse_inputstring(void) +{ + TextNode *input_node = curr_node; + char *name; + InputItem *item; + int size; + char *default_value; + + gStringValueOk = 0; + + /* first get the name */ + input_node->type = token.type; + get_expected_token(Lbrace); + name = get_input_string(); + input_node->data.text = alloc_string(name); + /* now get the width */ + get_expected_token(Lbrace); + get_expected_token(Word); + get_expected_token(Rbrace); + size = atoi(token.id); + if (size < 0) { + fprintf(stderr, "Illegal size in Input string\n"); + longjmp(jmpbuf, 1); + } + + /* get the default value */ + get_expected_token(Lbrace); + default_value = get_input_string(); + + /** now I need to malloc space for the input stuff **/ + item = (InputItem *) halloc(sizeof(InputItem), "InputItem"); + + /* Now store all the string info */ + item->name = (char *) + halloc((strlen(input_node->data.text) + 1) * (sizeof(char)),"parse_inputstring"); + strcpy(item->name, input_node->data.text); + item->size = size; + item->entered = 0; + item->next = NULL; + initialize_default(item, default_value); + + /** Now that I have all the structures made, lets make the window, and + add the item to the list ****/ + + input_node->link = make_input_window(item); + if (!make_input_file) + item->win = input_node->link->win; /* TTT */ + insert_item(item); + gStringValueOk = 1; + curr_node = input_node; + return ; +} + +void +parse_simplebox(void) +{ + InputBox *box; + char *name; + short int picked = 0; + char *filename; + TextNode *input_box = curr_node; + + gStringValueOk = 0; + + /* set the type and space fields */ + input_box->type = SimpleBox; + input_box->space = token.id[-1]; + + /* IS it selected? */ + get_token(); + if (token.type == Lsquarebrace) { + get_expected_token(Word); + if (!is_number(token.id)) { + fprintf(stderr, + "parse_simple_box: Expected a value not %s\n", token.id); + print_page_and_filename(); + jump(); + } + else if (!strcmp(token.id, "1")) + picked = 1; + else if (!strcmp(token.id, "0")) + picked = 0; + else { + fprintf(stderr, "parse_simple_box: Unexpected Value %s\n", token.id); + print_page_and_filename(); + jump(); + } + get_expected_token(Rsquarebrace); + get_token(); + } + + if (token.type != Lbrace) { + token_name(token.type); + fprintf(stderr, "parse_inputbox was expecting a { not a %s\n", ebuffer); + print_page_and_filename(); + jump(); + } + + name = get_input_string(); + if (gPageBeingParsed->box_hash && hash_find(gPageBeingParsed->box_hash, name)) { + fprintf(stderr, "Input box name %s is not unique \n", name); + print_page_and_filename(); + jump(); + } + + box = alloc_inputbox(); + box->name = alloc_string(name); + input_box->data.text = alloc_string(name); + box->picked = picked; + + /* Get the filename for the selected and unselected bitmaps */ + get_expected_token(Lbrace); + filename = get_input_string(); + if (!make_input_file) + box->selected = insert_image_struct(filename); + get_expected_token(Lbrace); + filename = get_input_string(); + if (!make_input_file) { + box->unselected = insert_image_struct(filename); + /* set the width and height for the maximaum of the two */ + input_box->height = max(box->selected->height, box->unselected->height); + input_box->width = max(box->selected->width, box->unselected->width); + /* Make the window and stuff */ + input_box->link = make_box_window(box, SimpleBox); + box->win = input_box->link->win; + + /* Now add the box to the box_has table for this window */ + if (gPageBeingParsed->box_hash == NULL) { + gPageBeingParsed->box_hash = (HashTable *) halloc(sizeof(HashTable), + "Box Hash"); + hash_init( + gPageBeingParsed->box_hash, + BoxHashSize, + (EqualFunction) string_equal, + (HashcodeFunction) string_hash); + } + hash_insert(gPageBeingParsed->box_hash, (char *)box, box->name); + } + + /* reset the curr_node and then return */ + curr_node = input_box; + gStringValueOk = 1; + return; +} +void +parse_radiobox(void) +{ + InputBox *box; + char *name; + char *group_name; + short int picked = 0; + TextNode *input_box = curr_node; + + gStringValueOk = 0; + + /* set the type and space fields */ + input_box->type = Radiobox; + input_box->space = token.id[-1]; + + /* IS it selected? */ + get_token(); + if (token.type == Lsquarebrace) { + get_expected_token(Word); + if (!is_number(token.id)) { + fprintf(stderr, + "parse_simple_box: Expected a value not %s\n", token.id); + print_page_and_filename(); + jump(); + } + else if (!strcmp(token.id, "1")) + picked = 1; + else if (!strcmp(token.id, "0")) + picked = 0; + else { + fprintf(stderr, "parse_simple_box: Unexpected Value %s\n", token.id); + print_page_and_filename(); + jump(); + } + get_expected_token(Rsquarebrace); + get_token(); + } + + if (token.type != Lbrace) { + token_name(token.type); + fprintf(stderr, "parse_inputbox was expecting a { not a %s\n", ebuffer); + print_page_and_filename(); + jump(); + } + + name = get_input_string(); + if (gPageBeingParsed->box_hash && hash_find(gPageBeingParsed->box_hash, name)) { + fprintf(stderr, "Input box name %s is not unique \n", name); + print_page_and_filename(); + jump(); + } + + box = alloc_inputbox(); + box->name = alloc_string(name); + input_box->data.text = alloc_string(name); + box->picked = picked; + + /* Now what I need to do is get the group name */ + get_token(); + if (token.type != Lbrace) { + token_name(token.type); + fprintf(stderr, "parse_inputbox was expecting a { not a %s\n", ebuffer); + print_page_and_filename(); + jump(); + } + group_name = get_input_string(); + + /* + * Now call a routine which searches the radio box list for the current + * group name, and if found adds this box to it + */ + add_box_to_rb_list(group_name, box); + + input_box->width = box->rbs->width; + input_box->height = box->rbs->height; + /* Make the window and stuff */ + input_box->link = make_box_window(box, Radiobox); + if (!make_input_file) + box->win = input_box->link->win; /* TTT */ + + + /* Now add the box to the box_has table for this window */ + if (gPageBeingParsed->box_hash == NULL) { + gPageBeingParsed->box_hash = (HashTable *) halloc(sizeof(HashTable), + "Box Hash"); + hash_init( + gPageBeingParsed->box_hash, + BoxHashSize, + (EqualFunction) string_equal, + (HashcodeFunction) string_hash); + } + hash_insert(gPageBeingParsed->box_hash, (char *)box, box->name); + + /* reset the curr_node and then return */ + curr_node = input_box; + gStringValueOk = 1; + return; +} +static void +add_box_to_rb_list(char *name,InputBox *box) +{ + RadioBoxes *trace = gPageBeingParsed->radio_boxes; + InputBox *list; + /*int found = 0;*/ + + while (trace != NULL && strcmp(trace->name, name)) + trace = trace->next; + + if (!trace) { + fprintf(stderr, "Tried to add a radio box to a non-existent group %s\n", + name); + print_page_and_filename(); + jump(); + } + + /* now add the box to the list */ + list = trace->boxes; + box->next = list; + trace->boxes = box; + + if (box->picked && check_others(box->next)) { + fprintf(stderr, "Only a single radio button can be picked\n"); + print_page_and_filename(); + box->picked = 0; + } + box->selected = trace->selected; + box->unselected = trace->unselected; + box->rbs = trace; + + return; +} +static int +check_others(InputBox *list) +{ + InputBox *trace = list; + + while (trace != NULL && !trace->picked) + trace = trace->next; + + if (trace != NULL) + return 1; + else + return 0; +} + + +/* inserts an item into the current input list */ +static void +insert_item(InputItem *item) +{ + InputItem *trace = gPageBeingParsed->input_list; + + if (gPageBeingParsed->current_item == NULL) { + gPageBeingParsed->current_item = item; + } + if (trace == NULL) { + /** Insert at the front of the list **/ + gPageBeingParsed->input_list = item; + return; + } + else { + /** find the end of the list **/ + while (trace->next != NULL) + trace = trace->next; + trace->next = item; + return; + } +} + +InputItem *save_item; + +void +init_paste_item(InputItem *item) +{ + InputItem *trace = gPageBeingParsed->input_list; + + if (!item) { + gPageBeingParsed->input_list = NULL; + gPageBeingParsed->current_item = NULL; + save_item = NULL; + } + else { + save_item = item->next; + trace->next = NULL; + } +} +void +repaste_item(void) +{ + InputItem *trace; + + if (save_item) { + for (trace = gPageBeingParsed->input_list; trace && trace->next != NULL; + trace = trace->next); + if (trace) { + trace->next = save_item; + } + else { + gWindow->page->input_list = save_item; + gWindow->page->current_item = save_item; + } + } + save_item = NULL; +} + +InputItem * +current_item(void) +{ + InputItem *trace = gPageBeingParsed->input_list; + + if (trace) { + for (; trace->next != NULL; trace = trace->next); + return trace; + } + else + return NULL; +} +int +already_there(char *name) +{ + RadioBoxes *trace = gPageBeingParsed->radio_boxes; + + while (trace && strcmp(trace->name, name)) + trace = trace->next; + + if (trace) + return 1; + else + return 0; +} +void +parse_radioboxes(void) +{ + TextNode *return_node = curr_node; + RadioBoxes *newrb; + char *fname; + + /* I really don't need this node, it just sets up some parsing stuff */ + return_node->type = Noop; + + newrb = alloc_rbs(); + + get_token(); + if (token.type != Lbrace) { + token_name(token.type); + fprintf(stderr, "\\radioboxes was expecting a name not %s\n", ebuffer); + print_page_and_filename(); + jump(); + } + + newrb->name = alloc_string(get_input_string()); + + /* quick search for the name in the current list */ + if (already_there(newrb->name)) { + free(newrb->name); + free(newrb); + fprintf(stderr, "Tried to redefine radioboxes %s\n", newrb->name); + print_page_and_filename(); + jump(); + } + /* now I have to get the selected and unslected bitmaps */ + get_token(); + if (token.type != Lbrace) { + token_name(token.type); + fprintf(stderr, "\\radioboxes was expecting a name not %s\n", ebuffer); + print_page_and_filename(); + jump(); + } + fname = get_input_string(); + if (!make_input_file) + newrb->selected = insert_image_struct(fname); + + get_token(); + if (token.type != Lbrace) { + token_name(token.type); + fprintf(stderr, "\\radioboxes was expecting a name not %s\n", ebuffer); + print_page_and_filename(); + jump(); + } + fname = get_input_string(); + if (!make_input_file) { + newrb->unselected = insert_image_struct(fname); + newrb->height = max(newrb->selected->height, newrb->unselected->height); + newrb->width = max(newrb->selected->width, newrb->unselected->width); + /* now add the thing to the current list of radio boxes */ + } + newrb->next = gPageBeingParsed->radio_boxes; + gPageBeingParsed->radio_boxes = newrb; + + curr_node = return_node; + return; +} diff --git a/src/hyper/parse-input.pamphlet b/src/hyper/parse-input.pamphlet deleted file mode 100644 index 020ff97a..00000000 --- a/src/hyper/parse-input.pamphlet +++ /dev/null @@ -1,631 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/parse-input} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{parse-input.c} -<>= -#include "axiom-c-macros.h" -#define _PARSE_INPUT_C -/*** - Contains all the code needed to parse input items, - InputString - SimpleBox - RadioBox. - ****/ - -#include "useproto.h" -#include "debug.h" - -#include "parse.h" -#include "parse-aux.h" -#include "lex.h" -#include "mem.h" - -#include "all_hyper_proto.H1" - -/* create an unmapped input window for getting strings * */ -extern int make_input_file; - -HyperLink * -make_input_window(InputItem * item) -{ - HyperLink *link; - XSetWindowAttributes at; - - if (!make_input_file) { - link = (HyperLink *) halloc(sizeof(HyperLink), "HyperLink"); - if (link == NULL) { - fprintf(stderr, "Ran out of memory allocating a hyper link!\n"); - exit(-1); - } - at.cursor = gActiveCursor; - at.background_pixel = gInputBackgroundColor; - at.border_pixel = gActiveColor; - link->win = XCreateWindow(gXDisplay, gWindow->fDisplayedWindow, 0, 0, 100, 100, 0, - 0, InputOutput, CopyFromParent, - CWCursor | CWBackPixel | CWBorderPixel, &at); - XSelectInput(gXDisplay, link->win, ButtonPressMask); - link->type = Inputstring; - link->x = link->y = 0; - /** This way when I click in an input window, I need only use reference - to get a pointer to the item ***/ - link->reference.string = item; - hash_insert(gLinkHashTable,(char *) link,(char *) &link->win); - - return link; - } - return 0; -} - -/* create an unmapped input window for boxes */ -HyperLink * -make_box_window(InputBox * box, int type) -{ - HyperLink *link = 0; - XSetWindowAttributes at; - - if (!make_input_file) { - link = (HyperLink *) halloc(sizeof(HyperLink), "Make_box_window"); - if (link == NULL) { - fprintf(stderr, "Ran out of memory allocating a hyper link!\n"); - exit(-1); - } - at.cursor = gActiveCursor; - at.background_pixel = gInputBackgroundColor; - link->win = XCreateWindow(gXDisplay, gWindow->fDisplayedWindow, - 0, 0, 100, 100, 0, - 0, InputOutput, CopyFromParent, - CWCursor | CWBackPixel, &at); - XSelectInput(gXDisplay, link->win, ButtonPressMask); - link->type = type; - link->x = link->y = 0; - /** This way when I click in an input window, I need only use reference - to get a pointer to the item ***/ - link->reference.box = box; - hash_insert(gLinkHashTable, (char *)link,(char *) &link->win); - } - - return link; -} - -void -initialize_default(InputItem *item,char * buff) -{ - LineStruct *newline; - LineStruct *curr_line; - int size = item->size; - int bp; - - item->curr_line = item->lines = alloc_inputline(size); - curr_line = item->lines; - item->num_lines = 1; - curr_line->line_number = 1; - /* while I still have lines to fill */ - for (bp = 0; *buff;) { - if (*buff == '\n') { - curr_line->len = bp; - curr_line->buffer[bp] = 0; - newline = alloc_inputline(size); - newline->line_number = ++(item->num_lines); - curr_line->next = newline; - newline->prev = curr_line; - curr_line = newline; - bp = 0; - buff++; - } - else if (bp == size) { - curr_line->len = size + 1; - curr_line->buffer[size] = '_'; - curr_line->buffer[size + 1] = 0; - newline = alloc_inputline(size); - newline->line_number = ++(item->num_lines); - curr_line->next = newline; - newline->prev = curr_line; - bp = 0; - curr_line = newline; - } - else { - curr_line->buffer[bp++] = *buff++; - } - } - curr_line->buff_pntr = curr_line->len = bp; - item->curr_line = curr_line; -} - - - -/* Parse the input string statement * */ -void -parse_inputstring(void) -{ - TextNode *input_node = curr_node; - char *name; - InputItem *item; - int size; - char *default_value; - - gStringValueOk = 0; - - /* first get the name */ - input_node->type = token.type; - get_expected_token(Lbrace); - name = get_input_string(); - input_node->data.text = alloc_string(name); - /* now get the width */ - get_expected_token(Lbrace); - get_expected_token(Word); - get_expected_token(Rbrace); - size = atoi(token.id); - if (size < 0) { - fprintf(stderr, "Illegal size in Input string\n"); - longjmp(jmpbuf, 1); - } - - /* get the default value */ - get_expected_token(Lbrace); - default_value = get_input_string(); - - /** now I need to malloc space for the input stuff **/ - item = (InputItem *) halloc(sizeof(InputItem), "InputItem"); - - /* Now store all the string info */ - item->name = (char *) - halloc((strlen(input_node->data.text) + 1) * (sizeof(char)),"parse_inputstring"); - strcpy(item->name, input_node->data.text); - item->size = size; - item->entered = 0; - item->next = NULL; - initialize_default(item, default_value); - - /** Now that I have all the structures made, lets make the window, and - add the item to the list ****/ - - input_node->link = make_input_window(item); - if (!make_input_file) - item->win = input_node->link->win; /* TTT */ - insert_item(item); - gStringValueOk = 1; - curr_node = input_node; - return ; -} - -void -parse_simplebox(void) -{ - InputBox *box; - char *name; - short int picked = 0; - char *filename; - TextNode *input_box = curr_node; - - gStringValueOk = 0; - - /* set the type and space fields */ - input_box->type = SimpleBox; - input_box->space = token.id[-1]; - - /* IS it selected? */ - get_token(); - if (token.type == Lsquarebrace) { - get_expected_token(Word); - if (!is_number(token.id)) { - fprintf(stderr, - "parse_simple_box: Expected a value not %s\n", token.id); - print_page_and_filename(); - jump(); - } - else if (!strcmp(token.id, "1")) - picked = 1; - else if (!strcmp(token.id, "0")) - picked = 0; - else { - fprintf(stderr, "parse_simple_box: Unexpected Value %s\n", token.id); - print_page_and_filename(); - jump(); - } - get_expected_token(Rsquarebrace); - get_token(); - } - - if (token.type != Lbrace) { - token_name(token.type); - fprintf(stderr, "parse_inputbox was expecting a { not a %s\n", ebuffer); - print_page_and_filename(); - jump(); - } - - name = get_input_string(); - if (gPageBeingParsed->box_hash && hash_find(gPageBeingParsed->box_hash, name)) { - fprintf(stderr, "Input box name %s is not unique \n", name); - print_page_and_filename(); - jump(); - } - - box = alloc_inputbox(); - box->name = alloc_string(name); - input_box->data.text = alloc_string(name); - box->picked = picked; - - /* Get the filename for the selected and unselected bitmaps */ - get_expected_token(Lbrace); - filename = get_input_string(); - if (!make_input_file) - box->selected = insert_image_struct(filename); - get_expected_token(Lbrace); - filename = get_input_string(); - if (!make_input_file) { - box->unselected = insert_image_struct(filename); - /* set the width and height for the maximaum of the two */ - input_box->height = max(box->selected->height, box->unselected->height); - input_box->width = max(box->selected->width, box->unselected->width); - /* Make the window and stuff */ - input_box->link = make_box_window(box, SimpleBox); - box->win = input_box->link->win; - - /* Now add the box to the box_has table for this window */ - if (gPageBeingParsed->box_hash == NULL) { - gPageBeingParsed->box_hash = (HashTable *) halloc(sizeof(HashTable), - "Box Hash"); - hash_init( - gPageBeingParsed->box_hash, - BoxHashSize, - (EqualFunction) string_equal, - (HashcodeFunction) string_hash); - } - hash_insert(gPageBeingParsed->box_hash, (char *)box, box->name); - } - - /* reset the curr_node and then return */ - curr_node = input_box; - gStringValueOk = 1; - return; -} -void -parse_radiobox(void) -{ - InputBox *box; - char *name; - char *group_name; - short int picked = 0; - TextNode *input_box = curr_node; - - gStringValueOk = 0; - - /* set the type and space fields */ - input_box->type = Radiobox; - input_box->space = token.id[-1]; - - /* IS it selected? */ - get_token(); - if (token.type == Lsquarebrace) { - get_expected_token(Word); - if (!is_number(token.id)) { - fprintf(stderr, - "parse_simple_box: Expected a value not %s\n", token.id); - print_page_and_filename(); - jump(); - } - else if (!strcmp(token.id, "1")) - picked = 1; - else if (!strcmp(token.id, "0")) - picked = 0; - else { - fprintf(stderr, "parse_simple_box: Unexpected Value %s\n", token.id); - print_page_and_filename(); - jump(); - } - get_expected_token(Rsquarebrace); - get_token(); - } - - if (token.type != Lbrace) { - token_name(token.type); - fprintf(stderr, "parse_inputbox was expecting a { not a %s\n", ebuffer); - print_page_and_filename(); - jump(); - } - - name = get_input_string(); - if (gPageBeingParsed->box_hash && hash_find(gPageBeingParsed->box_hash, name)) { - fprintf(stderr, "Input box name %s is not unique \n", name); - print_page_and_filename(); - jump(); - } - - box = alloc_inputbox(); - box->name = alloc_string(name); - input_box->data.text = alloc_string(name); - box->picked = picked; - - /* Now what I need to do is get the group name */ - get_token(); - if (token.type != Lbrace) { - token_name(token.type); - fprintf(stderr, "parse_inputbox was expecting a { not a %s\n", ebuffer); - print_page_and_filename(); - jump(); - } - group_name = get_input_string(); - - /* - * Now call a routine which searches the radio box list for the current - * group name, and if found adds this box to it - */ - add_box_to_rb_list(group_name, box); - - input_box->width = box->rbs->width; - input_box->height = box->rbs->height; - /* Make the window and stuff */ - input_box->link = make_box_window(box, Radiobox); - if (!make_input_file) - box->win = input_box->link->win; /* TTT */ - - - /* Now add the box to the box_has table for this window */ - if (gPageBeingParsed->box_hash == NULL) { - gPageBeingParsed->box_hash = (HashTable *) halloc(sizeof(HashTable), - "Box Hash"); - hash_init( - gPageBeingParsed->box_hash, - BoxHashSize, - (EqualFunction) string_equal, - (HashcodeFunction) string_hash); - } - hash_insert(gPageBeingParsed->box_hash, (char *)box, box->name); - - /* reset the curr_node and then return */ - curr_node = input_box; - gStringValueOk = 1; - return; -} -static void -add_box_to_rb_list(char *name,InputBox *box) -{ - RadioBoxes *trace = gPageBeingParsed->radio_boxes; - InputBox *list; - /*int found = 0;*/ - - while (trace != NULL && strcmp(trace->name, name)) - trace = trace->next; - - if (!trace) { - fprintf(stderr, "Tried to add a radio box to a non-existent group %s\n", - name); - print_page_and_filename(); - jump(); - } - - /* now add the box to the list */ - list = trace->boxes; - box->next = list; - trace->boxes = box; - - if (box->picked && check_others(box->next)) { - fprintf(stderr, "Only a single radio button can be picked\n"); - print_page_and_filename(); - box->picked = 0; - } - box->selected = trace->selected; - box->unselected = trace->unselected; - box->rbs = trace; - - return; -} -static int -check_others(InputBox *list) -{ - InputBox *trace = list; - - while (trace != NULL && !trace->picked) - trace = trace->next; - - if (trace != NULL) - return 1; - else - return 0; -} - - -/* inserts an item into the current input list */ -static void -insert_item(InputItem *item) -{ - InputItem *trace = gPageBeingParsed->input_list; - - if (gPageBeingParsed->current_item == NULL) { - gPageBeingParsed->current_item = item; - } - if (trace == NULL) { - /** Insert at the front of the list **/ - gPageBeingParsed->input_list = item; - return; - } - else { - /** find the end of the list **/ - while (trace->next != NULL) - trace = trace->next; - trace->next = item; - return; - } -} - -InputItem *save_item; - -void -init_paste_item(InputItem *item) -{ - InputItem *trace = gPageBeingParsed->input_list; - - if (!item) { - gPageBeingParsed->input_list = NULL; - gPageBeingParsed->current_item = NULL; - save_item = NULL; - } - else { - save_item = item->next; - trace->next = NULL; - } -} -void -repaste_item(void) -{ - InputItem *trace; - - if (save_item) { - for (trace = gPageBeingParsed->input_list; trace && trace->next != NULL; - trace = trace->next); - if (trace) { - trace->next = save_item; - } - else { - gWindow->page->input_list = save_item; - gWindow->page->current_item = save_item; - } - } - save_item = NULL; -} - -InputItem * -current_item(void) -{ - InputItem *trace = gPageBeingParsed->input_list; - - if (trace) { - for (; trace->next != NULL; trace = trace->next); - return trace; - } - else - return NULL; -} -int -already_there(char *name) -{ - RadioBoxes *trace = gPageBeingParsed->radio_boxes; - - while (trace && strcmp(trace->name, name)) - trace = trace->next; - - if (trace) - return 1; - else - return 0; -} -void -parse_radioboxes(void) -{ - TextNode *return_node = curr_node; - RadioBoxes *newrb; - char *fname; - - /* I really don't need this node, it just sets up some parsing stuff */ - return_node->type = Noop; - - newrb = alloc_rbs(); - - get_token(); - if (token.type != Lbrace) { - token_name(token.type); - fprintf(stderr, "\\radioboxes was expecting a name not %s\n", ebuffer); - print_page_and_filename(); - jump(); - } - - newrb->name = alloc_string(get_input_string()); - - /* quick search for the name in the current list */ - if (already_there(newrb->name)) { - free(newrb->name); - free(newrb); - fprintf(stderr, "Tried to redefine radioboxes %s\n", newrb->name); - print_page_and_filename(); - jump(); - } - /* now I have to get the selected and unslected bitmaps */ - get_token(); - if (token.type != Lbrace) { - token_name(token.type); - fprintf(stderr, "\\radioboxes was expecting a name not %s\n", ebuffer); - print_page_and_filename(); - jump(); - } - fname = get_input_string(); - if (!make_input_file) - newrb->selected = insert_image_struct(fname); - - get_token(); - if (token.type != Lbrace) { - token_name(token.type); - fprintf(stderr, "\\radioboxes was expecting a name not %s\n", ebuffer); - print_page_and_filename(); - jump(); - } - fname = get_input_string(); - if (!make_input_file) { - newrb->unselected = insert_image_struct(fname); - newrb->height = max(newrb->selected->height, newrb->unselected->height); - newrb->width = max(newrb->selected->width, newrb->unselected->width); - /* now add the thing to the current list of radio boxes */ - } - newrb->next = gPageBeingParsed->radio_boxes; - gPageBeingParsed->radio_boxes = newrb; - - curr_node = return_node; - return; -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/parse-paste.c b/src/hyper/parse-paste.c new file mode 100644 index 00000000..3cd35b1f --- /dev/null +++ b/src/hyper/parse-paste.c @@ -0,0 +1,386 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +/****************************************************************************** + * + * parse-paste.c: HyperDoc routines for paste-in areas. + * + * Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993. + * + ****************************************************************************/ +#define _PARSE_PASTE_C +#include "axiom-c-macros.h" +#include "useproto.h" +#include "debug.h" + + +#include "parse.h" +#include "hyper.h" +#include "display.h" +#include "group.h" + +#include "all_hyper_proto.H1" + + +extern FILE *cfile; +short int gInPaste; + + +void +parse_paste(void) +{ + TextNode *pn = curr_node; + PasteNode *paste; + int where; + + if (gParserRegion != Scrolling) { + fprintf(stderr, "(HyperDoc) Paste areas are only allowed in the scrolling area:"); + print_page_and_filename(); + jump(); + } + gInPaste++; + + /* now I need to get the name */ + get_token(); + if (token.type != Lbrace) { + fprintf(stderr, "(HyperDoc) A paste area needs a name:\n"); + print_next_ten_tokens(); + print_page_and_filename(); + jump(); + } + pn->data.text = alloc_string(get_input_string()); + pn->type = Paste; + + /* + * now see if there is already an entry in the hash_table for this thing, + * if not create it and put it there. + */ + paste = (PasteNode *) hash_find(gWindow->fPasteHashTable, pn->data.text); + if (paste == 0) { + paste = alloc_paste_node(pn->data.text); + hash_insert(gWindow->fPasteHashTable, (char *)paste, paste->name); + } + else if (paste->haspaste) { + fprintf(stderr, "(HyperDoc) Tried to redefine paste area %s\n", paste->name); + print_page_and_filename(); + /* jump(); */ + } + paste->haspaste = 1; + paste->paste_item = current_item(); + get_token(); + if (token.type == Lsquarebrace) { + /* user wishes to specify a where to send the command */ + where = get_where(); + if (where == -1) { + paste->where = -1; + fprintf(stderr, "(HyperDoc) \\begin{paste} was expecting [lisp|unix|ht]\n"); + print_next_ten_tokens(); + print_page_and_filename(); + jump(); + } + else + paste->where = where; + get_token(); + } + else + paste->where = FromFile; + + /* now try to get the command argument or page name */ + if (token.type != Lbrace) { + paste->where = 0; + fprintf(stderr, "(HyperDoc) \\begin{paste} was expecting an argument\n"); + print_next_ten_tokens(); + print_page_and_filename(); + jump(); + } + paste->arg_node = alloc_node(); + curr_node = paste->arg_node; + parse_HyperDoc(); + curr_node->type = Endarg; + + gWindow->fDisplayedWindow = gWindow->fScrollWindow; + + /* Now try to find the displaying text */ + pn->next = alloc_node(); + curr_node = pn->next; + parse_HyperDoc(); + curr_node->type = Endpaste; + paste->end_node = curr_node; + + paste->begin_node = pn; + gInPaste--; +} + +void +parse_pastebutton(void) +{ + PasteNode *paste; + TextNode *pb; + + /* + * this routine parse a \pastebutton expression. The syntax is + * \pastebutton{name} + */ + pb = curr_node; + pb->type = Pastebutton; + + /* first thing I should do is get the name */ + get_token(); + if (token.type != Lbrace) { + fprintf(stderr, "(HyperDoc) \\pastebutton needs a name\n"); + print_page_and_filename(); + print_next_ten_tokens(); + jump(); + } + pb->data.text = alloc_string(get_input_string()); + + /* + * now I should see if the paste area has already been parsed, and if not + * I should create a spot in the hash table for it + */ + paste = (PasteNode *) hash_find(gWindow->fPasteHashTable, pb->data.text); + if (paste == 0) { + paste = alloc_paste_node(pb->data.text); + hash_insert(gWindow->fPasteHashTable,(char *) paste, paste->name); + } + else if (paste->hasbutton) { + fprintf(stderr, "(HyperDoc) Tried to redefine paste area %s\n", paste->name); + print_page_and_filename(); + /* jump(); */ + } + paste->hasbutton = 1; + + /* Now we need to parse the HyperDoc and for the displayed text */ + + get_token(); + if (token.type != Lbrace) { + fprintf(stderr, "(HyperDoc) \\pastebutton was expecting a { \n"); + print_page_and_filename(); + print_next_ten_tokens(); + jump(); + } + pb->next = alloc_node(); + curr_node = pb->next; + parse_HyperDoc(); + curr_node->type = Endpastebutton; + + /* once that is done I need only make the window for this link */ + pb->link = make_paste_window(paste); +} + + +/* + * this routine is responsible for parsing a patch from a file. To do this I + * guess er will init_scanner, then parse, the parsed piece of text + * will replace the current PasteNode which will be squashed down to + * nothing, and then discarded. + */ + +HyperDocPage * +parse_patch(PasteNode *paste) +{ + TextNode *new; + TextNode *end_node; + TextNode *begin_node; + TextNode *arg_node; + TextNode *throw; + TextNode *next_node; + InputItem *paste_item = paste->paste_item; + int where = paste->where; + GroupItem *g = paste->group; + ItemStack *is = paste->item_stack; + PatchStore *patch; + char *patch_name; + int ret_value = 1; + + /* prepare to throw away the current paste node */ + end_node = paste->end_node; + next_node = end_node->next; + begin_node = paste->begin_node; + arg_node = paste->arg_node; + throw = begin_node->next; + + /* now read the new stuff and add it in between all this stuff */ + + switch (where) { + case FromFile: + patch_name = print_to_string(arg_node); + patch = (PatchStore *) hash_find(gWindow->fPatchHashTable, patch_name); + if (!patch) { + fprintf(stderr, "(HyperDoc) Unknown patch name %s\n", patch_name); + BeepAtTheUser(); + return 0; + } + if (!patch->loaded) + load_patch(patch); + input_type = FromString; + input_string = patch->string; + break; + case FromSpadSocket: + input_type = FromSpadSocket; + ret_value = issue_serverpaste(arg_node); + if (ret_value < 0) { + paste->where = where; + paste->end_node = end_node; + paste->arg_node = arg_node; + paste->group = g; + paste->item_stack = is; + paste->haspaste = 1; + return 0; + } + break; + case FromUnixFD: + input_type = FromUnixFD; + issue_unixpaste(arg_node); + break; + default: + fprintf(stderr, "(HyperDoc) \\parsebutton error: Unknown where\n"); + exit(-1); + break; + } + + paste->where = 0; + paste->end_node = paste->arg_node = paste->begin_node = 0; + paste->group = 0; + paste->item_stack = 0; + paste->haspaste = 0; + paste->paste_item = 0; + + + /* set the jump buffer in case it is needed */ + if (setjmp(jmpbuf)) { + /*** OOOPS, an error occurred ****/ + fprintf(stderr, "(HyperDoc) Had an error parsing a patch: Goodbye!\n"); + exit(-1); + } + + + end_node->next = 0; + free_node(throw, 1); + + init_parse_patch(gWindow->page); + init_paste_item(paste_item); + get_token(); + if (token.type != Patch) { + fprintf(stderr, "(HyperDoc) Pastebutton %s was expecting a patch\n", + paste->name); + jump(); + } + if (input_type == FromString) { + get_token(); + if (token.type != Lbrace) { + token_name(token.type); + fprintf(stderr, "(HyperDoc) Unexpected %s \n", ebuffer); + print_page_and_filename(); + jump(); + } + + get_token(); + if (token.type != Word) { + token_name(token.type); + fprintf(stderr, "(HyperDoc) Unexpected %s \n", ebuffer); + print_page_and_filename(); + jump(); + } + + get_token(); + if (token.type != Rbrace) { + token_name(token.type); + fprintf(stderr, "(HyperDoc) Unexpected %s \n", ebuffer); + print_page_and_filename(); + jump(); + } + } + new = alloc_node(); + curr_node = new; + parse_HyperDoc(); + + /* Once I am back, I need only reallign all the text structures */ + curr_node->type = Noop; + curr_node->next = next_node; + begin_node->next = new; + begin_node->type = Noop; + free(begin_node->data.text); + begin_node->data.text = 0; + + gWindow->fDisplayedWindow = gWindow->fScrollWindow; + + repaste_item(); + + paste_page(begin_node); + + /* so now I should just be able to disappear */ + return gWindow->page; +} + +static void +load_patch(PatchStore *patch) +{ + long start_fpos; + int size = 0; + int limsize; + char *trace; + + + save_scanner_state(); + cfile = find_fp(patch->fpos); + + init_scanner(); + + /** First thing I should do is make sure that the name is correct ***/ + start_fpos = fpos; + get_expected_token(Patch); + get_expected_token(Lbrace); + get_expected_token(Word); + if (strcmp(token.id, patch->name)) { + /** WOW, Somehow I had the location of the wrong macro **/ + fprintf(stderr, "(HyperDoc) Expected patch name %s: got instead %s in load_patch\n", + patch->name, token.id); + jump(); + } + get_expected_token(Rbrace); + + scan_HyperDoc(); + fseek(cfile, patch->fpos.pos + start_fpos, 0); + limsize = fpos - start_fpos + 1; + patch->string = (char *) halloc((limsize + 1) * sizeof(char), "Patch String"); + for (size = 1, trace = patch->string; size < limsize; size++) + *trace++ = getc(cfile); + *trace = '\0'; + patch->loaded = 1; + restore_scanner_state(); +} + + diff --git a/src/hyper/parse-paste.h b/src/hyper/parse-paste.h new file mode 100644 index 00000000..ec550ff3 --- /dev/null +++ b/src/hyper/parse-paste.h @@ -0,0 +1,44 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyirght (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +#ifndef _PARSE_PASTE_H_ +#define _PARSE_PASTE_H_ 1 + +#include "axiom-c-macros.h" +#include "hyper.h" + +extern short int gInPaste; + +#endif diff --git a/src/hyper/parse-paste.pamphlet b/src/hyper/parse-paste.pamphlet deleted file mode 100644 index af851bd7..00000000 --- a/src/hyper/parse-paste.pamphlet +++ /dev/null @@ -1,428 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/parse-paste} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{parse-paste.h} -<>= -<> -#ifndef _PARSE_PASTE_H_ -#define _PARSE_PASTE_H_ 1 - -#include "axiom-c-macros.h" -#include "hyper.h" - -extern short int gInPaste; - -#endif -@ -\section{parse-paste.c} -<>= -/****************************************************************************** - * - * parse-paste.c: HyperDoc routines for paste-in areas. - * - * Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993. - * - ****************************************************************************/ -#define _PARSE_PASTE_C -#include "axiom-c-macros.h" -#include "useproto.h" -#include "debug.h" - - -#include "parse.h" -#include "parse-aux.h" -#include "mem.h" -#include "display.h" -#include "group.h" - -#include "all_hyper_proto.H1" - - -extern FILE *cfile; -short int gInPaste; - - -void -parse_paste(void) -{ - TextNode *pn = curr_node; - PasteNode *paste; - int where; - - if (gParserRegion != Scrolling) { - fprintf(stderr, "(HyperDoc) Paste areas are only allowed in the scrolling area:"); - print_page_and_filename(); - jump(); - } - gInPaste++; - - /* now I need to get the name */ - get_token(); - if (token.type != Lbrace) { - fprintf(stderr, "(HyperDoc) A paste area needs a name:\n"); - print_next_ten_tokens(); - print_page_and_filename(); - jump(); - } - pn->data.text = alloc_string(get_input_string()); - pn->type = Paste; - - /* - * now see if there is already an entry in the hash_table for this thing, - * if not create it and put it there. - */ - paste = (PasteNode *) hash_find(gWindow->fPasteHashTable, pn->data.text); - if (paste == 0) { - paste = alloc_paste_node(pn->data.text); - hash_insert(gWindow->fPasteHashTable, (char *)paste, paste->name); - } - else if (paste->haspaste) { - fprintf(stderr, "(HyperDoc) Tried to redefine paste area %s\n", paste->name); - print_page_and_filename(); - /* jump(); */ - } - paste->haspaste = 1; - paste->paste_item = current_item(); - get_token(); - if (token.type == Lsquarebrace) { - /* user wishes to specify a where to send the command */ - where = get_where(); - if (where == -1) { - paste->where = -1; - fprintf(stderr, "(HyperDoc) \\begin{paste} was expecting [lisp|unix|ht]\n"); - print_next_ten_tokens(); - print_page_and_filename(); - jump(); - } - else - paste->where = where; - get_token(); - } - else - paste->where = FromFile; - - /* now try to get the command argument or page name */ - if (token.type != Lbrace) { - paste->where = 0; - fprintf(stderr, "(HyperDoc) \\begin{paste} was expecting an argument\n"); - print_next_ten_tokens(); - print_page_and_filename(); - jump(); - } - paste->arg_node = alloc_node(); - curr_node = paste->arg_node; - parse_HyperDoc(); - curr_node->type = Endarg; - - gWindow->fDisplayedWindow = gWindow->fScrollWindow; - - /* Now try to find the displaying text */ - pn->next = alloc_node(); - curr_node = pn->next; - parse_HyperDoc(); - curr_node->type = Endpaste; - paste->end_node = curr_node; - - paste->begin_node = pn; - gInPaste--; -} - -void -parse_pastebutton(void) -{ - PasteNode *paste; - TextNode *pb; - - /* - * this routine parse a \pastebutton expression. The syntax is - * \pastebutton{name} - */ - pb = curr_node; - pb->type = Pastebutton; - - /* first thing I should do is get the name */ - get_token(); - if (token.type != Lbrace) { - fprintf(stderr, "(HyperDoc) \\pastebutton needs a name\n"); - print_page_and_filename(); - print_next_ten_tokens(); - jump(); - } - pb->data.text = alloc_string(get_input_string()); - - /* - * now I should see if the paste area has already been parsed, and if not - * I should create a spot in the hash table for it - */ - paste = (PasteNode *) hash_find(gWindow->fPasteHashTable, pb->data.text); - if (paste == 0) { - paste = alloc_paste_node(pb->data.text); - hash_insert(gWindow->fPasteHashTable,(char *) paste, paste->name); - } - else if (paste->hasbutton) { - fprintf(stderr, "(HyperDoc) Tried to redefine paste area %s\n", paste->name); - print_page_and_filename(); - /* jump(); */ - } - paste->hasbutton = 1; - - /* Now we need to parse the HyperDoc and for the displayed text */ - - get_token(); - if (token.type != Lbrace) { - fprintf(stderr, "(HyperDoc) \\pastebutton was expecting a { \n"); - print_page_and_filename(); - print_next_ten_tokens(); - jump(); - } - pb->next = alloc_node(); - curr_node = pb->next; - parse_HyperDoc(); - curr_node->type = Endpastebutton; - - /* once that is done I need only make the window for this link */ - pb->link = make_paste_window(paste); -} - - -/* - * this routine is responsible for parsing a patch from a file. To do this I - * guess er will init_scanner, then parse, the parsed piece of text - * will replace the current PasteNode which will be squashed down to - * nothing, and then discarded. - */ - -HyperDocPage * -parse_patch(PasteNode *paste) -{ - TextNode *new; - TextNode *end_node; - TextNode *begin_node; - TextNode *arg_node; - TextNode *throw; - TextNode *next_node; - InputItem *paste_item = paste->paste_item; - int where = paste->where; - GroupItem *g = paste->group; - ItemStack *is = paste->item_stack; - PatchStore *patch; - char *patch_name; - int ret_value = 1; - - /* prepare to throw away the current paste node */ - end_node = paste->end_node; - next_node = end_node->next; - begin_node = paste->begin_node; - arg_node = paste->arg_node; - throw = begin_node->next; - - /* now read the new stuff and add it in between all this stuff */ - - switch (where) { - case FromFile: - patch_name = print_to_string(arg_node); - patch = (PatchStore *) hash_find(gWindow->fPatchHashTable, patch_name); - if (!patch) { - fprintf(stderr, "(HyperDoc) Unknown patch name %s\n", patch_name); - BeepAtTheUser(); - return 0; - } - if (!patch->loaded) - load_patch(patch); - input_type = FromString; - input_string = patch->string; - break; - case FromSpadSocket: - input_type = FromSpadSocket; - ret_value = issue_serverpaste(arg_node); - if (ret_value < 0) { - paste->where = where; - paste->end_node = end_node; - paste->arg_node = arg_node; - paste->group = g; - paste->item_stack = is; - paste->haspaste = 1; - return 0; - } - break; - case FromUnixFD: - input_type = FromUnixFD; - issue_unixpaste(arg_node); - break; - default: - fprintf(stderr, "(HyperDoc) \\parsebutton error: Unknown where\n"); - exit(-1); - break; - } - - paste->where = 0; - paste->end_node = paste->arg_node = paste->begin_node = 0; - paste->group = 0; - paste->item_stack = 0; - paste->haspaste = 0; - paste->paste_item = 0; - - - /* set the jump buffer in case it is needed */ - if (setjmp(jmpbuf)) { - /*** OOOPS, an error occurred ****/ - fprintf(stderr, "(HyperDoc) Had an error parsing a patch: Goodbye!\n"); - exit(-1); - } - - - end_node->next = 0; - free_node(throw, 1); - - init_parse_patch(gWindow->page); - init_paste_item(paste_item); - get_token(); - if (token.type != Patch) { - fprintf(stderr, "(HyperDoc) Pastebutton %s was expecting a patch\n", - paste->name); - jump(); - } - if (input_type == FromString) { - get_token(); - if (token.type != Lbrace) { - token_name(token.type); - fprintf(stderr, "(HyperDoc) Unexpected %s \n", ebuffer); - print_page_and_filename(); - jump(); - } - - get_token(); - if (token.type != Word) { - token_name(token.type); - fprintf(stderr, "(HyperDoc) Unexpected %s \n", ebuffer); - print_page_and_filename(); - jump(); - } - - get_token(); - if (token.type != Rbrace) { - token_name(token.type); - fprintf(stderr, "(HyperDoc) Unexpected %s \n", ebuffer); - print_page_and_filename(); - jump(); - } - } - new = alloc_node(); - curr_node = new; - parse_HyperDoc(); - - /* Once I am back, I need only reallign all the text structures */ - curr_node->type = Noop; - curr_node->next = next_node; - begin_node->next = new; - begin_node->type = Noop; - free(begin_node->data.text); - begin_node->data.text = 0; - - gWindow->fDisplayedWindow = gWindow->fScrollWindow; - - repaste_item(); - - paste_page(begin_node); - - /* so now I should just be able to disappear */ - return gWindow->page; -} - -static void -load_patch(PatchStore *patch) -{ - long start_fpos; - int size = 0; - int limsize; - char *trace; - - - save_scanner_state(); - cfile = find_fp(patch->fpos); - - init_scanner(); - - /** First thing I should do is make sure that the name is correct ***/ - start_fpos = fpos; - get_expected_token(Patch); - get_expected_token(Lbrace); - get_expected_token(Word); - if (strcmp(token.id, patch->name)) { - /** WOW, Somehow I had the location of the wrong macro **/ - fprintf(stderr, "(HyperDoc) Expected patch name %s: got instead %s in load_patch\n", - patch->name, token.id); - jump(); - } - get_expected_token(Rbrace); - - scan_HyperDoc(); - fseek(cfile, patch->fpos.pos + start_fpos, 0); - limsize = fpos - start_fpos + 1; - patch->string = (char *) halloc((limsize + 1) * sizeof(char), "Patch String"); - for (size = 1, trace = patch->string; size < limsize; size++) - *trace++ = getc(cfile); - *trace = '\0'; - patch->loaded = 1; - restore_scanner_state(); -} - - -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/parse-types.c b/src/hyper/parse-types.c new file mode 100644 index 00000000..047423e9 --- /dev/null +++ b/src/hyper/parse-types.c @@ -0,0 +1,775 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +/****************************************************************************** + * + * parse-types.h: HyperDoc parsing routines for node types. + * + * Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993. + * + ****************************************************************************/ +#define _PARSE_TYPES_C +#include "axiom-c-macros.h" +#include "useproto.h" +#include "debug.h" + +#include "parse.h" +#include "parse-types.h" +#include "hyper.h" +#include "lex.h" +#include "extent.h" +#include "hterror.h" + +#include "all_hyper_proto.H1" + +boolean gInButton = FALSE; +boolean gInIf = FALSE; +boolean gInItems = FALSE; +boolean gInOptional = FALSE; + +void +parse_ifcond(void) +{ + TextNode *ifnode = curr_node; + TextNode *endif; + TextNode *condnode; + + /* + * parse a conditional. At first I am just going to parse if + * fi + */ + if (gInIf) { + curr_node->type = Noop; + fprintf(stderr, "\\if found within \\if \n"); + longjmp(jmpbuf, 1); + fprintf(stderr, "Longjump failed, Exiting\n"); + exit(-1); + } + gInIf++; + curr_node->type = Ifcond; + curr_node->space = token.id[-1]; + curr_node->data.ifnode = alloc_ifnode(); + /* Now get the cond node I hope */ + + condnode = curr_node->data.ifnode->cond = alloc_node(); + curr_node = condnode; + parse_condnode(); + + endif = alloc_node(); + endif->type = Endif; + ifnode->data.ifnode->thennode = alloc_node(); + curr_node = ifnode->data.ifnode->thennode; + parse_HyperDoc(); + if (token.type == Fi) { + curr_node->type = Fi; + curr_node->next = endif; + ifnode->data.ifnode->elsenode = endif; + } + else if (token.type == Else) { + /* first finish up the then part */ + curr_node->type = Fi; + curr_node->next = endif; + /* the go and parse the else part */ + ifnode->data.ifnode->elsenode = alloc_node(); + curr_node = ifnode->data.ifnode->elsenode; + parse_HyperDoc(); + if (token.type != Fi) { + token_name(token.type); + curr_node->type = Noop; + fprintf(stderr, "Expected a \\fi not a %s", ebuffer); + longjmp(jmpbuf, 1); + fprintf(stderr, "Longjump failed, Exiting\n"); + exit(-1); + } + curr_node->type = Fi; + curr_node->next = endif; + } + else { + curr_node->type = Noop; + token_name(token.type); + fprintf(stderr, "Expected a \\fi not a %s", ebuffer); + longjmp(jmpbuf, 1); + fprintf(stderr, "Longjump failed, Exiting\n"); + exit(-1); + } + ifnode->next = ifnode->data.ifnode->thennode; + ifnode->width = -1; /* A flag for compute if extents */ + curr_node = endif; + gInIf--; +} + +static void +parse_condnode(void) +{ + get_token(); + + switch (token.type) { + case Cond: + curr_node->type = Cond; + curr_node->data.text = alloc_string(token.id); + break; + case Haslisp: + case Hasreturn: + case Lastwindow: + case Hasup: + curr_node->type = token.type; + break; + case Boxcond: + curr_node->type = Boxcond; + curr_node->data.text = alloc_string(token.id); + break; + case Hasreturnto: + parse_hasreturnto(); + break; + default: + { + char eb[128]; + token_name(token.type); + sprintf(eb, "Unexpected Token %s\n", eb); + htperror(eb, HTCONDNODE); + } + break; + } +} + +static void +parse_hasreturnto(void) +{ + TextNode *hrt = curr_node, *arg_node = alloc_node(); + + curr_node->type = Hasreturnto; + curr_node = arg_node; + get_expected_token(Lbrace); + parse_HyperDoc(); + curr_node->type = Endarg; + hrt->data.node = arg_node; + curr_node = hrt; +} + +void +parse_newcond(void) +{ + char label[256]; + + get_expected_token(Lbrace); + get_expected_token(Unkeyword); + strcpy(label, token.id); + get_expected_token(Rbrace); + insert_cond(label, "0"); + curr_node->type = Noop; +} + +void +parse_setcond(void) +{ + char label[256], cond[256]; + + get_expected_token(Lbrace); + get_expected_token(Cond); + strcpy(label, token.id); + get_expected_token(Rbrace); + get_expected_token(Lbrace); + get_expected_token(Word); + strcpy(cond, token.id); + get_expected_token(Rbrace); + change_cond(label, cond); + curr_node->type = Noop; +} + +void +parse_begin_items(void) +{ + TextNode *bi = curr_node; + + /* + * This procedure parses a begin item. It sets the current + * node and sees if there is an optional argument for the itemspace + */ + + bi->type = token.type; + get_token(); + if (token.type == Lsquarebrace) { + bi->data.node = alloc_node(); + curr_node = bi->data.node; + gInOptional++; + parse_HyperDoc(); + gInOptional--; + curr_node->type = Enddescription; + if (token.type != Rsquarebrace) { + fprintf(stderr, "(HyperDoc) Optional arguments must end with ].\n"); + print_next_ten_tokens(); + print_page_and_filename(); + jump(); + } + curr_node = bi; + } + else + unget_token(); + gInItems++; +} + +void +parse_item(void) +{ + if (!gInItems) { + fprintf(stderr, "\\item found outside an items environment\n"); + print_page_and_filename(); + print_next_ten_tokens(); + jump(); + } + curr_node->type = Item; + get_token(); + if (token.type == Lsquarebrace) { + /* I should parse the optional argument */ + curr_node->next = alloc_node(); + curr_node = curr_node->next; + curr_node->type = Description; + curr_node->next = alloc_node(); + curr_node = curr_node->next; + gInOptional++; + parse_HyperDoc(); + gInOptional--; + curr_node->type = Enddescription; + if (token.type != Rsquarebrace) { + fprintf(stderr, "(HyperDoc) Optional arguments must end with ].\n"); + print_next_ten_tokens(); + print_page_and_filename(); + jump(); + } + } + else { + unget_token(); + } +} + +void +parse_mitem(void) +{ + if (!gInItems) { + fprintf(stderr, "\\mitem found outside an items environment\n"); + print_page_and_filename(); + print_next_ten_tokens(); + jump(); + } + curr_node->type = Mitem; +} + +char *vbuf = NULL; +int vbuf_size = 0; + +#define VbufSlop 10 +#define resizeVbuf()\ + if (size == vbuf_size) { \ + vbuf = resizeBuffer(size + VbufSlop, vbuf, &vbuf_size); \ + vb = vbuf + size; \ + } + +#define new_verb_node() \ + resizeVbuf(); \ + *vb = '\0'; \ + curr_node->data.text = alloc_string(vbuf); \ + curr_node->next = alloc_node(); \ + curr_node = curr_node->next; \ + curr_node->type = Newline; \ + curr_node->next = alloc_node(); \ + curr_node = curr_node->next; \ + curr_node->type = type; \ + if (*end_string == '\n') es = end_string+1; \ + else es = end_string; \ + size = 0; \ + vb = vbuf; + +void +parse_verbatim(int type) +{ + int size = 0, c; + char *end_string, *vb = vbuf, *es; + + curr_node->type = type; + if (token.id[-1]) + curr_node->space = 1; + if (type == Spadsrctxt) { + es = end_string = "\n\\end{spadsrc}"; + } + else if (type == Math) + es = end_string = "$"; + else + es = end_string = "\\end{verbatim}"; + while ((c = get_char()) != EOF) { + resizeVbuf(); + size++; + if (c == '\n') { + new_verb_node(); + continue; + } + *vb++ = c; + if (*es++ != c) + es = end_string; + if (!*es) + break; + } + if (c == EOF) { + fprintf(stderr, "parse_verbatim: Unexpected EOF found\n"); + longjmp(jmpbuf, 1); + } + resizeVbuf(); + if (*end_string == '\n') + es = end_string + 1; + else + es = end_string; + vbuf[size - strlen(es)] = '\0'; + if (*vbuf) { + curr_node->data.text = alloc_string(vbuf); + curr_node->next = alloc_node(); + curr_node = curr_node->next; + } + if (type == Spadsrctxt) + curr_node->type = Endspadsrc; + else if (type == Math) + curr_node->type = Endmath; + else + curr_node->type = Endverbatim; +} + +void +parse_input_pix(void) +{ + TextNode *pixnode; + char *filename; + + pixnode = curr_node; + pixnode->type = token.type; + pixnode->space = token.id[-1]; + pixnode->width = -1; + get_expected_token(Lbrace); + filename = get_input_string(); + pixnode->data.text = alloc_string(filename); + curr_node = pixnode; + if (pixnode->type == Inputimage) { + char f[256]; + char *p; + + if ((gXDisplay && DisplayPlanes(gXDisplay, gXScreenNumber) == 1) || gSwitch_to_mono ==1) { + pixnode->type = Inputbitmap; + strcpy(f, pixnode->data.text); + strcat(f, ".bm"); + p=pixnode->data.text; + pixnode->data.text = alloc_string(f); + free(p); + } + else { + pixnode->type = Inputpixmap; + strcpy(f, pixnode->data.text); +#ifdef OLD + strcat(f, ".pm"); +#endif + strcat(f, ".xpm.Z"); + p=pixnode->data.text; + pixnode->data.text = alloc_string(f); + free(p); + } + } +} + +void +parse_centerline(void) +{ + curr_node->type = token.type; + curr_node->space = token.id[-1]; + curr_node->width = -1; + curr_node->next = alloc_node(); + curr_node = curr_node->next; + get_expected_token(Lbrace); + parse_HyperDoc(); + if (token.type != Rbrace) { + curr_node->type = Noop; + fprintf(stderr, "(HyperdDoc) \\centerline was expecting a }\n"); + print_page_and_filename(); + print_next_ten_tokens(); + longjmp(jmpbuf, 1); + } + curr_node->type = Endcenter; +} + +void +parse_command(void) +{ + TextNode *link_node, *save_node, *arg_node; + + gInButton++; + if (gParserMode == SimpleMode) { + curr_node->type = Noop; + fprintf(stderr, "Parser Error token %s unexpected\n", + token_table[token.type]); + longjmp(jmpbuf, 1); + } + gStringValueOk = 1; + + /* set the values for the current node */ + curr_node->type = token.type; + curr_node->space = token.id[-1]; + + /* now parse for the label */ + link_node = curr_node; + curr_node->next = alloc_node(); + curr_node = curr_node->next; + get_expected_token(Lbrace); + parse_HyperDoc(); + curr_node->type = Endbutton; + save_node = curr_node; + arg_node = alloc_node(); + curr_node = arg_node; + get_expected_token(Lbrace); + parse_HyperDoc(); + curr_node->type = Endarg; + link_node->link = make_link_window(arg_node, link_node->type, 0); + gStringValueOk = 0; + curr_node = save_node; + gInButton--; +} + +void +parse_button(void) +{ + TextNode *link_node, *save_node; + + gInButton++; + if (gParserMode == SimpleMode) { + curr_node->type = Noop; + fprintf(stderr, "Parser Error token %s unexpected\n", + token_table[token.type]); + longjmp(jmpbuf, 1); + } + /* fill the node */ + curr_node->type = token.type; + curr_node->space = token.id[-1]; + + /* the save the current node for creating the link and stuff */ + link_node = curr_node; + + /* then parse the label */ + curr_node->next = alloc_node(); + curr_node = curr_node->next; + get_expected_token(Lbrace); + parse_HyperDoc(); + curr_node->type = Endbutton; + + /* now try to get the argument node */ + save_node = curr_node; + get_expected_token(Lbrace); + save_node->data.node = alloc_node(); + curr_node = save_node->data.node; + parse_HyperDoc(); + curr_node->type = Endarg; + + /* + * buffer[0] = '\0'; print_to_string(arg_node, buffer + 1); + */ + link_node->link = + make_link_window(save_node->data.node, link_node->type, 0); + curr_node = save_node; + gInButton--; +} + +extern int example_number; + +void +parse_spadcommand(TextNode *spad_node) +{ + /*TextNode *node = NULL;*/ + + example_number++; + gInButton++; + spad_node->type = token.type; + spad_node->space = token.id[-1]; + get_expected_token(Lbrace); + cur_spadcom = curr_node; + + spad_node->next = alloc_node(); + curr_node = spad_node->next; + parse_HyperDoc(); + curr_node->type = Endspadcommand; + cur_spadcom = NULL; + spad_node->link = make_link_window(spad_node->next, spad_node->type, 1); + gInButton--; +} + +void +parse_spadsrc(TextNode *spad_node) +{ + char buf[512], *c = buf; + int ch, start_opts = 0; + /*TextNode *node = NULL;*/ + + example_number++; + gInButton++; + gInSpadsrc++; + spad_node->type = Spadsrc; + spad_node->space = token.id[-1]; + + cur_spadcom = curr_node; + spad_node->next = alloc_node(); + curr_node = spad_node->next; + + do { + ch = get_char(); + if (ch == ']') + start_opts = 0; + if (start_opts) + *c++ = ch; + if (ch == '[') + start_opts = 1; + } while (ch != '\n'); + *c = '\0'; + parse_verbatim(Spadsrctxt); + parse_from_string(buf); + + curr_node->type = Endspadsrc; + cur_spadcom = NULL; + spad_node->link = make_link_window(spad_node->next, Spadsrc, 1); + gInButton--; + gInSpadsrc--; +} + +void +parse_env(TextNode *node) +{ + char *env; + char buff[256]; + char *buff_pntr = &buff[1]; + int noEnv = 0; + + get_expected_token(Lbrace); + get_expected_token(Word); + env = getenv(token.id); + + if (env == NULL) { + /** The environment variable was not found **/ + + fprintf(stderr, "(HyperDoc) Warning: environment variable \'%s\' was not found.\n", + token.id); + + env = halloc(1, "string"); + env[0] = '\0'; + noEnv = 1; + } + + buff[0] = token.id[-1]; + strcpy(buff_pntr, env); + + if (noEnv) + free(env); + + node->data.text = alloc_string(buff_pntr); + node->type = Word; + + get_expected_token(Rbrace); +} + +/* + * This parse_value routine accepts an empty {} but makes it a zero instead + * of a one. Thus \indent{} is equivelant to \indent{0} + */ + +void +parse_value1(void) +{ + TextNode *value_node, *ocn = curr_node; + char *s; + + curr_node->type = token.type; + curr_node->space = token.id[-1]; + + value_node = alloc_node(); + value_node->type = Word; + curr_node->data.node = value_node; + get_expected_token(Lbrace); + s = get_input_string(); + if (!is_number(s)) { + fprintf(stderr, + "Parser Error: parse for value was expecting a numeric value\n"); + strcpy(value_node->data.text, "0"); + } + else { + value_node->data.text = alloc_string(s); + } + curr_node = ocn; +} + +/* + * This command accepts an empty argument command. Thus \space{} is + * equivelant \space{1} + */ + +void +parse_value2(void) +{ + TextNode *value_node, *ocn = curr_node; + char *s; + + curr_node->type = token.type; + curr_node->space = token.id[-1]; + + value_node = alloc_node(); + value_node->type = Word; + curr_node->data.node = value_node; + get_expected_token(Lbrace); + s = get_input_string(); + if (!is_number(s)) { + fprintf(stderr, + "Parser Error: parse for value was expecting a numeric value\n"); + strcpy(value_node->data.text, "1"); + } + else { + value_node->data.text = alloc_string(s); + } + curr_node = ocn; +} + + +/* parse a \table sommand */ + +void +parse_table(void) +{ + TextNode *tn = curr_node; + + if (gParserMode != AllMode) { + curr_node->type = Noop; + fprintf(stderr, "Parser Error token %s unexpected\n", + token_table[token.type]); + longjmp(jmpbuf, 1); + } + curr_node->type = Table; + get_expected_token(Lbrace); + curr_node->next = alloc_node(); + curr_node = curr_node->next; + + get_token(); + if (token.type == Lbrace) { + while (token.type != Rbrace) { + curr_node->type = Tableitem; + curr_node->next = alloc_node(); + curr_node = curr_node->next; + parse_HyperDoc(); + curr_node->type = Endtableitem; + curr_node->next = alloc_node(); + curr_node = curr_node->next; + get_token(); + } + curr_node->type = Endtable; + } + else { /* a patch for SG for empty tables */ + if (token.type != Rbrace) { + token_name(token.type); + fprintf(stderr, + "Unexpected Token %s found while parsing a table\n", + ebuffer); + print_page_and_filename(); + jump(); + } + tn->type = Noop; + tn->next = NULL; + free(curr_node); + curr_node = tn; + } +} + +void +parse_box(void) +{ + curr_node->type = token.type; + curr_node->space = token.id[-1]; + curr_node->width = -1; + curr_node->next = alloc_node(); + curr_node = curr_node->next; + get_expected_token(Lbrace); + parse_HyperDoc(); + curr_node->type = Endbox; +} + +void +parse_mbox(void) +{ + curr_node->type = token.type; + curr_node->space = token.id[-1]; + curr_node->width = -1; + curr_node->next = alloc_node(); + curr_node = curr_node->next; + get_expected_token(Lbrace); + parse_HyperDoc(); + curr_node->type = Endbox; +} + +void +parse_free(void) +{ + TextNode *free_node = curr_node; + + curr_node->type = token.type; + curr_node->space = token.id[-1]; + curr_node->width = -1; + curr_node->data.node = alloc_node(); + curr_node = curr_node->data.node; + get_expected_token(Lbrace); + parse_HyperDoc(); + curr_node->type = Endarg; + curr_node = free_node; +} + +void +parse_help(void) +{ + curr_node->type = Noop; + get_token(); + if (token.type != Lbrace) { + token_name(token.type); + fprintf(stderr, "\\helppage was expecting a { and not a %s\n", ebuffer); + print_page_and_filename(); + jump(); + } + +/* before we clobber this pointer we better free the contents (cf. alloc_page) */ + free(gPageBeingParsed->helppage); + gPageBeingParsed->helppage = alloc_string(get_input_string()); + + if (token.type != Rbrace) { + token_name(token.type); + fprintf(stderr, "\\helppage was expecting a } and not a %s\n", + ebuffer); + print_page_and_filename(); + jump(); + } +} diff --git a/src/hyper/parse-types.h b/src/hyper/parse-types.h new file mode 100644 index 00000000..c5bd3802 --- /dev/null +++ b/src/hyper/parse-types.h @@ -0,0 +1,47 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +#ifndef _PARSE_TYPES_H_ +#define _PARSE_TYPES_H_ 1 + +#include "hyper.h" + +extern boolean gInButton; +extern boolean gInIf; +extern boolean gInItems; +extern boolean gInOptional; + + +#endif diff --git a/src/hyper/parse-types.pamphlet b/src/hyper/parse-types.pamphlet deleted file mode 100644 index 8f3902ce..00000000 --- a/src/hyper/parse-types.pamphlet +++ /dev/null @@ -1,821 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/parse-types} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{parse-types.h} -<>= -<> -#ifndef _PARSE_TYPES_H_ -#define _PARSE_TYPES_H_ 1 - -#include "hyper.h" - -extern boolean gInButton; -extern boolean gInIf; -extern boolean gInItems; -extern boolean gInOptional; - - -#endif -@ -\section{parse-types.c} -<>= -/****************************************************************************** - * - * parse-types.h: HyperDoc parsing routines for node types. - * - * Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993. - * - ****************************************************************************/ -#define _PARSE_TYPES_C -#include "axiom-c-macros.h" -#include "useproto.h" -#include "debug.h" - -#include "parse.h" -#include "parse-aux.h" -#include "parse-types.h" -#include "cond.h" -#include "lex.h" -#include "mem.h" -#include "extent.h" -#include "hterror.h" - -#include "all_hyper_proto.H1" - -boolean gInButton = FALSE; -boolean gInIf = FALSE; -boolean gInItems = FALSE; -boolean gInOptional = FALSE; - -void -parse_ifcond(void) -{ - TextNode *ifnode = curr_node; - TextNode *endif; - TextNode *condnode; - - /* - * parse a conditional. At first I am just going to parse if - * fi - */ - if (gInIf) { - curr_node->type = Noop; - fprintf(stderr, "\\if found within \\if \n"); - longjmp(jmpbuf, 1); - fprintf(stderr, "Longjump failed, Exiting\n"); - exit(-1); - } - gInIf++; - curr_node->type = Ifcond; - curr_node->space = token.id[-1]; - curr_node->data.ifnode = alloc_ifnode(); - /* Now get the cond node I hope */ - - condnode = curr_node->data.ifnode->cond = alloc_node(); - curr_node = condnode; - parse_condnode(); - - endif = alloc_node(); - endif->type = Endif; - ifnode->data.ifnode->thennode = alloc_node(); - curr_node = ifnode->data.ifnode->thennode; - parse_HyperDoc(); - if (token.type == Fi) { - curr_node->type = Fi; - curr_node->next = endif; - ifnode->data.ifnode->elsenode = endif; - } - else if (token.type == Else) { - /* first finish up the then part */ - curr_node->type = Fi; - curr_node->next = endif; - /* the go and parse the else part */ - ifnode->data.ifnode->elsenode = alloc_node(); - curr_node = ifnode->data.ifnode->elsenode; - parse_HyperDoc(); - if (token.type != Fi) { - token_name(token.type); - curr_node->type = Noop; - fprintf(stderr, "Expected a \\fi not a %s", ebuffer); - longjmp(jmpbuf, 1); - fprintf(stderr, "Longjump failed, Exiting\n"); - exit(-1); - } - curr_node->type = Fi; - curr_node->next = endif; - } - else { - curr_node->type = Noop; - token_name(token.type); - fprintf(stderr, "Expected a \\fi not a %s", ebuffer); - longjmp(jmpbuf, 1); - fprintf(stderr, "Longjump failed, Exiting\n"); - exit(-1); - } - ifnode->next = ifnode->data.ifnode->thennode; - ifnode->width = -1; /* A flag for compute if extents */ - curr_node = endif; - gInIf--; -} - -static void -parse_condnode(void) -{ - get_token(); - - switch (token.type) { - case Cond: - curr_node->type = Cond; - curr_node->data.text = alloc_string(token.id); - break; - case Haslisp: - case Hasreturn: - case Lastwindow: - case Hasup: - curr_node->type = token.type; - break; - case Boxcond: - curr_node->type = Boxcond; - curr_node->data.text = alloc_string(token.id); - break; - case Hasreturnto: - parse_hasreturnto(); - break; - default: - { - char eb[128]; - token_name(token.type); - sprintf(eb, "Unexpected Token %s\n", eb); - htperror(eb, HTCONDNODE); - } - break; - } -} - -static void -parse_hasreturnto(void) -{ - TextNode *hrt = curr_node, *arg_node = alloc_node(); - - curr_node->type = Hasreturnto; - curr_node = arg_node; - get_expected_token(Lbrace); - parse_HyperDoc(); - curr_node->type = Endarg; - hrt->data.node = arg_node; - curr_node = hrt; -} - -void -parse_newcond(void) -{ - char label[256]; - - get_expected_token(Lbrace); - get_expected_token(Unkeyword); - strcpy(label, token.id); - get_expected_token(Rbrace); - insert_cond(label, "0"); - curr_node->type = Noop; -} - -void -parse_setcond(void) -{ - char label[256], cond[256]; - - get_expected_token(Lbrace); - get_expected_token(Cond); - strcpy(label, token.id); - get_expected_token(Rbrace); - get_expected_token(Lbrace); - get_expected_token(Word); - strcpy(cond, token.id); - get_expected_token(Rbrace); - change_cond(label, cond); - curr_node->type = Noop; -} - -void -parse_begin_items(void) -{ - TextNode *bi = curr_node; - - /* - * This procedure parses a begin item. It sets the current - * node and sees if there is an optional argument for the itemspace - */ - - bi->type = token.type; - get_token(); - if (token.type == Lsquarebrace) { - bi->data.node = alloc_node(); - curr_node = bi->data.node; - gInOptional++; - parse_HyperDoc(); - gInOptional--; - curr_node->type = Enddescription; - if (token.type != Rsquarebrace) { - fprintf(stderr, "(HyperDoc) Optional arguments must end with ].\n"); - print_next_ten_tokens(); - print_page_and_filename(); - jump(); - } - curr_node = bi; - } - else - unget_token(); - gInItems++; -} - -void -parse_item(void) -{ - if (!gInItems) { - fprintf(stderr, "\\item found outside an items environment\n"); - print_page_and_filename(); - print_next_ten_tokens(); - jump(); - } - curr_node->type = Item; - get_token(); - if (token.type == Lsquarebrace) { - /* I should parse the optional argument */ - curr_node->next = alloc_node(); - curr_node = curr_node->next; - curr_node->type = Description; - curr_node->next = alloc_node(); - curr_node = curr_node->next; - gInOptional++; - parse_HyperDoc(); - gInOptional--; - curr_node->type = Enddescription; - if (token.type != Rsquarebrace) { - fprintf(stderr, "(HyperDoc) Optional arguments must end with ].\n"); - print_next_ten_tokens(); - print_page_and_filename(); - jump(); - } - } - else { - unget_token(); - } -} - -void -parse_mitem(void) -{ - if (!gInItems) { - fprintf(stderr, "\\mitem found outside an items environment\n"); - print_page_and_filename(); - print_next_ten_tokens(); - jump(); - } - curr_node->type = Mitem; -} - -char *vbuf = NULL; -int vbuf_size = 0; - -#define VbufSlop 10 -#define resizeVbuf()\ - if (size == vbuf_size) { \ - vbuf = resizeBuffer(size + VbufSlop, vbuf, &vbuf_size); \ - vb = vbuf + size; \ - } - -#define new_verb_node() \ - resizeVbuf(); \ - *vb = '\0'; \ - curr_node->data.text = alloc_string(vbuf); \ - curr_node->next = alloc_node(); \ - curr_node = curr_node->next; \ - curr_node->type = Newline; \ - curr_node->next = alloc_node(); \ - curr_node = curr_node->next; \ - curr_node->type = type; \ - if (*end_string == '\n') es = end_string+1; \ - else es = end_string; \ - size = 0; \ - vb = vbuf; - -void -parse_verbatim(int type) -{ - int size = 0, c; - char *end_string, *vb = vbuf, *es; - - curr_node->type = type; - if (token.id[-1]) - curr_node->space = 1; - if (type == Spadsrctxt) { - es = end_string = "\n\\end{spadsrc}"; - } - else if (type == Math) - es = end_string = "$"; - else - es = end_string = "\\end{verbatim}"; - while ((c = get_char()) != EOF) { - resizeVbuf(); - size++; - if (c == '\n') { - new_verb_node(); - continue; - } - *vb++ = c; - if (*es++ != c) - es = end_string; - if (!*es) - break; - } - if (c == EOF) { - fprintf(stderr, "parse_verbatim: Unexpected EOF found\n"); - longjmp(jmpbuf, 1); - } - resizeVbuf(); - if (*end_string == '\n') - es = end_string + 1; - else - es = end_string; - vbuf[size - strlen(es)] = '\0'; - if (*vbuf) { - curr_node->data.text = alloc_string(vbuf); - curr_node->next = alloc_node(); - curr_node = curr_node->next; - } - if (type == Spadsrctxt) - curr_node->type = Endspadsrc; - else if (type == Math) - curr_node->type = Endmath; - else - curr_node->type = Endverbatim; -} - -void -parse_input_pix(void) -{ - TextNode *pixnode; - char *filename; - - pixnode = curr_node; - pixnode->type = token.type; - pixnode->space = token.id[-1]; - pixnode->width = -1; - get_expected_token(Lbrace); - filename = get_input_string(); - pixnode->data.text = alloc_string(filename); - curr_node = pixnode; - if (pixnode->type == Inputimage) { - char f[256]; - char *p; - - if ((gXDisplay && DisplayPlanes(gXDisplay, gXScreenNumber) == 1) || gSwitch_to_mono ==1) { - pixnode->type = Inputbitmap; - strcpy(f, pixnode->data.text); - strcat(f, ".bm"); - p=pixnode->data.text; - pixnode->data.text = alloc_string(f); - free(p); - } - else { - pixnode->type = Inputpixmap; - strcpy(f, pixnode->data.text); -#ifdef OLD - strcat(f, ".pm"); -#endif - strcat(f, ".xpm.Z"); - p=pixnode->data.text; - pixnode->data.text = alloc_string(f); - free(p); - } - } -} - -void -parse_centerline(void) -{ - curr_node->type = token.type; - curr_node->space = token.id[-1]; - curr_node->width = -1; - curr_node->next = alloc_node(); - curr_node = curr_node->next; - get_expected_token(Lbrace); - parse_HyperDoc(); - if (token.type != Rbrace) { - curr_node->type = Noop; - fprintf(stderr, "(HyperdDoc) \\centerline was expecting a }\n"); - print_page_and_filename(); - print_next_ten_tokens(); - longjmp(jmpbuf, 1); - } - curr_node->type = Endcenter; -} - -void -parse_command(void) -{ - TextNode *link_node, *save_node, *arg_node; - - gInButton++; - if (gParserMode == SimpleMode) { - curr_node->type = Noop; - fprintf(stderr, "Parser Error token %s unexpected\n", - token_table[token.type]); - longjmp(jmpbuf, 1); - } - gStringValueOk = 1; - - /* set the values for the current node */ - curr_node->type = token.type; - curr_node->space = token.id[-1]; - - /* now parse for the label */ - link_node = curr_node; - curr_node->next = alloc_node(); - curr_node = curr_node->next; - get_expected_token(Lbrace); - parse_HyperDoc(); - curr_node->type = Endbutton; - save_node = curr_node; - arg_node = alloc_node(); - curr_node = arg_node; - get_expected_token(Lbrace); - parse_HyperDoc(); - curr_node->type = Endarg; - link_node->link = make_link_window(arg_node, link_node->type, 0); - gStringValueOk = 0; - curr_node = save_node; - gInButton--; -} - -void -parse_button(void) -{ - TextNode *link_node, *save_node; - - gInButton++; - if (gParserMode == SimpleMode) { - curr_node->type = Noop; - fprintf(stderr, "Parser Error token %s unexpected\n", - token_table[token.type]); - longjmp(jmpbuf, 1); - } - /* fill the node */ - curr_node->type = token.type; - curr_node->space = token.id[-1]; - - /* the save the current node for creating the link and stuff */ - link_node = curr_node; - - /* then parse the label */ - curr_node->next = alloc_node(); - curr_node = curr_node->next; - get_expected_token(Lbrace); - parse_HyperDoc(); - curr_node->type = Endbutton; - - /* now try to get the argument node */ - save_node = curr_node; - get_expected_token(Lbrace); - save_node->data.node = alloc_node(); - curr_node = save_node->data.node; - parse_HyperDoc(); - curr_node->type = Endarg; - - /* - * buffer[0] = '\0'; print_to_string(arg_node, buffer + 1); - */ - link_node->link = - make_link_window(save_node->data.node, link_node->type, 0); - curr_node = save_node; - gInButton--; -} - -extern int example_number; - -void -parse_spadcommand(TextNode *spad_node) -{ - /*TextNode *node = NULL;*/ - - example_number++; - gInButton++; - spad_node->type = token.type; - spad_node->space = token.id[-1]; - get_expected_token(Lbrace); - cur_spadcom = curr_node; - - spad_node->next = alloc_node(); - curr_node = spad_node->next; - parse_HyperDoc(); - curr_node->type = Endspadcommand; - cur_spadcom = NULL; - spad_node->link = make_link_window(spad_node->next, spad_node->type, 1); - gInButton--; -} - -void -parse_spadsrc(TextNode *spad_node) -{ - char buf[512], *c = buf; - int ch, start_opts = 0; - /*TextNode *node = NULL;*/ - - example_number++; - gInButton++; - gInSpadsrc++; - spad_node->type = Spadsrc; - spad_node->space = token.id[-1]; - - cur_spadcom = curr_node; - spad_node->next = alloc_node(); - curr_node = spad_node->next; - - do { - ch = get_char(); - if (ch == ']') - start_opts = 0; - if (start_opts) - *c++ = ch; - if (ch == '[') - start_opts = 1; - } while (ch != '\n'); - *c = '\0'; - parse_verbatim(Spadsrctxt); - parse_from_string(buf); - - curr_node->type = Endspadsrc; - cur_spadcom = NULL; - spad_node->link = make_link_window(spad_node->next, Spadsrc, 1); - gInButton--; - gInSpadsrc--; -} - -void -parse_env(TextNode *node) -{ - char *env; - char buff[256]; - char *buff_pntr = &buff[1]; - int noEnv = 0; - - get_expected_token(Lbrace); - get_expected_token(Word); - env = getenv(token.id); - - if (env == NULL) { - /** The environment variable was not found **/ - - fprintf(stderr, "(HyperDoc) Warning: environment variable \'%s\' was not found.\n", - token.id); - - env = halloc(1, "string"); - env[0] = '\0'; - noEnv = 1; - } - - buff[0] = token.id[-1]; - strcpy(buff_pntr, env); - - if (noEnv) - free(env); - - node->data.text = alloc_string(buff_pntr); - node->type = Word; - - get_expected_token(Rbrace); -} - -/* - * This parse_value routine accepts an empty {} but makes it a zero instead - * of a one. Thus \indent{} is equivelant to \indent{0} - */ - -void -parse_value1(void) -{ - TextNode *value_node, *ocn = curr_node; - char *s; - - curr_node->type = token.type; - curr_node->space = token.id[-1]; - - value_node = alloc_node(); - value_node->type = Word; - curr_node->data.node = value_node; - get_expected_token(Lbrace); - s = get_input_string(); - if (!is_number(s)) { - fprintf(stderr, - "Parser Error: parse for value was expecting a numeric value\n"); - strcpy(value_node->data.text, "0"); - } - else { - value_node->data.text = alloc_string(s); - } - curr_node = ocn; -} - -/* - * This command accepts an empty argument command. Thus \space{} is - * equivelant \space{1} - */ - -void -parse_value2(void) -{ - TextNode *value_node, *ocn = curr_node; - char *s; - - curr_node->type = token.type; - curr_node->space = token.id[-1]; - - value_node = alloc_node(); - value_node->type = Word; - curr_node->data.node = value_node; - get_expected_token(Lbrace); - s = get_input_string(); - if (!is_number(s)) { - fprintf(stderr, - "Parser Error: parse for value was expecting a numeric value\n"); - strcpy(value_node->data.text, "1"); - } - else { - value_node->data.text = alloc_string(s); - } - curr_node = ocn; -} - - -/* parse a \table sommand */ - -void -parse_table(void) -{ - TextNode *tn = curr_node; - - if (gParserMode != AllMode) { - curr_node->type = Noop; - fprintf(stderr, "Parser Error token %s unexpected\n", - token_table[token.type]); - longjmp(jmpbuf, 1); - } - curr_node->type = Table; - get_expected_token(Lbrace); - curr_node->next = alloc_node(); - curr_node = curr_node->next; - - get_token(); - if (token.type == Lbrace) { - while (token.type != Rbrace) { - curr_node->type = Tableitem; - curr_node->next = alloc_node(); - curr_node = curr_node->next; - parse_HyperDoc(); - curr_node->type = Endtableitem; - curr_node->next = alloc_node(); - curr_node = curr_node->next; - get_token(); - } - curr_node->type = Endtable; - } - else { /* a patch for SG for empty tables */ - if (token.type != Rbrace) { - token_name(token.type); - fprintf(stderr, - "Unexpected Token %s found while parsing a table\n", - ebuffer); - print_page_and_filename(); - jump(); - } - tn->type = Noop; - tn->next = NULL; - free(curr_node); - curr_node = tn; - } -} - -void -parse_box(void) -{ - curr_node->type = token.type; - curr_node->space = token.id[-1]; - curr_node->width = -1; - curr_node->next = alloc_node(); - curr_node = curr_node->next; - get_expected_token(Lbrace); - parse_HyperDoc(); - curr_node->type = Endbox; -} - -void -parse_mbox(void) -{ - curr_node->type = token.type; - curr_node->space = token.id[-1]; - curr_node->width = -1; - curr_node->next = alloc_node(); - curr_node = curr_node->next; - get_expected_token(Lbrace); - parse_HyperDoc(); - curr_node->type = Endbox; -} - -void -parse_free(void) -{ - TextNode *free_node = curr_node; - - curr_node->type = token.type; - curr_node->space = token.id[-1]; - curr_node->width = -1; - curr_node->data.node = alloc_node(); - curr_node = curr_node->data.node; - get_expected_token(Lbrace); - parse_HyperDoc(); - curr_node->type = Endarg; - curr_node = free_node; -} - -void -parse_help(void) -{ - curr_node->type = Noop; - get_token(); - if (token.type != Lbrace) { - token_name(token.type); - fprintf(stderr, "\\helppage was expecting a { and not a %s\n", ebuffer); - print_page_and_filename(); - jump(); - } - -/* before we clobber this pointer we better free the contents (cf. alloc_page) */ - free(gPageBeingParsed->helppage); - gPageBeingParsed->helppage = alloc_string(get_input_string()); - - if (token.type != Rbrace) { - token_name(token.type); - fprintf(stderr, "\\helppage was expecting a } and not a %s\n", - ebuffer); - print_page_and_filename(); - jump(); - } -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/parse.c b/src/hyper/parse.c new file mode 100644 index 00000000..92703cc6 --- /dev/null +++ b/src/hyper/parse.c @@ -0,0 +1,842 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +#define _PARSE_C +#include "useproto.h" +#include "debug.h" + +#include "parse.h" +#include "parse-paste.h" +#include "parse-types.h" +#include "lex.h" +#include "hyper.h" +#include "extent.h" +#include "event.h" +#include "display.h" +#include "group.h" +#include "scrollbar.h" +#include "titlebar.h" + +#include "all_hyper_proto.H1" + + + +TextNode *curr_node; /* current node being parsed. It is to be the + * next one filled */ +HashTable *gLinkHashTable; /* the hash table of active link windows */ +TextNode *cur_spadcom; /* The current AXIOM command */ + +short int gParserMode; /* Parser mode flag */ +short int gParserRegion; /* Parser Region flag scrolling etc */ +short int gStringValueOk; /* is a string or box value ok */ +boolean gEndedPage; + +extern int example_number; /* sequence example number */ + + +int ret_val; /* The return value from get_token */ + +HyperDocPage *cur_page; + +char *replace_page; /* true if dynamic page is link to static one */ + +/* + * These routines are used for storing an restoring the parser mode. When + * I start to parse from string, or from a macro, I need to restore the + * parser mode and region once done. These routines do that + * + */ + +typedef struct mr_stack { + /** The structure for storing parser mode and region **/ + short int fParserMode; + short int fParserRegion; + struct mr_stack *fNext; +} MR_Stack; + +MR_Stack *top_mr_stack = NULL; /** Declaration for the stack **/ + +static void +Push_MR(void) +{ + MR_Stack *newStackItem = (MR_Stack *) halloc(sizeof(MR_Stack), "Mode Region Stack"); + + newStackItem->fParserMode = gParserMode; + newStackItem->fParserRegion = gParserRegion; + newStackItem->fNext = top_mr_stack; + top_mr_stack = newStackItem; +} + +static void +Pop_MR(void) +{ + MR_Stack *old = top_mr_stack; + + if (old == NULL) { + fprintf(stderr, "(HyperDoc) Parser Error: Tried to pop empty MR Stack\n"); + exit(-1); + } + else { + gParserMode = old->fParserMode; + gParserRegion = old->fParserRegion; + top_mr_stack = old->fNext; + free(old); + } +} + +void +load_page(HyperDocPage *page) +{ + if (page->type == UnloadedPageType) { + HyperDocPage *new_page; + init_scanner(); + new_page = format_page((UnloadedPage *)page); + gWindow->page = new_page; + /* free(page); */ + page = new_page; + } +} + +HyperDocPage *formatpage; + +/* Display a HyperDoc page with the given name, parsing it if needed */ + +void +display_page(HyperDocPage *page) +{ + HyperDocPage *new_page; + + XUnmapSubwindows(gXDisplay, gWindow->fMainWindow); + XUnmapSubwindows(gXDisplay, gWindow->fScrollWindow); + XFlush(gXDisplay); + + if (setjmp(jmpbuf)) { + + /* + * since I did not finish formatting the page, let me get rid of what + * I had + */ + free_page(formatpage); + /* Replace the buggy page with what I started with */ + hash_replace(gWindow->fPageHashTable, (char *)page, formatpage->name); + if (!strcmp(formatpage->name, "ErrorPage")) { + fprintf(stderr, "(HyperDoc) Oops the error page is buggy\n"); + exit(-1); + } + gWindow->page = page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, "ErrorPage"); + if (page == NULL) { + fprintf(stderr, "(HyperDoc) No error page found, exiting\n"); + exit(-1); + } + reset_connection(); + } + if (page->type == UnloadedPageType || page->type == ErrorPage) { + /* Gack! (page should be a union!) */ + init_scanner(); + new_page = format_page((UnloadedPage *)page); + gWindow->page = new_page; + /* free(page); */ + page = new_page; + } + show_page(page); +} + + +/* Parse a given HyperDoc Page, from the top */ + +static HyperDocPage * +format_page(UnloadedPage *ulpage) +{ + /*int ret_val;*/ + HyperDocPage *page = alloc_page(ulpage->name); + + /* + * In case of an error I will have to get at this page so I can free the + * waisted memory + */ + formatpage = page; + page->type = Normal; + hash_replace(gWindow->fPageHashTable, (char *)page, ulpage->name); + + cfile = find_fp(ulpage->fpos); + + + page->filename = alloc_string(ulpage->fpos.name); + parse_page(page); + return page; +} + +/* parse the HyperDoc statements in the given string */ + +void +parse_from_string(char *str) +{ + save_scanner_state(); + last_ch = NoChar; + last_token = 0; + input_string = str; + input_type = FromString; + parse_HyperDoc(); + restore_scanner_state(); +} + +static void +parse_title(HyperDocPage *page) +{ + TextNode *node; + + Push_MR(); + gParserRegion = Title; + get_expected_token(Lbrace); + node = alloc_node(); + page->title = node; + node->type = Titlenode; + node->next = alloc_node(); + node = node->next; + node->type = Center; + node->next = alloc_node(); + curr_node = node->next; + parse_HyperDoc(); + curr_node->type = Endcenter; + curr_node->next = alloc_node(); + curr_node = curr_node->next; + curr_node->type = Endtitle; + curr_node->next = NULL; + if (gNeedIconName) { + char *title = print_to_string(page->title); + + XSetIconName(gXDisplay, gWindow->fMainWindow, title); + gNeedIconName = 0; + } + if (token.type != Rbrace) { + fprintf(stderr, "(HyperDoc) Parse title was expecting a closing brace\n"); + print_page_and_filename(); + jump(); + } + linkTitleBarWindows(); + Pop_MR(); +} + +static void +parse_header(HyperDocPage *page) +{ + TextNode *node; + + Push_MR(); + gParserRegion = Header; + node = alloc_node(); + page->header = node; + node->type = Headernode; + node->next = alloc_node(); + curr_node = node->next; + parse_HyperDoc(); +} + +/* + * parse a page from the top level + */ + +static void +init_parse_page(HyperDocPage *page) +{ + gEndedPage = gInDesc = gStringValueOk = gInIf = + gInButton = gInOptional = gInVerbatim = gInPaste = gInItems = + gInSpadsrc = FALSE; + example_number = 1; + cur_page = page; + gParserMode = AllMode; + /* Now I should set the input list to be null */ + free_input_list(page->input_list); + page->input_list = page->current_item = NULL; + + init_top_group(); + clear_be_stack(); + + cur_spadcom = NULL; + gLinkHashTable = page->fLinkHashTable; + hash_init( + gLinkHashTable, + LinkHashSize, + (EqualFunction) window_equal, + (HashcodeFunction) window_code); + gPageBeingParsed = page; + +} + +void +init_parse_patch(HyperDocPage *page) +{ + gEndedPage = gInDesc = gStringValueOk = gInIf = + gInButton = gInOptional = gInVerbatim = gInPaste = gInItems = + gInSpadsrc = FALSE; + gParserMode = AllMode; + gParserRegion = Scrolling; + + init_top_group(); + clear_be_stack(); + + cur_spadcom = NULL; + gLinkHashTable = page->fLinkHashTable; + gPageBeingParsed = page; +} + +#define end_page(t) ((t == Page || t == NewCommand ||t == Endpage)?1:0) + +static void +parse_page(HyperDocPage *page) +{ + init_parse_page(page); + + /* Get the name of the page */ + + get_expected_token(Page); + get_expected_token(Lbrace); + get_expected_token(Word); + if (page->name == NULL) + page->name = alloc_string(token.id); + get_expected_token(Rbrace); + /* parse the title */ + gWindow->fDisplayedWindow = gWindow->fMainWindow; + parse_title(page); + + /* + * Now start parsing the header region + */ + parse_header(page); +} + +char *ExpectedBeginScroll = +"Parser Error: Unexpected new page, expecting a begin scroll\n", *ExpectedEndScroll = +"Parser Error: Unexpected new page, expected an end scroll\n"; + +/* + * The general HyperDoc parsing function. expects to see anything. This + * function will parse until it sees either: 1) A new page starting 2) An end + * of file 3) a closing bracket "}" + */ + +void +parse_HyperDoc(void) +{ + TextNode *node = NULL /*, *save_node = NULL, *arg_node = NULL*/ ; + + for(;;) { + ret_val = get_token(); + + if (ret_val == EOF) + return; + + switch (token.type) { + case Spadsrc: + parse_spadsrc(curr_node); + break; + case Helppage: + parse_help(); + break; + case Endpatch: + case Endpaste: + case Rbrace: + return; + case Paste: + parse_paste(); + break; + case Pastebutton: + parse_pastebutton(); + break; + case Endpage: + case NewCommand: + case Page: + end_a_page(); + return; + case EndScroll: + token.type = Endscroll; + case Endscroll: + start_footer(); + break; + case Beginscroll: + start_scrolling(); + break; + case Thispage: /* it really is just a word */ + curr_node->type = Word; + curr_node->data.text = alloc_string(gPageBeingParsed->name); + break; + case Icorrection: + node->type = Noop; + break; + case Newcond: + parse_newcond(); + break; + case Setcond: + parse_setcond(); + break; + case Dollar: + parse_verbatim(Math); + break; + case Verbatim: + parse_verbatim(Verbatim); + break; + case Ifcond: + parse_ifcond(); + break; + case Fi: + if (gInIf) + return; + else { + curr_node->type = Noop; + /* Oops I had a problem parsing this puppy */ + fprintf(stderr, "(HyperDoc) \\fi found without macthing if?\n"); + longjmp(jmpbuf, 1); + fprintf(stderr, "(HyperDoc) Longjmp failed -- Exiting \n"); + exit(-1); + } + case Else: + if (gInIf) + return; + else { + /* Oops I had a problem parsing this puppy */ + curr_node->type = Noop; + fprintf(stderr, "(HyperDoc) \\else found without macthing if?\n"); + longjmp(jmpbuf, 1); + fprintf(stderr, "(HyperDoc) Longjmp failed -- Exiting \n"); + exit(-1); + } + case Macro: + parse_macro(); + break; + case Env: + /** In this case, get the environment value, and make it a word **/ + parse_env(curr_node); + break; + case WindowId: + curr_node->type = WindowId; + curr_node->space = token.id[-1]; + curr_node->data.text = window_id(gWindow->fMainWindow); + break; + case Punctuation: + case Word: + case Lsquarebrace: + case Dash: + curr_node->type = token.type; + curr_node->space = token.id[-1]; + curr_node->data.text = alloc_string(token.id); + break; + case Pagename: + { + char *str; + + curr_node->type = Word; + curr_node->space = 0; + str = halloc(strlen(cur_page->name) + 1, "parse"); + sprintf(str, "%s", cur_page->name); + curr_node->data.text = alloc_string(str); + break; + } + case Examplenumber: + { + char *str; + + curr_node->type = Word; + curr_node->space = 0; + str = halloc(5, "parse"); + sprintf(str, "%d", example_number); + curr_node->data.text = alloc_string(str); + break; + } + case Rsquarebrace: + if (gInOptional) + return; + else { + curr_node->type = token.type; + curr_node->space = token.id[-1]; + curr_node->data.text = alloc_string(token.id); + } + break; + case EndTitems: + token.type = Endtitems; + case Endtitems: + if (gParserMode != AllMode) { + curr_node->type = Noop; + fprintf(stderr, "(HyperDoc) Found a bad token %s\n", token_table[token.type]); + longjmp(jmpbuf, 1); + } + else { + curr_node->type = token.type; + break; + } + case EndItems: + token.type = Enditems; + case Enditems: + gInItems--; + case Horizontalline: + case Par: + case Newline: + case Titem: + if (gParserMode != AllMode) { + curr_node->type = Noop; + fprintf(stderr, "(HyperDoc) Found a bad token %s\n", token_table[token.type]); + longjmp(jmpbuf, 1); + } + else { + curr_node->type = token.type; + break; + } + case Begintitems: + case Beginitems: + if (gParserMode != AllMode) { + curr_node->type = Noop; + fprintf(stderr, "(HyperDoc) Found a bad token %s\n", token_table[token.type]); + longjmp(jmpbuf, 1); + } + else { + parse_begin_items(); + break; + } + case Item: + parse_item(); + break; + case Mitem: + parse_mitem(); + break; + case VSpace: + case Tab: + case HSpace: + case Indent: + case Indentrel: + parse_value1(); + break; + case Space: + parse_value2(); + break; + case Lbrace: + curr_node->type = Group; + curr_node->space = token.id[-1]; + push_group_stack(); + node = alloc_node(); + curr_node->next = node; + curr_node = curr_node->next; + parse_HyperDoc(); + curr_node->type = Endgroup; + pop_group_stack(); + break; + case Upbutton: + case Returnbutton: + case Link: + case Downlink: + case Memolink: + case Windowlink: + parse_button(); + break; + case Unixlink: + case LispMemoLink: + case LispDownLink: + case Lisplink: + case Lispcommand: + case Lispcommandquit: + case Spadlink: + case Spaddownlink: + case Spadmemolink: + case Unixcommand: + case Spadcall: + case Spadcallquit: + case Qspadcall: + case Qspadcallquit: + case Lispwindowlink: + parse_command(); + break; + case Controlbitmap: + case Inputbitmap: + case Inputpixmap: + case Inputimage: + parse_input_pix(); + break; + case Box: + parse_box(); + break; + case Mbox: + parse_mbox(); + break; + case Free: + parse_free(); + break; + case Center: + parse_centerline(); + break; + case Bound: + add_dependencies(); + break; + case Spadcommand: + case Spadgraph: + parse_spadcommand(curr_node); + break; + case Table: + parse_table(); + break; + case Beep: + case Emphasize: + case BoldFace: + case Rm: + case It: + case Tt: + case Sl: + curr_node->type = token.type; + curr_node->space = token.id[-1]; + break; + case Inputstring: + parse_inputstring(); + break; + case SimpleBox: + parse_simplebox(); + break; + case BoxValue: + case StringValue: + if (!gStringValueOk) { + strcpy(ebuffer,"(HyperDoc): Unexpected Value Command:"); + strcat(ebuffer, token.id); + + parser_error(ebuffer); + curr_node->type = Noop; + longjmp(jmpbuf, 1); + } + curr_node->type = token.type; + curr_node->space = token.id[-1]; + get_expected_token(Lbrace); + get_expected_token(Word); + curr_node->data.text = alloc_string(token.id); + get_expected_token(Rbrace); + break; + case NoLines: + gPageBeingParsed->page_flags |= NOLINES; + break; + case Pound: + curr_node->type = Pound; + curr_node->space = token.id[-1]; + curr_node->next = alloc_node(); + curr_node = curr_node->next; + parse_parameters(); + break; + case Radiobox: + parse_radiobox(); + break; + case Radioboxes: + parse_radioboxes(); + break; + case Replacepage: + parse_replacepage(); + break; + default: + fprintf(stderr, "(HyperDoc) Keyword not currently supported: %s\n", token.id); + print_page_and_filename(); + curr_node->type = Noop; + break; + } + if (gEndedPage) + return; + if (curr_node->type != Noop) { + node = alloc_node(); + curr_node->next = node; + curr_node = node; + } + } +} + + +/* parse a page from a socket source */ + +HyperDocPage * +parse_page_from_socket(void) +{ + HyperDocPage *page = alloc_page((char *) NULL); + HyperDocPage *hpage; + + init_scanner(); + input_type = FromSpadSocket; + input_string = ""; + cur_spadcom = NULL; + gLinkHashTable = page->fLinkHashTable; + hash_init( + gLinkHashTable, + LinkHashSize, + (EqualFunction) window_equal, + (HashcodeFunction) window_code); + gPageBeingParsed = page; + replace_page = NULL; + if (setjmp(jmpbuf)) { + /* Ooops, somewhere I had an error */ + free_page(page); + page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, "ErrorPage"); + reset_connection(); + } + else { + parse_page(page); + page->type = SpadGen; + page->filename = NULL; + /* just for kicks, let me add this thing to the hash file */ + hpage = (HyperDocPage *) hash_find(gWindow->fPageHashTable, page->name); + if (hpage) + hash_replace(gWindow->fPageHashTable, (char *)page, page->name); + else { + hash_insert(gWindow->fPageHashTable, (char *)page, page->name); + } + } + if (replace_page != NULL) { + free_page(page); + page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, replace_page); + if (page == NULL) + fprintf(stderr, "(HyperDoc) Unknown page: %s\n", replace_page); + } + return page; +} + +HyperDocPage * +parse_page_from_unixfd(void) +{ + HyperDocPage *page = alloc_page((char *) NULL); + + init_scanner(); + input_type = FromUnixFD; + cur_spadcom = NULL; + gLinkHashTable = page->fLinkHashTable; + hash_init( + gLinkHashTable, + LinkHashSize, + (EqualFunction) window_equal, + (HashcodeFunction) window_code); + gPageBeingParsed = page; + if (setjmp(jmpbuf)) { + /* Ooops, somewhere I had an error */ + free_page(page); + page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, "ErrorPage"); + reset_connection(); + } + else { + parse_page(page); + page->type = Unixfd; + page->filename = NULL; + } + return page; + +} + +static void +start_scrolling(void) +{ + + /* + * if I am here than I had a begin scroll. This means I should end the + * header, and then start parsing the footer + */ + + if (gParserRegion != Header) { + curr_node->type = Noop; + fprintf(stderr, "(HyperDoc) Parser Error: Unexpected BeginScrollFound\n"); + longjmp(jmpbuf, 1); + fprintf(stderr, "(HyperDoc) Longjump failed exiting\n"); + } + curr_node->type = Endheader; + curr_node->next = NULL; + Pop_MR(); + + Push_MR(); + gParserRegion = Scrolling; + gWindow->fDisplayedWindow = gWindow->fScrollWindow; + curr_node = alloc_node(); + gPageBeingParsed->scrolling = curr_node; + curr_node->type = Scrollingnode; +} + +static void +start_footer(void) +{ + /* + * This ends the parsing of the scrolling region, and then starts to + * parse the footer + */ + + if (gParserRegion != Scrolling) { + curr_node->type = Noop; + fprintf(stderr, "(HyperDoc) Parser Error: Unexpected Endscroll Found\n"); + print_page_and_filename(); + longjmp(jmpbuf, 1); + fprintf(stderr, "(HyperDoc) Longjump failed exiting\n"); + } + + curr_node->type = Endscrolling; + curr_node->next = NULL; + Pop_MR(); + linkScrollBars(); + + Push_MR(); + gParserRegion = Footer; + curr_node = alloc_node(); + curr_node->type = Footernode; + gPageBeingParsed->footer = curr_node; + gWindow->fDisplayedWindow = gWindow->fMainWindow; +} + +static void +end_a_page(void) +{ + if (gParserRegion == Scrolling) { + fprintf(stderr, "%s\n", + "(HyperDoc) end_a_page: Unexpected End of Page occurred \ + inside a \beginscroll"); + print_page_and_filename(); + jump(); + } + gEndedPage = TRUE; + if (gParserRegion == Footer) { + /* the person had all the regions, I basically just have to leave */ + curr_node->type = Endscrolling; + curr_node->next = NULL; + Pop_MR(); + } + else if (gParserRegion == Header) { + /* person had a header. So just end it and return */ + curr_node->type = Endheader; + curr_node->next = NULL; + Pop_MR(); + gPageBeingParsed->scrolling = NULL; + gPageBeingParsed->footer = NULL; + } +} + +static void +parse_replacepage(void) +{ + get_expected_token(Lbrace); + get_token(); + replace_page = alloc_string(token.id); + get_expected_token(Rbrace); +} diff --git a/src/hyper/parse.h b/src/hyper/parse.h new file mode 100644 index 00000000..6ea2e75d --- /dev/null +++ b/src/hyper/parse.h @@ -0,0 +1,107 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +#ifndef _PARSE_H_ +#define _PARSE_H_ 1 + +#include "axiom-c-macros.h" +#include "hterror.h" + +#ifdef SUNplatform +#include +#endif + +#include +#include +#include +#include +#include "hyper.h" + +#include + +extern jmp_buf jmpbuf; +extern int vbuff; + +extern TextNode *cur_spadcom; /* spad command being parsed *** */ +extern TextNode *curr_node; +extern long page_start_fpos;/* tells the character position of the start + * of the page, needed to find the current + * position when restoring the scanner */ + +/* + * Default sizes of hash tables + */ + +#define LinkHashSize 25 +#define DependHashSize 20 + +extern HashTable *gLinkHashTable; /* the hash table of active link windows */ + +/* + * Flags and defines for the modes the parser can be in + */ + +#define AllMode 0 +#define NoVerticalMode 1 +#define SimpleMode 2 + +extern short int gParserMode; + +/* + * Flags and defines for telling us what part of the page is being parsed. + */ + +extern short int gParserRegion; +extern short int gStringValueOk; +extern boolean gEndedPage; + +extern int line_number; + +/* + * Things for handling macro parameters + */ + + + +extern ParameterList parameters; + + +/* + * The error buffer + */ + +extern char ebuffer[]; + +#endif diff --git a/src/hyper/parse.pamphlet b/src/hyper/parse.pamphlet deleted file mode 100644 index c685dd38..00000000 --- a/src/hyper/parse.pamphlet +++ /dev/null @@ -1,947 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/parse} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{parse.h} -<>= -<> -#ifndef _PARSE_H_ -#define _PARSE_H_ 1 - -#include "axiom-c-macros.h" -#include "hterror.h" - -#ifdef SUNplatform -#include -#endif - -#include -#include -#include -#include -#include "hyper.h" - -#include - -extern jmp_buf jmpbuf; -extern int vbuff; - -extern TextNode *cur_spadcom; /* spad command being parsed *** */ -extern TextNode *curr_node; -extern long page_start_fpos;/* tells the character position of the start - * of the page, needed to find the current - * position when restoring the scanner */ - -/* - * Default sizes of hash tables - */ - -#define LinkHashSize 25 -#define DependHashSize 20 - -extern HashTable *gLinkHashTable; /* the hash table of active link windows */ - -/* - * Flags and defines for the modes the parser can be in - */ - -#define AllMode 0 -#define NoVerticalMode 1 -#define SimpleMode 2 - -extern short int gParserMode; - -/* - * Flags and defines for telling us what part of the page is being parsed. - */ - -extern short int gParserRegion; -extern short int gStringValueOk; -extern boolean gEndedPage; - -extern int line_number; - -/* - * Things for handling macro parameters - */ - - - -extern ParameterList parameters; - - -/* - * The error buffer - */ - -extern char ebuffer[]; - -#endif -@ -\section{parse.c} -<>= -#define _PARSE_C -#include "useproto.h" -#include "debug.h" - -#include "parse.h" -#include "parse-aux.h" -#include "parse-paste.h" -#include "parse-types.h" -#include "lex.h" -#include "mem.h" -#include "extent.h" -#include "event.h" -#include "display.h" -#include "group.h" -#include "scrollbar.h" -#include "titlebar.h" - -#include "all_hyper_proto.H1" - - - -TextNode *curr_node; /* current node being parsed. It is to be the - * next one filled */ -HashTable *gLinkHashTable; /* the hash table of active link windows */ -TextNode *cur_spadcom; /* The current AXIOM command */ - -short int gParserMode; /* Parser mode flag */ -short int gParserRegion; /* Parser Region flag scrolling etc */ -short int gStringValueOk; /* is a string or box value ok */ -boolean gEndedPage; - -extern int example_number; /* sequence example number */ - - -int ret_val; /* The return value from get_token */ - -HyperDocPage *cur_page; - -char *replace_page; /* true if dynamic page is link to static one */ - -/* - * These routines are used for storing an restoring the parser mode. When - * I start to parse from string, or from a macro, I need to restore the - * parser mode and region once done. These routines do that - * - */ - -typedef struct mr_stack { - /** The structure for storing parser mode and region **/ - short int fParserMode; - short int fParserRegion; - struct mr_stack *fNext; -} MR_Stack; - -MR_Stack *top_mr_stack = NULL; /** Declaration for the stack **/ - -static void -Push_MR(void) -{ - MR_Stack *newStackItem = (MR_Stack *) halloc(sizeof(MR_Stack), "Mode Region Stack"); - - newStackItem->fParserMode = gParserMode; - newStackItem->fParserRegion = gParserRegion; - newStackItem->fNext = top_mr_stack; - top_mr_stack = newStackItem; -} - -static void -Pop_MR(void) -{ - MR_Stack *old = top_mr_stack; - - if (old == NULL) { - fprintf(stderr, "(HyperDoc) Parser Error: Tried to pop empty MR Stack\n"); - exit(-1); - } - else { - gParserMode = old->fParserMode; - gParserRegion = old->fParserRegion; - top_mr_stack = old->fNext; - free(old); - } -} - -void -load_page(HyperDocPage *page) -{ - if (page->type == UnloadedPageType) { - HyperDocPage *new_page; - init_scanner(); - new_page = format_page((UnloadedPage *)page); - gWindow->page = new_page; - /* free(page); */ - page = new_page; - } -} - -HyperDocPage *formatpage; - -/* Display a HyperDoc page with the given name, parsing it if needed */ - -void -display_page(HyperDocPage *page) -{ - HyperDocPage *new_page; - - XUnmapSubwindows(gXDisplay, gWindow->fMainWindow); - XUnmapSubwindows(gXDisplay, gWindow->fScrollWindow); - XFlush(gXDisplay); - - if (setjmp(jmpbuf)) { - - /* - * since I did not finish formatting the page, let me get rid of what - * I had - */ - free_page(formatpage); - /* Replace the buggy page with what I started with */ - hash_replace(gWindow->fPageHashTable, (char *)page, formatpage->name); - if (!strcmp(formatpage->name, "ErrorPage")) { - fprintf(stderr, "(HyperDoc) Oops the error page is buggy\n"); - exit(-1); - } - gWindow->page = page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, "ErrorPage"); - if (page == NULL) { - fprintf(stderr, "(HyperDoc) No error page found, exiting\n"); - exit(-1); - } - reset_connection(); - } - if (page->type == UnloadedPageType || page->type == ErrorPage) { - /* Gack! (page should be a union!) */ - init_scanner(); - new_page = format_page((UnloadedPage *)page); - gWindow->page = new_page; - /* free(page); */ - page = new_page; - } - show_page(page); -} - - -/* Parse a given HyperDoc Page, from the top */ - -static HyperDocPage * -format_page(UnloadedPage *ulpage) -{ - /*int ret_val;*/ - HyperDocPage *page = alloc_page(ulpage->name); - - /* - * In case of an error I will have to get at this page so I can free the - * waisted memory - */ - formatpage = page; - page->type = Normal; - hash_replace(gWindow->fPageHashTable, (char *)page, ulpage->name); - - cfile = find_fp(ulpage->fpos); - - - page->filename = alloc_string(ulpage->fpos.name); - parse_page(page); - return page; -} - -/* parse the HyperDoc statements in the given string */ - -void -parse_from_string(char *str) -{ - save_scanner_state(); - last_ch = NoChar; - last_token = 0; - input_string = str; - input_type = FromString; - parse_HyperDoc(); - restore_scanner_state(); -} - -static void -parse_title(HyperDocPage *page) -{ - TextNode *node; - - Push_MR(); - gParserRegion = Title; - get_expected_token(Lbrace); - node = alloc_node(); - page->title = node; - node->type = Titlenode; - node->next = alloc_node(); - node = node->next; - node->type = Center; - node->next = alloc_node(); - curr_node = node->next; - parse_HyperDoc(); - curr_node->type = Endcenter; - curr_node->next = alloc_node(); - curr_node = curr_node->next; - curr_node->type = Endtitle; - curr_node->next = NULL; - if (gNeedIconName) { - char *title = print_to_string(page->title); - - XSetIconName(gXDisplay, gWindow->fMainWindow, title); - gNeedIconName = 0; - } - if (token.type != Rbrace) { - fprintf(stderr, "(HyperDoc) Parse title was expecting a closing brace\n"); - print_page_and_filename(); - jump(); - } - linkTitleBarWindows(); - Pop_MR(); -} - -static void -parse_header(HyperDocPage *page) -{ - TextNode *node; - - Push_MR(); - gParserRegion = Header; - node = alloc_node(); - page->header = node; - node->type = Headernode; - node->next = alloc_node(); - curr_node = node->next; - parse_HyperDoc(); -} - -/* - * parse a page from the top level - */ - -static void -init_parse_page(HyperDocPage *page) -{ - gEndedPage = gInDesc = gStringValueOk = gInIf = - gInButton = gInOptional = gInVerbatim = gInPaste = gInItems = - gInSpadsrc = FALSE; - example_number = 1; - cur_page = page; - gParserMode = AllMode; - /* Now I should set the input list to be null */ - free_input_list(page->input_list); - page->input_list = page->current_item = NULL; - - init_top_group(); - clear_be_stack(); - - cur_spadcom = NULL; - gLinkHashTable = page->fLinkHashTable; - hash_init( - gLinkHashTable, - LinkHashSize, - (EqualFunction) window_equal, - (HashcodeFunction) window_code); - gPageBeingParsed = page; - -} - -void -init_parse_patch(HyperDocPage *page) -{ - gEndedPage = gInDesc = gStringValueOk = gInIf = - gInButton = gInOptional = gInVerbatim = gInPaste = gInItems = - gInSpadsrc = FALSE; - gParserMode = AllMode; - gParserRegion = Scrolling; - - init_top_group(); - clear_be_stack(); - - cur_spadcom = NULL; - gLinkHashTable = page->fLinkHashTable; - gPageBeingParsed = page; -} - -#define end_page(t) ((t == Page || t == NewCommand ||t == Endpage)?1:0) - -static void -parse_page(HyperDocPage *page) -{ - init_parse_page(page); - - /* Get the name of the page */ - - get_expected_token(Page); - get_expected_token(Lbrace); - get_expected_token(Word); - if (page->name == NULL) - page->name = alloc_string(token.id); - get_expected_token(Rbrace); - /* parse the title */ - gWindow->fDisplayedWindow = gWindow->fMainWindow; - parse_title(page); - - /* - * Now start parsing the header region - */ - parse_header(page); -} - -char *ExpectedBeginScroll = -"Parser Error: Unexpected new page, expecting a begin scroll\n", *ExpectedEndScroll = -"Parser Error: Unexpected new page, expected an end scroll\n"; - -/* - * The general HyperDoc parsing function. expects to see anything. This - * function will parse until it sees either: 1) A new page starting 2) An end - * of file 3) a closing bracket "}" - */ - -void -parse_HyperDoc(void) -{ - TextNode *node = NULL /*, *save_node = NULL, *arg_node = NULL*/ ; - - for(;;) { - ret_val = get_token(); - - if (ret_val == EOF) - return; - - switch (token.type) { - case Spadsrc: - parse_spadsrc(curr_node); - break; - case Helppage: - parse_help(); - break; - case Endpatch: - case Endpaste: - case Rbrace: - return; - case Paste: - parse_paste(); - break; - case Pastebutton: - parse_pastebutton(); - break; - case Endpage: - case NewCommand: - case Page: - end_a_page(); - return; - case EndScroll: - token.type = Endscroll; - case Endscroll: - start_footer(); - break; - case Beginscroll: - start_scrolling(); - break; - case Thispage: /* it really is just a word */ - curr_node->type = Word; - curr_node->data.text = alloc_string(gPageBeingParsed->name); - break; - case Icorrection: - node->type = Noop; - break; - case Newcond: - parse_newcond(); - break; - case Setcond: - parse_setcond(); - break; - case Dollar: - parse_verbatim(Math); - break; - case Verbatim: - parse_verbatim(Verbatim); - break; - case Ifcond: - parse_ifcond(); - break; - case Fi: - if (gInIf) - return; - else { - curr_node->type = Noop; - /* Oops I had a problem parsing this puppy */ - fprintf(stderr, "(HyperDoc) \\fi found without macthing if?\n"); - longjmp(jmpbuf, 1); - fprintf(stderr, "(HyperDoc) Longjmp failed -- Exiting \n"); - exit(-1); - } - case Else: - if (gInIf) - return; - else { - /* Oops I had a problem parsing this puppy */ - curr_node->type = Noop; - fprintf(stderr, "(HyperDoc) \\else found without macthing if?\n"); - longjmp(jmpbuf, 1); - fprintf(stderr, "(HyperDoc) Longjmp failed -- Exiting \n"); - exit(-1); - } - case Macro: - parse_macro(); - break; - case Env: - /** In this case, get the environment value, and make it a word **/ - parse_env(curr_node); - break; - case WindowId: - curr_node->type = WindowId; - curr_node->space = token.id[-1]; - curr_node->data.text = window_id(gWindow->fMainWindow); - break; - case Punctuation: - case Word: - case Lsquarebrace: - case Dash: - curr_node->type = token.type; - curr_node->space = token.id[-1]; - curr_node->data.text = alloc_string(token.id); - break; - case Pagename: - { - char *str; - - curr_node->type = Word; - curr_node->space = 0; - str = halloc(strlen(cur_page->name) + 1, "parse"); - sprintf(str, "%s", cur_page->name); - curr_node->data.text = alloc_string(str); - break; - } - case Examplenumber: - { - char *str; - - curr_node->type = Word; - curr_node->space = 0; - str = halloc(5, "parse"); - sprintf(str, "%d", example_number); - curr_node->data.text = alloc_string(str); - break; - } - case Rsquarebrace: - if (gInOptional) - return; - else { - curr_node->type = token.type; - curr_node->space = token.id[-1]; - curr_node->data.text = alloc_string(token.id); - } - break; - case EndTitems: - token.type = Endtitems; - case Endtitems: - if (gParserMode != AllMode) { - curr_node->type = Noop; - fprintf(stderr, "(HyperDoc) Found a bad token %s\n", token_table[token.type]); - longjmp(jmpbuf, 1); - } - else { - curr_node->type = token.type; - break; - } - case EndItems: - token.type = Enditems; - case Enditems: - gInItems--; - case Horizontalline: - case Par: - case Newline: - case Titem: - if (gParserMode != AllMode) { - curr_node->type = Noop; - fprintf(stderr, "(HyperDoc) Found a bad token %s\n", token_table[token.type]); - longjmp(jmpbuf, 1); - } - else { - curr_node->type = token.type; - break; - } - case Begintitems: - case Beginitems: - if (gParserMode != AllMode) { - curr_node->type = Noop; - fprintf(stderr, "(HyperDoc) Found a bad token %s\n", token_table[token.type]); - longjmp(jmpbuf, 1); - } - else { - parse_begin_items(); - break; - } - case Item: - parse_item(); - break; - case Mitem: - parse_mitem(); - break; - case VSpace: - case Tab: - case HSpace: - case Indent: - case Indentrel: - parse_value1(); - break; - case Space: - parse_value2(); - break; - case Lbrace: - curr_node->type = Group; - curr_node->space = token.id[-1]; - push_group_stack(); - node = alloc_node(); - curr_node->next = node; - curr_node = curr_node->next; - parse_HyperDoc(); - curr_node->type = Endgroup; - pop_group_stack(); - break; - case Upbutton: - case Returnbutton: - case Link: - case Downlink: - case Memolink: - case Windowlink: - parse_button(); - break; - case Unixlink: - case LispMemoLink: - case LispDownLink: - case Lisplink: - case Lispcommand: - case Lispcommandquit: - case Spadlink: - case Spaddownlink: - case Spadmemolink: - case Unixcommand: - case Spadcall: - case Spadcallquit: - case Qspadcall: - case Qspadcallquit: - case Lispwindowlink: - parse_command(); - break; - case Controlbitmap: - case Inputbitmap: - case Inputpixmap: - case Inputimage: - parse_input_pix(); - break; - case Box: - parse_box(); - break; - case Mbox: - parse_mbox(); - break; - case Free: - parse_free(); - break; - case Center: - parse_centerline(); - break; - case Bound: - add_dependencies(); - break; - case Spadcommand: - case Spadgraph: - parse_spadcommand(curr_node); - break; - case Table: - parse_table(); - break; - case Beep: - case Emphasize: - case BoldFace: - case Rm: - case It: - case Tt: - case Sl: - curr_node->type = token.type; - curr_node->space = token.id[-1]; - break; - case Inputstring: - parse_inputstring(); - break; - case SimpleBox: - parse_simplebox(); - break; - case BoxValue: - case StringValue: - if (!gStringValueOk) { - strcpy(ebuffer,"(HyperDoc): Unexpected Value Command:"); - strcat(ebuffer, token.id); - - parser_error(ebuffer); - curr_node->type = Noop; - longjmp(jmpbuf, 1); - } - curr_node->type = token.type; - curr_node->space = token.id[-1]; - get_expected_token(Lbrace); - get_expected_token(Word); - curr_node->data.text = alloc_string(token.id); - get_expected_token(Rbrace); - break; - case NoLines: - gPageBeingParsed->page_flags |= NOLINES; - break; - case Pound: - curr_node->type = Pound; - curr_node->space = token.id[-1]; - curr_node->next = alloc_node(); - curr_node = curr_node->next; - parse_parameters(); - break; - case Radiobox: - parse_radiobox(); - break; - case Radioboxes: - parse_radioboxes(); - break; - case Replacepage: - parse_replacepage(); - break; - default: - fprintf(stderr, "(HyperDoc) Keyword not currently supported: %s\n", token.id); - print_page_and_filename(); - curr_node->type = Noop; - break; - } - if (gEndedPage) - return; - if (curr_node->type != Noop) { - node = alloc_node(); - curr_node->next = node; - curr_node = node; - } - } -} - - -/* parse a page from a socket source */ - -HyperDocPage * -parse_page_from_socket(void) -{ - HyperDocPage *page = alloc_page((char *) NULL); - HyperDocPage *hpage; - - init_scanner(); - input_type = FromSpadSocket; - input_string = ""; - cur_spadcom = NULL; - gLinkHashTable = page->fLinkHashTable; - hash_init( - gLinkHashTable, - LinkHashSize, - (EqualFunction) window_equal, - (HashcodeFunction) window_code); - gPageBeingParsed = page; - replace_page = NULL; - if (setjmp(jmpbuf)) { - /* Ooops, somewhere I had an error */ - free_page(page); - page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, "ErrorPage"); - reset_connection(); - } - else { - parse_page(page); - page->type = SpadGen; - page->filename = NULL; - /* just for kicks, let me add this thing to the hash file */ - hpage = (HyperDocPage *) hash_find(gWindow->fPageHashTable, page->name); - if (hpage) - hash_replace(gWindow->fPageHashTable, (char *)page, page->name); - else { - hash_insert(gWindow->fPageHashTable, (char *)page, page->name); - } - } - if (replace_page != NULL) { - free_page(page); - page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, replace_page); - if (page == NULL) - fprintf(stderr, "(HyperDoc) Unknown page: %s\n", replace_page); - } - return page; -} - -HyperDocPage * -parse_page_from_unixfd(void) -{ - HyperDocPage *page = alloc_page((char *) NULL); - - init_scanner(); - input_type = FromUnixFD; - cur_spadcom = NULL; - gLinkHashTable = page->fLinkHashTable; - hash_init( - gLinkHashTable, - LinkHashSize, - (EqualFunction) window_equal, - (HashcodeFunction) window_code); - gPageBeingParsed = page; - if (setjmp(jmpbuf)) { - /* Ooops, somewhere I had an error */ - free_page(page); - page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, "ErrorPage"); - reset_connection(); - } - else { - parse_page(page); - page->type = Unixfd; - page->filename = NULL; - } - return page; - -} - -static void -start_scrolling(void) -{ - - /* - * if I am here than I had a begin scroll. This means I should end the - * header, and then start parsing the footer - */ - - if (gParserRegion != Header) { - curr_node->type = Noop; - fprintf(stderr, "(HyperDoc) Parser Error: Unexpected BeginScrollFound\n"); - longjmp(jmpbuf, 1); - fprintf(stderr, "(HyperDoc) Longjump failed exiting\n"); - } - curr_node->type = Endheader; - curr_node->next = NULL; - Pop_MR(); - - Push_MR(); - gParserRegion = Scrolling; - gWindow->fDisplayedWindow = gWindow->fScrollWindow; - curr_node = alloc_node(); - gPageBeingParsed->scrolling = curr_node; - curr_node->type = Scrollingnode; -} - -static void -start_footer(void) -{ - /* - * This ends the parsing of the scrolling region, and then starts to - * parse the footer - */ - - if (gParserRegion != Scrolling) { - curr_node->type = Noop; - fprintf(stderr, "(HyperDoc) Parser Error: Unexpected Endscroll Found\n"); - print_page_and_filename(); - longjmp(jmpbuf, 1); - fprintf(stderr, "(HyperDoc) Longjump failed exiting\n"); - } - - curr_node->type = Endscrolling; - curr_node->next = NULL; - Pop_MR(); - linkScrollBars(); - - Push_MR(); - gParserRegion = Footer; - curr_node = alloc_node(); - curr_node->type = Footernode; - gPageBeingParsed->footer = curr_node; - gWindow->fDisplayedWindow = gWindow->fMainWindow; -} - -static void -end_a_page(void) -{ - if (gParserRegion == Scrolling) { - fprintf(stderr, "%s\n", - "(HyperDoc) end_a_page: Unexpected End of Page occurred \ - inside a \beginscroll"); - print_page_and_filename(); - jump(); - } - gEndedPage = TRUE; - if (gParserRegion == Footer) { - /* the person had all the regions, I basically just have to leave */ - curr_node->type = Endscrolling; - curr_node->next = NULL; - Pop_MR(); - } - else if (gParserRegion == Header) { - /* person had a header. So just end it and return */ - curr_node->type = Endheader; - curr_node->next = NULL; - Pop_MR(); - gPageBeingParsed->scrolling = NULL; - gPageBeingParsed->footer = NULL; - } -} - -static void -parse_replacepage(void) -{ - get_expected_token(Lbrace); - get_token(); - replace_page = alloc_string(token.id); - get_expected_token(Rbrace); -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/presea b/src/hyper/presea new file mode 100755 index 00000000..b3b9485c --- /dev/null +++ b/src/hyper/presea @@ -0,0 +1,27 @@ +#!/bin/awk -f +BEGIN {n=0;m=0 +} + +{ + a[n] = $0; + n=n+1; + j=split($0,b,"{"); + m=m+substr(b[j],1,length(b[j])-1); +} + +END { + if (case==1) + printf ("\\begin{page}{staticsearchpage}{No matches found}\n") + else if ( n==0 || m==0 ) + printf ("\\begin{page}{staticsearchpage}{No matches found for {\\em %s}}\n",expr) + else + printf ("\\begin{page}{staticsearchpage}{%d matches found in %d pages for {\\em %s}}\n",m,n,expr); + printf ("Matches\\tab{8}in Page\n"); + printf "\\beginscroll\n"; + printf "\\beginmenu\n"; + for(i=0;ifScrollUpWindow = XCreateSimpleWindow(gXDisplay, gWindow->fMainWindow, + 1, 1, supwidth, supheight, + gWindow->border_width, + gBorderColor, + BACKCOLOR); + + gWindow->fScrollDownWindow = XCreateSimpleWindow(gXDisplay, gWindow->fMainWindow, + 1, 1, sdown_width, sdown_height, + gWindow->border_width, + gBorderColor, + BACKCOLOR); + + gWindow->scrollbar = XCreateSimpleWindow(gXDisplay, gWindow->fMainWindow, + 1, 1, 1, 1, + gWindow->border_width, + gBorderColor, + BACKCOLOR); + gWindow->scroller = XCreateSimpleWindow(gXDisplay, gWindow->scrollbar, + 1, 1, 1, 1, 0, + gBorderColor, + BACKCOLOR); + +#ifdef DEBUG + fprintf(stderr, "Changing Window Attributes in scrollbar.c #2\n"); +#endif + + at.background_pixmap = sup; + XChangeWindowAttributes(gXDisplay, gWindow->fScrollUpWindow, + CWBackPixmap | CWEventMask | CWCursor, &at); + + at.background_pixmap = sdown; + XChangeWindowAttributes(gXDisplay, gWindow->fScrollDownWindow, + CWBackPixmap | CWEventMask | CWCursor, &at); + + XChangeWindowAttributes(gXDisplay, gWindow->scrollbar, + CWEventMask | CWCursor, &at); + + + if (scroller == 0) + scroller = XCreatePixmapFromBitmapData(gXDisplay, + RootWindow(gXDisplay, gXScreenNumber), + scroller_bits, scroller_width, + scroller_height, + FORECOLOR, + BACKCOLOR, + DefaultDepth(gXDisplay, gXScreenNumber)); + if (scrollbar_pix == 0) + scrollbar_pix = XCreatePixmapFromBitmapData(gXDisplay, + RootWindow(gXDisplay, gXScreenNumber), + scrollbar_pix_bits, + scrollbar_pix_width, + scrollbar_pix_height, + FORECOLOR, + BACKCOLOR, + DefaultDepth(gXDisplay, gXScreenNumber)); + + at.background_pixmap = scroller; + XChangeWindowAttributes(gXDisplay, gWindow->scroller, + CWBackPixmap | CWCursor, &at); + at.background_pixmap = scrollbar_pix; + XChangeWindowAttributes(gXDisplay, gWindow->scrollbar, + CWBackPixmap, &at); +} + +static void +drawScroller3DEffects(HDWindow * hdWindow, int x1, int y1, int x2, int y2) +{ + XClearWindow(gXDisplay, hdWindow->scroller); + + /* draw right "black" line */ + + XDrawLine(gXDisplay, hdWindow->scroller, hdWindow->fControlGC, + x2 - 3, y1 + 2, x2 - 3, y2 - 3); + + /* draw bottom "black" line */ + + XDrawLine(gXDisplay, hdWindow->scroller, hdWindow->fControlGC, + x1 + 2, y2 - 3, x2 - 3, y2 - 3); + + /* flip foreground and background colors */ + + XSetBackground(gXDisplay, hdWindow->fControlGC, gControlForegroundColor); + XSetForeground(gXDisplay, hdWindow->fControlGC, gControlBackgroundColor); + + /* draw top "white" line */ + + XDrawLine(gXDisplay, hdWindow->scroller, hdWindow->fControlGC, + x1 + 2, y1 + 2, x2 - 3, y1 + 2); + + /* draw left "white" line */ + + XDrawLine(gXDisplay, hdWindow->scroller, hdWindow->fControlGC, + x1 + 2, y1 + 2, x1 + 2, y2 - 3); + + /* reset colors */ + + XSetBackground(gXDisplay, hdWindow->fControlGC, gControlBackgroundColor); + XSetForeground(gXDisplay, hdWindow->fControlGC, gControlForegroundColor); +} + +void +showScrollBars(HDWindow * hdWindow) +{ + XWindowChanges wc; + /*int src_x = 0, src_y = 0;*/ + /*unsigned int width = supwidth, height = supheight;*/ + /*int dest_x = 0, dest_y = 0;*/ + + /* see if we even need scroll bars */ + + if (hdWindow->page->scrolling->height <= hdWindow->scrollheight) + return; + + wc.x = hdWindow->scrollx; + wc.y = hdWindow->scrollupy; + wc.height = supheight; + wc.width = supwidth; + XConfigureWindow(gXDisplay, hdWindow->fScrollUpWindow, CWX | CWY | CWHeight + | CWWidth, &wc); + wc.y = hdWindow->scrolldowny; + XConfigureWindow(gXDisplay, hdWindow->fScrollDownWindow, + CWX | CWY | CWHeight | CWWidth, + &wc); + wc.height = hdWindow->fScrollBarHeight; + wc.y = hdWindow->scrollbary; + XConfigureWindow(gXDisplay, hdWindow->scrollbar, + CWX | CWY | CWHeight | CWWidth, + &wc); + wc.x = 0; + wc.y = hdWindow->fScrollerTopPos; + wc.width = supwidth; + wc.height = hdWindow->fScrollerHeight; + XConfigureWindow(gXDisplay, hdWindow->scroller, + CWX | CWY | CWHeight | CWWidth, + &wc); + + /* + * Now we map the windows, since the bitmaps are the backgrounds for the + * windows, we need to worry about redrawing them. + */ + + XMapWindow(gXDisplay, hdWindow->fScrollUpWindow); + XMapWindow(gXDisplay, hdWindow->fScrollDownWindow); + XMapWindow(gXDisplay, hdWindow->scrollbar); + XMapWindow(gXDisplay, hdWindow->scroller); + + drawScroller3DEffects(hdWindow, 0, 0, wc.width, wc.height); +} + + +/************************************************************************ + + Moves the scroller to its proper place within the scrollbar. It + calculates how far down the page we are, and then moves the scroller + accordingly + + **************************************************************************/ + +void +moveScroller(HDWindow * hdWindow) +{ + XWindowChanges wc; + + /** moves the scroller to it's proper place **/ + + int t = (int) (hdWindow->fScrollBarHeight * (-hdWindow->page->scroll_off)); + hdWindow->fScrollerTopPos = (int) (t / hdWindow->page->scrolling->height); + wc.x = 0; + wc.y = hdWindow->fScrollerTopPos; + wc.width = supwidth; + wc.height = hdWindow->fScrollerHeight; + XConfigureWindow(gXDisplay, hdWindow->scroller, + CWX | CWY | CWHeight | CWWidth, + &wc); + drawScroller3DEffects(hdWindow, 0, 0, wc.width, wc.height); +} + +#define tophalf(y) ((y % 2 == 0)?(y/2):(y/2) + 1) +#define bothalf(y) (y/2) + +void +drawScrollLines(void) +{ + /* Checks the page_flags to see if we need a top, or a bottom line. */ + /* These are the horizontal lines framing a scrolling region when the */ + /* scrolling region is not the entire window. */ + + if (!(gWindow->page->page_flags & NOLINES)) { + line_top_group(); + if (gWindow->page->header->height) { + XDrawLine(gXDisplay, gWindow->fMainWindow, gWindow->fStandardGC, + 0, + gWindow->page->top_scroll_margin - tophalf(gWindow->border_width) + - 2 * scroll_top_margin, + gWindow->scrollwidth, + gWindow->page->top_scroll_margin - tophalf(gWindow->border_width) + - 2 * scroll_top_margin); + } + if (gWindow->page->footer->height) { + XDrawLine(gXDisplay, gWindow->fMainWindow, gWindow->fStandardGC, + 0, + gWindow->page->bot_scroll_margin + bothalf(gWindow->border_width) - 1, + gWindow->scrollwidth, + gWindow->page->bot_scroll_margin + bothalf(gWindow->border_width) - 1); + } + pop_group_stack(); + } +} + + +/* + * Calculates all the measures for the scrollbars + */ + +void +calculateScrollBarMeasures(void) +{ + int t; + + /* + * The scrollhieght is the height of the scrolling region visible in the + * HT window. Notice how it is a multiple of line height. This was needed + * to make everything scroll nicely. + */ + + gWindow->scrollheight = gWindow->page->bot_scroll_margin - + gWindow->page->top_scroll_margin - scroll_top_margin; + gWindow->scrollheight = gWindow->scrollheight - gWindow->scrollheight % line_height; + + /* + * Now do a quick check to see if I really need a scroll bar, and if not, + * just return right away + */ + + if (gWindow->scrollheight >= gWindow->page->scrolling->height) { + gWindow->page->scroll_off = 0; + return; + } + + /* + * The height of the scrollbar region, extends form the top page margin + * all the way to the bottom, excluding the room needed for the up and + * down windows + */ + + gWindow->fScrollBarHeight = gWindow->page->bot_scroll_margin - + gWindow->page->top_scroll_margin - 2 * supheight - + 2 * gWindow->border_width; + + gWindow->scrollupy = gWindow->page->top_scroll_margin - gWindow->border_width; + gWindow->scrollupy -= 2 * scroll_top_margin; + gWindow->scrolldowny = gWindow->page->bot_scroll_margin + - supheight - gWindow->border_width; + gWindow->scrollbary = gWindow->scrollupy + supheight + gWindow->border_width; + gWindow->scrollx = gWindow->width - supwidth - gWindow->border_width; + + /* + * the scroller height is calculated from the following formula + * + * fScrollerHeight scrollheight -------------- == + * --------- ------------- fScrollBarHeight + * page->scrolling_height + * + */ + + gWindow->fScrollerHeight = 1 + 2 * scroll_top_margin + /** possible integer error correction **/ + (int) (gWindow->fScrollBarHeight * gWindow->scrollheight / gWindow->page->scrolling->height); + + /* + * Check the scroll offset, to see if it is too Large + */ + + if (-(gWindow->page->scroll_off) > + (gWindow->page->scrolling->height - gWindow->scrollheight)) + gWindow->page->scroll_off = + -(gWindow->page->scrolling->height - gWindow->scrollheight); + + /* + * Then move the top of the scroller to it's proper position + */ + + gWindow->fScrollBarHeight += 2 * scroll_top_margin; + t = (int) (gWindow->fScrollBarHeight * (-gWindow->page->scroll_off)); + gWindow->fScrollerTopPos = (int) (t / (gWindow->page->scrolling->height)); +} + +void +linkScrollBars(void) +{ + HyperLink *uplink = (HyperLink *) halloc(sizeof(HyperLink), "HyperLink"); + HyperLink *downlink = (HyperLink *) halloc(sizeof(HyperLink), "HyperLink"); + HyperLink *barlink = (HyperLink *) halloc(sizeof(HyperLink), "HyperLink"); + + uplink->win = gWindow->fScrollUpWindow; + downlink->win = gWindow->fScrollDownWindow; + barlink->win = gWindow->scrollbar; + uplink->type = Scrollupbutton; + downlink->type = Scrolldownbutton; + barlink->type = Scrollbar; + barlink->x = barlink->y = 0; + uplink->x = uplink->y = 0; + downlink->x = downlink->y = 0; + uplink->reference.node = NULL; + downlink->reference.node = NULL; + hash_insert(gLinkHashTable, (char *)uplink,(char *) &uplink->win); + hash_insert(gLinkHashTable, (char *)barlink,(char *) &barlink->win); + hash_insert(gLinkHashTable, (char *)downlink,(char *) &downlink->win); +} + +void +scrollUp(void) +{ + + if (gWindow->page->scroll_off == 0); /* BeepAtTheUser(); *//* The + * beeping annoyed me. RSS */ + else { + changeWindowBackgroundPixmap(gWindow->fScrollUpWindow, sup_pressed); + + gWindow->page->scroll_off += line_height; /* Scroll a line */ + if (gWindow->page->scroll_off > 0) + gWindow->page->scroll_off = 0; + XCopyArea(gXDisplay, gWindow->fScrollWindow, gWindow->fScrollWindow, gWindow->fStandardGC, + 0, 0, + gWindow->scrollwidth, gWindow->scrollheight - line_height + 1, + 0, line_height); + XClearArea(gXDisplay, gWindow->fScrollWindow, 0, 0, + gWindow->scrollwidth, + line_height, False); + scroll_page(gWindow->page); + + changeWindowBackgroundPixmap(gWindow->fScrollUpWindow, sup); + } + +} + +void +scrollUpPage(void) +{ + if (gWindow->page->scroll_off == 0); /* BeepAtTheUser(); */ + else { + /* Scroll a page */ + + gWindow->page->scroll_off += ch(gWindow->scrollheight) - line_height; + if (gWindow->page->scroll_off > 0) + gWindow->page->scroll_off = 0; + + XClearWindow(gXDisplay, gWindow->fScrollWindow); + scroll_page(gWindow->page); + } +} + +void +scrollToFirstPage(void) +{ + if (gWindow->page->scroll_off == 0); /* BeepAtTheUser(); */ + else { + gWindow->page->scroll_off = 0; + XClearWindow(gXDisplay, gWindow->fScrollWindow); + scroll_page(gWindow->page); + } +} + +void +scrollDown(void) +{ + + if (-(gWindow->page->scroll_off) >= + (gWindow->page->scrolling->height - gWindow->scrollheight)) { + ; /* BeepAtTheUser(); */ + } + else { + changeWindowBackgroundPixmap(gWindow->fScrollDownWindow, sdown_pressed); + + gWindow->page->scroll_off -= line_height; /* Scroll a line */ + + XCopyArea(gXDisplay, gWindow->fScrollWindow, gWindow->fScrollWindow, gWindow->fStandardGC, + 0, line_height, + gWindow->scrollwidth, gWindow->scrollheight - line_height + 1, + 0, 0); + XClearArea(gXDisplay, gWindow->fScrollWindow, 0, + gWindow->scrollheight - line_height, + gWindow->scrollwidth, + line_height, False); + scroll_page(gWindow->page); + + changeWindowBackgroundPixmap(gWindow->fScrollDownWindow, sdown); + } +} + + +void +scrollDownPage(void) +{ + if (gWindow->page->scrolling == NULL || (-(gWindow->page->scroll_off) >= + (gWindow->page->scrolling->height - gWindow->scrollheight))) { + ; /* BeepAtTheUser(); */ + } + else { + gWindow->page->scroll_off -= ch(gWindow->scrollheight) - line_height; + + if (-(gWindow->page->scroll_off) > + (gWindow->page->scrolling->height - gWindow->scrollheight)) + gWindow->page->scroll_off = - + (gWindow->page->scrolling->height - gWindow->scrollheight); + + XClearWindow(gXDisplay, gWindow->fScrollWindow); + + scroll_page(gWindow->page); + } +} + +void +scrollScroller(XButtonEvent * event) +{ + + /* + * This routine checks to see where in the window the button press + * occured. It then tries to move the scroller so that the top of the + * scroller is at the spot of the event + */ + + int y = event->y; + int top = y; + + if (top < 0) { + top = 0; + if (gWindow->fScrollerTopPos == 0) + return; + gWindow->page->scroll_off = 0; + } + else if ((top + gWindow->fScrollerHeight) > gWindow->fScrollBarHeight) { + top = gWindow->fScrollBarHeight - gWindow->fScrollerHeight; + if (top == gWindow->fScrollerTopPos) + return; + gWindow->page->scroll_off = + -(gWindow->page->scrolling->height - gWindow->scrollheight); + gWindow->page->scroll_off -= gWindow->page->scroll_off % line_height; + } + else { /** top is in an ok spot **/ + int t; + + t = -(gWindow->page->scrolling->height) * top; + t = t / (gWindow->fScrollBarHeight); + if (gWindow->page->scroll_off == (t -= t % line_height)) + return; + gWindow->page->scroll_off = t; + gWindow->fScrollerTopPos = top; + } + XClearWindow(gXDisplay, gWindow->fScrollWindow); + scroll_page(gWindow->page); +} + + +void +hideScrollBars(HDWindow * hdWindow) +{ + XUnmapWindow(gXDisplay, hdWindow->fScrollDownWindow); + XUnmapWindow(gXDisplay, hdWindow->fScrollUpWindow); + XUnmapWindow(gXDisplay, hdWindow->scrollbar); + XUnmapWindow(gXDisplay, hdWindow->scroller); +} + +void +getScrollBarMinimumSize(int *width, int *height) +{ + (*width) = sup_width + 4; + (*height) = sup_height + sdown_height + 5; +} + +static int +ch(int height) +{ + /*int rheight;*/ + int rem = height % line_height; + + if (rem == 0) + return height; + return height - rem + line_height; +} + +static void +changeWindowBackgroundPixmap(Window window, Pixmap pixmap) +{ + if (pixmap) { + XSetWindowAttributes at; + + at.background_pixmap = pixmap; + XChangeWindowAttributes(gXDisplay, window, CWBackPixmap, &at); + XClearWindow(gXDisplay, window); + } +} diff --git a/src/hyper/scrollbar.h b/src/hyper/scrollbar.h new file mode 100644 index 00000000..c1721fe8 --- /dev/null +++ b/src/hyper/scrollbar.h @@ -0,0 +1,43 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +#ifndef _SCROLLBAR_H_ +#define _SCROLLBAR_H_ 1 + +#include "hyper.h" + +extern int gScrollbarWidth; + +#endif diff --git a/src/hyper/scrollbar.pamphlet b/src/hyper/scrollbar.pamphlet deleted file mode 100644 index 11532305..00000000 --- a/src/hyper/scrollbar.pamphlet +++ /dev/null @@ -1,746 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/scrollbar} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{scrollbar.h} -<>= -<> -#ifndef _SCROLLBAR_H_ -#define _SCROLLBAR_H_ 1 - -#include "hyper.h" - -extern int gScrollbarWidth; - -#endif -@ -\section{scrollbar.c} -<>= -/****************************************************************************** - * - * scrollbar.c: HyperDoc Scrollbar routines - * - * Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993. - * - ****************************************************************************/ -#define _SCROLLBAR_C -#include "axiom-c-macros.h" -#include "useproto.h" -#include "debug.h" - -#include "extent.h" -#include "display.h" -#include "group.h" -#include "initx.h" -#include "scrollbar.h" -#include "parse.h" - -#include "all_hyper_proto.H1" - -/************************************************************************* - Scrollbar Comments 10/08/89 - - The scrollbar is displayed on the side of the HyperDoc display, if needed. - It is composed of four windows - - fScrollUpWindow -- the arrowed box at the top of the scrollbar. Scrolls the - window up a line at a time. - fScrollDownWindow -- Located at the bottom of the window, it is used to scroll - down a single line at a time. - scrollbar -- this is the window which does the variable scrolling. It - houses the actual scroller. - scroller -- This is the scroller inside the scroll bar. - - The procedure below, makes all these windows, and also makes three bitmaps, - sup -- The up arrow for the fScrollUpWindow. - sdown -- the down arrow for the fScrollDownWindow. - scroller -- the scroller stipple. - It then fills the window with the proper Pixmap background. - - The scrollbar and scroller works as follows. The size of the scroller is - calculated as - - size of scroller size of visible text - ----------------- === ------------------------------ . - size of scrollbar size of whole scrolling region - - The top of the scroller shows the relative position in the page of - the top of the scrolling region. This way the user knows how far - down the page he or she has moved. - When the user clicks in the scrollbar, the center of the - scroller, if possible, is placed at the point of the click. - - See the routines - showScrollBars -- to see how the scroll bars are actually realized. - moveScroller -- to see how the scroller is moved when the user scrolls - - - **************************************************************************/ - -#ifndef _NO_PROTO -static int ch(int height); -static void changeWindowBackgroundPixmap(Window window, Pixmap pixmap); -#else -static int ch(); -static void changeWindowBackgroundPixmap(); -#endif - -static Pixmap sup = 0, sdown = 0, sup_pressed = 0, sdown_pressed = 0, scroller = 0, scrollbar_pix = 0; - - -/* #undef BITMAPS2D to get old style 2d effect */ - -#ifdef BITMAPS2D - -#define CONTROLS_3D 0 - -#include "sdown.bitmap" -#include "sup.bitmap" - -#define BACKCOLOR gBackgroundColor -#define FORECOLOR gActiveColor - -#else - -#define CONTROLS_3D 1 - -#include "sdown3d.bitmap" -#include "sdown3dpr.bitmap" - -#include "sup3d.bitmap" -#include "sup3dpr.bitmap" - -#define sup_width sup3d_width -#define sup_height sup3d_height -#define sup_bits sup3d_bits - -#define sdown_width sdown3d_width -#define sdown_height sdown3d_height -#define sdown_bits sdown3d_bits - -#define BACKCOLOR gControlBackgroundColor -#define FORECOLOR gControlForegroundColor - -#endif - - -#if 0 -#define scroller_width 3 -#define scroller_height 3 -static char scroller_bits[] = {0x05, 0x07, 0x03}; - -#endif - -#define scroller_width 2 -#define scroller_height 2 -static char scroller_bits[] = { - 0x01, 0x02}; - - - -static int supheight = sup_height; -static int supwidth = sup_width; - -#define scrollbar_pix_width 3 -#define scrollbar_pix_height 3 -static char scrollbar_pix_bits[] = {0x00, 0x03, 0x00}; - - - -int gScrollbarWidth = sup_width + 2; - - - -void -makeScrollBarWindows(void) -{ - XSetWindowAttributes at; - - at.cursor = gActiveCursor; - at.event_mask = ButtonPress; - /** create the bitmaps **/ - if (supwidth != sdown_width || supheight != sdown_height) { - fprintf(stderr, - "Scrollbar error, up and down pointers must have the same dimensions\n"); - exit(-1); - } - - if (sup == 0) - sup = XCreatePixmapFromBitmapData( - gXDisplay, - RootWindow(gXDisplay, gXScreenNumber), - sup_bits, supwidth, supheight, - FORECOLOR, BACKCOLOR, - DefaultDepth(gXDisplay, gXScreenNumber)); - - if (sdown == 0) - sdown = XCreatePixmapFromBitmapData( - gXDisplay, - RootWindow(gXDisplay, gXScreenNumber), - sdown_bits, sdown_width, sdown_height, - FORECOLOR, BACKCOLOR, - DefaultDepth(gXDisplay, gXScreenNumber)); - - if (CONTROLS_3D) { - sup_pressed = XCreatePixmapFromBitmapData( - gXDisplay, - RootWindow(gXDisplay, gXScreenNumber), - sup3dpr_bits, sup3dpr_width, sup3dpr_height, - FORECOLOR, BACKCOLOR, - DefaultDepth(gXDisplay, gXScreenNumber)); - sdown_pressed = XCreatePixmapFromBitmapData( - gXDisplay, - RootWindow(gXDisplay, gXScreenNumber), - sdown3dpr_bits, sdown3dpr_width, sdown3dpr_height, - FORECOLOR, BACKCOLOR, - DefaultDepth(gXDisplay, gXScreenNumber)); - } - - gWindow->fScrollUpWindow = XCreateSimpleWindow(gXDisplay, gWindow->fMainWindow, - 1, 1, supwidth, supheight, - gWindow->border_width, - gBorderColor, - BACKCOLOR); - - gWindow->fScrollDownWindow = XCreateSimpleWindow(gXDisplay, gWindow->fMainWindow, - 1, 1, sdown_width, sdown_height, - gWindow->border_width, - gBorderColor, - BACKCOLOR); - - gWindow->scrollbar = XCreateSimpleWindow(gXDisplay, gWindow->fMainWindow, - 1, 1, 1, 1, - gWindow->border_width, - gBorderColor, - BACKCOLOR); - gWindow->scroller = XCreateSimpleWindow(gXDisplay, gWindow->scrollbar, - 1, 1, 1, 1, 0, - gBorderColor, - BACKCOLOR); - -#ifdef DEBUG - fprintf(stderr, "Changing Window Attributes in scrollbar.c #2\n"); -#endif - - at.background_pixmap = sup; - XChangeWindowAttributes(gXDisplay, gWindow->fScrollUpWindow, - CWBackPixmap | CWEventMask | CWCursor, &at); - - at.background_pixmap = sdown; - XChangeWindowAttributes(gXDisplay, gWindow->fScrollDownWindow, - CWBackPixmap | CWEventMask | CWCursor, &at); - - XChangeWindowAttributes(gXDisplay, gWindow->scrollbar, - CWEventMask | CWCursor, &at); - - - if (scroller == 0) - scroller = XCreatePixmapFromBitmapData(gXDisplay, - RootWindow(gXDisplay, gXScreenNumber), - scroller_bits, scroller_width, - scroller_height, - FORECOLOR, - BACKCOLOR, - DefaultDepth(gXDisplay, gXScreenNumber)); - if (scrollbar_pix == 0) - scrollbar_pix = XCreatePixmapFromBitmapData(gXDisplay, - RootWindow(gXDisplay, gXScreenNumber), - scrollbar_pix_bits, - scrollbar_pix_width, - scrollbar_pix_height, - FORECOLOR, - BACKCOLOR, - DefaultDepth(gXDisplay, gXScreenNumber)); - - at.background_pixmap = scroller; - XChangeWindowAttributes(gXDisplay, gWindow->scroller, - CWBackPixmap | CWCursor, &at); - at.background_pixmap = scrollbar_pix; - XChangeWindowAttributes(gXDisplay, gWindow->scrollbar, - CWBackPixmap, &at); -} - -static void -drawScroller3DEffects(HDWindow * hdWindow, int x1, int y1, int x2, int y2) -{ - XClearWindow(gXDisplay, hdWindow->scroller); - - /* draw right "black" line */ - - XDrawLine(gXDisplay, hdWindow->scroller, hdWindow->fControlGC, - x2 - 3, y1 + 2, x2 - 3, y2 - 3); - - /* draw bottom "black" line */ - - XDrawLine(gXDisplay, hdWindow->scroller, hdWindow->fControlGC, - x1 + 2, y2 - 3, x2 - 3, y2 - 3); - - /* flip foreground and background colors */ - - XSetBackground(gXDisplay, hdWindow->fControlGC, gControlForegroundColor); - XSetForeground(gXDisplay, hdWindow->fControlGC, gControlBackgroundColor); - - /* draw top "white" line */ - - XDrawLine(gXDisplay, hdWindow->scroller, hdWindow->fControlGC, - x1 + 2, y1 + 2, x2 - 3, y1 + 2); - - /* draw left "white" line */ - - XDrawLine(gXDisplay, hdWindow->scroller, hdWindow->fControlGC, - x1 + 2, y1 + 2, x1 + 2, y2 - 3); - - /* reset colors */ - - XSetBackground(gXDisplay, hdWindow->fControlGC, gControlBackgroundColor); - XSetForeground(gXDisplay, hdWindow->fControlGC, gControlForegroundColor); -} - -void -showScrollBars(HDWindow * hdWindow) -{ - XWindowChanges wc; - /*int src_x = 0, src_y = 0;*/ - /*unsigned int width = supwidth, height = supheight;*/ - /*int dest_x = 0, dest_y = 0;*/ - - /* see if we even need scroll bars */ - - if (hdWindow->page->scrolling->height <= hdWindow->scrollheight) - return; - - wc.x = hdWindow->scrollx; - wc.y = hdWindow->scrollupy; - wc.height = supheight; - wc.width = supwidth; - XConfigureWindow(gXDisplay, hdWindow->fScrollUpWindow, CWX | CWY | CWHeight - | CWWidth, &wc); - wc.y = hdWindow->scrolldowny; - XConfigureWindow(gXDisplay, hdWindow->fScrollDownWindow, - CWX | CWY | CWHeight | CWWidth, - &wc); - wc.height = hdWindow->fScrollBarHeight; - wc.y = hdWindow->scrollbary; - XConfigureWindow(gXDisplay, hdWindow->scrollbar, - CWX | CWY | CWHeight | CWWidth, - &wc); - wc.x = 0; - wc.y = hdWindow->fScrollerTopPos; - wc.width = supwidth; - wc.height = hdWindow->fScrollerHeight; - XConfigureWindow(gXDisplay, hdWindow->scroller, - CWX | CWY | CWHeight | CWWidth, - &wc); - - /* - * Now we map the windows, since the bitmaps are the backgrounds for the - * windows, we need to worry about redrawing them. - */ - - XMapWindow(gXDisplay, hdWindow->fScrollUpWindow); - XMapWindow(gXDisplay, hdWindow->fScrollDownWindow); - XMapWindow(gXDisplay, hdWindow->scrollbar); - XMapWindow(gXDisplay, hdWindow->scroller); - - drawScroller3DEffects(hdWindow, 0, 0, wc.width, wc.height); -} - - -/************************************************************************ - - Moves the scroller to its proper place within the scrollbar. It - calculates how far down the page we are, and then moves the scroller - accordingly - - **************************************************************************/ - -void -moveScroller(HDWindow * hdWindow) -{ - XWindowChanges wc; - - /** moves the scroller to it's proper place **/ - - int t = (int) (hdWindow->fScrollBarHeight * (-hdWindow->page->scroll_off)); - hdWindow->fScrollerTopPos = (int) (t / hdWindow->page->scrolling->height); - wc.x = 0; - wc.y = hdWindow->fScrollerTopPos; - wc.width = supwidth; - wc.height = hdWindow->fScrollerHeight; - XConfigureWindow(gXDisplay, hdWindow->scroller, - CWX | CWY | CWHeight | CWWidth, - &wc); - drawScroller3DEffects(hdWindow, 0, 0, wc.width, wc.height); -} - -#define tophalf(y) ((y % 2 == 0)?(y/2):(y/2) + 1) -#define bothalf(y) (y/2) - -void -drawScrollLines(void) -{ - /* Checks the page_flags to see if we need a top, or a bottom line. */ - /* These are the horizontal lines framing a scrolling region when the */ - /* scrolling region is not the entire window. */ - - if (!(gWindow->page->page_flags & NOLINES)) { - line_top_group(); - if (gWindow->page->header->height) { - XDrawLine(gXDisplay, gWindow->fMainWindow, gWindow->fStandardGC, - 0, - gWindow->page->top_scroll_margin - tophalf(gWindow->border_width) - - 2 * scroll_top_margin, - gWindow->scrollwidth, - gWindow->page->top_scroll_margin - tophalf(gWindow->border_width) - - 2 * scroll_top_margin); - } - if (gWindow->page->footer->height) { - XDrawLine(gXDisplay, gWindow->fMainWindow, gWindow->fStandardGC, - 0, - gWindow->page->bot_scroll_margin + bothalf(gWindow->border_width) - 1, - gWindow->scrollwidth, - gWindow->page->bot_scroll_margin + bothalf(gWindow->border_width) - 1); - } - pop_group_stack(); - } -} - - -/* - * Calculates all the measures for the scrollbars - */ - -void -calculateScrollBarMeasures(void) -{ - int t; - - /* - * The scrollhieght is the height of the scrolling region visible in the - * HT window. Notice how it is a multiple of line height. This was needed - * to make everything scroll nicely. - */ - - gWindow->scrollheight = gWindow->page->bot_scroll_margin - - gWindow->page->top_scroll_margin - scroll_top_margin; - gWindow->scrollheight = gWindow->scrollheight - gWindow->scrollheight % line_height; - - /* - * Now do a quick check to see if I really need a scroll bar, and if not, - * just return right away - */ - - if (gWindow->scrollheight >= gWindow->page->scrolling->height) { - gWindow->page->scroll_off = 0; - return; - } - - /* - * The height of the scrollbar region, extends form the top page margin - * all the way to the bottom, excluding the room needed for the up and - * down windows - */ - - gWindow->fScrollBarHeight = gWindow->page->bot_scroll_margin - - gWindow->page->top_scroll_margin - 2 * supheight - - 2 * gWindow->border_width; - - gWindow->scrollupy = gWindow->page->top_scroll_margin - gWindow->border_width; - gWindow->scrollupy -= 2 * scroll_top_margin; - gWindow->scrolldowny = gWindow->page->bot_scroll_margin - - supheight - gWindow->border_width; - gWindow->scrollbary = gWindow->scrollupy + supheight + gWindow->border_width; - gWindow->scrollx = gWindow->width - supwidth - gWindow->border_width; - - /* - * the scroller height is calculated from the following formula - * - * fScrollerHeight scrollheight -------------- == - * --------- ------------- fScrollBarHeight - * page->scrolling_height - * - */ - - gWindow->fScrollerHeight = 1 + 2 * scroll_top_margin + /** possible integer error correction **/ - (int) (gWindow->fScrollBarHeight * gWindow->scrollheight / gWindow->page->scrolling->height); - - /* - * Check the scroll offset, to see if it is too Large - */ - - if (-(gWindow->page->scroll_off) > - (gWindow->page->scrolling->height - gWindow->scrollheight)) - gWindow->page->scroll_off = - -(gWindow->page->scrolling->height - gWindow->scrollheight); - - /* - * Then move the top of the scroller to it's proper position - */ - - gWindow->fScrollBarHeight += 2 * scroll_top_margin; - t = (int) (gWindow->fScrollBarHeight * (-gWindow->page->scroll_off)); - gWindow->fScrollerTopPos = (int) (t / (gWindow->page->scrolling->height)); -} - -void -linkScrollBars(void) -{ - HyperLink *uplink = (HyperLink *) halloc(sizeof(HyperLink), "HyperLink"); - HyperLink *downlink = (HyperLink *) halloc(sizeof(HyperLink), "HyperLink"); - HyperLink *barlink = (HyperLink *) halloc(sizeof(HyperLink), "HyperLink"); - - uplink->win = gWindow->fScrollUpWindow; - downlink->win = gWindow->fScrollDownWindow; - barlink->win = gWindow->scrollbar; - uplink->type = Scrollupbutton; - downlink->type = Scrolldownbutton; - barlink->type = Scrollbar; - barlink->x = barlink->y = 0; - uplink->x = uplink->y = 0; - downlink->x = downlink->y = 0; - uplink->reference.node = NULL; - downlink->reference.node = NULL; - hash_insert(gLinkHashTable, (char *)uplink,(char *) &uplink->win); - hash_insert(gLinkHashTable, (char *)barlink,(char *) &barlink->win); - hash_insert(gLinkHashTable, (char *)downlink,(char *) &downlink->win); -} - -void -scrollUp(void) -{ - - if (gWindow->page->scroll_off == 0); /* BeepAtTheUser(); *//* The - * beeping annoyed me. RSS */ - else { - changeWindowBackgroundPixmap(gWindow->fScrollUpWindow, sup_pressed); - - gWindow->page->scroll_off += line_height; /* Scroll a line */ - if (gWindow->page->scroll_off > 0) - gWindow->page->scroll_off = 0; - XCopyArea(gXDisplay, gWindow->fScrollWindow, gWindow->fScrollWindow, gWindow->fStandardGC, - 0, 0, - gWindow->scrollwidth, gWindow->scrollheight - line_height + 1, - 0, line_height); - XClearArea(gXDisplay, gWindow->fScrollWindow, 0, 0, - gWindow->scrollwidth, - line_height, False); - scroll_page(gWindow->page); - - changeWindowBackgroundPixmap(gWindow->fScrollUpWindow, sup); - } - -} - -void -scrollUpPage(void) -{ - if (gWindow->page->scroll_off == 0); /* BeepAtTheUser(); */ - else { - /* Scroll a page */ - - gWindow->page->scroll_off += ch(gWindow->scrollheight) - line_height; - if (gWindow->page->scroll_off > 0) - gWindow->page->scroll_off = 0; - - XClearWindow(gXDisplay, gWindow->fScrollWindow); - scroll_page(gWindow->page); - } -} - -void -scrollToFirstPage(void) -{ - if (gWindow->page->scroll_off == 0); /* BeepAtTheUser(); */ - else { - gWindow->page->scroll_off = 0; - XClearWindow(gXDisplay, gWindow->fScrollWindow); - scroll_page(gWindow->page); - } -} - -void -scrollDown(void) -{ - - if (-(gWindow->page->scroll_off) >= - (gWindow->page->scrolling->height - gWindow->scrollheight)) { - ; /* BeepAtTheUser(); */ - } - else { - changeWindowBackgroundPixmap(gWindow->fScrollDownWindow, sdown_pressed); - - gWindow->page->scroll_off -= line_height; /* Scroll a line */ - - XCopyArea(gXDisplay, gWindow->fScrollWindow, gWindow->fScrollWindow, gWindow->fStandardGC, - 0, line_height, - gWindow->scrollwidth, gWindow->scrollheight - line_height + 1, - 0, 0); - XClearArea(gXDisplay, gWindow->fScrollWindow, 0, - gWindow->scrollheight - line_height, - gWindow->scrollwidth, - line_height, False); - scroll_page(gWindow->page); - - changeWindowBackgroundPixmap(gWindow->fScrollDownWindow, sdown); - } -} - - -void -scrollDownPage(void) -{ - if (gWindow->page->scrolling == NULL || (-(gWindow->page->scroll_off) >= - (gWindow->page->scrolling->height - gWindow->scrollheight))) { - ; /* BeepAtTheUser(); */ - } - else { - gWindow->page->scroll_off -= ch(gWindow->scrollheight) - line_height; - - if (-(gWindow->page->scroll_off) > - (gWindow->page->scrolling->height - gWindow->scrollheight)) - gWindow->page->scroll_off = - - (gWindow->page->scrolling->height - gWindow->scrollheight); - - XClearWindow(gXDisplay, gWindow->fScrollWindow); - - scroll_page(gWindow->page); - } -} - -void -scrollScroller(XButtonEvent * event) -{ - - /* - * This routine checks to see where in the window the button press - * occured. It then tries to move the scroller so that the top of the - * scroller is at the spot of the event - */ - - int y = event->y; - int top = y; - - if (top < 0) { - top = 0; - if (gWindow->fScrollerTopPos == 0) - return; - gWindow->page->scroll_off = 0; - } - else if ((top + gWindow->fScrollerHeight) > gWindow->fScrollBarHeight) { - top = gWindow->fScrollBarHeight - gWindow->fScrollerHeight; - if (top == gWindow->fScrollerTopPos) - return; - gWindow->page->scroll_off = - -(gWindow->page->scrolling->height - gWindow->scrollheight); - gWindow->page->scroll_off -= gWindow->page->scroll_off % line_height; - } - else { /** top is in an ok spot **/ - int t; - - t = -(gWindow->page->scrolling->height) * top; - t = t / (gWindow->fScrollBarHeight); - if (gWindow->page->scroll_off == (t -= t % line_height)) - return; - gWindow->page->scroll_off = t; - gWindow->fScrollerTopPos = top; - } - XClearWindow(gXDisplay, gWindow->fScrollWindow); - scroll_page(gWindow->page); -} - - -void -hideScrollBars(HDWindow * hdWindow) -{ - XUnmapWindow(gXDisplay, hdWindow->fScrollDownWindow); - XUnmapWindow(gXDisplay, hdWindow->fScrollUpWindow); - XUnmapWindow(gXDisplay, hdWindow->scrollbar); - XUnmapWindow(gXDisplay, hdWindow->scroller); -} - -void -getScrollBarMinimumSize(int *width, int *height) -{ - (*width) = sup_width + 4; - (*height) = sup_height + sdown_height + 5; -} - -static int -ch(int height) -{ - /*int rheight;*/ - int rem = height % line_height; - - if (rem == 0) - return height; - return height - rem + line_height; -} - -static void -changeWindowBackgroundPixmap(Window window, Pixmap pixmap) -{ - if (pixmap) { - XSetWindowAttributes at; - - at.background_pixmap = pixmap; - XChangeWindowAttributes(gXDisplay, window, CWBackPixmap, &at); - XClearWindow(gXDisplay, window); - } -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/sdown.bitmap b/src/hyper/sdown.bitmap new file mode 100644 index 00000000..c16c607f --- /dev/null +++ b/src/hyper/sdown.bitmap @@ -0,0 +1,9 @@ +#define sdown_width 21 +#define sdown_height 21 +static char sdown_bits[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0xf0, + 0x03, 0x00, 0xf8, 0x07, 0x00, 0xfc, 0x0f, 0x00, 0xfe, 0x1f, 0x00, 0xff, + 0x3f, 0x80, 0xff, 0x7f, 0xc0, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xf1, 0xff, + 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff}; diff --git a/src/hyper/sdown3d.bitmap b/src/hyper/sdown3d.bitmap new file mode 100644 index 00000000..e34dc105 --- /dev/null +++ b/src/hyper/sdown3d.bitmap @@ -0,0 +1,9 @@ +#define sdown3d_width 21 +#define sdown3d_height 21 +static char sdown3d_bits[] = { + 0xaa, 0xaa, 0x0a, 0x55, 0x55, 0x15, 0x02, 0x00, 0x0c, 0x51, 0x55, 0x15, + 0xaa, 0xaa, 0x0e, 0x51, 0x5f, 0x15, 0xaa, 0xae, 0x0e, 0x51, 0x5f, 0x15, + 0xaa, 0xae, 0x0e, 0x51, 0x5f, 0x15, 0xea, 0xff, 0x0e, 0xd1, 0x7f, 0x15, + 0xaa, 0xbf, 0x0e, 0x51, 0x5f, 0x15, 0xaa, 0xae, 0x0e, 0x51, 0x55, 0x15, + 0xaa, 0xaa, 0x0e, 0x51, 0x55, 0x15, 0xfe, 0xff, 0x0f, 0x55, 0x55, 0x15, + 0xaa, 0xaa, 0x0a}; diff --git a/src/hyper/sdown3dpr.bitmap b/src/hyper/sdown3dpr.bitmap new file mode 100644 index 00000000..6ce090b1 --- /dev/null +++ b/src/hyper/sdown3dpr.bitmap @@ -0,0 +1,9 @@ +#define sdown3dpr_width 21 +#define sdown3dpr_height 21 +static char sdown3dpr_bits[] = { + 0xaa, 0xaa, 0x0a, 0x55, 0x55, 0x15, 0xfe, 0xff, 0x0f, 0x55, 0x55, 0x11, + 0xae, 0xaa, 0x0a, 0x55, 0x55, 0x11, 0xae, 0xbe, 0x0a, 0x55, 0x5d, 0x11, + 0xae, 0xbe, 0x0a, 0x55, 0x5d, 0x11, 0xae, 0xbe, 0x0a, 0xd5, 0xff, 0x11, + 0xae, 0xff, 0x0a, 0x55, 0x7f, 0x11, 0xae, 0xbe, 0x0a, 0x55, 0x5d, 0x11, + 0xae, 0xaa, 0x0a, 0x55, 0x55, 0x11, 0x06, 0x00, 0x08, 0x55, 0x55, 0x15, + 0xaa, 0xaa, 0x0a}; diff --git a/src/hyper/search.pamphlet b/src/hyper/search.pamphlet deleted file mode 100644 index 7033b007..00000000 --- a/src/hyper/search.pamphlet +++ /dev/null @@ -1,67 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/search} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{search.h} -Construct a page with a menu of references to the word. -The syntax of the command is: -\begin{verbatim} -htsearch word -\end{verbatim} -<>= -#!/bin/sh - -htbindir=$AXIOM/lib -htpagedir=$AXIOM/share/hypertex/pages - - -if test -z "$1" -then - echo ""|$htbindir/presea case=1 - -else -( cd $htpagedir; $htbindir/hthits "$1" $htpagedir/ht.db |sort -r -n +0.22 |$htbindir/presea case=0 expr="$1" -) -fi -@ -<>= -#!/bin/awk -f -BEGIN {n=0;m=0 -} - -{ - a[n] = $0; - n=n+1; - j=split($0,b,"{"); - m=m+substr(b[j],1,length(b[j])-1); -} - -END { - if (case==1) - printf ("\\begin{page}{staticsearchpage}{No matches found}\n") - else if ( n==0 || m==0 ) - printf ("\\begin{page}{staticsearchpage}{No matches found for {\\em %s}}\n",expr) - else - printf ("\\begin{page}{staticsearchpage}{%d matches found in %d pages for {\\em %s}}\n",m,n,expr); - printf ("Matches\\tab{8}in Page\n"); - printf "\\beginscroll\n"; - printf "\\beginmenu\n"; - for(i=0;i>= -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} diff --git a/src/hyper/show-types.c b/src/hyper/show-types.c new file mode 100644 index 00000000..50413414 --- /dev/null +++ b/src/hyper/show-types.c @@ -0,0 +1,599 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +/****************************************************************************** + * + * show_types.c: Show the various types of things that can show up in text + * + * Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993. + * + ****************************************************************************/ +#define _SHOW_TYPES_C +#include "axiom-c-macros.h" +#include "useproto.h" +#include "debug.h" + + +#include "hyper.h" +#include "display.h" +#include "extent.h" +#include "group.h" + +#include "all_hyper_proto.H1" + + + +/* + * Display the page whose extent has been computed, using the actual size of + * the window, and y_off to determine clipped areas + */ + +void +show_text(TextNode *node, int Ender) +{ + /*int twidth, len;*/ + /*int otext_x, otext_y, t;*/ + /*XFontStruct *old_font;*/ + /*int old_color;*/ + + for (; node != NULL; node = node->next) { + switch (node->type) { + case 0: + case Beginitems: + case Begintitems: + case Bound: + case Center: + case Free: + case HSpace: + case Indent: + case Indentrel: + case Item: + case Macro: + case Mbox: + case Newline: + case Noop: + case Par: + case Pound: + case Rbrace: + case Space: + case Tab: + case Table: + case Titem: + case VSpace: + break; + + case Dash: + case Fi: + case Ifcond: + if (visible(node->y, node->height)) { + if (strlen(node->data.text) > 1) { + XDrawLine(gXDisplay, gWindow->fDisplayedWindow, gWindow->fStandardGC, node->x, + node->y + gRegionOffset + y_off + - gTopOfGroupStack->cur_font->descent - + word_off_height, + node->x + node->width, + node->y + gRegionOffset + y_off - word_off_height - + gTopOfGroupStack->cur_font->descent); + } + else { + XDrawString(gXDisplay, gWindow->fDisplayedWindow, gWindow->fStandardGC, node->x, node->y + + gRegionOffset - gTopOfGroupStack->cur_font->descent + y_off, + node->data.text, 1); + } + } + else { + if (above(node->y)) + need_scroll_up_button = 1; + else if (below(node->y)) + need_scroll_down_button = 1; + } + break; + + case Lsquarebrace: + case Math: + case Punctuation: + case Rsquarebrace: + case Spadsrctxt: + case WindowId: + case Word: + if (visible(node->y, node->height)) + XDrawString(gXDisplay, gWindow->fDisplayedWindow, gWindow->fStandardGC, node->x, node->y + + gRegionOffset - gTopOfGroupStack->cur_font->descent + y_off, + node->data.text, node->width); + else { + if (above(node->y)) + need_scroll_up_button = 1; + else if (below(node->y)) + need_scroll_down_button = 1; + } + break; + + case Verbatim: + push_group_stack(); + tt_top_group(); + if (visible(node->y, node->height)) + XDrawString(gXDisplay, gWindow->fDisplayedWindow, gWindow->fStandardGC, node->x, node->y + + gRegionOffset - gTopOfGroupStack->cur_font->descent + y_off, + node->data.text, node->width); + else { + if (above(node->y)) + need_scroll_up_button = 1; + else if (below(node->y)) + need_scroll_down_button = 1; + } + pop_group_stack(); + break; + + case Horizontalline: + if (visible(node->y, node->height)) { + line_top_group(); + XDrawLine(gXDisplay, gWindow->fDisplayedWindow, gWindow->fStandardGC, 0, + node->y + gRegionOffset + y_off, + gWindow->width, + node->y + gRegionOffset + y_off); + pop_group_stack(); + } + else { + if (above(node->y)) + need_scroll_up_button = 1; + else if (below(node->y)) + need_scroll_down_button = 1; + } + break; + + case Box: + if (visible(node->y, node->height)) + XDrawRectangle(gXDisplay, gWindow->fDisplayedWindow, gWindow->fStandardGC, + node->x, + node->y + gRegionOffset + y_off - node->height, + node->width, + node->height); + else { + if (above(node->y)) + need_scroll_up_button = 1; + else if (below(node->y)) + need_scroll_down_button = 1; + } + break; + + + case Downlink: + case Link: + case LispDownLink: + case LispMemoLink: + case Lispcommand: + case Lispcommandquit: + case Lisplink: + case Lispwindowlink: + case Memolink: + case Qspadcall: + case Qspadcallquit: + case Returnbutton: + case Spadcall: + case Spadcallquit: + case Spaddownlink: + case Spadlink: + case Spadmemolink: + case Unixcommand: + case Unixlink: + case Upbutton: + case Windowlink: + if (pix_visible(node->y, node->height)) + show_link(node); + break; + + case Spadcommand: + case Spadgraph: + case Spadsrc: + show_spadcommand(node); + break; + + case Pastebutton: + if (visible(node->y, node->height)) + show_pastebutton(node); + break; + + case Paste: + show_paste(node); + break; + + case Group: + case Tableitem: + push_group_stack(); + break; + + case Controlbitmap: + show_image(node, gWindow->fControlGC); + break; + + case Inputbitmap: + show_image(node, gWindow->fStandardGC); + break; + + case Inputpixmap: + show_image(node, gWindow->fStandardGC); + break; + + case BoldFace: + bf_top_group(); + break; + + case Emphasize: + if (gTopOfGroupStack->cur_font == gRmFont) + em_top_group(); + else + rm_top_group(); + break; + + case It: + em_top_group(); + break; + + case Sl: + case Rm: + rm_top_group(); + break; + + case Tt: + tt_top_group(); + break; + + case Inputstring: + show_input(node); + break; + + case Radiobox: + case SimpleBox: + show_simple_box(node); + break; + + case Beep: + LoudBeepAtTheUser(); + break; + + case Description: + bf_top_group(); + break; + + case Endspadsrc: + case Endspadcommand: + gInAxiomCommand = 1; + case Endtableitem: + case Enddescription: + case Endpastebutton: + case Endlink: + case Endbutton: + case Endgroup: + pop_group_stack(); + case Endverbatim: + case Endmath: + case Endbox: + case Endtable: + case Endmbox: + case Endparameter: + case Endpaste: + case Endinputbox: + case Endcenter: + case Endmacro: + case Endif: + case Endtitems: + case Enditems: + + /* + * Now since I can show specific regions of the text, then at + * this point I should check to see if I am the end + */ + if (node->type == Ender) + return; + break; + case Endfooter: + case Endscrolling: + case Endheader: + case Endtitle: + + /* + * regardless of what ender I have, I always terminate showing + * with one of these + */ + return; + default: + fprintf(stderr, "Show_text: Unknown Node Type %d\n", node->type); + break; + } + } +} + +static void +show_link(TextNode *node) +{ + /* XFontStruct *old_font;*/ + XWindowChanges wc; + /*int twidth, boxwidth, old_color;*/ + int active; + + switch (node->type) { + case Upbutton: + if (!need_up_button) { + XClearArea(gXDisplay, gWindow->fDisplayedWindow, node->x, + node->y - node->height + gRegionOffset, + node->width, node->height, 0); + active = 0; + } + else + active = 1; + break; + case Returnbutton: + if (!need_return_button) { + XClearArea(gXDisplay, gWindow->fDisplayedWindow, node->x, + node->y - node->height + gRegionOffset, + node->width, node->height, 0); + active = 0; + } + else + active = 1; + break; + case Helpbutton: + if (!need_help_button) { + XClearArea(gXDisplay, gWindow->fDisplayedWindow, node->x, + node->y - node->height + gRegionOffset, + node->width, node->height, 0); + active = 0; + } + else + active = 1; + break; + default: + active = 1; + break; + } + + if (active) { + ButtonList *bl = alloc_button_list(); + + push_active_group(); + wc.x = node->x; + wc.y = node->y - node->height + y_off + gRegionOffset; + wc.height = node->height; + wc.width = node->width - trailing_space(node->next); + bl->x0 = wc.x; + bl->y0 = wc.y; + bl->x1 = bl->x0 + wc.width; + bl->y1 = bl->y0 + wc.height; + bl->link = node->link; + if (!not_in_scroll) { + bl->y0 += gWindow->page->top_scroll_margin + scroll_top_margin; + bl->y1 += gWindow->page->top_scroll_margin + scroll_top_margin; + bl->next = gWindow->page->s_button_list; + gWindow->page->s_button_list = bl; + } + else { + bl->next = gWindow->page->button_list; + gWindow->page->button_list = bl; + } + } + else + rm_top_group(); +} + +static void +show_paste(TextNode *node) +{ + PasteNode *paste; + + if (!(paste = (PasteNode *) hash_find(gWindow->fPasteHashTable, + node->data.text))) + return; + + /* + * Once I have got this far, then I had better save the current group + * stack and the item stack + */ + if (paste->group) + free_group_stack(paste->group); + paste->group = (GroupItem *) copy_group_stack(); + if (paste->item_stack) + free_item_stack(paste->item_stack); + paste->item_stack = (ItemStack *) copy_item_stack(); +} + +static void +show_pastebutton(TextNode *node) +{ + /*XFontStruct *old_font;*/ + XWindowChanges wc; + /*int twidth, boxwidth, old_color;*/ + /*int active;*/ + + push_active_group(); + wc.x = node->x; + wc.y = node->y - node->height + y_off + gRegionOffset; + wc.height = node->height; + wc.width = node->width - trailing_space(node->next); +#ifdef DEBUG + fprintf(stderr, "Configure in show_link %d %d %d %d\n", + wc.x, wc.y, wc.width, wc.height); +#endif + XConfigureWindow(gXDisplay, node->link->win, + CWX | CWY | CWHeight | CWWidth, &wc); + XMapWindow(gXDisplay, node->link->win); +} + +/* display an input string window */ + +static void +show_input(TextNode *node) +{ + /*XFontStruct *old_font;*/ + XWindowChanges wc; + /*int twidth, boxwidth, old_color;*/ + /*Window root, child;*/ + /*int root_x, root_y, win_x, win_y, buttons;*/ + InputItem *item; + char *inpbuffer; + + item = node->link->reference.string; + inpbuffer = item->curr_line->buffer; + + wc.border_width = 0; + wc.x = node->x; + wc.y = node->y + gRegionOffset + y_off - node->height + 2; + wc.height = node->height - 2; + wc.width = node->width; + if (pix_visible(node->y, node->height)) { + XConfigureWindow(gXDisplay, node->link->win, + CWX | CWY | CWHeight | CWWidth | CWBorderWidth, + &wc); + XMapWindow(gXDisplay, node->link->win); + } + XFlush(gXDisplay); + draw_inputsymbol(item); +} + +static void +show_simple_box(TextNode *node) +{ + XWindowChanges wc; + InputBox *box; + + /* first configure the box size properly */ + box = node->link->reference.box; + wc.x = node->x; + wc.y = node->y + gRegionOffset + y_off - node->height; + wc.height = ((box->picked) ? + (box->selected->height) : (box->unselected->height)); + wc.width = node->width; + if (visible(node->y + gTopOfGroupStack->cur_font->ascent, node->height)) { + XConfigureWindow(gXDisplay, node->link->win, CWX | CWY | CWHeight | CWWidth, + &wc); + XMapWindow(gXDisplay, node->link->win); + if (box->picked) + pick_box(box); + else + unpick_box(box); + } +} + +/* display a spad command node */ + +static void +show_spadcommand(TextNode *node) +{ + XWindowChanges wc; + + gInAxiomCommand = 1; + + push_spad_group(); + wc.x = node->x; + if (node->type == Spadsrc) + wc.y = node->y + gRegionOffset + y_off - 2 * node->height; + else + wc.y = node->y + gRegionOffset + y_off - node->height; + wc.height = node->height; + wc.width = node->width; +#ifdef DEBUG + fprintf(stderr, "Spadcommand configured %d x %d -- (%d, %d)\n", + wc.width, wc.height, wc.x, wc.y); +#endif + XConfigureWindow(gXDisplay, node->link->win, + CWX | CWY | CWHeight | CWWidth, &wc); + XMapWindow(gXDisplay, node->link->win); +} + + +/* display a pixmap */ + +static void +show_image(TextNode *node, GC gc) +{ + int src_x, src_y, src_width, src_height, dest_x, dest_y, ret_val; + + if (!pix_visible(node->y, node->height)) + return; + if (node->image.xi == NULL) + return; + + dest_x = node->x; + src_x = 0; + src_y = 0; + dest_y = node->y + gRegionOffset - node->height + y_off; + need_scroll_up_button = 1; + if (node->width > (right_margin - node->x)) + src_width = right_margin - node->x; + else + src_width = node->width; + + if (gDisplayRegion != Scrolling) { + src_y = 0; + src_height = node->image.xi->height; + } + else { + /* I may have only a partial image */ + if (dest_y < 0) { /* the top is cut off */ + src_y = -dest_y; + dest_y = 0; + src_height = node->image.xi->height - src_y; + } + else if (dest_y + node->image.xi->height > gWindow->scrollheight) { + /* the bottom is cut off */ + src_y = 0; + src_height = gWindow->scrollheight - dest_y; + } + else { /* the whole thing is visible */ + src_y = 0; + src_height = node->image.xi->height; + } + } + + ret_val = XPutImage(gXDisplay, gWindow->fDisplayedWindow, gc, + node->image.xi, src_x, src_y, dest_x, dest_y, + src_width, src_height); + + switch (ret_val) { + case BadDrawable: + fprintf(stderr, "(HyperDoc: show_image) bad drawable\n"); + break; + case BadGC: + fprintf(stderr, "(HyperDoc: show_image) bad GC"); + break; + case BadMatch: + fprintf(stderr, "(HyperDoc: show_image) bad match"); + break; + case BadValue: +#ifndef HP9platform + fprintf(stderr, "(HyperDoc: show_image) bad value"); +#endif /* HP complains about this*/ + break; + } +} diff --git a/src/hyper/show-types.pamphlet b/src/hyper/show-types.pamphlet deleted file mode 100644 index 4bb68ae9..00000000 --- a/src/hyper/show-types.pamphlet +++ /dev/null @@ -1,639 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/show-types} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{show-types.h} -<>= -<> -#ifndef _SHOW_TYPES_H_ -#define _SHOW_TYPES_H_ 1 - -#include "hyper.h" - -#endif -@ -\section{show-types.c} -<>= -/****************************************************************************** - * - * show_types.c: Show the various types of things that can show up in text - * - * Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993. - * - ****************************************************************************/ -#define _SHOW_TYPES_C -#include "axiom-c-macros.h" -#include "useproto.h" -#include "debug.h" - - -#include "show-types.h" -#include "dialog.h" -#include "display.h" -#include "extent.h" -#include "group.h" -#include "mem.h" - -#include "all_hyper_proto.H1" - - - -/* - * Display the page whose extent has been computed, using the actual size of - * the window, and y_off to determine clipped areas - */ - -void -show_text(TextNode *node, int Ender) -{ - /*int twidth, len;*/ - /*int otext_x, otext_y, t;*/ - /*XFontStruct *old_font;*/ - /*int old_color;*/ - - for (; node != NULL; node = node->next) { - switch (node->type) { - case 0: - case Beginitems: - case Begintitems: - case Bound: - case Center: - case Free: - case HSpace: - case Indent: - case Indentrel: - case Item: - case Macro: - case Mbox: - case Newline: - case Noop: - case Par: - case Pound: - case Rbrace: - case Space: - case Tab: - case Table: - case Titem: - case VSpace: - break; - - case Dash: - case Fi: - case Ifcond: - if (visible(node->y, node->height)) { - if (strlen(node->data.text) > 1) { - XDrawLine(gXDisplay, gWindow->fDisplayedWindow, gWindow->fStandardGC, node->x, - node->y + gRegionOffset + y_off - - gTopOfGroupStack->cur_font->descent - - word_off_height, - node->x + node->width, - node->y + gRegionOffset + y_off - word_off_height - - gTopOfGroupStack->cur_font->descent); - } - else { - XDrawString(gXDisplay, gWindow->fDisplayedWindow, gWindow->fStandardGC, node->x, node->y + - gRegionOffset - gTopOfGroupStack->cur_font->descent + y_off, - node->data.text, 1); - } - } - else { - if (above(node->y)) - need_scroll_up_button = 1; - else if (below(node->y)) - need_scroll_down_button = 1; - } - break; - - case Lsquarebrace: - case Math: - case Punctuation: - case Rsquarebrace: - case Spadsrctxt: - case WindowId: - case Word: - if (visible(node->y, node->height)) - XDrawString(gXDisplay, gWindow->fDisplayedWindow, gWindow->fStandardGC, node->x, node->y + - gRegionOffset - gTopOfGroupStack->cur_font->descent + y_off, - node->data.text, node->width); - else { - if (above(node->y)) - need_scroll_up_button = 1; - else if (below(node->y)) - need_scroll_down_button = 1; - } - break; - - case Verbatim: - push_group_stack(); - tt_top_group(); - if (visible(node->y, node->height)) - XDrawString(gXDisplay, gWindow->fDisplayedWindow, gWindow->fStandardGC, node->x, node->y + - gRegionOffset - gTopOfGroupStack->cur_font->descent + y_off, - node->data.text, node->width); - else { - if (above(node->y)) - need_scroll_up_button = 1; - else if (below(node->y)) - need_scroll_down_button = 1; - } - pop_group_stack(); - break; - - case Horizontalline: - if (visible(node->y, node->height)) { - line_top_group(); - XDrawLine(gXDisplay, gWindow->fDisplayedWindow, gWindow->fStandardGC, 0, - node->y + gRegionOffset + y_off, - gWindow->width, - node->y + gRegionOffset + y_off); - pop_group_stack(); - } - else { - if (above(node->y)) - need_scroll_up_button = 1; - else if (below(node->y)) - need_scroll_down_button = 1; - } - break; - - case Box: - if (visible(node->y, node->height)) - XDrawRectangle(gXDisplay, gWindow->fDisplayedWindow, gWindow->fStandardGC, - node->x, - node->y + gRegionOffset + y_off - node->height, - node->width, - node->height); - else { - if (above(node->y)) - need_scroll_up_button = 1; - else if (below(node->y)) - need_scroll_down_button = 1; - } - break; - - - case Downlink: - case Link: - case LispDownLink: - case LispMemoLink: - case Lispcommand: - case Lispcommandquit: - case Lisplink: - case Lispwindowlink: - case Memolink: - case Qspadcall: - case Qspadcallquit: - case Returnbutton: - case Spadcall: - case Spadcallquit: - case Spaddownlink: - case Spadlink: - case Spadmemolink: - case Unixcommand: - case Unixlink: - case Upbutton: - case Windowlink: - if (pix_visible(node->y, node->height)) - show_link(node); - break; - - case Spadcommand: - case Spadgraph: - case Spadsrc: - show_spadcommand(node); - break; - - case Pastebutton: - if (visible(node->y, node->height)) - show_pastebutton(node); - break; - - case Paste: - show_paste(node); - break; - - case Group: - case Tableitem: - push_group_stack(); - break; - - case Controlbitmap: - show_image(node, gWindow->fControlGC); - break; - - case Inputbitmap: - show_image(node, gWindow->fStandardGC); - break; - - case Inputpixmap: - show_image(node, gWindow->fStandardGC); - break; - - case BoldFace: - bf_top_group(); - break; - - case Emphasize: - if (gTopOfGroupStack->cur_font == gRmFont) - em_top_group(); - else - rm_top_group(); - break; - - case It: - em_top_group(); - break; - - case Sl: - case Rm: - rm_top_group(); - break; - - case Tt: - tt_top_group(); - break; - - case Inputstring: - show_input(node); - break; - - case Radiobox: - case SimpleBox: - show_simple_box(node); - break; - - case Beep: - LoudBeepAtTheUser(); - break; - - case Description: - bf_top_group(); - break; - - case Endspadsrc: - case Endspadcommand: - gInAxiomCommand = 1; - case Endtableitem: - case Enddescription: - case Endpastebutton: - case Endlink: - case Endbutton: - case Endgroup: - pop_group_stack(); - case Endverbatim: - case Endmath: - case Endbox: - case Endtable: - case Endmbox: - case Endparameter: - case Endpaste: - case Endinputbox: - case Endcenter: - case Endmacro: - case Endif: - case Endtitems: - case Enditems: - - /* - * Now since I can show specific regions of the text, then at - * this point I should check to see if I am the end - */ - if (node->type == Ender) - return; - break; - case Endfooter: - case Endscrolling: - case Endheader: - case Endtitle: - - /* - * regardless of what ender I have, I always terminate showing - * with one of these - */ - return; - default: - fprintf(stderr, "Show_text: Unknown Node Type %d\n", node->type); - break; - } - } -} - -static void -show_link(TextNode *node) -{ - /* XFontStruct *old_font;*/ - XWindowChanges wc; - /*int twidth, boxwidth, old_color;*/ - int active; - - switch (node->type) { - case Upbutton: - if (!need_up_button) { - XClearArea(gXDisplay, gWindow->fDisplayedWindow, node->x, - node->y - node->height + gRegionOffset, - node->width, node->height, 0); - active = 0; - } - else - active = 1; - break; - case Returnbutton: - if (!need_return_button) { - XClearArea(gXDisplay, gWindow->fDisplayedWindow, node->x, - node->y - node->height + gRegionOffset, - node->width, node->height, 0); - active = 0; - } - else - active = 1; - break; - case Helpbutton: - if (!need_help_button) { - XClearArea(gXDisplay, gWindow->fDisplayedWindow, node->x, - node->y - node->height + gRegionOffset, - node->width, node->height, 0); - active = 0; - } - else - active = 1; - break; - default: - active = 1; - break; - } - - if (active) { - ButtonList *bl = alloc_button_list(); - - push_active_group(); - wc.x = node->x; - wc.y = node->y - node->height + y_off + gRegionOffset; - wc.height = node->height; - wc.width = node->width - trailing_space(node->next); - bl->x0 = wc.x; - bl->y0 = wc.y; - bl->x1 = bl->x0 + wc.width; - bl->y1 = bl->y0 + wc.height; - bl->link = node->link; - if (!not_in_scroll) { - bl->y0 += gWindow->page->top_scroll_margin + scroll_top_margin; - bl->y1 += gWindow->page->top_scroll_margin + scroll_top_margin; - bl->next = gWindow->page->s_button_list; - gWindow->page->s_button_list = bl; - } - else { - bl->next = gWindow->page->button_list; - gWindow->page->button_list = bl; - } - } - else - rm_top_group(); -} - -static void -show_paste(TextNode *node) -{ - PasteNode *paste; - - if (!(paste = (PasteNode *) hash_find(gWindow->fPasteHashTable, - node->data.text))) - return; - - /* - * Once I have got this far, then I had better save the current group - * stack and the item stack - */ - if (paste->group) - free_group_stack(paste->group); - paste->group = (GroupItem *) copy_group_stack(); - if (paste->item_stack) - free_item_stack(paste->item_stack); - paste->item_stack = (ItemStack *) copy_item_stack(); -} - -static void -show_pastebutton(TextNode *node) -{ - /*XFontStruct *old_font;*/ - XWindowChanges wc; - /*int twidth, boxwidth, old_color;*/ - /*int active;*/ - - push_active_group(); - wc.x = node->x; - wc.y = node->y - node->height + y_off + gRegionOffset; - wc.height = node->height; - wc.width = node->width - trailing_space(node->next); -#ifdef DEBUG - fprintf(stderr, "Configure in show_link %d %d %d %d\n", - wc.x, wc.y, wc.width, wc.height); -#endif - XConfigureWindow(gXDisplay, node->link->win, - CWX | CWY | CWHeight | CWWidth, &wc); - XMapWindow(gXDisplay, node->link->win); -} - -/* display an input string window */ - -static void -show_input(TextNode *node) -{ - /*XFontStruct *old_font;*/ - XWindowChanges wc; - /*int twidth, boxwidth, old_color;*/ - /*Window root, child;*/ - /*int root_x, root_y, win_x, win_y, buttons;*/ - InputItem *item; - char *inpbuffer; - - item = node->link->reference.string; - inpbuffer = item->curr_line->buffer; - - wc.border_width = 0; - wc.x = node->x; - wc.y = node->y + gRegionOffset + y_off - node->height + 2; - wc.height = node->height - 2; - wc.width = node->width; - if (pix_visible(node->y, node->height)) { - XConfigureWindow(gXDisplay, node->link->win, - CWX | CWY | CWHeight | CWWidth | CWBorderWidth, - &wc); - XMapWindow(gXDisplay, node->link->win); - } - XFlush(gXDisplay); - draw_inputsymbol(item); -} - -static void -show_simple_box(TextNode *node) -{ - XWindowChanges wc; - InputBox *box; - - /* first configure the box size properly */ - box = node->link->reference.box; - wc.x = node->x; - wc.y = node->y + gRegionOffset + y_off - node->height; - wc.height = ((box->picked) ? - (box->selected->height) : (box->unselected->height)); - wc.width = node->width; - if (visible(node->y + gTopOfGroupStack->cur_font->ascent, node->height)) { - XConfigureWindow(gXDisplay, node->link->win, CWX | CWY | CWHeight | CWWidth, - &wc); - XMapWindow(gXDisplay, node->link->win); - if (box->picked) - pick_box(box); - else - unpick_box(box); - } -} - -/* display a spad command node */ - -static void -show_spadcommand(TextNode *node) -{ - XWindowChanges wc; - - gInAxiomCommand = 1; - - push_spad_group(); - wc.x = node->x; - if (node->type == Spadsrc) - wc.y = node->y + gRegionOffset + y_off - 2 * node->height; - else - wc.y = node->y + gRegionOffset + y_off - node->height; - wc.height = node->height; - wc.width = node->width; -#ifdef DEBUG - fprintf(stderr, "Spadcommand configured %d x %d -- (%d, %d)\n", - wc.width, wc.height, wc.x, wc.y); -#endif - XConfigureWindow(gXDisplay, node->link->win, - CWX | CWY | CWHeight | CWWidth, &wc); - XMapWindow(gXDisplay, node->link->win); -} - - -/* display a pixmap */ - -static void -show_image(TextNode *node, GC gc) -{ - int src_x, src_y, src_width, src_height, dest_x, dest_y, ret_val; - - if (!pix_visible(node->y, node->height)) - return; - if (node->image.xi == NULL) - return; - - dest_x = node->x; - src_x = 0; - src_y = 0; - dest_y = node->y + gRegionOffset - node->height + y_off; - need_scroll_up_button = 1; - if (node->width > (right_margin - node->x)) - src_width = right_margin - node->x; - else - src_width = node->width; - - if (gDisplayRegion != Scrolling) { - src_y = 0; - src_height = node->image.xi->height; - } - else { - /* I may have only a partial image */ - if (dest_y < 0) { /* the top is cut off */ - src_y = -dest_y; - dest_y = 0; - src_height = node->image.xi->height - src_y; - } - else if (dest_y + node->image.xi->height > gWindow->scrollheight) { - /* the bottom is cut off */ - src_y = 0; - src_height = gWindow->scrollheight - dest_y; - } - else { /* the whole thing is visible */ - src_y = 0; - src_height = node->image.xi->height; - } - } - - ret_val = XPutImage(gXDisplay, gWindow->fDisplayedWindow, gc, - node->image.xi, src_x, src_y, dest_x, dest_y, - src_width, src_height); - - switch (ret_val) { - case BadDrawable: - fprintf(stderr, "(HyperDoc: show_image) bad drawable\n"); - break; - case BadGC: - fprintf(stderr, "(HyperDoc: show_image) bad GC"); - break; - case BadMatch: - fprintf(stderr, "(HyperDoc: show_image) bad match"); - break; - case BadValue: -#ifndef HP9platform - fprintf(stderr, "(HyperDoc: show_image) bad value"); -#endif /* HP complains about this*/ - break; - } -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/spadbuf.c b/src/hyper/spadbuf.c new file mode 100644 index 00000000..46f6dbd4 --- /dev/null +++ b/src/hyper/spadbuf.c @@ -0,0 +1,258 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +#define _SPADBUF_C +#include "axiom-c-macros.h" +#include "useproto.h" +#include "debug.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef SGIplatform +#include +#endif + +#include "bsdsignal.h" +#include "edible.h" +#include "com.h" + +#include "spadbuf.H1" +#include "bsdsignal.H1" +#include "sockio-c.H1" +#include "edin.H1" +#include "wct.H1" +#include "prt.H1" +#include "cursor.H1" +#include "fnct_key.H1" + + + +unsigned char _INTR, _QUIT, _ERASE, _KILL, _EOF, _EOL, _RES1, _RES2; +int contNum; /* do reading and all the other fun stuff + * depend on this for all there ioctl's */ +int num_read; + +/* + * Here are the term structures I need for setting and resetting the terminal + * characteristics. + */ +struct termios oldbuf; /* the initial settings */ +struct termios canonbuf; /* set it to be canonical */ +struct termios childbuf; + +short INS_MODE; /* Flag for insert mode */ +short ECHOIT; /* Flag for echoing */ +short PTY; +int MODE; /* Am I in cbreak, raw, or canonical */ + +char in_buff[1024]; /* buffer for storing characters read + until they are processed */ +char buff[MAXLINE]; /* Buffers for collecting input and */ +int buff_flag[MAXLINE]; /* flags for whether buff chars + are printing or non-printing */ +int (*old_handler) (); +Sock *session_sock, *menu_sock; +char *buff_name = NULL; /* name for the aixterm */ + +/* + * This routine used to be used to send sigint onto spad, but now they go + * through just fine on their own reinstated for AIX V3.2 + */ + +static void +spadbuf_inter_handler(int sig) +{ + send_signal(session_sock, SIGUSR2); +} + +static void +spadbuf_function_chars(void) +{ + /** once I have that get the special characters ****/ + _INTR = oldbuf.c_cc[VINTR]; + _QUIT = oldbuf.c_cc[VQUIT]; + _ERASE = oldbuf.c_cc[VERASE]; + _KILL = oldbuf.c_cc[VKILL]; + _EOF = oldbuf.c_cc[VEOF]; + _EOL = oldbuf.c_cc[VEOL]; + return; +} + +/* act as terminal session for sock connected to stdin + and stdout of another process */ +static void +interp_io(void) +{ + char buf[1024]; + fd_set rd; + int len, command; + + while (1) { + FD_ZERO(&rd); + FD_SET(menu_sock->socket, &rd); + FD_SET(session_sock->socket, &rd); + FD_SET(1, &rd); + len = sselect(FD_SETSIZE, &rd, 0, 0, NULL); + if (len == -1) { + perror("stdio select"); + return; + } + if (FD_ISSET(session_sock->socket, &rd)) { + len = sread(session_sock, buf, 1024, "stdio"); + if (len == -1) + return; + else { + write(1, buf, len); + } + } + if (FD_ISSET(menu_sock->socket, &rd)) { + command = get_int(menu_sock); + switch (command) { + case -1: + exit(0); + case ReceiveInputLine: + get_string_buf(menu_sock, in_buff, 1024); + num_read = strlen(in_buff); + clear_buff(); + do_reading(); + break; + case TestLine: + break; + default: + break; + } + } + if (FD_ISSET(1, &rd)) { + num_read = read(0, in_buff, 1024); + do_reading(); + } + } +} + +static void +init_parent(void) +{ + + /** get the original termio settings, so I never have to check again **/ + if (tcgetattr(0,&oldbuf) == -1) { + perror("Clef Trying to get terms initial settings"); + exit(-1); + } + + /** get the settings for my different modes ***/ + if (tcgetattr(0,&canonbuf) == -1) { + perror("Clef Getting terminal settings"); + exit(-1); + } + + /*** set the buffer to read before an eoln is typed ***/ + canonbuf.c_lflag &= ~(ICANON | ECHO | ISIG); + canonbuf.c_lflag |= ISIG; + + /*** Accordingly tell it we want every character ***/ + canonbuf.c_cc[VMIN] = 1; /* we want every character */ + canonbuf.c_cc[VTIME] = 1; /* these may require tweaking */ + + if (tcsetattr(0, TCSAFLUSH, &canonbuf) == -1) { + perror("Spadbuf setting parent to canon"); + exit(0); + } + + /* + * This routine is in edin.c and sets the users preferences for function + * keys. In order to use it I have to set childbuf to be the same as + * oldbuf + */ + + + spadbuf_function_chars(); + INS_MODE = 0; + ECHOIT = 1; + Cursor_shape(2); +} + +int +main(int argc,char ** argv) +{ + /*int name_found;*/ + /*FILE *junk;*/ + FILE *fopen(); + + /* + * Modified on 6/13/90 for the command line completion abiltities of + * Since I am only calling this program from within spadint, I decided + * that the usage should be + * + * spadbuf page_name [completion_ files] + * + */ + if (argc < 2) { + fprintf(stderr, "Usage : spadbuf page_name [completion_files] \n"); + exit(-1); + } + buff_name = *++argv; + + while (*++argv) { + load_wct_file(*argv); + } + skim_wct(); + + session_sock = connect_to_local_server(SessionServer, InterpWindow, Forever); + menu_sock = connect_to_local_server(MenuServerName, InterpWindow, Forever); + + bsdSignal(SIGINT, spadbuf_inter_handler,RestartSystemCalls); + + /* + * set contNum so it is pointing down the socket to the childs + */ + contNum = session_sock->socket; + send_string(menu_sock, buff_name); + init_parent(); + define_function_keys(); + init_reader(); + PTY = 0; + interp_io(); + return(1); +} + + + diff --git a/src/hyper/spadbuf.pamphlet b/src/hyper/spadbuf.pamphlet deleted file mode 100644 index d50041cd..00000000 --- a/src/hyper/spadbuf.pamphlet +++ /dev/null @@ -1,286 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/spadbuf} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{spadbuf.c} -<>= -#define _SPADBUF_C -#include "axiom-c-macros.h" -#include "useproto.h" -#include "debug.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef SGIplatform -#include -#endif - -#include "bsdsignal.h" -#include "edible.h" -#include "com.h" - -#include "spadbuf.H1" -#include "bsdsignal.H1" -#include "sockio-c.H1" -#include "edin.H1" -#include "wct.H1" -#include "prt.H1" -#include "cursor.H1" -#include "fnct_key.H1" - - - -unsigned char _INTR, _QUIT, _ERASE, _KILL, _EOF, _EOL, _RES1, _RES2; -int contNum; /* do reading and all the other fun stuff - * depend on this for all there ioctl's */ -int num_read; - -/* - * Here are the term structures I need for setting and resetting the terminal - * characteristics. - */ -struct termios oldbuf; /* the initial settings */ -struct termios canonbuf; /* set it to be canonical */ -struct termios childbuf; - -short INS_MODE; /* Flag for insert mode */ -short ECHOIT; /* Flag for echoing */ -short PTY; -int MODE; /* Am I in cbreak, raw, or canonical */ - -char in_buff[1024]; /* buffer for storing characters read - until they are processed */ -char buff[MAXLINE]; /* Buffers for collecting input and */ -int buff_flag[MAXLINE]; /* flags for whether buff chars - are printing or non-printing */ -int (*old_handler) (); -Sock *session_sock, *menu_sock; -char *buff_name = NULL; /* name for the aixterm */ - -/* - * This routine used to be used to send sigint onto spad, but now they go - * through just fine on their own reinstated for AIX V3.2 - */ - -static void -spadbuf_inter_handler(int sig) -{ - send_signal(session_sock, SIGUSR2); -} - -static void -spadbuf_function_chars(void) -{ - /** once I have that get the special characters ****/ - _INTR = oldbuf.c_cc[VINTR]; - _QUIT = oldbuf.c_cc[VQUIT]; - _ERASE = oldbuf.c_cc[VERASE]; - _KILL = oldbuf.c_cc[VKILL]; - _EOF = oldbuf.c_cc[VEOF]; - _EOL = oldbuf.c_cc[VEOL]; - return; -} - -/* act as terminal session for sock connected to stdin - and stdout of another process */ -static void -interp_io(void) -{ - char buf[1024]; - fd_set rd; - int len, command; - - while (1) { - FD_ZERO(&rd); - FD_SET(menu_sock->socket, &rd); - FD_SET(session_sock->socket, &rd); - FD_SET(1, &rd); - len = sselect(FD_SETSIZE, &rd, 0, 0, NULL); - if (len == -1) { - perror("stdio select"); - return; - } - if (FD_ISSET(session_sock->socket, &rd)) { - len = sread(session_sock, buf, 1024, "stdio"); - if (len == -1) - return; - else { - write(1, buf, len); - } - } - if (FD_ISSET(menu_sock->socket, &rd)) { - command = get_int(menu_sock); - switch (command) { - case -1: - exit(0); - case ReceiveInputLine: - get_string_buf(menu_sock, in_buff, 1024); - num_read = strlen(in_buff); - clear_buff(); - do_reading(); - break; - case TestLine: - break; - default: - break; - } - } - if (FD_ISSET(1, &rd)) { - num_read = read(0, in_buff, 1024); - do_reading(); - } - } -} - -static void -init_parent(void) -{ - - /** get the original termio settings, so I never have to check again **/ - if (tcgetattr(0,&oldbuf) == -1) { - perror("Clef Trying to get terms initial settings"); - exit(-1); - } - - /** get the settings for my different modes ***/ - if (tcgetattr(0,&canonbuf) == -1) { - perror("Clef Getting terminal settings"); - exit(-1); - } - - /*** set the buffer to read before an eoln is typed ***/ - canonbuf.c_lflag &= ~(ICANON | ECHO | ISIG); - canonbuf.c_lflag |= ISIG; - - /*** Accordingly tell it we want every character ***/ - canonbuf.c_cc[VMIN] = 1; /* we want every character */ - canonbuf.c_cc[VTIME] = 1; /* these may require tweaking */ - - if (tcsetattr(0, TCSAFLUSH, &canonbuf) == -1) { - perror("Spadbuf setting parent to canon"); - exit(0); - } - - /* - * This routine is in edin.c and sets the users preferences for function - * keys. In order to use it I have to set childbuf to be the same as - * oldbuf - */ - - - spadbuf_function_chars(); - INS_MODE = 0; - ECHOIT = 1; - Cursor_shape(2); -} - -int -main(int argc,char ** argv) -{ - /*int name_found;*/ - /*FILE *junk;*/ - FILE *fopen(); - - /* - * Modified on 6/13/90 for the command line completion abiltities of - * Since I am only calling this program from within spadint, I decided - * that the usage should be - * - * spadbuf page_name [completion_ files] - * - */ - if (argc < 2) { - fprintf(stderr, "Usage : spadbuf page_name [completion_files] \n"); - exit(-1); - } - buff_name = *++argv; - - while (*++argv) { - load_wct_file(*argv); - } - skim_wct(); - - session_sock = connect_to_local_server(SessionServer, InterpWindow, Forever); - menu_sock = connect_to_local_server(MenuServerName, InterpWindow, Forever); - - bsdSignal(SIGINT, spadbuf_inter_handler,RestartSystemCalls); - - /* - * set contNum so it is pointing down the socket to the childs - */ - contNum = session_sock->socket; - send_string(menu_sock, buff_name); - init_parent(); - define_function_keys(); - init_reader(); - PTY = 0; - interp_io(); - return(1); -} - - - -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/spadint.c b/src/hyper/spadint.c new file mode 100644 index 00000000..eb90c2fa --- /dev/null +++ b/src/hyper/spadint.c @@ -0,0 +1,1259 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +/* Still a problem with close_client */ + +/* Communication interface for external AXIOM buffers */ +#define _SPADINT_C +#include "axiom-c-macros.h" +#include "useproto.h" +#include "debug.h" + +#include + +#include "hyper.h" +#include "parse.h" +#include "bsdsignal.h" + +#include "all_hyper_proto.H1" +#include "sockio-c.H1" +#include "bsdsignal.H1" + + +typedef struct sock_list { /* linked list of Sock */ + Sock Socket; + struct sock_list *next; +} Sock_List; + +Sock_List *plSock = (Sock_List *) 0; +Sock *spad_socket = (Sock *) 0; /* to_server socket for SpadServer */ + +/* issue a AXIOM command to the buffer associated with a page */ +void +issue_spadcommand(HyperDocPage *page, TextNode *command, int immediate, + int type) +{ + char *buf; + int ret_val; + + ret_val = connect_spad(); + if (ret_val == NotConnected || ret_val == SpadBusy) + return; + + if (page->sock == NULL) + start_user_buffer(page); + ret_val = send_int(page->sock, TestLine); + if (ret_val == -1) { + page->sock = NULL; + clear_execution_marks(page->depend_hash); + issue_spadcommand(page, command, immediate, type); + return; + } + issue_dependent_commands(page, command, type); + ret_val = send_int(page->sock, ReceiveInputLine); + buf = print_to_string(command); + if (immediate) { + buf[strlen(buf) + 1] = '\0'; + buf[strlen(buf)] = '\n'; + } + if (type == Spadsrc) + send_pile(page->sock, buf); + else + send_string(page->sock, buf); + mark_as_executed(page, command, type); + gIsEndOfOutput = 0; +} +static void +send_pile(Sock *sock,char * str) +{ + FILE *f; + char name[512], command[512]; + + sprintf(name, "/tmp/hyper%s.input", getenv("SPADNUM")); + f = fopen(name, "w"); + if (f == NULL) { + fprintf(stderr, "Can't open temporary input file %s\n", name); + return; + } + fprintf(f, "%s", str); + fclose(f); + sprintf(command, ")read %s\n", name); + send_string(sock, command); +} +static void +issue_dependent_commands(HyperDocPage *page, TextNode *command,int type) +{ + TextNode *node, *depend_label; + SpadcomDepend *depend; + int end_type = (type == Spadcommand || type == Spadgraph) ? + (Endspadcommand) : (Endspadsrc); + + for (node = command->next; node->type != end_type; + node = node->next) + if (node->type == Free) + for (depend_label = node->data.node; depend_label != NULL; + depend_label = depend_label->next) + if (depend_label->type == Word) { + depend = (SpadcomDepend *) + hash_find(page->depend_hash, depend_label->data.text); + if (depend == NULL) { + fprintf(stderr, "Error: dependency on undefined label: %s\n", + depend_label->data.text); + continue; + } + if (!depend->executed) { + issue_spadcommand(page, depend->spadcom->next, 1, + depend->spadcom->type); + while (!gIsEndOfOutput) + pause(); + sleep(1); + } + } +} +static void +mark_as_executed(HyperDocPage *page, TextNode *command,int type) +{ + TextNode *node, *depend_label; + SpadcomDepend *depend; + int end_type = (type == Spadcommand || type == Spadgraph) + ? (Endspadcommand) : (Endspadsrc); + + for (node = command; node->type != end_type; node = node->next) + if (node->type == Bound) + for (depend_label = node->data.node; depend_label != NULL; + depend_label = depend_label->next) + if (depend_label->type == Word) { + depend = (SpadcomDepend *) + hash_find(page->depend_hash, depend_label->data.text); + if (depend == NULL) { + fprintf(stderr, "No dependency entry for label: %s\n", + depend_label->data.text); + continue; + } + depend->executed = 1; + } +} + +/* start a spad buffer for the page associated with the give */ +static void +start_user_buffer(HyperDocPage *page) +{ + char buf[1024], *title; + char *SPAD; + char spadbuf[250]; + char complfile[250]; + int ret_val; + + SPAD = (char *) getenv("AXIOM"); + if (SPAD == NULL) { + sprintf(SPAD, "/spad/mnt/rios"); + } + sprintf(spadbuf, "%s/lib/spadbuf", SPAD); + sprintf(complfile, "%s/lib/command.list", SPAD); + title = print_to_string(page->title); + if (access(complfile, R_OK) == 0) + + /* + * TTT says : why not invoke with "-name axiomclient" and set any + * defaults in the usual way + */ +#ifdef RIOSplatform + sprintf(buf, + "aixterm -sb -sl 500 -name axiomclient -n '%s' -T '%s' -e %s %s %s&", + title, title, spadbuf, page->name, complfile); + else + sprintf(buf, + "aixterm -sb -sl 500 -name axiomclient -n '%s' -T '%s' -e %s %s&", + title, title, spadbuf, page->name); +#else +#ifdef SUNplatform + sprintf(buf, + "xterm -sb -sl 500 -name axiomclient -n '%s' -T '%s' -e %s %s %s&", + title, title, spadbuf, page->name, complfile); + else + sprintf(buf, + "xterm -sb -sl 500 -name axiomclient -n '%s' -T '%s' -e %s %s&", + title, title, spadbuf, page->name); +#else + sprintf(buf, + "xterm -sb -sl 500 -name axiomclient -n '%s' -T '%s' -e %s %s %s&", + title, title, spadbuf, page->name, complfile); + else + sprintf(buf, + "xterm -sb -sl 500 -name axiomclient -n '%s' -T '%s' -e %s '%s'&", + title, title, spadbuf, page->name); +#endif +#endif + ret_val = system(buf); + if (ret_val == -1 || ret_val == 127) { + + /* + * perror("running the xterm spadbuf program"); exit(-1); + */ + } + accept_menu_server_connection(page); + sleep(2); +} + +/* Clears the execution marks in a hash table when a buffer has been killed */ +static void +clear_execution_marks(HashTable *depend_hash) +{ + int i; + HashEntry *h; + SpadcomDepend *depend; + + if (depend_hash == 0) + return; + for (i = 0; i < depend_hash->size; i++) + for (h = depend_hash->table[i]; h != NULL; h = h->next) { + depend = (SpadcomDepend *) h->data; + depend->executed = 0; + } +} + +Sock * +accept_menu_connection(Sock *server_sock) +{ + int sock_fd /*, session, ret_code*/; + Sock_List *pls; + /*Sock local_sock;*/ + + /* Could only be InterpWindow */ + + pls = (Sock_List *) halloc(sizeof(Sock_List),"SockList"); + sock_fd = accept(server_sock->socket, 0, 0); + if (sock_fd == -1) { + perror("session : accepting connection"); + return 0; + } + (pls->Socket).socket = sock_fd; + get_socket_type((Sock *) pls); + +#ifdef DEBUG + fprintf(stderr, + "session: accepted InterpWindow , fd = %d\n", sock_fd); +#endif + + + /* put new item at head of list */ + + if (plSock == (Sock_List *) 0) { + plSock = pls; + plSock->next = (Sock_List *) 0; + } + else { + pls->next = plSock; + plSock = pls; + } + + /* need to maintain socket_mask since we roll our own accept */ + + FD_SET(plSock->Socket.socket, &socket_mask); + return (Sock *) plSock; +} + +static void +accept_menu_server_connection(HyperDocPage *page) +{ + + /* + * TTT thinks this code should just provide a Sock to the page. The only + * client assumed is a spadbuf. Since spadbuf was invoked with the page + * name, it just passes it back here as a check (get_string line). + */ + int ret_code/*, i*/; + fd_set rd; + Sock *sock; + char *buf_name; + HyperDocPage *npage; + + if (page->sock != NULL) + return; + while (1) { + rd = server_mask; + ret_code = sselect(FD_SETSIZE, &rd, 0, 0, NULL); + if (ret_code == -1) { + perror("Session manager select"); + continue; + } + + if (server[1].socket > 0 && FD_ISSET(server[1].socket, &rd)) { + sock = accept_menu_connection(server + 1); + if (sock == 0) + return; + if (sock->purpose == InterpWindow) { + buf_name = get_string(sock); + npage = (HyperDocPage *) + hash_find(gWindow->fPageHashTable, buf_name); + if (npage == NULL) { + + /* + * Lets just try using the current page TTT doesn't know + * why this could be detrimental + * + * fprintf(stderr, "connecting spadbuf to unknown page: + * %s\n", buf_name); + */ + page->sock = sock; + return; + } + else { + + /* + * For some reason npage and page may be different TTT + * thinks this happens when a dynamic page has the same + * name as an existing static page. + */ + npage->sock = sock; + page->sock = sock; + } + if (!strcmp(buf_name, page->name)) { + return; + } + } + } + } +} + + +/* + * This procedure takes a HyperDoc node, and expands it into string + */ + +char *p2sBuf = NULL; +int p2sBufSize = 0; + +/* + * This routine takes a text node and creates a string out of it. This is for + * use with things such as spad commands. There are a very limited set of + * node types it can handle, so be careful + */ + +char * +print_to_string(TextNode *command) +{ + int len = 0; + + print_to_string1(command, &len); + p2sBuf = resizeBuffer(len, p2sBuf, &p2sBufSize); + return print_to_string1(command, NULL); +} + +/* +see the code in ht-util.boot + $funnyQuote := char 127 + $funnyBacks := char 128 +*/ +#define funnyEscape(c) ((c) == '"' ? '\177' : ((c) == '\\' ? '\200' : c)) +#define funnyUnescape(c) ((c) == '\177' ? '"' : ((c) == '\200' ? '\\' : c)) +#define storeChar(ch) if (sizeBuf) (*sizeBuf)++; else *c++ = (ch) +#define storeString(str) for (s=str;*s;s++) {storeChar(*s);} + +extern int include_bf; + +char * +print_to_string1(TextNode *command,int * sizeBuf) +{ + char *c = p2sBuf; + char *s; + InputItem *item; + LineStruct *curr_line; + int lcount; + InputBox *box; + int num_spaces; + int count; + TextNode *node; + + /* + * Init the stack of text nodes, things are pushed on here when I trace + * through a nodes data.node. This way I always no where my next is. + */ + + for (node = command; node != NULL;) { + switch (node->type) { + case Newline: + storeChar('\n'); + node = node->next; + break; + case Ifcond: + if (check_condition(node->data.ifnode->cond)) + node = node->data.ifnode->thennode; + else + node = node->data.ifnode->elsenode; + break; + case Endarg: + case Endspadcommand: + case Endspadsrc: + case Endpix: + storeChar('\0'); + return p2sBuf; + case Endverbatim: + case Endif: + case Fi: + case Endmacro: + case Endparameter: + case Rbrace: + case Endgroup: + node = node->next; + break; + case Punctuation: + + /* + * Simply copy the piece of text + */ + if (node->space & FRONTSPACE) { storeChar(' '); } + for (s = node->data.text; *s; s++) { storeChar(*s); } + node = node->next; + break; + case WindowId: + + /* + * Simply copy the piece of text + */ + if (node->space) { storeChar(' '); } + for (s = node->data.text; *s; s++) { storeChar(*s); } + storeChar(' '); + node = node->next; + break; + case Verbatim: + case Spadsrctxt: + + /* + * Simply copy the piece of text + */ + if (node->space) { storeChar(' '); } + for (s = node->data.text; *s; s++) { storeChar(*s); } + + /* + * now add the eol + */ + + /* + * if(node->next && node->next->type != Endspadsrc) + * storeChar('\n'); + */ + node = node->next; + break; + case Dash: + case Rsquarebrace: + case Lsquarebrace: + case Word: + + /* + * Simply copy the piece of text + */ + if (node->space) { storeChar(' '); } + for (s = node->data.text; *s; s++) { storeChar(*s); } + node = node->next; + break; + case BoxValue: + box = + (InputBox *) hash_find(gWindow->page->box_hash, node->data.text); + if (box == NULL) { + fprintf(stderr, + "Print_to_string:Box %s Has no symbol table entry\n", + node->data.text); + exit(-1); + } + storeChar(' '); + if (box->picked) { + storeChar('t'); + } + else { + storeChar('n'); + storeChar('i'); + storeChar('l'); + } + node = node->next; + break; + case StringValue: + item = return_item(node->data.text); + if (item != NULL) { + if (node->space) + storeChar(' '); + curr_line = item->lines; + while (curr_line != NULL) { + for (lcount = 0, s = curr_line->buffer; *s && lcount < item->size; + s++, lcount++) { + storeChar(funnyUnescape(*s)); + } + if (curr_line->len <= item->size && curr_line->next) + storeChar('\n'); + curr_line = curr_line->next; + } + } + else if ((box = (InputBox *) hash_find(gWindow->page->box_hash, + node->data.text)) != NULL) { + if (node->space) { storeChar(' '); } + if (box->picked) { + storeChar('t'); + } + else { + storeChar('n'); + storeChar('i'); + storeChar('l'); + } + } + else { + fprintf(stderr, "Error, Symbol %s has no symbol table entry\n", + node->data.text); + exit(-1); + } + node = node->next; + break; + case Space: + num_spaces = (node->data.node != NULL ? + atoi(node->data.node->data.text) : 1); + for (count = 0; count < num_spaces; count++) + storeChar(' '); + node = node->next; + break; + case Titlenode: + case Endtitle: + case Center: + case Endcenter: + case BoldFace: + case Emphasize: + case Indentrel: + node = node->next; + break; + case Bound: + if (include_bf) { + int len, i; + TextNode *n2 = node->data.node; + + storeChar('\\'); + storeChar('b'); + storeChar('o'); + storeChar('u'); + storeChar('n'); + storeChar('d'); + storeChar('{'); + for (; n2->type != Endarg; n2 = n2->next) { + if (n2->type == Word) { + len = strlen(n2->data.text); + for (i = 0; i < len; i++) + storeChar(n2->data.text[i]); + storeChar(' '); + } + } + storeChar('}'); + } + node = node->next; + break; + case Free: + if (include_bf) { + int len, i; + TextNode *n2 = node->data.node; + + storeChar('\\'); + storeChar('f'); + storeChar('r'); + storeChar('e'); + storeChar('e'); + storeChar('{'); + for (; n2->type != Endarg; n2 = n2->next) { + if (n2->type == Word) { + len = strlen(n2->data.text); + for (i = 0; i < len; i++) + storeChar(n2->data.text[i]); + storeChar(' '); + } + } + storeChar('}'); + } + node = node->next; + break; + case Macro: + node = node->next; + break; + case Pound: + if (node->space) { storeChar(' '); } + node = node->next; + break; + case Group: + node = node->next; + break; + case Indent: + num_spaces = (node->data.node != NULL ? + atoi(node->data.node->data.text) : 1); + for (count = 0; count < num_spaces; count++) + storeChar(' '); + node = node->next; + break; + default: + fprintf(stderr, + "Print_to_string: Unrecognized Keyword Type %d\n", + node->type); + node=node->next; + break; + } + } + storeChar('\0'); + return p2sBuf; +} + +/* + * Send a lisp or spad command to the AXIOM server for execution , if + * type is link, then we wait for a HyperDoc card to be returned + */ + +HyperDocPage * +issue_server_command(HyperLink *link) +{ + TextNode *command = (TextNode *) link->reference.node; + int ret_val; + char *buf; + HyperDocPage *page; + + ret_val = connect_spad(); + if (ret_val == NotConnected) { + page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, "SpadNotConnectedPage"); + if (page == NULL) + fprintf(stderr, "No SpadNotConnectedPage found\n"); + return page; + } + if (ret_val == SpadBusy) { + page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, "SpadBusyPage"); + if (page == NULL) + fprintf(stderr, "No SpadBusyPage found\n"); + return page; + } + switch_frames(); + switch (link->type) { + case Qspadcall: + case Qspadcallquit: + case Spadlink: + case Spaddownlink: + case Spadmemolink: + send_int(spad_socket, QuietSpadCommand); + break; + case Spadcall: + case Spadcallquit: + send_int(spad_socket, SpadCommand); + break; + default: + send_int(spad_socket, LispCommand); + break; + } + buf = print_to_string(command); + send_string(spad_socket, buf); + if (link->type == Lispcommand || link->type == Spadcall + || link->type == Spadcallquit || link->type == Qspadcallquit + || link->type == Qspadcall || link->type == Lispcommandquit) + return NULL; + page = parse_page_from_socket(); + return page; +} + +int +issue_serverpaste(TextNode *command) +{ + char *buf; + int ret_val; + + ret_val = connect_spad(); + if (ret_val == NotConnected || ret_val == SpadBusy) + return 1; + switch_frames(); + send_int(spad_socket, LispCommand); + buf = print_to_string(command); + send_string(spad_socket, buf); + return 1; +} + +/* + * issue a unix command + */ +void +issue_unixcommand(TextNode *node) +{ + char *buf; + char *copy; + + + buf = print_to_string(node); + copy =(char *) halloc((strlen(buf)+2)*sizeof(char),"Unixcommand"); + strcpy(copy,buf); + copy[strlen(buf) + 1] = '\0'; + copy[strlen(buf)] = '&'; + system(copy); + free(copy); + return; +} + +HyperDocPage * +issue_unixlink(TextNode *node) +{ + HyperDocPage *page; + char *buf; + + buf = print_to_string(node); + if ((unixfd = popen(buf, "r")) == NULL) { + fprintf(stderr, "Error popening %s\n", buf); + exit(-1); + } + bsdSignal(SIGUSR2,SIG_IGN,0); + page = parse_page_from_unixfd(); + bsdSignal(SIGUSR2,sigusr2_handler,0); + return page; +} + +int +issue_unixpaste(TextNode *node) +{ + char *buf; + + buf = print_to_string(node); + if ((unixfd = popen(buf, "r")) == NULL) { + fprintf(stderr, "Error popening %s\n", buf); + exit(-1); + } + return 1; +} + + +/* + * called when session_server selects + */ +void +service_session_socket(void) +{ + int cmd, pid; + + cmd = get_int(session_server); + switch (cmd) { + case CloseClient: + pid = get_int(session_server); + if (pid != -1) + close_client(pid); + break; + default: + fprintf(stderr, + "(HyperDoc) Unknown command from SessionServer %d\n", cmd); + break; + } +} + + +/* + * let spad know which frame to issue command via + */ +static void +switch_frames(void) +{ + if (session_server == NULL) { + fprintf(stderr, "(HyperDoc) No session manager connected!\n"); + return; + } + if (gWindow->fAxiomFrame == -1) { + fprintf(stderr, "(HyperDoc) No AXIOM frame associated with top level window!\n"); + return; + } + send_int(session_server, SwitchFrames); + send_int(session_server, gWindow->fAxiomFrame); +} +void +send_lisp_command(char *command) +{ + int ret_val; + + ret_val = connect_spad(); + if (ret_val == NotConnected || ret_val == SpadBusy) { + return; + } + send_int(spad_socket, LispCommand); + send_string(spad_socket, command); +} +void +escape_string(char *s) +{ + char *st; + + for (st = s; *st; st++) + *st = funnyEscape(*st); +} +void +unescape_string(char *s) +{ + char *st; + + for (st = s; *st; st++) + *st = funnyUnescape(*st); +} +static void +close_client(int pid) +{ + /*int i;*/ + Sock_List *pSock, *locSock; + + /* + * just need to drop the list item + */ + + if (plSock == (Sock_List *) 0) + return; + + /* + * first check head + */ + + if ((plSock->Socket.pid == pid)) { + locSock = plSock; + if ((*plSock).next == (Sock_List *) 0) { + plSock = (Sock_List *) 0; + } + else { + plSock = plSock->next; + } + free(locSock); + } + + /* + * now check the rest + */ + + else { + for (pSock = plSock; pSock->next != (Sock_List *) 0; pSock = pSock->next) + if (pSock->next->Socket.pid == pid) { + locSock = pSock->next; + if (pSock->next->next == (Sock_List *) 0) { + pSock->next = (Sock_List *) 0; + } + else { + pSock->next = pSock->next->next; + } + free(locSock); + break; + } + } +} + + + +char * +print_source_to_string(TextNode *command) +{ + int len = 0; + + print_source_to_string1(command, &len); + p2sBuf = resizeBuffer(len, p2sBuf, &p2sBufSize); + return print_source_to_string1(command, NULL); +} +char * +print_source_to_string1(TextNode *command,int * sizeBuf) +{ + char *c = p2sBuf; + char *s; + InputItem *item; + LineStruct *curr_line; + int lcount; + InputBox *box; + int num_spaces; + int count; + TextNode *node; + + /* + print out HyperDoc source for what you see + */ + + for (node = command; node != NULL;) { + switch (node->type) { + case Newline: + storeString("\\newline\n"); + node = node->next; + break; + case Par: + storeString("\n\n"); + node = node->next; + break; + case Indentrel: + storeString("\\indentrel{"); + storeString(node->data.node->data.text); + storeChar('}'); + node = node->next; + break; + case Tab: + storeString("\\tab{"); + storeString(node->data.node->data.text); + storeChar('}'); + node = node->next; + break; + case Ifcond: + if (check_condition(node->data.ifnode->cond)) + node = node->data.ifnode->thennode; + else + node = node->data.ifnode->elsenode; + break; + case Endarg: + case Endspadsrc: + case Endpix: + case Endbutton: + storeChar('}'); + node = node->next; + break; + case Endverbatim: + case Endif: + case Fi: + case Endmacro: + case Endparameter: + case Rbrace: + node = node->next; + break; + case Punctuation: + + /* + * Simply copy the piece of text + */ + if (node->space & FRONTSPACE) { storeChar(' '); } + for (s = node->data.text; *s; s++) { storeChar(*s); } + node = node->next; + break; + case WindowId: + storeString("\\windowid "); + node = node->next; + break; + case Verbatim: + case Spadsrctxt: + if (node->space) { storeChar(' '); } + for (s = node->data.text; *s; s++) { storeChar(*s); } + node = node->next; + break; + case Dash: + case Rsquarebrace: + case Lsquarebrace: + case Word: + if (node->space) { storeChar(' '); } + for (s = node->data.text; *s; s++) { storeChar(*s); } + node = node->next; + break; + case BoxValue: + box = (InputBox *) hash_find(gWindow->page->box_hash, node->data.text); + if (box == NULL) { + fprintf(stderr, "Print_to_string:Box %s Has no symbol table entry\n", + node->data.text); + exit(-1); + } + storeChar(' '); + if (box->picked) { + storeChar('t'); + } + else { + storeChar('n'); + storeChar('i'); + storeChar('l'); + } + node = node->next; + break; + case StringValue: + item = return_item(node->data.text); + if (item != NULL) { + if (node->space) { storeChar(' '); } + curr_line = item->lines; + while (curr_line != NULL) { + for (lcount = 0, s = curr_line->buffer; + *s && lcount < item->size; + s++, lcount++) { + storeChar(funnyUnescape(*s)); + } + if (curr_line->len <= item->size && curr_line->next) + storeChar('\n'); + curr_line = curr_line->next; + } + } + else if ((box = (InputBox *) hash_find(gWindow->page->box_hash, + node->data.text)) != NULL) { + if (node->space) { storeChar(' '); } + if (box->picked) { + storeChar('t'); + } + else { + storeChar('n'); + storeChar('i'); + storeChar('l'); + } + } + else { + fprintf(stderr, "Error, Symbol %s has no symbol table entry\n", + node->data.text); + exit(-1); + } + node = node->next; + break; + case Space: + num_spaces = (node->data.node != NULL ? + atoi(node->data.node->data.text) : 1); + for (count = 0; count < num_spaces; count++) + storeChar(' '); + node = node->next; + break; + case Emphasize: + storeString("\\em "); + node = node->next; + break; + case BoldFace: + storeString("\\bf "); + node = node->next; + break; + case Sl: + storeString("\\it "); + node = node->next; + break; + case Rm: + storeString("\\rm "); + node = node->next; + break; + case It: + storeString("\\it "); + node = node->next; + break; + case Tt: + storeString("\\tt "); + node = node->next; + break; + case Group: +/* skip {} */ + if (node->next->type==Endgroup){ + node=node->next->next; + break; + } + storeChar('{'); + node = node->next; + break; + case Endgroup: + storeChar('}'); + node = node->next; + break; + case Box: + storeString("\\box{"); + node = node->next; + break; + case Endbox: + storeChar('}'); + node = node->next; + break; + case Center: + storeString("\\center{"); + node = node->next; + break; + case Endcenter: + storeString("}"); + storeChar('\n'); + node = node->next; + break; + case Titlenode: + case Endtitle: + node = node->next; + break; + case Bound: + { + TextNode *n2 = node->data.node; + + storeString("\\bound{"); + for (; n2->type != Endarg; n2 = n2->next) { + if (n2->type == Word) { + storeString(n2->data.text); + storeChar(' '); + } + } + storeChar('}'); + } + node = node->next; + break; + case Free: + { + TextNode *n2 = node->data.node; + + storeString("\\free{"); + for (; n2->type != Endarg; n2 = n2->next) { + if (n2->type == Word) { + storeString(n2->data.text); + storeChar(' '); + } + } + storeChar('}'); + } + node = node->next; + break; + case Macro: + storeChar(' '); + node = node->next; + break; + case Pound: + if (node->space) { storeChar(' '); } + node = node->next; + break; + case Indent: + num_spaces = (node->data.node != NULL ? + atoi(node->data.node->data.text) : 1); + for (count = 0; count < num_spaces; count++) + storeChar(' '); + node = node->next; + break; + case Inputbitmap: + storeString("\\inputbitmap{"); + storeString(node->data.text); + storeString("}\n"); + node = node->next; + break; + case Endscrolling: + storeString("\\end{scroll}\n"); + node = node->next; + break; + case Scrollingnode: + storeString("\\begin{scroll}\n"); + storeString("% This is the scrolling area\n"); + node = node->next; + break; + case Horizontalline: + storeString("\\horizontalline\n"); + node = node->next; + break; + case Endtable: + storeChar('}'); + node = node->next; + break; + case Table: + storeString("\\table{"); + node = node->next; + break; + case Tableitem: + storeChar('{'); + node = node->next; + break; + case Endtableitem: + storeChar('}'); + node = node->next; + break; + case Beginitems: + storeString("\\begin{items}"); + node = node->next; + break; + case Item: + storeString("\n\\item"); + node = node->next; + break; + case Enditems: + storeString("\n\\end{items}"); + node = node->next; + break; +/*** LINKS ***/ +/* all these guys are ended by Endbutton +we close the brace then */ + case Spadlink: + storeString("\\fauxspadlink{"); + node = node->next; + break; + case Unixlink: + storeString("\\fauxunixlink{"); + node = node->next; + break; + case Lisplink: + storeString("\\fauxlisplink{"); + node = node->next; + break; + case Link: + storeString("\\fauxlink{"); + node = node->next; + break; + case LispDownLink: + storeString("\\fauxlispdownlink{"); + node = node->next; + break; + case LispMemoLink: + storeString("\\fauxlispmemolink{"); + node = node->next; + break; + case Memolink: + storeString("\\fauxmemolink{"); + node = node->next; + break; + case Windowlink: + storeString("\\fauxwindowlink{"); + node = node->next; + break; + case Downlink: + storeString("\\fauxdownlink{"); + node = node->next; + break; +/** END OF LINKS **/ + case Unixcommand: + storeString("\\unixcommand{"); + node = node->next; + break; + case Lispcommand: + storeString("\\lispcommand{"); + node = node->next; + break; + case Spadgraph: + storeString("\\spadgraph{"); + node = node->next; + break; + case Spadcommand: + storeString("\\spadcommand{"); + node = node->next; + break; + case Endspadcommand: + storeChar('}'); + node = node->next; + break; + case Footernode: + storeString("% This is the footer\n"); + node = node->next; + break; + case Endfooter: + storeString("% This is the end of the footer\n"); + node = node->next; + break; + case Endheader: + storeString("% This is the end of the header\n"); + node = node->next; + break; + case Headernode: + storeString("% This is the header\n"); + node = node->next; + break; + default: + fprintf(stderr, + "Print_to_string: Unrecognized Keyword Type %d\n", + node->type); + node=node->next; + break; + } + } + storeChar('\0'); + return p2sBuf; +} diff --git a/src/hyper/spadint.pamphlet b/src/hyper/spadint.pamphlet deleted file mode 100644 index 0c0869e6..00000000 --- a/src/hyper/spadint.pamphlet +++ /dev/null @@ -1,1289 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/spadint} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{spadint.c} -<>= -/* Still a problem with close_client */ - -/* Communication interface for external AXIOM buffers */ -#define _SPADINT_C -#include "axiom-c-macros.h" -#include "useproto.h" -#include "debug.h" - -#include - -#include "hyper.h" -#include "cond.h" -#include "mem.h" -#include "parse.h" -#include "bsdsignal.h" - -#include "all_hyper_proto.H1" -#include "sockio-c.H1" -#include "bsdsignal.H1" - - -typedef struct sock_list { /* linked list of Sock */ - Sock Socket; - struct sock_list *next; -} Sock_List; - -Sock_List *plSock = (Sock_List *) 0; -Sock *spad_socket = (Sock *) 0; /* to_server socket for SpadServer */ - -/* issue a AXIOM command to the buffer associated with a page */ -void -issue_spadcommand(HyperDocPage *page, TextNode *command, int immediate, - int type) -{ - char *buf; - int ret_val; - - ret_val = connect_spad(); - if (ret_val == NotConnected || ret_val == SpadBusy) - return; - - if (page->sock == NULL) - start_user_buffer(page); - ret_val = send_int(page->sock, TestLine); - if (ret_val == -1) { - page->sock = NULL; - clear_execution_marks(page->depend_hash); - issue_spadcommand(page, command, immediate, type); - return; - } - issue_dependent_commands(page, command, type); - ret_val = send_int(page->sock, ReceiveInputLine); - buf = print_to_string(command); - if (immediate) { - buf[strlen(buf) + 1] = '\0'; - buf[strlen(buf)] = '\n'; - } - if (type == Spadsrc) - send_pile(page->sock, buf); - else - send_string(page->sock, buf); - mark_as_executed(page, command, type); - gIsEndOfOutput = 0; -} -static void -send_pile(Sock *sock,char * str) -{ - FILE *f; - char name[512], command[512]; - - sprintf(name, "/tmp/hyper%s.input", getenv("SPADNUM")); - f = fopen(name, "w"); - if (f == NULL) { - fprintf(stderr, "Can't open temporary input file %s\n", name); - return; - } - fprintf(f, "%s", str); - fclose(f); - sprintf(command, ")read %s\n", name); - send_string(sock, command); -} -static void -issue_dependent_commands(HyperDocPage *page, TextNode *command,int type) -{ - TextNode *node, *depend_label; - SpadcomDepend *depend; - int end_type = (type == Spadcommand || type == Spadgraph) ? - (Endspadcommand) : (Endspadsrc); - - for (node = command->next; node->type != end_type; - node = node->next) - if (node->type == Free) - for (depend_label = node->data.node; depend_label != NULL; - depend_label = depend_label->next) - if (depend_label->type == Word) { - depend = (SpadcomDepend *) - hash_find(page->depend_hash, depend_label->data.text); - if (depend == NULL) { - fprintf(stderr, "Error: dependency on undefined label: %s\n", - depend_label->data.text); - continue; - } - if (!depend->executed) { - issue_spadcommand(page, depend->spadcom->next, 1, - depend->spadcom->type); - while (!gIsEndOfOutput) - pause(); - sleep(1); - } - } -} -static void -mark_as_executed(HyperDocPage *page, TextNode *command,int type) -{ - TextNode *node, *depend_label; - SpadcomDepend *depend; - int end_type = (type == Spadcommand || type == Spadgraph) - ? (Endspadcommand) : (Endspadsrc); - - for (node = command; node->type != end_type; node = node->next) - if (node->type == Bound) - for (depend_label = node->data.node; depend_label != NULL; - depend_label = depend_label->next) - if (depend_label->type == Word) { - depend = (SpadcomDepend *) - hash_find(page->depend_hash, depend_label->data.text); - if (depend == NULL) { - fprintf(stderr, "No dependency entry for label: %s\n", - depend_label->data.text); - continue; - } - depend->executed = 1; - } -} - -/* start a spad buffer for the page associated with the give */ -static void -start_user_buffer(HyperDocPage *page) -{ - char buf[1024], *title; - char *SPAD; - char spadbuf[250]; - char complfile[250]; - int ret_val; - - SPAD = (char *) getenv("AXIOM"); - if (SPAD == NULL) { - sprintf(SPAD, "/spad/mnt/rios"); - } - sprintf(spadbuf, "%s/lib/spadbuf", SPAD); - sprintf(complfile, "%s/lib/command.list", SPAD); - title = print_to_string(page->title); - if (access(complfile, R_OK) == 0) - - /* - * TTT says : why not invoke with "-name axiomclient" and set any - * defaults in the usual way - */ -#ifdef RIOSplatform - sprintf(buf, - "aixterm -sb -sl 500 -name axiomclient -n '%s' -T '%s' -e %s %s %s&", - title, title, spadbuf, page->name, complfile); - else - sprintf(buf, - "aixterm -sb -sl 500 -name axiomclient -n '%s' -T '%s' -e %s %s&", - title, title, spadbuf, page->name); -#else -#ifdef SUNplatform - sprintf(buf, - "xterm -sb -sl 500 -name axiomclient -n '%s' -T '%s' -e %s %s %s&", - title, title, spadbuf, page->name, complfile); - else - sprintf(buf, - "xterm -sb -sl 500 -name axiomclient -n '%s' -T '%s' -e %s %s&", - title, title, spadbuf, page->name); -#else - sprintf(buf, - "xterm -sb -sl 500 -name axiomclient -n '%s' -T '%s' -e %s %s %s&", - title, title, spadbuf, page->name, complfile); - else - sprintf(buf, - "xterm -sb -sl 500 -name axiomclient -n '%s' -T '%s' -e %s '%s'&", - title, title, spadbuf, page->name); -#endif -#endif - ret_val = system(buf); - if (ret_val == -1 || ret_val == 127) { - - /* - * perror("running the xterm spadbuf program"); exit(-1); - */ - } - accept_menu_server_connection(page); - sleep(2); -} - -/* Clears the execution marks in a hash table when a buffer has been killed */ -static void -clear_execution_marks(HashTable *depend_hash) -{ - int i; - HashEntry *h; - SpadcomDepend *depend; - - if (depend_hash == 0) - return; - for (i = 0; i < depend_hash->size; i++) - for (h = depend_hash->table[i]; h != NULL; h = h->next) { - depend = (SpadcomDepend *) h->data; - depend->executed = 0; - } -} - -Sock * -accept_menu_connection(Sock *server_sock) -{ - int sock_fd /*, session, ret_code*/; - Sock_List *pls; - /*Sock local_sock;*/ - - /* Could only be InterpWindow */ - - pls = (Sock_List *) halloc(sizeof(Sock_List),"SockList"); - sock_fd = accept(server_sock->socket, 0, 0); - if (sock_fd == -1) { - perror("session : accepting connection"); - return 0; - } - (pls->Socket).socket = sock_fd; - get_socket_type((Sock *) pls); - -#ifdef DEBUG - fprintf(stderr, - "session: accepted InterpWindow , fd = %d\n", sock_fd); -#endif - - - /* put new item at head of list */ - - if (plSock == (Sock_List *) 0) { - plSock = pls; - plSock->next = (Sock_List *) 0; - } - else { - pls->next = plSock; - plSock = pls; - } - - /* need to maintain socket_mask since we roll our own accept */ - - FD_SET(plSock->Socket.socket, &socket_mask); - return (Sock *) plSock; -} - -static void -accept_menu_server_connection(HyperDocPage *page) -{ - - /* - * TTT thinks this code should just provide a Sock to the page. The only - * client assumed is a spadbuf. Since spadbuf was invoked with the page - * name, it just passes it back here as a check (get_string line). - */ - int ret_code/*, i*/; - fd_set rd; - Sock *sock; - char *buf_name; - HyperDocPage *npage; - - if (page->sock != NULL) - return; - while (1) { - rd = server_mask; - ret_code = sselect(FD_SETSIZE, &rd, 0, 0, NULL); - if (ret_code == -1) { - perror("Session manager select"); - continue; - } - - if (server[1].socket > 0 && FD_ISSET(server[1].socket, &rd)) { - sock = accept_menu_connection(server + 1); - if (sock == 0) - return; - if (sock->purpose == InterpWindow) { - buf_name = get_string(sock); - npage = (HyperDocPage *) - hash_find(gWindow->fPageHashTable, buf_name); - if (npage == NULL) { - - /* - * Lets just try using the current page TTT doesn't know - * why this could be detrimental - * - * fprintf(stderr, "connecting spadbuf to unknown page: - * %s\n", buf_name); - */ - page->sock = sock; - return; - } - else { - - /* - * For some reason npage and page may be different TTT - * thinks this happens when a dynamic page has the same - * name as an existing static page. - */ - npage->sock = sock; - page->sock = sock; - } - if (!strcmp(buf_name, page->name)) { - return; - } - } - } - } -} - - -/* - * This procedure takes a HyperDoc node, and expands it into string - */ - -char *p2sBuf = NULL; -int p2sBufSize = 0; - -/* - * This routine takes a text node and creates a string out of it. This is for - * use with things such as spad commands. There are a very limited set of - * node types it can handle, so be careful - */ - -char * -print_to_string(TextNode *command) -{ - int len = 0; - - print_to_string1(command, &len); - p2sBuf = resizeBuffer(len, p2sBuf, &p2sBufSize); - return print_to_string1(command, NULL); -} - -/* -see the code in ht-util.boot - $funnyQuote := char 127 - $funnyBacks := char 128 -*/ -#define funnyEscape(c) ((c) == '"' ? '\177' : ((c) == '\\' ? '\200' : c)) -#define funnyUnescape(c) ((c) == '\177' ? '"' : ((c) == '\200' ? '\\' : c)) -#define storeChar(ch) if (sizeBuf) (*sizeBuf)++; else *c++ = (ch) -#define storeString(str) for (s=str;*s;s++) {storeChar(*s);} - -extern int include_bf; - -char * -print_to_string1(TextNode *command,int * sizeBuf) -{ - char *c = p2sBuf; - char *s; - InputItem *item; - LineStruct *curr_line; - int lcount; - InputBox *box; - int num_spaces; - int count; - TextNode *node; - - /* - * Init the stack of text nodes, things are pushed on here when I trace - * through a nodes data.node. This way I always no where my next is. - */ - - for (node = command; node != NULL;) { - switch (node->type) { - case Newline: - storeChar('\n'); - node = node->next; - break; - case Ifcond: - if (check_condition(node->data.ifnode->cond)) - node = node->data.ifnode->thennode; - else - node = node->data.ifnode->elsenode; - break; - case Endarg: - case Endspadcommand: - case Endspadsrc: - case Endpix: - storeChar('\0'); - return p2sBuf; - case Endverbatim: - case Endif: - case Fi: - case Endmacro: - case Endparameter: - case Rbrace: - case Endgroup: - node = node->next; - break; - case Punctuation: - - /* - * Simply copy the piece of text - */ - if (node->space & FRONTSPACE) { storeChar(' '); } - for (s = node->data.text; *s; s++) { storeChar(*s); } - node = node->next; - break; - case WindowId: - - /* - * Simply copy the piece of text - */ - if (node->space) { storeChar(' '); } - for (s = node->data.text; *s; s++) { storeChar(*s); } - storeChar(' '); - node = node->next; - break; - case Verbatim: - case Spadsrctxt: - - /* - * Simply copy the piece of text - */ - if (node->space) { storeChar(' '); } - for (s = node->data.text; *s; s++) { storeChar(*s); } - - /* - * now add the eol - */ - - /* - * if(node->next && node->next->type != Endspadsrc) - * storeChar('\n'); - */ - node = node->next; - break; - case Dash: - case Rsquarebrace: - case Lsquarebrace: - case Word: - - /* - * Simply copy the piece of text - */ - if (node->space) { storeChar(' '); } - for (s = node->data.text; *s; s++) { storeChar(*s); } - node = node->next; - break; - case BoxValue: - box = - (InputBox *) hash_find(gWindow->page->box_hash, node->data.text); - if (box == NULL) { - fprintf(stderr, - "Print_to_string:Box %s Has no symbol table entry\n", - node->data.text); - exit(-1); - } - storeChar(' '); - if (box->picked) { - storeChar('t'); - } - else { - storeChar('n'); - storeChar('i'); - storeChar('l'); - } - node = node->next; - break; - case StringValue: - item = return_item(node->data.text); - if (item != NULL) { - if (node->space) - storeChar(' '); - curr_line = item->lines; - while (curr_line != NULL) { - for (lcount = 0, s = curr_line->buffer; *s && lcount < item->size; - s++, lcount++) { - storeChar(funnyUnescape(*s)); - } - if (curr_line->len <= item->size && curr_line->next) - storeChar('\n'); - curr_line = curr_line->next; - } - } - else if ((box = (InputBox *) hash_find(gWindow->page->box_hash, - node->data.text)) != NULL) { - if (node->space) { storeChar(' '); } - if (box->picked) { - storeChar('t'); - } - else { - storeChar('n'); - storeChar('i'); - storeChar('l'); - } - } - else { - fprintf(stderr, "Error, Symbol %s has no symbol table entry\n", - node->data.text); - exit(-1); - } - node = node->next; - break; - case Space: - num_spaces = (node->data.node != NULL ? - atoi(node->data.node->data.text) : 1); - for (count = 0; count < num_spaces; count++) - storeChar(' '); - node = node->next; - break; - case Titlenode: - case Endtitle: - case Center: - case Endcenter: - case BoldFace: - case Emphasize: - case Indentrel: - node = node->next; - break; - case Bound: - if (include_bf) { - int len, i; - TextNode *n2 = node->data.node; - - storeChar('\\'); - storeChar('b'); - storeChar('o'); - storeChar('u'); - storeChar('n'); - storeChar('d'); - storeChar('{'); - for (; n2->type != Endarg; n2 = n2->next) { - if (n2->type == Word) { - len = strlen(n2->data.text); - for (i = 0; i < len; i++) - storeChar(n2->data.text[i]); - storeChar(' '); - } - } - storeChar('}'); - } - node = node->next; - break; - case Free: - if (include_bf) { - int len, i; - TextNode *n2 = node->data.node; - - storeChar('\\'); - storeChar('f'); - storeChar('r'); - storeChar('e'); - storeChar('e'); - storeChar('{'); - for (; n2->type != Endarg; n2 = n2->next) { - if (n2->type == Word) { - len = strlen(n2->data.text); - for (i = 0; i < len; i++) - storeChar(n2->data.text[i]); - storeChar(' '); - } - } - storeChar('}'); - } - node = node->next; - break; - case Macro: - node = node->next; - break; - case Pound: - if (node->space) { storeChar(' '); } - node = node->next; - break; - case Group: - node = node->next; - break; - case Indent: - num_spaces = (node->data.node != NULL ? - atoi(node->data.node->data.text) : 1); - for (count = 0; count < num_spaces; count++) - storeChar(' '); - node = node->next; - break; - default: - fprintf(stderr, - "Print_to_string: Unrecognized Keyword Type %d\n", - node->type); - node=node->next; - break; - } - } - storeChar('\0'); - return p2sBuf; -} - -/* - * Send a lisp or spad command to the AXIOM server for execution , if - * type is link, then we wait for a HyperDoc card to be returned - */ - -HyperDocPage * -issue_server_command(HyperLink *link) -{ - TextNode *command = (TextNode *) link->reference.node; - int ret_val; - char *buf; - HyperDocPage *page; - - ret_val = connect_spad(); - if (ret_val == NotConnected) { - page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, "SpadNotConnectedPage"); - if (page == NULL) - fprintf(stderr, "No SpadNotConnectedPage found\n"); - return page; - } - if (ret_val == SpadBusy) { - page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, "SpadBusyPage"); - if (page == NULL) - fprintf(stderr, "No SpadBusyPage found\n"); - return page; - } - switch_frames(); - switch (link->type) { - case Qspadcall: - case Qspadcallquit: - case Spadlink: - case Spaddownlink: - case Spadmemolink: - send_int(spad_socket, QuietSpadCommand); - break; - case Spadcall: - case Spadcallquit: - send_int(spad_socket, SpadCommand); - break; - default: - send_int(spad_socket, LispCommand); - break; - } - buf = print_to_string(command); - send_string(spad_socket, buf); - if (link->type == Lispcommand || link->type == Spadcall - || link->type == Spadcallquit || link->type == Qspadcallquit - || link->type == Qspadcall || link->type == Lispcommandquit) - return NULL; - page = parse_page_from_socket(); - return page; -} - -int -issue_serverpaste(TextNode *command) -{ - char *buf; - int ret_val; - - ret_val = connect_spad(); - if (ret_val == NotConnected || ret_val == SpadBusy) - return 1; - switch_frames(); - send_int(spad_socket, LispCommand); - buf = print_to_string(command); - send_string(spad_socket, buf); - return 1; -} - -/* - * issue a unix command - */ -void -issue_unixcommand(TextNode *node) -{ - char *buf; - char *copy; - - - buf = print_to_string(node); - copy =(char *) halloc((strlen(buf)+2)*sizeof(char),"Unixcommand"); - strcpy(copy,buf); - copy[strlen(buf) + 1] = '\0'; - copy[strlen(buf)] = '&'; - system(copy); - free(copy); - return; -} - -HyperDocPage * -issue_unixlink(TextNode *node) -{ - HyperDocPage *page; - char *buf; - - buf = print_to_string(node); - if ((unixfd = popen(buf, "r")) == NULL) { - fprintf(stderr, "Error popening %s\n", buf); - exit(-1); - } - bsdSignal(SIGUSR2,SIG_IGN,0); - page = parse_page_from_unixfd(); - bsdSignal(SIGUSR2,sigusr2_handler,0); - return page; -} - -int -issue_unixpaste(TextNode *node) -{ - char *buf; - - buf = print_to_string(node); - if ((unixfd = popen(buf, "r")) == NULL) { - fprintf(stderr, "Error popening %s\n", buf); - exit(-1); - } - return 1; -} - - -/* - * called when session_server selects - */ -void -service_session_socket(void) -{ - int cmd, pid; - - cmd = get_int(session_server); - switch (cmd) { - case CloseClient: - pid = get_int(session_server); - if (pid != -1) - close_client(pid); - break; - default: - fprintf(stderr, - "(HyperDoc) Unknown command from SessionServer %d\n", cmd); - break; - } -} - - -/* - * let spad know which frame to issue command via - */ -static void -switch_frames(void) -{ - if (session_server == NULL) { - fprintf(stderr, "(HyperDoc) No session manager connected!\n"); - return; - } - if (gWindow->fAxiomFrame == -1) { - fprintf(stderr, "(HyperDoc) No AXIOM frame associated with top level window!\n"); - return; - } - send_int(session_server, SwitchFrames); - send_int(session_server, gWindow->fAxiomFrame); -} -void -send_lisp_command(char *command) -{ - int ret_val; - - ret_val = connect_spad(); - if (ret_val == NotConnected || ret_val == SpadBusy) { - return; - } - send_int(spad_socket, LispCommand); - send_string(spad_socket, command); -} -void -escape_string(char *s) -{ - char *st; - - for (st = s; *st; st++) - *st = funnyEscape(*st); -} -void -unescape_string(char *s) -{ - char *st; - - for (st = s; *st; st++) - *st = funnyUnescape(*st); -} -static void -close_client(int pid) -{ - /*int i;*/ - Sock_List *pSock, *locSock; - - /* - * just need to drop the list item - */ - - if (plSock == (Sock_List *) 0) - return; - - /* - * first check head - */ - - if ((plSock->Socket.pid == pid)) { - locSock = plSock; - if ((*plSock).next == (Sock_List *) 0) { - plSock = (Sock_List *) 0; - } - else { - plSock = plSock->next; - } - free(locSock); - } - - /* - * now check the rest - */ - - else { - for (pSock = plSock; pSock->next != (Sock_List *) 0; pSock = pSock->next) - if (pSock->next->Socket.pid == pid) { - locSock = pSock->next; - if (pSock->next->next == (Sock_List *) 0) { - pSock->next = (Sock_List *) 0; - } - else { - pSock->next = pSock->next->next; - } - free(locSock); - break; - } - } -} - - - -char * -print_source_to_string(TextNode *command) -{ - int len = 0; - - print_source_to_string1(command, &len); - p2sBuf = resizeBuffer(len, p2sBuf, &p2sBufSize); - return print_source_to_string1(command, NULL); -} -char * -print_source_to_string1(TextNode *command,int * sizeBuf) -{ - char *c = p2sBuf; - char *s; - InputItem *item; - LineStruct *curr_line; - int lcount; - InputBox *box; - int num_spaces; - int count; - TextNode *node; - - /* - print out HyperDoc source for what you see - */ - - for (node = command; node != NULL;) { - switch (node->type) { - case Newline: - storeString("\\newline\n"); - node = node->next; - break; - case Par: - storeString("\n\n"); - node = node->next; - break; - case Indentrel: - storeString("\\indentrel{"); - storeString(node->data.node->data.text); - storeChar('}'); - node = node->next; - break; - case Tab: - storeString("\\tab{"); - storeString(node->data.node->data.text); - storeChar('}'); - node = node->next; - break; - case Ifcond: - if (check_condition(node->data.ifnode->cond)) - node = node->data.ifnode->thennode; - else - node = node->data.ifnode->elsenode; - break; - case Endarg: - case Endspadsrc: - case Endpix: - case Endbutton: - storeChar('}'); - node = node->next; - break; - case Endverbatim: - case Endif: - case Fi: - case Endmacro: - case Endparameter: - case Rbrace: - node = node->next; - break; - case Punctuation: - - /* - * Simply copy the piece of text - */ - if (node->space & FRONTSPACE) { storeChar(' '); } - for (s = node->data.text; *s; s++) { storeChar(*s); } - node = node->next; - break; - case WindowId: - storeString("\\windowid "); - node = node->next; - break; - case Verbatim: - case Spadsrctxt: - if (node->space) { storeChar(' '); } - for (s = node->data.text; *s; s++) { storeChar(*s); } - node = node->next; - break; - case Dash: - case Rsquarebrace: - case Lsquarebrace: - case Word: - if (node->space) { storeChar(' '); } - for (s = node->data.text; *s; s++) { storeChar(*s); } - node = node->next; - break; - case BoxValue: - box = (InputBox *) hash_find(gWindow->page->box_hash, node->data.text); - if (box == NULL) { - fprintf(stderr, "Print_to_string:Box %s Has no symbol table entry\n", - node->data.text); - exit(-1); - } - storeChar(' '); - if (box->picked) { - storeChar('t'); - } - else { - storeChar('n'); - storeChar('i'); - storeChar('l'); - } - node = node->next; - break; - case StringValue: - item = return_item(node->data.text); - if (item != NULL) { - if (node->space) { storeChar(' '); } - curr_line = item->lines; - while (curr_line != NULL) { - for (lcount = 0, s = curr_line->buffer; - *s && lcount < item->size; - s++, lcount++) { - storeChar(funnyUnescape(*s)); - } - if (curr_line->len <= item->size && curr_line->next) - storeChar('\n'); - curr_line = curr_line->next; - } - } - else if ((box = (InputBox *) hash_find(gWindow->page->box_hash, - node->data.text)) != NULL) { - if (node->space) { storeChar(' '); } - if (box->picked) { - storeChar('t'); - } - else { - storeChar('n'); - storeChar('i'); - storeChar('l'); - } - } - else { - fprintf(stderr, "Error, Symbol %s has no symbol table entry\n", - node->data.text); - exit(-1); - } - node = node->next; - break; - case Space: - num_spaces = (node->data.node != NULL ? - atoi(node->data.node->data.text) : 1); - for (count = 0; count < num_spaces; count++) - storeChar(' '); - node = node->next; - break; - case Emphasize: - storeString("\\em "); - node = node->next; - break; - case BoldFace: - storeString("\\bf "); - node = node->next; - break; - case Sl: - storeString("\\it "); - node = node->next; - break; - case Rm: - storeString("\\rm "); - node = node->next; - break; - case It: - storeString("\\it "); - node = node->next; - break; - case Tt: - storeString("\\tt "); - node = node->next; - break; - case Group: -/* skip {} */ - if (node->next->type==Endgroup){ - node=node->next->next; - break; - } - storeChar('{'); - node = node->next; - break; - case Endgroup: - storeChar('}'); - node = node->next; - break; - case Box: - storeString("\\box{"); - node = node->next; - break; - case Endbox: - storeChar('}'); - node = node->next; - break; - case Center: - storeString("\\center{"); - node = node->next; - break; - case Endcenter: - storeString("}"); - storeChar('\n'); - node = node->next; - break; - case Titlenode: - case Endtitle: - node = node->next; - break; - case Bound: - { - TextNode *n2 = node->data.node; - - storeString("\\bound{"); - for (; n2->type != Endarg; n2 = n2->next) { - if (n2->type == Word) { - storeString(n2->data.text); - storeChar(' '); - } - } - storeChar('}'); - } - node = node->next; - break; - case Free: - { - TextNode *n2 = node->data.node; - - storeString("\\free{"); - for (; n2->type != Endarg; n2 = n2->next) { - if (n2->type == Word) { - storeString(n2->data.text); - storeChar(' '); - } - } - storeChar('}'); - } - node = node->next; - break; - case Macro: - storeChar(' '); - node = node->next; - break; - case Pound: - if (node->space) { storeChar(' '); } - node = node->next; - break; - case Indent: - num_spaces = (node->data.node != NULL ? - atoi(node->data.node->data.text) : 1); - for (count = 0; count < num_spaces; count++) - storeChar(' '); - node = node->next; - break; - case Inputbitmap: - storeString("\\inputbitmap{"); - storeString(node->data.text); - storeString("}\n"); - node = node->next; - break; - case Endscrolling: - storeString("\\end{scroll}\n"); - node = node->next; - break; - case Scrollingnode: - storeString("\\begin{scroll}\n"); - storeString("% This is the scrolling area\n"); - node = node->next; - break; - case Horizontalline: - storeString("\\horizontalline\n"); - node = node->next; - break; - case Endtable: - storeChar('}'); - node = node->next; - break; - case Table: - storeString("\\table{"); - node = node->next; - break; - case Tableitem: - storeChar('{'); - node = node->next; - break; - case Endtableitem: - storeChar('}'); - node = node->next; - break; - case Beginitems: - storeString("\\begin{items}"); - node = node->next; - break; - case Item: - storeString("\n\\item"); - node = node->next; - break; - case Enditems: - storeString("\n\\end{items}"); - node = node->next; - break; -/*** LINKS ***/ -/* all these guys are ended by Endbutton -we close the brace then */ - case Spadlink: - storeString("\\fauxspadlink{"); - node = node->next; - break; - case Unixlink: - storeString("\\fauxunixlink{"); - node = node->next; - break; - case Lisplink: - storeString("\\fauxlisplink{"); - node = node->next; - break; - case Link: - storeString("\\fauxlink{"); - node = node->next; - break; - case LispDownLink: - storeString("\\fauxlispdownlink{"); - node = node->next; - break; - case LispMemoLink: - storeString("\\fauxlispmemolink{"); - node = node->next; - break; - case Memolink: - storeString("\\fauxmemolink{"); - node = node->next; - break; - case Windowlink: - storeString("\\fauxwindowlink{"); - node = node->next; - break; - case Downlink: - storeString("\\fauxdownlink{"); - node = node->next; - break; -/** END OF LINKS **/ - case Unixcommand: - storeString("\\unixcommand{"); - node = node->next; - break; - case Lispcommand: - storeString("\\lispcommand{"); - node = node->next; - break; - case Spadgraph: - storeString("\\spadgraph{"); - node = node->next; - break; - case Spadcommand: - storeString("\\spadcommand{"); - node = node->next; - break; - case Endspadcommand: - storeChar('}'); - node = node->next; - break; - case Footernode: - storeString("% This is the footer\n"); - node = node->next; - break; - case Endfooter: - storeString("% This is the end of the footer\n"); - node = node->next; - break; - case Endheader: - storeString("% This is the end of the header\n"); - node = node->next; - break; - case Headernode: - storeString("% This is the header\n"); - node = node->next; - break; - default: - fprintf(stderr, - "Print_to_string: Unrecognized Keyword Type %d\n", - node->type); - node=node->next; - break; - } - } - storeChar('\0'); - return p2sBuf; -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/sup.bitmap b/src/hyper/sup.bitmap new file mode 100644 index 00000000..1b5f823e --- /dev/null +++ b/src/hyper/sup.bitmap @@ -0,0 +1,9 @@ +#define sup_width 21 +#define sup_height 21 +static char sup_bits[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfb, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xe0, 0xff, 0x7f, 0xc0, 0xff, + 0x3f, 0x80, 0xff, 0x1f, 0x00, 0xff, 0x0f, 0x00, 0xfe, 0x07, 0x00, 0xfc, + 0x03, 0x00, 0xf8, 0x01, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff}; diff --git a/src/hyper/sup3d.bitmap b/src/hyper/sup3d.bitmap new file mode 100644 index 00000000..c1dd285b --- /dev/null +++ b/src/hyper/sup3d.bitmap @@ -0,0 +1,9 @@ +#define sup3d_width 21 +#define sup3d_height 21 +static char sup3d_bits[] = { + 0xaa, 0xaa, 0x0a, 0x55, 0x55, 0x15, 0x02, 0x00, 0x0c, 0x51, 0x55, 0x15, + 0xaa, 0xaa, 0x0e, 0x51, 0x55, 0x15, 0xaa, 0xae, 0x0e, 0x51, 0x5f, 0x15, + 0xaa, 0xbf, 0x0e, 0xd1, 0x7f, 0x15, 0xea, 0xff, 0x0e, 0x51, 0x5f, 0x15, + 0xaa, 0xae, 0x0e, 0x51, 0x5f, 0x15, 0xaa, 0xae, 0x0e, 0x51, 0x5f, 0x15, + 0xaa, 0xaa, 0x0e, 0x51, 0x55, 0x15, 0xfa, 0xff, 0x0f, 0x55, 0x55, 0x15, + 0xaa, 0xaa, 0x0a}; diff --git a/src/hyper/sup3dpr.bitmap b/src/hyper/sup3dpr.bitmap new file mode 100644 index 00000000..2617792f --- /dev/null +++ b/src/hyper/sup3dpr.bitmap @@ -0,0 +1,9 @@ +#define sup3dpr_width 21 +#define sup3dpr_height 21 +static char sup3dpr_bits[] = { + 0xaa, 0xaa, 0x0a, 0x55, 0x55, 0x15, 0xfe, 0xff, 0x0f, 0x55, 0x55, 0x11, + 0xae, 0xaa, 0x0a, 0x55, 0x55, 0x11, 0xae, 0xaa, 0x0a, 0x55, 0x5d, 0x11, + 0xae, 0xbe, 0x0a, 0x55, 0x7f, 0x11, 0xae, 0xff, 0x0a, 0xd5, 0xff, 0x11, + 0xae, 0xbe, 0x0a, 0x55, 0x5d, 0x11, 0xae, 0xbe, 0x0a, 0x55, 0x5d, 0x11, + 0xae, 0xbe, 0x0a, 0x55, 0x55, 0x11, 0x06, 0x00, 0x08, 0x55, 0x55, 0x15, + 0xaa, 0xaa, 0x0a}; diff --git a/src/hyper/titlebar.c b/src/hyper/titlebar.c new file mode 100644 index 00000000..51ff3696 --- /dev/null +++ b/src/hyper/titlebar.c @@ -0,0 +1,356 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + 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. +*/ + +/****************************************************************************** + * + * titlebar.c: Produces HyperDoc titlebar + * + * Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993. + * + ****************************************************************************/ +#define _TITLEBAR_C +#include "axiom-c-macros.h" +#include "useproto.h" +#include "debug.h" + +#include + +#include "titlebar.h" +#include "display.h" +#include "group.h" +#include "initx.h" +#include "parse.h" + +#include "all_hyper_proto.H1" + +extern int y_off; /* y offset for scrolling regions */ + +/* Images for the title bar windows */ + +static XImage *tw1image = NULL, + *tw2image = NULL, + *tw3image = NULL, + *tw4image = NULL, + *noopimage = NULL; + +/* #undef BITMAPS2D to get old style 2d effect */ + +#ifdef BITMAPS2D + +static char *tw1file = "exit.bitmap"; +static char *tw2file = "help2.bitmap"; +static char *tw3file = "return3.bitmap"; +static char *tw4file = "up3.bitmap"; +static char *noopfile = "noop.bitmap"; + +#define BACKCOLOR gBackgroundColor +#define BUTTGC fStandardGC + +#else + +static char *tw1file = "exit3d.bitmap"; +static char *tw2file = "help3d.bitmap"; +static char *tw3file = "home3d.bitmap"; +static char *tw4file = "up3d.bitmap"; +static char *noopfile = "noop3d.bitmap"; + +#define BACKCOLOR gControlBackgroundColor +#define BUTTGC fControlGC + +#endif + + +int twwidth, twheight; /* the width and height for all windows in the */ + /* title bar */ + +void +makeTitleBarWindows(void) +{ + XSetWindowAttributes at; + unsigned long valuemask = 0L; + + /* read the images if we don't have them already */ + + if (tw1image == NULL) + readTitleBarImages(); + + /* set the window attributes */ + + at.cursor = gActiveCursor; + valuemask |= CWCursor; + at.event_mask = ButtonPress; + valuemask |= CWEventMask; + + /* create the windows for the buttons */ + + gWindow->fTitleBarButton1 = XCreateSimpleWindow(gXDisplay, gWindow->fMainWindow, + 1, 1, twwidth, twheight, + 0, gBorderColor, BACKCOLOR); + XChangeWindowAttributes(gXDisplay, gWindow->fTitleBarButton1, valuemask, &at); + + gWindow->fTitleBarButton2 = XCreateSimpleWindow(gXDisplay, gWindow->fMainWindow, + 1, 1, twwidth, twheight, + 0, gBorderColor, BACKCOLOR); + XChangeWindowAttributes(gXDisplay, gWindow->fTitleBarButton2, valuemask, &at); + + gWindow->fTitleBarButton3 = XCreateSimpleWindow(gXDisplay, gWindow->fMainWindow, + 1, 1, twwidth, twheight, + 0, gBorderColor, BACKCOLOR); + XChangeWindowAttributes(gXDisplay, gWindow->fTitleBarButton3, valuemask, &at); + + gWindow->fTitleBarButton4 = XCreateSimpleWindow(gXDisplay, gWindow->fMainWindow, + 1, 1, twwidth, twheight, + 0, gBorderColor, BACKCOLOR); + XChangeWindowAttributes(gXDisplay, gWindow->fTitleBarButton4, valuemask, &at); +} + +void +showTitleBar(void) +{ + XWindowChanges wc; + int height, hbw = (int) gWindow->border_width / 2; + XImage *image; + + /* + * the first thing we do is pop up all the windows and + * place them properly + */ + + if (gWindow->page->title->height != twheight) + height = gWindow->page->title->height; + else + height = twheight; + + push_active_group(); + + /* configure and map button number 1 */ + + wc.x = 0; + wc.y = 0; + wc.height = twheight; + wc.width = twwidth; + XConfigureWindow(gXDisplay, gWindow->fTitleBarButton1, CWX | CWY | CWHeight | CWWidth, &wc); + XMapWindow(gXDisplay, gWindow->fTitleBarButton1); + + image = tw1image; + XPutImage(gXDisplay, gWindow->fTitleBarButton1, gWindow->BUTTGC, + image, 0, 0, 0, 0, + image->width, + image->height); + + /* configure and map button number 2 */ + + wc.x += twwidth + gWindow->border_width; + XConfigureWindow(gXDisplay, gWindow->fTitleBarButton2, CWX | CWY | CWHeight | CWWidth, &wc); + XMapWindow(gXDisplay, gWindow->fTitleBarButton2); + + image = need_help_button ? tw2image : noopimage; + XPutImage(gXDisplay, gWindow->fTitleBarButton2, gWindow->BUTTGC, + image, 0, 0, 0, 0, + image->width, + image->height); + + /* configure and map button number 4 */ + + wc.x = gWindow->width - twwidth; + XConfigureWindow(gXDisplay, gWindow->fTitleBarButton4, CWX | CWY | CWHeight | CWWidth, &wc); + XMapWindow(gXDisplay, gWindow->fTitleBarButton4); + + image = need_up_button ? tw4image : noopimage; + XPutImage(gXDisplay, gWindow->fTitleBarButton4, gWindow->BUTTGC, + image, 0, 0, 0, 0, + image->width, + image->height); + + /* configure and map button number 3 */ + + wc.x = wc.x - twwidth - gWindow->border_width; + XConfigureWindow(gXDisplay, gWindow->fTitleBarButton3, CWX | CWY | CWHeight | CWWidth, &wc); + XMapWindow(gXDisplay, gWindow->fTitleBarButton3); + + image = need_return_button ? tw3image : noopimage; + XPutImage(gXDisplay, gWindow->fTitleBarButton3, gWindow->BUTTGC, + image, 0, 0, 0, 0, + image->width, + image->height); + + gWindow->fDisplayedWindow = gWindow->fMainWindow; + gDisplayRegion = Title; + gRegionOffset = 0; + y_off = 0; + + pop_group_stack(); + + show_text(gWindow->page->title->next, Endheader); + + /* Now draw the box around the title */ + + line_top_group(); + +#if BITMAPS2D + XDrawRectangle(gXDisplay, gWindow->fMainWindow, gWindow->fStandardGC, gWindow->page->title->x, + -hbw, + wc.x - gWindow->page->title->x - hbw, + height + 2 * hbw); +#endif + + XDrawLine(gXDisplay, gWindow->fMainWindow, gWindow->fStandardGC, 0, height + hbw, + gWindow->width, height + hbw); + +#if BITMAPS2D + /* Now draw the lines down the middle */ + + XDrawLine(gXDisplay, gWindow->fMainWindow, gWindow->fStandardGC, + twwidth + hbw, 0, + twwidth + hbw, height); + XDrawLine(gXDisplay, gWindow->fMainWindow, gWindow->fStandardGC, + gWindow->width - twwidth - hbw, 0, + gWindow->width - twwidth - hbw, height); +#endif + + pop_group_stack(); + +#if BITMAPS2D + /* now fill the areas under the bitmaps if we have to */ + + if (gWindow->page->title->height > twheight) { + push_active_group(); + height = height - twheight; + + XFillRectangle(gXDisplay, gWindow->fMainWindow, gWindow->fStandardGC, 0, + twheight, twwidth, height); + XFillRectangle(gXDisplay, gWindow->fMainWindow, gWindow->fStandardGC, + twwidth + gWindow->border_width, + twheight, twwidth, height); + XFillRectangle(gXDisplay, gWindow->fMainWindow, gWindow->fStandardGC, + gWindow->width - 2 * twwidth - gWindow->border_width, + twheight, twwidth, height); + XFillRectangle(gXDisplay, gWindow->fMainWindow, gWindow->fStandardGC, + gWindow->width - twwidth, + twheight, twwidth, height); + pop_group_stack(); + } +#endif +} + +void +linkTitleBarWindows(void) +{ + HyperLink *tw1link = (HyperLink *) halloc(sizeof(HyperLink), "HyperLink"), + *tw2link = (HyperLink *) halloc(sizeof(HyperLink), "HyperLink"), + *tw3link = (HyperLink *) halloc(sizeof(HyperLink), "HyperLink"), + *tw4link = (HyperLink *) halloc(sizeof(HyperLink), "HyperLink"); + + tw1link->win = gWindow->fTitleBarButton1; + tw1link->type = Quitbutton; + tw1link->reference.node = NULL; + tw1link->x = tw1link->y = 0; + + tw2link->win = gWindow->fTitleBarButton2; + tw2link->type = Helpbutton; + tw2link->reference.node = NULL; + tw2link->x = tw2link->y = 0; + + tw3link->win = gWindow->fTitleBarButton3; + tw3link->type = Returnbutton; + tw3link->reference.node = NULL; + tw3link->x = tw3link->y = 0; + + tw4link->win = gWindow->fTitleBarButton4; + tw4link->type = Upbutton; + tw4link->reference.node = NULL; + tw4link->x = tw4link->y = 0; + + hash_insert(gLinkHashTable, (char *)tw1link,(char *) &tw1link->win); + hash_insert(gLinkHashTable, (char *)tw2link,(char *) &tw2link->win); + hash_insert(gLinkHashTable, (char *)tw3link,(char *) &tw3link->win); + hash_insert(gLinkHashTable, (char *)tw4link,(char *) &tw4link->win); +} + +static void +readTitleBarImages(void) +{ + int w, h; + char filename[128]; + char *axiomEnvVar = NULL; + + axiomEnvVar = getenv("AXIOM"); + + if (axiomEnvVar) + sprintf(filename, "%s/share/hypertex/bitmaps/%s", axiomEnvVar, tw1file); + else + sprintf(filename, "%s", tw1file); + tw1image = HTReadBitmapFile(gXDisplay, gXScreenNumber, filename, + &twwidth, &twheight); + + if (axiomEnvVar) + sprintf(filename, "%s/share/hypertex/bitmaps/%s", axiomEnvVar, tw2file); + else + sprintf(filename, "%s", tw2file); + tw2image = HTReadBitmapFile(gXDisplay, gXScreenNumber, filename, + &w, &h); + twwidth = ((twwidth >= w) ? (twwidth) : (w)); + + if (axiomEnvVar) + sprintf(filename, "%s/share/hypertex/bitmaps/%s", axiomEnvVar, tw3file); + else + sprintf(filename, "%s", tw3file); + tw3image = HTReadBitmapFile(gXDisplay, gXScreenNumber, filename, + &w, &h); + twwidth = ((twwidth >= w) ? (twwidth) : (w)); + + if (axiomEnvVar) + sprintf(filename, "%s/share/hypertex/bitmaps/%s", axiomEnvVar, tw4file); + else + sprintf(filename, "%s", tw4file); + tw4image = HTReadBitmapFile(gXDisplay, gXScreenNumber, filename, + &w, &h); + twwidth = ((twwidth >= w) ? (twwidth) : (w)); + + + if (axiomEnvVar) + sprintf(filename, "%s/share/hypertex/bitmaps/%s", axiomEnvVar, noopfile); + else + sprintf(filename, "%s", noopfile); + noopimage = HTReadBitmapFile(gXDisplay, gXScreenNumber, filename, + &twwidth, &twheight); +} + +void +getTitleBarMinimumSize(int *width, int *height) +{ + (*width) = 4 * twwidth + 40; + (*height) = twheight + 2; +} diff --git a/src/hyper/titlebar.h b/src/hyper/titlebar.h new file mode 100644 index 00000000..2bf66cbe --- /dev/null +++ b/src/hyper/titlebar.h @@ -0,0 +1,44 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + All right 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. +*/ + +#ifndef _TITLEBAR_H_ +#define _TITLEBAR_H_ 1 + +#include "hyper.h" + +extern int twwidth, twheight; /* the width and height for all windows in the */ + /* title bar */ + +#endif diff --git a/src/hyper/titlebar.pamphlet b/src/hyper/titlebar.pamphlet deleted file mode 100644 index 1808cc63..00000000 --- a/src/hyper/titlebar.pamphlet +++ /dev/null @@ -1,398 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/titlebar} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{titlebar.h} -<>= -<> -#ifndef _TITLEBAR_H_ -#define _TITLEBAR_H_ 1 - -#include "hyper.h" - -extern int twwidth, twheight; /* the width and height for all windows in the */ - /* title bar */ - -#endif -@ -\section{titlebar.c} -<>= -/****************************************************************************** - * - * titlebar.c: Produces HyperDoc titlebar - * - * Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993. - * - ****************************************************************************/ -#define _TITLEBAR_C -#include "axiom-c-macros.h" -#include "useproto.h" -#include "debug.h" - -#include - -#include "titlebar.h" -#include "display.h" -#include "group.h" -#include "initx.h" -#include "show-types.h" -#include "parse.h" - -#include "all_hyper_proto.H1" - -extern int y_off; /* y offset for scrolling regions */ - -/* Images for the title bar windows */ - -static XImage *tw1image = NULL, - *tw2image = NULL, - *tw3image = NULL, - *tw4image = NULL, - *noopimage = NULL; - -/* #undef BITMAPS2D to get old style 2d effect */ - -#ifdef BITMAPS2D - -static char *tw1file = "exit.bitmap"; -static char *tw2file = "help2.bitmap"; -static char *tw3file = "return3.bitmap"; -static char *tw4file = "up3.bitmap"; -static char *noopfile = "noop.bitmap"; - -#define BACKCOLOR gBackgroundColor -#define BUTTGC fStandardGC - -#else - -static char *tw1file = "exit3d.bitmap"; -static char *tw2file = "help3d.bitmap"; -static char *tw3file = "home3d.bitmap"; -static char *tw4file = "up3d.bitmap"; -static char *noopfile = "noop3d.bitmap"; - -#define BACKCOLOR gControlBackgroundColor -#define BUTTGC fControlGC - -#endif - - -int twwidth, twheight; /* the width and height for all windows in the */ - /* title bar */ - -void -makeTitleBarWindows(void) -{ - XSetWindowAttributes at; - unsigned long valuemask = 0L; - - /* read the images if we don't have them already */ - - if (tw1image == NULL) - readTitleBarImages(); - - /* set the window attributes */ - - at.cursor = gActiveCursor; - valuemask |= CWCursor; - at.event_mask = ButtonPress; - valuemask |= CWEventMask; - - /* create the windows for the buttons */ - - gWindow->fTitleBarButton1 = XCreateSimpleWindow(gXDisplay, gWindow->fMainWindow, - 1, 1, twwidth, twheight, - 0, gBorderColor, BACKCOLOR); - XChangeWindowAttributes(gXDisplay, gWindow->fTitleBarButton1, valuemask, &at); - - gWindow->fTitleBarButton2 = XCreateSimpleWindow(gXDisplay, gWindow->fMainWindow, - 1, 1, twwidth, twheight, - 0, gBorderColor, BACKCOLOR); - XChangeWindowAttributes(gXDisplay, gWindow->fTitleBarButton2, valuemask, &at); - - gWindow->fTitleBarButton3 = XCreateSimpleWindow(gXDisplay, gWindow->fMainWindow, - 1, 1, twwidth, twheight, - 0, gBorderColor, BACKCOLOR); - XChangeWindowAttributes(gXDisplay, gWindow->fTitleBarButton3, valuemask, &at); - - gWindow->fTitleBarButton4 = XCreateSimpleWindow(gXDisplay, gWindow->fMainWindow, - 1, 1, twwidth, twheight, - 0, gBorderColor, BACKCOLOR); - XChangeWindowAttributes(gXDisplay, gWindow->fTitleBarButton4, valuemask, &at); -} - -void -showTitleBar(void) -{ - XWindowChanges wc; - int height, hbw = (int) gWindow->border_width / 2; - XImage *image; - - /* - * the first thing we do is pop up all the windows and - * place them properly - */ - - if (gWindow->page->title->height != twheight) - height = gWindow->page->title->height; - else - height = twheight; - - push_active_group(); - - /* configure and map button number 1 */ - - wc.x = 0; - wc.y = 0; - wc.height = twheight; - wc.width = twwidth; - XConfigureWindow(gXDisplay, gWindow->fTitleBarButton1, CWX | CWY | CWHeight | CWWidth, &wc); - XMapWindow(gXDisplay, gWindow->fTitleBarButton1); - - image = tw1image; - XPutImage(gXDisplay, gWindow->fTitleBarButton1, gWindow->BUTTGC, - image, 0, 0, 0, 0, - image->width, - image->height); - - /* configure and map button number 2 */ - - wc.x += twwidth + gWindow->border_width; - XConfigureWindow(gXDisplay, gWindow->fTitleBarButton2, CWX | CWY | CWHeight | CWWidth, &wc); - XMapWindow(gXDisplay, gWindow->fTitleBarButton2); - - image = need_help_button ? tw2image : noopimage; - XPutImage(gXDisplay, gWindow->fTitleBarButton2, gWindow->BUTTGC, - image, 0, 0, 0, 0, - image->width, - image->height); - - /* configure and map button number 4 */ - - wc.x = gWindow->width - twwidth; - XConfigureWindow(gXDisplay, gWindow->fTitleBarButton4, CWX | CWY | CWHeight | CWWidth, &wc); - XMapWindow(gXDisplay, gWindow->fTitleBarButton4); - - image = need_up_button ? tw4image : noopimage; - XPutImage(gXDisplay, gWindow->fTitleBarButton4, gWindow->BUTTGC, - image, 0, 0, 0, 0, - image->width, - image->height); - - /* configure and map button number 3 */ - - wc.x = wc.x - twwidth - gWindow->border_width; - XConfigureWindow(gXDisplay, gWindow->fTitleBarButton3, CWX | CWY | CWHeight | CWWidth, &wc); - XMapWindow(gXDisplay, gWindow->fTitleBarButton3); - - image = need_return_button ? tw3image : noopimage; - XPutImage(gXDisplay, gWindow->fTitleBarButton3, gWindow->BUTTGC, - image, 0, 0, 0, 0, - image->width, - image->height); - - gWindow->fDisplayedWindow = gWindow->fMainWindow; - gDisplayRegion = Title; - gRegionOffset = 0; - y_off = 0; - - pop_group_stack(); - - show_text(gWindow->page->title->next, Endheader); - - /* Now draw the box around the title */ - - line_top_group(); - -#if BITMAPS2D - XDrawRectangle(gXDisplay, gWindow->fMainWindow, gWindow->fStandardGC, gWindow->page->title->x, - -hbw, - wc.x - gWindow->page->title->x - hbw, - height + 2 * hbw); -#endif - - XDrawLine(gXDisplay, gWindow->fMainWindow, gWindow->fStandardGC, 0, height + hbw, - gWindow->width, height + hbw); - -#if BITMAPS2D - /* Now draw the lines down the middle */ - - XDrawLine(gXDisplay, gWindow->fMainWindow, gWindow->fStandardGC, - twwidth + hbw, 0, - twwidth + hbw, height); - XDrawLine(gXDisplay, gWindow->fMainWindow, gWindow->fStandardGC, - gWindow->width - twwidth - hbw, 0, - gWindow->width - twwidth - hbw, height); -#endif - - pop_group_stack(); - -#if BITMAPS2D - /* now fill the areas under the bitmaps if we have to */ - - if (gWindow->page->title->height > twheight) { - push_active_group(); - height = height - twheight; - - XFillRectangle(gXDisplay, gWindow->fMainWindow, gWindow->fStandardGC, 0, - twheight, twwidth, height); - XFillRectangle(gXDisplay, gWindow->fMainWindow, gWindow->fStandardGC, - twwidth + gWindow->border_width, - twheight, twwidth, height); - XFillRectangle(gXDisplay, gWindow->fMainWindow, gWindow->fStandardGC, - gWindow->width - 2 * twwidth - gWindow->border_width, - twheight, twwidth, height); - XFillRectangle(gXDisplay, gWindow->fMainWindow, gWindow->fStandardGC, - gWindow->width - twwidth, - twheight, twwidth, height); - pop_group_stack(); - } -#endif -} - -void -linkTitleBarWindows(void) -{ - HyperLink *tw1link = (HyperLink *) halloc(sizeof(HyperLink), "HyperLink"), - *tw2link = (HyperLink *) halloc(sizeof(HyperLink), "HyperLink"), - *tw3link = (HyperLink *) halloc(sizeof(HyperLink), "HyperLink"), - *tw4link = (HyperLink *) halloc(sizeof(HyperLink), "HyperLink"); - - tw1link->win = gWindow->fTitleBarButton1; - tw1link->type = Quitbutton; - tw1link->reference.node = NULL; - tw1link->x = tw1link->y = 0; - - tw2link->win = gWindow->fTitleBarButton2; - tw2link->type = Helpbutton; - tw2link->reference.node = NULL; - tw2link->x = tw2link->y = 0; - - tw3link->win = gWindow->fTitleBarButton3; - tw3link->type = Returnbutton; - tw3link->reference.node = NULL; - tw3link->x = tw3link->y = 0; - - tw4link->win = gWindow->fTitleBarButton4; - tw4link->type = Upbutton; - tw4link->reference.node = NULL; - tw4link->x = tw4link->y = 0; - - hash_insert(gLinkHashTable, (char *)tw1link,(char *) &tw1link->win); - hash_insert(gLinkHashTable, (char *)tw2link,(char *) &tw2link->win); - hash_insert(gLinkHashTable, (char *)tw3link,(char *) &tw3link->win); - hash_insert(gLinkHashTable, (char *)tw4link,(char *) &tw4link->win); -} - -static void -readTitleBarImages(void) -{ - int w, h; - char filename[128]; - char *axiomEnvVar = NULL; - - axiomEnvVar = getenv("AXIOM"); - - if (axiomEnvVar) - sprintf(filename, "%s/share/hypertex/bitmaps/%s", axiomEnvVar, tw1file); - else - sprintf(filename, "%s", tw1file); - tw1image = HTReadBitmapFile(gXDisplay, gXScreenNumber, filename, - &twwidth, &twheight); - - if (axiomEnvVar) - sprintf(filename, "%s/share/hypertex/bitmaps/%s", axiomEnvVar, tw2file); - else - sprintf(filename, "%s", tw2file); - tw2image = HTReadBitmapFile(gXDisplay, gXScreenNumber, filename, - &w, &h); - twwidth = ((twwidth >= w) ? (twwidth) : (w)); - - if (axiomEnvVar) - sprintf(filename, "%s/share/hypertex/bitmaps/%s", axiomEnvVar, tw3file); - else - sprintf(filename, "%s", tw3file); - tw3image = HTReadBitmapFile(gXDisplay, gXScreenNumber, filename, - &w, &h); - twwidth = ((twwidth >= w) ? (twwidth) : (w)); - - if (axiomEnvVar) - sprintf(filename, "%s/share/hypertex/bitmaps/%s", axiomEnvVar, tw4file); - else - sprintf(filename, "%s", tw4file); - tw4image = HTReadBitmapFile(gXDisplay, gXScreenNumber, filename, - &w, &h); - twwidth = ((twwidth >= w) ? (twwidth) : (w)); - - - if (axiomEnvVar) - sprintf(filename, "%s/share/hypertex/bitmaps/%s", axiomEnvVar, noopfile); - else - sprintf(filename, "%s", noopfile); - noopimage = HTReadBitmapFile(gXDisplay, gXScreenNumber, filename, - &twwidth, &twheight); -} - -void -getTitleBarMinimumSize(int *width, int *height) -{ - (*width) = 4 * twwidth + 40; - (*height) = twheight + 2; -} -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - diff --git a/src/hyper/token.h b/src/hyper/token.h new file mode 100644 index 00000000..cc8ed0be --- /dev/null +++ b/src/hyper/token.h @@ -0,0 +1,360 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2008, Gabriel Dos Reis. + All right 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. +*/ + +#ifndef _TOKEN_H_ +#define _TOKEN_H_ 1 + +/* + Here are a couple of flags added for whitespace stuff. They tell + punctuation if there was space in front of it or not +*/ + +#define FRONTSPACE 0001 +#define BACKSPACE 0002 + +/* HyperDoc parser tokens */ + +typedef struct toke { + int type; /* token type. One of those listed below */ + char *id; /* string value if type == Identifier */ +} Token; + +/* + User tokens. ie, these can be found on a page +*/ + +#define Word 1 +#define Page 2 +#define Lispcommandquit 3 +#define BoldFace 4 +#define Link 5 +#define Downlink 6 +#define Beginscroll 7 +#define Spadcommand 8 +#define NoLines 9 +#define Env 10 +#define Par 11 +#define Center 12 +#define Begin 13 +#define Beginitems 14 +#define Item 15 +#define Table 16 +#define Box 17 +#define Tab 18 +#define Space 19 +#define Indent 20 +#define Horizontalline 21 +#define Newline 22 +#define Enditems 23 +#define Returnbutton 24 +#define Memolink 25 +#define Upbutton 26 +#define Endscroll 27 +#define Thispage 28 +#define Returnto 29 +#define Free 30 +#define Bound 31 +#define Lisplink 32 +#define Unixlink 33 +#define Mbox 34 +#define Inputstring 35 +#define StringValue 36 +#define Spadlink 37 +#define Inputbitmap 38 +#define Inputpixmap 39 +#define Unixcommand 40 +#define Emphasize 41 +#define Lispcommand 42 +#define LispMemoLink 43 +#define LispDownLink 44 +#define Spadcall 45 +#define Spadcallquit 46 +#define Spaddownlink 47 +#define Spadmemolink 48 +#define Qspadcall 49 +#define Qspadcallquit 50 +#define SimpleBox 51 +#define Radioboxes 52 +#define BoxValue 53 +#define VSpace 54 +#define HSpace 55 +#define NewCommand 56 +#define WindowId 57 +#define Beep 58 +#define Quitbutton 59 +#define Begintitems 60 +#define Titem 61 +#define End 62 +#define It 63 +#define Sl 64 +#define Tt 65 +#define Rm 66 +#define Ifcond 67 +#define Else 68 +#define Fi 69 +#define Newcond 70 +#define Setcond 71 +#define Button 72 +#define Windowlink 73 +#define Haslisp 74 +#define Hasup 75 +#define Hasreturn 76 +#define Hasreturnto 77 +#define Lastwindow 78 +#define Endtitems 79 +#define Lispwindowlink 80 +#define Beginpile 81 +#define Endpile 82 +#define Nextline 83 +#define Pastebutton 84 +#define Color 85 +#define Helppage 86 +#define Patch 87 +#define Radiobox 88 +#define ifrecond 89 +#define Math 90 +#define Mitem 91 +#define Pagename 92 +#define Examplenumber 93 +#define Replacepage 94 +#define Inputimage 95 +#define Spadgraph 96 +#define Indentrel 97 +#define Controlbitmap 98 + +#define NumberUserTokens 98 + + +extern char *token_table[]; + +#ifdef PARSER +char *token_table[] = { + "", /* Dummy token name */ + "word", + "page", + "lispcommandquit", + "bf", + "link", + "downlink", + "beginscroll", + "spadcommand", + "nolines", + "env", + "par", + "centerline", + "begin", + "beginitems", + "item", + "table", + "fbox", + "tab", + "space", + "indent", + "horizontalline", + "newline", + "enditems", + "returnbutton", + "memolink", + "upbutton", + "endscroll", + "thispage", + "returnto", + "free", + "bound", + "lisplink", + "unixlink", + "mbox", + "inputstring", + "stringvalue", + "spadlink", + "inputbitmap", + "inputpixmap", + "unixcommand", + "em", + "lispcommand", + "lispmemolink", + "lispdownlink", + "spadcall", + "spadcallquit", + "spaddownlink", + "spadmemolink", + "qspadcall", + "qspadcallquit", + "inputbox", + "radioboxes", + "boxvalue", + "vspace", + "hspace", + "newcommand", + "windowid", + "beep", + "quitbutton", + "begintitems", + "titem", + "end", + "it", + "sl", + "tt", + "rm", + "ifcond", + "else", + "fi", + "newcond", + "setcond" , + "button", + "windowlink", + "haslisp", + "hasup", + "hasreturn", + "hasreturnto", + "lastwindow", + "endtitems", + "lispwindowlink", + "beginpile", + "endpile", + "nextline", + "pastebutton", + "color", + "helppage", + "patch", + "radiobox", + "ifrecond", + "math", + "mitem", + "pagename", + "examplenumber", + "replacepage", + "inputimage", + "spadgraph", + "indentrel", + "controlbitmap" + }; +#endif + + +/* places from which input may be read */ +#define FromFile 1 +#define FromString 2 +#define FromSpadSocket 3 +#define FromUnixFD 4 + +extern FILE *unixfd; + +/* + * Here are the system tokens. These are used internally to help + * with parsing and displaying of text + */ + +#define SystemTokens 1001 +#define Lbrace 1001 +#define Rbrace 1002 +#define Macro 1003 +#define Group 1004 +#define Scrollbar 1005 +#define Pound 1006 +#define Lsquarebrace 1007 +#define Rsquarebrace 1008 +#define Punctuation 1009 +#define Dash 1010 +#define Tableitem 1011 +#define Scrollingnode 1012 +#define Headernode 1013 +#define Footernode 1014 +#define Verbatim 1015 +#define Scroll 1016 +#define Dollar 1017 +#define Percent 1018 +#define Carrot 1019 +#define Underscore 1020 +#define Tilde 1021 +#define Cond 1022 +#define Noop 1023 +#define Description 1024 +#define Icorrection 1025 +#define Boxcond 1026 +#define Unkeyword 1027 +#define Titlenode 1028 +#define Paste 1029 +#define Spadsrc 1030 +#define Helpbutton 1031 +#define Spadsrctxt 1032 + + +/* + * Here are the tokens used to mark the end to some sort of group of + * tokens. ie, the tokens found in a centerline command + */ + +#define Endtokens 2000 +#define End1 2001 +#define End2 2002 +#define Endbutton 2003 +#define Endlink 2004 +#define Endheader 2005 +#define Endfooter 2006 +#define Endscrolling 2007 +#define Endgroup 2008 +#define Endarg 2009 +#define Endbox 2010 +#define Endmbox 2011 +#define Endspadcommand 2012 +#define Endpix 2013 +#define Endmacro 2014 +#define Endparameter 2015 +#define Endtable 2016 +#define Endtableitem 2017 +#define End3 2018 +#define Endif 2019 +#define Enddescription 2020 +#define Endinputbox 2021 +#define Endtitle 2022 +#define Endpastebutton 2023 + +#define Endtypes 3000 +#define Endpage 3002 +#define EndScroll 3007 /* had to use a S because Endscroll is + already a keyword */ + +#define Endcenter 3012 +#define EndItems 3014 /* Same thing here as EndScroll except + with the i */ +#define EndTitems 3060 /* Ibid for the T */ +#define Endpatch 3087 +#define Endverbatim 4015 +#define Endmath 4016 +#define Endpaste 4029 +#define Endspadsrc 4030 + +#endif diff --git a/src/hyper/token.pamphlet b/src/hyper/token.pamphlet deleted file mode 100644 index 49360601..00000000 --- a/src/hyper/token.pamphlet +++ /dev/null @@ -1,389 +0,0 @@ -\documentclass{article} -\usepackage{axiom} -\begin{document} -\title{\$SPAD/src/token} -\author{The Axiom Team} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject -\section{token.h} -<>= -<> -#ifndef _TOKEN_H_ -#define _TOKEN_H_ 1 - -/* - Here are a couple of flags added for whitespace stuff. They tell - punctuation if there was space in front of it or not -*/ - -#define FRONTSPACE 0001 -#define BACKSPACE 0002 - -/* HyperDoc parser tokens */ - -typedef struct toke { - int type; /* token type. One of those listed below */ - char *id; /* string value if type == Identifier */ -} Token; - -/* - User tokens. ie, these can be found on a page -*/ - -#define Word 1 -#define Page 2 -#define Lispcommandquit 3 -#define BoldFace 4 -#define Link 5 -#define Downlink 6 -#define Beginscroll 7 -#define Spadcommand 8 -#define NoLines 9 -#define Env 10 -#define Par 11 -#define Center 12 -#define Begin 13 -#define Beginitems 14 -#define Item 15 -#define Table 16 -#define Box 17 -#define Tab 18 -#define Space 19 -#define Indent 20 -#define Horizontalline 21 -#define Newline 22 -#define Enditems 23 -#define Returnbutton 24 -#define Memolink 25 -#define Upbutton 26 -#define Endscroll 27 -#define Thispage 28 -#define Returnto 29 -#define Free 30 -#define Bound 31 -#define Lisplink 32 -#define Unixlink 33 -#define Mbox 34 -#define Inputstring 35 -#define StringValue 36 -#define Spadlink 37 -#define Inputbitmap 38 -#define Inputpixmap 39 -#define Unixcommand 40 -#define Emphasize 41 -#define Lispcommand 42 -#define LispMemoLink 43 -#define LispDownLink 44 -#define Spadcall 45 -#define Spadcallquit 46 -#define Spaddownlink 47 -#define Spadmemolink 48 -#define Qspadcall 49 -#define Qspadcallquit 50 -#define SimpleBox 51 -#define Radioboxes 52 -#define BoxValue 53 -#define VSpace 54 -#define HSpace 55 -#define NewCommand 56 -#define WindowId 57 -#define Beep 58 -#define Quitbutton 59 -#define Begintitems 60 -#define Titem 61 -#define End 62 -#define It 63 -#define Sl 64 -#define Tt 65 -#define Rm 66 -#define Ifcond 67 -#define Else 68 -#define Fi 69 -#define Newcond 70 -#define Setcond 71 -#define Button 72 -#define Windowlink 73 -#define Haslisp 74 -#define Hasup 75 -#define Hasreturn 76 -#define Hasreturnto 77 -#define Lastwindow 78 -#define Endtitems 79 -#define Lispwindowlink 80 -#define Beginpile 81 -#define Endpile 82 -#define Nextline 83 -#define Pastebutton 84 -#define Color 85 -#define Helppage 86 -#define Patch 87 -#define Radiobox 88 -#define ifrecond 89 -#define Math 90 -#define Mitem 91 -#define Pagename 92 -#define Examplenumber 93 -#define Replacepage 94 -#define Inputimage 95 -#define Spadgraph 96 -#define Indentrel 97 -#define Controlbitmap 98 - -#define NumberUserTokens 98 - - -extern char *token_table[]; - -#ifdef PARSER -char *token_table[] = { - "", /* Dummy token name */ - "word", - "page", - "lispcommandquit", - "bf", - "link", - "downlink", - "beginscroll", - "spadcommand", - "nolines", - "env", - "par", - "centerline", - "begin", - "beginitems", - "item", - "table", - "fbox", - "tab", - "space", - "indent", - "horizontalline", - "newline", - "enditems", - "returnbutton", - "memolink", - "upbutton", - "endscroll", - "thispage", - "returnto", - "free", - "bound", - "lisplink", - "unixlink", - "mbox", - "inputstring", - "stringvalue", - "spadlink", - "inputbitmap", - "inputpixmap", - "unixcommand", - "em", - "lispcommand", - "lispmemolink", - "lispdownlink", - "spadcall", - "spadcallquit", - "spaddownlink", - "spadmemolink", - "qspadcall", - "qspadcallquit", - "inputbox", - "radioboxes", - "boxvalue", - "vspace", - "hspace", - "newcommand", - "windowid", - "beep", - "quitbutton", - "begintitems", - "titem", - "end", - "it", - "sl", - "tt", - "rm", - "ifcond", - "else", - "fi", - "newcond", - "setcond" , - "button", - "windowlink", - "haslisp", - "hasup", - "hasreturn", - "hasreturnto", - "lastwindow", - "endtitems", - "lispwindowlink", - "beginpile", - "endpile", - "nextline", - "pastebutton", - "color", - "helppage", - "patch", - "radiobox", - "ifrecond", - "math", - "mitem", - "pagename", - "examplenumber", - "replacepage", - "inputimage", - "spadgraph", - "indentrel", - "controlbitmap" - }; -#endif - - -/* places from which input may be read */ -#define FromFile 1 -#define FromString 2 -#define FromSpadSocket 3 -#define FromUnixFD 4 - -extern FILE *unixfd; - -/* - * Here are the system tokens. These are used internally to help - * with parsing and displaying of text - */ - -#define SystemTokens 1001 -#define Lbrace 1001 -#define Rbrace 1002 -#define Macro 1003 -#define Group 1004 -#define Scrollbar 1005 -#define Pound 1006 -#define Lsquarebrace 1007 -#define Rsquarebrace 1008 -#define Punctuation 1009 -#define Dash 1010 -#define Tableitem 1011 -#define Scrollingnode 1012 -#define Headernode 1013 -#define Footernode 1014 -#define Verbatim 1015 -#define Scroll 1016 -#define Dollar 1017 -#define Percent 1018 -#define Carrot 1019 -#define Underscore 1020 -#define Tilde 1021 -#define Cond 1022 -#define Noop 1023 -#define Description 1024 -#define Icorrection 1025 -#define Boxcond 1026 -#define Unkeyword 1027 -#define Titlenode 1028 -#define Paste 1029 -#define Spadsrc 1030 -#define Helpbutton 1031 -#define Spadsrctxt 1032 - - -/* - * Here are the tokens used to mark the end to some sort of group of - * tokens. ie, the tokens found in a centerline command - */ - -#define Endtokens 2000 -#define End1 2001 -#define End2 2002 -#define Endbutton 2003 -#define Endlink 2004 -#define Endheader 2005 -#define Endfooter 2006 -#define Endscrolling 2007 -#define Endgroup 2008 -#define Endarg 2009 -#define Endbox 2010 -#define Endmbox 2011 -#define Endspadcommand 2012 -#define Endpix 2013 -#define Endmacro 2014 -#define Endparameter 2015 -#define Endtable 2016 -#define Endtableitem 2017 -#define End3 2018 -#define Endif 2019 -#define Enddescription 2020 -#define Endinputbox 2021 -#define Endtitle 2022 -#define Endpastebutton 2023 - -#define Endtypes 3000 -#define Endpage 3002 -#define EndScroll 3007 /* had to use a S because Endscroll is - already a keyword */ - -#define Endcenter 3012 -#define EndItems 3014 /* Same thing here as EndScroll except - with the i */ -#define EndTitems 3060 /* Ibid for the T */ -#define Endpatch 3087 -#define Endverbatim 4015 -#define Endmath 4016 -#define Endpaste 4029 -#define Endspadsrc 4030 - -#endif -@ -\section{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. -*/ - -@ -<<*>>= -<> -<> -@ -\eject -\begin{thebibliography}{99} -\bibitem{1} nothing -\end{thebibliography} -\end{document} - - - - -- cgit v1.2.3