From 4ae82c64d8f219666c2f8315a8a5ab9e30a1c1af Mon Sep 17 00:00:00 2001 From: Igor Pashev Date: Sat, 29 Oct 2022 15:37:18 +0200 Subject: WIP --- Makefile.am | 630 ++++++++++++++++++++++++ configure.ac | 230 +++++++++ m4/m4_ax_cxx_compile_stdcxx.m4 | 1009 ++++++++++++++++++++++++++++++++++++++ m4/open-axiom-deps.m4 | 28 ++ src/clef/edible.c | 516 ------------------- src/clef/edible.cc | 516 +++++++++++++++++++ src/etc/asq.c.pamphlet | 1 - src/graph/Gdraws/Gdraws0.h | 1 - src/graph/view2D/buttons2d.c | 1 - src/graph/view2D/control2d.c | 1 - src/graph/view2D/graph2d.c | 1 - src/graph/view2D/main2d.c | 1 - src/graph/view2D/pot2d.c | 1 - src/graph/view2D/process2d.c | 1 - src/graph/view2D/spadAction2d.c | 1 - src/graph/view2D/stuff2d.c | 1 - src/graph/view2D/write2d.c | 1 - src/graph/view3D/buttons3d.c | 1 - src/graph/view3D/closeView3d.c | 1 - src/graph/view3D/component3d.c | 1 - src/graph/view3D/control3d.c | 1 - src/graph/view3D/illuminate3d.c | 1 - src/graph/view3D/lightbut3d.c | 1 - src/graph/view3D/lighting3d.c | 1 - src/graph/view3D/main3d.c | 1 - src/graph/view3D/mesh3d.c | 1 - src/graph/view3D/msort3d.c | 1 - src/graph/view3D/pot3d.c | 1 - src/graph/view3D/process3d.c | 1 - src/graph/view3D/project3d.c | 1 - src/graph/view3D/quit3d.c | 1 - src/graph/view3D/quitbut3d.c | 1 - src/graph/view3D/save3d.c | 1 - src/graph/view3D/savebut3d.c | 1 - src/graph/view3D/smoothShade3d.c | 1 - src/graph/view3D/spadAction3d.c | 1 - src/graph/view3D/stuff3d.c | 1 - src/graph/view3D/surface3d.c | 1 - src/graph/view3D/testcol.c | 1 - src/graph/view3D/transform3d.c | 1 - src/graph/view3D/viewport3d.c | 1 - src/graph/view3D/volume3d.c | 1 - src/graph/view3D/write3d.c | 1 - src/graph/viewAlone/viewAlone.c | 1 - src/graph/viewman/cleanup.c | 1 - src/graph/viewman/make2D.c | 1 - src/graph/viewman/make3D.c | 1 - src/graph/viewman/makeGraph.c | 1 - src/graph/viewman/readView.c | 1 - src/graph/viewman/sselect.c | 1 - src/graph/viewman/viewman.c | 1 - src/hyper/ReadBitmap.c | 1 - src/hyper/addfile.c | 1 - src/hyper/cond.c | 1 - src/hyper/debug.c | 1 - src/hyper/dialog.c | 1 - src/hyper/display.c | 1 - src/hyper/event.c | 1 - src/hyper/ex2ht.c | 1 - src/hyper/extent.h | 1 - src/hyper/extent1.c | 1 - src/hyper/extent2.c | 1 - src/hyper/form-ext.c | 1 - src/hyper/group.h | 1 - src/hyper/htadd.c | 1 - src/hyper/hthits.c | 1 - src/hyper/htinp.c | 1 - src/hyper/htsearch.cc | 1 - src/hyper/hyper.h | 1 - src/hyper/initx.c | 1 - src/hyper/input.c | 1 - src/hyper/item.c | 1 - src/hyper/keyin.c | 1 - src/hyper/lex.c | 1 - src/hyper/macro.c | 1 - src/hyper/parse-aux.c | 1 - src/hyper/parse-input.c | 1 - src/hyper/parse-paste.c | 1 - src/hyper/parse-paste.h | 1 - src/hyper/parse-types.c | 1 - src/hyper/parse.h | 1 - src/hyper/scrollbar.c | 1 - src/hyper/show-types.c | 1 - src/hyper/spadbuf.c | 1 - src/hyper/titlebar.c | 1 - src/hyper/token.h | 1 - src/include/open-axiom.h | 6 +- src/include/open-axiom/storage | 1 - src/include/sockio.h | 1 - src/lib/XDither.c | 1 - src/lib/XShade.c | 1 - src/lib/XSpadFill.c | 1 - src/lib/bsdsignal.cxx | 1 - src/lib/cfuns-c.cxx | 8 +- src/lib/cursor.c | 144 ------ src/lib/cursor.cc | 143 ++++++ src/lib/edin.c | 951 ----------------------------------- src/lib/edin.cc | 950 +++++++++++++++++++++++++++++++++++ src/lib/emupty.c | 1 - src/lib/fnct_key.c | 345 ------------- src/lib/fnct_key.cc | 344 +++++++++++++ src/lib/halloc.c | 1 - src/lib/hash.c | 1 - src/lib/openpty.c | 168 ------- src/lib/openpty.cc | 171 +++++++ src/lib/pixmap.c | 1 - src/lib/prt.c | 407 --------------- src/lib/prt.cc | 406 +++++++++++++++ src/lib/sockio-c.cxx | 4 +- src/lib/spadcolors.c | 1 - src/lib/util.c | 1 - src/lib/wct.c | 732 --------------------------- src/lib/wct.cc | 731 +++++++++++++++++++++++++++ src/lisp/core.lisp.in | 6 +- src/sman/session.c | 534 -------------------- src/sman/session.cc | 534 ++++++++++++++++++++ src/sman/sman.c | 794 ------------------------------ src/sman/sman.cc | 794 ++++++++++++++++++++++++++++++ src/sman/spadclient.c | 75 --- src/sman/spadclient.cc | 74 +++ src/utils/command.cc | 5 +- src/utils/hammer.cc | 2 +- src/utils/storage.cxx | 12 + 123 files changed, 6592 insertions(+), 4769 deletions(-) create mode 100644 Makefile.am create mode 100644 configure.ac create mode 100644 m4/m4_ax_cxx_compile_stdcxx.m4 create mode 100644 m4/open-axiom-deps.m4 delete mode 100644 src/clef/edible.c create mode 100644 src/clef/edible.cc delete mode 100644 src/lib/cursor.c create mode 100644 src/lib/cursor.cc delete mode 100644 src/lib/edin.c create mode 100644 src/lib/edin.cc delete mode 100644 src/lib/fnct_key.c create mode 100644 src/lib/fnct_key.cc delete mode 100644 src/lib/openpty.c create mode 100644 src/lib/openpty.cc delete mode 100644 src/lib/prt.c create mode 100644 src/lib/prt.cc delete mode 100644 src/lib/wct.c create mode 100644 src/lib/wct.cc delete mode 100644 src/sman/session.c create mode 100644 src/sman/session.cc delete mode 100644 src/sman/sman.c create mode 100644 src/sman/sman.cc delete mode 100644 src/sman/spadclient.c create mode 100644 src/sman/spadclient.cc diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 00000000..040407f5 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,630 @@ +SUFFIXES = .lisp .clisp .cl .boot .$(FASLEXT) + +FASL_V = $(FASL_V_@AM_V@) +FASL_V_ = $(FASL_V_@AM_DEFAULT_V@) +FASL_V_0 = @echo " FASL " $@; + +OALD_V = $(OALD_V_@AM_V@) +OALD_V_ = $(OALD_V_@AM_DEFAULT_V@) +OALD_V_0 = @echo " OALD " $@; + +DISTCLEANFILES = $(OA_DEPS_FILE) + +noinst_PROGRAMS = +libexec_PROGRAMS = +CLEANFILES = +DRIVER = $(top_builddir)/open-axiom$(EXEEXT) + +bin_PROGRAMS = open-axiom +open_axiom_CPPFLAGS = -I$(srcdir)/src/include +open_axiom_CPPFLAGS += -DOPENAXIOM_ROOT_DIRECTORY="\"$(libexecdir)\"" +open_axiom_SOURCES = \ + src/driver/main.cc \ + src/lib/cfuns-c.cxx \ + src/utils/command.cc + + +libexec_PROGRAMS += session +session_CPPFLAGS = -I$(srcdir)/src/include +session_SOURCES = \ + src/lib/bsdsignal.cxx \ + src/lib/cfuns-c.cxx \ + src/lib/sockio-c.cxx \ + src/sman/session.cc + +libexec_PROGRAMS += sman +sman_CPPFLAGS = -I$(srcdir)/src/include +sman_CPPFLAGS += -DOPENAXIOM_ROOT_DIRECTORY="\"$(libexecdir)\"" +sman_SOURCES = \ + src/lib/bsdsignal.cxx \ + src/lib/cfuns-c.cxx \ + src/lib/sockio-c.cxx \ + src/lib/openpty.cc \ + src/sman/sman.cc \ + src/utils/command.cc + +libexec_PROGRAMS += spadclient +spadclient_CPPFLAGS = -I$(srcdir)/src/include +spadclient_SOURCES = \ + src/lib/bsdsignal.cxx \ + src/lib/cfuns-c.cxx \ + src/lib/sockio-c.cxx \ + src/sman/spadclient.cc + +libexec_PROGRAMS += clef +clef_CPPFLAGS = -I$(srcdir)/src/include +clef_SOURCES = \ + src/clef/edible.cc \ + src/lib/bsdsignal.cxx \ + src/lib/cfuns-c.cxx \ + src/lib/cursor.cc \ + src/lib/edin.cc \ + src/lib/fnct_key.cc \ + src/lib/openpty.cc \ + src/lib/prt.cc \ + src/lib/wct.cc + + +noinst_PROGRAMS += hammer +hammer_CPPFLAGS = -I$(srcdir)/src/include +hammer_SOURCES = \ + src/utils/hammer.cc \ + src/utils/storage.cxx + +noinst_PROGRAMS += oalisp +am_oalisp_OBJECTS = $(oalisp_SOURCES:.lisp=.$(FASLEXT)) +CLEANFILES += $(am_oalisp_OBJECTS) +oalisp_SOURCES = src/lisp/core.lisp +oalisp_LINK = $(OA_LISP) $(OA_LISP_BATCH_FLAGS) $(OA_LISP_EVAL_FLAGS) '(load "$<")' $(OA_LISP_EVAL_FLAGS) '(|AxiomCore|::|link| "$@" (quote nil) "|AxiomCore|::|topLevel|")' \# +src/lisp/core.$(FASLEXT): src/lisp/core.lisp + $(FASL_V)$(OA_LISP) $(OA_LISP_BATCH_FLAGS) $(OA_LISP_EVAL_FLAGS) '(progn (setq *compile-print* nil *compile-verbose* nil) (compile-file "$<") (quit))' + +noinst_PROGRAMS += bootsys0 +bootsys0_LINK = $(DRIVER) --execpath=oalisp$(EXEEXT) --make --main='|AxiomCore|::|topLevel|' --prologue='(pushnew :open-axiom-boot *features*)' --load-directory=$( +#endif +]]) + +AC_CHECK_HEADERS_ONCE([sys/mman.h]) +AC_CHECK_DECLS([MAP_ANONYMOUS, MAP_ANON], [], [], [[ +#ifdef HAVE_SYS_MMAN_H +#include +#endif +]]) + + +AC_CHECK_HEADERS_ONCE([sys/socket.h sys/un.h]) +AC_CHECK_DECLS([AF_LOCAL, AF_UNIX], [], [], [[ +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_SYS_UN_H +#include +#endif +]]) + +AC_CHECK_HEADERS_ONCE([libutil.h pty.h termios.h util.h]) +AC_CHECK_DECLS([openpty], [], [], [[ +#if HAVE_SYS_IOCTL_H +# include +#endif +#if HAVE_SYS_TYPESL_H +# include +#endif +#if HAVE_LIBUTIL_H +# include +#endif +#if HAVE_PTY_H +# include +#endif +#if HAVE_TERMIOS_H +# include +#endif +#if HAVE_UTIL_H +# include +#endif +]]) +AC_SEARCH_LIBS([openpty], [util]) + + +dnl **** LISP **** + +AC_ARG_WITH([lisp], + [AS_HELP_STRING([--with-lisp=LISP], [use LISP to build Open Axiom])], + [OA_LISP="$withval"], + [AC_PATH_PROGS([OA_LISP], [sbcl gcl ecl clisp clozure], [none])]) +AS_IF([test "x$OA_LISP" = xnone], [AC_MSG_ERROR([could not find suitable Lisp])]) + +AC_MSG_CHECKING([Lisp]) +AC_MSG_RESULT([$OA_LISP]) + +AC_MSG_CHECKING([for Lisp flavor]) +oa_lisp_impl_type=`echo '(lisp-implementation-type)' | $OA_LISP 2>&AS_MESSAGE_LOG_FD` +AS_CASE([$oa_lisp_impl_type], + [*"SBCL"*], [oa_lisp_flavor="sbcl"], + [*"GNU Common Lisp"*], [oa_lisp_flavor="gcl"], + [*"Embeddable Common-Lisp"*], [oa_lisp_flavor="ecl"], + [*"CLISP"*], [oa_lisp_flavor="clisp"], + [*"Clozure Common Lisp"*], [oa_lisp_flavor="clozure"], + [AC_MSG_RESULT([unknown]) + AC_MSG_ERROR([unsupported Lisp])]) +AC_MSG_RESULT([$oa_lisp_flavor]) + +AS_CASE([$oa_lisp_flavor], + [sbcl], [OA_LISP_BATCH_FLAGS='--noinform --noprint --no-sysinit --no-userinit --disable-debugger' + OA_LISP_EVAL_FLAGS='--eval' + oa_delay_ffi=yes + char_type='char' + double_type='double' + float_type='float' + int_type='int' + pointer_type='(* t)' + string_type='c-string' + void_type='void'], + [gcl], [OA_LISP_BATCH_FLAGS='-batch' + OA_LISP_EVAL_FLAGS='-eval' + oa_delay_ffi=no + void_type='void' + char_type='char' + int_type='int' + float_type='float' + double_type='double' + string_type='string' + AS_IF([test "x$SIZEOF_VOID_P" = x4], [pointer_type='fixnum'], [pointer_type='(signed-integer 64)'])], + [ecl], [OA_LISP_BATCH_FLAGS='--nodebug --norc' + OA_LISP_EVAL_FLAGS='--eval' + oa_delay_ffi=no + void_type=':void' + char_type=':char' + int_type=':int' + float_type=':float' + double_type=':double' + string_type=':cstring' + pointer_type=':pointer-void'], + [clisp], [OA_LISP_BATCH_FLAGS='-q -q -norc' + OA_LISP_EVAL_FLAGS='-x' + oa_delay_ffi=yes + void_type='nil' + char_type='character' + int_type='int' + float_type='single-float' + double_type='double-float' + string_type='c-string' + pointer_type='c-pointer'], + [clozure], [OA_LISP_BATCH_FLAGS='--quiet --no-init' + OA_LISP_EVAL_FLAGS='--eval' + oa_delay_ffi=yes + void_type=':void' + char_type=':unsigned-byte' + int_type=':signed-fullword' + float_type=':single-float' + double_type=':double-float' + string_type=':address' + pointer_type=':address'], + [AC_MSG_ERROR([unsupported Lisp flavor $oa_lisp_flavor])]) + +AC_MSG_CHECKING([how to invoke Lisp]) +AC_MSG_RESULT([$OA_LISP $OA_LISP_BATCH_FLAGS $OA_LISP_EVAL_FLAGS]) + +AC_MSG_CHECKING([for compiled Lisp file extension]) +oa_fasl_type=`$OA_LISP $OA_LISP_BATCH_FLAGS $OA_LISP_EVAL_FLAGS '(progn (format t "oa_fasl_type:~a" (pathname-type (compile-file-pathname "non-existing.lisp"))) (quit))' 2>&AS_MESSAGE_LOG_FD` +AS_IF([test "x$oa_fasl_type" = x], [AC_MSG_RESULT([failed]) + AC_MSG_ERROR([Lisp compiler does not work, see config.log for details])]) +oa_fasl_type=`echo "$oa_fasl_type" | $AWK -F : '/oa_fasl_type:/{print $2}'` +AC_MSG_RESULT([$oa_fasl_type]) + +AC_SUBST([OA_LISP]) +AC_SUBST([OA_LISP_BATCH_FLAGS]) +AC_SUBST([OA_LISP_EVAL_FLAGS]) +AC_SUBST([FASLEXT], [$oa_fasl_type]) +AC_DEFINE_UNQUOTED([FASLEXT], ["$oa_fasl_type"], [Compiled Lisp file extension (usually "fasl").]) +AC_DEFINE_UNQUOTED([OPENAXIOM_BASE_RTS], [Runtime::$oa_lisp_flavor], [The kind of base runtime system for this build.]) + +AC_MSG_CHECKING([Lisp char type]) +AC_MSG_RESULT([$char_type]) +AC_SUBST([char_type]) + +AC_MSG_CHECKING([Lisp double type]) +AC_MSG_RESULT([$double_type]) +AC_SUBST([double_type]) + +AC_SUBST([float_type]) +AC_MSG_CHECKING([Lisp float type]) +AC_MSG_RESULT([$float_type]) + +AC_MSG_CHECKING([Lisp int type]) +AC_MSG_RESULT([$int_type]) +AC_SUBST([int_type]) + +AC_MSG_CHECKING([Lisp pointer type]) +AC_MSG_RESULT([$pointer_type]) +AC_SUBST([pointer_type]) + +AC_MSG_CHECKING([Lisp string type]) +AC_MSG_RESULT([$string_type]) +AC_SUBST([string_type]) + +AC_MSG_CHECKING([Lisp void type]) +AC_MSG_RESULT([$void_type]) +AC_SUBST([void_type]) + + +AC_SUBST([oa_delay_ffi]) +AC_SUBST([oa_editor], [/usr/bin/editor]) +AC_SUBST([oa_enable_profiling], [nil]) +AC_SUBST([oa_keep_files], []) +AC_SUBST([oa_optimize_options], [speed]) +AC_SUBST([oa_standard_linking], [no]) +AC_SUBST([oa_use_llvm], [no]) +AC_SUBST([oa_c_runtime_extra], []) + + +AC_DEFINE_UNQUOTED([OPENAXIOM_EXEEXT], ["$ac_cv_exeext"], [File extensions of the executables (e. g. ".exe").]) +AC_DEFINE_UNQUOTED([OPENAXIOM_USE_GUI], [0], [Whether to use the Qt-base GUI as driver.]) +AC_DEFINE_UNQUOTED([OPENAXIOM_USE_SMAN], [1], [Whether to use the session manager as driver.]) + +OA_DEPS=dependencies.mk +rm -f "$OA_DEPS" +OA_RESOLVE_DEPENDENCIES([src/boot], ["$OA_DEPS"]) +OA_RESOLVE_DEPENDENCIES([src/boot/strap], ["$OA_DEPS"]) +OA_RESOLVE_DEPENDENCIES([src/interp], ["$OA_DEPS"]) +AC_SUBST_FILE([OA_DEPS]) +AC_SUBST([OA_DEPS_FILE], [$OA_DEPS]) + +AC_CONFIG_LINKS([src/boot/stage1/ast.boot:src/boot/ast.boot + src/boot/stage1/includer.boot:src/boot/includer.boot + src/boot/stage1/parser.boot:src/boot/parser.boot + src/boot/stage1/pile.boot:src/boot/pile.boot + src/boot/stage1/scanner.boot:src/boot/scanner.boot + src/boot/stage1/tokens.boot:src/boot/tokens.boot + src/boot/stage1/translator.boot:src/boot/translator.boot + src/boot/stage1/utility.boot:src/boot/utility.boot]) + +AC_CONFIG_FILES([Makefile src/lisp/core.lisp]) +AC_OUTPUT + diff --git a/m4/m4_ax_cxx_compile_stdcxx.m4 b/m4/m4_ax_cxx_compile_stdcxx.m4 new file mode 100644 index 00000000..a3d964c6 --- /dev/null +++ b/m4/m4_ax_cxx_compile_stdcxx.m4 @@ -0,0 +1,1009 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the specified +# version of the C++ standard. If necessary, add switches to CXX and +# CXXCPP to enable support. VERSION may be '11', '14', '17', or '20' for +# the respective C++ standard version. +# +# The second argument, if specified, indicates whether you insist on an +# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. +# -std=c++11). If neither is specified, you get whatever works, with +# preference for no added switch, and then for an extended mode. +# +# The third argument, if specified 'mandatory' or if left unspecified, +# indicates that baseline support for the specified C++ standard is +# required and that the macro should error out if no mode with that +# support is found. If specified 'optional', then configuration proceeds +# regardless, after defining HAVE_CXX${VERSION} if and only if a +# supporting mode is found. +# +# LICENSE +# +# Copyright (c) 2008 Benjamin Kosnik +# Copyright (c) 2012 Zack Weinberg +# Copyright (c) 2013 Roy Stogner +# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov +# Copyright (c) 2015 Paul Norman +# Copyright (c) 2015 Moritz Klammler +# Copyright (c) 2016, 2018 Krzesimir Nowak +# Copyright (c) 2019 Enji Cooper +# Copyright (c) 2020 Jason Merrill +# Copyright (c) 2021 Jörn Heusipp +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 15 + +dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro +dnl (serial version number 13). + +AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl + m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], + [$1], [14], [ax_cxx_compile_alternatives="14 1y"], + [$1], [17], [ax_cxx_compile_alternatives="17 1z"], + [$1], [20], [ax_cxx_compile_alternatives="20"], + [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$2], [], [], + [$2], [ext], [], + [$2], [noext], [], + [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], + [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], + [$3], [optional], [ax_cxx_compile_cxx$1_required=false], + [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) + AC_LANG_PUSH([C++])dnl + ac_success=no + + m4_if([$2], [], [dnl + AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, + ax_cv_cxx_compile_cxx$1, + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [ax_cv_cxx_compile_cxx$1=yes], + [ax_cv_cxx_compile_cxx$1=no])]) + if test x$ax_cv_cxx_compile_cxx$1 = xyes; then + ac_success=yes + fi]) + + m4_if([$2], [noext], [], [dnl + if test x$ac_success = xno; then + for alternative in ${ax_cxx_compile_alternatives}; do + switch="-std=gnu++${alternative}" + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + fi]) + + m4_if([$2], [ext], [], [dnl + if test x$ac_success = xno; then + dnl HP's aCC needs +std=c++11 according to: + dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf + dnl Cray's crayCC needs "-h std=c++11" + for alternative in ${ax_cxx_compile_alternatives}; do + for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + if test x$ac_success = xyes; then + break + fi + done + fi]) + AC_LANG_POP([C++]) + if test x$ax_cxx_compile_cxx$1_required = xtrue; then + if test x$ac_success = xno; then + AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) + fi + fi + if test x$ac_success = xno; then + HAVE_CXX$1=0 + AC_MSG_NOTICE([No compiler with C++$1 support was found]) + else + HAVE_CXX$1=1 + AC_DEFINE(HAVE_CXX$1,1, + [define if the compiler supports basic C++$1 syntax]) + fi + AC_SUBST(HAVE_CXX$1) +]) + + +dnl Test body for checking C++11 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 +) + +dnl Test body for checking C++14 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 +) + +dnl Test body for checking C++17 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 +) + +dnl Test body for checking C++20 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_20], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_20 +) + + +dnl Tests for new features in C++11 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +// MSVC always sets __cplusplus to 199711L in older versions; newer versions +// only set it correctly if /Zc:__cplusplus is specified as well as a +// /std:c++NN switch: +// https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ +#elif __cplusplus < 201103L && !defined _MSC_VER + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual ~Base() {} + virtual void f() {} + }; + + struct Derived : public Base + { + virtual ~Derived() override {} + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + +]]) + + +dnl Tests for new features in C++14 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L && !defined _MSC_VER + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + + namespace test_polymorphic_lambdas + { + + int + test() + { + const auto lambda = [](auto&&... args){ + const auto istiny = [](auto x){ + return (sizeof(x) == 1UL) ? 1 : 0; + }; + const int aretiny[] = { istiny(args)... }; + return aretiny[0]; + }; + return lambda(1, 1L, 1.0f, '1'); + } + + } + + namespace test_binary_literals + { + + constexpr auto ivii = 0b0000000000101010; + static_assert(ivii == 42, "wrong value"); + + } + + namespace test_generalized_constexpr + { + + template < typename CharT > + constexpr unsigned long + strlen_c(const CharT *const s) noexcept + { + auto length = 0UL; + for (auto p = s; *p; ++p) + ++length; + return length; + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("x") == 1UL, ""); + static_assert(strlen_c("test") == 4UL, ""); + static_assert(strlen_c("another\0test") == 7UL, ""); + + } + + namespace test_lambda_init_capture + { + + int + test() + { + auto x = 0; + const auto lambda1 = [a = x](int b){ return a + b; }; + const auto lambda2 = [a = lambda1(x)](){ return a; }; + return lambda2(); + } + + } + + namespace test_digit_separators + { + + constexpr auto ten_million = 100'000'000; + static_assert(ten_million == 100000000, ""); + + } + + namespace test_return_type_deduction + { + + auto f(int& x) { return x; } + decltype(auto) g(int& x) { return x; } + + template < typename T1, typename T2 > + struct is_same + { + static constexpr auto value = false; + }; + + template < typename T > + struct is_same + { + static constexpr auto value = true; + }; + + int + test() + { + auto x = 0; + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + return x; + } + + } + +} // namespace cxx14 + +#endif // __cplusplus >= 201402L + +]]) + + +dnl Tests for new features in C++17 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ + +// If the compiler admits that it is not ready for C++17, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201703L && !defined _MSC_VER + +#error "This is not a C++17 compiler" + +#else + +#include +#include +#include + +namespace cxx17 +{ + + namespace test_constexpr_lambdas + { + + constexpr int foo = [](){return 42;}(); + + } + + namespace test::nested_namespace::definitions + { + + } + + namespace test_fold_expression + { + + template + int multiply(Args... args) + { + return (args * ... * 1); + } + + template + bool all(Args... args) + { + return (args && ...); + } + + } + + namespace test_extended_static_assert + { + + static_assert (true); + + } + + namespace test_auto_brace_init_list + { + + auto foo = {5}; + auto bar {5}; + + static_assert(std::is_same, decltype(foo)>::value); + static_assert(std::is_same::value); + } + + namespace test_typename_in_template_template_parameter + { + + template typename X> struct D; + + } + + namespace test_fallthrough_nodiscard_maybe_unused_attributes + { + + int f1() + { + return 42; + } + + [[nodiscard]] int f2() + { + [[maybe_unused]] auto unused = f1(); + + switch (f1()) + { + case 17: + f1(); + [[fallthrough]]; + case 42: + f1(); + } + return f1(); + } + + } + + namespace test_extended_aggregate_initialization + { + + struct base1 + { + int b1, b2 = 42; + }; + + struct base2 + { + base2() { + b3 = 42; + } + int b3; + }; + + struct derived : base1, base2 + { + int d; + }; + + derived d1 {{1, 2}, {}, 4}; // full initialization + derived d2 {{}, {}, 4}; // value-initialized bases + + } + + namespace test_general_range_based_for_loop + { + + struct iter + { + int i; + + int& operator* () + { + return i; + } + + const int& operator* () const + { + return i; + } + + iter& operator++() + { + ++i; + return *this; + } + }; + + struct sentinel + { + int i; + }; + + bool operator== (const iter& i, const sentinel& s) + { + return i.i == s.i; + } + + bool operator!= (const iter& i, const sentinel& s) + { + return !(i == s); + } + + struct range + { + iter begin() const + { + return {0}; + } + + sentinel end() const + { + return {5}; + } + }; + + void f() + { + range r {}; + + for (auto i : r) + { + [[maybe_unused]] auto v = i; + } + } + + } + + namespace test_lambda_capture_asterisk_this_by_value + { + + struct t + { + int i; + int foo() + { + return [*this]() + { + return i; + }(); + } + }; + + } + + namespace test_enum_class_construction + { + + enum class byte : unsigned char + {}; + + byte foo {42}; + + } + + namespace test_constexpr_if + { + + template + int f () + { + if constexpr(cond) + { + return 13; + } + else + { + return 42; + } + } + + } + + namespace test_selection_statement_with_initializer + { + + int f() + { + return 13; + } + + int f2() + { + if (auto i = f(); i > 0) + { + return 3; + } + + switch (auto i = f(); i + 4) + { + case 17: + return 2; + + default: + return 1; + } + } + + } + + namespace test_template_argument_deduction_for_class_templates + { + + template + struct pair + { + pair (T1 p1, T2 p2) + : m1 {p1}, + m2 {p2} + {} + + T1 m1; + T2 m2; + }; + + void f() + { + [[maybe_unused]] auto p = pair{13, 42u}; + } + + } + + namespace test_non_type_auto_template_parameters + { + + template + struct B + {}; + + B<5> b1; + B<'a'> b2; + + } + + namespace test_structured_bindings + { + + int arr[2] = { 1, 2 }; + std::pair pr = { 1, 2 }; + + auto f1() -> int(&)[2] + { + return arr; + } + + auto f2() -> std::pair& + { + return pr; + } + + struct S + { + int x1 : 2; + volatile double y1; + }; + + S f3() + { + return {}; + } + + auto [ x1, y1 ] = f1(); + auto& [ xr1, yr1 ] = f1(); + auto [ x2, y2 ] = f2(); + auto& [ xr2, yr2 ] = f2(); + const auto [ x3, y3 ] = f3(); + + } + + namespace test_exception_spec_type_system + { + + struct Good {}; + struct Bad {}; + + void g1() noexcept; + void g2(); + + template + Bad + f(T*, T*); + + template + Good + f(T1*, T2*); + + static_assert (std::is_same_v); + + } + + namespace test_inline_variables + { + + template void f(T) + {} + + template inline T g(T) + { + return T{}; + } + + template<> inline void f<>(int) + {} + + template<> int g<>(int) + { + return 5; + } + + } + +} // namespace cxx17 + +#endif // __cplusplus < 201703L && !defined _MSC_VER + +]]) + + +dnl Tests for new features in C++20 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_20], [[ + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 202002L && !defined _MSC_VER + +#error "This is not a C++20 compiler" + +#else + +#include + +namespace cxx20 +{ + +// As C++20 supports feature test macros in the standard, there is no +// immediate need to actually test for feature availability on the +// Autoconf side. + +} // namespace cxx20 + +#endif // __cplusplus < 202002L && !defined _MSC_VER + +]]) diff --git a/m4/open-axiom-deps.m4 b/m4/open-axiom-deps.m4 new file mode 100644 index 00000000..595c6da3 --- /dev/null +++ b/m4/open-axiom-deps.m4 @@ -0,0 +1,28 @@ +# Resolve dependencies between *.boot, *.lisp, *.clisp +# and other OpenAxiom source files within the given directory. +# Dependencies will be written (appended) to the makefile: +# +# OA_RESOLVE_DEPENDENCIES(directory, makefile) +# +# Example: +# +# OA_RESOLVE_DEPENDENCIES([src/boot/strap], [Makefile]) +# +# ----------------------------- +AC_DEFUN([OA_RESOLVE_DEPENDENCIES], +[ AC_MSG_CHECKING([dependencies in $1]) + for f in $1/*.clisp $1/*.lisp $1/*.boot + do + AS_IF([test -f "$f"], + [AS_CASE(["$f"], + [*.boot], [OA_EXTRACT_BOOT([/^import @<:@^ @:>@+$/], [/^import /], [/$/], [$1], ["$f"]) >> $2], + [*.clisp], [OA_EXTRACT_LISP([/\((IMPORT-MODULE|import-module) "/], [/"\)/], [$1], ["$f"]) >> $2], + [*.lisp], [OA_EXTRACT_LISP([/\((IMPORT-MODULE|import-module) "/], [/"\)/], [$1], ["$f"]) >> $2])]) + done + AC_MSG_RESULT([done])]) + +AC_DEFUN([OA_EXTRACT_LISP], [OA_EXTRACT([$1], [$1], [$2], [$3], [$4])]) +AC_DEFUN([OA_EXTRACT_BOOT], [OA_EXTRACT([$1], [$2], [$3], [$4], [$5])]) + +AC_DEFUN([OA_EXTRACT], +[$AWK 'BEGIN {t=ARGV@<:@1@:>@; sub(/\.@<:@^.@:>@+$/,".$(FASLEXT)",t)} $1 {gsub ($2, "$4/"); gsub($3, ".$(FASLEXT)"); gsub(/_-/, "-"); r=r " " @S|@0} END {printf("%s:%s\n", t, r)}' $5]) diff --git a/src/clef/edible.c b/src/clef/edible.c deleted file mode 100644 index c3022060..00000000 --- a/src/clef/edible.c +++ /dev/null @@ -1,516 +0,0 @@ -/* - Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. - All rights reserved. - Copyright (C) 2007-2014, 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "open-axiom.h" -#include "sockio.h" -#include "edible.h" -#include "com.h" -#include "bsdsignal.h" - -#include "openpty.h" -#include "prt.h" -#include "edin.h" -#include "wct.h" -#include "fnct_key.h" -#include "cfuns.h" - -using namespace OpenAxiom; - -#ifdef AXIOM_UNLIKELY -#define log 1 -#define logterm 1 -#define siglog 1 -#endif - - -#define Cursor_shape(x) - -static void catch_signals(void); -static void init_parent(void); -static void set_function_chars(void); - - -#ifdef siglog -int sigfile; -char sigbuff[256]; -#endif - -/* Here are the term structures I need for setting and resetting the - terminal characteristics. */ - -struct termios childbuf; /* the childs normal operating termio */ -struct termios oldbuf; /* the initial settings */ -struct termios rawbuf; /* the parents raw state, when it is doing nothing */ -struct termios canonbuf; /* set it to be canonical */ - -/* the terminals mapping of the function keys */ -unsigned char _INTR, _QUIT, _ERASE, _KILL, _EOF, _EOL, _RES1, _RES2; - - -int ppid; /* the parents's parent pid */ -int child_pid; /* the childs process id */ - -short INS_MODE ; /* Flag for insert mode */ -short ECHOIT = 1; /* Flag for echoing */ -short PTY; /* Flag which tells me whether I should echo newlines */ - -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 **/ - - -char serverPath[20]; /* path name for opening the server side */ - -int contNum, serverNum; /* file descriptors for pty's */ -int num_read; /* Number of chars read */ - -#ifdef log -int logfd; -char logpath[30]; -#endif - - - - - -int -main(int argc, char *argv[]) -{ - using namespace OpenAxiom; - fd_set rfds; /* the structure for the select call */ - int code; /* return code from system calls */ - char out_buff[MAXLINE]; /* from child and stdin */ - int out_flag[MAXLINE] ; /* initialize the output flags */ - char *program; /* a string to hold the child program invocation */ - char **pargs = 0; /* holds parts of the command line */ - int not_command = 1; /* a flag while parsing the command line */ - - - - oa_setenv("LC_ALL", "C"); - setlocale(LC_ALL, ""); - /* try to get a pseudoterminal to play with */ - if (ptyopen(&contNum, &serverNum, serverPath) == -1) { - perror("ptyopen failed"); - exit(-1); - } - - /* call the routine that handles signals */ - catch_signals(); - - /* parse the command line arguments - as with the aixterm the command - argument -e should be last on the line. */ - - while(*++argv && not_command) { - if(!strcmp(*argv, "-f")) - load_wct_file(*++argv); - else if(!strcmp(*argv, "-e")) { - not_command = 0; - pargs = ++argv; - } - else { - fprintf(stderr, "usage: clef [-f fname] -e command\n"); - exit(-1); - } - } - skim_wct(); - -#ifdef log - sprintf(logpath, "/tmp/cleflog%d", oa_getpid()); - logfd = open(logpath, O_CREAT | O_RDWR, 0666); -#endif - - /* get the original termio settings, so the child has them */ - - if(tcgetattr(0,&childbuf) == -1) { - perror("clef trying to get the initial terminal settings"); - exit(-1); - } - - /* start the child process */ - - child_pid = fork(); - switch(child_pid) { - case -1 : - perror("clef can't create a new process"); - exit(-1); - case 0: - /* CHILD */ - /* Dissasociate form my parents group so all my child processes - look at my terminal as the controlling terminal for the group */ - setsid(); - - serverNum = open(serverPath,O_RDWR); - if (serverNum == -1) perror("open serverPath failed"); - - /* since I am the child, I can close ptc, and dup pts for all it - standard descriptors */ - if (dup2(serverNum, 0) == -1) perror("dup2 0 failed"); - if (dup2(serverNum, 1) == -1) perror("dup2 1 failed"); - if (dup2(serverNum, 2) == -1) perror("dup2 2 failed"); - if( (dup2(serverNum, 0) == -1) || - (dup2(serverNum, 1) == -1) || - (dup2(serverNum, 2) == -1) ) { - perror("clef trying to dup2"); - exit(-1); - } - - /* since they have been duped, close them */ - close(serverNum); - close(contNum); - - - /* To make sure everything is nice, set off enhedit */ - /* childbuf.c_line = 0; */ - - /* reconfigure the child's terminal get echoing */ - if(tcsetattr(0, TCSAFLUSH, &childbuf) == -1) { - perror("clef child trying to set child's terminal"); - exit(-1); - } - - /* fire up the child's process */ - if(pargs){ - execvp( pargs[0], pargs); - perror("clef trying to execvp its argument"); - fprintf(stderr, "Process --> %s\n", pargs[0]); - } - else{ - program = oa_getenv("SHELL"); - if (!program) - program = strdup("/bin/sh"); - else - program = strdup (program); - execlp( program,program, (char *) NULL); - perror("clef trying to execlp the default child"); - fprintf(stderr, "Process --> %s\n", program); - } - exit(-1); - break; - /* end switch */ - } - /* PARENT */ - /* Since I am the parent, I should start to initialize some stuff. - I have to close the pts side for it to work properly */ - - close(serverNum); - ppid = getppid(); - - /* Iinitialize some stuff for the reading and writing */ - init_flag(out_flag, MAXLINE); - define_function_keys(); - init_reader(); - PTY = 1; - init_parent(); - - /* Here is the main loop, it simply starts reading characters from - the std input, and from the child. */ - - while(1) { /* loop forever */ - - /* use select to see who has stuff waiting for me to handle */ - /* set file descriptors for ptc and stdin */ - FD_ZERO(&rfds); - FD_SET(contNum,&rfds); - FD_SET(0,&rfds); - set_function_chars(); -#ifdef log - { - char modepath[30]; - sprintf(modepath, "\nMODE = %d\n", MODE); - write(logfd, modepath, strlen(modepath)); - } -#endif -#ifdef logterm - { - struct termio ptermio; - char pbuff[1024]; - tcgetattr(contNum, &ptermio); - sprintf(pbuff, "child's settings: Lflag = %d, Oflag = %d, Iflag = %d\n", - ptermio.c_lflag, ptermio.c_oflag, ptermio.c_iflag); - write(logfd, pbuff, strlen(pbuff)); - } -#endif - - code = select(FD_SETSIZE, &rfds, NULL, NULL, NULL); - for(; code < 0 ;) { - if(errno == EINTR) { - code = select(FD_SETSIZE, &rfds, NULL, NULL, NULL); - } - else { - perror("clef select failure"); - exit(-1); - } - } - - /* reading from the child **/ - if( FD_ISSET(contNum,&rfds)) { - if( (num_read = read(contNum, out_buff, MAXLINE)) == -1) { - num_read = 0; - } -#ifdef log - write(logfd, "OUT<<<<<", strlen("OUT<<<<<")); - write(logfd, out_buff, num_read); -#endif - if(num_read > 0) { - /* now do the printing to the screen */ - if(MODE!= CLEFRAW) { - back_up(buff_pntr); - write(1,out_buff, num_read); - print_whole_buff(); /* reprint the input buffer */ - } - else write(1,out_buff, num_read); - } - } /* done the child stuff */ - /* I should read from std input */ - else { - if(FD_ISSET(0,&rfds)) { - num_read = read(0, in_buff, MAXLINE); -#ifdef log - write(logfd, "IN<<<<<", strlen("IN<<<<<")); - write(logfd, in_buff, num_read); -#endif - if(MODE == CLEFRAW ) - write(contNum, in_buff, num_read); - else - 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 terminal initial settings"); - exit(-1); - } - - /* get the settings for my different modes */ - if ((tcgetattr(0, &canonbuf) == -1) || - (tcgetattr(0, &rawbuf) == -1) ) { - perror("clef trying to get terminal settings"); - exit(-1); - } - - - canonbuf.c_lflag &= ~(ICANON | ECHO | ISIG); - /* read before an eoln is typed */ - - canonbuf.c_lflag |= ISIG; - - /* canonbuf.c_line = 0; turn off enhanced edit */ - - canonbuf.c_cc[VMIN] = 1; /* we want every character */ - canonbuf.c_cc[VTIME] = 1; /* these may require tweaking */ - - /* also set up the parents raw setting for when needed **/ - rawbuf.c_oflag = rawbuf.c_iflag = rawbuf.c_lflag /* = rawbuf.c_line */ = 0; - rawbuf.c_cc[VMIN] = 1; - rawbuf.c_cc[VTIME] = 1; - - - if(tcsetattr(0, TCSAFLUSH, &canonbuf) == -1) { - perror("clef setting parent terminal to canonical processing"); - exit(0); - } - - /* initialize some flags I will be using */ - MODE = CLEFCANONICAL; - INS_MODE = 1; - Cursor_shape(2); -} - - -static void -hangup_handler(int sig) -{ -#ifdef siglog - sigfile = open(sigbuff, O_RDWR | O_APPEND); - write(sigfile, "Hangup Handler\n", strlen("Hangup Handler\n")); - close(sigfile); -#endif - /* try to kill my child if it is around */ - if(kill(child_pid, 0)) kill(child_pid, SIGTERM); - if(kill(ppid, 0) >= 0) { - /* fix the terminal and exit */ - if(tcsetattr(0, TCSAFLUSH, &oldbuf) == -1) { - perror("clef restoring terminal in hangup handler"); - } - printf("\n"); - } - /* remove the temporary editor filename */ - unlink(editorfilename); - exit(-1); -} - -static void -terminate_handler(int sig) -{ -#ifdef siglog - sigfile = open(sigbuff, O_RDWR | O_APPEND); - write(sigfile, "Terminate Handler\n", strlen("Terminate Handler\n") + 1); - close(sigfile); - openaxiom_sleep(1); -#endif - kill(child_pid, SIGTERM); - /* fix the terminal, and exit */ - if(tcsetattr(0, TCSAFLUSH, &oldbuf) == -1) { - perror("clef restoring terminal in terminate handler"); - } - printf("\n"); - Cursor_shape(2); - fprintf(stderr, "\n"); - /* remove the temporary editor filename */ - unlink(editorfilename); - exit(0); -} - -static void -interrupt_handler(int sig) -{ -#ifdef siglog - sigfile = open(sigbuff, O_RDWR | O_APPEND); - write(sigfile, "Interrupt Handler\n", strlen("Interrupt Handler\n") + 1); - close(sigfile); - openaxiom_sleep(1); -#endif - kill(child_pid, SIGINT); -} - -static void -child_handler(int sig) -{ -#ifdef siglog - sigfile = open(sigbuff, O_RDWR | O_APPEND ); - write(sigfile, "Child Handler\n", strlen("Child Handler\n") + 1); - close(sigfile); -#endif - Cursor_shape(2); - close(contNum); - if(kill(ppid, 0) >= 0) { - /* fix the terminal, and exit */ - if(tcsetattr(0, TCSAFLUSH, &oldbuf) == -1) { - perror("clef restoring terminal in child handler"); - } - printf("\n"); - } - /* remove the temporary editor filename */ - unlink(editorfilename); - exit(0); -} - -static void -alarm_handler(int sig) -{ - int newppid = getppid(); -#ifdef siglog - sigfile = open(sigbuff, O_RDWR | O_APPEND); - write(sigfile, "Alarm Handler\n", strlen("Alarm Handler\n")+ 1 ); - close(sigfile); -#endif - /* simply gets the parent process id, if different, it terminates , - otherwise it resets the alarm */ - - if(ppid == newppid) { - alarm(60); - return; - } - else { - /* once that is done fix the terminal, and exit */ - if(tcsetattr(0, TCSAFLUSH, &oldbuf) == -1) { - perror("clef restoring terminal in alarm handler"); - } - Cursor_shape(2); - fprintf(stderr, "\n"); - /* remove the temporary editor filename */ - unlink(editorfilename); - exit(0); - } -} - -/* a procedure which tells my parent how to catch signals from its children */ -static void -catch_signals(void) -{ -#ifdef siglog - sprintf(sigbuff, "/tmp/csig%d", oa_getpid()); - sigfile = open(sigbuff, O_RDWR | O_TRUNC | O_CREAT); - write(sigfile, "Started \n", strlen("Started \n")); - close(sigfile); -#endif - bsdSignal(SIGHUP, hangup_handler,RestartSystemCalls); - bsdSignal(SIGCHLD,child_handler,RestartSystemCalls); - bsdSignal(SIGTERM, terminate_handler,RestartSystemCalls); - bsdSignal(SIGINT, interrupt_handler,RestartSystemCalls); - bsdSignal(SIGALRM, alarm_handler,RestartSystemCalls); - alarm(60); -} - -#define etc_whitespace(c) ((c == ' ' || c == '\t')?(1):(0)) - - -static void -set_function_chars(void) -{ - /* get the special characters */ - _INTR = childbuf.c_cc[VINTR]; - _QUIT = childbuf.c_cc[VQUIT]; - _ERASE = childbuf.c_cc[VERASE]; - _KILL = childbuf.c_cc[VKILL]; - _EOF = childbuf.c_cc[VEOF]; - _EOL = childbuf.c_cc[VEOL]; - return; -} diff --git a/src/clef/edible.cc b/src/clef/edible.cc new file mode 100644 index 00000000..c3022060 --- /dev/null +++ b/src/clef/edible.cc @@ -0,0 +1,516 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2014, 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "open-axiom.h" +#include "sockio.h" +#include "edible.h" +#include "com.h" +#include "bsdsignal.h" + +#include "openpty.h" +#include "prt.h" +#include "edin.h" +#include "wct.h" +#include "fnct_key.h" +#include "cfuns.h" + +using namespace OpenAxiom; + +#ifdef AXIOM_UNLIKELY +#define log 1 +#define logterm 1 +#define siglog 1 +#endif + + +#define Cursor_shape(x) + +static void catch_signals(void); +static void init_parent(void); +static void set_function_chars(void); + + +#ifdef siglog +int sigfile; +char sigbuff[256]; +#endif + +/* Here are the term structures I need for setting and resetting the + terminal characteristics. */ + +struct termios childbuf; /* the childs normal operating termio */ +struct termios oldbuf; /* the initial settings */ +struct termios rawbuf; /* the parents raw state, when it is doing nothing */ +struct termios canonbuf; /* set it to be canonical */ + +/* the terminals mapping of the function keys */ +unsigned char _INTR, _QUIT, _ERASE, _KILL, _EOF, _EOL, _RES1, _RES2; + + +int ppid; /* the parents's parent pid */ +int child_pid; /* the childs process id */ + +short INS_MODE ; /* Flag for insert mode */ +short ECHOIT = 1; /* Flag for echoing */ +short PTY; /* Flag which tells me whether I should echo newlines */ + +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 **/ + + +char serverPath[20]; /* path name for opening the server side */ + +int contNum, serverNum; /* file descriptors for pty's */ +int num_read; /* Number of chars read */ + +#ifdef log +int logfd; +char logpath[30]; +#endif + + + + + +int +main(int argc, char *argv[]) +{ + using namespace OpenAxiom; + fd_set rfds; /* the structure for the select call */ + int code; /* return code from system calls */ + char out_buff[MAXLINE]; /* from child and stdin */ + int out_flag[MAXLINE] ; /* initialize the output flags */ + char *program; /* a string to hold the child program invocation */ + char **pargs = 0; /* holds parts of the command line */ + int not_command = 1; /* a flag while parsing the command line */ + + + + oa_setenv("LC_ALL", "C"); + setlocale(LC_ALL, ""); + /* try to get a pseudoterminal to play with */ + if (ptyopen(&contNum, &serverNum, serverPath) == -1) { + perror("ptyopen failed"); + exit(-1); + } + + /* call the routine that handles signals */ + catch_signals(); + + /* parse the command line arguments - as with the aixterm the command + argument -e should be last on the line. */ + + while(*++argv && not_command) { + if(!strcmp(*argv, "-f")) + load_wct_file(*++argv); + else if(!strcmp(*argv, "-e")) { + not_command = 0; + pargs = ++argv; + } + else { + fprintf(stderr, "usage: clef [-f fname] -e command\n"); + exit(-1); + } + } + skim_wct(); + +#ifdef log + sprintf(logpath, "/tmp/cleflog%d", oa_getpid()); + logfd = open(logpath, O_CREAT | O_RDWR, 0666); +#endif + + /* get the original termio settings, so the child has them */ + + if(tcgetattr(0,&childbuf) == -1) { + perror("clef trying to get the initial terminal settings"); + exit(-1); + } + + /* start the child process */ + + child_pid = fork(); + switch(child_pid) { + case -1 : + perror("clef can't create a new process"); + exit(-1); + case 0: + /* CHILD */ + /* Dissasociate form my parents group so all my child processes + look at my terminal as the controlling terminal for the group */ + setsid(); + + serverNum = open(serverPath,O_RDWR); + if (serverNum == -1) perror("open serverPath failed"); + + /* since I am the child, I can close ptc, and dup pts for all it + standard descriptors */ + if (dup2(serverNum, 0) == -1) perror("dup2 0 failed"); + if (dup2(serverNum, 1) == -1) perror("dup2 1 failed"); + if (dup2(serverNum, 2) == -1) perror("dup2 2 failed"); + if( (dup2(serverNum, 0) == -1) || + (dup2(serverNum, 1) == -1) || + (dup2(serverNum, 2) == -1) ) { + perror("clef trying to dup2"); + exit(-1); + } + + /* since they have been duped, close them */ + close(serverNum); + close(contNum); + + + /* To make sure everything is nice, set off enhedit */ + /* childbuf.c_line = 0; */ + + /* reconfigure the child's terminal get echoing */ + if(tcsetattr(0, TCSAFLUSH, &childbuf) == -1) { + perror("clef child trying to set child's terminal"); + exit(-1); + } + + /* fire up the child's process */ + if(pargs){ + execvp( pargs[0], pargs); + perror("clef trying to execvp its argument"); + fprintf(stderr, "Process --> %s\n", pargs[0]); + } + else{ + program = oa_getenv("SHELL"); + if (!program) + program = strdup("/bin/sh"); + else + program = strdup (program); + execlp( program,program, (char *) NULL); + perror("clef trying to execlp the default child"); + fprintf(stderr, "Process --> %s\n", program); + } + exit(-1); + break; + /* end switch */ + } + /* PARENT */ + /* Since I am the parent, I should start to initialize some stuff. + I have to close the pts side for it to work properly */ + + close(serverNum); + ppid = getppid(); + + /* Iinitialize some stuff for the reading and writing */ + init_flag(out_flag, MAXLINE); + define_function_keys(); + init_reader(); + PTY = 1; + init_parent(); + + /* Here is the main loop, it simply starts reading characters from + the std input, and from the child. */ + + while(1) { /* loop forever */ + + /* use select to see who has stuff waiting for me to handle */ + /* set file descriptors for ptc and stdin */ + FD_ZERO(&rfds); + FD_SET(contNum,&rfds); + FD_SET(0,&rfds); + set_function_chars(); +#ifdef log + { + char modepath[30]; + sprintf(modepath, "\nMODE = %d\n", MODE); + write(logfd, modepath, strlen(modepath)); + } +#endif +#ifdef logterm + { + struct termio ptermio; + char pbuff[1024]; + tcgetattr(contNum, &ptermio); + sprintf(pbuff, "child's settings: Lflag = %d, Oflag = %d, Iflag = %d\n", + ptermio.c_lflag, ptermio.c_oflag, ptermio.c_iflag); + write(logfd, pbuff, strlen(pbuff)); + } +#endif + + code = select(FD_SETSIZE, &rfds, NULL, NULL, NULL); + for(; code < 0 ;) { + if(errno == EINTR) { + code = select(FD_SETSIZE, &rfds, NULL, NULL, NULL); + } + else { + perror("clef select failure"); + exit(-1); + } + } + + /* reading from the child **/ + if( FD_ISSET(contNum,&rfds)) { + if( (num_read = read(contNum, out_buff, MAXLINE)) == -1) { + num_read = 0; + } +#ifdef log + write(logfd, "OUT<<<<<", strlen("OUT<<<<<")); + write(logfd, out_buff, num_read); +#endif + if(num_read > 0) { + /* now do the printing to the screen */ + if(MODE!= CLEFRAW) { + back_up(buff_pntr); + write(1,out_buff, num_read); + print_whole_buff(); /* reprint the input buffer */ + } + else write(1,out_buff, num_read); + } + } /* done the child stuff */ + /* I should read from std input */ + else { + if(FD_ISSET(0,&rfds)) { + num_read = read(0, in_buff, MAXLINE); +#ifdef log + write(logfd, "IN<<<<<", strlen("IN<<<<<")); + write(logfd, in_buff, num_read); +#endif + if(MODE == CLEFRAW ) + write(contNum, in_buff, num_read); + else + 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 terminal initial settings"); + exit(-1); + } + + /* get the settings for my different modes */ + if ((tcgetattr(0, &canonbuf) == -1) || + (tcgetattr(0, &rawbuf) == -1) ) { + perror("clef trying to get terminal settings"); + exit(-1); + } + + + canonbuf.c_lflag &= ~(ICANON | ECHO | ISIG); + /* read before an eoln is typed */ + + canonbuf.c_lflag |= ISIG; + + /* canonbuf.c_line = 0; turn off enhanced edit */ + + canonbuf.c_cc[VMIN] = 1; /* we want every character */ + canonbuf.c_cc[VTIME] = 1; /* these may require tweaking */ + + /* also set up the parents raw setting for when needed **/ + rawbuf.c_oflag = rawbuf.c_iflag = rawbuf.c_lflag /* = rawbuf.c_line */ = 0; + rawbuf.c_cc[VMIN] = 1; + rawbuf.c_cc[VTIME] = 1; + + + if(tcsetattr(0, TCSAFLUSH, &canonbuf) == -1) { + perror("clef setting parent terminal to canonical processing"); + exit(0); + } + + /* initialize some flags I will be using */ + MODE = CLEFCANONICAL; + INS_MODE = 1; + Cursor_shape(2); +} + + +static void +hangup_handler(int sig) +{ +#ifdef siglog + sigfile = open(sigbuff, O_RDWR | O_APPEND); + write(sigfile, "Hangup Handler\n", strlen("Hangup Handler\n")); + close(sigfile); +#endif + /* try to kill my child if it is around */ + if(kill(child_pid, 0)) kill(child_pid, SIGTERM); + if(kill(ppid, 0) >= 0) { + /* fix the terminal and exit */ + if(tcsetattr(0, TCSAFLUSH, &oldbuf) == -1) { + perror("clef restoring terminal in hangup handler"); + } + printf("\n"); + } + /* remove the temporary editor filename */ + unlink(editorfilename); + exit(-1); +} + +static void +terminate_handler(int sig) +{ +#ifdef siglog + sigfile = open(sigbuff, O_RDWR | O_APPEND); + write(sigfile, "Terminate Handler\n", strlen("Terminate Handler\n") + 1); + close(sigfile); + openaxiom_sleep(1); +#endif + kill(child_pid, SIGTERM); + /* fix the terminal, and exit */ + if(tcsetattr(0, TCSAFLUSH, &oldbuf) == -1) { + perror("clef restoring terminal in terminate handler"); + } + printf("\n"); + Cursor_shape(2); + fprintf(stderr, "\n"); + /* remove the temporary editor filename */ + unlink(editorfilename); + exit(0); +} + +static void +interrupt_handler(int sig) +{ +#ifdef siglog + sigfile = open(sigbuff, O_RDWR | O_APPEND); + write(sigfile, "Interrupt Handler\n", strlen("Interrupt Handler\n") + 1); + close(sigfile); + openaxiom_sleep(1); +#endif + kill(child_pid, SIGINT); +} + +static void +child_handler(int sig) +{ +#ifdef siglog + sigfile = open(sigbuff, O_RDWR | O_APPEND ); + write(sigfile, "Child Handler\n", strlen("Child Handler\n") + 1); + close(sigfile); +#endif + Cursor_shape(2); + close(contNum); + if(kill(ppid, 0) >= 0) { + /* fix the terminal, and exit */ + if(tcsetattr(0, TCSAFLUSH, &oldbuf) == -1) { + perror("clef restoring terminal in child handler"); + } + printf("\n"); + } + /* remove the temporary editor filename */ + unlink(editorfilename); + exit(0); +} + +static void +alarm_handler(int sig) +{ + int newppid = getppid(); +#ifdef siglog + sigfile = open(sigbuff, O_RDWR | O_APPEND); + write(sigfile, "Alarm Handler\n", strlen("Alarm Handler\n")+ 1 ); + close(sigfile); +#endif + /* simply gets the parent process id, if different, it terminates , + otherwise it resets the alarm */ + + if(ppid == newppid) { + alarm(60); + return; + } + else { + /* once that is done fix the terminal, and exit */ + if(tcsetattr(0, TCSAFLUSH, &oldbuf) == -1) { + perror("clef restoring terminal in alarm handler"); + } + Cursor_shape(2); + fprintf(stderr, "\n"); + /* remove the temporary editor filename */ + unlink(editorfilename); + exit(0); + } +} + +/* a procedure which tells my parent how to catch signals from its children */ +static void +catch_signals(void) +{ +#ifdef siglog + sprintf(sigbuff, "/tmp/csig%d", oa_getpid()); + sigfile = open(sigbuff, O_RDWR | O_TRUNC | O_CREAT); + write(sigfile, "Started \n", strlen("Started \n")); + close(sigfile); +#endif + bsdSignal(SIGHUP, hangup_handler,RestartSystemCalls); + bsdSignal(SIGCHLD,child_handler,RestartSystemCalls); + bsdSignal(SIGTERM, terminate_handler,RestartSystemCalls); + bsdSignal(SIGINT, interrupt_handler,RestartSystemCalls); + bsdSignal(SIGALRM, alarm_handler,RestartSystemCalls); + alarm(60); +} + +#define etc_whitespace(c) ((c == ' ' || c == '\t')?(1):(0)) + + +static void +set_function_chars(void) +{ + /* get the special characters */ + _INTR = childbuf.c_cc[VINTR]; + _QUIT = childbuf.c_cc[VQUIT]; + _ERASE = childbuf.c_cc[VERASE]; + _KILL = childbuf.c_cc[VKILL]; + _EOF = childbuf.c_cc[VEOF]; + _EOL = childbuf.c_cc[VEOL]; + return; +} diff --git a/src/etc/asq.c.pamphlet b/src/etc/asq.c.pamphlet index 0ef9c5ef..98217cae 100644 --- a/src/etc/asq.c.pamphlet +++ b/src/etc/asq.c.pamphlet @@ -524,7 +524,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /* printhelp -- print the help info */ /* main */ -#include "openaxiom-c-macros.h" #include #include diff --git a/src/graph/Gdraws/Gdraws0.h b/src/graph/Gdraws/Gdraws0.h index 632c3704..88425df1 100644 --- a/src/graph/Gdraws/Gdraws0.h +++ b/src/graph/Gdraws/Gdraws0.h @@ -36,7 +36,6 @@ #ifndef _GDRAWS0_H_ #define _GDRAWS0_H_ 1 -#include "openaxiom-c-macros.h" #include diff --git a/src/graph/view2D/buttons2d.c b/src/graph/view2D/buttons2d.c index 1babc196..1f435657 100644 --- a/src/graph/view2D/buttons2d.c +++ b/src/graph/view2D/buttons2d.c @@ -34,7 +34,6 @@ */ #define _BUTTONS2D_C -#include "openaxiom-c-macros.h" #include diff --git a/src/graph/view2D/control2d.c b/src/graph/view2D/control2d.c index 051184c4..83be366c 100644 --- a/src/graph/view2D/control2d.c +++ b/src/graph/view2D/control2d.c @@ -34,7 +34,6 @@ */ #define _CONTROL2D_C -#include "openaxiom-c-macros.h" #include #include diff --git a/src/graph/view2D/graph2d.c b/src/graph/view2D/graph2d.c index dadd4008..2e1f9f86 100644 --- a/src/graph/view2D/graph2d.c +++ b/src/graph/view2D/graph2d.c @@ -34,7 +34,6 @@ */ #define _GRAPH2D_C -#include "openaxiom-c-macros.h" #include #include diff --git a/src/graph/view2D/main2d.c b/src/graph/view2D/main2d.c index 29c3b3d7..ac8547ee 100644 --- a/src/graph/view2D/main2d.c +++ b/src/graph/view2D/main2d.c @@ -34,7 +34,6 @@ */ #define _MAIN2D_C -#include "openaxiom-c-macros.h" #include #include diff --git a/src/graph/view2D/pot2d.c b/src/graph/view2D/pot2d.c index 19f34e96..69aa985a 100644 --- a/src/graph/view2D/pot2d.c +++ b/src/graph/view2D/pot2d.c @@ -34,7 +34,6 @@ */ #define _POT2D_C -#include "openaxiom-c-macros.h" #include "header2.h" diff --git a/src/graph/view2D/process2d.c b/src/graph/view2D/process2d.c index 52c326f6..96740d35 100644 --- a/src/graph/view2D/process2d.c +++ b/src/graph/view2D/process2d.c @@ -34,7 +34,6 @@ */ #define _PROCESS2D_C -#include "openaxiom-c-macros.h" #include #include diff --git a/src/graph/view2D/spadAction2d.c b/src/graph/view2D/spadAction2d.c index 60789eb1..bceec18d 100644 --- a/src/graph/view2D/spadAction2d.c +++ b/src/graph/view2D/spadAction2d.c @@ -34,7 +34,6 @@ */ #define _SPADACTION2D_C -#include "openaxiom-c-macros.h" #include #include diff --git a/src/graph/view2D/stuff2d.c b/src/graph/view2D/stuff2d.c index 1674d2f2..49649fdb 100644 --- a/src/graph/view2D/stuff2d.c +++ b/src/graph/view2D/stuff2d.c @@ -34,7 +34,6 @@ */ #define _STUFF2D_C -#include "openaxiom-c-macros.h" #include #include diff --git a/src/graph/view2D/write2d.c b/src/graph/view2D/write2d.c index 395b821a..967dd149 100644 --- a/src/graph/view2D/write2d.c +++ b/src/graph/view2D/write2d.c @@ -34,7 +34,6 @@ */ #define _WRITE2D_C -#include "openaxiom-c-macros.h" #include #include diff --git a/src/graph/view3D/buttons3d.c b/src/graph/view3D/buttons3d.c index d96031b9..1b3c4bcb 100644 --- a/src/graph/view3D/buttons3d.c +++ b/src/graph/view3D/buttons3d.c @@ -34,7 +34,6 @@ */ #define _BUTTONS3D_C -#include "openaxiom-c-macros.h" #include "header.h" #include "cpanel.h" diff --git a/src/graph/view3D/closeView3d.c b/src/graph/view3D/closeView3d.c index 14c64110..af040411 100644 --- a/src/graph/view3D/closeView3d.c +++ b/src/graph/view3D/closeView3d.c @@ -34,7 +34,6 @@ */ #define _CLOSEVIEW3D_C -#include "openaxiom-c-macros.h" #include #include "header.h" diff --git a/src/graph/view3D/component3d.c b/src/graph/view3D/component3d.c index 626790be..e45c58cf 100644 --- a/src/graph/view3D/component3d.c +++ b/src/graph/view3D/component3d.c @@ -34,7 +34,6 @@ */ #define _COMPONENT3D_C -#include "openaxiom-c-macros.h" #include "header.h" #include "draw.h" diff --git a/src/graph/view3D/control3d.c b/src/graph/view3D/control3d.c index 2fb407e6..0e59aec5 100644 --- a/src/graph/view3D/control3d.c +++ b/src/graph/view3D/control3d.c @@ -34,7 +34,6 @@ */ #define _CONTROL3D_C -#include "openaxiom-c-macros.h" #include #include diff --git a/src/graph/view3D/illuminate3d.c b/src/graph/view3D/illuminate3d.c index 323e5916..78bec762 100644 --- a/src/graph/view3D/illuminate3d.c +++ b/src/graph/view3D/illuminate3d.c @@ -34,7 +34,6 @@ */ #define _ILLUMINATE3D_C -#include "openaxiom-c-macros.h" #include diff --git a/src/graph/view3D/lightbut3d.c b/src/graph/view3D/lightbut3d.c index b15b14da..42eb140b 100644 --- a/src/graph/view3D/lightbut3d.c +++ b/src/graph/view3D/lightbut3d.c @@ -34,7 +34,6 @@ */ #define _LIGHTBUT3D_C -#include "openaxiom-c-macros.h" #include "header.h" #include "cpanel.h" diff --git a/src/graph/view3D/lighting3d.c b/src/graph/view3D/lighting3d.c index 5d0b5489..03438aaa 100644 --- a/src/graph/view3D/lighting3d.c +++ b/src/graph/view3D/lighting3d.c @@ -34,7 +34,6 @@ */ #define _LIGHTING3D_C -#include "openaxiom-c-macros.h" #include #include diff --git a/src/graph/view3D/main3d.c b/src/graph/view3D/main3d.c index 90616192..a987028f 100644 --- a/src/graph/view3D/main3d.c +++ b/src/graph/view3D/main3d.c @@ -34,7 +34,6 @@ */ #define _MAIN3D_C -#include "openaxiom-c-macros.h" #include #include diff --git a/src/graph/view3D/mesh3d.c b/src/graph/view3D/mesh3d.c index 716cebeb..c1369e3f 100644 --- a/src/graph/view3D/mesh3d.c +++ b/src/graph/view3D/mesh3d.c @@ -34,7 +34,6 @@ */ #define _MESH3D_C -#include "openaxiom-c-macros.h" #include diff --git a/src/graph/view3D/msort3d.c b/src/graph/view3D/msort3d.c index f034fe2d..36d2ca43 100644 --- a/src/graph/view3D/msort3d.c +++ b/src/graph/view3D/msort3d.c @@ -34,7 +34,6 @@ */ #define _MSORT3D_C -#include "openaxiom-c-macros.h" /***************************************************** diff --git a/src/graph/view3D/pot3d.c b/src/graph/view3D/pot3d.c index 0e519313..a38b16e9 100644 --- a/src/graph/view3D/pot3d.c +++ b/src/graph/view3D/pot3d.c @@ -34,7 +34,6 @@ */ #define _POT3D_C -#include "openaxiom-c-macros.h" #include "header.h" #include "all_3d.H1" diff --git a/src/graph/view3D/process3d.c b/src/graph/view3D/process3d.c index f5adbf9e..fcceb2e4 100644 --- a/src/graph/view3D/process3d.c +++ b/src/graph/view3D/process3d.c @@ -34,7 +34,6 @@ */ #define _PROCESS3D_C -#include "openaxiom-c-macros.h" #include #include diff --git a/src/graph/view3D/project3d.c b/src/graph/view3D/project3d.c index f95d12d5..0032953d 100644 --- a/src/graph/view3D/project3d.c +++ b/src/graph/view3D/project3d.c @@ -34,7 +34,6 @@ */ #define _PROJECT3D_C -#include "openaxiom-c-macros.h" #include #include "header.h" diff --git a/src/graph/view3D/quit3d.c b/src/graph/view3D/quit3d.c index bcbcd707..3218e00e 100644 --- a/src/graph/view3D/quit3d.c +++ b/src/graph/view3D/quit3d.c @@ -34,7 +34,6 @@ */ #define _QUIT3D_C -#include "openaxiom-c-macros.h" #include #include "header.h" diff --git a/src/graph/view3D/quitbut3d.c b/src/graph/view3D/quitbut3d.c index 448d80ed..a4ada8f4 100644 --- a/src/graph/view3D/quitbut3d.c +++ b/src/graph/view3D/quitbut3d.c @@ -34,7 +34,6 @@ */ #define _QUITBUT3D_C -#include "openaxiom-c-macros.h" #include "header.h" #include "cpanel.h" diff --git a/src/graph/view3D/save3d.c b/src/graph/view3D/save3d.c index be86090f..2114668a 100644 --- a/src/graph/view3D/save3d.c +++ b/src/graph/view3D/save3d.c @@ -34,7 +34,6 @@ */ #define _SAVE3D_C -#include "openaxiom-c-macros.h" #include #include diff --git a/src/graph/view3D/savebut3d.c b/src/graph/view3D/savebut3d.c index d6e1e900..f2b80a8d 100644 --- a/src/graph/view3D/savebut3d.c +++ b/src/graph/view3D/savebut3d.c @@ -34,7 +34,6 @@ */ #define _SAVEBUT3D_C -#include "openaxiom-c-macros.h" #include "header.h" #include "cpanel.h" diff --git a/src/graph/view3D/smoothShade3d.c b/src/graph/view3D/smoothShade3d.c index b794f210..bb6a97bd 100644 --- a/src/graph/view3D/smoothShade3d.c +++ b/src/graph/view3D/smoothShade3d.c @@ -34,7 +34,6 @@ */ #define _SMOOTHSHADE_C -#include "openaxiom-c-macros.h" #include #include diff --git a/src/graph/view3D/spadAction3d.c b/src/graph/view3D/spadAction3d.c index 0c3861f3..e9ce3827 100644 --- a/src/graph/view3D/spadAction3d.c +++ b/src/graph/view3D/spadAction3d.c @@ -34,7 +34,6 @@ */ #define _SPADACTION3D_C -#include "openaxiom-c-macros.h" #include #include diff --git a/src/graph/view3D/stuff3d.c b/src/graph/view3D/stuff3d.c index ed466eb3..2362fc74 100644 --- a/src/graph/view3D/stuff3d.c +++ b/src/graph/view3D/stuff3d.c @@ -34,7 +34,6 @@ */ #define _STUFF3D_C -#include "openaxiom-c-macros.h" #include "header.h" diff --git a/src/graph/view3D/surface3d.c b/src/graph/view3D/surface3d.c index 3cff2df6..27647d23 100644 --- a/src/graph/view3D/surface3d.c +++ b/src/graph/view3D/surface3d.c @@ -34,7 +34,6 @@ */ #define _SURFACE3D_C -#include "openaxiom-c-macros.h" #include #include diff --git a/src/graph/view3D/testcol.c b/src/graph/view3D/testcol.c index 9eaea909..2c576bd6 100644 --- a/src/graph/view3D/testcol.c +++ b/src/graph/view3D/testcol.c @@ -34,7 +34,6 @@ */ #define _MAIN3D_C -#include "openaxiom-c-macros.h" #include #include #include diff --git a/src/graph/view3D/transform3d.c b/src/graph/view3D/transform3d.c index 4030e25c..c4390f99 100644 --- a/src/graph/view3D/transform3d.c +++ b/src/graph/view3D/transform3d.c @@ -34,7 +34,6 @@ */ #define _TRANSFORM3D_C -#include "openaxiom-c-macros.h" #include "header.h" diff --git a/src/graph/view3D/viewport3d.c b/src/graph/view3D/viewport3d.c index eed96b72..b0d9cb40 100644 --- a/src/graph/view3D/viewport3d.c +++ b/src/graph/view3D/viewport3d.c @@ -34,7 +34,6 @@ */ #define _VIEWPORT3D_C -#include "openaxiom-c-macros.h" #include #include diff --git a/src/graph/view3D/volume3d.c b/src/graph/view3D/volume3d.c index 87bce529..1794a1d2 100644 --- a/src/graph/view3D/volume3d.c +++ b/src/graph/view3D/volume3d.c @@ -34,7 +34,6 @@ */ #define _VOLUME3D_C -#include "openaxiom-c-macros.h" #include #include diff --git a/src/graph/view3D/write3d.c b/src/graph/view3D/write3d.c index 7eeaf15b..dd3c9a15 100644 --- a/src/graph/view3D/write3d.c +++ b/src/graph/view3D/write3d.c @@ -34,7 +34,6 @@ */ #define _WRITE3D_C -#include "openaxiom-c-macros.h" #include #include diff --git a/src/graph/viewAlone/viewAlone.c b/src/graph/viewAlone/viewAlone.c index 07f89039..5fb48a93 100644 --- a/src/graph/viewAlone/viewAlone.c +++ b/src/graph/viewAlone/viewAlone.c @@ -34,7 +34,6 @@ */ #define _VIEWALONE_C -#include "openaxiom-c-macros.h" #include #include "viewAlone.h" diff --git a/src/graph/viewman/cleanup.c b/src/graph/viewman/cleanup.c index 4dfbc04e..20c4cfa9 100644 --- a/src/graph/viewman/cleanup.c +++ b/src/graph/viewman/cleanup.c @@ -34,7 +34,6 @@ */ #define _CLEANUP_C -#include "openaxiom-c-macros.h" #include #include diff --git a/src/graph/viewman/make2D.c b/src/graph/viewman/make2D.c index 65810003..0cbcf8bc 100644 --- a/src/graph/viewman/make2D.c +++ b/src/graph/viewman/make2D.c @@ -34,7 +34,6 @@ */ #define _MAKE2D_C -#include "openaxiom-c-macros.h" #include "viewman.h" diff --git a/src/graph/viewman/make3D.c b/src/graph/viewman/make3D.c index 30f2e869..2bbaebb9 100644 --- a/src/graph/viewman/make3D.c +++ b/src/graph/viewman/make3D.c @@ -34,7 +34,6 @@ */ #define _MAKE3D_C -#include "openaxiom-c-macros.h" #include diff --git a/src/graph/viewman/makeGraph.c b/src/graph/viewman/makeGraph.c index 331d32cf..344144ec 100644 --- a/src/graph/viewman/makeGraph.c +++ b/src/graph/viewman/makeGraph.c @@ -34,7 +34,6 @@ */ #define _MAKEGRAPH_C -#include "openaxiom-c-macros.h" #include #include diff --git a/src/graph/viewman/readView.c b/src/graph/viewman/readView.c index b21cf3df..13745459 100644 --- a/src/graph/viewman/readView.c +++ b/src/graph/viewman/readView.c @@ -34,7 +34,6 @@ */ #define _READVIEW_C -#include "openaxiom-c-macros.h" #include #include diff --git a/src/graph/viewman/sselect.c b/src/graph/viewman/sselect.c index 68a3f869..942aa14c 100644 --- a/src/graph/viewman/sselect.c +++ b/src/graph/viewman/sselect.c @@ -34,7 +34,6 @@ */ #define _SSELECT_C -#include "openaxiom-c-macros.h" #include #include diff --git a/src/graph/viewman/viewman.c b/src/graph/viewman/viewman.c index e5940302..34c48a71 100644 --- a/src/graph/viewman/viewman.c +++ b/src/graph/viewman/viewman.c @@ -34,7 +34,6 @@ */ #define _VIEWMAN_C -#include "openaxiom-c-macros.h" #include #include diff --git a/src/hyper/ReadBitmap.c b/src/hyper/ReadBitmap.c index ee8e89d2..3ecd3bd4 100644 --- a/src/hyper/ReadBitmap.c +++ b/src/hyper/ReadBitmap.c @@ -33,7 +33,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "openaxiom-c-macros.h" #include "debug.h" #include "halloc.h" #include "sockio.h" diff --git a/src/hyper/addfile.c b/src/hyper/addfile.c index 3671b2a5..cac8a957 100644 --- a/src/hyper/addfile.c +++ b/src/hyper/addfile.c @@ -33,7 +33,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "openaxiom-c-macros.h" #include #include diff --git a/src/hyper/cond.c b/src/hyper/cond.c index 1771ca02..4db1f352 100644 --- a/src/hyper/cond.c +++ b/src/hyper/cond.c @@ -41,7 +41,6 @@ * ****************************************************************************/ -#include "openaxiom-c-macros.h" #include "debug.h" #include "sockio.h" #include "halloc.h" diff --git a/src/hyper/debug.c b/src/hyper/debug.c index 7260ca15..c00d53d2 100644 --- a/src/hyper/debug.c +++ b/src/hyper/debug.c @@ -34,7 +34,6 @@ */ #define _DEBUG_C -#include "openaxiom-c-macros.h" #include "debug.h" diff --git a/src/hyper/dialog.c b/src/hyper/dialog.c index e3ae5122..e67ca0fd 100644 --- a/src/hyper/dialog.c +++ b/src/hyper/dialog.c @@ -43,7 +43,6 @@ #include #define _DIALOG_C -#include "openaxiom-c-macros.h" #include "debug.h" diff --git a/src/hyper/display.c b/src/hyper/display.c index e7d493f6..0bb5fa36 100644 --- a/src/hyper/display.c +++ b/src/hyper/display.c @@ -52,7 +52,6 @@ */ #define _DISPLAY_C -#include "openaxiom-c-macros.h" #include "debug.h" #include "sockio.h" diff --git a/src/hyper/event.c b/src/hyper/event.c index b2217805..8412df23 100644 --- a/src/hyper/event.c +++ b/src/hyper/event.c @@ -35,7 +35,6 @@ #define _EVENT_C -#include "openaxiom-c-macros.h" #include #include diff --git a/src/hyper/ex2ht.c b/src/hyper/ex2ht.c index 64a55a2e..36042231 100644 --- a/src/hyper/ex2ht.c +++ b/src/hyper/ex2ht.c @@ -36,7 +36,6 @@ /* ex2ht creates a cover page for structured HyperDoc example pages */ -#include "openaxiom-c-macros.h" #include "debug.h" #include diff --git a/src/hyper/extent.h b/src/hyper/extent.h index efc9ece4..4e1e2425 100644 --- a/src/hyper/extent.h +++ b/src/hyper/extent.h @@ -36,7 +36,6 @@ #ifndef _EXTENT_H_ #define _EXTENT_H_ 1 -#include "openaxiom-c-macros.h" #include "hyper.h" /* diff --git a/src/hyper/extent1.c b/src/hyper/extent1.c index 95766791..46977487 100644 --- a/src/hyper/extent1.c +++ b/src/hyper/extent1.c @@ -41,7 +41,6 @@ * ****************************************************************************/ -#include "openaxiom-c-macros.h" #include "debug.h" #include "sockio.h" #include "extent.h" diff --git a/src/hyper/extent2.c b/src/hyper/extent2.c index 10f7b923..c251e6ac 100644 --- a/src/hyper/extent2.c +++ b/src/hyper/extent2.c @@ -41,7 +41,6 @@ * ****************************************************************************/ -#include "openaxiom-c-macros.h" #include "debug.h" #include "halloc.h" #include "sockio.h" diff --git a/src/hyper/form-ext.c b/src/hyper/form-ext.c index 93d8d0b0..24c94a24 100644 --- a/src/hyper/form-ext.c +++ b/src/hyper/form-ext.c @@ -33,7 +33,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "openaxiom-c-macros.h" #include "debug.h" #include "sockio.h" #include "extent.h" diff --git a/src/hyper/group.h b/src/hyper/group.h index 7253cd83..0a1b9d44 100644 --- a/src/hyper/group.h +++ b/src/hyper/group.h @@ -36,7 +36,6 @@ #ifndef _GROUP_H_ #define _GROUP_H_ 1 -#include "openaxiom-c-macros.h" #include "hyper.h" extern void bf_top_group(void ); diff --git a/src/hyper/htadd.c b/src/hyper/htadd.c index b3a5962a..8457885c 100644 --- a/src/hyper/htadd.c +++ b/src/hyper/htadd.c @@ -36,7 +36,6 @@ /* HyperDoc database file manager */ -#include "openaxiom-c-macros.h" #include #include diff --git a/src/hyper/hthits.c b/src/hyper/hthits.c index 4e628b16..5f04bdbf 100644 --- a/src/hyper/hthits.c +++ b/src/hyper/hthits.c @@ -49,7 +49,6 @@ * SMW Feb 91 */ -#include "openaxiom-c-macros.h" #include "debug.h" diff --git a/src/hyper/htinp.c b/src/hyper/htinp.c index b44047f8..fafa992a 100644 --- a/src/hyper/htinp.c +++ b/src/hyper/htinp.c @@ -37,7 +37,6 @@ #include #include -#include "openaxiom-c-macros.h" #include "debug.h" #include "halloc.h" #include "sockio.h" diff --git a/src/hyper/htsearch.cc b/src/hyper/htsearch.cc index b42c0b0f..d521a12f 100644 --- a/src/hyper/htsearch.cc +++ b/src/hyper/htsearch.cc @@ -41,7 +41,6 @@ * result. */ -#include "openaxiom-c-macros.h" #include #include diff --git a/src/hyper/hyper.h b/src/hyper/hyper.h index 67537647..2b4b577d 100644 --- a/src/hyper/hyper.h +++ b/src/hyper/hyper.h @@ -36,7 +36,6 @@ #ifndef _HYPER_H_ #define _HYPER_H_ 1 -#include "openaxiom-c-macros.h" #include #include #include diff --git a/src/hyper/initx.c b/src/hyper/initx.c index c69c2071..911208c9 100644 --- a/src/hyper/initx.c +++ b/src/hyper/initx.c @@ -43,7 +43,6 @@ /* #define DEBUG 1 */ -#include "openaxiom-c-macros.h" #include #include diff --git a/src/hyper/input.c b/src/hyper/input.c index 2c645208..cabfdc24 100644 --- a/src/hyper/input.c +++ b/src/hyper/input.c @@ -33,7 +33,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "openaxiom-c-macros.h" #include "debug.h" #include "sockio.h" #include "hyper.h" diff --git a/src/hyper/item.c b/src/hyper/item.c index 7bf7d724..576cc895 100644 --- a/src/hyper/item.c +++ b/src/hyper/item.c @@ -33,7 +33,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "openaxiom-c-macros.h" #include "sockio.h" #include "debug.h" #include "halloc.h" diff --git a/src/hyper/keyin.c b/src/hyper/keyin.c index fa8af8de..e8dbf70d 100644 --- a/src/hyper/keyin.c +++ b/src/hyper/keyin.c @@ -42,7 +42,6 @@ ****************************************************************************/ #include -#include "openaxiom-c-macros.h" #include "debug.h" #include "halloc.h" #include "sockio.h" diff --git a/src/hyper/lex.c b/src/hyper/lex.c index ed281403..9c7edc23 100644 --- a/src/hyper/lex.c +++ b/src/hyper/lex.c @@ -57,7 +57,6 @@ * */ #define _LEX_C -#include "openaxiom-c-macros.h" #include #include diff --git a/src/hyper/macro.c b/src/hyper/macro.c index 7bf0f77b..54e70f09 100644 --- a/src/hyper/macro.c +++ b/src/hyper/macro.c @@ -33,7 +33,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "openaxiom-c-macros.h" #include "debug.h" #include "halloc.h" #include "sockio.h" diff --git a/src/hyper/parse-aux.c b/src/hyper/parse-aux.c index 24efcf89..cbfb2197 100644 --- a/src/hyper/parse-aux.c +++ b/src/hyper/parse-aux.c @@ -33,7 +33,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "openaxiom-c-macros.h" #include "debug.h" #include "halloc.h" #include "sockio.h" diff --git a/src/hyper/parse-input.c b/src/hyper/parse-input.c index 727acc9d..f97a68eb 100644 --- a/src/hyper/parse-input.c +++ b/src/hyper/parse-input.c @@ -33,7 +33,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "openaxiom-c-macros.h" /*** Contains all the code needed to parse input items, InputString diff --git a/src/hyper/parse-paste.c b/src/hyper/parse-paste.c index 06d84fa1..58ea290e 100644 --- a/src/hyper/parse-paste.c +++ b/src/hyper/parse-paste.c @@ -41,7 +41,6 @@ * ****************************************************************************/ -#include "openaxiom-c-macros.h" #include "debug.h" #include "halloc.h" #include "sockio.h" diff --git a/src/hyper/parse-paste.h b/src/hyper/parse-paste.h index cb0556b9..6b8ba74f 100644 --- a/src/hyper/parse-paste.h +++ b/src/hyper/parse-paste.h @@ -36,7 +36,6 @@ #ifndef _PARSE_PASTE_H_ #define _PARSE_PASTE_H_ 1 -#include "openaxiom-c-macros.h" #include "hyper.h" extern void parse_paste(); diff --git a/src/hyper/parse-types.c b/src/hyper/parse-types.c index e42d93f9..60a25d35 100644 --- a/src/hyper/parse-types.c +++ b/src/hyper/parse-types.c @@ -41,7 +41,6 @@ * ****************************************************************************/ -#include "openaxiom-c-macros.h" #include "debug.h" #include "halloc.h" #include "sockio.h" diff --git a/src/hyper/parse.h b/src/hyper/parse.h index 3e2c04b4..20109ba5 100644 --- a/src/hyper/parse.h +++ b/src/hyper/parse.h @@ -36,7 +36,6 @@ #ifndef _PARSE_H_ #define _PARSE_H_ 1 -#include "openaxiom-c-macros.h" #ifdef SUNplatform #include diff --git a/src/hyper/scrollbar.c b/src/hyper/scrollbar.c index 92e67ad1..2571d501 100644 --- a/src/hyper/scrollbar.c +++ b/src/hyper/scrollbar.c @@ -41,7 +41,6 @@ * ****************************************************************************/ -#include "openaxiom-c-macros.h" #include "debug.h" #include "halloc.h" #include "sockio.h" diff --git a/src/hyper/show-types.c b/src/hyper/show-types.c index e34498d8..31a02a46 100644 --- a/src/hyper/show-types.c +++ b/src/hyper/show-types.c @@ -41,7 +41,6 @@ * ****************************************************************************/ -#include "openaxiom-c-macros.h" #include "debug.h" #include "sockio.h" #include "hyper.h" diff --git a/src/hyper/spadbuf.c b/src/hyper/spadbuf.c index bfb4b377..d6f3e0b1 100644 --- a/src/hyper/spadbuf.c +++ b/src/hyper/spadbuf.c @@ -34,7 +34,6 @@ */ #define _SPADBUF_C -#include "openaxiom-c-macros.h" #include "debug.h" diff --git a/src/hyper/titlebar.c b/src/hyper/titlebar.c index 7cc21822..072284c5 100644 --- a/src/hyper/titlebar.c +++ b/src/hyper/titlebar.c @@ -42,7 +42,6 @@ ****************************************************************************/ #include -#include "openaxiom-c-macros.h" #include "debug.h" #include "halloc.h" #include "sockio.h" diff --git a/src/hyper/token.h b/src/hyper/token.h index b40d069a..f6ddbd31 100644 --- a/src/hyper/token.h +++ b/src/hyper/token.h @@ -36,7 +36,6 @@ #ifndef _TOKEN_H_ #define _TOKEN_H_ 1 -#include "openaxiom-c-macros.h" #include /* diff --git a/src/include/open-axiom.h b/src/include/open-axiom.h index 7d15e4ec..5f173e33 100644 --- a/src/include/open-axiom.h +++ b/src/include/open-axiom.h @@ -34,11 +34,13 @@ #ifndef OPENAXIOM_included #define OPENAXIOM_included +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include -#include "openaxiom-c-macros.h" - /* Annotation to request C calling convention */ #ifdef __cplusplus # define OPENAXIOM_C_CALL extern "C" diff --git a/src/include/open-axiom/storage b/src/include/open-axiom/storage index fe12d1eb..1ac6cbcf 100644 --- a/src/include/open-axiom/storage +++ b/src/include/open-axiom/storage @@ -40,7 +40,6 @@ #ifndef OPENAXIOM_STORAGE_included #define OPENAXIOM_STORAGE_included -#include #include #include #include diff --git a/src/include/sockio.h b/src/include/sockio.h index f77f8d50..4b683105 100644 --- a/src/include/sockio.h +++ b/src/include/sockio.h @@ -50,7 +50,6 @@ # define OPENAXIOM_INVALID_SOCKET (-1) #endif -#include "openaxiom-c-macros.h" #include "open-axiom.h" namespace OpenAxiom { diff --git a/src/lib/XDither.c b/src/lib/XDither.c index d766633d..aac711f8 100644 --- a/src/lib/XDither.c +++ b/src/lib/XDither.c @@ -33,7 +33,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "openaxiom-c-macros.h" #include #include diff --git a/src/lib/XShade.c b/src/lib/XShade.c index 590f2d2f..a5851f69 100644 --- a/src/lib/XShade.c +++ b/src/lib/XShade.c @@ -33,7 +33,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "openaxiom-c-macros.h" #include #include diff --git a/src/lib/XSpadFill.c b/src/lib/XSpadFill.c index 566c57ce..0b2212e5 100644 --- a/src/lib/XSpadFill.c +++ b/src/lib/XSpadFill.c @@ -58,7 +58,6 @@ #include #include -#include "openaxiom-c-macros.h" #include "spadcolors.h" #include "XSpadFill.h" #include "XShade.h" diff --git a/src/lib/bsdsignal.cxx b/src/lib/bsdsignal.cxx index 07fc6b54..66e4dcd0 100644 --- a/src/lib/bsdsignal.cxx +++ b/src/lib/bsdsignal.cxx @@ -33,7 +33,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "openaxiom-c-macros.h" #include #include "bsdsignal.h" diff --git a/src/lib/cfuns-c.cxx b/src/lib/cfuns-c.cxx index 5dbcd6bc..5cb5f338 100644 --- a/src/lib/cfuns-c.cxx +++ b/src/lib/cfuns-c.cxx @@ -34,7 +34,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "openaxiom-c-macros.h" +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include #include @@ -501,11 +503,11 @@ oa_acquire_temporary_pathname() { } return strdup(buf); #elif HAVE_DECL_MKTEMP - return mktemp(copy_c_str(std::string{ oa_get_tmpdir() } + "/oa-XXXXXX")); + return mktemp(strdup((std::string{ oa_get_tmpdir() } + "/oa-XXXXXX").c_str())); #elif HAVE_DECL_TEMPNAM return tempnam(oa_get_tmpdir(), "oa-"); #else - return copy_c_str("oa-" + std::to_string(random())); + return strdup(("oa-" + std::to_string(random())).c_str()); #endif } diff --git a/src/lib/cursor.c b/src/lib/cursor.c deleted file mode 100644 index 5413151d..00000000 --- a/src/lib/cursor.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. - All rights reserved. - Copyright (C) 2007-2010, 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 -#include "openaxiom-c-macros.h" - -#include "cursor.h" - -/* - * This routine changes the shape of the cursor. it is a modified version of - * a program by SMWatt, called cursor.c. JMW 6/22/89 - */ - -/* this stuff can only be done on AIX the right terminal (aixterm,hft) */ -#if (defined(RIOSplatform) || defined(RTplatform)) && !defined(_AIX41) -#include "edible.h" -/* the HFT stuff requires ioctl's and termio's */ -#include -#include -#include -#include - -int -Cursor_shape(int shape) -{ - int hftfd; - char hftpath[16], s[100]; - int chno; - int i; - struct termio oldterm, newterm; - struct hftgetid hftgid; - char *termVal; - - termVal = oa_getenv("TERM"); - if (strcmp("hft", termVal) && strncmp("aixterm", termVal, 7)) - return; - - - - /* determine the desired shape */ - if (shape < 0 || shape > 5) { - fprintf(stderr, "%d - Invalid cursor number\n"); - return (-1); - } - /* change the shape */ - s[0] = 033; /* hf_intro.hf_esc */ - s[1] = '['; /* hf_intro.hf_lbr */ - s[2] = 'x'; /* hf_intro.hf_ex */ - s[3] = 0; /* hf_intro.hf_len[0] */ - s[4] = 0; /* hf_intro.hf_len[1] */ - s[5] = 0; /* hf_intro.hf_len[2] */ - s[6] = 10; /* hf_intro.hf_len[3] */ - s[7] = 2; /* hf_intro.hf_typehi */ - s[8] = 8; /* hf_intro.hf_typelo */ - s[9] = 2; /* hf_sublen */ - s[10] = 0; /* hf_subtype */ - s[11] = 0; /* hf_rsvd */ - s[12] = shape; /* hf_shape */ - - if (ioctl(0, HFTGETID, &hftgid) < 0) { - /* perror("ioctl: HFTGETID"); */ - chno = -1; - } - else - chno = hftgid.hf_chan; - if (chno == -1) { - /** try being moronic and just writing what I want to - standard output ****/ - - if (((ioctl(2, TCGETA, &oldterm)) == -1) || - ((ioctl(2, TCGETA, &newterm)) == -1)) { - perror("Getting termio"); - exit(0); - } - newterm.c_oflag = newterm.c_lflag = newterm.c_iflag = 0; - newterm.c_cc[0] = -1; - for (i = 1; i <= 5; i++) - newterm.c_cc[i] = 0; - if ((ioctl(2, TCSETAF, &newterm)) == -1) { - perror("Setting to raw mode"); - exit(0); - } - write(2, s, 13); - read(0, s, 1024); - if ((ioctl(2, TCSETAF, &oldterm)) == -1) { - perror("Resetting terminal"); - exit(0); - } - } - else { - /* open the currently active virtual terminal on the hft */ - sprintf(hftpath, "/dev/hft/%d", chno); - if ((hftfd = open(hftpath, O_RDWR)) == -1) { - perror("Could not open hft channel\n"); - exit(0); - } - write(hftfd, s, 13); - } -} -#else - -int -Cursor_shape(int shape) -{ - return shape; -} -#endif - - - - - diff --git a/src/lib/cursor.cc b/src/lib/cursor.cc new file mode 100644 index 00000000..af0b6603 --- /dev/null +++ b/src/lib/cursor.cc @@ -0,0 +1,143 @@ +/* + Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2010, 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 + +#include "cursor.h" + +/* + * This routine changes the shape of the cursor. it is a modified version of + * a program by SMWatt, called cursor.c. JMW 6/22/89 + */ + +/* this stuff can only be done on AIX the right terminal (aixterm,hft) */ +#if (defined(RIOSplatform) || defined(RTplatform)) && !defined(_AIX41) +#include "edible.h" +/* the HFT stuff requires ioctl's and termio's */ +#include +#include +#include +#include + +int +Cursor_shape(int shape) +{ + int hftfd; + char hftpath[16], s[100]; + int chno; + int i; + struct termio oldterm, newterm; + struct hftgetid hftgid; + char *termVal; + + termVal = oa_getenv("TERM"); + if (strcmp("hft", termVal) && strncmp("aixterm", termVal, 7)) + return; + + + + /* determine the desired shape */ + if (shape < 0 || shape > 5) { + fprintf(stderr, "%d - Invalid cursor number\n"); + return (-1); + } + /* change the shape */ + s[0] = 033; /* hf_intro.hf_esc */ + s[1] = '['; /* hf_intro.hf_lbr */ + s[2] = 'x'; /* hf_intro.hf_ex */ + s[3] = 0; /* hf_intro.hf_len[0] */ + s[4] = 0; /* hf_intro.hf_len[1] */ + s[5] = 0; /* hf_intro.hf_len[2] */ + s[6] = 10; /* hf_intro.hf_len[3] */ + s[7] = 2; /* hf_intro.hf_typehi */ + s[8] = 8; /* hf_intro.hf_typelo */ + s[9] = 2; /* hf_sublen */ + s[10] = 0; /* hf_subtype */ + s[11] = 0; /* hf_rsvd */ + s[12] = shape; /* hf_shape */ + + if (ioctl(0, HFTGETID, &hftgid) < 0) { + /* perror("ioctl: HFTGETID"); */ + chno = -1; + } + else + chno = hftgid.hf_chan; + if (chno == -1) { + /** try being moronic and just writing what I want to + standard output ****/ + + if (((ioctl(2, TCGETA, &oldterm)) == -1) || + ((ioctl(2, TCGETA, &newterm)) == -1)) { + perror("Getting termio"); + exit(0); + } + newterm.c_oflag = newterm.c_lflag = newterm.c_iflag = 0; + newterm.c_cc[0] = -1; + for (i = 1; i <= 5; i++) + newterm.c_cc[i] = 0; + if ((ioctl(2, TCSETAF, &newterm)) == -1) { + perror("Setting to raw mode"); + exit(0); + } + write(2, s, 13); + read(0, s, 1024); + if ((ioctl(2, TCSETAF, &oldterm)) == -1) { + perror("Resetting terminal"); + exit(0); + } + } + else { + /* open the currently active virtual terminal on the hft */ + sprintf(hftpath, "/dev/hft/%d", chno); + if ((hftfd = open(hftpath, O_RDWR)) == -1) { + perror("Could not open hft channel\n"); + exit(0); + } + write(hftfd, s, 13); + } +} +#else + +int +Cursor_shape(int shape) +{ + return shape; +} +#endif + + + + + diff --git a/src/lib/edin.c b/src/lib/edin.c deleted file mode 100644 index 568bb77a..00000000 --- a/src/lib/edin.c +++ /dev/null @@ -1,951 +0,0 @@ -/* - Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. - All rights reserved. - Copyright (C) 2007-2010, 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 debug 1 */ - -#include -#include "openaxiom-c-macros.h" -#include -#include -#include -#include - -#include "edible.h" - -#define HFT 0 -#define SUN 1 -#define DEC 2 -#define control_to_alpha(x) (x + ('A' - 0x01)) -#define alpha_to_control(x) (x - ('A' - 0x01)) - -int termId; -QueStruct *ring = NULL; -QueStruct *current = NULL; -int ring_size = 0; -int MAXRING = 64; -int prev_check = 10; -int curr_pntr; -int num_pntr; -int num_proc; -int had_tab; -int had_tab_last; -extern char buff[1024]; /* Buffers for collecting input and */ -extern int buff_flag[1024]; /* flags for whether buff chars - are printing or non-printing */ -int buff_pntr; /* present length of buff */ - - -#include "edin.h" -#include "prt.h" -#include "wct.h" -#include "cursor.h" -#include "fnct_key.h" - - - -void -init_reader(void) -{ - char *termVal; - - buff[50] = '\0'; /** initialize some stuff ***/ - init_flag(buff_flag, MAXLINE); - buff_pntr = curr_pntr = 0; - - had_tab = 0; - had_tab_last = 0; - termVal = (char *) getenv("TERM"); - if (!strcmp("sun", termVal)) - termId = SUN; - else if (!strcmp("xterm", termVal) || !strncmp("vt", termVal, 2)) - termId = DEC; - else if (!strcmp("hft", termVal) || !strncmp("aixterm", termVal, 7)) - termId = HFT; -} - - -void -do_reading(void) -{ - int ttt_read; - int done_completely; - - done_completely = 0; - num_proc = 0; - while (num_proc < num_read) { - if(in_buff[num_proc]== _ERASE) { - back_over_current_char(); - num_proc++; - } - else { - switch (in_buff[num_proc]) { - /* lets start checking for different types of chars */ - case _EOLN: - case _CR: - /* If I have read a complete line, so send it to the child */ - send_line_to_child(); - if (!PTY) - myputchar('\n'); - break; - - /* - * Use 0x7f as delete - */ - case _DEL: - /* Had a delete key */ - delete_current_char(); - break; - - case _CNTRL_W: - move_back_word(); - num_proc++; - break; - case _TAB: - had_tab = 1; - /* command completion stuff */ - num_proc++; - if (had_tab_last) - rescan_wct(); - else - find_wct(); - break; - case _BELL: - insert_buff_nonprinting(1); - putchar(_BELL); - fflush(stdout); - break; - case _ESC: - - /* - * get 2 characters more - */ - while (!(num_read - num_proc > 2)) { - ttt_read = read(0, - in_buff + num_read, - 2 - (num_read - num_proc) + 1); - if (ttt_read > 0) - num_read = num_read + ttt_read; - } - if (in_buff[num_proc + 1] == _LBRACK) { - - /* ESC [ */ - - switch (in_buff[num_proc + 2]) { - /* look for arrows */ - case _A: - /* up arrow */ - - /* - * The first thing I plan to do is get rid of the present - * input ** - */ - prev_buff(); - curr_pntr = buff_pntr; - num_proc = num_proc + 3; - break; - case _B: - /* down arrow */ - next_buff(); - curr_pntr = buff_pntr; - num_proc = num_proc + 3; - break; - case _C: - /* right arrow */ - move_ahead(); - num_proc = num_proc + 3; - break; - case _D: - /* left arrow */ - move_back(); - num_proc = num_proc + 3; - break; - - /* - * Use ^[[P as delete - */ - case _P: - /*** Had a delete key ****/ - delete_current_char(); - break; - case _H: - case 0: - move_home(); - num_proc += 3; - break; - case _M: - case _Z: - insert_buff_nonprinting(3); - done_completely = 1; - num_proc += 3; - break; - case _x: - num_proc = num_read; - break; - case _1: - case _2: - case _0: - - /* - * I have had a possible function key hit, look for the - * ones I want. check for ESC ] x ~ - */ - while (!(num_read - num_proc > 3)) { - ttt_read = read(0, - in_buff + num_read, - 3 - (num_read - num_proc) + 1); - if (ttt_read > 0) - num_read = num_read + ttt_read; - } - if (in_buff[num_proc + 3] == _twiddle) { - - /* - * treat ESC ] x ~ - */ - switch (in_buff[num_proc + 2]) { - case _2: - flip(INS_MODE); - if (INS_MODE) - Cursor_shape(5); - else - Cursor_shape(2); - reprint(curr_pntr); - num_proc += 4; - break; - default: - insert_buff_nonprinting(1); - break; - } - break; - } - /* check for ESC ] x y ~ */ - while (!(num_read - num_proc > 4)) { - ttt_read = read(0, - in_buff + num_read, - 4 - (num_read - num_proc) + 1); - if (ttt_read > 0) - num_read = num_read + ttt_read; - } - if (in_buff[num_proc + 4] == _twiddle) { - - /* - * treat ESC ] x y ~ - */ - insert_buff_nonprinting(1); - break; - } - - /* check for ESC ] x y z [q|z] */ - - while (!(num_read - num_proc > 5)) { - ttt_read = read(0, - in_buff + num_read, - 5 - (num_read - num_proc) + 1); - if (ttt_read > 0) - num_read = num_read + ttt_read; - } - if (insert_toggle(&in_buff[num_proc + 3])) { - flip(INS_MODE); - if (INS_MODE) - Cursor_shape(5); - else - Cursor_shape(2); - reprint(curr_pntr); - num_proc = num_proc + 6; - break; - } - else if (cntrl_end(&in_buff[num_proc + 3])) { - num_proc = num_proc + 6; - delete_to_end_of_line(); - break; - } - else if (back_word(&in_buff[num_proc + 3])) { - move_back_word(); - num_proc += 6; - break; - } - else if (fore_word(&in_buff[num_proc + 3])) { - move_fore_word(); - num_proc += 6; - break; - } - else if (end_key(&in_buff[num_proc + 3])) { - move_end(); - num_proc += 6; - break; - } - switch (in_buff[num_proc + 5]) { - case _q: - - /* - * IBM function keys - */ - { - char num[3]; - int key; - - num[0] = in_buff[num_proc + 3]; - num[1] = in_buff[num_proc + 4]; - num[2] = '\0'; - key = atoi(num); - if (key > 0 && key < 13) { - if (function_key[key].str != NULL) { - handle_function_key(key, contNum); - done_completely = 1; - } - else { - insert_buff_nonprinting(6); - done_completely = 1; - } - } - else { - insert_buff_nonprinting(6); - done_completely = 1; - } - break; - } - case _z: - - /* - * Sun function keys - */ - { - char num[3]; - int key; - - num[0] = in_buff[num_proc + 3]; - num[1] = in_buff[num_proc + 4]; - num[2] = '\0'; - key = atoi(num) - 23; - if (key > 0 && key < 13) { - if (function_key[key].str != NULL) { - handle_function_key(key, contNum); - done_completely = 1; - } - else { - insert_buff_nonprinting(6); - done_completely = 1; - } - } - else if (atoi(num) == 14) { - move_home(); - num_proc += 6; - done_completely = 1; - } - else if (atoi(num) == 20) { - move_end(); - num_proc += 6; - done_completely = 1; - } - else if (atoi(num) == 47) { - flip(INS_MODE); - if (INS_MODE) - Cursor_shape(5); - else - Cursor_shape(2); - reprint(curr_pntr); - num_proc = num_proc + 6; - done_completely = 1; - } - else { - insert_buff_nonprinting(6); - done_completely = 1; - } - - break; - } - - default: - insert_buff_nonprinting(1); - break; - } - default: - if (!done_completely) - insert_buff_nonprinting(1); - break; - } - } /* if */ - else { /* ESC w/o [ */ - insert_buff_nonprinting(1); - } - break; - - case _BKSPC: - back_over_current_char(); - num_proc++; - break; - default: - if (in_buff[num_proc] == _KILL) { - delete_line(); - num_proc++; - } - else { - if ((in_buff[num_proc] == _INTR) || (in_buff[num_proc] == _QUIT)) { - write(contNum, &in_buff[num_proc], num_read - num_proc); - if (!PTY) - write(contNum, "\n", 1); - num_proc++; - } - else { - if (in_buff[num_proc] == _EOF) { - insert_buff_nonprinting(1); - if (!PTY) - write(contNum, "\n", 1); - - /*comment out this bit - if (!buff_pntr) { - write(contNum, &in_buff[num_proc], 1); - if (!PTY) - write(contNum, "\n", 1); - } - else { - write(contNum, buff, buff_pntr); - } - */ - num_proc++; - } - else { - if (in_buff[num_proc] == _EOL) { - send_line_to_child(); - if (!PTY) - write(contNum, "\n", 1); - } - else { - if (in_buff[num_proc] == _ERASE) { - back_over_current_char(); - num_proc++; - } - else { - if (control_char(in_buff[num_proc])) - insert_buff_nonprinting(1); - else - insert_buff_printing(1); - } - } - } - } - } /* close the default case */ - break; - } /* switch */ - } /*else*/ - if (had_tab) { - had_tab_last = 1; - had_tab = 0; - } - else - had_tab_last = 0; - - } /* while */ -} - - - -void -send_line_to_child(void) -{ - static char converted_buffer[MAXLINE]; - int converted_num; - - /* Takes care of sending a line to the child, and resetting the - buffer for new input */ - - back_it_up(curr_pntr); - - /* start by putting the line into the command line ring ***/ - if (buff_pntr) - insert_queue(); - - /* finish the line and send it to the child **/ - buff[buff_pntr] = in_buff[num_proc]; - buff_flag[buff_pntr++] = 1; - buff[buff_pntr] = '\0'; - buff_flag[buff_pntr] = -1; - - /* - * Instead of actually writing the Line, I have to substitute in the - * actual characters recieved - */ - converted_num = - convert_buffer(converted_buffer, buff, buff_flag, buff_pntr); - write(contNum, converted_buffer, converted_num); - - /** reinitialize the buffer ***/ - init_flag(buff_flag, buff_pntr); - init_buff(buff, buff_pntr); - /** reinitialize my buffer pointers **/ - buff_pntr = curr_pntr = 0; - - /** reset the ring pointer **/ - current = NULL; - num_proc++; - return; -} - -int -convert_buffer(char *target, char *source,int * source_flag, int num) -{ - int i, j; - - /* - * Until I get something wierd, just keep copying - */ - for (i = 0, j = 0; i < num; i++, j++) { - switch (source[i]) { - case _CARROT: - if (source_flag[i] == 1) { - target[j] = source[i]; - } - else { - if (source[i + 1] == _LBRACK) { - target[j] = _ESC; - i++; - } - else if (source[i + 1] >= 'A' && source[i + 1] <= 'Z') { - target[j] = alpha_to_control(source[i + 1]); - i++; - } - } - break; - case '?': - default: - target[j] = source[i]; - } - } - return j; -} - - -void -insert_buff_printing(int amount) -{ - int count; - - /* This procedure takes the character at in_buff[num_proc] and adds - it to the buffer. It first checks to see if we should be inserting - or overwriting, and then does the appropriate thing */ - - if ((buff_pntr + amount) > 1023) { - putchar(_BELL); - fflush(stdout); - num_proc += amount; - } - else { - - if (INS_MODE) { - - forwardcopy(&buff[curr_pntr + amount], - &buff[curr_pntr], - buff_pntr - curr_pntr); - forwardflag_cpy(&buff_flag[curr_pntr + amount], - &buff_flag[curr_pntr], - buff_pntr - curr_pntr); - for (count = 0; count < amount; count++) { - buff[curr_pntr + count] = in_buff[num_proc + count]; - buff_flag[curr_pntr + count] = 1; - } - ins_print(curr_pntr, amount); - buff_pntr = buff_pntr + amount; - } - else { - for (count = 0; count < amount; count++) { - if (buff_flag[curr_pntr + count] == 2) { - myputchar(buff[curr_pntr + count]); - curr_pntr += count + 1; - delete_current_char(); - /** fix num_proc affected by delete **/ - num_proc -= 3; - curr_pntr -= count + 1; - myputchar(_BKSPC); - } - buff[curr_pntr + count] = in_buff[num_proc + count]; - buff_flag[curr_pntr + count] = 1; - } - myputchar(in_buff[num_proc]); - if (curr_pntr == buff_pntr) - buff_pntr++; - } - num_proc = num_proc + amount; - curr_pntr = curr_pntr + amount; - fflush(stdout); - } - return; - -} - -void -insert_buff_nonprinting(int amount) -{ - int count; - - /* This procedure takes the character at in_buff[num_proc] and adds - it to the buffer. It first checks to see if we should be inserting - or overwriting, and then does the appropriate thing */ - - /* it takes care of the special case, when I have an esc character */ - - if ((buff_pntr + amount) > 1023) { - myputchar(_BELL); - fflush(stdout); - num_proc += amount; - } - else { - if (INS_MODE) { - forwardcopy(&buff[curr_pntr + amount + 1], - &buff[curr_pntr], - buff_pntr - curr_pntr); - forwardflag_cpy(&buff_flag[curr_pntr + amount + 1], - &buff_flag[curr_pntr], - buff_pntr - curr_pntr); - /** now insert the special character **/ - switch (in_buff[num_proc]) { - case _ESC: - /** in this case I insert a '^[' into the string ***/ - buff[curr_pntr] = _CARROT; - buff_flag[curr_pntr] = 2; - buff[curr_pntr + 1] = _LBRACK; - buff_flag[curr_pntr + 1] = 0; - break; - default: - if (control_char(in_buff[num_proc])) { - buff[curr_pntr] = _CARROT; - buff_flag[curr_pntr] = 2; - buff[curr_pntr + 1] = control_to_alpha(in_buff[num_proc]); - buff_flag[curr_pntr + 1] = 0; - } - else { - /** What do I have ? **/ - buff[curr_pntr] = '?'; - buff_flag[curr_pntr] = 2; - buff[curr_pntr + 1] = in_buff[num_proc]; - buff_flag[curr_pntr] = 0; - break; - } - } - /** Now add the normal characters **/ - for (count = 1; count < amount; count++) { - buff[curr_pntr + count + 1] = in_buff[num_proc + count]; - buff_flag[curr_pntr + count + 1] = 1; - } - ins_print(curr_pntr, amount + 1); - buff_pntr = buff_pntr + amount + 1; - } - else { - /** I am in the overstrike mode **/ - switch (in_buff[num_proc]) { - case _ESC: - /** in this case I insert a '^[' into the string ***/ - buff[curr_pntr] = _CARROT; - buff_flag[curr_pntr] = 2; - buff[curr_pntr + 1] = _LBRACK; - buff_flag[curr_pntr + 1] = 0; - break; - default: - if (control_char(in_buff[num_proc])) { - buff[curr_pntr] = _CARROT; - buff_flag[curr_pntr] = 2; - buff[curr_pntr + 1] = control_to_alpha(in_buff[num_proc]); - buff_flag[curr_pntr + 1] = 0; - } - else { - /** What do I have ? **/ - buff[curr_pntr] = '?'; - buff_flag[curr_pntr] = 2; - buff[curr_pntr + 1] = in_buff[num_proc]; - buff_flag[curr_pntr] = 0; - break; - } - } - for (count = 1; count < amount; count++) { - if (buff_flag[curr_pntr + count] == 2) { - curr_pntr += count + 1; - delete_current_char(); - /** fix num. processed form delete **/ - num_proc -= 3; - curr_pntr -= count + 1; - } - buff[curr_pntr + count + 1] = in_buff[num_proc + count]; - buff_flag[curr_pntr + count + 1] = 1; - } - /** now print the characters I have put in **/ - printbuff(curr_pntr, amount + 1); - } - num_proc = num_proc + amount; - curr_pntr = curr_pntr + amount + 1; - if (curr_pntr > buff_pntr) - buff_pntr = curr_pntr; - } - return; - -} - -void -prev_buff(void) -{ - - /* - * If the current command ring is NULL, then I should NOT clear the - * current line. Thus my business is already done - */ - if (ring == NULL) - return; - clear_buff(); - init_buff(buff, buff_pntr); - init_flag(buff_flag, buff_pntr); - - if (current == NULL) { - if (ring == NULL) - return; - current = ring; - } - else - current = current->prev; - strcpy(buff, current->buff); - flagcpy(buff_flag, current->flags); - - /* first back up and blank the line */ - fflush(stdout); - printbuff(0, strlen(buff)); - curr_pntr = buff_pntr = strlen(buff); - fflush(stdout); - return ; -} - -void -next_buff(void) -{ - - /* - * If the current command ring is NULL, then I should NOT clear the - * current line. Thus my business is already done - */ - if (ring == NULL) - return; - clear_buff(); - init_buff(buff, buff_pntr); - init_flag(buff_flag, buff_pntr); - if (current == NULL) { - if (ring == NULL) - return; - current = ring->next; - } - else - current = current->next; - strcpy(buff, current->buff); - flagcpy(buff_flag, current->flags); - - /* first back up and blank the line **/ - fflush(stdout); - printbuff(0, strlen(buff)); - curr_pntr = buff_pntr = strlen(buff); - fflush(stdout); - return ; -} - - -void -forwardcopy(char *buff1,char * buff2,int num) -{ - int count; - - for (count = num; count >= 0; count--) - buff1[count] = buff2[count]; -} - - -void -forwardflag_cpy(int *buff1,int * buff2,int num) -{ - int count; - - for (count = num; count >= 0; count--) - buff1[count] = buff2[count]; -} - -void -strnmov(char *dest, const char *src, size_t n) -{ - while (n-- && (*dest++ = *src++)); -} - -void -strmov(char *dest, const char *src) -{ - while ((*dest++ = *src++)); -} - -void -flagcpy(int *s,int *t) -{ - while (*t >= 0) - *s++ = *t++; - *s = *t; -} - -void -flagncpy(int *s,int *t,int n) -{ - while (n-- > 0) - *s++ = *t++; -} - -void -insert_queue(void) -{ - QueStruct *trace; - QueStruct *new_q; - int c; - - if (!ECHOIT) - return; - if (ring != NULL && !strcmp(buff, ring->buff)) - return; - for (c = 0, trace = ring; trace != NULL && c < (prev_check - 1); - c++, trace = trace->prev) { - if (!strcmp(buff, trace->buff)) { - - /* - * throw this puppy at the end of the ring - */ - trace->next->prev = trace->prev; - trace->prev->next = trace->next; - trace->prev = ring; - trace->next = ring->next; - ring->next = trace; - trace->next->prev = trace; - ring = trace; - return; - } - } - - /* - * simply places the buff command into the front of the queue - */ - if (ring_size < MAXRING) { - new_q = (QueStruct *) malloc(sizeof(struct que_struct)); - if (new_q == NULL) { - fprintf(stderr, "Malloc Error: Ran out of memory\n"); - exit(-1); - } - if (ring_size == 0) { - ring = new_q; - ring->prev = ring->next = new_q; - } - else { - new_q->next = ring->next; - new_q->prev = ring; - ring->next = new_q; - new_q->next->prev = new_q; - ring = new_q; - } - ring_size++; - } - else - ring = ring->next; - - init_flag(ring->flags, MAXLINE); - init_buff(ring->buff, MAXLINE); - strcpy(ring->buff, buff); - flagncpy(ring->flags, buff_flag, buff_pntr); - (ring->buff)[buff_pntr] = '\0'; - (ring->flags)[buff_pntr] = -1; -} - - -void -init_flag(int *flags, int num) -{ - int i; - - for (i = 0; i < num; i++) - flags[i] = -1; -} - -void -init_buff(char *flags, int num) -{ - int i; - - for (i = 0; i < num; i++) - flags[i] = '\0'; -} - - -void -send_function_to_child(void) -{ - /* Takes care of sending a line to the child, and resetting the - buffer for new input */ - - back_it_up(curr_pntr); - /** start by putting the line into the command line ring ***/ - if (buff_pntr) - insert_queue(); - - /** finish the line and send it to the child **/ - buff[buff_pntr] = _EOLN; - - buff_flag[buff_pntr++] = 1; - buff[buff_pntr] = '\0'; - buff_flag[buff_pntr] = 0; - write(contNum, buff, buff_pntr); - - /** reinitialize the buffer ***/ - init_flag(buff_flag, buff_pntr); - init_buff(buff, buff_pntr); - /** reinitialize my buffer pointers **/ - buff_pntr = curr_pntr = 0; - - /** reset the ring pointer **/ - current = NULL; - - num_proc++; - return; -} - -void -send_buff_to_child(int chann) -{ - if (buff_pntr > 0) - write(chann, buff, buff_pntr); - num_proc += 6; - /** reinitialize the buffer ***/ - init_flag(buff_flag, buff_pntr); - init_buff(buff, buff_pntr); - /** reinitialize my buffer pointers **/ - buff_pntr = curr_pntr = 0; - /** reset the ring pointer **/ - current = NULL; - return; -} - diff --git a/src/lib/edin.cc b/src/lib/edin.cc new file mode 100644 index 00000000..7fee5176 --- /dev/null +++ b/src/lib/edin.cc @@ -0,0 +1,950 @@ +/* + Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2010, 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 debug 1 */ + +#include +#include +#include +#include +#include + +#include "edible.h" + +#define HFT 0 +#define SUN 1 +#define DEC 2 +#define control_to_alpha(x) (x + ('A' - 0x01)) +#define alpha_to_control(x) (x - ('A' - 0x01)) + +int termId; +QueStruct *ring = NULL; +QueStruct *current = NULL; +int ring_size = 0; +int MAXRING = 64; +int prev_check = 10; +int curr_pntr; +int num_pntr; +int num_proc; +int had_tab; +int had_tab_last; +extern char buff[1024]; /* Buffers for collecting input and */ +extern int buff_flag[1024]; /* flags for whether buff chars + are printing or non-printing */ +int buff_pntr; /* present length of buff */ + + +#include "edin.h" +#include "prt.h" +#include "wct.h" +#include "cursor.h" +#include "fnct_key.h" + + + +void +init_reader(void) +{ + char *termVal; + + buff[50] = '\0'; /** initialize some stuff ***/ + init_flag(buff_flag, MAXLINE); + buff_pntr = curr_pntr = 0; + + had_tab = 0; + had_tab_last = 0; + termVal = (char *) getenv("TERM"); + if (!strcmp("sun", termVal)) + termId = SUN; + else if (!strcmp("xterm", termVal) || !strncmp("vt", termVal, 2)) + termId = DEC; + else if (!strcmp("hft", termVal) || !strncmp("aixterm", termVal, 7)) + termId = HFT; +} + + +void +do_reading(void) +{ + int ttt_read; + int done_completely; + + done_completely = 0; + num_proc = 0; + while (num_proc < num_read) { + if(in_buff[num_proc]== _ERASE) { + back_over_current_char(); + num_proc++; + } + else { + switch (in_buff[num_proc]) { + /* lets start checking for different types of chars */ + case _EOLN: + case _CR: + /* If I have read a complete line, so send it to the child */ + send_line_to_child(); + if (!PTY) + myputchar('\n'); + break; + + /* + * Use 0x7f as delete + */ + case _DEL: + /* Had a delete key */ + delete_current_char(); + break; + + case _CNTRL_W: + move_back_word(); + num_proc++; + break; + case _TAB: + had_tab = 1; + /* command completion stuff */ + num_proc++; + if (had_tab_last) + rescan_wct(); + else + find_wct(); + break; + case _BELL: + insert_buff_nonprinting(1); + putchar(_BELL); + fflush(stdout); + break; + case _ESC: + + /* + * get 2 characters more + */ + while (!(num_read - num_proc > 2)) { + ttt_read = read(0, + in_buff + num_read, + 2 - (num_read - num_proc) + 1); + if (ttt_read > 0) + num_read = num_read + ttt_read; + } + if (in_buff[num_proc + 1] == _LBRACK) { + + /* ESC [ */ + + switch (in_buff[num_proc + 2]) { + /* look for arrows */ + case _A: + /* up arrow */ + + /* + * The first thing I plan to do is get rid of the present + * input ** + */ + prev_buff(); + curr_pntr = buff_pntr; + num_proc = num_proc + 3; + break; + case _B: + /* down arrow */ + next_buff(); + curr_pntr = buff_pntr; + num_proc = num_proc + 3; + break; + case _C: + /* right arrow */ + move_ahead(); + num_proc = num_proc + 3; + break; + case _D: + /* left arrow */ + move_back(); + num_proc = num_proc + 3; + break; + + /* + * Use ^[[P as delete + */ + case _P: + /*** Had a delete key ****/ + delete_current_char(); + break; + case _H: + case 0: + move_home(); + num_proc += 3; + break; + case _M: + case _Z: + insert_buff_nonprinting(3); + done_completely = 1; + num_proc += 3; + break; + case _x: + num_proc = num_read; + break; + case _1: + case _2: + case _0: + + /* + * I have had a possible function key hit, look for the + * ones I want. check for ESC ] x ~ + */ + while (!(num_read - num_proc > 3)) { + ttt_read = read(0, + in_buff + num_read, + 3 - (num_read - num_proc) + 1); + if (ttt_read > 0) + num_read = num_read + ttt_read; + } + if (in_buff[num_proc + 3] == _twiddle) { + + /* + * treat ESC ] x ~ + */ + switch (in_buff[num_proc + 2]) { + case _2: + flip(INS_MODE); + if (INS_MODE) + Cursor_shape(5); + else + Cursor_shape(2); + reprint(curr_pntr); + num_proc += 4; + break; + default: + insert_buff_nonprinting(1); + break; + } + break; + } + /* check for ESC ] x y ~ */ + while (!(num_read - num_proc > 4)) { + ttt_read = read(0, + in_buff + num_read, + 4 - (num_read - num_proc) + 1); + if (ttt_read > 0) + num_read = num_read + ttt_read; + } + if (in_buff[num_proc + 4] == _twiddle) { + + /* + * treat ESC ] x y ~ + */ + insert_buff_nonprinting(1); + break; + } + + /* check for ESC ] x y z [q|z] */ + + while (!(num_read - num_proc > 5)) { + ttt_read = read(0, + in_buff + num_read, + 5 - (num_read - num_proc) + 1); + if (ttt_read > 0) + num_read = num_read + ttt_read; + } + if (insert_toggle(&in_buff[num_proc + 3])) { + flip(INS_MODE); + if (INS_MODE) + Cursor_shape(5); + else + Cursor_shape(2); + reprint(curr_pntr); + num_proc = num_proc + 6; + break; + } + else if (cntrl_end(&in_buff[num_proc + 3])) { + num_proc = num_proc + 6; + delete_to_end_of_line(); + break; + } + else if (back_word(&in_buff[num_proc + 3])) { + move_back_word(); + num_proc += 6; + break; + } + else if (fore_word(&in_buff[num_proc + 3])) { + move_fore_word(); + num_proc += 6; + break; + } + else if (end_key(&in_buff[num_proc + 3])) { + move_end(); + num_proc += 6; + break; + } + switch (in_buff[num_proc + 5]) { + case _q: + + /* + * IBM function keys + */ + { + char num[3]; + int key; + + num[0] = in_buff[num_proc + 3]; + num[1] = in_buff[num_proc + 4]; + num[2] = '\0'; + key = atoi(num); + if (key > 0 && key < 13) { + if (function_key[key].str != NULL) { + handle_function_key(key, contNum); + done_completely = 1; + } + else { + insert_buff_nonprinting(6); + done_completely = 1; + } + } + else { + insert_buff_nonprinting(6); + done_completely = 1; + } + break; + } + case _z: + + /* + * Sun function keys + */ + { + char num[3]; + int key; + + num[0] = in_buff[num_proc + 3]; + num[1] = in_buff[num_proc + 4]; + num[2] = '\0'; + key = atoi(num) - 23; + if (key > 0 && key < 13) { + if (function_key[key].str != NULL) { + handle_function_key(key, contNum); + done_completely = 1; + } + else { + insert_buff_nonprinting(6); + done_completely = 1; + } + } + else if (atoi(num) == 14) { + move_home(); + num_proc += 6; + done_completely = 1; + } + else if (atoi(num) == 20) { + move_end(); + num_proc += 6; + done_completely = 1; + } + else if (atoi(num) == 47) { + flip(INS_MODE); + if (INS_MODE) + Cursor_shape(5); + else + Cursor_shape(2); + reprint(curr_pntr); + num_proc = num_proc + 6; + done_completely = 1; + } + else { + insert_buff_nonprinting(6); + done_completely = 1; + } + + break; + } + + default: + insert_buff_nonprinting(1); + break; + } + default: + if (!done_completely) + insert_buff_nonprinting(1); + break; + } + } /* if */ + else { /* ESC w/o [ */ + insert_buff_nonprinting(1); + } + break; + + case _BKSPC: + back_over_current_char(); + num_proc++; + break; + default: + if (in_buff[num_proc] == _KILL) { + delete_line(); + num_proc++; + } + else { + if ((in_buff[num_proc] == _INTR) || (in_buff[num_proc] == _QUIT)) { + write(contNum, &in_buff[num_proc], num_read - num_proc); + if (!PTY) + write(contNum, "\n", 1); + num_proc++; + } + else { + if (in_buff[num_proc] == _EOF) { + insert_buff_nonprinting(1); + if (!PTY) + write(contNum, "\n", 1); + + /*comment out this bit + if (!buff_pntr) { + write(contNum, &in_buff[num_proc], 1); + if (!PTY) + write(contNum, "\n", 1); + } + else { + write(contNum, buff, buff_pntr); + } + */ + num_proc++; + } + else { + if (in_buff[num_proc] == _EOL) { + send_line_to_child(); + if (!PTY) + write(contNum, "\n", 1); + } + else { + if (in_buff[num_proc] == _ERASE) { + back_over_current_char(); + num_proc++; + } + else { + if (control_char(in_buff[num_proc])) + insert_buff_nonprinting(1); + else + insert_buff_printing(1); + } + } + } + } + } /* close the default case */ + break; + } /* switch */ + } /*else*/ + if (had_tab) { + had_tab_last = 1; + had_tab = 0; + } + else + had_tab_last = 0; + + } /* while */ +} + + + +void +send_line_to_child(void) +{ + static char converted_buffer[MAXLINE]; + int converted_num; + + /* Takes care of sending a line to the child, and resetting the + buffer for new input */ + + back_it_up(curr_pntr); + + /* start by putting the line into the command line ring ***/ + if (buff_pntr) + insert_queue(); + + /* finish the line and send it to the child **/ + buff[buff_pntr] = in_buff[num_proc]; + buff_flag[buff_pntr++] = 1; + buff[buff_pntr] = '\0'; + buff_flag[buff_pntr] = -1; + + /* + * Instead of actually writing the Line, I have to substitute in the + * actual characters recieved + */ + converted_num = + convert_buffer(converted_buffer, buff, buff_flag, buff_pntr); + write(contNum, converted_buffer, converted_num); + + /** reinitialize the buffer ***/ + init_flag(buff_flag, buff_pntr); + init_buff(buff, buff_pntr); + /** reinitialize my buffer pointers **/ + buff_pntr = curr_pntr = 0; + + /** reset the ring pointer **/ + current = NULL; + num_proc++; + return; +} + +int +convert_buffer(char *target, char *source,int * source_flag, int num) +{ + int i, j; + + /* + * Until I get something wierd, just keep copying + */ + for (i = 0, j = 0; i < num; i++, j++) { + switch (source[i]) { + case _CARROT: + if (source_flag[i] == 1) { + target[j] = source[i]; + } + else { + if (source[i + 1] == _LBRACK) { + target[j] = _ESC; + i++; + } + else if (source[i + 1] >= 'A' && source[i + 1] <= 'Z') { + target[j] = alpha_to_control(source[i + 1]); + i++; + } + } + break; + case '?': + default: + target[j] = source[i]; + } + } + return j; +} + + +void +insert_buff_printing(int amount) +{ + int count; + + /* This procedure takes the character at in_buff[num_proc] and adds + it to the buffer. It first checks to see if we should be inserting + or overwriting, and then does the appropriate thing */ + + if ((buff_pntr + amount) > 1023) { + putchar(_BELL); + fflush(stdout); + num_proc += amount; + } + else { + + if (INS_MODE) { + + forwardcopy(&buff[curr_pntr + amount], + &buff[curr_pntr], + buff_pntr - curr_pntr); + forwardflag_cpy(&buff_flag[curr_pntr + amount], + &buff_flag[curr_pntr], + buff_pntr - curr_pntr); + for (count = 0; count < amount; count++) { + buff[curr_pntr + count] = in_buff[num_proc + count]; + buff_flag[curr_pntr + count] = 1; + } + ins_print(curr_pntr, amount); + buff_pntr = buff_pntr + amount; + } + else { + for (count = 0; count < amount; count++) { + if (buff_flag[curr_pntr + count] == 2) { + myputchar(buff[curr_pntr + count]); + curr_pntr += count + 1; + delete_current_char(); + /** fix num_proc affected by delete **/ + num_proc -= 3; + curr_pntr -= count + 1; + myputchar(_BKSPC); + } + buff[curr_pntr + count] = in_buff[num_proc + count]; + buff_flag[curr_pntr + count] = 1; + } + myputchar(in_buff[num_proc]); + if (curr_pntr == buff_pntr) + buff_pntr++; + } + num_proc = num_proc + amount; + curr_pntr = curr_pntr + amount; + fflush(stdout); + } + return; + +} + +void +insert_buff_nonprinting(int amount) +{ + int count; + + /* This procedure takes the character at in_buff[num_proc] and adds + it to the buffer. It first checks to see if we should be inserting + or overwriting, and then does the appropriate thing */ + + /* it takes care of the special case, when I have an esc character */ + + if ((buff_pntr + amount) > 1023) { + myputchar(_BELL); + fflush(stdout); + num_proc += amount; + } + else { + if (INS_MODE) { + forwardcopy(&buff[curr_pntr + amount + 1], + &buff[curr_pntr], + buff_pntr - curr_pntr); + forwardflag_cpy(&buff_flag[curr_pntr + amount + 1], + &buff_flag[curr_pntr], + buff_pntr - curr_pntr); + /** now insert the special character **/ + switch (in_buff[num_proc]) { + case _ESC: + /** in this case I insert a '^[' into the string ***/ + buff[curr_pntr] = _CARROT; + buff_flag[curr_pntr] = 2; + buff[curr_pntr + 1] = _LBRACK; + buff_flag[curr_pntr + 1] = 0; + break; + default: + if (control_char(in_buff[num_proc])) { + buff[curr_pntr] = _CARROT; + buff_flag[curr_pntr] = 2; + buff[curr_pntr + 1] = control_to_alpha(in_buff[num_proc]); + buff_flag[curr_pntr + 1] = 0; + } + else { + /** What do I have ? **/ + buff[curr_pntr] = '?'; + buff_flag[curr_pntr] = 2; + buff[curr_pntr + 1] = in_buff[num_proc]; + buff_flag[curr_pntr] = 0; + break; + } + } + /** Now add the normal characters **/ + for (count = 1; count < amount; count++) { + buff[curr_pntr + count + 1] = in_buff[num_proc + count]; + buff_flag[curr_pntr + count + 1] = 1; + } + ins_print(curr_pntr, amount + 1); + buff_pntr = buff_pntr + amount + 1; + } + else { + /** I am in the overstrike mode **/ + switch (in_buff[num_proc]) { + case _ESC: + /** in this case I insert a '^[' into the string ***/ + buff[curr_pntr] = _CARROT; + buff_flag[curr_pntr] = 2; + buff[curr_pntr + 1] = _LBRACK; + buff_flag[curr_pntr + 1] = 0; + break; + default: + if (control_char(in_buff[num_proc])) { + buff[curr_pntr] = _CARROT; + buff_flag[curr_pntr] = 2; + buff[curr_pntr + 1] = control_to_alpha(in_buff[num_proc]); + buff_flag[curr_pntr + 1] = 0; + } + else { + /** What do I have ? **/ + buff[curr_pntr] = '?'; + buff_flag[curr_pntr] = 2; + buff[curr_pntr + 1] = in_buff[num_proc]; + buff_flag[curr_pntr] = 0; + break; + } + } + for (count = 1; count < amount; count++) { + if (buff_flag[curr_pntr + count] == 2) { + curr_pntr += count + 1; + delete_current_char(); + /** fix num. processed form delete **/ + num_proc -= 3; + curr_pntr -= count + 1; + } + buff[curr_pntr + count + 1] = in_buff[num_proc + count]; + buff_flag[curr_pntr + count + 1] = 1; + } + /** now print the characters I have put in **/ + printbuff(curr_pntr, amount + 1); + } + num_proc = num_proc + amount; + curr_pntr = curr_pntr + amount + 1; + if (curr_pntr > buff_pntr) + buff_pntr = curr_pntr; + } + return; + +} + +void +prev_buff(void) +{ + + /* + * If the current command ring is NULL, then I should NOT clear the + * current line. Thus my business is already done + */ + if (ring == NULL) + return; + clear_buff(); + init_buff(buff, buff_pntr); + init_flag(buff_flag, buff_pntr); + + if (current == NULL) { + if (ring == NULL) + return; + current = ring; + } + else + current = current->prev; + strcpy(buff, current->buff); + flagcpy(buff_flag, current->flags); + + /* first back up and blank the line */ + fflush(stdout); + printbuff(0, strlen(buff)); + curr_pntr = buff_pntr = strlen(buff); + fflush(stdout); + return ; +} + +void +next_buff(void) +{ + + /* + * If the current command ring is NULL, then I should NOT clear the + * current line. Thus my business is already done + */ + if (ring == NULL) + return; + clear_buff(); + init_buff(buff, buff_pntr); + init_flag(buff_flag, buff_pntr); + if (current == NULL) { + if (ring == NULL) + return; + current = ring->next; + } + else + current = current->next; + strcpy(buff, current->buff); + flagcpy(buff_flag, current->flags); + + /* first back up and blank the line **/ + fflush(stdout); + printbuff(0, strlen(buff)); + curr_pntr = buff_pntr = strlen(buff); + fflush(stdout); + return ; +} + + +void +forwardcopy(char *buff1,char * buff2,int num) +{ + int count; + + for (count = num; count >= 0; count--) + buff1[count] = buff2[count]; +} + + +void +forwardflag_cpy(int *buff1,int * buff2,int num) +{ + int count; + + for (count = num; count >= 0; count--) + buff1[count] = buff2[count]; +} + +void +strnmov(char *dest, const char *src, size_t n) +{ + while (n-- && (*dest++ = *src++)); +} + +void +strmov(char *dest, const char *src) +{ + while ((*dest++ = *src++)); +} + +void +flagcpy(int *s,int *t) +{ + while (*t >= 0) + *s++ = *t++; + *s = *t; +} + +void +flagncpy(int *s,int *t,int n) +{ + while (n-- > 0) + *s++ = *t++; +} + +void +insert_queue(void) +{ + QueStruct *trace; + QueStruct *new_q; + int c; + + if (!ECHOIT) + return; + if (ring != NULL && !strcmp(buff, ring->buff)) + return; + for (c = 0, trace = ring; trace != NULL && c < (prev_check - 1); + c++, trace = trace->prev) { + if (!strcmp(buff, trace->buff)) { + + /* + * throw this puppy at the end of the ring + */ + trace->next->prev = trace->prev; + trace->prev->next = trace->next; + trace->prev = ring; + trace->next = ring->next; + ring->next = trace; + trace->next->prev = trace; + ring = trace; + return; + } + } + + /* + * simply places the buff command into the front of the queue + */ + if (ring_size < MAXRING) { + new_q = (QueStruct *) malloc(sizeof(struct que_struct)); + if (new_q == NULL) { + fprintf(stderr, "Malloc Error: Ran out of memory\n"); + exit(-1); + } + if (ring_size == 0) { + ring = new_q; + ring->prev = ring->next = new_q; + } + else { + new_q->next = ring->next; + new_q->prev = ring; + ring->next = new_q; + new_q->next->prev = new_q; + ring = new_q; + } + ring_size++; + } + else + ring = ring->next; + + init_flag(ring->flags, MAXLINE); + init_buff(ring->buff, MAXLINE); + strcpy(ring->buff, buff); + flagncpy(ring->flags, buff_flag, buff_pntr); + (ring->buff)[buff_pntr] = '\0'; + (ring->flags)[buff_pntr] = -1; +} + + +void +init_flag(int *flags, int num) +{ + int i; + + for (i = 0; i < num; i++) + flags[i] = -1; +} + +void +init_buff(char *flags, int num) +{ + int i; + + for (i = 0; i < num; i++) + flags[i] = '\0'; +} + + +void +send_function_to_child(void) +{ + /* Takes care of sending a line to the child, and resetting the + buffer for new input */ + + back_it_up(curr_pntr); + /** start by putting the line into the command line ring ***/ + if (buff_pntr) + insert_queue(); + + /** finish the line and send it to the child **/ + buff[buff_pntr] = _EOLN; + + buff_flag[buff_pntr++] = 1; + buff[buff_pntr] = '\0'; + buff_flag[buff_pntr] = 0; + write(contNum, buff, buff_pntr); + + /** reinitialize the buffer ***/ + init_flag(buff_flag, buff_pntr); + init_buff(buff, buff_pntr); + /** reinitialize my buffer pointers **/ + buff_pntr = curr_pntr = 0; + + /** reset the ring pointer **/ + current = NULL; + + num_proc++; + return; +} + +void +send_buff_to_child(int chann) +{ + if (buff_pntr > 0) + write(chann, buff, buff_pntr); + num_proc += 6; + /** reinitialize the buffer ***/ + init_flag(buff_flag, buff_pntr); + init_buff(buff, buff_pntr); + /** reinitialize my buffer pointers **/ + buff_pntr = curr_pntr = 0; + /** reset the ring pointer **/ + current = NULL; + return; +} + diff --git a/src/lib/emupty.c b/src/lib/emupty.c index 7ddfbd2d..9b9848c9 100644 --- a/src/lib/emupty.c +++ b/src/lib/emupty.c @@ -31,7 +31,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "openaxiom-c-macros.h" /* Here is some code taken from Nick Simicich. It takes an escape sequence diff --git a/src/lib/fnct_key.c b/src/lib/fnct_key.c deleted file mode 100644 index f70bc430..00000000 --- a/src/lib/fnct_key.c +++ /dev/null @@ -1,345 +0,0 @@ -/* - Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. - All rights reserved. - Copyright (C) 2007-2013 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 "openaxiom-c-macros.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#include "cfuns.h" -#include "edible.h" -#include "bsdsignal.h" - - -#include "fnct_key.h" -#include "prt.h" -#include "edin.h" - -/* FIXME: Remove this in complete rewrite */ -using namespace OpenAxiom; - -/** Some constants for functio key defs ****/ -#define DELAYED 0 -#define IMMEDIATE 1 -#define SPECIAL 2 - - -/** Here is the structure for storing bound pf-keys ***/ -fkey function_key[13]; /** Strings which replace function - keys when a key is hit ***/ - -static const char *defaulteditor = "clefedit"; -char editorfilename[100]; - - - -/* - * The following function environment variable clef editor. The command - * should be the one that the user wishes to have execed - */ - -void -set_editor_key(void) -{ - int pid; - - sprintf(editorfilename, "/tmp/clef%d", pid = oa_getpid()); - - if (function_key[12].str == NULL) { - (function_key[12]).type = SPECIAL; - (function_key[12]).str = defaulteditor; - } -} - - - - -/*** This routine id used to find the users function key mappings. It - simply searches the users HOME directory for a file called ".clef". - If found it gets the key bindings from within - *****/ - -void -define_function_keys(void) -{ - char *HOME, path[1024], string[1024]; - int key; - int fd; - char type; - - /** lets initialize the key pointers **/ - for (key = 0; key < 13; key++) - (function_key[key]).str = NULL; - /** see if the user has a .clef file ***/ - HOME = oa_getenv("HOME"); - sprintf(path, "%s/.clef", HOME); - if ((fd = open(path, O_RDONLY)) == -1) { - return; - } - else { - /*** If so, then get the key bindings **/ - while ((key = get_key(fd, &type))) { - get_str(fd, string); - switch (type) { - case 'D': - if (key == 12) { - fprintf(stderr, - "Clef Error: PF12 can only be of type E in .clef\n"); - fprintf(stderr, "Line will be ignored\n"); - type = -1; - } - else { - (function_key[key]).type = DELAYED; - } - break; - case 'F': - if (key == 12) { - fprintf(stderr, - "Clef Error: PF12 can only be of type E in .clef\n"); - fprintf(stderr, "Line will be ignored\n"); - type = -1; - } - else { - (function_key[key]).type = IMMEDIATE; - } - break; - case 'E': - if (key != 12) { - fprintf(stderr, - "Clef Error: PF12 can only be of type E in .clef\n"); - fprintf(stderr, "Line will be ignored\n"); - type = -1; - } - else { - (function_key[key]).type = SPECIAL; - } - break; - } - if (type != -1) - (function_key[key]).str = strdup(string); - } - } - - /* - * Now set the editor function key - */ - set_editor_key(); -} - - -#define defof(c) ((c == 'F' || c == 'D' || c == 'E')?(1):(0)) - -int -get_key(int fd,char * ty) -{ - - /* - * Determines the key number being mapped, and whether it is immediate or - * delay. It reurns the key value, and modifies the parameter type - */ - char keynum[1024]; - int nr; - - nr = read(fd, keynum, 3); - if (nr != -1 && nr != 0) { - if (!defof(keynum[0])) { - return 0; - } - else { - *ty = keynum[0]; - keynum[3] = '\0'; - return (atoi(&keynum[1])); - } - } - else - return 0; -} - -int -get_str(int fd,char * string) -{ - /** Gets the key mapping being bound **/ - char c; - int count = 0; - char *trace = string; - - read(fd, &c, 1); - while (c == ' ') - read(fd, &c, 1); - while (c != '\n') { - count++; - *trace++ = c; - if (read(fd, &c, 1) == 0) - break; - } - *trace = '\0'; - return count; -} - -void -null_fnct(int sig) -{ - return; -} - -void -handle_function_key(int key,int chann) -{ - /** this procedure simply adds the string specified by the function key - to the buffer ****/ - int count, fd; - int amount = strlen(function_key[key].str); - int id; - - /*** This procedure takes the character at in_buff[num_proc] and adds - it to the buffer. It first checks to see if we should be inserting - or overwriting, and then does the appropriate thing *******/ - - switch ((function_key[key]).type) { - case IMMEDIATE: - if (INS_MODE) { - forwardcopy(&buff[curr_pntr + amount], - &buff[curr_pntr], - buff_pntr - curr_pntr); - forwardflag_cpy(&buff_flag[curr_pntr + amount], - &buff_flag[curr_pntr], - buff_pntr - curr_pntr); - for (count = 0; count < amount; count++) { - buff[curr_pntr + count] = (function_key[key].str)[count]; - buff_flag[curr_pntr + count] = '1'; - } - ins_print(curr_pntr, amount + 1); - buff_pntr = buff_pntr + amount; - } - else { - for (count = 0; count < amount; count++) { - buff[curr_pntr + count] = (function_key[key].str)[count]; - buff_flag[curr_pntr + count] = '1'; - myputchar((function_key[key].str)[count]); - } - } - num_proc = num_proc + 6; - curr_pntr = curr_pntr + amount; - buff_pntr = buff_pntr + amount; - send_function_to_child(); - break; - case DELAYED: - if (INS_MODE) { - forwardcopy(&buff[curr_pntr + amount], - &buff[curr_pntr], - buff_pntr - curr_pntr); - forwardflag_cpy(&buff_flag[curr_pntr + amount], - &buff_flag[curr_pntr], - buff_pntr - curr_pntr); - for (count = 0; count < amount; count++) { - buff[curr_pntr + count] = (function_key[key].str)[count]; - buff_flag[curr_pntr + count] = '1'; - } - ins_print(curr_pntr, amount + 1); - buff_pntr = buff_pntr + amount; - } - else { - for (count = 0; count < amount; count++) { - buff[curr_pntr + count] = (function_key[key].str)[count]; - buff_flag[curr_pntr + count] = '1'; - myputchar((function_key[key].str)[count]); - } - } - num_proc = num_proc + 6; - curr_pntr = curr_pntr + amount; - buff_pntr = buff_pntr + amount; - fflush(stdout); - break; - case SPECIAL: - /* fprintf(stderr, "Here I am \n"); */ - if (access(editorfilename, F_OK) < 0) { - fd = open(editorfilename, O_RDWR | O_CREAT, 0666); - write(fd, buff, buff_pntr); - back_up(buff_pntr); - close(fd); - } - else { - if (buff_pntr > 0) { - fd = open(editorfilename, O_RDWR | O_TRUNC); - write(fd, buff, buff_pntr); - back_up(buff_pntr); - close(fd); - } - } - bsdSignal(OPENAXIOM_SIGCHLD, null_fnct,RestartSystemCalls); - switch (id = fork()) { - case -1: - perror("Special key"); - break; - case 0: - execlp((function_key[12]).str, - (function_key[12]).str, - editorfilename, (char*) NULL); - perror("Returned from exec"); - exit(0); - - } - while (wait((int *) 0) < 0); - /** now I should read that file and send all it stuff thru the - reader *****/ - fd = open(editorfilename, O_RDWR); - if (fd == -1) { - perror("Opening temp file"); - exit(-1); - } - num_proc += 6; - - /** reinitialize the buffer ***/ - init_flag(buff_flag, buff_pntr); - init_buff(buff, buff_pntr); - /** reinitialize my buffer pointers **/ - buff_pntr = curr_pntr = 0; - /** reset the ring pointer **/ - current = NULL; - ECHOIT = 0; - while ((num_read = read(fd, in_buff, MAXLINE))) { - do_reading(); - } - close(fd); - break; - } - return; - -} diff --git a/src/lib/fnct_key.cc b/src/lib/fnct_key.cc new file mode 100644 index 00000000..af0d5c28 --- /dev/null +++ b/src/lib/fnct_key.cc @@ -0,0 +1,344 @@ +/* + Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2013 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 +#include +#include +#include +#include +#include +#include +#include + +#include "cfuns.h" +#include "edible.h" +#include "bsdsignal.h" + + +#include "fnct_key.h" +#include "prt.h" +#include "edin.h" + +/* FIXME: Remove this in complete rewrite */ +using namespace OpenAxiom; + +/** Some constants for functio key defs ****/ +#define DELAYED 0 +#define IMMEDIATE 1 +#define SPECIAL 2 + + +/** Here is the structure for storing bound pf-keys ***/ +fkey function_key[13]; /** Strings which replace function + keys when a key is hit ***/ + +static const char *defaulteditor = "clefedit"; +char editorfilename[100]; + + + +/* + * The following function environment variable clef editor. The command + * should be the one that the user wishes to have execed + */ + +void +set_editor_key(void) +{ + int pid; + + sprintf(editorfilename, "/tmp/clef%d", pid = oa_getpid()); + + if (function_key[12].str == NULL) { + (function_key[12]).type = SPECIAL; + (function_key[12]).str = defaulteditor; + } +} + + + + +/*** This routine id used to find the users function key mappings. It + simply searches the users HOME directory for a file called ".clef". + If found it gets the key bindings from within + *****/ + +void +define_function_keys(void) +{ + char *HOME, path[1024], string[1024]; + int key; + int fd; + char type; + + /** lets initialize the key pointers **/ + for (key = 0; key < 13; key++) + (function_key[key]).str = NULL; + /** see if the user has a .clef file ***/ + HOME = oa_getenv("HOME"); + sprintf(path, "%s/.clef", HOME); + if ((fd = open(path, O_RDONLY)) == -1) { + return; + } + else { + /*** If so, then get the key bindings **/ + while ((key = get_key(fd, &type))) { + get_str(fd, string); + switch (type) { + case 'D': + if (key == 12) { + fprintf(stderr, + "Clef Error: PF12 can only be of type E in .clef\n"); + fprintf(stderr, "Line will be ignored\n"); + type = -1; + } + else { + (function_key[key]).type = DELAYED; + } + break; + case 'F': + if (key == 12) { + fprintf(stderr, + "Clef Error: PF12 can only be of type E in .clef\n"); + fprintf(stderr, "Line will be ignored\n"); + type = -1; + } + else { + (function_key[key]).type = IMMEDIATE; + } + break; + case 'E': + if (key != 12) { + fprintf(stderr, + "Clef Error: PF12 can only be of type E in .clef\n"); + fprintf(stderr, "Line will be ignored\n"); + type = -1; + } + else { + (function_key[key]).type = SPECIAL; + } + break; + } + if (type != -1) + (function_key[key]).str = strdup(string); + } + } + + /* + * Now set the editor function key + */ + set_editor_key(); +} + + +#define defof(c) ((c == 'F' || c == 'D' || c == 'E')?(1):(0)) + +int +get_key(int fd,char * ty) +{ + + /* + * Determines the key number being mapped, and whether it is immediate or + * delay. It reurns the key value, and modifies the parameter type + */ + char keynum[1024]; + int nr; + + nr = read(fd, keynum, 3); + if (nr != -1 && nr != 0) { + if (!defof(keynum[0])) { + return 0; + } + else { + *ty = keynum[0]; + keynum[3] = '\0'; + return (atoi(&keynum[1])); + } + } + else + return 0; +} + +int +get_str(int fd,char * string) +{ + /** Gets the key mapping being bound **/ + char c; + int count = 0; + char *trace = string; + + read(fd, &c, 1); + while (c == ' ') + read(fd, &c, 1); + while (c != '\n') { + count++; + *trace++ = c; + if (read(fd, &c, 1) == 0) + break; + } + *trace = '\0'; + return count; +} + +void +null_fnct(int sig) +{ + return; +} + +void +handle_function_key(int key,int chann) +{ + /** this procedure simply adds the string specified by the function key + to the buffer ****/ + int count, fd; + int amount = strlen(function_key[key].str); + int id; + + /*** This procedure takes the character at in_buff[num_proc] and adds + it to the buffer. It first checks to see if we should be inserting + or overwriting, and then does the appropriate thing *******/ + + switch ((function_key[key]).type) { + case IMMEDIATE: + if (INS_MODE) { + forwardcopy(&buff[curr_pntr + amount], + &buff[curr_pntr], + buff_pntr - curr_pntr); + forwardflag_cpy(&buff_flag[curr_pntr + amount], + &buff_flag[curr_pntr], + buff_pntr - curr_pntr); + for (count = 0; count < amount; count++) { + buff[curr_pntr + count] = (function_key[key].str)[count]; + buff_flag[curr_pntr + count] = '1'; + } + ins_print(curr_pntr, amount + 1); + buff_pntr = buff_pntr + amount; + } + else { + for (count = 0; count < amount; count++) { + buff[curr_pntr + count] = (function_key[key].str)[count]; + buff_flag[curr_pntr + count] = '1'; + myputchar((function_key[key].str)[count]); + } + } + num_proc = num_proc + 6; + curr_pntr = curr_pntr + amount; + buff_pntr = buff_pntr + amount; + send_function_to_child(); + break; + case DELAYED: + if (INS_MODE) { + forwardcopy(&buff[curr_pntr + amount], + &buff[curr_pntr], + buff_pntr - curr_pntr); + forwardflag_cpy(&buff_flag[curr_pntr + amount], + &buff_flag[curr_pntr], + buff_pntr - curr_pntr); + for (count = 0; count < amount; count++) { + buff[curr_pntr + count] = (function_key[key].str)[count]; + buff_flag[curr_pntr + count] = '1'; + } + ins_print(curr_pntr, amount + 1); + buff_pntr = buff_pntr + amount; + } + else { + for (count = 0; count < amount; count++) { + buff[curr_pntr + count] = (function_key[key].str)[count]; + buff_flag[curr_pntr + count] = '1'; + myputchar((function_key[key].str)[count]); + } + } + num_proc = num_proc + 6; + curr_pntr = curr_pntr + amount; + buff_pntr = buff_pntr + amount; + fflush(stdout); + break; + case SPECIAL: + /* fprintf(stderr, "Here I am \n"); */ + if (access(editorfilename, F_OK) < 0) { + fd = open(editorfilename, O_RDWR | O_CREAT, 0666); + write(fd, buff, buff_pntr); + back_up(buff_pntr); + close(fd); + } + else { + if (buff_pntr > 0) { + fd = open(editorfilename, O_RDWR | O_TRUNC); + write(fd, buff, buff_pntr); + back_up(buff_pntr); + close(fd); + } + } + bsdSignal(OPENAXIOM_SIGCHLD, null_fnct,RestartSystemCalls); + switch (id = fork()) { + case -1: + perror("Special key"); + break; + case 0: + execlp((function_key[12]).str, + (function_key[12]).str, + editorfilename, (char*) NULL); + perror("Returned from exec"); + exit(0); + + } + while (wait((int *) 0) < 0); + /** now I should read that file and send all it stuff thru the + reader *****/ + fd = open(editorfilename, O_RDWR); + if (fd == -1) { + perror("Opening temp file"); + exit(-1); + } + num_proc += 6; + + /** reinitialize the buffer ***/ + init_flag(buff_flag, buff_pntr); + init_buff(buff, buff_pntr); + /** reinitialize my buffer pointers **/ + buff_pntr = curr_pntr = 0; + /** reset the ring pointer **/ + current = NULL; + ECHOIT = 0; + while ((num_read = read(fd, in_buff, MAXLINE))) { + do_reading(); + } + close(fd); + break; + } + return; + +} diff --git a/src/lib/halloc.c b/src/lib/halloc.c index 4b19c60a..fb43d6b3 100644 --- a/src/lib/halloc.c +++ b/src/lib/halloc.c @@ -31,7 +31,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "openaxiom-c-macros.h" /* memory allocation used by HyperDoc and addfile */ diff --git a/src/lib/hash.c b/src/lib/hash.c index 837eb8b1..7f727ecf 100644 --- a/src/lib/hash.c +++ b/src/lib/hash.c @@ -32,7 +32,6 @@ */ -#include "openaxiom-c-macros.h" #define _HASH_C #include "debug.h" diff --git a/src/lib/openpty.c b/src/lib/openpty.c deleted file mode 100644 index 5918aa7a..00000000 --- a/src/lib/openpty.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. - All rights reserved. - Copyright (C) 2007-2013, 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 "openaxiom-c-macros.h" -#include -#include -#include -#include -#include - -#ifdef HAVE_SYS_IOCTL_H -# include -#endif -#ifdef HAVE_PTY_H -# include -#endif -#ifdef HAVE_UTIL_H -# include -#endif -#ifdef HAVE_TERMIOS_H -# include -#endif -#ifdef HAVE_LIBUTIL_H -# include -# include -#endif - - -#include "openpty.h" - -#if defined(SUNplatform) -static void -makeNextPtyNames(char *cont,char * serv) -{ - static int channelNo = 0; - static char group[] = "pqrstuvwxyzPQRST"; - static int groupNo = 0; - - sprintf(cont, "/dev/pty%c%x", group[groupNo], channelNo); - sprintf(serv, "/dev/tty%c%x", group[groupNo], channelNo); - channelNo++; /* try next */ - if (channelNo == 16) { /* move to new group */ - channelNo = 0; - groupNo++; - if (groupNo == 16) groupNo = 0; /* recycle */ - } -} -#endif - - -/* - * The main function is ptyopen. It simply opens up both sides of a - * pseudo-terminal. It uses and saves the pathnames for - * the devices which were actually opened. - * - * If it fails it simply exits the program. - * - * - * ptyopen(controller, server, controllerPath, serverPath) - * int *controller; The file descriptor for controller side of the pty - * int *server; The file descriptor for the server side - * char *serverPath; - * - * The path name vars should be declared of size 11 or more - */ - - -int -ptyopen(int *controller,int * server,char * serverPath) -{ -#if HAVE_DECL_OPENPTY - return openpty(controller,server, serverPath, NULL, NULL); -#elif defined(SUNplatform) - int looking = 1, i; - int oflag = O_RDWR; /* flag for opening the pty */ - char controllerPath[128]; - - for (i = 0; looking && i < 1000; i++) { - makeNextPtyNames(controllerPath, serverPath); - if (access(controllerPath, 6) != 0) continue; - *controller = open(controllerPath, oflag, 0); - if (*controller >= 0) { - *server = open(serverPath, oflag, 0); - if (*server > 0) - looking = 0; - else - close(*controller); - } - } - if (looking) { - fprintf(stderr, "Couldn't find a free pty.\n"); - exit(-1); - } - return (*controller); -#elif defined(SUN4OS5platform) -extern int grantpt(int); -extern int unlockpt(int); -extern char* ptsname(int); - int fdm,fds; - char *slavename; - - /* open master */ - if ((fdm = open("/dev/ptmx", O_RDWR)) < 0 ) - perror("ptyopen: Failed to open /dev/ptmx"); - else { - /* change permission ofslave */ - if (grantpt(fdm) < 0) - perror("ptyopen: Failed to grant access to slave device"); - /* unlock slave */ - if (unlockpt(fdm) < 0) - perror("ptyopen: Failed to unlock master/slave pair"); - /* get name of slave */ - if ((slavename = ptsname(fdm)) == NULL) - perror("ptyopen: Failed to get name of slave device"); - /* open slave */ - if ((fds = open(slavename, O_RDWR)) < 0 ) - perror("ptyopen: Failed to open slave"); - else { - /* push ptem */ - if (ioctl(fds, I_PUSH, "ptem") < 0) - perror("ptyopen: Failed to push ptem"); - /* push ldterm */ - if (ioctl(fds, I_PUSH, "ldterm") < 0) - perror("ptyopen: Failed to push idterm"); - strcpy(serverPath,slavename); - *controller=fdm; - *server=fds; - } - } - return(fdm); -#else -# error "don't know how to open a pty" -#endif -} - - diff --git a/src/lib/openpty.cc b/src/lib/openpty.cc new file mode 100644 index 00000000..4262832e --- /dev/null +++ b/src/lib/openpty.cc @@ -0,0 +1,171 @@ +/* + Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2013, 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. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#ifdef HAVE_PTY_H +# include +#endif +#ifdef HAVE_UTIL_H +# include +#endif +#ifdef HAVE_TERMIOS_H +# include +#endif +#ifdef HAVE_LIBUTIL_H +# include +# include +#endif + + +#include "openpty.h" + +#if defined(SUNplatform) +static void +makeNextPtyNames(char *cont,char * serv) +{ + static int channelNo = 0; + static char group[] = "pqrstuvwxyzPQRST"; + static int groupNo = 0; + + sprintf(cont, "/dev/pty%c%x", group[groupNo], channelNo); + sprintf(serv, "/dev/tty%c%x", group[groupNo], channelNo); + channelNo++; /* try next */ + if (channelNo == 16) { /* move to new group */ + channelNo = 0; + groupNo++; + if (groupNo == 16) groupNo = 0; /* recycle */ + } +} +#endif + + +/* + * The main function is ptyopen. It simply opens up both sides of a + * pseudo-terminal. It uses and saves the pathnames for + * the devices which were actually opened. + * + * If it fails it simply exits the program. + * + * + * ptyopen(controller, server, controllerPath, serverPath) + * int *controller; The file descriptor for controller side of the pty + * int *server; The file descriptor for the server side + * char *serverPath; + * + * The path name vars should be declared of size 11 or more + */ + + +int +ptyopen(int *controller,int * server,char * serverPath) +{ +#if HAVE_DECL_OPENPTY + return openpty(controller,server, serverPath, NULL, NULL); +#elif defined(SUNplatform) + int looking = 1, i; + int oflag = O_RDWR; /* flag for opening the pty */ + char controllerPath[128]; + + for (i = 0; looking && i < 1000; i++) { + makeNextPtyNames(controllerPath, serverPath); + if (access(controllerPath, 6) != 0) continue; + *controller = open(controllerPath, oflag, 0); + if (*controller >= 0) { + *server = open(serverPath, oflag, 0); + if (*server > 0) + looking = 0; + else + close(*controller); + } + } + if (looking) { + fprintf(stderr, "Couldn't find a free pty.\n"); + exit(-1); + } + return (*controller); +#elif defined(SUN4OS5platform) +extern int grantpt(int); +extern int unlockpt(int); +extern char* ptsname(int); + int fdm,fds; + char *slavename; + + /* open master */ + if ((fdm = open("/dev/ptmx", O_RDWR)) < 0 ) + perror("ptyopen: Failed to open /dev/ptmx"); + else { + /* change permission ofslave */ + if (grantpt(fdm) < 0) + perror("ptyopen: Failed to grant access to slave device"); + /* unlock slave */ + if (unlockpt(fdm) < 0) + perror("ptyopen: Failed to unlock master/slave pair"); + /* get name of slave */ + if ((slavename = ptsname(fdm)) == NULL) + perror("ptyopen: Failed to get name of slave device"); + /* open slave */ + if ((fds = open(slavename, O_RDWR)) < 0 ) + perror("ptyopen: Failed to open slave"); + else { + /* push ptem */ + if (ioctl(fds, I_PUSH, "ptem") < 0) + perror("ptyopen: Failed to push ptem"); + /* push ldterm */ + if (ioctl(fds, I_PUSH, "ldterm") < 0) + perror("ptyopen: Failed to push idterm"); + strcpy(serverPath,slavename); + *controller=fdm; + *server=fds; + } + } + return(fdm); +#else +# error "don't know how to open a pty" +#endif +} + + diff --git a/src/lib/pixmap.c b/src/lib/pixmap.c index d0ad2097..da169dfb 100644 --- a/src/lib/pixmap.c +++ b/src/lib/pixmap.c @@ -33,7 +33,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "openaxiom-c-macros.h" #include #include diff --git a/src/lib/prt.c b/src/lib/prt.c deleted file mode 100644 index ee5b3af0..00000000 --- a/src/lib/prt.c +++ /dev/null @@ -1,407 +0,0 @@ -/* - 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. -*/ - -#include "openaxiom-c-macros.h" -#include -#include -#include -#include "edible.h" - -#include "prt.h" -#include "edin.h" - -void -myputchar(char c) -{ - if (ECHOIT) - putchar(c); - return; -} - -void -clear_buff(void) -{ - int count; - - /*** called when spadbuf gives me a line incase there is something already - on the line ****/ - if (buff_pntr > 0) { - /*** backup to the beginning of the line ***/ - for (count = curr_pntr; count > 0; count--) - myputchar(_BKSPC); - /** blank over the line ***/ - for (count = 0; count < buff_pntr; count++) { - myputchar(_BLANK); - } - /** back up again ***/ - for (count = buff_pntr; count > 0; count--) - myputchar(_BKSPC); - init_buff(buff, buff_pntr); - init_flag(buff_flag, buff_pntr); - curr_pntr = buff_pntr = 0; - } -} - - -void -move_end(void) -{ - - /** Moves cursor to the end of the line ***/ - if (curr_pntr == buff_pntr) { - putchar(_BELL); - } - else { - for (; curr_pntr < buff_pntr;) { - myputchar(buff[curr_pntr++]); - } - } - fflush(stdout); -} - -void -move_home(void) -{ - - /*** Moves the cursor to the front of the line ***/ - if (curr_pntr > 0) { - for (; curr_pntr > 0;) { - myputchar(_BKSPC); - curr_pntr--; - } - } - else { - putchar(_BELL); - } - fflush(stdout); - -} - -void -move_fore_word(void) -{ - /** move the cursor to the next blank space **/ - if (curr_pntr != buff_pntr) { - myputchar(buff[curr_pntr]); - curr_pntr++; - while (curr_pntr < buff_pntr && buff[curr_pntr] != ' ') { - myputchar(buff[curr_pntr]); - curr_pntr++; - } - } - else - putchar(_BELL); - fflush(stdout); - return; -} - -void -move_back_word(void) -{ - /*** moves the cursor to the last blank space ***/ - if (curr_pntr > 0) { - myputchar(_BKSPC); - curr_pntr--; - while (curr_pntr > 0 && buff[curr_pntr - 1] != ' ') { - myputchar(_BKSPC); - curr_pntr--; - } - - } - else - putchar(_BELL); - fflush(stdout); - return; -} - -void -delete_current_char(void) -{ - /** deletes the char currently above the current_pntr, if it can be **/ - if (curr_pntr != buff_pntr) { - if (buff_flag[curr_pntr] == 1 || buff_flag[curr_pntr] == 0) { - myputchar(_BLANK); - myputchar(_BKSPC); - strmov(&buff[curr_pntr], - &buff[curr_pntr + 1]); - flagcpy(&buff_flag[curr_pntr], - &buff_flag[curr_pntr + 1]); - buff_pntr--; - del_print(curr_pntr, 1); - } - else { - /** lets delete two of the little buggers **/ - myputchar(_BLANK); - myputchar(_BLANK); - myputchar(_BKSPC); - myputchar(_BKSPC); - strmov(&buff[curr_pntr], - &buff[curr_pntr + 2]); - flagcpy(&buff_flag[curr_pntr], - &buff_flag[curr_pntr + 2]); - buff_pntr -= 2; - del_print(curr_pntr, 2); - } - } - else { - putchar(_BELL); - fflush(stdout); - } - num_proc = num_proc + 3; -} - -void -delete_to_end_of_line(void) -{ - int count; - - /*** deletes from the curr_pntr to the end of line ***/ - - if (curr_pntr == buff_pntr) - return; /** There is nothing to do **/ - - /** blank over the end of the line ***/ - for (count = curr_pntr; count < buff_pntr; count++) { - myputchar(_BLANK); - } - /** back up again ***/ - for (count = buff_pntr; count > curr_pntr; count--) - myputchar(_BKSPC); - - buff_pntr = curr_pntr; - fflush(stdout); - return; - -} - -void -delete_line(void) -{ - int count; - - /*** deletes the entire line *****/ - - if (buff_pntr == 0) - return; /** There is nothing to do **/ - - /** first I have to back up to the beginning of the line ****/ - for (count = curr_pntr; count > 0; count--) - myputchar(_BKSPC); - - /** blank over the end of the line ***/ - for (count = 0; count < buff_pntr; count++) { - myputchar(_BLANK); - } - /** back up again ***/ - for (count = buff_pntr; count > 0; count--) - myputchar(_BKSPC); - - /* Also clear the buffer */ - init_buff(buff, buff_pntr); - init_flag(buff_flag, buff_pntr); - buff_pntr = curr_pntr = 0; - - fflush(stdout); - return; - -} - -void -printbuff(int start,int num) -{ - int trace; - - for (trace = start; trace < start + num; trace++) - if (buff[trace] != '\0') - myputchar(buff[trace]); - fflush(stdout); -} - -void -del_print(int start, int num) -{ - int count; - - /*** move the rest of the string ***/ - for (count = start; count < buff_pntr; count++) { - myputchar(buff[count]); - } - /** now blank out the number of chars we are supposed to ***/ - for (count = 0; count < num; count++) - myputchar(_BLANK); - /*** Now back up ***/ - for (count = buff_pntr + num; count > start; count--) - myputchar(_BKSPC); - fflush(stdout); -} - - -void -ins_print(int start,int num) -{ - int count; - - /** write the rest of the word ***/ - for (count = start; count < buff_pntr + num; count++) { - myputchar(buff[count]); - } - /** now back up to where we should be ***/ - for (count = buff_pntr; count > start; count--) - myputchar(_BKSPC); - fflush(stdout); -} - -void -reprint(int start) -{ - /** simply reprints a single character **/ - if (buff[start] == '\0') - myputchar(_BLANK); - else - myputchar(buff[start]); - myputchar(_BKSPC); - fflush(stdout); - return; -} - -void -back_up(int num_chars) -{ - int cnt; - - for (cnt = 0; cnt < num_chars; cnt++) - myputchar(_BKSPC); - for (cnt = 0; cnt < num_chars; cnt++) - myputchar(_BLANK); - for (cnt = 0; cnt < num_chars; cnt++) - myputchar(_BKSPC); - fflush(stdout); - -} - -void -back_it_up(int num_chars) -{ - int cnt; - - for (cnt = 0; cnt < num_chars; cnt++) - myputchar(_BKSPC); - fflush(stdout); -} - - -void -print_whole_buff(void) -{ - int trace; - - for (trace = 0; trace < buff_pntr; trace++) - if (buff[trace] != '\0') - myputchar(buff[trace]); - fflush(stdout); -} - -void -move_ahead(void) -{ - /*** simply moves the pointer ahead a single word ***/ - if (curr_pntr == buff_pntr) { - putchar(_BELL); - } - else { - if (buff_flag[curr_pntr] == 2) { - myputchar(buff[curr_pntr++]); - } - myputchar(buff[curr_pntr++]); - } - fflush(stdout); -} - -void -move_back(void) -{ - /** simply moves the cursor back one position **/ - if (curr_pntr == 0) { - putchar(_BELL); - } - else { - if (!buff_flag[curr_pntr - 1]) { - myputchar(_BKSPC); - curr_pntr--; - } - myputchar(_BKSPC); - curr_pntr--; - } - fflush(stdout); -} - -void -back_over_current_char(void) -{ - /*** simply backs over the character behind the cursor ***/ - if (curr_pntr == 0) { - putchar(_BELL); - } - else { - if (!buff_flag[curr_pntr - 1]) { - myputchar(_BKSPC); - myputchar(_BKSPC); - myputchar(_BLANK); - myputchar(_BLANK); - myputchar(_BKSPC); - myputchar(_BKSPC); - strmov(&buff[curr_pntr - 2], - &buff[curr_pntr]); - flagcpy(&buff_flag[curr_pntr - 2], - &buff_flag[curr_pntr]); - buff_pntr -= 2; - curr_pntr -= 2; - del_print(curr_pntr, 2); - } - else { - myputchar(_BKSPC); - myputchar(_BLANK); - myputchar(_BKSPC); - strmov(&buff[curr_pntr - 1], - &buff[curr_pntr]); - flagcpy(&buff_flag[curr_pntr - 1], - &buff_flag[curr_pntr]); - curr_pntr--; - buff_pntr--; - del_print(curr_pntr, 1); - } - } - fflush(stdout); - return; -} - diff --git a/src/lib/prt.cc b/src/lib/prt.cc new file mode 100644 index 00000000..831a199e --- /dev/null +++ b/src/lib/prt.cc @@ -0,0 +1,406 @@ +/* + 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. +*/ + +#include +#include +#include +#include "edible.h" + +#include "prt.h" +#include "edin.h" + +void +myputchar(char c) +{ + if (ECHOIT) + putchar(c); + return; +} + +void +clear_buff(void) +{ + int count; + + /*** called when spadbuf gives me a line incase there is something already + on the line ****/ + if (buff_pntr > 0) { + /*** backup to the beginning of the line ***/ + for (count = curr_pntr; count > 0; count--) + myputchar(_BKSPC); + /** blank over the line ***/ + for (count = 0; count < buff_pntr; count++) { + myputchar(_BLANK); + } + /** back up again ***/ + for (count = buff_pntr; count > 0; count--) + myputchar(_BKSPC); + init_buff(buff, buff_pntr); + init_flag(buff_flag, buff_pntr); + curr_pntr = buff_pntr = 0; + } +} + + +void +move_end(void) +{ + + /** Moves cursor to the end of the line ***/ + if (curr_pntr == buff_pntr) { + putchar(_BELL); + } + else { + for (; curr_pntr < buff_pntr;) { + myputchar(buff[curr_pntr++]); + } + } + fflush(stdout); +} + +void +move_home(void) +{ + + /*** Moves the cursor to the front of the line ***/ + if (curr_pntr > 0) { + for (; curr_pntr > 0;) { + myputchar(_BKSPC); + curr_pntr--; + } + } + else { + putchar(_BELL); + } + fflush(stdout); + +} + +void +move_fore_word(void) +{ + /** move the cursor to the next blank space **/ + if (curr_pntr != buff_pntr) { + myputchar(buff[curr_pntr]); + curr_pntr++; + while (curr_pntr < buff_pntr && buff[curr_pntr] != ' ') { + myputchar(buff[curr_pntr]); + curr_pntr++; + } + } + else + putchar(_BELL); + fflush(stdout); + return; +} + +void +move_back_word(void) +{ + /*** moves the cursor to the last blank space ***/ + if (curr_pntr > 0) { + myputchar(_BKSPC); + curr_pntr--; + while (curr_pntr > 0 && buff[curr_pntr - 1] != ' ') { + myputchar(_BKSPC); + curr_pntr--; + } + + } + else + putchar(_BELL); + fflush(stdout); + return; +} + +void +delete_current_char(void) +{ + /** deletes the char currently above the current_pntr, if it can be **/ + if (curr_pntr != buff_pntr) { + if (buff_flag[curr_pntr] == 1 || buff_flag[curr_pntr] == 0) { + myputchar(_BLANK); + myputchar(_BKSPC); + strmov(&buff[curr_pntr], + &buff[curr_pntr + 1]); + flagcpy(&buff_flag[curr_pntr], + &buff_flag[curr_pntr + 1]); + buff_pntr--; + del_print(curr_pntr, 1); + } + else { + /** lets delete two of the little buggers **/ + myputchar(_BLANK); + myputchar(_BLANK); + myputchar(_BKSPC); + myputchar(_BKSPC); + strmov(&buff[curr_pntr], + &buff[curr_pntr + 2]); + flagcpy(&buff_flag[curr_pntr], + &buff_flag[curr_pntr + 2]); + buff_pntr -= 2; + del_print(curr_pntr, 2); + } + } + else { + putchar(_BELL); + fflush(stdout); + } + num_proc = num_proc + 3; +} + +void +delete_to_end_of_line(void) +{ + int count; + + /*** deletes from the curr_pntr to the end of line ***/ + + if (curr_pntr == buff_pntr) + return; /** There is nothing to do **/ + + /** blank over the end of the line ***/ + for (count = curr_pntr; count < buff_pntr; count++) { + myputchar(_BLANK); + } + /** back up again ***/ + for (count = buff_pntr; count > curr_pntr; count--) + myputchar(_BKSPC); + + buff_pntr = curr_pntr; + fflush(stdout); + return; + +} + +void +delete_line(void) +{ + int count; + + /*** deletes the entire line *****/ + + if (buff_pntr == 0) + return; /** There is nothing to do **/ + + /** first I have to back up to the beginning of the line ****/ + for (count = curr_pntr; count > 0; count--) + myputchar(_BKSPC); + + /** blank over the end of the line ***/ + for (count = 0; count < buff_pntr; count++) { + myputchar(_BLANK); + } + /** back up again ***/ + for (count = buff_pntr; count > 0; count--) + myputchar(_BKSPC); + + /* Also clear the buffer */ + init_buff(buff, buff_pntr); + init_flag(buff_flag, buff_pntr); + buff_pntr = curr_pntr = 0; + + fflush(stdout); + return; + +} + +void +printbuff(int start,int num) +{ + int trace; + + for (trace = start; trace < start + num; trace++) + if (buff[trace] != '\0') + myputchar(buff[trace]); + fflush(stdout); +} + +void +del_print(int start, int num) +{ + int count; + + /*** move the rest of the string ***/ + for (count = start; count < buff_pntr; count++) { + myputchar(buff[count]); + } + /** now blank out the number of chars we are supposed to ***/ + for (count = 0; count < num; count++) + myputchar(_BLANK); + /*** Now back up ***/ + for (count = buff_pntr + num; count > start; count--) + myputchar(_BKSPC); + fflush(stdout); +} + + +void +ins_print(int start,int num) +{ + int count; + + /** write the rest of the word ***/ + for (count = start; count < buff_pntr + num; count++) { + myputchar(buff[count]); + } + /** now back up to where we should be ***/ + for (count = buff_pntr; count > start; count--) + myputchar(_BKSPC); + fflush(stdout); +} + +void +reprint(int start) +{ + /** simply reprints a single character **/ + if (buff[start] == '\0') + myputchar(_BLANK); + else + myputchar(buff[start]); + myputchar(_BKSPC); + fflush(stdout); + return; +} + +void +back_up(int num_chars) +{ + int cnt; + + for (cnt = 0; cnt < num_chars; cnt++) + myputchar(_BKSPC); + for (cnt = 0; cnt < num_chars; cnt++) + myputchar(_BLANK); + for (cnt = 0; cnt < num_chars; cnt++) + myputchar(_BKSPC); + fflush(stdout); + +} + +void +back_it_up(int num_chars) +{ + int cnt; + + for (cnt = 0; cnt < num_chars; cnt++) + myputchar(_BKSPC); + fflush(stdout); +} + + +void +print_whole_buff(void) +{ + int trace; + + for (trace = 0; trace < buff_pntr; trace++) + if (buff[trace] != '\0') + myputchar(buff[trace]); + fflush(stdout); +} + +void +move_ahead(void) +{ + /*** simply moves the pointer ahead a single word ***/ + if (curr_pntr == buff_pntr) { + putchar(_BELL); + } + else { + if (buff_flag[curr_pntr] == 2) { + myputchar(buff[curr_pntr++]); + } + myputchar(buff[curr_pntr++]); + } + fflush(stdout); +} + +void +move_back(void) +{ + /** simply moves the cursor back one position **/ + if (curr_pntr == 0) { + putchar(_BELL); + } + else { + if (!buff_flag[curr_pntr - 1]) { + myputchar(_BKSPC); + curr_pntr--; + } + myputchar(_BKSPC); + curr_pntr--; + } + fflush(stdout); +} + +void +back_over_current_char(void) +{ + /*** simply backs over the character behind the cursor ***/ + if (curr_pntr == 0) { + putchar(_BELL); + } + else { + if (!buff_flag[curr_pntr - 1]) { + myputchar(_BKSPC); + myputchar(_BKSPC); + myputchar(_BLANK); + myputchar(_BLANK); + myputchar(_BKSPC); + myputchar(_BKSPC); + strmov(&buff[curr_pntr - 2], + &buff[curr_pntr]); + flagcpy(&buff_flag[curr_pntr - 2], + &buff_flag[curr_pntr]); + buff_pntr -= 2; + curr_pntr -= 2; + del_print(curr_pntr, 2); + } + else { + myputchar(_BKSPC); + myputchar(_BLANK); + myputchar(_BKSPC); + strmov(&buff[curr_pntr - 1], + &buff[curr_pntr]); + flagcpy(&buff_flag[curr_pntr - 1], + &buff_flag[curr_pntr]); + curr_pntr--; + buff_pntr--; + del_print(curr_pntr, 1); + } + } + fflush(stdout); + return; +} + diff --git a/src/lib/sockio-c.cxx b/src/lib/sockio-c.cxx index dda95ec3..c17c3398 100644 --- a/src/lib/sockio-c.cxx +++ b/src/lib/sockio-c.cxx @@ -70,9 +70,9 @@ namespace OpenAxiom { /* Note that the name AF_LOCAL is more portable than AF_UNIX, but MingW implementation and Windows documentation don't always agree. */ -#if HAVE_AF_LOCAL +#if HAVE_DECL_AF_LOCAL # define OPENAXIOM_AF_LOCAL AF_LOCAL -#elif HAVE_AF_UNIX +#elif HAVE_DECL_AF_UNIX # define OPENAXIOM_AF_LOCAL AF_UNIX #else # error "needs one of AF_LOCAL or AF_UNIX" diff --git a/src/lib/spadcolors.c b/src/lib/spadcolors.c index b8d784f2..8007b450 100644 --- a/src/lib/spadcolors.c +++ b/src/lib/spadcolors.c @@ -33,7 +33,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "openaxiom-c-macros.h" #include "spadcolors.h" #include diff --git a/src/lib/util.c b/src/lib/util.c index 198cd3bf..264590ea 100644 --- a/src/lib/util.c +++ b/src/lib/util.c @@ -33,7 +33,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "openaxiom-c-macros.h" #include #include #include diff --git a/src/lib/wct.c b/src/lib/wct.c deleted file mode 100644 index 44510558..00000000 --- a/src/lib/wct.c +++ /dev/null @@ -1,732 +0,0 @@ -/* - Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. - All rights reserved. - Copyright (C) 2007-2011 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. -*/ -/* - * Word completion. - * - * - * Word completion is driven from a list of completion tables. Each table - * contains a list of words. - * - */ - -#include "openaxiom-c-macros.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* #define PINFO *//* A flag to suppress printing of the file info */ - -#define WCT /* A flag needed because ctype.h stole some - * of my constants */ -#include "edible.h" - -#define MAX_PREFIX 1024 -#define strneql(a,b,n) (*(a) == *(b) && !strncmp((a),(b),(n))) -#define Delimiter(c) (! isalnum(c) && c != '%' && c != '!' && c != '?' && c != '_') - - -#include "wct.h" -#include "prt.h" -#include "edin.h" - - - -static Wct *pwct = 0; -static Wix *pwix; -static Wix curr_wix; -static char curr_prefix[MAX_PREFIX]; -static Wct *pHeadwct; - -time_t -ftime(char *path) -{ - int rc; - struct stat stbuf; - - rc = stat(path, &stbuf); - if (rc == -1) - fatal("Cannot deterimine status of %s.", path); - - return stbuf.st_mtime; -} - -off_t -fsize(char *path) -{ - int rc; - struct stat stbuf; - - rc = stat(path, &stbuf); - if (rc == -1) - fatal("Cannot deterimine status of %s.", path); - - return stbuf.st_size; -} - - -/* - * Scan a word completion table for a particular word. - */ - - -Wix * -scanWct(Wct *pwct, char *prefix) -{ - long fmod; - int preflen, i, wc; - char **wv; - - preflen = strlen(prefix); - strncpy(curr_prefix, prefix, MAX_PREFIX); - - pHeadwct = pwct; - curr_wix.pwct = 0; - curr_wix.word = 0; - - for (; pwct; pwct = pwct->next) { - curr_wix.pwct = pwct; - - - - fmod = ftime(pwct->fname); - if (fmod > pwct->ftime) - reintern1Wct(pwct); - - wv = pwct->wordv; - wc = pwct->wordc; - for (i = 0; i < wc; i++) { - curr_wix.word = i; - if (strneql(wv[i], prefix, preflen)) - return &curr_wix; - } - } - return 0; -} - -Wix * -rescanWct(void) -{ - Wct *pwct, *start_pwct; - int preflen, start_word, i, wc; - char **wv, *prefix; - - start_pwct = curr_wix.pwct; - start_word = curr_wix.word; - - if (!start_pwct) return(0); - prefix = curr_prefix; - preflen = strlen(prefix); - - /* - * Finish the current structure. - */ - - pwct = start_pwct; - - curr_wix.pwct = pwct; - wv = pwct->wordv; - wc = pwct->wordc; - for (i = start_word + 1; i < wc; i++) { - curr_wix.word = i; - if (strneql(wv[i], prefix, preflen)) - return &curr_wix; - } - - /* - * Finish to the end of the list, doing whole structures. - */ - for (pwct = pwct->next; pwct; pwct = pwct->next) { - curr_wix.pwct = pwct; - - wv = pwct->wordv; - wc = pwct->wordc; - for (i = 0; i < wc; i++) { - curr_wix.word = i; - if (strneql(wv[i], prefix, preflen)) - return &curr_wix; - } - } - - /* - * Restart at beginning, doing whole structures. - */ - for (pwct = pHeadwct; pwct != start_pwct; pwct = pwct->next) { - curr_wix.pwct = pwct; - - wv = pwct->wordv; - wc = pwct->wordc; - for (i = 0; i < wc; i++) { - curr_wix.word = i; - if (strneql(wv[i], prefix, preflen)) - return &curr_wix; - } - } - - /* - * Do beginning half of the start structure. - */ - curr_wix.pwct = pwct; - wv = pwct->wordv; - wc = pwct->wordc; - for (i = 0; i <= start_word; i++) { - curr_wix.word = i; - if (strneql(wv[i], prefix, preflen)) - return &curr_wix; - } - - /* Not found? */ - return 0; -} - -/* - * Summarize a table. - */ -void -skimWct(Wct *pwct) -{ - while (pwct) { -#ifdef PINFO - skim1Wct(pwct); -#endif - pwct = pwct->next; - } -} - -void -skim1Wct(Wct *pwct) -{ -#define NHEAD 13 -#define NTAIL 7 - - int cc; - - printf("%-10s", pwct->fname); - printTime((long *)&(pwct->ftime)); - cc = skimString(pwct->fimage, pwct->fsize, NHEAD, NTAIL); - printf("%s", " " + (cc - (NHEAD + NTAIL))); - printf(" [%d w, %ld c]", pwct->wordc, (long)(pwct->fsize)); - printf("\n"); - -#ifdef SHOW_WORDS - { - int i; - char **wv; - - for (i = 1, wv = pwct->wordv; *wv; i++, wv++) { - printf("%5d: %s\n", i, *wv); - } - } -#endif -} - -void -printTime(long *clock) -{ - struct tm *tm; - - tm = localtime((time_t *)clock); - printf("%.2d/%.2d/%.2d %.2d:%.2d:%.2d ", - tm->tm_year, tm->tm_mon + 1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec); -} - -int -skimString(char *s, int slen,int nhead,int ntail) -{ - int spos, tlen, i, cc; - - cc = printf("\""); - for (spos = 0; spos < slen && cc <= nhead; spos++) - cc += prChar(s[spos]); - - /* Assume same tail has the same multi-character format ratio. */ - tlen = ntail * ((1.0 * spos) / nhead); - - if (spos + tlen >= slen) - for (; spos < slen; spos++) - cc += prChar(s[spos]); - else { - cc += printf("\"...\""); - for (i = slen - tlen; i < slen; i++) - cc += prChar(s[i]); - } - cc += printf("\""); - return cc; -} - -int -prChar(int c) -{ - if (c == '\n') - return printf("\\n"); - if (c == '\t') - return printf("\\t"); - if (c == '\b') - return printf("\\b"); - if (c == '"') - return printf("\\\""); - if (iscntrl(c)) - return printf("^%c", (c + 0100) % 0200); - if (isascii(c)) - return printf("%c", c); - - return printf("\\%d", c); -} - -Wct * -reread1Wct(Wct *pwct) -{ - int fd, rc; - - /* Check information about the file. */ - pwct->fsize = fsize(pwct->fname); - pwct->ftime = ftime(pwct->fname); - - /* Allocate space for file image */ - if (pwct->fimage) - free(pwct->fimage); - pwct->fimage = (char *) malloc(pwct->fsize + 1); - if (pwct->fimage == 0) - sfatal("Cannot allocate new table."); - pwct->fimage[pwct->fsize] = 0; - - /* Read file into buffer. */ - fd = open(pwct->fname, O_RDONLY); - if (fd == -1) - fatal("Cannot read file %s.", pwct->fname); - rc = read(fd, pwct->fimage, pwct->fsize); - if (rc != pwct->fsize) - fatal("Did not read all of file %s.", pwct->fname); - - return pwct; -} - -Wct * -read1Wct(char *fname) -{ - Wct *pwct; - - /* Allocate a new link for this file. */ - pwct = (Wct *) malloc(sizeof(Wct)); - if (pwct == 0) - sfatal("Cannot allocate new table."); - - pwct->fname = fname; - pwct->wordc = 0; - pwct->wordv = 0; - pwct->fimage = 0; - pwct->next = 0; - - return reread1Wct(pwct); -} - -Wct * -nconcWct(Wct *pwct,Wct * qwct) -{ - Wct *p0 = pwct; - - if (!p0) - return qwct; - - while (pwct->next) - pwct = pwct->next; - pwct->next = qwct; - - return p0; -} - -void -sortWct(Wct *pwct) -{ - while (pwct) { - sort1Wct(pwct); - pwct = pwct->next; - } -} - -void -sort1Wct(Wct *pwct) -{ - qsort((char *) pwct->wordv, pwct->wordc, - sizeof(*(pwct->wordv)), mystrcmp); -} - -int -mystrcmp(const void *s1,const void * s2) -{ - return strcmp(*(char **)s1, *(char **)s2); -} - -/* - * Break wct struct into words. - */ - -void -burstWct(Wct *pwct) -{ - while (pwct) { - burst1Wct(pwct); - pwct = pwct->next; - } -} - -void -burst1Wct(Wct *pwct) -{ - char *s, **wv; - int i, j, inword = 0; - - - for (s = pwct->fimage, i = 0; i < pwct->fsize; s++, i++) { - if (isspace(*s) || iscntrl(*s)) { - *s = 0; - inword = 0; - } - else if (!inword) { - inword = 1; - pwct->wordc++; - } - } - - if (pwct->wordv) - free(pwct->wordv); - pwct->wordv = (char **) calloc(pwct->wordc + 1, sizeof(char *)); - if (!pwct->wordv) - fatal("Could not make word list for %s.", pwct->fname); - - s = pwct->fimage; - i = 0; - for (wv = pwct->wordv, j = 0; j < pwct->wordc; wv++, j++) { - while (i < pwct->fsize && !s[i]) - i++; - *wv = s + i; - while (i < pwct->fsize && s[i]) - i++; - } - *wv = 0; -} - -Wct * -intern1Wct(char *fname) -{ - Wct *pwct; - - pwct = read1Wct(fname); - burst1Wct(pwct); - return pwct; -} - -void -reintern1Wct(Wct *pwct) -{ - reread1Wct(pwct); - burst1Wct(pwct); -} - -void -sfatal(const char *s) -{ - fatal("%s", s); -} - -void -fatal(const char* fmt, const char* s) -{ - static char fbuf[256]; - - sprintf(fbuf, fmt, s); - - perror(fbuf); - exit(1); -} - - - -/* load up the wct database */ -void -load_wct_file(char *fname) -{ - pwct = nconcWct(intern1Wct(fname), pwct); -} - -void -skim_wct(void) -{ - skimWct(pwct); -} - -/* - * This routine is called when a tab is hit. It simply takes the current - * buffer and tries to find a completion of the last word on the line in the - * data base. - */ - - -void -rescan_wct(void) -{ - int b = curr_pntr - 1; - int old_len; - int new_len; - int diff; - int i; - int ncs = 0; - - /* - * first thing I should do is find my way back to the beginning of the - * word - */ - while (b && !Delimiter(buff[b])) - b--; - if (Delimiter(buff[b])) - b++; - - old_len = curr_pntr - b; - - pwix = rescanWct(); - - if (!pwix) { - putchar(_BELL); - fflush(stdout); - } - else { - Wct *pwct = pwix->pwct; /* start replacing it */ - - new_len = strlen(pwct->wordv[pwix->word]); - if (new_len > old_len) { - - /* - * I have to just slide the characters forward a bit, stuff in - * the new characters, and then adjust curr_pntr - */ - diff = new_len - old_len; - if (curr_pntr != buff_pntr) { - forwardcopy(&buff[curr_pntr + diff], - &buff[curr_pntr], - buff_pntr - curr_pntr); - forwardflag_cpy(&buff_flag[curr_pntr + diff], - &buff_flag[curr_pntr], - buff_pntr - curr_pntr); - } - buff_pntr += diff; - ncs = curr_pntr + diff; - - /* Now insert the new word */ - for (i = 0; i < new_len; i++) - buff[b + i] = (pwct->wordv[pwix->word])[i]; - - /* move cursor to the beginning of the word */ - for (; curr_pntr != b; curr_pntr--) - putchar(_BKSPC); - - /** now print the characters on the rest of the line **/ - printbuff(curr_pntr, buff_pntr - curr_pntr); - - /* now move bcak the number of characters I want to */ - for (i = buff_pntr; i != ncs; i--) - putchar(_BKSPC); - - fflush(stdout); - - curr_pntr = ncs; - } - else if (new_len < old_len) { - /* this time I simply copy backwards and do the substituting */ - diff = old_len - new_len; - strnmov(&buff[curr_pntr - diff], - &buff[curr_pntr], - buff_pntr - curr_pntr); - flagncpy(&buff_flag[curr_pntr - diff], - &buff_flag[curr_pntr], - buff_pntr - curr_pntr); - buff_pntr -= diff; - ncs = curr_pntr - diff; - - /* Now insert the new word */ - for (i = 0; i < new_len; i++) - buff[b + i] = (pwct->wordv[pwix->word])[i]; - - /* move cursor to the beginning of the word */ - for (; curr_pntr != b; curr_pntr--) - putchar(_BKSPC); - - /** now print the characters on the rest of the line **/ - printbuff(b, buff_pntr - b); - - /* now blank out the characters out on the end of this line */ - for (i = 0; i < diff; i++) - myputchar(' '); - - /* now move back the number of characters I want to */ - for (i = buff_pntr + diff; i != ncs; i--) - putchar(_BKSPC); - - fflush(stdout); - - curr_pntr = ncs; - } - else { - diff = 0; - ncs = curr_pntr; - /* Now insert the new word */ - for (i = 0; i < new_len; i++) - buff[b + i] = (pwct->wordv[pwix->word])[i]; - - /* move cursor to the beginning of the word */ - for (; curr_pntr != b; curr_pntr--) - putchar(_BKSPC); - - /** now print the characters on the rest of the line **/ - printbuff(curr_pntr, buff_pntr - curr_pntr); - - /* now move back the number of characters I want to */ - for (i = buff_pntr; i != ncs; i--) - putchar(_BKSPC); - - fflush(stdout); - - curr_pntr = ncs; - } - } -} - -void -find_wct(void) -{ - - char search_buff[100]; - char *filler = search_buff; - int b = curr_pntr - 1; - int e = curr_pntr; - int ne = 0; - int st; - Wix *pwix; - int curr_len; - int new_len; - int diff; - int i; - - /* - * First thing I do is try and construct the string to be searched for. - * Basically I just start from the curr_pntr and search backward until I - * find a blank. Once I find a blank I copy forward until I get back to - * curr_pntr; - */ - if (!curr_pntr) { - putchar(_BELL); - return; - } - /* then get back to the first blank or back to the beginning */ - while (b && !Delimiter(buff[b])) - b--; - if (Delimiter(buff[b])) - b++; - - /* At the same time, let me find the end of the word */ - while (e < buff_pntr && !Delimiter(buff[e])) { - e++; - ne++; - } - - st = b; - curr_len = e - b; - - /* now simply copy the text forward */ - while (b < curr_pntr) - *filler++ = buff[b++]; - - *filler = '\0'; - - pwix = scanWct(pwct, search_buff); - - /* - * else pwix = rescanWct(); - */ - - if (!pwix) { - putchar(_BELL); - fflush(stdout); - } - else { - Wct *pwct = pwix->pwct; - - /* - * printf("Found %s in file %s\n", pwct->wordv[pwix->word], - * pwct->fname); - */ - /* copy them buffer into where it should be */ - new_len = strlen(pwct->wordv[pwix->word]); - diff = new_len - curr_len; - if (curr_pntr != buff_pntr) { - forwardcopy(&buff[curr_pntr + diff], - &buff[curr_pntr], - buff_pntr - curr_pntr); - forwardflag_cpy(&buff_flag[curr_pntr + diff], - &buff_flag[curr_pntr], - buff_pntr - curr_pntr); - } - buff_pntr += diff; - - - /* Now insert the new characters */ - for (i = new_len - diff; i < new_len; i++) - buff[st + i] = (pwct->wordv[pwix->word])[i]; - - /* Now move the cursor forward to the end of the word */ - for (i = 0; i < diff; i++) - putchar(buff[curr_pntr++]); - - /** now print the characters on the rest of the line **/ - printbuff(curr_pntr, buff_pntr - curr_pntr); - - /* now move bcak the number of characters I want to */ - for (i = buff_pntr; i != e + diff; i--) - putchar(_BKSPC); - - fflush(stdout); - - curr_pntr = diff + e; - - } - - -} diff --git a/src/lib/wct.cc b/src/lib/wct.cc new file mode 100644 index 00000000..bac8c894 --- /dev/null +++ b/src/lib/wct.cc @@ -0,0 +1,731 @@ +/* + Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2011 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. +*/ +/* + * Word completion. + * + * + * Word completion is driven from a list of completion tables. Each table + * contains a list of words. + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* #define PINFO *//* A flag to suppress printing of the file info */ + +#define WCT /* A flag needed because ctype.h stole some + * of my constants */ +#include "edible.h" + +#define MAX_PREFIX 1024 +#define strneql(a,b,n) (*(a) == *(b) && !strncmp((a),(b),(n))) +#define Delimiter(c) (! isalnum(c) && c != '%' && c != '!' && c != '?' && c != '_') + + +#include "wct.h" +#include "prt.h" +#include "edin.h" + + + +static Wct *pwct = 0; +static Wix *pwix; +static Wix curr_wix; +static char curr_prefix[MAX_PREFIX]; +static Wct *pHeadwct; + +time_t +ftime(char *path) +{ + int rc; + struct stat stbuf; + + rc = stat(path, &stbuf); + if (rc == -1) + fatal("Cannot deterimine status of %s.", path); + + return stbuf.st_mtime; +} + +off_t +fsize(char *path) +{ + int rc; + struct stat stbuf; + + rc = stat(path, &stbuf); + if (rc == -1) + fatal("Cannot deterimine status of %s.", path); + + return stbuf.st_size; +} + + +/* + * Scan a word completion table for a particular word. + */ + + +Wix * +scanWct(Wct *pwct, char *prefix) +{ + long fmod; + int preflen, i, wc; + char **wv; + + preflen = strlen(prefix); + strncpy(curr_prefix, prefix, MAX_PREFIX); + + pHeadwct = pwct; + curr_wix.pwct = 0; + curr_wix.word = 0; + + for (; pwct; pwct = pwct->next) { + curr_wix.pwct = pwct; + + + + fmod = ftime(pwct->fname); + if (fmod > pwct->ftime) + reintern1Wct(pwct); + + wv = pwct->wordv; + wc = pwct->wordc; + for (i = 0; i < wc; i++) { + curr_wix.word = i; + if (strneql(wv[i], prefix, preflen)) + return &curr_wix; + } + } + return 0; +} + +Wix * +rescanWct(void) +{ + Wct *pwct, *start_pwct; + int preflen, start_word, i, wc; + char **wv, *prefix; + + start_pwct = curr_wix.pwct; + start_word = curr_wix.word; + + if (!start_pwct) return(0); + prefix = curr_prefix; + preflen = strlen(prefix); + + /* + * Finish the current structure. + */ + + pwct = start_pwct; + + curr_wix.pwct = pwct; + wv = pwct->wordv; + wc = pwct->wordc; + for (i = start_word + 1; i < wc; i++) { + curr_wix.word = i; + if (strneql(wv[i], prefix, preflen)) + return &curr_wix; + } + + /* + * Finish to the end of the list, doing whole structures. + */ + for (pwct = pwct->next; pwct; pwct = pwct->next) { + curr_wix.pwct = pwct; + + wv = pwct->wordv; + wc = pwct->wordc; + for (i = 0; i < wc; i++) { + curr_wix.word = i; + if (strneql(wv[i], prefix, preflen)) + return &curr_wix; + } + } + + /* + * Restart at beginning, doing whole structures. + */ + for (pwct = pHeadwct; pwct != start_pwct; pwct = pwct->next) { + curr_wix.pwct = pwct; + + wv = pwct->wordv; + wc = pwct->wordc; + for (i = 0; i < wc; i++) { + curr_wix.word = i; + if (strneql(wv[i], prefix, preflen)) + return &curr_wix; + } + } + + /* + * Do beginning half of the start structure. + */ + curr_wix.pwct = pwct; + wv = pwct->wordv; + wc = pwct->wordc; + for (i = 0; i <= start_word; i++) { + curr_wix.word = i; + if (strneql(wv[i], prefix, preflen)) + return &curr_wix; + } + + /* Not found? */ + return 0; +} + +/* + * Summarize a table. + */ +void +skimWct(Wct *pwct) +{ + while (pwct) { +#ifdef PINFO + skim1Wct(pwct); +#endif + pwct = pwct->next; + } +} + +void +skim1Wct(Wct *pwct) +{ +#define NHEAD 13 +#define NTAIL 7 + + int cc; + + printf("%-10s", pwct->fname); + printTime((long *)&(pwct->ftime)); + cc = skimString(pwct->fimage, pwct->fsize, NHEAD, NTAIL); + printf("%s", " " + (cc - (NHEAD + NTAIL))); + printf(" [%d w, %ld c]", pwct->wordc, (long)(pwct->fsize)); + printf("\n"); + +#ifdef SHOW_WORDS + { + int i; + char **wv; + + for (i = 1, wv = pwct->wordv; *wv; i++, wv++) { + printf("%5d: %s\n", i, *wv); + } + } +#endif +} + +void +printTime(long *clock) +{ + struct tm *tm; + + tm = localtime((time_t *)clock); + printf("%.2d/%.2d/%.2d %.2d:%.2d:%.2d ", + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec); +} + +int +skimString(char *s, int slen,int nhead,int ntail) +{ + int spos, tlen, i, cc; + + cc = printf("\""); + for (spos = 0; spos < slen && cc <= nhead; spos++) + cc += prChar(s[spos]); + + /* Assume same tail has the same multi-character format ratio. */ + tlen = ntail * ((1.0 * spos) / nhead); + + if (spos + tlen >= slen) + for (; spos < slen; spos++) + cc += prChar(s[spos]); + else { + cc += printf("\"...\""); + for (i = slen - tlen; i < slen; i++) + cc += prChar(s[i]); + } + cc += printf("\""); + return cc; +} + +int +prChar(int c) +{ + if (c == '\n') + return printf("\\n"); + if (c == '\t') + return printf("\\t"); + if (c == '\b') + return printf("\\b"); + if (c == '"') + return printf("\\\""); + if (iscntrl(c)) + return printf("^%c", (c + 0100) % 0200); + if (isascii(c)) + return printf("%c", c); + + return printf("\\%d", c); +} + +Wct * +reread1Wct(Wct *pwct) +{ + int fd, rc; + + /* Check information about the file. */ + pwct->fsize = fsize(pwct->fname); + pwct->ftime = ftime(pwct->fname); + + /* Allocate space for file image */ + if (pwct->fimage) + free(pwct->fimage); + pwct->fimage = (char *) malloc(pwct->fsize + 1); + if (pwct->fimage == 0) + sfatal("Cannot allocate new table."); + pwct->fimage[pwct->fsize] = 0; + + /* Read file into buffer. */ + fd = open(pwct->fname, O_RDONLY); + if (fd == -1) + fatal("Cannot read file %s.", pwct->fname); + rc = read(fd, pwct->fimage, pwct->fsize); + if (rc != pwct->fsize) + fatal("Did not read all of file %s.", pwct->fname); + + return pwct; +} + +Wct * +read1Wct(char *fname) +{ + Wct *pwct; + + /* Allocate a new link for this file. */ + pwct = (Wct *) malloc(sizeof(Wct)); + if (pwct == 0) + sfatal("Cannot allocate new table."); + + pwct->fname = fname; + pwct->wordc = 0; + pwct->wordv = 0; + pwct->fimage = 0; + pwct->next = 0; + + return reread1Wct(pwct); +} + +Wct * +nconcWct(Wct *pwct,Wct * qwct) +{ + Wct *p0 = pwct; + + if (!p0) + return qwct; + + while (pwct->next) + pwct = pwct->next; + pwct->next = qwct; + + return p0; +} + +void +sortWct(Wct *pwct) +{ + while (pwct) { + sort1Wct(pwct); + pwct = pwct->next; + } +} + +void +sort1Wct(Wct *pwct) +{ + qsort((char *) pwct->wordv, pwct->wordc, + sizeof(*(pwct->wordv)), mystrcmp); +} + +int +mystrcmp(const void *s1,const void * s2) +{ + return strcmp(*(char **)s1, *(char **)s2); +} + +/* + * Break wct struct into words. + */ + +void +burstWct(Wct *pwct) +{ + while (pwct) { + burst1Wct(pwct); + pwct = pwct->next; + } +} + +void +burst1Wct(Wct *pwct) +{ + char *s, **wv; + int i, j, inword = 0; + + + for (s = pwct->fimage, i = 0; i < pwct->fsize; s++, i++) { + if (isspace(*s) || iscntrl(*s)) { + *s = 0; + inword = 0; + } + else if (!inword) { + inword = 1; + pwct->wordc++; + } + } + + if (pwct->wordv) + free(pwct->wordv); + pwct->wordv = (char **) calloc(pwct->wordc + 1, sizeof(char *)); + if (!pwct->wordv) + fatal("Could not make word list for %s.", pwct->fname); + + s = pwct->fimage; + i = 0; + for (wv = pwct->wordv, j = 0; j < pwct->wordc; wv++, j++) { + while (i < pwct->fsize && !s[i]) + i++; + *wv = s + i; + while (i < pwct->fsize && s[i]) + i++; + } + *wv = 0; +} + +Wct * +intern1Wct(char *fname) +{ + Wct *pwct; + + pwct = read1Wct(fname); + burst1Wct(pwct); + return pwct; +} + +void +reintern1Wct(Wct *pwct) +{ + reread1Wct(pwct); + burst1Wct(pwct); +} + +void +sfatal(const char *s) +{ + fatal("%s", s); +} + +void +fatal(const char* fmt, const char* s) +{ + static char fbuf[256]; + + sprintf(fbuf, fmt, s); + + perror(fbuf); + exit(1); +} + + + +/* load up the wct database */ +void +load_wct_file(char *fname) +{ + pwct = nconcWct(intern1Wct(fname), pwct); +} + +void +skim_wct(void) +{ + skimWct(pwct); +} + +/* + * This routine is called when a tab is hit. It simply takes the current + * buffer and tries to find a completion of the last word on the line in the + * data base. + */ + + +void +rescan_wct(void) +{ + int b = curr_pntr - 1; + int old_len; + int new_len; + int diff; + int i; + int ncs = 0; + + /* + * first thing I should do is find my way back to the beginning of the + * word + */ + while (b && !Delimiter(buff[b])) + b--; + if (Delimiter(buff[b])) + b++; + + old_len = curr_pntr - b; + + pwix = rescanWct(); + + if (!pwix) { + putchar(_BELL); + fflush(stdout); + } + else { + Wct *pwct = pwix->pwct; /* start replacing it */ + + new_len = strlen(pwct->wordv[pwix->word]); + if (new_len > old_len) { + + /* + * I have to just slide the characters forward a bit, stuff in + * the new characters, and then adjust curr_pntr + */ + diff = new_len - old_len; + if (curr_pntr != buff_pntr) { + forwardcopy(&buff[curr_pntr + diff], + &buff[curr_pntr], + buff_pntr - curr_pntr); + forwardflag_cpy(&buff_flag[curr_pntr + diff], + &buff_flag[curr_pntr], + buff_pntr - curr_pntr); + } + buff_pntr += diff; + ncs = curr_pntr + diff; + + /* Now insert the new word */ + for (i = 0; i < new_len; i++) + buff[b + i] = (pwct->wordv[pwix->word])[i]; + + /* move cursor to the beginning of the word */ + for (; curr_pntr != b; curr_pntr--) + putchar(_BKSPC); + + /** now print the characters on the rest of the line **/ + printbuff(curr_pntr, buff_pntr - curr_pntr); + + /* now move bcak the number of characters I want to */ + for (i = buff_pntr; i != ncs; i--) + putchar(_BKSPC); + + fflush(stdout); + + curr_pntr = ncs; + } + else if (new_len < old_len) { + /* this time I simply copy backwards and do the substituting */ + diff = old_len - new_len; + strnmov(&buff[curr_pntr - diff], + &buff[curr_pntr], + buff_pntr - curr_pntr); + flagncpy(&buff_flag[curr_pntr - diff], + &buff_flag[curr_pntr], + buff_pntr - curr_pntr); + buff_pntr -= diff; + ncs = curr_pntr - diff; + + /* Now insert the new word */ + for (i = 0; i < new_len; i++) + buff[b + i] = (pwct->wordv[pwix->word])[i]; + + /* move cursor to the beginning of the word */ + for (; curr_pntr != b; curr_pntr--) + putchar(_BKSPC); + + /** now print the characters on the rest of the line **/ + printbuff(b, buff_pntr - b); + + /* now blank out the characters out on the end of this line */ + for (i = 0; i < diff; i++) + myputchar(' '); + + /* now move back the number of characters I want to */ + for (i = buff_pntr + diff; i != ncs; i--) + putchar(_BKSPC); + + fflush(stdout); + + curr_pntr = ncs; + } + else { + diff = 0; + ncs = curr_pntr; + /* Now insert the new word */ + for (i = 0; i < new_len; i++) + buff[b + i] = (pwct->wordv[pwix->word])[i]; + + /* move cursor to the beginning of the word */ + for (; curr_pntr != b; curr_pntr--) + putchar(_BKSPC); + + /** now print the characters on the rest of the line **/ + printbuff(curr_pntr, buff_pntr - curr_pntr); + + /* now move back the number of characters I want to */ + for (i = buff_pntr; i != ncs; i--) + putchar(_BKSPC); + + fflush(stdout); + + curr_pntr = ncs; + } + } +} + +void +find_wct(void) +{ + + char search_buff[100]; + char *filler = search_buff; + int b = curr_pntr - 1; + int e = curr_pntr; + int ne = 0; + int st; + Wix *pwix; + int curr_len; + int new_len; + int diff; + int i; + + /* + * First thing I do is try and construct the string to be searched for. + * Basically I just start from the curr_pntr and search backward until I + * find a blank. Once I find a blank I copy forward until I get back to + * curr_pntr; + */ + if (!curr_pntr) { + putchar(_BELL); + return; + } + /* then get back to the first blank or back to the beginning */ + while (b && !Delimiter(buff[b])) + b--; + if (Delimiter(buff[b])) + b++; + + /* At the same time, let me find the end of the word */ + while (e < buff_pntr && !Delimiter(buff[e])) { + e++; + ne++; + } + + st = b; + curr_len = e - b; + + /* now simply copy the text forward */ + while (b < curr_pntr) + *filler++ = buff[b++]; + + *filler = '\0'; + + pwix = scanWct(pwct, search_buff); + + /* + * else pwix = rescanWct(); + */ + + if (!pwix) { + putchar(_BELL); + fflush(stdout); + } + else { + Wct *pwct = pwix->pwct; + + /* + * printf("Found %s in file %s\n", pwct->wordv[pwix->word], + * pwct->fname); + */ + /* copy them buffer into where it should be */ + new_len = strlen(pwct->wordv[pwix->word]); + diff = new_len - curr_len; + if (curr_pntr != buff_pntr) { + forwardcopy(&buff[curr_pntr + diff], + &buff[curr_pntr], + buff_pntr - curr_pntr); + forwardflag_cpy(&buff_flag[curr_pntr + diff], + &buff_flag[curr_pntr], + buff_pntr - curr_pntr); + } + buff_pntr += diff; + + + /* Now insert the new characters */ + for (i = new_len - diff; i < new_len; i++) + buff[st + i] = (pwct->wordv[pwix->word])[i]; + + /* Now move the cursor forward to the end of the word */ + for (i = 0; i < diff; i++) + putchar(buff[curr_pntr++]); + + /** now print the characters on the rest of the line **/ + printbuff(curr_pntr, buff_pntr - curr_pntr); + + /* now move bcak the number of characters I want to */ + for (i = buff_pntr; i != e + diff; i--) + putchar(_BKSPC); + + fflush(stdout); + + curr_pntr = diff + e; + + } + + +} diff --git a/src/lisp/core.lisp.in b/src/lisp/core.lisp.in index 4fce2768..d5e36548 100644 --- a/src/lisp/core.lisp.in +++ b/src/lisp/core.lisp.in @@ -423,7 +423,10 @@ (eval-when (:compile-toplevel :load-toplevel :execute) (progn (setq *read-default-float-format* 'double-float) - (setq *load-verbose* nil))) + (setq *load-print* nil) + (setq *load-verbose* nil) + (setq *compile-print* nil) + (setq *compile-verbose* nil))) ;; True means that the base Lisp system uses conventional C-style ;; program linking model, whereby programs are constructed by linking @@ -673,6 +676,7 @@ (defun |getFileType|(file) (let ((file-type (pathname-type file))) (cond ((or (equal "clisp" file-type) + (equal "cl" file-type) (equal "lsp" file-type)) |$LispFileType|) (t file-type)))) diff --git a/src/sman/session.c b/src/sman/session.c deleted file mode 100644 index 20a29307..00000000 --- a/src/sman/session.c +++ /dev/null @@ -1,534 +0,0 @@ -/* - Copyright (c) 1991-2002, The Numerical Algorithms Group Ltd. - All rights reserved. - - Copyright (C) 2007-2013, 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 DEBUG */ -#define _SESSION_C - -#include -#include -#include -#include -#include -#include - -#include "open-axiom.h" -#include "sockio.h" -#include "com.h" -#include "bsdsignal.h" -#include "cfuns.h" -#include "sockio.h" - -using namespace OpenAxiom; - -static void usr1_handler(int); -static void usr2_handler(int); -static void term_handler(int); -static void close_client(int); -static void read_SpadServer_command(void); -static int test_sock_for_process(openaxiom_sio*); -static void read_menu_client_command(void); -static void read_from_spad_io(void); -static void kill_spad(void); -static int accept_session_connection(openaxiom_sio*); -static void read_from_session(openaxiom_sio*); -static void manage_sessions(void); - - -#define BufSize 4096 /* size of communication buffer */ - -typedef struct sock_list { /* linked list of Sock */ - openaxiom_sio Socket; - struct sock_list *next; -} Sock_List; - -openaxiom_sio* spad_io = 0; /* to_server socket for SessionIO */ -openaxiom_sio* spad_server = 0; /* to_server socket for SpadServer */ -openaxiom_sio* menu_client = 0; /* to_client socket for MenuServerName */ -openaxiom_sio* active_session = 0; /* pointer to currently active session */ - -Sock_List *plSock = (Sock_List *) 0; - -char big_bad_buf[BufSize]; /* big I/O buffer */ -int num_active_clients = 0; /* number of InterpWindows attached */ -int reading_output = 0; -fd_set session_socket_mask; - -static void -usr1_handler(int sig) -{ - return; -} - -static void -usr2_handler(int sig) -{ - send_signal(spad_server, SIGINT); - return; -} - -static void -term_handler(int sig) -{ - exit(1); -} - -#ifdef DEBUG -static void -pr() -{ - Sock_List *pSock; - - fprintf(stderr,"The socket list:\n"); - for(pSock=plSock;pSock!=(Sock_List *)0;pSock=pSock->next){ - fprintf(stderr,"(%d,%d,%d)\t",pSock->Socket.pid,2<<(pSock->Socket.socket),pSock->Socket.frame); - } - fprintf(stderr,"\n"); -} -#endif - -static void -close_client(int frame) -{ - Sock_List *pSock,*locSock; - int socket_fd; - - /* we will check for frame equality, - kill with send_signal, - notify HyperTex so that it updates its list (if it's a spadbuf), - repair the list, - unset the active_session, - update num_active_clients - */ - - - /* first check head */ -#ifdef DEBUG -fprintf(stderr,"close_client(%d)\n",frame); -#endif - - if ( (plSock) && (plSock->Socket.frame == frame) ){ - socket_fd = plSock->Socket.socket; - send_signal((openaxiom_sio *)plSock, SIGTERM); - if ( menu_client != (openaxiom_sio *) 0){ - send_int(menu_client,CloseClient); - send_int(menu_client,(*plSock).Socket.pid); - } -#ifdef DEBUG -fprintf(stderr,"trying to clear %u\n",socket_fd); -#endif - FD_CLR(socket_fd,&session_socket_mask); - locSock = plSock; - if ((*plSock).next == (Sock_List *) 0) - {plSock = (Sock_List *) 0;} - else - {plSock = plSock->next;} - active_session = (openaxiom_sio *) 0; - num_active_clients--; - free(locSock); - } - - /* now check the rest */ - - else { - for (pSock=plSock; pSock->next != (Sock_List *) 0 ; pSock=pSock->next) - if (pSock->next->Socket.frame == frame){ - socket_fd = pSock->next->Socket.socket; - send_signal((openaxiom_sio *)pSock->next, SIGTERM); - if ( menu_client != (openaxiom_sio *) 0){ - send_int(menu_client,CloseClient); - send_int(menu_client,(*plSock).Socket.pid); - } -#ifdef DEBUG -fprintf(stderr,"trying to clear %u\n",socket_fd); -#endif - FD_CLR(socket_fd,&session_socket_mask); - locSock = pSock->next; - if ( pSock->next->next == (Sock_List *) 0 ) - { pSock->next= (Sock_List *) 0;} - else - { pSock->next = pSock->next->next;} - num_active_clients--; - active_session = (openaxiom_sio *) 0; - free(locSock); - break; - } - } -#ifdef DEBUG -pr(); -#endif -} - -static void -read_SpadServer_command(void) -{ - int cmd, frame, num; - cmd = get_int(spad_server); - switch (cmd) { - case EndOfOutput: - if (menu_client != (openaxiom_sio *) 0) send_signal(menu_client, SIGUSR2); - if (reading_output != 0) reading_output = 0; - break; - case QueryClients: - /* don't count MenuServer */ - num = num_active_clients ; - send_int(spad_server, num); - break; - case CloseClient: - frame = get_int(spad_server); - if (frame != -1) close_client(frame); - break; - case SendXEventToHyperTeX: - break; - default: - fprintf(stderr, "session : unknown command from SpadServer %d\n", cmd); - break; - } -} - -static int -test_sock_for_process(openaxiom_sio *sock) -{ - if (sock == (openaxiom_sio *)0 ) return -1; - return kill(sock->pid, 0); -} - -static void -read_menu_client_command(void) -{ - int cmd,frame, i,socket_fd; - Sock_List *pSock; - - /* save it for possible clearing */ - socket_fd = menu_client->socket; - - if (test_sock_for_process(menu_client) == -1) { - FD_CLR(socket_fd,&session_socket_mask); - menu_client = (openaxiom_sio *) 0; - reading_output = 0; - return; - } - cmd = get_int(menu_client); - switch(cmd) { - case -1: /* socket closed */ - FD_CLR(socket_fd,&session_socket_mask); - menu_client = (openaxiom_sio *) 0; - reading_output = 0; - break; - case SwitchFrames: -#ifdef DEBUG -fprintf(stderr,"menu:SwitchFrames\n"); -#endif - frame = get_int(menu_client); - send_int(spad_server, SwitchFrames); - send_int(spad_server, frame); - for(i=0,pSock=plSock; pSock != (Sock_List *) 0 ; i++,pSock=pSock->next) - if (pSock->Socket.frame == frame) { - active_session = (openaxiom_sio *)pSock; - reading_output = 1; - break; - } - if (i == num_active_clients) { - /* fprintf(stderr, "Couldn't find socket for frame %d\n", frame); */ - } - break; - case QuerySpad: -#ifdef DEBUG -fprintf(stderr,"menu:QuerySpad\n"); -#endif - send_int(menu_client, reading_output); - break; - default: - fprintf(stderr, "session : unknown command from MenuServer: %d\n", cmd); - menu_client = (openaxiom_sio *) 0; - break; - } -} - -static void -read_from_spad_io(void) -{ - int ret_code; - ret_code = sread(spad_io, byte_address(big_bad_buf), BufSize, - "session: stdout socket"); - if (ret_code == -1) return; - if(active_session != (openaxiom_sio *) 0) { - ret_code = swrite(active_session, byte_address(big_bad_buf), - ret_code, NULL); - } -} - -static void -kill_spad(void) -{ - int i; - Sock_List *pSock; - - send_signal(spad_server, SIGTERM); - for (pSock=plSock,i=0; - (inext) { - if ((pSock->Socket).socket != 0) - send_signal((openaxiom_sio *)pSock, SIGTERM); - } - if (menu_client != (openaxiom_sio *) 0) send_signal(menu_client, SIGTERM); - exit(0); -} - -static int -accept_session_connection(openaxiom_sio *server_sock) -{ - int sock_fd, ret_code; - Sock_List *pls; - - /* Could be three things : KillSpad MenuServer InterpWindow */ - - pls = (Sock_List *) malloc(sizeof (Sock_List)); - sock_fd = accept(server_sock->socket, 0, 0); - if (sock_fd == -1) { - perror("session : accepting connection"); - return -1; - } - (pls->Socket).socket = sock_fd; - get_socket_type((openaxiom_sio *)pls); - - switch((pls->Socket).purpose) { - case KillSpad: - kill_spad(); - return KillSpad; - free(pls); - case MenuServer: -#ifdef DEBUG - fprintf(stderr,"session: accepted MenuServer , fd = %d\n",sock_fd); -#endif - menu_client = &(pls->Socket); - FD_SET(menu_client->socket, &session_socket_mask); - return MenuServer; - case InterpWindow: -#ifdef DEBUG - fprintf(stderr,"session: accepted InterpWindow , fd = %d\n",sock_fd); -#endif - - /* new Sock is put at the head of the list */ - if (plSock == (Sock_List *)0 ) { - plSock = pls; - plSock->next = (Sock_List *)0 ; - } - else{ - pls->next = plSock; - plSock = pls; - } - - /* we need to maintain session_socket_mask here since we roll our own accept */ - - FD_SET(plSock->Socket.socket, &session_socket_mask); - send_int(spad_server, CreateFrame); - plSock->Socket.frame = get_int(spad_server); - active_session = (openaxiom_sio *)plSock; - get_string_buf(spad_server, big_bad_buf, BufSize); - ret_code = swrite((openaxiom_sio *)plSock, - byte_address(big_bad_buf), - strlen(big_bad_buf)+1, - "session: writing to InterpWindow"); - if (ret_code == -1) - return -1; - num_active_clients++; -#ifdef DEBUG -pr(); -#endif - return plSock->Socket.purpose; - } - return (-1); -} - -static void -read_from_session(openaxiom_sio *sock) -{ - int ret_code; - if (sock != active_session) { - send_int(spad_server, SwitchFrames); - send_int(spad_server, sock->frame); - } - active_session = sock; - ret_code = sread(sock, byte_address(big_bad_buf), BufSize, - "session: reading InterpWindow"); - if (ret_code == -1) { - active_session = (openaxiom_sio *) 0; - reading_output = 0; - return; - } - ret_code = swrite(spad_io, byte_address(big_bad_buf), ret_code, - "session: writing SessionIO"); - if (ret_code == -1) { - active_session = (openaxiom_sio *)0 ; - reading_output = 0; - return; - } - reading_output = 1; -} - -static void -manage_sessions(void) -{ - int ret_code; - fd_set rd, wr, ex; - Sock_List *pSock; - - reading_output = 0; - while (1) { - FD_ZERO(&rd); - FD_ZERO(&wr); - FD_ZERO(&ex); - - /* Allow server socket and all connections if not waiting for output - socket_mask is maintained by libspad.a */ -#ifdef DEBUG -fprintf(stderr,"session_socket_mask=%u ",*((long *)session_socket_mask.fds_bits)); -#endif - rd = session_socket_mask; - if (!reading_output) { - rd = session_socket_mask; - } - - /* Allow the active_session if set */ - if (active_session) FD_SET(active_session->socket, &rd); -#ifdef DEBUG -fprintf(stderr,"[rd=%u ",*((long *)rd.fds_bits)); -#endif - - ret_code = sselect(FD_SETSIZE, &rd, &wr, &ex, NULL); - if (ret_code == -1) { - break; - } -#ifdef DEBUG -fprintf(stderr,"rd=%u]\n",*((long *)rd.fds_bits)); -#endif - - if ((menu_client != (openaxiom_sio *) 0) - && FD_ISSET(menu_client->socket, &rd)) { - /* MenuServer wants to talk */ - read_menu_client_command(); } - - - if (FD_ISSET(spad_io->socket, &rd)) { - /* Lisp has output */ - read_from_spad_io(); } - - - if (FD_ISSET(server.socket, &rd)) { - /* Someone wants to connect to our server socket */ - accept_session_connection(&server); } - - - for(pSock=plSock; pSock != (Sock_List *) 0 ; pSock=pSock->next) { - if ((active_session == (openaxiom_sio *)pSock || !reading_output) && - (pSock->Socket).socket>0 && FD_ISSET(pSock->Socket.socket, &rd)) { - /* An InterpWindow */ - read_from_session((openaxiom_sio *)pSock); } - } - - - if (FD_ISSET(spad_server->socket, &rd)) { - /* The Lisp socket */ - read_SpadServer_command(); } - } -} - -int -main(void) -{ - using namespace OpenAxiom; -#ifdef DEBUG2 - /* delay for attaching with debugger before interesting things happen */ - openaxiom_sleep(30); -#endif - - oa_setenv("LC_ALL", "C"); - setlocale(LC_ALL, ""); - /* spad_server connects to Lisp server socket - read_SpadServer_command handles requests */ - spad_server = connect_to_local_server(SpadServer, SessionManager, Forever); - if (spad_server == (openaxiom_sio *) 0) { - fprintf(stderr, "session: Cannot connect to OpenAxiom server!\n"); - exit(0); - } - else { -#ifdef DEBUG - fprintf(stderr, "session: connected SpadServer , fd = %d\n", - spad_server->socket); -#endif - FD_SET(spad_server->socket, &session_socket_mask); - } - - - /* spad_io connects to SessionIOName server socket - this is Lisp std IO read_from_spad_io handles requests */ - spad_io = connect_to_local_server(SessionIOName, SessionIO, Forever); - if (spad_io == (openaxiom_sio *) 0) { - fprintf(stderr, "session: Cannot connect to OpenAxiom IO!\n"); - exit(0); - } - else { -#ifdef DEBUG - fprintf(stderr,"session: connected SessionIOName , fd = %d\n", - spad_io->socket); -#endif - FD_SET(spad_io->socket, &session_socket_mask); - } - bsdSignal(SIGUSR2, usr2_handler,DontRestartSystemCalls); - bsdSignal(SIGUSR1, usr1_handler,RestartSystemCalls); - bsdSignal(SIGINT, SIG_IGN,RestartSystemCalls); - bsdSignal(SIGTERM, term_handler,RestartSystemCalls); - - /* open_server opens the server socket so that we can accept connections - we expect connections from spadbuf/spadclient(purpose:InterpWindow) - and hypertex (MenuServer) */ - - if (open_server(SessionServer) == -2) { - fprintf(stderr, "session: Cannot make server socket!\n"); - exit(-1); - } - else { -#ifdef DEBUG - fprintf(stderr, "session: opened SessionServer , fd = %d\n", - server.socket); -#endif - FD_SET(server.socket,&session_socket_mask); - } - manage_sessions(); - return(0); -} - - diff --git a/src/sman/session.cc b/src/sman/session.cc new file mode 100644 index 00000000..20a29307 --- /dev/null +++ b/src/sman/session.cc @@ -0,0 +1,534 @@ +/* + Copyright (c) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + + Copyright (C) 2007-2013, 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 DEBUG */ +#define _SESSION_C + +#include +#include +#include +#include +#include +#include + +#include "open-axiom.h" +#include "sockio.h" +#include "com.h" +#include "bsdsignal.h" +#include "cfuns.h" +#include "sockio.h" + +using namespace OpenAxiom; + +static void usr1_handler(int); +static void usr2_handler(int); +static void term_handler(int); +static void close_client(int); +static void read_SpadServer_command(void); +static int test_sock_for_process(openaxiom_sio*); +static void read_menu_client_command(void); +static void read_from_spad_io(void); +static void kill_spad(void); +static int accept_session_connection(openaxiom_sio*); +static void read_from_session(openaxiom_sio*); +static void manage_sessions(void); + + +#define BufSize 4096 /* size of communication buffer */ + +typedef struct sock_list { /* linked list of Sock */ + openaxiom_sio Socket; + struct sock_list *next; +} Sock_List; + +openaxiom_sio* spad_io = 0; /* to_server socket for SessionIO */ +openaxiom_sio* spad_server = 0; /* to_server socket for SpadServer */ +openaxiom_sio* menu_client = 0; /* to_client socket for MenuServerName */ +openaxiom_sio* active_session = 0; /* pointer to currently active session */ + +Sock_List *plSock = (Sock_List *) 0; + +char big_bad_buf[BufSize]; /* big I/O buffer */ +int num_active_clients = 0; /* number of InterpWindows attached */ +int reading_output = 0; +fd_set session_socket_mask; + +static void +usr1_handler(int sig) +{ + return; +} + +static void +usr2_handler(int sig) +{ + send_signal(spad_server, SIGINT); + return; +} + +static void +term_handler(int sig) +{ + exit(1); +} + +#ifdef DEBUG +static void +pr() +{ + Sock_List *pSock; + + fprintf(stderr,"The socket list:\n"); + for(pSock=plSock;pSock!=(Sock_List *)0;pSock=pSock->next){ + fprintf(stderr,"(%d,%d,%d)\t",pSock->Socket.pid,2<<(pSock->Socket.socket),pSock->Socket.frame); + } + fprintf(stderr,"\n"); +} +#endif + +static void +close_client(int frame) +{ + Sock_List *pSock,*locSock; + int socket_fd; + + /* we will check for frame equality, + kill with send_signal, + notify HyperTex so that it updates its list (if it's a spadbuf), + repair the list, + unset the active_session, + update num_active_clients + */ + + + /* first check head */ +#ifdef DEBUG +fprintf(stderr,"close_client(%d)\n",frame); +#endif + + if ( (plSock) && (plSock->Socket.frame == frame) ){ + socket_fd = plSock->Socket.socket; + send_signal((openaxiom_sio *)plSock, SIGTERM); + if ( menu_client != (openaxiom_sio *) 0){ + send_int(menu_client,CloseClient); + send_int(menu_client,(*plSock).Socket.pid); + } +#ifdef DEBUG +fprintf(stderr,"trying to clear %u\n",socket_fd); +#endif + FD_CLR(socket_fd,&session_socket_mask); + locSock = plSock; + if ((*plSock).next == (Sock_List *) 0) + {plSock = (Sock_List *) 0;} + else + {plSock = plSock->next;} + active_session = (openaxiom_sio *) 0; + num_active_clients--; + free(locSock); + } + + /* now check the rest */ + + else { + for (pSock=plSock; pSock->next != (Sock_List *) 0 ; pSock=pSock->next) + if (pSock->next->Socket.frame == frame){ + socket_fd = pSock->next->Socket.socket; + send_signal((openaxiom_sio *)pSock->next, SIGTERM); + if ( menu_client != (openaxiom_sio *) 0){ + send_int(menu_client,CloseClient); + send_int(menu_client,(*plSock).Socket.pid); + } +#ifdef DEBUG +fprintf(stderr,"trying to clear %u\n",socket_fd); +#endif + FD_CLR(socket_fd,&session_socket_mask); + locSock = pSock->next; + if ( pSock->next->next == (Sock_List *) 0 ) + { pSock->next= (Sock_List *) 0;} + else + { pSock->next = pSock->next->next;} + num_active_clients--; + active_session = (openaxiom_sio *) 0; + free(locSock); + break; + } + } +#ifdef DEBUG +pr(); +#endif +} + +static void +read_SpadServer_command(void) +{ + int cmd, frame, num; + cmd = get_int(spad_server); + switch (cmd) { + case EndOfOutput: + if (menu_client != (openaxiom_sio *) 0) send_signal(menu_client, SIGUSR2); + if (reading_output != 0) reading_output = 0; + break; + case QueryClients: + /* don't count MenuServer */ + num = num_active_clients ; + send_int(spad_server, num); + break; + case CloseClient: + frame = get_int(spad_server); + if (frame != -1) close_client(frame); + break; + case SendXEventToHyperTeX: + break; + default: + fprintf(stderr, "session : unknown command from SpadServer %d\n", cmd); + break; + } +} + +static int +test_sock_for_process(openaxiom_sio *sock) +{ + if (sock == (openaxiom_sio *)0 ) return -1; + return kill(sock->pid, 0); +} + +static void +read_menu_client_command(void) +{ + int cmd,frame, i,socket_fd; + Sock_List *pSock; + + /* save it for possible clearing */ + socket_fd = menu_client->socket; + + if (test_sock_for_process(menu_client) == -1) { + FD_CLR(socket_fd,&session_socket_mask); + menu_client = (openaxiom_sio *) 0; + reading_output = 0; + return; + } + cmd = get_int(menu_client); + switch(cmd) { + case -1: /* socket closed */ + FD_CLR(socket_fd,&session_socket_mask); + menu_client = (openaxiom_sio *) 0; + reading_output = 0; + break; + case SwitchFrames: +#ifdef DEBUG +fprintf(stderr,"menu:SwitchFrames\n"); +#endif + frame = get_int(menu_client); + send_int(spad_server, SwitchFrames); + send_int(spad_server, frame); + for(i=0,pSock=plSock; pSock != (Sock_List *) 0 ; i++,pSock=pSock->next) + if (pSock->Socket.frame == frame) { + active_session = (openaxiom_sio *)pSock; + reading_output = 1; + break; + } + if (i == num_active_clients) { + /* fprintf(stderr, "Couldn't find socket for frame %d\n", frame); */ + } + break; + case QuerySpad: +#ifdef DEBUG +fprintf(stderr,"menu:QuerySpad\n"); +#endif + send_int(menu_client, reading_output); + break; + default: + fprintf(stderr, "session : unknown command from MenuServer: %d\n", cmd); + menu_client = (openaxiom_sio *) 0; + break; + } +} + +static void +read_from_spad_io(void) +{ + int ret_code; + ret_code = sread(spad_io, byte_address(big_bad_buf), BufSize, + "session: stdout socket"); + if (ret_code == -1) return; + if(active_session != (openaxiom_sio *) 0) { + ret_code = swrite(active_session, byte_address(big_bad_buf), + ret_code, NULL); + } +} + +static void +kill_spad(void) +{ + int i; + Sock_List *pSock; + + send_signal(spad_server, SIGTERM); + for (pSock=plSock,i=0; + (inext) { + if ((pSock->Socket).socket != 0) + send_signal((openaxiom_sio *)pSock, SIGTERM); + } + if (menu_client != (openaxiom_sio *) 0) send_signal(menu_client, SIGTERM); + exit(0); +} + +static int +accept_session_connection(openaxiom_sio *server_sock) +{ + int sock_fd, ret_code; + Sock_List *pls; + + /* Could be three things : KillSpad MenuServer InterpWindow */ + + pls = (Sock_List *) malloc(sizeof (Sock_List)); + sock_fd = accept(server_sock->socket, 0, 0); + if (sock_fd == -1) { + perror("session : accepting connection"); + return -1; + } + (pls->Socket).socket = sock_fd; + get_socket_type((openaxiom_sio *)pls); + + switch((pls->Socket).purpose) { + case KillSpad: + kill_spad(); + return KillSpad; + free(pls); + case MenuServer: +#ifdef DEBUG + fprintf(stderr,"session: accepted MenuServer , fd = %d\n",sock_fd); +#endif + menu_client = &(pls->Socket); + FD_SET(menu_client->socket, &session_socket_mask); + return MenuServer; + case InterpWindow: +#ifdef DEBUG + fprintf(stderr,"session: accepted InterpWindow , fd = %d\n",sock_fd); +#endif + + /* new Sock is put at the head of the list */ + if (plSock == (Sock_List *)0 ) { + plSock = pls; + plSock->next = (Sock_List *)0 ; + } + else{ + pls->next = plSock; + plSock = pls; + } + + /* we need to maintain session_socket_mask here since we roll our own accept */ + + FD_SET(plSock->Socket.socket, &session_socket_mask); + send_int(spad_server, CreateFrame); + plSock->Socket.frame = get_int(spad_server); + active_session = (openaxiom_sio *)plSock; + get_string_buf(spad_server, big_bad_buf, BufSize); + ret_code = swrite((openaxiom_sio *)plSock, + byte_address(big_bad_buf), + strlen(big_bad_buf)+1, + "session: writing to InterpWindow"); + if (ret_code == -1) + return -1; + num_active_clients++; +#ifdef DEBUG +pr(); +#endif + return plSock->Socket.purpose; + } + return (-1); +} + +static void +read_from_session(openaxiom_sio *sock) +{ + int ret_code; + if (sock != active_session) { + send_int(spad_server, SwitchFrames); + send_int(spad_server, sock->frame); + } + active_session = sock; + ret_code = sread(sock, byte_address(big_bad_buf), BufSize, + "session: reading InterpWindow"); + if (ret_code == -1) { + active_session = (openaxiom_sio *) 0; + reading_output = 0; + return; + } + ret_code = swrite(spad_io, byte_address(big_bad_buf), ret_code, + "session: writing SessionIO"); + if (ret_code == -1) { + active_session = (openaxiom_sio *)0 ; + reading_output = 0; + return; + } + reading_output = 1; +} + +static void +manage_sessions(void) +{ + int ret_code; + fd_set rd, wr, ex; + Sock_List *pSock; + + reading_output = 0; + while (1) { + FD_ZERO(&rd); + FD_ZERO(&wr); + FD_ZERO(&ex); + + /* Allow server socket and all connections if not waiting for output + socket_mask is maintained by libspad.a */ +#ifdef DEBUG +fprintf(stderr,"session_socket_mask=%u ",*((long *)session_socket_mask.fds_bits)); +#endif + rd = session_socket_mask; + if (!reading_output) { + rd = session_socket_mask; + } + + /* Allow the active_session if set */ + if (active_session) FD_SET(active_session->socket, &rd); +#ifdef DEBUG +fprintf(stderr,"[rd=%u ",*((long *)rd.fds_bits)); +#endif + + ret_code = sselect(FD_SETSIZE, &rd, &wr, &ex, NULL); + if (ret_code == -1) { + break; + } +#ifdef DEBUG +fprintf(stderr,"rd=%u]\n",*((long *)rd.fds_bits)); +#endif + + if ((menu_client != (openaxiom_sio *) 0) + && FD_ISSET(menu_client->socket, &rd)) { + /* MenuServer wants to talk */ + read_menu_client_command(); } + + + if (FD_ISSET(spad_io->socket, &rd)) { + /* Lisp has output */ + read_from_spad_io(); } + + + if (FD_ISSET(server.socket, &rd)) { + /* Someone wants to connect to our server socket */ + accept_session_connection(&server); } + + + for(pSock=plSock; pSock != (Sock_List *) 0 ; pSock=pSock->next) { + if ((active_session == (openaxiom_sio *)pSock || !reading_output) && + (pSock->Socket).socket>0 && FD_ISSET(pSock->Socket.socket, &rd)) { + /* An InterpWindow */ + read_from_session((openaxiom_sio *)pSock); } + } + + + if (FD_ISSET(spad_server->socket, &rd)) { + /* The Lisp socket */ + read_SpadServer_command(); } + } +} + +int +main(void) +{ + using namespace OpenAxiom; +#ifdef DEBUG2 + /* delay for attaching with debugger before interesting things happen */ + openaxiom_sleep(30); +#endif + + oa_setenv("LC_ALL", "C"); + setlocale(LC_ALL, ""); + /* spad_server connects to Lisp server socket + read_SpadServer_command handles requests */ + spad_server = connect_to_local_server(SpadServer, SessionManager, Forever); + if (spad_server == (openaxiom_sio *) 0) { + fprintf(stderr, "session: Cannot connect to OpenAxiom server!\n"); + exit(0); + } + else { +#ifdef DEBUG + fprintf(stderr, "session: connected SpadServer , fd = %d\n", + spad_server->socket); +#endif + FD_SET(spad_server->socket, &session_socket_mask); + } + + + /* spad_io connects to SessionIOName server socket + this is Lisp std IO read_from_spad_io handles requests */ + spad_io = connect_to_local_server(SessionIOName, SessionIO, Forever); + if (spad_io == (openaxiom_sio *) 0) { + fprintf(stderr, "session: Cannot connect to OpenAxiom IO!\n"); + exit(0); + } + else { +#ifdef DEBUG + fprintf(stderr,"session: connected SessionIOName , fd = %d\n", + spad_io->socket); +#endif + FD_SET(spad_io->socket, &session_socket_mask); + } + bsdSignal(SIGUSR2, usr2_handler,DontRestartSystemCalls); + bsdSignal(SIGUSR1, usr1_handler,RestartSystemCalls); + bsdSignal(SIGINT, SIG_IGN,RestartSystemCalls); + bsdSignal(SIGTERM, term_handler,RestartSystemCalls); + + /* open_server opens the server socket so that we can accept connections + we expect connections from spadbuf/spadclient(purpose:InterpWindow) + and hypertex (MenuServer) */ + + if (open_server(SessionServer) == -2) { + fprintf(stderr, "session: Cannot make server socket!\n"); + exit(-1); + } + else { +#ifdef DEBUG + fprintf(stderr, "session: opened SessionServer , fd = %d\n", + server.socket); +#endif + FD_SET(server.socket,&session_socket_mask); + } + manage_sessions(); + return(0); +} + + diff --git a/src/sman/sman.c b/src/sman/sman.c deleted file mode 100644 index ac941266..00000000 --- a/src/sman/sman.c +++ /dev/null @@ -1,794 +0,0 @@ -/* - Copyright (c) 1991-2002, The Numerical Algorithms Group Ltd. - All rights reserved. - Copyright (C) 2007-2014, 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "open-axiom.h" -#include "sockio.h" -#include "com.h" -#include "bsdsignal.h" -#include "sman.h" - -#include "sockio.h" -#include "openpty.h" -#include "cfuns.h" - -using namespace OpenAxiom; - -static void process_arguments(Command*, int, char**); -static int in_X(void); -static void set_up_defaults(void); -static void process_options(Command*, int, char**); -static void death_handler(int); -static void sman_catch_signals(void); -static void fix_env(int); -static void init_term_io(void); -static const char* strPrefix(const char* , const char*); -static void check_spad_proc(const char* , const char*); -static void clean_up_old_sockets(void); -static SpadProcess* fork_you(int); -static void exec_command_env(const char*); -static SpadProcess* spawn_of_hell(const char* , int); -static void start_the_spadclient(void); -static void start_the_local_spadclient(void); -static void start_the_session_manager(void); -static void start_the_hypertex(Command*); -static void start_the_graphics(Command*); -static void fork_Axiom(Command*); -static void start_the_Axiom(Command*); -static void clean_up_sockets(void); -static void clean_hypertex_socket(void); -static void read_from_spad_io(int); -static void read_from_manager(int); -static void manage_spad_io(int); -static SpadProcess* find_child(int); -static void kill_all_children(void); -static void monitor_children(void); - -/* System defined pointer to array or environment variables. */ -extern char** environ; - -int start_clef; /* start clef under spad */ -int start_graphics; /* start the viewman */ -int start_ht; /* start hypertex */ -int start_spadclient; /* Start the client spad buffer */ -int start_local_spadclient; /* Start the client spad buffer */ -int use_X; /* Use the X windows environment */ -int server_num; /* OpenAxiom server number */ - -/************************************************/ -/* definitions of programs which sman can start */ -/************************************************/ - -const char *GraphicsProgram = "/lib/viewman"; -const char *HypertexProgram = "/lib/hypertex"; -const char *ClefProgram = "$AXIOM/bin/clef -f $AXIOM/lib/command.list -e "; -const char *SessionManagerProgram = "$AXIOM/lib/session"; -const char *SpadClientProgram = "$AXIOM/lib/spadclient"; -char *PasteFile = NULL; -char *MakeRecordFile = NULL; -char *VerifyRecordFile = NULL; - -SpadProcess *spad_process_list = NULL; -/***************************/ -/* sman defaults file name */ -/***************************/ - -#define SpadDefaultFile "spadprof.input" - -char ClefCommandLine[256]; - -#define BufSize 4096 /* size of communication buffer */ -char big_bad_buf[BufSize]; /* big I/O buffer */ - -openaxiom_sio* session_io = NULL; /* socket connecting to session manager */ - -/***********************************************************/ -/* Some characters used and externally defined in edible.h */ -/***********************************************************/ - -unsigned char _INTR, _QUIT, _ERASE, _KILL, _EOF, _EOL, _RES1, _RES2; - -/*************************************/ -/* Stuff for opening pseudo-terminal */ -/*************************************/ - -int ptsNum, ptcNum; -char ptsPath[20]; - -int child_pid; /* child's process id */ -struct termios oldbuf; /* the original settings */ -struct termios childbuf; /* terminal structure for user i/o */ - - -int death_signal = 0; - -static void -process_arguments(Command* command, int argc,char ** argv) -{ - int arg; - int other = 0; - for (arg = 1; arg < argc; arg++) { - if (strcmp(argv[arg], "-noclef") == 0) - start_clef = 0; - else if (strcmp(argv[arg], "-clef") == 0) - start_clef = 1; - else if (strcmp(argv[arg], "-gr") == 0 - || strcmp(argv[arg], "--graph") == 0 ) { - if (!OPENAXIOM_HAVE_GRAPHICS) - fprintf(stderr, "OpenAxiom was not build with Graphics support.\n"); - else - start_graphics = 1; - } - else if (strcmp(argv[arg], "-nogr") == 0 - || strcmp(argv[arg], "--no-graph") == 0) - start_graphics = 0; - else if (strcmp(argv[arg], "-ht") == 0 - || strcmp(argv[arg], "--hyperdoc") == 0) { - if (!OPENAXIOM_HAVE_GRAPHICS) - fprintf(stderr, "OpenAxiom was not build with HyperDoc support.\n"); - else - start_ht = 1; - } - else if (strcmp(argv[arg], "-noht") == 0 - || strcmp(argv[arg], "--no-hyperdoc") == 0) - start_ht = 0; - else if (strcmp(argv[arg], "-iw") == 0) - start_spadclient = 1; - else if (strcmp(argv[arg], "-ihere") == 0) - start_local_spadclient = 1; - else if (strcmp(argv[arg], "-noihere") == 0) - start_local_spadclient = 0; - else if (strcmp(argv[arg], "-noiw") == 0) - start_spadclient = 0; - else if (strcmp(argv[arg], "-nox") == 0 - || strcmp(argv[arg], "--no-gui") == 0) { - use_X = 0; - start_local_spadclient = 1; - start_spadclient = 0; - start_ht = 0; - start_graphics = 0; - } - else if (strcmp(argv[arg], "-clefprog") == 0) { - strcpy(ClefCommandLine,argv[++arg]); - ClefProgram = - strcat(ClefCommandLine, " -f $AXIOM/lib/command.list -e "); - } - else if (strcmp(argv[arg], "-rm") == 0) - MakeRecordFile = argv[++arg]; - else if (strcmp(argv[arg], "-rv") == 0) - VerifyRecordFile = argv[++arg]; - else if (strcmp(argv[arg], "-paste") == 0) - PasteFile = argv[++arg]; - else - argv[other++] = argv[arg]; - } - - command->core.argv = argv; - command->core.argc = other; - -/* If there were no X libraries - * at build-time, we proceed to - * overwrite the defaults startup - * values to not start any of the - * graphical components of - * OpenAxiom (Hyperdoc, Graphics). */ - - if (!OPENAXIOM_HAVE_GRAPHICS) { - use_X = 0; - start_local_spadclient = 1; - start_ht = 0; - start_graphics = 0; - } -} - -static int -in_X(void) -{ - if (oa_getenv("DISPLAY")) return 1; - return 0; -} - -static void -set_up_defaults(void) -{ - start_clef = 1; - start_graphics = 1; - start_ht = 1; - start_spadclient = 0; - start_local_spadclient = 1; - use_X = isatty(0) && in_X(); -} - -static void -process_options(Command* command, int argc, char **argv) -{ - set_up_defaults(); - process_arguments(command, argc, argv); - /* Complain about command line arguments unknown to Superman. */ - if (command->core.argc > 0) { - int i; - for (i = 0; i < command->core.argc; ++i) - fprintf(stderr,"command line error: %s\n", command->core.argv[i]); - exit(-1); - } -} - -static void -death_handler(int sig) -{ - death_signal = 1; -} - -static void -sman_catch_signals(void) -{ - - /* Set up the signal handlers for sman */ - bsdSignal(SIGINT, SIG_IGN,RestartSystemCalls); - bsdSignal(SIGTERM, death_handler,RestartSystemCalls); - bsdSignal(SIGQUIT, death_handler,RestartSystemCalls); - bsdSignal(SIGHUP, death_handler,RestartSystemCalls); - bsdSignal(SIGILL, death_handler,RestartSystemCalls); - bsdSignal(SIGTRAP, death_handler,RestartSystemCalls); - -#ifdef SIGABRT - bsdSignal(SIGABRT, death_handler,RestartSystemCalls); -#else - #ifdef SIGIOT - bsdSignal(SIGIOT, death_handler,RestartSystemCalls); - #endif -#endif - - bsdSignal(SIGBUS, death_handler,RestartSystemCalls); - bsdSignal(SIGSEGV, death_handler,RestartSystemCalls); - -} - -static void -fix_env(int spadnum) -{ - char sn[20]; - sprintf(sn, "%d", spadnum); - oa_setenv("SPADNUM", sn); - oa_setenv("SPADSERVER", "TRUE"); -} - -static void -init_term_io(void) -{ - if(!isatty(0)) return; - if( tcgetattr(0, &oldbuf) == -1) { - perror("getting termios"); - return ; /* exit(-1); */ - } - if( tcgetattr(0, &childbuf) == -1) { - perror("getting termios"); - return ; /* exit(-1); */ - } - _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]; -} - -static const char* -strPrefix(const char* prefix, const char* s) -{ - while (*prefix != '\0' && *prefix == *s) { - prefix++; - s++; - } - if (*prefix == '\0') return s; - return NULL; -} - -static void -check_spad_proc(const char *file, const char *prefix) -{ - const char *num; - int pid; - if ((num = strPrefix(prefix, file))) { - pid = atoi(num); - if (pid > 2) { - kill(pid, 0); - if (kill(pid, 0) == -1 && errno == ESRCH) { - unlink(file); - } - } - } -} - -static void -clean_up_old_sockets(void) -{ - char com[512], tmp_file[128]; - FILE *file; - int len; - sprintf(tmp_file, "/tmp/socks.%d", server_num); - sprintf(com, "ls /tmp/.d* /tmp/.s* /tmp/.i* /tmp/.h* 2> %s > %s", - tmp_file, tmp_file); - system(com); - file = fopen(tmp_file, "r"); - if (file == NULL) { - fprintf(stderr, "Can't open socket listing file\n"); - return; - } - while(fgets(com, 512, file) != NULL) { - len = strlen(com); - if (len) com[len-1] = '\0'; - else break; - check_spad_proc(com, "/tmp/.d"); - check_spad_proc(com, "/tmp/.s"); - check_spad_proc(com, "/tmp/.i"); - check_spad_proc(com, "/tmp/.h"); - } - fclose(file); - unlink(tmp_file); -} - -static SpadProcess * -fork_you(int death_action) -{ - /* fork a new process, giving it a default death action */ - /* return NULL in child, SpadProcess in parent */ - int child_pid = fork(); - SpadProcess *proc; - if (!child_pid) return NULL; - proc = (SpadProcess *) malloc(sizeof(SpadProcess)); - proc->proc_id = child_pid; - proc->death_action = death_action; - proc->command = NULL; - proc->next = spad_process_list; - spad_process_list = proc; - return proc; -} - -static void -exec_command_env(const char *command) -{ - char new_command[512]; - sprintf(new_command, "exec %s", command); - execle("/bin/sh","/bin/sh", "-c", new_command, (char*)NULL, environ); -} - -static SpadProcess * -spawn_of_hell(const char *command, int death_action) -{ - SpadProcess *proc = fork_you(death_action); - if (proc != NULL) { - proc->command = command; - return proc; - } - exec_command_env(command); - return NULL; -} - -static void -start_the_spadclient(void) -{ - char command[256]; - if (start_clef) - sprintf(command, - "xterm -sb -sl 500 -name axiomclient -n OpenAxiom -T OpenAxiom -e %s %s", - ClefProgram, SpadClientProgram); - else - sprintf(command, - "xterm -sb -sl 500 -name axiomclient -n OpenAxiom -T OpenAxiom -e %s", - SpadClientProgram); - spawn_of_hell(command, NadaDelShitsky); -} - -static void -start_the_local_spadclient(void) -{ - char command[256]; - if (start_clef) - sprintf(command, "%s %s", ClefProgram, SpadClientProgram); - else - sprintf(command, "%s", SpadClientProgram); - spawn_of_hell(command, NadaDelShitsky); -} - -static void -start_the_session_manager(void) -{ - spawn_of_hell(SessionManagerProgram, Die); -} - -static void -start_the_hypertex(Command* cmd) -{ - const char* root_dir = cmd->root_dir; - const char* command = oa_concatenate_string(root_dir,HypertexProgram); - - if (readablep(command) != 1) { - fprintf(stderr, "Hypertex program not found.\n"); - return; - } - if (PasteFile){ - command = oa_concatenate_string(command, " -s -k -ip "); - command = oa_concatenate_string(command, PasteFile); - spawn_of_hell(command, NadaDelShitsky); - } - else if (MakeRecordFile){ - command = oa_concatenate_string(command, " -s -k -rm "); - command = oa_concatenate_string(command, MakeRecordFile); - spawn_of_hell(command, NadaDelShitsky); - } - else if (VerifyRecordFile){ - command = oa_concatenate_string(command, " -s -k -rv "); - command = oa_concatenate_string(command, VerifyRecordFile); - spawn_of_hell(command, NadaDelShitsky); - } - else - spawn_of_hell(command, CleanHypertexSocket); -} - -static void -start_the_graphics(Command* cmd) -{ - const char* root_dir = cmd -> root_dir; - const char* command = oa_concatenate_string(root_dir,GraphicsProgram); - - if (readablep(command) == 1) - spawn_of_hell(command, DoItAgain); - else - fprintf(stderr, "Graphics program not found.\n"); -} - -/* Start the core executable session in a separate process, */ -/* using a pseudo-terminal to catch all input and output */ -static void -fork_Axiom(Command* cmd) -{ - SpadProcess *proc; - - proc = fork_you(Die); - child_pid = (proc == NULL ? 0 : proc->proc_id); - switch(child_pid) { - case -1 : - fprintf(stderr, "Can't create a new process \n"); - exit(0); - case 0: - /* Dissasociate from my parents group so all my child processes */ - /* look at my terminal as the controlling terminal for the */ - /* group */ - - if(setsid() < 0) { - perror("Dissassociating from parents group"); - exit(-1); - } - - close(ptsNum); - /* Now reopen the server side, so that pg, su, etc. work properly */ - - if ((ptsNum = open(ptsPath, O_RDWR)) < 0 ) { - perror("fork_Axiom: Failed to reopen server"); - exit(-1); - } -#if defined(SUN4OS5platform) || defined(HP10platform) - ioctl(ptsNum,I_PUSH,"ptem"); - ioctl(ptsNum,I_PUSH,"ldterm"); -#endif - - /* since I am the child, I can close ptc, and dup pts for all its */ - /* standard descriptors */ - - if( (dup2(ptsNum, 0) == -1) || - (dup2(ptsNum, 1) == -1) || - (dup2(ptsNum, 2) == -1) ) { - perror("trying to dupe the child"); - exit(-1); - } - close(ptcNum); - close(ptsNum); - - - /* I also have to turn off echoing, since I am echoing all the */ - /* input myself */ - - childbuf.c_lflag &= ~ECHO; - if( tcsetattr(0, TCSAFLUSH, &childbuf) == -1) { - perror("setting the term buffer"); - exit(-1); - } - - /* Tell the Core that it is being invoked in server mode. */ - oa_allocate_process_argv(&cmd->core, 2); - cmd->core.argv[0] = (char*) make_path_for(cmd->root_dir, Driver::core); - cmd->core.argv[1] = (char*) "--role=server"; - execute_core(cmd, Driver::core); - } -} - -static void -start_the_Axiom(Command* cmd) -{ - server_num = make_server_number(); - clean_up_old_sockets(); - if (server_num == -1) { - fprintf(stderr, "could not get an OpenAxiom server number\n"); - exit(-1); - } - if (ptyopen(&ptcNum, &ptsNum, ptsPath) == -1) { - perror("start_the_Axiom: ptyopen failed"); - exit(-1); - } - fix_env(server_num); - fork_Axiom(cmd); - close(ptsNum); -} - -static void -clean_hypertex_socket(void) -{ - char name[256]; - sprintf(name, "%s%d", MenuServerName, server_num); - unlink(name); -} - -static void -clean_up_sockets(void) -{ - char name[256]; - sprintf(name, "%s%d", SpadServer, server_num); - unlink(name); - sprintf(name, "%s%d", SessionServer, server_num); - unlink(name); - sprintf(name, "%s%d", SessionIOName, server_num); - unlink(name); - clean_hypertex_socket(); -} - -static void -read_from_spad_io(int ptcNum) -{ - int ret_code = 0, i=0; - static int mes_len =0; - ret_code = read(ptcNum, big_bad_buf, BufSize); - if (ret_code == -1) { - clean_up_sockets(); - exit(-1); - } - if (session_io == NULL) { - if (ret_code < mes_len) - mes_len -= ret_code; - else { - if (mes_len > 0) { - i = mes_len; - mes_len = 0; - } - else - i = 0; - ret_code = write(1, big_bad_buf+i, ret_code-i); - } - } - else - ret_code = swrite(session_io, byte_address(big_bad_buf), ret_code, - "writing to session man"); - if (ret_code == -1) { - perror("writing output to session manager"); - clean_up_sockets(); - exit(-1); - } -} - -static void -read_from_manager(int ptcNum) -{ - int ret_code; - ret_code = sread(session_io, byte_address(big_bad_buf), BufSize, - "reading session io"); - if (ret_code == -1) { - return; - } - ret_code = write(ptcNum, big_bad_buf, ret_code); - if (ret_code == -1) { - return; - } -} - -static void -manage_spad_io(int ptcNum) -{ - int ret_code, p; - fd_set rd; - while (1) { - rd = socket_mask; - FD_SET(ptcNum, &rd); - if (session_io != NULL) - FD_SET(session_io->socket, &rd); - ret_code = sselect(FD_SETSIZE, &rd, 0, 0, NULL); - if (ret_code == -1) { - perror("Session manager select"); - clean_up_sockets(); - exit(-1); - } - if (FD_ISSET(ptcNum, &rd)) { - read_from_spad_io(ptcNum); - } - if (server.socket > 0 && FD_ISSET(server.socket, &rd)) { - p = accept_connection(); - switch(p) { - case SessionIO: - session_io = purpose_table[SessionIO]; - /* printf("connected session manager\n\r");*/ - printf("\n"); - break; - default: - printf("sman: Unknown connection request type: %d\n", p); - break; - } - } - if (session_io != NULL && FD_ISSET(session_io->socket, &rd)) { - read_from_manager(ptcNum); - } - } -} - -#if 0 -static void -print_spad_process_list() -{ - SpadProcess *proc; - for(proc = spad_process_list; proc != NULL; proc = proc->next) - fprintf(stderr, "proc_id = %d, death_action = %d\n", proc->proc_id, - proc->death_action); -} -#endif - -static SpadProcess * -find_child(int proc_id) -{ - SpadProcess *proc; - for(proc = spad_process_list; proc != NULL; proc = proc->next) - if (proc->proc_id == proc_id) return proc; - return NULL; -} - -static void -kill_all_children(void) -{ - char name[256]; - SpadProcess *proc; - - - for(proc = spad_process_list; proc != NULL; proc = proc->next) { - kill(proc->proc_id, SIGTERM); - } - sprintf(name, "/tmp/hyper%d.input",server_num); - unlink(name); - -} - -static void -monitor_children(void) -{ - int dead_baby, stat; - SpadProcess *proc; - while (1) { - stat = 0; - dead_baby = wait(&stat); - /* Check the value of dead_baby, since wait may have returned - a pid but subsequently we have received a signal. Yeuch! */ - if (dead_baby == -1 && death_signal) { - kill_all_children(); - clean_up_sockets(); - openaxiom_sleep(2); - exit(0); - } - - if (dead_baby == -1) { - fprintf(stderr, "sman: wait returned -1\n"); - continue; - } - proc = find_child(dead_baby); - if (proc == NULL) { - /* fprintf(stderr, "sman: %d is not known to be a child process\n", - dead_baby); - */ - continue; - } - switch(proc->death_action) { - case Die: - kill_all_children(); - clean_up_sockets(); - openaxiom_sleep(2); - exit(0); - case NadaDelShitsky: - break; - case DoItAgain: - spawn_of_hell(proc->command, DoItAgain); - break; - case CleanHypertexSocket: - clean_hypertex_socket(); - break; - } - } -} - -int -main(int argc, char *argv[]) -{ - Command command; - command.root_dir = get_systemdir(argc, argv); - process_options(&command, argc, argv); - - oa_setenv("LC_ALL", "C"); - setlocale(LC_ALL, ""); - bsdSignal(SIGINT, SIG_IGN,RestartSystemCalls); - init_term_io(); - spad_process_list = NULL; - start_the_Axiom(&command); - if (open_server(SessionIOName) == -2) { - fprintf(stderr, "Fatal error opening I/O socket\n"); - clean_up_sockets(); - exit(-1); - } - start_the_session_manager(); - if (start_spadclient) - start_the_spadclient(); - if (start_local_spadclient) - start_the_local_spadclient(); - if (start_ht and in_X()) - start_the_hypertex(&command); - if (start_graphics and in_X()) - start_the_graphics(&command); - openaxiom_sleep(1); - - if (fork_you(Die) != NULL) { - sman_catch_signals(); - monitor_children(); - exit(0); - } - manage_spad_io(ptcNum); - return(0); -} - - diff --git a/src/sman/sman.cc b/src/sman/sman.cc new file mode 100644 index 00000000..ac941266 --- /dev/null +++ b/src/sman/sman.cc @@ -0,0 +1,794 @@ +/* + Copyright (c) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2014, 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "open-axiom.h" +#include "sockio.h" +#include "com.h" +#include "bsdsignal.h" +#include "sman.h" + +#include "sockio.h" +#include "openpty.h" +#include "cfuns.h" + +using namespace OpenAxiom; + +static void process_arguments(Command*, int, char**); +static int in_X(void); +static void set_up_defaults(void); +static void process_options(Command*, int, char**); +static void death_handler(int); +static void sman_catch_signals(void); +static void fix_env(int); +static void init_term_io(void); +static const char* strPrefix(const char* , const char*); +static void check_spad_proc(const char* , const char*); +static void clean_up_old_sockets(void); +static SpadProcess* fork_you(int); +static void exec_command_env(const char*); +static SpadProcess* spawn_of_hell(const char* , int); +static void start_the_spadclient(void); +static void start_the_local_spadclient(void); +static void start_the_session_manager(void); +static void start_the_hypertex(Command*); +static void start_the_graphics(Command*); +static void fork_Axiom(Command*); +static void start_the_Axiom(Command*); +static void clean_up_sockets(void); +static void clean_hypertex_socket(void); +static void read_from_spad_io(int); +static void read_from_manager(int); +static void manage_spad_io(int); +static SpadProcess* find_child(int); +static void kill_all_children(void); +static void monitor_children(void); + +/* System defined pointer to array or environment variables. */ +extern char** environ; + +int start_clef; /* start clef under spad */ +int start_graphics; /* start the viewman */ +int start_ht; /* start hypertex */ +int start_spadclient; /* Start the client spad buffer */ +int start_local_spadclient; /* Start the client spad buffer */ +int use_X; /* Use the X windows environment */ +int server_num; /* OpenAxiom server number */ + +/************************************************/ +/* definitions of programs which sman can start */ +/************************************************/ + +const char *GraphicsProgram = "/lib/viewman"; +const char *HypertexProgram = "/lib/hypertex"; +const char *ClefProgram = "$AXIOM/bin/clef -f $AXIOM/lib/command.list -e "; +const char *SessionManagerProgram = "$AXIOM/lib/session"; +const char *SpadClientProgram = "$AXIOM/lib/spadclient"; +char *PasteFile = NULL; +char *MakeRecordFile = NULL; +char *VerifyRecordFile = NULL; + +SpadProcess *spad_process_list = NULL; +/***************************/ +/* sman defaults file name */ +/***************************/ + +#define SpadDefaultFile "spadprof.input" + +char ClefCommandLine[256]; + +#define BufSize 4096 /* size of communication buffer */ +char big_bad_buf[BufSize]; /* big I/O buffer */ + +openaxiom_sio* session_io = NULL; /* socket connecting to session manager */ + +/***********************************************************/ +/* Some characters used and externally defined in edible.h */ +/***********************************************************/ + +unsigned char _INTR, _QUIT, _ERASE, _KILL, _EOF, _EOL, _RES1, _RES2; + +/*************************************/ +/* Stuff for opening pseudo-terminal */ +/*************************************/ + +int ptsNum, ptcNum; +char ptsPath[20]; + +int child_pid; /* child's process id */ +struct termios oldbuf; /* the original settings */ +struct termios childbuf; /* terminal structure for user i/o */ + + +int death_signal = 0; + +static void +process_arguments(Command* command, int argc,char ** argv) +{ + int arg; + int other = 0; + for (arg = 1; arg < argc; arg++) { + if (strcmp(argv[arg], "-noclef") == 0) + start_clef = 0; + else if (strcmp(argv[arg], "-clef") == 0) + start_clef = 1; + else if (strcmp(argv[arg], "-gr") == 0 + || strcmp(argv[arg], "--graph") == 0 ) { + if (!OPENAXIOM_HAVE_GRAPHICS) + fprintf(stderr, "OpenAxiom was not build with Graphics support.\n"); + else + start_graphics = 1; + } + else if (strcmp(argv[arg], "-nogr") == 0 + || strcmp(argv[arg], "--no-graph") == 0) + start_graphics = 0; + else if (strcmp(argv[arg], "-ht") == 0 + || strcmp(argv[arg], "--hyperdoc") == 0) { + if (!OPENAXIOM_HAVE_GRAPHICS) + fprintf(stderr, "OpenAxiom was not build with HyperDoc support.\n"); + else + start_ht = 1; + } + else if (strcmp(argv[arg], "-noht") == 0 + || strcmp(argv[arg], "--no-hyperdoc") == 0) + start_ht = 0; + else if (strcmp(argv[arg], "-iw") == 0) + start_spadclient = 1; + else if (strcmp(argv[arg], "-ihere") == 0) + start_local_spadclient = 1; + else if (strcmp(argv[arg], "-noihere") == 0) + start_local_spadclient = 0; + else if (strcmp(argv[arg], "-noiw") == 0) + start_spadclient = 0; + else if (strcmp(argv[arg], "-nox") == 0 + || strcmp(argv[arg], "--no-gui") == 0) { + use_X = 0; + start_local_spadclient = 1; + start_spadclient = 0; + start_ht = 0; + start_graphics = 0; + } + else if (strcmp(argv[arg], "-clefprog") == 0) { + strcpy(ClefCommandLine,argv[++arg]); + ClefProgram = + strcat(ClefCommandLine, " -f $AXIOM/lib/command.list -e "); + } + else if (strcmp(argv[arg], "-rm") == 0) + MakeRecordFile = argv[++arg]; + else if (strcmp(argv[arg], "-rv") == 0) + VerifyRecordFile = argv[++arg]; + else if (strcmp(argv[arg], "-paste") == 0) + PasteFile = argv[++arg]; + else + argv[other++] = argv[arg]; + } + + command->core.argv = argv; + command->core.argc = other; + +/* If there were no X libraries + * at build-time, we proceed to + * overwrite the defaults startup + * values to not start any of the + * graphical components of + * OpenAxiom (Hyperdoc, Graphics). */ + + if (!OPENAXIOM_HAVE_GRAPHICS) { + use_X = 0; + start_local_spadclient = 1; + start_ht = 0; + start_graphics = 0; + } +} + +static int +in_X(void) +{ + if (oa_getenv("DISPLAY")) return 1; + return 0; +} + +static void +set_up_defaults(void) +{ + start_clef = 1; + start_graphics = 1; + start_ht = 1; + start_spadclient = 0; + start_local_spadclient = 1; + use_X = isatty(0) && in_X(); +} + +static void +process_options(Command* command, int argc, char **argv) +{ + set_up_defaults(); + process_arguments(command, argc, argv); + /* Complain about command line arguments unknown to Superman. */ + if (command->core.argc > 0) { + int i; + for (i = 0; i < command->core.argc; ++i) + fprintf(stderr,"command line error: %s\n", command->core.argv[i]); + exit(-1); + } +} + +static void +death_handler(int sig) +{ + death_signal = 1; +} + +static void +sman_catch_signals(void) +{ + + /* Set up the signal handlers for sman */ + bsdSignal(SIGINT, SIG_IGN,RestartSystemCalls); + bsdSignal(SIGTERM, death_handler,RestartSystemCalls); + bsdSignal(SIGQUIT, death_handler,RestartSystemCalls); + bsdSignal(SIGHUP, death_handler,RestartSystemCalls); + bsdSignal(SIGILL, death_handler,RestartSystemCalls); + bsdSignal(SIGTRAP, death_handler,RestartSystemCalls); + +#ifdef SIGABRT + bsdSignal(SIGABRT, death_handler,RestartSystemCalls); +#else + #ifdef SIGIOT + bsdSignal(SIGIOT, death_handler,RestartSystemCalls); + #endif +#endif + + bsdSignal(SIGBUS, death_handler,RestartSystemCalls); + bsdSignal(SIGSEGV, death_handler,RestartSystemCalls); + +} + +static void +fix_env(int spadnum) +{ + char sn[20]; + sprintf(sn, "%d", spadnum); + oa_setenv("SPADNUM", sn); + oa_setenv("SPADSERVER", "TRUE"); +} + +static void +init_term_io(void) +{ + if(!isatty(0)) return; + if( tcgetattr(0, &oldbuf) == -1) { + perror("getting termios"); + return ; /* exit(-1); */ + } + if( tcgetattr(0, &childbuf) == -1) { + perror("getting termios"); + return ; /* exit(-1); */ + } + _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]; +} + +static const char* +strPrefix(const char* prefix, const char* s) +{ + while (*prefix != '\0' && *prefix == *s) { + prefix++; + s++; + } + if (*prefix == '\0') return s; + return NULL; +} + +static void +check_spad_proc(const char *file, const char *prefix) +{ + const char *num; + int pid; + if ((num = strPrefix(prefix, file))) { + pid = atoi(num); + if (pid > 2) { + kill(pid, 0); + if (kill(pid, 0) == -1 && errno == ESRCH) { + unlink(file); + } + } + } +} + +static void +clean_up_old_sockets(void) +{ + char com[512], tmp_file[128]; + FILE *file; + int len; + sprintf(tmp_file, "/tmp/socks.%d", server_num); + sprintf(com, "ls /tmp/.d* /tmp/.s* /tmp/.i* /tmp/.h* 2> %s > %s", + tmp_file, tmp_file); + system(com); + file = fopen(tmp_file, "r"); + if (file == NULL) { + fprintf(stderr, "Can't open socket listing file\n"); + return; + } + while(fgets(com, 512, file) != NULL) { + len = strlen(com); + if (len) com[len-1] = '\0'; + else break; + check_spad_proc(com, "/tmp/.d"); + check_spad_proc(com, "/tmp/.s"); + check_spad_proc(com, "/tmp/.i"); + check_spad_proc(com, "/tmp/.h"); + } + fclose(file); + unlink(tmp_file); +} + +static SpadProcess * +fork_you(int death_action) +{ + /* fork a new process, giving it a default death action */ + /* return NULL in child, SpadProcess in parent */ + int child_pid = fork(); + SpadProcess *proc; + if (!child_pid) return NULL; + proc = (SpadProcess *) malloc(sizeof(SpadProcess)); + proc->proc_id = child_pid; + proc->death_action = death_action; + proc->command = NULL; + proc->next = spad_process_list; + spad_process_list = proc; + return proc; +} + +static void +exec_command_env(const char *command) +{ + char new_command[512]; + sprintf(new_command, "exec %s", command); + execle("/bin/sh","/bin/sh", "-c", new_command, (char*)NULL, environ); +} + +static SpadProcess * +spawn_of_hell(const char *command, int death_action) +{ + SpadProcess *proc = fork_you(death_action); + if (proc != NULL) { + proc->command = command; + return proc; + } + exec_command_env(command); + return NULL; +} + +static void +start_the_spadclient(void) +{ + char command[256]; + if (start_clef) + sprintf(command, + "xterm -sb -sl 500 -name axiomclient -n OpenAxiom -T OpenAxiom -e %s %s", + ClefProgram, SpadClientProgram); + else + sprintf(command, + "xterm -sb -sl 500 -name axiomclient -n OpenAxiom -T OpenAxiom -e %s", + SpadClientProgram); + spawn_of_hell(command, NadaDelShitsky); +} + +static void +start_the_local_spadclient(void) +{ + char command[256]; + if (start_clef) + sprintf(command, "%s %s", ClefProgram, SpadClientProgram); + else + sprintf(command, "%s", SpadClientProgram); + spawn_of_hell(command, NadaDelShitsky); +} + +static void +start_the_session_manager(void) +{ + spawn_of_hell(SessionManagerProgram, Die); +} + +static void +start_the_hypertex(Command* cmd) +{ + const char* root_dir = cmd->root_dir; + const char* command = oa_concatenate_string(root_dir,HypertexProgram); + + if (readablep(command) != 1) { + fprintf(stderr, "Hypertex program not found.\n"); + return; + } + if (PasteFile){ + command = oa_concatenate_string(command, " -s -k -ip "); + command = oa_concatenate_string(command, PasteFile); + spawn_of_hell(command, NadaDelShitsky); + } + else if (MakeRecordFile){ + command = oa_concatenate_string(command, " -s -k -rm "); + command = oa_concatenate_string(command, MakeRecordFile); + spawn_of_hell(command, NadaDelShitsky); + } + else if (VerifyRecordFile){ + command = oa_concatenate_string(command, " -s -k -rv "); + command = oa_concatenate_string(command, VerifyRecordFile); + spawn_of_hell(command, NadaDelShitsky); + } + else + spawn_of_hell(command, CleanHypertexSocket); +} + +static void +start_the_graphics(Command* cmd) +{ + const char* root_dir = cmd -> root_dir; + const char* command = oa_concatenate_string(root_dir,GraphicsProgram); + + if (readablep(command) == 1) + spawn_of_hell(command, DoItAgain); + else + fprintf(stderr, "Graphics program not found.\n"); +} + +/* Start the core executable session in a separate process, */ +/* using a pseudo-terminal to catch all input and output */ +static void +fork_Axiom(Command* cmd) +{ + SpadProcess *proc; + + proc = fork_you(Die); + child_pid = (proc == NULL ? 0 : proc->proc_id); + switch(child_pid) { + case -1 : + fprintf(stderr, "Can't create a new process \n"); + exit(0); + case 0: + /* Dissasociate from my parents group so all my child processes */ + /* look at my terminal as the controlling terminal for the */ + /* group */ + + if(setsid() < 0) { + perror("Dissassociating from parents group"); + exit(-1); + } + + close(ptsNum); + /* Now reopen the server side, so that pg, su, etc. work properly */ + + if ((ptsNum = open(ptsPath, O_RDWR)) < 0 ) { + perror("fork_Axiom: Failed to reopen server"); + exit(-1); + } +#if defined(SUN4OS5platform) || defined(HP10platform) + ioctl(ptsNum,I_PUSH,"ptem"); + ioctl(ptsNum,I_PUSH,"ldterm"); +#endif + + /* since I am the child, I can close ptc, and dup pts for all its */ + /* standard descriptors */ + + if( (dup2(ptsNum, 0) == -1) || + (dup2(ptsNum, 1) == -1) || + (dup2(ptsNum, 2) == -1) ) { + perror("trying to dupe the child"); + exit(-1); + } + close(ptcNum); + close(ptsNum); + + + /* I also have to turn off echoing, since I am echoing all the */ + /* input myself */ + + childbuf.c_lflag &= ~ECHO; + if( tcsetattr(0, TCSAFLUSH, &childbuf) == -1) { + perror("setting the term buffer"); + exit(-1); + } + + /* Tell the Core that it is being invoked in server mode. */ + oa_allocate_process_argv(&cmd->core, 2); + cmd->core.argv[0] = (char*) make_path_for(cmd->root_dir, Driver::core); + cmd->core.argv[1] = (char*) "--role=server"; + execute_core(cmd, Driver::core); + } +} + +static void +start_the_Axiom(Command* cmd) +{ + server_num = make_server_number(); + clean_up_old_sockets(); + if (server_num == -1) { + fprintf(stderr, "could not get an OpenAxiom server number\n"); + exit(-1); + } + if (ptyopen(&ptcNum, &ptsNum, ptsPath) == -1) { + perror("start_the_Axiom: ptyopen failed"); + exit(-1); + } + fix_env(server_num); + fork_Axiom(cmd); + close(ptsNum); +} + +static void +clean_hypertex_socket(void) +{ + char name[256]; + sprintf(name, "%s%d", MenuServerName, server_num); + unlink(name); +} + +static void +clean_up_sockets(void) +{ + char name[256]; + sprintf(name, "%s%d", SpadServer, server_num); + unlink(name); + sprintf(name, "%s%d", SessionServer, server_num); + unlink(name); + sprintf(name, "%s%d", SessionIOName, server_num); + unlink(name); + clean_hypertex_socket(); +} + +static void +read_from_spad_io(int ptcNum) +{ + int ret_code = 0, i=0; + static int mes_len =0; + ret_code = read(ptcNum, big_bad_buf, BufSize); + if (ret_code == -1) { + clean_up_sockets(); + exit(-1); + } + if (session_io == NULL) { + if (ret_code < mes_len) + mes_len -= ret_code; + else { + if (mes_len > 0) { + i = mes_len; + mes_len = 0; + } + else + i = 0; + ret_code = write(1, big_bad_buf+i, ret_code-i); + } + } + else + ret_code = swrite(session_io, byte_address(big_bad_buf), ret_code, + "writing to session man"); + if (ret_code == -1) { + perror("writing output to session manager"); + clean_up_sockets(); + exit(-1); + } +} + +static void +read_from_manager(int ptcNum) +{ + int ret_code; + ret_code = sread(session_io, byte_address(big_bad_buf), BufSize, + "reading session io"); + if (ret_code == -1) { + return; + } + ret_code = write(ptcNum, big_bad_buf, ret_code); + if (ret_code == -1) { + return; + } +} + +static void +manage_spad_io(int ptcNum) +{ + int ret_code, p; + fd_set rd; + while (1) { + rd = socket_mask; + FD_SET(ptcNum, &rd); + if (session_io != NULL) + FD_SET(session_io->socket, &rd); + ret_code = sselect(FD_SETSIZE, &rd, 0, 0, NULL); + if (ret_code == -1) { + perror("Session manager select"); + clean_up_sockets(); + exit(-1); + } + if (FD_ISSET(ptcNum, &rd)) { + read_from_spad_io(ptcNum); + } + if (server.socket > 0 && FD_ISSET(server.socket, &rd)) { + p = accept_connection(); + switch(p) { + case SessionIO: + session_io = purpose_table[SessionIO]; + /* printf("connected session manager\n\r");*/ + printf("\n"); + break; + default: + printf("sman: Unknown connection request type: %d\n", p); + break; + } + } + if (session_io != NULL && FD_ISSET(session_io->socket, &rd)) { + read_from_manager(ptcNum); + } + } +} + +#if 0 +static void +print_spad_process_list() +{ + SpadProcess *proc; + for(proc = spad_process_list; proc != NULL; proc = proc->next) + fprintf(stderr, "proc_id = %d, death_action = %d\n", proc->proc_id, + proc->death_action); +} +#endif + +static SpadProcess * +find_child(int proc_id) +{ + SpadProcess *proc; + for(proc = spad_process_list; proc != NULL; proc = proc->next) + if (proc->proc_id == proc_id) return proc; + return NULL; +} + +static void +kill_all_children(void) +{ + char name[256]; + SpadProcess *proc; + + + for(proc = spad_process_list; proc != NULL; proc = proc->next) { + kill(proc->proc_id, SIGTERM); + } + sprintf(name, "/tmp/hyper%d.input",server_num); + unlink(name); + +} + +static void +monitor_children(void) +{ + int dead_baby, stat; + SpadProcess *proc; + while (1) { + stat = 0; + dead_baby = wait(&stat); + /* Check the value of dead_baby, since wait may have returned + a pid but subsequently we have received a signal. Yeuch! */ + if (dead_baby == -1 && death_signal) { + kill_all_children(); + clean_up_sockets(); + openaxiom_sleep(2); + exit(0); + } + + if (dead_baby == -1) { + fprintf(stderr, "sman: wait returned -1\n"); + continue; + } + proc = find_child(dead_baby); + if (proc == NULL) { + /* fprintf(stderr, "sman: %d is not known to be a child process\n", + dead_baby); + */ + continue; + } + switch(proc->death_action) { + case Die: + kill_all_children(); + clean_up_sockets(); + openaxiom_sleep(2); + exit(0); + case NadaDelShitsky: + break; + case DoItAgain: + spawn_of_hell(proc->command, DoItAgain); + break; + case CleanHypertexSocket: + clean_hypertex_socket(); + break; + } + } +} + +int +main(int argc, char *argv[]) +{ + Command command; + command.root_dir = get_systemdir(argc, argv); + process_options(&command, argc, argv); + + oa_setenv("LC_ALL", "C"); + setlocale(LC_ALL, ""); + bsdSignal(SIGINT, SIG_IGN,RestartSystemCalls); + init_term_io(); + spad_process_list = NULL; + start_the_Axiom(&command); + if (open_server(SessionIOName) == -2) { + fprintf(stderr, "Fatal error opening I/O socket\n"); + clean_up_sockets(); + exit(-1); + } + start_the_session_manager(); + if (start_spadclient) + start_the_spadclient(); + if (start_local_spadclient) + start_the_local_spadclient(); + if (start_ht and in_X()) + start_the_hypertex(&command); + if (start_graphics and in_X()) + start_the_graphics(&command); + openaxiom_sleep(1); + + if (fork_you(Die) != NULL) { + sman_catch_signals(); + monitor_children(); + exit(0); + } + manage_spad_io(ptcNum); + return(0); +} + + diff --git a/src/sman/spadclient.c b/src/sman/spadclient.c deleted file mode 100644 index 85b8815e..00000000 --- a/src/sman/spadclient.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. - All rights reserved. - Copyright (C) 2007-2009, 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 _SPADCLIENT_C - -#include -#include -#include - -#include "openaxiom-c-macros.h" -#include "sockio.h" -#include "com.h" -#include "bsdsignal.h" -#include "cfuns.h" -#include - -#include "sockio.h" - -using namespace OpenAxiom; - -openaxiom_sio* sock; - -static void -inter_handler(int sig) -{ - send_signal(sock, SIGUSR2); - fflush(stderr); -} - - -int -main(void) -{ - using namespace OpenAxiom; - oa_setenv("LC_ALL", "C"); - setlocale(LC_ALL, ""); - sock = connect_to_local_server(SessionServer, InterpWindow, Forever); - bsdSignal(SIGINT, inter_handler,RestartSystemCalls); - remote_stdio(sock); - return(0); -} - diff --git a/src/sman/spadclient.cc b/src/sman/spadclient.cc new file mode 100644 index 00000000..029d354a --- /dev/null +++ b/src/sman/spadclient.cc @@ -0,0 +1,74 @@ +/* + Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. + All rights reserved. + Copyright (C) 2007-2009, 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 _SPADCLIENT_C + +#include +#include +#include + +#include "sockio.h" +#include "com.h" +#include "bsdsignal.h" +#include "cfuns.h" +#include + +#include "sockio.h" + +using namespace OpenAxiom; + +openaxiom_sio* sock; + +static void +inter_handler(int sig) +{ + send_signal(sock, SIGUSR2); + fflush(stderr); +} + + +int +main(void) +{ + using namespace OpenAxiom; + oa_setenv("LC_ALL", "C"); + setlocale(LC_ALL, ""); + sock = connect_to_local_server(SessionServer, InterpWindow, Forever); + bsdSignal(SIGINT, inter_handler,RestartSystemCalls); + remote_stdio(sock); + return(0); +} + diff --git a/src/utils/command.cc b/src/utils/command.cc index 55716bc1..b0419a99 100644 --- a/src/utils/command.cc +++ b/src/utils/command.cc @@ -234,9 +234,10 @@ build_rts_options(Command* command, Driver driver) break; case Runtime::ecl: - command->rt_args.allocate(2); + command->rt_args.allocate(3); command->rt_args[0] = (char*) "-q"; - command->rt_args[1] = (char*) "-norc"; + command->rt_args[1] = (char*) "--nodebug"; + command->rt_args[1] = (char*) "--norc"; break; default: diff --git a/src/utils/hammer.cc b/src/utils/hammer.cc index 003cd1f8..36193c0b 100644 --- a/src/utils/hammer.cc +++ b/src/utils/hammer.cc @@ -152,7 +152,7 @@ namespace OpenAxiom::Hammer { CompositeText prose; // the prose around the chunks. ChunkTable defs; // chunk definition table. CompositeText* active_chunk; // chunk under construction. - const char8_t* text_start; // begining of current basic text. + const char8_t* text_start; // beginning of current basic text. // Append basic text in the range `[text_start,last)' // to the current chunk. diff --git a/src/utils/storage.cxx b/src/utils/storage.cxx index 98b0a27f..a2eb2919 100644 --- a/src/utils/storage.cxx +++ b/src/utils/storage.cxx @@ -31,6 +31,10 @@ // --%: Gabriel Dos Reis. +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #ifdef HAVE_SYS_TYPES_H @@ -56,6 +60,14 @@ #include #include +#if HAVE_DECL_MAP_ANONYMOUS +# define OPENAXIOM_MM_ANONYMOUS_MAP_FLAG MAP_ANONYMOUS +#elif HAVE_DECL_MAP_ANON +# define OPENAXIOM_MM_ANONYMOUS_MAP_FLAG MAP_ANON +#else +# error MAP_ANONYMOUS or MAP_ANON must be defined +#endif + namespace OpenAxiom { // ---------------- // -- SystemError -- -- cgit v1.2.3