summaryrefslogtreecommitdiffstats
path: root/contrib/ee
diff options
context:
space:
mode:
authored <ed@FreeBSD.org>2009-05-26 20:13:17 +0000
committered <ed@FreeBSD.org>2009-05-26 20:13:17 +0000
commitfbad22d013baa1ed80ce29fd090be19e99ed314c (patch)
tree802aed2d76270bc9fee21713d1e79973febde177 /contrib/ee
parent6cf142b7b439d69ca0ee2ce20e9551f628a65110 (diff)
parentcd2cd8f376f2d165e207cc5b80154f80bffbac4d (diff)
downloadFreeBSD-src-fbad22d013baa1ed80ce29fd090be19e99ed314c.zip
FreeBSD-src-fbad22d013baa1ed80ce29fd090be19e99ed314c.tar.gz
Copy ee 1.4.2 into the contrib directory.
This allows me to merge our custom changes to ee(1) back on top of original sources, with correct mergeinfo.
Diffstat (limited to 'contrib/ee')
-rw-r--r--contrib/ee/Artistic117
-rwxr-xr-xcontrib/ee/Makefile29
-rw-r--r--contrib/ee/README.ee116
-rwxr-xr-xcontrib/ee/create.make268
-rw-r--r--contrib/ee/ee.1539
-rwxr-xr-xcontrib/ee/ee.c5268
-rw-r--r--contrib/ee/ee.i18n.guide158
-rw-r--r--contrib/ee/ee.msg185
-rwxr-xr-xcontrib/ee/genstr32
-rw-r--r--contrib/ee/make.default57
-rw-r--r--contrib/ee/new_curse.c3813
-rw-r--r--contrib/ee/new_curse.h260
12 files changed, 10842 insertions, 0 deletions
diff --git a/contrib/ee/Artistic b/contrib/ee/Artistic
new file mode 100644
index 0000000..fbf7989
--- /dev/null
+++ b/contrib/ee/Artistic
@@ -0,0 +1,117 @@
+
+
+
+
+ The "Artistic License"
+
+ Preamble
+
+The intent of this document is to state the conditions under which a
+Package may be copied, such that the Copyright Holder maintains some
+semblance of artistic control over the development of the package,
+while giving the users of the package the right to use and distribute
+the Package in a more-or-less customary fashion, plus the right to make
+reasonable modifications.
+
+Definitions:
+
+ "Package" refers to the collection of files distributed by the
+ Copyright Holder, and derivatives of that collection of files
+ created through textual modification.
+
+ "Standard Version" refers to such a Package if it has not been
+ modified, or has been modified in accordance with the wishes
+ of the Copyright Holder.
+
+ "Copyright Holder" is whoever is named in the copyright or
+ copyrights for the package.
+
+ "You" is you, if you're thinking about copying or distributing
+ this Package.
+
+ "Reasonable copying fee" is whatever you can justify on the
+ basis of media cost, duplication charges, time of people involved,
+ and so on. (You will not be required to justify it to the
+ Copyright Holder, but only to the computing community at large
+ as a market that must bear the fee.)
+
+ "Freely Available" means that no fee is charged for the item
+ itself, though there may be fees involved in handling the item.
+ It also means that recipients of the item may redistribute it
+ under the same conditions they received it.
+
+1. You may make and give away verbatim copies of the source form of the
+Standard Version of this Package without restriction, provided that you
+duplicate all of the original copyright notices and associated disclaimers.
+
+2. You may apply bug fixes, portability fixes and other modifications
+derived from the Public Domain or from the Copyright Holder. A Package
+modified in such a way shall still be considered the Standard Version.
+
+3. You may otherwise modify your copy of this Package in any way, provided
+that you insert a prominent notice in each changed file stating how and
+when you changed that file, and provided that you do at least ONE of the
+following:
+
+ a) place your modifications in the Public Domain or otherwise make them
+ Freely Available, such as by posting said modifications to Usenet or
+ an equivalent medium, or placing the modifications on a major archive
+ site such as uunet.uu.net, or by allowing the Copyright Holder to include
+ your modifications in the Standard Version of the Package.
+
+ b) use the modified Package only within your corporation or organization.
+
+ c) rename any non-standard executables so the names do not conflict
+ with standard executables, which must also be provided, and provide
+ a separate manual page for each non-standard executable that clearly
+ documents how it differs from the Standard Version.
+
+ d) make other distribution arrangements with the Copyright Holder.
+
+4. You may distribute the programs of this Package in object code or
+executable form, provided that you do at least ONE of the following:
+
+ a) distribute a Standard Version of the executables and library files,
+ together with instructions (in the manual page or equivalent) on where
+ to get the Standard Version.
+
+ b) accompany the distribution with the machine-readable source of
+ the Package with your modifications.
+
+ c) accompany any non-standard executables with their corresponding
+ Standard Version executables, giving the non-standard executables
+ non-standard names, and clearly documenting the differences in manual
+ pages (or equivalent), together with instructions on where to get
+ the Standard Version.
+
+ d) make other distribution arrangements with the Copyright Holder.
+
+5. You may charge a reasonable copying fee for any distribution of this
+Package. You may charge any fee you choose for support of this Package.
+You may not charge a fee for this Package itself. However,
+you may distribute this Package in aggregate with other (possibly
+commercial) programs as part of a larger (possibly commercial) software
+distribution provided that you do not advertise this Package as a
+product of your own.
+
+6. The scripts and library files supplied as input to or produced as
+output from the programs of this Package do not automatically fall
+under the copyright of this Package, but belong to whomever generated
+them, and may be sold commercially, and may be aggregated with this
+Package.
+
+7. C subroutines supplied by you and linked into this Package in order
+to emulate subroutines and variables of the language defined by this
+Package shall not be considered part of this Package, but are the
+equivalent of input as in Paragraph 6, provided these subroutines do
+not change the language in any way that would cause it to fail the
+regression tests for the language.
+
+8. The name of the Copyright Holder may not be used to endorse or promote
+products derived from this software without specific prior written permission.
+
+9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+ The End
diff --git a/contrib/ee/Makefile b/contrib/ee/Makefile
new file mode 100755
index 0000000..a6525ea
--- /dev/null
+++ b/contrib/ee/Makefile
@@ -0,0 +1,29 @@
+# This is the make file for ee, the "easy editor".
+#
+# A file called 'make.local' will be generated which will contain information
+# specific to the local system, such as if it is a BSD or System V based
+# version of UNIX, whether or not it has catgets, or select.
+#
+# The "install" target ("make install") will copy the ee binary to
+# the /usr/local/bin directory on the local system. The man page (ee.1)
+# will be copied into the /usr/local/man/man1 directory.
+#
+# The "clean" target ("make clean") will remove the ee and new_curse.o
+# object files, and the ee binary.
+#
+
+all : localmake buildee
+
+buildee :
+ make -f make.local
+
+localmake:
+ @./create.make
+
+install :
+ cp ee /usr/local/bin/ee
+ cp ee.1 /usr/local/man/man1/ee.1
+
+clean :
+ rm -f ee.o new_curse.o ee
+
diff --git a/contrib/ee/README.ee b/contrib/ee/README.ee
new file mode 100644
index 0000000..8850af2
--- /dev/null
+++ b/contrib/ee/README.ee
@@ -0,0 +1,116 @@
+ THIS MATERIAL IS PROVIDED "AS IS". THERE ARE NO WARRANTIES OF
+ ANY KIND WITH REGARD TO THIS MATERIAL, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS FOR A PARTICULAR PURPOSE. Neither Hewlett-Packard nor
+ Hugh Mahon shall be liable for errors contained herein, nor for
+ incidental or consequential damages in connection with the
+ furnishing, performance or use of this material. Neither
+ Hewlett-Packard nor Hugh Mahon assumes any responsibility for
+ the use or reliability of this software or documentation. This
+ software and documentation is totally UNSUPPORTED. There is no
+ support contract available. Hewlett-Packard has done NO
+ Quality Assurance on ANY of the program or documentation. You
+ may find the quality of the materials inferior to supported
+ materials.
+
+ This software may be distributed under the terms of Larry Wall's
+ Artistic license, a copy of which is included in this distribution.
+
+ This notice must be included with this software and any
+ derivatives.
+
+ Any modifications to this software by anyone but the original author
+ must be so noted.
+
+
+The editor 'ee' (easy editor) is intended to be a simple, easy to use
+terminal-based screen oriented editor that requires no instruction to
+use. Its primary use would be for people who are new to computers, or who
+use computers only for things like e-mail.
+
+ee's simplified interface is highlighted by the use of pop-up menus which
+make it possible for users to carry out tasks without the need to
+remember commands. An information window at the top of the screen shows
+the user the operations available with control-keys.
+
+ee allows users to use full eight-bit characters. If the host system has
+the capabilities, ee can use message catalogs, which would allow users to
+translate the message catalog into other languages which use eight-bit
+characters. See the file ee.i18n.guide for more details.
+
+ee relies on the virtual memory abilities of the platform it is running on
+and does not have its own memory management capabilities.
+
+I am releasing ee because I hate to see new users and non-computer types
+get frustrated by vi, and would like to see more intuitive interfaces for
+basic tools (both character-based and graphical) become more pervasive.
+Terminal capabilities and communication speeds have evolved considerably
+since the time in which vi's interface was created, allowing much more
+intuitive interfaces to be used. Since character-based I/O won't be
+completely replaced by graphical user interfaces for at least a few more
+years, I'd like to do what I can to make using computers with less
+glamorous interfaces as easy to use as possible. If terminal interfaces
+are still used in ten years, I hope neophytes won't still be stuck with
+only vi.
+
+For a text editor to be easy to use requires a certain set of abilities. In
+order for ee to work, a terminal must have the ability to position the cursor
+on the screen, and should have arrow keys that send unique sequences
+(multiple characters, the first character is an "escape", octal code
+'\033'). All of this information needs to be in a database called "terminfo"
+(System V implementations) or "termcap" (usually used for BSD systems). In
+case the arrow keys do not transmit unique sequences, motion operations are
+mapped to control keys as well, but this at least partially defeats the
+purpose. The curses package is used to handle the I/O which deals with the
+terminal's capabilities.
+
+While ee is based on curses, I have included here the source code to
+new_curse, a subset of curses developed for use with ee. 'curses' often
+will have a defect that reduces the usefulness of the editor relying upon
+it.
+
+The file new_curse.c contains a subset of 'curses', a package for
+applications to use to handle screen output. Unfortunately, curses
+varies from system to system, so I developed new_curse to provide
+consistent behavior across systems. It works on both SystemV and BSD
+systems, and while it can sometimes be slower than other curses packages,
+it will get the information on the screen painted correctly more often
+than vendor supplied curses. Unless problems occur during the building
+of ee, it is recommended that you use new_curse rather than the curses
+supplied with your system.
+
+If you experience problems with data being displayed improperly, check
+your terminal configuration, especially if you're using a terminal
+emulator, and make sure that you are using the right terminfo entry
+before rummaging through code. Terminfo entries often contain
+inaccuracies, or incomplete information, or may not totally match the
+terminal or emulator the terminal information is being used with.
+Complaints that ee isn't working quite right often end up being something
+else (like the terminal emulator being used).
+
+Both ee and new_curse were developed using K&R C (also known as "classic
+C"), but it can also be compiled with ANSI C. You should be able to
+build ee by simply typing "make". A make file which takes into account
+the characteristics of your system will be created, and then ee will be
+built. If there are problems encountered, you will be notified about
+them.
+
+ee is the result of several conflicting design goals. While I know that it
+solves the problems of some users, I also have no doubt that some will decry
+its lack of more features. I will settle for knowing that ee does fulfill
+the needs of a minority (but still large number) of users. The goals of ee
+are:
+
+ 1. To be so easy to use as to require no instruction.
+ 2. To be easy to compile and, if necessary, port to new platforms
+ by people with relatively little knowledge of C and UNIX.
+ 3. To have a minimum number of files to be dealt with, for compile
+ and installation.
+ 4. To have enough functionality to be useful to a large number of
+ people.
+
+Hugh Mahon |___|
+h_mahon@fc.hp.com | |
+ |\ /|
+ | \/ |
+
diff --git a/contrib/ee/create.make b/contrib/ee/create.make
new file mode 100755
index 0000000..dcf3e38
--- /dev/null
+++ b/contrib/ee/create.make
@@ -0,0 +1,268 @@
+#!/bin/sh
+
+#
+# This script will determine if the system is a System V or BSD based
+# UNIX system and create a makefile for ee appropriate for the system.
+#
+# $Header: /home/hugh/sources/old_ae/RCS/create.make,v 1.7 2001/01/20 04:57:17 hugh Exp hugh $
+#
+
+# test for existence of termcap (exists on both BSD and SysV systems)
+
+if [ -f /etc/termcap -o -f /usr/share/lib/termcap -o -f /usr/share/misc/termcap ]
+then
+ termcap_exists="TRUE"
+else
+ termcap_exists=""
+fi
+
+# test for terminfo directory (exists on SysV systems)
+
+if [ -d /usr/lib/terminfo -o -d /usr/share/lib/terminfo -o -d /usr/share/terminfo ]
+then
+ terminfo_exists=""
+else
+ terminfo_exists="-DCAP"
+fi
+
+# test for existence of termio header (on SysV systems)
+
+if [ -f /usr/include/termio.h ]
+then
+ termio="-DSYS5"
+else
+ termio=""
+fi
+
+# test for sgtty header (on BSD systems)
+
+if [ -f /usr/include/sgtty.h ]
+then
+ sgtty="TRUE"
+else
+ sgtty=""
+fi
+
+# look for select call in headers, make sure headers exist
+
+HEADER_FILES=""
+
+if [ -f /usr/include/sys/time.h ]
+then
+ HEADER_FILES="/usr/include/sys/time.h "
+fi
+
+if [ -f /usr/include/sys/types.h ]
+then
+ HEADER_FILES="$HEADER_FILES /usr/include/sys/types.h"
+fi
+
+# check for unistd.h
+
+if [ -f /usr/include/unistd.h ]
+then
+ HAS_UNISTD=-DHAS_UNISTD
+ HEADER_FILES="$HEADER_FILES /usr/include/unistd.h"
+else
+ HAS_UNISTD=""
+fi
+
+if [ -n "$HEADER_FILES" ]
+then
+ string="`grep select $HEADER_FILES`"
+ if [ -n "$string" ]
+ then
+ BSD_SELECT="-DBSD_SELECT"
+ else
+ BSD_SELECT=""
+ fi
+fi
+
+# check for existence of select.h (on AIX)
+
+if [ -f /usr/include/sys/select.h ]
+then
+ select_hdr="-DSLCT_HDR"
+else
+ select_hdr=""
+fi
+
+# check for stdlib.h
+
+if [ -f /usr/include/stdlib.h ]
+then
+ HAS_STDLIB=-DHAS_STDLIB
+else
+ HAS_STDLIB=""
+fi
+
+# check for stdarg.h
+
+if [ -f /usr/include/stdarg.h ]
+then
+ HAS_STDARG=-DHAS_STDARG
+else
+ HAS_STDARG=""
+fi
+
+# check for ctype.h
+
+if [ -f /usr/include/ctype.h ]
+then
+ HAS_CTYPE=-DHAS_CTYPE
+else
+ HAS_CTYPE=""
+fi
+
+# check for sys/ioctl.h
+
+if [ -f /usr/include/sys/ioctl.h ]
+then
+ HAS_SYS_IOCTL=-DHAS_SYS_IOCTL
+else
+ HAS_SYS_IOCTL=""
+fi
+
+# check for sys/wait.h
+
+if [ -f /usr/include/sys/wait.h ]
+then
+ HAS_SYS_WAIT=-DHAS_SYS_WAIT
+else
+ HAS_SYS_WAIT=""
+fi
+
+# check for localization headers
+
+if [ -f /usr/include/locale.h -a -f /usr/include/nl_types.h ]
+then
+ catgets=""
+else
+ catgets="-DNO_CATGETS"
+fi
+
+# make decisions about use of new_curse.c (use of new_curse is recommended
+# rather than local curses)
+
+if [ -n "$terminfo_exists" -a -z "$termcap_exists" ]
+then
+ echo "Neither terminfo or termcap are on this system! "
+ if [ -f /usr/include/curses.h ]
+ then
+ echo "Relying on local curses implementation."
+ else
+ cat <<-EOF
+ Don't know where to find curses, you'll need to modify
+ source code to be able to build!
+
+ Modify the file make.default and build ee by typing:
+
+ make -f make.default
+
+ EOF
+
+ exit 1
+ fi
+
+ TARGET="curses"
+ curses=""
+else
+ curses="-DNCURSE"
+ TARGET="ee"
+fi
+
+if [ -z "$termio" -a -z "$sgtty" ]
+then
+ echo "Neither termio.h or sgtty.h are on this system! "
+ if [ -f /usr/include/curses.h ]
+ then
+ echo "Relying on local curses implementation."
+ else
+ cat <<-EOF
+ Don't know where to find curses, you'll need to modify
+ source code to be able to build!
+
+ Modify the file make.default and build ee by typing:
+
+ make -f make.default
+
+ EOF
+
+ exit 1
+ fi
+
+ TARGET="curses"
+ curses=""
+fi
+
+# check if this is a SunOS system
+
+if [ -d /usr/5include ]
+then
+ five_include="-I/usr/5include"
+else
+ five_include=""
+fi
+
+if [ -d /usr/5lib ]
+then
+ five_lib="-L/usr/5lib"
+else
+ five_lib=""
+fi
+
+
+if [ -n "$CFLAGS" ]
+then
+ if [ -z "`echo $CFLAGS | grep '[-]g'`" ]
+ then
+ other_cflags="${CFLAGS} -s"
+ else
+ other_cflags="${CFLAGS}"
+ fi
+else
+ other_cflags="-s"
+fi
+
+# time to write the makefile
+
+echo "Generating make.local"
+
+if [ -f make.local ]
+then
+ mv make.local make.lcl.old
+fi
+
+echo "DEFINES = $termio $terminfo_exists $BSD_SELECT $catgets $select $curses " > make.local
+echo "" >> make.local
+echo "CFLAGS = $HAS_UNISTD $HAS_STDARG $HAS_STDLIB $HAS_CTYPE $HAS_SYS_IOCTL $HAS_SYS_WAIT $five_lib $five_include $select_hdr $other_cflags" >> make.local
+echo "" >> make.local
+echo "" >> make.local
+echo "all : $TARGET" >> make.local
+
+cat >> make.local << EOF
+
+curses : ee.c
+ cc ee.c -o ee \$(CFLAGS) -lcurses
+
+ee : ee.o new_curse.o
+ cc -o ee ee.o new_curse.o \$(CFLAGS)
+
+ee.o : ee.c new_curse.h
+ cc -c ee.c \$(DEFINES) \$(CFLAGS)
+
+new_curse.o : new_curse.c new_curse.h
+ cc new_curse.c -c \$(DEFINES) \$(CFLAGS)
+
+EOF
+
+if [ -f make.lcl.old ]
+then
+ diffs="`cmp make.lcl.old make.local`"
+ if [ -n "${diffs}" ]
+ then
+ rm -f ee.o new_curse.o ee
+ fi
+ rm -f make.lcl.old
+fi
+
diff --git a/contrib/ee/ee.1 b/contrib/ee/ee.1
new file mode 100644
index 0000000..be79cbf
--- /dev/null
+++ b/contrib/ee/ee.1
@@ -0,0 +1,539 @@
+.\"
+.\"
+.\" To format this reference page, use the command:
+.\"
+.\" nroff -man ee.1
+.\"
+.\" $Header: /home/hugh/sources/old_ae/RCS/ee.1,v 1.19 1995/11/29 04:03:15 hugh Exp hugh $
+.\"
+.\"
+.TH ee 1 "" "" "" ""
+.SH NAME
+ee \- easy editor
+.SH SYNOPSIS
+.nf
+ee [-e] [-i] [-h] [+#] [\fIfile\fR ...]
+ree [-e] [-i] [-h] [+#] [\fIfile\fR ...]
+.ta
+.fi
+.ad b
+.SH DESCRIPTION
+The command
+.I ee
+is a simple screen oriented text editor. It is always in text insertion
+mode unless there is a prompt at the bottom of the terminal, or a
+menu present (in a box in the middle of the terminal). The command
+.I ree
+is the same as
+.I ee,
+but restricted to editing the named
+file (no file operations, or shell escapes are allowed).
+.PP
+For
+.I ee
+to work properly, the environment variable
+.SM TERM
+must be set to indicate the type of terminal being used. For
+example, for an
+.SM HP 700/92
+terminal, the
+.SM TERM
+variable should be set to "70092". See your System Administrator if
+you need more information.
+.\"
+.\" options
+.\"
+.SS Options
+The following options are available from the command line:
+.PP
+.TP 4
+.B -e
+Turns off expansion of tab character to spaces.
+.TP
+.B -i
+Turns off display of information window at top of terminal.
+.TP
+.B -h
+Turns off highlighting of borders of windows and menus (improves
+performance on some terminals).
+.TP
+.B +#
+Moves the cursor to line '#' at startup.
+.br
+.\"
+.\" control keys
+.\"
+.SS "Control keys"
+To do anything other than insert text, the user must use the control
+keys (the
+.B Control
+key, represented by a "^", pressed in conjunction with an
+alphabetic key, e.g., ^a) and function keys available on the keyboard
+(such as
+.BR "Next Page" ", " "Prev Page" ,
+arrow keys, etc.).
+.PP
+Since not all terminals have function keys,
+.I ee
+has the basic cursor movement functions assigned to control keys as
+well as more intuitive keys on the keyboard when available. For
+instance, to move the cursor up, the user can use the up arrow key,
+or
+.BR ^u .
+.RS 4
+.nf
+.ta 1.4i
+.sp
+^a Prompt for the decimal value of a character to insert.
+^b Move to the bottom of the text.
+^c Get the prompt for a command.
+^d Move the cursor down.
+^e Prompt for the string to search for.
+^f Undelete the last deleted character.
+^g Move to the beginning of the line.
+^h Backspace.
+^i Tab.
+^j Insert a newline.
+^k Delete the character the cursor is sitting on.
+^l Move the cursor left.
+^m Insert a newline.
+^n Move to the next page.
+^o Move to the end of the line.
+^p Move to the previous page.
+^r Move the cursor to the right.
+^t Move to the top of the text.
+^u Move the cursor up.
+^v Undelete the last deleted word.
+^w Delete the word beginning at the cursor position.
+^x Search.
+^y Delete from the cursor position to the end of line.
+^z Undelete the last deleted line.
+^[ (ESC) Pop up menu.
+.ta
+.fi
+.RE
+.sp
+.SS "EMACS keys mode"
+.PP
+Since many shells provide an Emacs mode (for cursor movement and other editing
+operations), some bindings that may be more useful for people familiar with
+those bindings have been provided. These are accessible via the
+.B settings
+menu, or via the initialization file (see below). The mappings are as follows:
+.RS
+.nf
+.ta 1.4i
+^a Move to the beginning of the line.
+^b Back 1 character.
+^c Command prompt.
+^d Delete character the cursor is sitting on.
+^e End of line.
+^f Forward 1 character.
+^g Go back 1 page.
+^h Backspace.
+^i Tab.
+^j Undelete last deleted character.
+^k Delete line.
+^l Undelete last deleted line.
+^m Insert a newline.
+^n Move to the next line.
+^o Prompt for the decimal value of a character to insert.
+^p Previous line.
+^r Restore last deleted word.
+^t Move to the top of the text.
+^u Move to the bottom of the text.
+^v Move to the next page.
+^w Delete the word beginning at the cursor position.
+^y Prompt for the string to search for.
+^z Next word.
+^[ (ESC) Pop up menu.
+.ta
+.fi
+.RE
+.sp
+.\"
+.\" function keys
+.\"
+.SS "Function Keys"
+.RS 4
+.IP "\fBNext Page\fR"
+Move to the next page.
+.IP "\fBPrev Page\fR"
+Move to the previous page.
+.IP "\fBDelete Char\fR"
+Delete the character the cursor is on.
+.IP "\fBDelete Line\fR"
+Delete from the cursor to the end of line.
+.IP "\fBInsert line\fR"
+Insert a newline at the cursor position.
+.IP "\fBArrow keys\fR"
+Move the cursor in the direction indicated.
+.RE
+.\"
+.\" commands
+.\"
+.SS Commands
+.PP
+Some operations require more information than a single keystroke can
+provide. For the most basic operations, there is a menu that can be
+obtained by pressing the
+.SM \fBESC\fR
+key. The same operations, and more can be performed by obtaining the
+command prompt (^c) and typing in one of the commands below.
+.RS 4
+.IP "!\fBcmd\fR"
+Execute \fBcmd\fR in a shell.
+.IP "\fB0-9\fR"
+Move to the line indicated.
+.IP "\fBcase\fR"
+Make searches case sensitive.
+.IP "\fBcharacter\fR"
+Display the ascii value of the character at the cursor.
+.IP "\fBexit\fR"
+Save the edited text, and leave the editor.
+.IP "\fBexpand\fR"
+Expand tabs to spaces.
+.IP "\fBfile\fR"
+Print the name of the file.
+.IP "\fBhelp\fR"
+Display help screen.
+.IP "\fBline\fR"
+Display the current line number.
+.IP "\fBnocase\fR
+Make searches insensitive to case (the default).
+.IP "\fBnoexpand\fR"
+Don't expand tab to spaces when the TAB key is pressed.
+.IP "\fBquit\fR"
+Leave the editor without saving changes.
+.IP "\fBread\fR \fIfile\fR"
+Read the named \fIfile\fR.
+.IP "\fBwrite\fR \fIfile\fR"
+Write the text to the named \fIfile\fR.
+.RE
+.\"
+.\" menu operations
+.\"
+.SS "Menu Operations"
+.PP
+Pop-up menus can be obtained by pressing the
+.B escape
+key (or
+.B ^[
+if no
+.B escape
+key is present). When in the menu, the escape key can be
+used to leave the menu without performing any operations. Use the up and
+down arrow keys, or
+.B ^u
+for moving up and
+.B ^d
+for moving down to move to the desired items in the menu, then press
+.B return
+to perform the indicated task.
+.PP
+To the left of each menu item is a letter, which if the corresponding
+letter is pressed on the keyboard selects that menu entry.
+.PP
+The main menu in \fIee\fR is as follows:
+.RS 4
+.IP "\fBleave editor\fR"
+If changes have been made, the user will get a menu prompting whether or
+not the changes should be saved.
+.IP "\fBhelp\fR"
+Displays a help screen, with all of the keyboard operations and commands.
+.IP "\fBfile operations\fR"
+Pops up a menu for selecting whether to read a file, write to a file, or
+save the current contents of the editor, as well as send the contents of
+the editor to a print command (see the section \fBInitializing ee from a
+file\fR).
+.IP "\fBredraw screen\fR"
+Provides a means to repaint the screen if the screen has been corrupted.
+.IP "\fBsettings\fR"
+Shows the current values of the operating modes, and right margin. By
+pressing return when the cursor is on a particular item, the value can be
+changed. To leave this menu, press the \fBescape\fR key. (See \fBModes\fR
+below.)
+.IP "\fBsearch\fR"
+.br
+Pops up a menu in which the user may choose to enter a string to search
+for, or search for a string already entered.
+.IP "\fBmiscellaneous\fR"
+Pops up a menu that allows the user to format the current paragraph,
+execute a shell command, or check the spelling of the text in the editor.
+.RE
+.\"
+.\" paragraph formatting
+.\"
+.SS "Paragraph Formatting"
+.PP
+Paragraphs are defined for \fIee\fR by a block of text bounded by:
+.sp
+.RS 8
+.IP \(bu
+Begin or end of file.
+.IP \(bu
+Line with no characters, or only spaces and/or tabs.
+.IP \(bu
+Line starting with a period ('.') or right angle bracket ('>').
+.RE
+.PP
+A paragraph may be formatted two ways: explicitly by choosing the
+\fBformat paragraph\fR menu item, or by setting \fIee\fR to automatically
+format paragraphs. The automatic mode may be set via a menu, or via the
+initialization file.
+.PP
+There are three states for text operation in \fIee\fR: free-form, margins,
+and automatic formatting.
+.PP
+"Free-form" is best used for things like programming. There are no
+restrictions on the length of lines, and no formatting takes place.
+.PP
+"Margins" allows the user to type in text without having to worry about going
+beyond the right margin (the right margin may be set in the \fBsettings\fR
+menu, the default is for the margin to be the right edge of the
+terminal). This is the mode that allows the \fBformat paragraph\fR menu
+item to work.
+.PP
+"Automatic formatting" provides word-processor-like behavior. The user
+may type in text, while \fIee\fR will make sure the entire paragraph fits
+within the width of the terminal every time the user inserts a space after
+typing or deleting text. Margin observation must also be enabled in order for
+automatic formatting to occur.
+.\"
+.\" modes
+.\"
+.SS Modes
+.PP
+Although ee is a 'modeless' editor (it is in text insertion mode all the
+time), there are modes in some of the things it does. These include:
+.RS 4
+.IP "\fBtab expansion\fR"
+Tabs may be inserted as a single tab character, or replaced with spaces.
+.IP "\fBcase sensitivity\fR"
+The search operation can be sensitive to whether characters are upper- or
+lower-case, or ignore case completely.
+.IP "\fBmargins observed\fR"
+Lines can either be truncated at the right margin, or extend on forever.
+.IP "\fBauto paragraph formatting\fR"
+While typing in text, the editor can try to keep it looking reasonably well
+within the width of the screen.
+.IP "\fBeightbit characters\fR"
+Toggles whether eight bit characters are displayed as their value in angle
+brackets (e.g. "<220>") or as a character.
+.IP "\fBinfo window\fR"
+A window showing the keyboard operations that can be performed can be
+displayed or not.
+.IP "\fBemacs keys\fR"
+Control keys may be given bindings similar to emacs, or not.
+.IP "\f16 bit characters\fR"
+Toggles whether sixteen bit characters are handled as one 16-bit quantities or
+two 8-bit quantities. This works primarily with the Chinese Big 5 code set.
+.RE
+.PP
+You may set these modes via the initialization file (see below), or with a
+menu (see above).
+.\"
+.\" spell checking
+.\"
+.SS "Spell Checking"
+.PP
+There are two ways to have the spelling in the text checked from \fIee\fR.
+One is by the traditional \fIspell\fR(1) command, the other is with the
+optional \fIispell\fR(1) command.
+.PP
+Using \fIspell\fR, the words that are not recognized will be placed at the top
+of the file. For the \fIispell\fR option, the file is written to disk,
+then \fIispell\fR run on the file, and the file read back in once
+\fIispell\fR has completed making changes to the file.
+.\"
+.\" printing
+.\"
+.SS "Printing the contents of the editor"
+.PP
+The user may select a menu item which prints the contents of the editor.
+.I ee
+pipes the text in the editor to the command specified by the
+initialization command
+.B printcommand
+(see the section
+.B Initializing ee from a file
+below). The default is to send the contents to "lp".
+.PP
+Whatever the user assigns to
+.B printcommand
+must take input from
+standard input. See your system administrator for more details.
+.\"
+.\" shell operations
+.\"
+.SS "Shell operations"
+.PP
+Shell commands can be executed from within
+.I ee
+by selecting the
+.B shell command
+item in the
+.B miscellaneous
+menu, or by placing an exclamation mark ("!") before the command to
+execute at the
+.B command:
+prompt. Additionally, the user may direct the contents of the edit buffer
+out to a shell operation (via a pipe) by using the left angle bracket
+(">"), followed by a "!" and the shell command to execute. The output of
+a shell operation can also be directed into the edit buffer by using a
+right angle bracket ("<") before the exclamation mark. These can even be
+used together to send output to a shell operation and read back the
+results into the editor. So, if the editor contained a list of words
+to be sorted, they could be sorted by typing the following at the command
+prompt:
+.RS 4
+.sp
+><!sort
+.sp
+.RE
+This would send the contents of the editor to be piped into the
+.I sort
+utility and the result would be placed into the edit buffer at the current
+cursor location. The old information would have to be deleted by the user.
+.\"
+.\" initializing ee from a file
+.\"
+.SS "Initializing ee from a file"
+.PP
+Since different users have different preferences, \fIee\fR allows some
+slight configurability. There are three possible locations for an
+initialization file for ee: the file \fI/usr/local/lib/init.ee\fR, the
+file \fI.init.ee\fR in the user's home directory, or the file \fI.init.ee\fR
+in the current directory (if different from the home
+directory). This allows system administrators to set some preferences for
+the users on a system-wide basis (for example, the \fBprint\fR command),
+and the user to customize settings for particular directories (like one
+for correspondence, and a different directory for programming).
+.PP
+The file \fI\/usr/local/lib/init.ee\fR is read first, then
+\fI$HOME/.init.ee\fR, then \fI.init.ee\fR, with the settings specified by the
+most recent file read taking precedence.
+.PP
+The following items may be entered in the initialization file:
+.RS 4
+.IP \fBcase\fR
+Sets searches to be case sensitive.
+.IP \fBnocase\fR
+Sets searches to be insensitive to case (default).
+.IP \fBexpand\fR
+Causes \fIee\fR to expand tabs to spaces (default).
+.IP \fBnoexpand\fR
+Causes \fIee\fR to insert tabs as a single character.
+.IP \fBinfo\fR
+A small information window is displayed at the top of the terminal
+(default).
+.IP \fBnoinfo\fR
+Turns off the display of the information window.
+.IP \fBmargins\fR
+Causes \fIee\fR to truncate lines at the right margin when the
+cursor passes beyond the right margin as set by the user
+while text is being inserted
+(default).
+.IP \fBnomargins\fR
+Allows lines to extend beyond the right margin.
+.IP \fBautoformat\fR
+Causes \fIee\fR to automatically try to format the current paragraph while
+text insertion is occurring.
+.IP \fBnoautoformat\fR
+Turns off automatic paragraph formatting (default).
+.IP \fBprintcommand\fR
+Allows the setting of the print command (default: "lp").
+.IP \fBrightmargin\fR
+The user can select a value for the right margin (the first column on the
+screen is zero).
+.IP \fBhighlight\fR
+Turns on highlighting border of information window and menus (default).
+.IP \fBnohighlight\fR
+Turns off highlighting of border of information window and menus.
+.IP \fBeightbit\fR
+Turns on display of eight bit characters.
+.IP \fBnoeightbit\fR
+Turns off display of eight bit characters (they are displayed as their decimal
+value inside angle brackets, e.g., "<220>").
+.IP \fB16bit\fR
+Turns on handling of 16-bit characters.
+.IP \fbno16bit\fR
+Turns off handling of 16-bit characters.
+.IP \fBemacs\fR
+Turns on emacs key bindings.
+.IP \fBnoemacs\fR
+Turns off emacs key bindings.
+.RE
+.\"
+.\" save editor configuration
+.\"
+.SS "Save Editor Configuration"
+.PP
+When using this entry from the
+.B settings
+menu, the user may choose to save the current configuration of
+the editor (see \fBInitializing ee from a
+file\fR above) to a file named
+.I .init.ee
+in the current directory or the user's home directory. If a file named
+.I .init.ee
+already exists, it will be renamed
+.IR .init.ee.old .
+.\"
+.\" Caveats
+.\"
+.SH CAVEATS
+.PP
+THIS MATERIAL IS PROVIDED "AS IS". THERE ARE
+NO WARRANTIES OF ANY KIND WITH REGARD TO THIS
+MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE. Neither
+Hewlett-Packard nor Hugh Mahon shall be liable
+for errors contained herein, nor for
+incidental or consequential damages in
+connection with the furnishing, performance or
+use of this material. Neither Hewlett-Packard
+nor Hugh Mahon assumes any responsibility for
+the use or reliability of this software or
+documentation. This software and
+documentation is totally UNSUPPORTED. There
+is no support contract available. Hewlett-Packard
+has done NO Quality Assurance on ANY
+of the program or documentation. You may find
+the quality of the materials inferior to
+supported materials.
+.PP
+Always make a copy of files that cannot be easily reproduced before
+editing. Save files early, and save often.
+.SS "International Code Set Support"
+.I ee
+supports single-byte character code sets (eight-bit clean), or the
+Chinese Big-5 code set. (Other multi-byte code sets may function, but the
+reason Big-5 works is that a two-byte character also takes up two columns on
+the screen.)
+.SH WARNINGS
+The automatic paragraph formatting operation
+may be too slow for slower systems.
+.SH FILES
+.PP
+.I /usr/local/lib/init.ee
+.br
+.I $HOME/.init.ee
+.br
+.I .init.ee
+.SH AUTHOR
+.PP
+The software
+.I ee
+was developed by Hugh Mahon.
+.PP
+This software and documentation contains
+proprietary information which is protected by
+copyright. All rights are reserved.
+.PP
+Copyright (c) 1990, 1991, 1992, 1993, 1995, 1996 Hugh Mahon.
+.SH "SEE ALSO"
+.PP
+termcap(4), terminfo(4), environ(5), spell(1), ispell(1), lp(1)
+
diff --git a/contrib/ee/ee.c b/contrib/ee/ee.c
new file mode 100755
index 0000000..9a08dc4
--- /dev/null
+++ b/contrib/ee/ee.c
@@ -0,0 +1,5268 @@
+/*
+ | ee (easy editor)
+ |
+ | An easy to use, simple screen oriented editor.
+ |
+ | written by Hugh Mahon
+ |
+ | THIS MATERIAL IS PROVIDED "AS IS". THERE ARE
+ | NO WARRANTIES OF ANY KIND WITH REGARD TO THIS
+ | MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE
+ | IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ | FITNESS FOR A PARTICULAR PURPOSE. Neither
+ | Hewlett-Packard nor Hugh Mahon shall be liable
+ | for errors contained herein, nor for
+ | incidental or consequential damages in
+ | connection with the furnishing, performance or
+ | use of this material. Neither Hewlett-Packard
+ | nor Hugh Mahon assumes any responsibility for
+ | the use or reliability of this software or
+ | documentation. This software and
+ | documentation is totally UNSUPPORTED. There
+ | is no support contract available. Hewlett-
+ | Packard has done NO Quality Assurance on ANY
+ | of the program or documentation. You may find
+ | the quality of the materials inferior to
+ | supported materials.
+ |
+ | This software is not a product of Hewlett-Packard, Co., or any
+ | other company. No support is implied or offered with this software.
+ | You've got the source, and you're on your own.
+ |
+ | This software may be distributed under the terms of Larry Wall's
+ | Artistic license, a copy of which is included in this distribution.
+ |
+ | This notice must be included with this software and any derivatives.
+ |
+ | This editor was purposely developed to be simple, both in
+ | interface and implementation. This editor was developed to
+ | address a specific audience: the user who is new to computers
+ | (especially UNIX).
+ |
+ | ee is not aimed at technical users; for that reason more
+ | complex features were intentionally left out. In addition,
+ | ee is intended to be compiled by people with little computer
+ | experience, which means that it needs to be small, relatively
+ | simple in implementation, and portable.
+ |
+ | This software and documentation contains
+ | proprietary information which is protected by
+ | copyright. All rights are reserved.
+ |
+ | $Header: /home/hugh/sources/old_ae/RCS/ee.c,v 1.96 1998/07/14 05:02:30 hugh Exp $
+ |
+ */
+
+char *ee_copyright_message =
+"Copyright (c) 1986, 1990, 1991, 1992, 1993, 1994, 1995, 1996 Hugh Mahon ";
+
+char *ee_long_notice[] = {
+ "This software and documentation contains",
+ "proprietary information which is protected by",
+ "copyright. All rights are reserved."
+ };
+
+char *version = "@(#) ee, version 1.4.1 $Revision: 1.96 $";
+
+#ifdef NCURSE
+#include "new_curse.h"
+#else
+#include <curses.h>
+#endif
+
+#include <signal.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <string.h>
+#include <pwd.h>
+
+#ifdef HAS_SYS_WAIT
+#include <sys/wait.h>
+#endif
+
+#ifdef HAS_STDLIB
+#include <stdlib.h>
+#endif
+
+#ifdef HAS_STDARG
+#include <stdarg.h>
+#endif
+
+#ifdef HAS_UNISTD
+#include <unistd.h>
+#endif
+
+#ifdef HAS_CTYPE
+#include <ctype.h>
+#endif
+
+
+#ifndef NO_CATGETS
+#include <locale.h>
+#include <nl_types.h>
+
+nl_catd catalog;
+#else
+#define catgetlocal(a, b) (b)
+#endif /* NO_CATGETS */
+
+#ifndef SIGCHLD
+#define SIGCHLD SIGCLD
+#endif
+
+#define TAB 9
+#define max(a, b) (a > b ? a : b)
+#define min(a, b) (a < b ? a : b)
+
+/*
+ | defines for type of data to show in info window
+ */
+
+#define CONTROL_KEYS 1
+#define COMMANDS 2
+
+struct text {
+ unsigned char *line; /* line of characters */
+ int line_number; /* line number */
+ int line_length; /* actual number of characters in the line */
+ int max_length; /* maximum number of characters the line handles */
+ struct text *next_line; /* next line of text */
+ struct text *prev_line; /* previous line of text */
+ };
+
+struct text *first_line; /* first line of current buffer */
+struct text *dlt_line; /* structure for info on deleted line */
+struct text *curr_line; /* current line cursor is on */
+struct text *tmp_line; /* temporary line pointer */
+struct text *srch_line; /* temporary pointer for search routine */
+
+struct files { /* structure to store names of files to be edited*/
+ unsigned char *name; /* name of file */
+ struct files *next_name;
+ };
+
+struct files *top_of_stack = NULL;
+
+int d_wrd_len; /* length of deleted word */
+int position; /* offset in bytes from begin of line */
+int scr_pos; /* horizontal position */
+int scr_vert; /* vertical position on screen */
+int scr_horz; /* horizontal position on screen */
+int tmp_vert, tmp_horz;
+int input_file; /* indicate to read input file */
+int recv_file; /* indicate reading a file */
+int edit; /* continue executing while true */
+int gold; /* 'gold' function key pressed */
+int fildes; /* file descriptor */
+int case_sen; /* case sensitive search flag */
+int last_line; /* last line for text display */
+int last_col; /* last column for text display */
+int horiz_offset = 0; /* offset from left edge of text */
+int clear_com_win; /* flag to indicate com_win needs clearing */
+int text_changes = FALSE; /* indicate changes have been made to text */
+int get_fd; /* file descriptor for reading a file */
+int info_window = TRUE; /* flag to indicate if help window visible */
+int info_type = CONTROL_KEYS; /* flag to indicate type of info to display */
+int expand_tabs = TRUE; /* flag for expanding tabs */
+int right_margin = 0; /* the right margin */
+int observ_margins = TRUE; /* flag for whether margins are observed */
+int shell_fork;
+int temp_stdin; /* temporary storage for stdin */
+int temp_stdout; /* temp storage for stdout descriptor */
+int temp_stderr; /* temp storage for stderr descriptor */
+int pipe_out[2]; /* pipe file desc for output */
+int pipe_in[2]; /* pipe file descriptors for input */
+int out_pipe; /* flag that info is piped out */
+int in_pipe; /* flag that info is piped in */
+int formatted = FALSE; /* flag indicating paragraph formatted */
+int auto_format = FALSE; /* flag for auto_format mode */
+int restricted = FALSE; /* flag to indicate restricted mode */
+int nohighlight = FALSE; /* turns off highlighting */
+int eightbit = TRUE; /* eight bit character flag */
+int local_LINES = 0; /* copy of LINES, to detect when win resizes */
+int local_COLS = 0; /* copy of COLS, to detect when win resizes */
+int curses_initialized = FALSE; /* flag indicating if curses has been started*/
+int emacs_keys_mode = FALSE; /* mode for if emacs key binings are used */
+int ee_chinese = FALSE; /* allows handling of multi-byte characters */
+ /* by checking for high bit in a byte the */
+ /* code recognizes a two-byte character */
+ /* sequence */
+
+unsigned char *point; /* points to current position in line */
+unsigned char *srch_str; /* pointer for search string */
+unsigned char *u_srch_str; /* pointer to non-case sensitive search */
+unsigned char *srch_1; /* pointer to start of suspect string */
+unsigned char *srch_2; /* pointer to next character of string */
+unsigned char *srch_3;
+unsigned char *in_file_name = NULL; /* name of input file */
+char *tmp_file; /* temporary file name */
+unsigned char *d_char; /* deleted character */
+unsigned char *d_word; /* deleted word */
+unsigned char *d_line; /* deleted line */
+char in_string[513]; /* buffer for reading a file */
+unsigned char *print_command = "lp"; /* string to use for the print command */
+unsigned char *start_at_line = NULL; /* move to this line at start of session*/
+int in; /* input character */
+
+FILE *temp_fp; /* temporary file pointer */
+FILE *bit_bucket; /* file pointer to /dev/null */
+
+char *table[] = {
+ "^@", "^A", "^B", "^C", "^D", "^E", "^F", "^G", "^H", "\t", "^J",
+ "^K", "^L", "^M", "^N", "^O", "^P", "^Q", "^R", "^S", "^T", "^U",
+ "^V", "^W", "^X", "^Y", "^Z", "^[", "^\\", "^]", "^^", "^_"
+ };
+
+WINDOW *com_win;
+WINDOW *text_win;
+WINDOW *help_win;
+WINDOW *info_win;
+
+#if defined(__STDC__) || defined(__cplusplus)
+#define P_(s) s
+#else
+#define P_(s) ()
+#endif
+
+
+/*
+ | The following structure allows menu items to be flexibly declared.
+ | The first item is the string describing the selection, the second
+ | is the address of the procedure to call when the item is selected,
+ | and the third is the argument for the procedure.
+ |
+ | For those systems with i18n, the string should be accompanied by a
+ | catalog number. The 'int *' should be replaced with 'void *' on
+ | systems with that type.
+ |
+ | The first menu item will be the title of the menu, with NULL
+ | parameters for the procedure and argument, followed by the menu items.
+ |
+ | If the procedure value is NULL, the menu item is displayed, but no
+ | procedure is called when the item is selected. The number of the
+ | item will be returned. If the third (argument) parameter is -1, no
+ | argument is given to the procedure when it is called.
+ */
+
+struct menu_entries {
+ char *item_string;
+ int (*procedure)P_((struct menu_entries *));
+ struct menu_entries *ptr_argument;
+ int (*iprocedure)P_((int));
+ void (*nprocedure)P_((void));
+ int argument;
+ };
+
+int main P_((int argc, char *argv[]));
+unsigned char *resiz_line P_((int factor, struct text *rline, int rpos));
+void insert P_((int character));
+void delete P_((int disp));
+void scanline P_((unsigned char *pos));
+int tabshift P_((int temp_int));
+int out_char P_((WINDOW *window, int character, int column));
+int len_char P_((int character, int column));
+void draw_line P_((int vertical, int horiz, unsigned char *ptr, int t_pos, int length));
+void insert_line P_((int disp));
+struct text *txtalloc P_((void));
+struct files *name_alloc P_((void));
+unsigned char *next_word P_((unsigned char *string));
+void prev_word P_((void));
+void control P_((void));
+void emacs_control P_((void));
+void bottom P_((void));
+void top P_((void));
+void nextline P_((void));
+void prevline P_((void));
+void left P_((int disp));
+void right P_((int disp));
+void find_pos P_((void));
+void up P_((void));
+void down P_((void));
+void function_key P_((void));
+void print_buffer P_((void));
+void command_prompt P_((void));
+void command P_((char *cmd_str1));
+int scan P_((char *line, int offset, int column));
+char *get_string P_((char *prompt, int advance));
+int compare P_((char *string1, char *string2, int sensitive));
+void goto_line P_((char *cmd_str));
+void midscreen P_((int line, unsigned char *pnt));
+void get_options P_((int numargs, char *arguments[]));
+void check_fp P_((void));
+void get_file P_((char *file_name));
+void get_line P_((int length, unsigned char *in_string, int *append));
+void draw_screen P_((void));
+void finish P_((void));
+int quit P_((int noverify));
+void edit_abort P_((int arg));
+void delete_text P_((void));
+int write_file P_((char *file_name));
+int search P_((int display_message));
+void search_prompt P_((void));
+void del_char P_((void));
+void undel_char P_((void));
+void del_word P_((void));
+void undel_word P_((void));
+void del_line P_((void));
+void undel_line P_((void));
+void adv_word P_((void));
+void move_rel P_((char *direction, int lines));
+void eol P_((void));
+void bol P_((void));
+void adv_line P_((void));
+void sh_command P_((char *string));
+void set_up_term P_((void));
+void resize_check P_((void));
+int menu_op P_((struct menu_entries *));
+void paint_menu P_((struct menu_entries menu_list[], int max_width, int max_height, int list_size, int top_offset, WINDOW *menu_win, int off_start, int vert_size));
+void help P_((void));
+void paint_info_win P_((void));
+void no_info_window P_((void));
+void create_info_window P_((void));
+int file_op P_((int arg));
+void shell_op P_((void));
+void leave_op P_((void));
+void redraw P_((void));
+int Blank_Line P_((struct text *test_line));
+void Format P_((void));
+void ee_init P_((void));
+void dump_ee_conf P_((void));
+void echo_string P_((char *string));
+void spell_op P_((void));
+void ispell_op P_((void));
+int first_word_len P_((struct text *test_line));
+void Auto_Format P_((void));
+void modes_op P_((void));
+char *is_in_string P_((char *string, char *substring));
+char *resolve_name P_((char *name));
+int restrict_mode P_((void));
+int unique_test P_((char *string, char *list[]));
+void strings_init P_((void));
+
+#undef P_
+/*
+ | allocate space here for the strings that will be in the menu
+ */
+
+struct menu_entries modes_menu[] = {
+ {"", NULL, NULL, NULL, NULL, 0}, /* title */
+ {"", NULL, NULL, NULL, NULL, -1}, /* 1. tabs to spaces */
+ {"", NULL, NULL, NULL, NULL, -1}, /* 2. case sensitive search*/
+ {"", NULL, NULL, NULL, NULL, -1}, /* 3. margins observed */
+ {"", NULL, NULL, NULL, NULL, -1}, /* 4. auto-paragraph */
+ {"", NULL, NULL, NULL, NULL, -1}, /* 5. eightbit characters*/
+ {"", NULL, NULL, NULL, NULL, -1}, /* 6. info window */
+ {"", NULL, NULL, NULL, NULL, -1}, /* 7. emacs key bindings*/
+ {"", NULL, NULL, NULL, NULL, -1}, /* 8. right margin */
+ {"", NULL, NULL, NULL, NULL, -1}, /* 9. chinese text */
+ {"", NULL, NULL, NULL, dump_ee_conf, -1}, /* 10. save editor config */
+ {NULL, NULL, NULL, NULL, NULL, -1} /* terminator */
+ };
+
+char *mode_strings[11];
+
+#define NUM_MODES_ITEMS 10
+
+struct menu_entries config_dump_menu[] = {
+ {"", NULL, NULL, NULL, NULL, 0},
+ {"", NULL, NULL, NULL, NULL, -1},
+ {"", NULL, NULL, NULL, NULL, -1},
+ {NULL, NULL, NULL, NULL, NULL, -1}
+ };
+
+struct menu_entries leave_menu[] = {
+ {"", NULL, NULL, NULL, NULL, -1},
+ {"", NULL, NULL, NULL, finish, -1},
+ {"", NULL, NULL, quit, NULL, TRUE},
+ {NULL, NULL, NULL, NULL, NULL, -1}
+ };
+
+#define READ_FILE 1
+#define WRITE_FILE 2
+#define SAVE_FILE 3
+
+struct menu_entries file_menu[] = {
+ {"", NULL, NULL, NULL, NULL, -1},
+ {"", NULL, NULL, file_op, NULL, READ_FILE},
+ {"", NULL, NULL, file_op, NULL, WRITE_FILE},
+ {"", NULL, NULL, file_op, NULL, SAVE_FILE},
+ {"", NULL, NULL, NULL, print_buffer, -1},
+ {NULL, NULL, NULL, NULL, NULL, -1}
+ };
+
+struct menu_entries search_menu[] = {
+ {"", NULL, NULL, NULL, NULL, 0},
+ {"", NULL, NULL, NULL, search_prompt, -1},
+ {"", NULL, NULL, search, NULL, TRUE},
+ {NULL, NULL, NULL, NULL, NULL, -1}
+ };
+
+struct menu_entries spell_menu[] = {
+ {"", NULL, NULL, NULL, NULL, -1},
+ {"", NULL, NULL, NULL, spell_op, -1},
+ {"", NULL, NULL, NULL, ispell_op, -1},
+ {NULL, NULL, NULL, NULL, NULL, -1}
+ };
+
+struct menu_entries misc_menu[] = {
+ {"", NULL, NULL, NULL, NULL, -1},
+ {"", NULL, NULL, NULL, Format, -1},
+ {"", NULL, NULL, NULL, shell_op, -1},
+ {"", menu_op, spell_menu, NULL, NULL, -1},
+ {NULL, NULL, NULL, NULL, NULL, -1}
+ };
+
+struct menu_entries main_menu[] = {
+ {"", NULL, NULL, NULL, NULL, -1},
+ {"", NULL, NULL, NULL, leave_op, -1},
+ {"", NULL, NULL, NULL, help, -1},
+ {"", menu_op, file_menu, NULL, NULL, -1},
+ {"", NULL, NULL, NULL, redraw, -1},
+ {"", NULL, NULL, NULL, modes_op, -1},
+ {"", menu_op, search_menu, NULL, NULL, -1},
+ {"", menu_op, misc_menu, NULL, NULL, -1},
+ {NULL, NULL, NULL, NULL, NULL, -1}
+ };
+
+char *help_text[23];
+char *control_keys[5];
+
+char *emacs_help_text[22];
+char *emacs_control_keys[5];
+
+char *command_strings[5];
+char *commands[32];
+char *init_strings[22];
+
+#define MENU_WARN 1
+
+#define max_alpha_char 36
+
+/*
+ | Declarations for strings for localization
+ */
+
+char *com_win_message; /* to be shown in com_win if no info window */
+char *no_file_string;
+char *ascii_code_str;
+char *printer_msg_str;
+char *command_str;
+char *file_write_prompt_str;
+char *file_read_prompt_str;
+char *char_str;
+char *unkn_cmd_str;
+char *non_unique_cmd_msg;
+char *line_num_str;
+char *line_len_str;
+char *current_file_str;
+char *usage0;
+char *usage1;
+char *usage2;
+char *usage3;
+char *usage4;
+char *file_is_dir_msg;
+char *new_file_msg;
+char *cant_open_msg;
+char *open_file_msg;
+char *file_read_fin_msg;
+char *reading_file_msg;
+char *read_only_msg;
+char *file_read_lines_msg;
+char *save_file_name_prompt;
+char *file_not_saved_msg;
+char *changes_made_prompt;
+char *yes_char;
+char *file_exists_prompt;
+char *create_file_fail_msg;
+char *writing_file_msg;
+char *file_written_msg;
+char *searching_msg;
+char *str_not_found_msg;
+char *search_prompt_str;
+char *exec_err_msg;
+char *continue_msg;
+char *menu_cancel_msg;
+char *menu_size_err_msg;
+char *press_any_key_msg;
+char *shell_prompt;
+char *formatting_msg;
+char *shell_echo_msg;
+char *spell_in_prog_msg;
+char *margin_prompt;
+char *restricted_msg;
+char *ON;
+char *OFF;
+char *HELP;
+char *WRITE;
+char *READ;
+char *LINE;
+char *FILE_str;
+char *CHARACTER;
+char *REDRAW;
+char *RESEQUENCE;
+char *AUTHOR;
+char *VERSION;
+char *CASE;
+char *NOCASE;
+char *EXPAND;
+char *NOEXPAND;
+char *Exit_string;
+char *QUIT_string;
+char *INFO;
+char *NOINFO;
+char *MARGINS;
+char *NOMARGINS;
+char *AUTOFORMAT;
+char *NOAUTOFORMAT;
+char *Echo;
+char *PRINTCOMMAND;
+char *RIGHTMARGIN;
+char *HIGHLIGHT;
+char *NOHIGHLIGHT;
+char *EIGHTBIT;
+char *NOEIGHTBIT;
+char *EMACS_string;
+char *NOEMACS_string;
+char *conf_dump_err_msg;
+char *conf_dump_success_msg;
+char *conf_not_saved_msg;
+char *ree_no_file_msg;
+char *cancel_string;
+char *menu_too_lrg_msg;
+char *more_above_str, *more_below_str;
+
+char *chinese_cmd, *nochinese_cmd;
+
+#ifndef __STDC__
+#ifndef HAS_STDLIB
+extern char *malloc();
+extern char *realloc();
+extern char *getenv();
+FILE *fopen(); /* declaration for open function */
+#endif /* HAS_STDLIB */
+#endif /* __STDC__ */
+
+int
+main(argc, argv) /* beginning of main program */
+int argc;
+char *argv[];
+{
+ int counter;
+
+ for (counter = 1; counter < 24; counter++)
+ signal(counter, SIG_IGN);
+
+ signal(SIGCHLD, SIG_DFL);
+ signal(SIGSEGV, SIG_DFL);
+ signal(SIGINT, edit_abort);
+ d_char = malloc(3); /* provide a buffer for multi-byte chars */
+ d_word = malloc(150);
+ *d_word = (char) NULL;
+ d_line = NULL;
+ dlt_line = txtalloc();
+ dlt_line->line = d_line;
+ dlt_line->line_length = 0;
+ curr_line = first_line = txtalloc();
+ curr_line->line = point = malloc(10);
+ curr_line->line_length = 1;
+ curr_line->max_length = 10;
+ curr_line->prev_line = NULL;
+ curr_line->next_line = NULL;
+ curr_line->line_number = 1;
+ srch_str = NULL;
+ u_srch_str = NULL;
+ position = 1;
+ scr_pos =0;
+ scr_vert = 0;
+ scr_horz = 0;
+ bit_bucket = fopen("/dev/null", "w");
+ edit = TRUE;
+ gold = case_sen = FALSE;
+ shell_fork = TRUE;
+ strings_init();
+ ee_init();
+ if (argc > 0 )
+ get_options(argc, argv);
+ set_up_term();
+ if (right_margin == 0)
+ right_margin = COLS - 1;
+ if (top_of_stack == NULL)
+ {
+ if (restrict_mode())
+ {
+ wmove(com_win, 0, 0);
+ werase(com_win);
+ wprintw(com_win, ree_no_file_msg);
+ wrefresh(com_win);
+ edit_abort(0);
+ }
+ wprintw(com_win, no_file_string);
+ wrefresh(com_win);
+ }
+ else
+ check_fp();
+
+ clear_com_win = TRUE;
+
+ while(edit)
+ {
+ wrefresh(text_win);
+ in = wgetch(text_win);
+ if (in == -1)
+ exit(0);
+
+ resize_check();
+
+ if (clear_com_win)
+ {
+ clear_com_win = FALSE;
+ wmove(com_win, 0, 0);
+ werase(com_win);
+ if (!info_window)
+ {
+ wprintw(com_win, "%s", com_win_message);
+ }
+ wrefresh(com_win);
+ }
+
+ if (in > 255)
+ function_key();
+ else if ((in == '\10') || (in == 127))
+ {
+ in = 8; /* make sure key is set to backspace */
+ delete(TRUE);
+ }
+ else if ((in > 31) || (in == 9))
+ insert(in);
+ else if ((in >= 0) && (in <= 31))
+ {
+ if (emacs_keys_mode)
+ emacs_control();
+ else
+ control();
+ }
+ }
+ return(0);
+}
+
+unsigned char *
+resiz_line(factor, rline, rpos) /* resize the line to length + factor*/
+int factor; /* resize factor */
+struct text *rline; /* position in line */
+int rpos;
+{
+ unsigned char *rpoint;
+ int resiz_var;
+
+ rline->max_length += factor;
+ rpoint = rline->line = realloc(rline->line, rline->max_length );
+ for (resiz_var = 1 ; (resiz_var < rpos) ; resiz_var++)
+ rpoint++;
+ return(rpoint);
+}
+
+void
+insert(character) /* insert character into line */
+int character; /* new character */
+{
+ int counter;
+ int value;
+ unsigned char *temp; /* temporary pointer */
+ unsigned char *temp2; /* temporary pointer */
+
+ if ((character == '\011') && (expand_tabs))
+ {
+ counter = len_char('\011', scr_horz);
+ for (; counter > 0; counter--)
+ insert(' ');
+ if (auto_format)
+ Auto_Format();
+ return;
+ }
+ text_changes = TRUE;
+ if ((curr_line->max_length - curr_line->line_length) < 5)
+ point = resiz_line(10, curr_line, position);
+ curr_line->line_length++;
+ temp = point;
+ counter = position;
+ while (counter < curr_line->line_length) /* find end of line */
+ {
+ counter++;
+ temp++;
+ }
+ temp++; /* increase length of line by one */
+ while (point < temp)
+ {
+ temp2=temp - 1;
+ *temp= *temp2; /* shift characters over by one */
+ temp--;
+ }
+ *point = character; /* insert new character */
+ wclrtoeol(text_win);
+ if (((character >= 0) && (character < ' ')) || (character >= 127)) /* check for TAB character*/
+ {
+ scr_pos = scr_horz += out_char(text_win, character, scr_horz);
+ point++;
+ position++;
+ }
+ else
+ {
+ waddch(text_win, character);
+ scr_pos = ++scr_horz;
+ point++;
+ position ++;
+ }
+
+ if ((observ_margins) && (right_margin < scr_pos))
+ {
+ counter = position;
+ while (scr_pos > right_margin)
+ prev_word();
+ if (scr_pos == 0)
+ {
+ while (position < counter)
+ right(TRUE);
+ }
+ else
+ {
+ counter -= position;
+ insert_line(TRUE);
+ for (value = 0; value < counter; value++)
+ right(TRUE);
+ }
+ }
+
+ if ((scr_horz - horiz_offset) > last_col)
+ {
+ horiz_offset += 8;
+ midscreen(scr_vert, point);
+ }
+
+ if ((auto_format) && (character == ' ') && (!formatted))
+ Auto_Format();
+ else if ((character != ' ') && (character != '\t'))
+ formatted = FALSE;
+
+ draw_line(scr_vert, scr_horz, point, position, curr_line->line_length);
+}
+
+void
+delete(disp) /* delete character */
+int disp;
+{
+ unsigned char *tp;
+ unsigned char *temp2;
+ struct text *temp_buff;
+ int temp_vert;
+ int temp_pos;
+ int del_width = 1;
+
+ if (point != curr_line->line) /* if not at beginning of line */
+ {
+ text_changes = TRUE;
+ temp2 = tp = point;
+ if ((ee_chinese) && (position >= 2) && (*(point - 2) > 127))
+ {
+ del_width = 2;
+ }
+ tp -= del_width;
+ point -= del_width;
+ position -= del_width;
+ temp_pos = position;
+ curr_line->line_length -= del_width;
+ if ((*tp < ' ') || (*tp >= 127)) /* check for TAB */
+ scanline(tp);
+ else
+ scr_horz -= del_width;
+ scr_pos = scr_horz;
+ if (in == 8)
+ {
+ if (del_width == 1)
+ *d_char = *point; /* save deleted character */
+ else
+ {
+ d_char[0] = *point;
+ d_char[1] = *(point + 1);
+ }
+ d_char[del_width] = (unsigned char) NULL;
+ }
+ while (temp_pos <= curr_line->line_length)
+ {
+ temp_pos++;
+ *tp = *temp2;
+ tp++;
+ temp2++;
+ }
+ if (scr_horz < horiz_offset)
+ {
+ horiz_offset -= 8;
+ midscreen(scr_vert, point);
+ }
+ }
+ else if (curr_line->prev_line != NULL)
+ {
+ text_changes = TRUE;
+ left(disp); /* go to previous line */
+ temp_buff = curr_line->next_line;
+ point = resiz_line(temp_buff->line_length, curr_line, position);
+ if (temp_buff->next_line != NULL)
+ temp_buff->next_line->prev_line = curr_line;
+ curr_line->next_line = temp_buff->next_line;
+ temp2 = temp_buff->line;
+ if (in == 8)
+ {
+ d_char[0] = '\n';
+ d_char[1] = (unsigned char) NULL;
+ }
+ tp = point;
+ temp_pos = 1;
+ while (temp_pos < temp_buff->line_length)
+ {
+ curr_line->line_length++;
+ temp_pos++;
+ *tp = *temp2;
+ tp++;
+ temp2++;
+ }
+ *tp = (char) NULL;
+ free(temp_buff->line);
+ free(temp_buff);
+ temp_buff = curr_line;
+ temp_vert = scr_vert;
+ scr_pos = scr_horz;
+ if (scr_vert < last_line)
+ {
+ wmove(text_win, scr_vert + 1, 0);
+ wdeleteln(text_win);
+ }
+ while ((temp_buff != NULL) && (temp_vert < last_line))
+ {
+ temp_buff = temp_buff->next_line;
+ temp_vert++;
+ }
+ if ((temp_vert == last_line) && (temp_buff != NULL))
+ {
+ tp = temp_buff->line;
+ wmove(text_win, last_line,0);
+ wclrtobot(text_win);
+ draw_line(last_line, 0, tp, 1, temp_buff->line_length);
+ wmove(text_win, scr_vert, (scr_horz - horiz_offset));
+ }
+ }
+ draw_line(scr_vert, scr_horz, point, position, curr_line->line_length);
+ formatted = FALSE;
+}
+
+void
+scanline(pos) /* find the proper horizontal position for the pointer */
+unsigned char *pos;
+{
+ int temp;
+ unsigned char *ptr;
+
+ ptr = curr_line->line;
+ temp = 0;
+ while (ptr < pos)
+ {
+ if (*ptr <= 8)
+ temp += 2;
+ else if (*ptr == 9)
+ temp += tabshift(temp);
+ else if ((*ptr >= 10) && (*ptr <= 31))
+ temp += 2;
+ else if ((*ptr >= 32) && (*ptr < 127))
+ temp++;
+ else if (*ptr == 127)
+ temp += 2;
+ else if (!eightbit)
+ temp += 5;
+ else
+ temp++;
+ ptr++;
+ }
+ scr_horz = temp;
+ if ((scr_horz - horiz_offset) > last_col)
+ {
+ horiz_offset = (scr_horz - (scr_horz % 8)) - (COLS - 8);
+ midscreen(scr_vert, point);
+ }
+ else if (scr_horz < horiz_offset)
+ {
+ horiz_offset = max(0, (scr_horz - (scr_horz % 8)));
+ midscreen(scr_vert, point);
+ }
+}
+
+int
+tabshift(temp_int) /* give the number of spaces to shift */
+int temp_int;
+{
+ int leftover;
+
+ leftover = ((temp_int + 1) % 8);
+ if (leftover == 0)
+ return (1);
+ else
+ return (9 - leftover);
+}
+
+int
+out_char(window, character, column) /* output non-printing character */
+WINDOW *window;
+char character;
+int column;
+{
+ int i1, i2;
+ unsigned char *string;
+ char string2[8];
+
+ if (character == TAB)
+ {
+ i1 = tabshift(column);
+ for (i2 = 0;
+ (i2 < i1) && (((column+i2+1)-horiz_offset) < last_col); i2++)
+ {
+ waddch(window, ' ');
+ }
+ return(i1);
+ }
+ else if ((character >= '\0') && (character < ' '))
+ {
+ string = table[(int) character];
+ }
+ else if ((character < 0) || (character >= 127))
+ {
+ if (character == 127)
+ string = "^?";
+ else if (!eightbit)
+ {
+ sprintf(string2, "<%d>", (character < 0) ? (character + 256) : character);
+ string = string2;
+ }
+ else
+ {
+ waddch(window, (char)character );
+ return(1);
+ }
+ }
+ else
+ {
+ waddch(window, (char)character);
+ return(1);
+ }
+ for (i2 = 0; (string[i2] != (char) NULL) && (((column+i2+1)-horiz_offset) < last_col); i2++)
+ waddch(window, string[i2]);
+ return(strlen(string));
+}
+
+int
+len_char(character, column) /* return the length of the character */
+char character;
+int column; /* the column must be known to provide spacing for tabs */
+{
+ int length;
+
+ if (character == '\t')
+ length = tabshift(column);
+ else if ((character >= 0) && (character < 32))
+ length = 2;
+ else if ((character >= 32) && (character <= 126))
+ length = 1;
+ else if (character == 127)
+ length = 2;
+ else if (((character > 126) || (character < 0)) && (!eightbit))
+ length = 5;
+ else
+ length = 1;
+
+ return(length);
+}
+
+void
+draw_line(vertical, horiz, ptr, t_pos, length) /* redraw line from current position */
+int vertical; /* current vertical position on screen */
+int horiz; /* current horizontal position on screen */
+unsigned char *ptr; /* pointer to line */
+int t_pos; /* current position (offset in bytes) from bol */
+int length; /* length (in bytes) of line */
+{
+ int d; /* partial length of special or tab char to display */
+ unsigned char *temp; /* temporary pointer to position in line */
+ int abs_column; /* offset in screen units from begin of line */
+ int column; /* horizontal position on screen */
+ int row; /* vertical position on screen */
+ int posit; /* temporary position indicator within line */
+
+ abs_column = horiz;
+ column = horiz - horiz_offset;
+ row = vertical;
+ temp = ptr;
+ d = 0;
+ posit = t_pos;
+ if (column < 0)
+ {
+ wmove(text_win, row, 0);
+ wclrtoeol(text_win);
+ }
+ while (column < 0)
+ {
+ d = len_char(*temp, abs_column);
+ abs_column += d;
+ column += d;
+ posit++;
+ temp++;
+ }
+ wmove(text_win, row, column);
+ wclrtoeol(text_win);
+ while ((posit < length) && (column <= last_col))
+ {
+ if ((*temp < 32) || (*temp >= 127))
+ {
+ column += len_char(*temp, abs_column);
+ abs_column += out_char(text_win, *temp, abs_column);
+ }
+ else
+ {
+ abs_column++;
+ column++;
+ waddch(text_win, *temp);
+ }
+ posit++;
+ temp++;
+ }
+ if (column < last_col)
+ wclrtoeol(text_win);
+ wmove(text_win, vertical, (horiz - horiz_offset));
+}
+
+void
+insert_line(disp) /* insert new line */
+int disp;
+{
+ int temp_pos;
+ int temp_pos2;
+ unsigned char *temp;
+ unsigned char *extra;
+ struct text *temp_nod;
+
+ text_changes = TRUE;
+ wmove(text_win, scr_vert, (scr_horz - horiz_offset));
+ wclrtoeol(text_win);
+ temp_nod= txtalloc();
+ temp_nod->line = extra= malloc(10);
+ temp_nod->line_length = 1;
+ temp_nod->max_length = 10;
+ temp_nod->line_number = curr_line->line_number + 1;
+ temp_nod->next_line = curr_line->next_line;
+ if (temp_nod->next_line != NULL)
+ temp_nod->next_line->prev_line = temp_nod;
+ temp_nod->prev_line = curr_line;
+ curr_line->next_line = temp_nod;
+ temp_pos2 = position;
+ temp = point;
+ if (temp_pos2 < curr_line->line_length)
+ {
+ temp_pos = 1;
+ while (temp_pos2 < curr_line->line_length)
+ {
+ if ((temp_nod->max_length - temp_nod->line_length)< 5)
+ extra = resiz_line(10, temp_nod, temp_pos);
+ temp_nod->line_length++;
+ temp_pos++;
+ temp_pos2++;
+ *extra= *temp;
+ extra++;
+ temp++;
+ }
+ temp=point;
+ *temp = (char) NULL;
+ temp = resiz_line((1 - temp_nod->line_length), curr_line, position);
+ curr_line->line_length = 1 + temp - curr_line->line;
+ }
+ curr_line->line_length = position;
+ curr_line = temp_nod;
+ *extra = (char) NULL;
+ position = 1;
+ point= curr_line->line;
+ if (disp)
+ {
+ if (scr_vert < last_line)
+ {
+ scr_vert++;
+ wclrtoeol(text_win);
+ wmove(text_win, scr_vert, 0);
+ winsertln(text_win);
+ }
+ else
+ {
+ wmove(text_win, 0,0);
+ wdeleteln(text_win);
+ wmove(text_win, last_line,0);
+ wclrtobot(text_win);
+ }
+ scr_pos = scr_horz = 0;
+ if (horiz_offset)
+ {
+ horiz_offset = 0;
+ midscreen(scr_vert, point);
+ }
+ draw_line(scr_vert, scr_horz, point, position,
+ curr_line->line_length);
+ }
+}
+
+struct text *txtalloc() /* allocate space for line structure */
+{
+ return((struct text *) malloc(sizeof( struct text)));
+}
+
+struct files *name_alloc() /* allocate space for file name list node */
+{
+ return((struct files *) malloc(sizeof( struct files)));
+}
+
+unsigned char *next_word(string) /* move to next word in string */
+unsigned char *string;
+{
+ while ((*string != (char) NULL) && ((*string != 32) && (*string != 9)))
+ string++;
+ while ((*string != (char) NULL) && ((*string == 32) || (*string == 9)))
+ string++;
+ return(string);
+}
+
+void
+prev_word() /* move to start of previous word in text */
+{
+ if (position != 1)
+ {
+ if ((position != 1) && ((point[-1] == ' ') || (point[-1] == '\t')))
+ { /* if at the start of a word */
+ while ((position != 1) && ((*point != ' ') && (*point != '\t')))
+ left(TRUE);
+ }
+ while ((position != 1) && ((*point == ' ') || (*point == '\t')))
+ left(TRUE);
+ while ((position != 1) && ((*point != ' ') && (*point != '\t')))
+ left(TRUE);
+ if ((position != 1) && ((*point == ' ') || (*point == '\t')))
+ right(TRUE);
+ }
+ else
+ left(TRUE);
+}
+
+void
+control() /* use control for commands */
+{
+ char *string;
+
+ if (in == 1) /* control a */
+ {
+ string = get_string(ascii_code_str, TRUE);
+ if (*string != (char) NULL)
+ {
+ in = atoi(string);
+ wmove(text_win, scr_vert, (scr_horz - horiz_offset));
+ insert(in);
+ }
+ free(string);
+ }
+ else if (in == 2) /* control b */
+ bottom();
+ else if (in == 3) /* control c */
+ {
+ command_prompt();
+ }
+ else if (in == 4) /* control d */
+ down();
+ else if (in == 5) /* control e */
+ search_prompt();
+ else if (in == 6) /* control f */
+ undel_char();
+ else if (in == 7) /* control g */
+ bol();
+ else if (in == 8) /* control h */
+ delete(TRUE);
+ else if (in == 9) /* control i */
+ ;
+ else if (in == 10) /* control j */
+ insert_line(TRUE);
+ else if (in == 11) /* control k */
+ del_char();
+ else if (in == 12) /* control l */
+ left(TRUE);
+ else if (in == 13) /* control m */
+ insert_line(TRUE);
+ else if (in == 14) /* control n */
+ move_rel("d", max(5, (last_line - 5)));
+ else if (in == 15) /* control o */
+ eol();
+ else if (in == 16) /* control p */
+ move_rel("u", max(5, (last_line - 5)));
+ else if (in == 17) /* control q */
+ ;
+ else if (in == 18) /* control r */
+ right(TRUE);
+ else if (in == 19) /* control s */
+ ;
+ else if (in == 20) /* control t */
+ top();
+ else if (in == 21) /* control u */
+ up();
+ else if (in == 22) /* control v */
+ undel_word();
+ else if (in == 23) /* control w */
+ del_word();
+ else if (in == 24) /* control x */
+ search(TRUE);
+ else if (in == 25) /* control y */
+ del_line();
+ else if (in == 26) /* control z */
+ undel_line();
+ else if (in == 27) /* control [ (escape) */
+ {
+ menu_op(main_menu);
+ }
+}
+
+/*
+ | Emacs control-key bindings
+ */
+
+void
+emacs_control()
+{
+ char *string;
+
+ if (in == 1) /* control a */
+ bol();
+ else if (in == 2) /* control b */
+ left(TRUE);
+ else if (in == 3) /* control c */
+ {
+ command_prompt();
+ }
+ else if (in == 4) /* control d */
+ del_char();
+ else if (in == 5) /* control e */
+ eol();
+ else if (in == 6) /* control f */
+ right(TRUE);
+ else if (in == 7) /* control g */
+ move_rel("u", max(5, (last_line - 5)));
+ else if (in == 8) /* control h */
+ delete(TRUE);
+ else if (in == 9) /* control i */
+ ;
+ else if (in == 10) /* control j */
+ undel_char();
+ else if (in == 11) /* control k */
+ del_line();
+ else if (in == 12) /* control l */
+ undel_line();
+ else if (in == 13) /* control m */
+ insert_line(TRUE);
+ else if (in == 14) /* control n */
+ down();
+ else if (in == 15) /* control o */
+ {
+ string = get_string(ascii_code_str, TRUE);
+ if (*string != (char) NULL)
+ {
+ in = atoi(string);
+ wmove(text_win, scr_vert, (scr_horz - horiz_offset));
+ insert(in);
+ }
+ free(string);
+ }
+ else if (in == 16) /* control p */
+ up();
+ else if (in == 17) /* control q */
+ ;
+ else if (in == 18) /* control r */
+ undel_word();
+ else if (in == 19) /* control s */
+ ;
+ else if (in == 20) /* control t */
+ top();
+ else if (in == 21) /* control u */
+ bottom();
+ else if (in == 22) /* control v */
+ move_rel("d", max(5, (last_line - 5)));
+ else if (in == 23) /* control w */
+ del_word();
+ else if (in == 24) /* control x */
+ search(TRUE);
+ else if (in == 25) /* control y */
+ search_prompt();
+ else if (in == 26) /* control z */
+ adv_word();
+ else if (in == 27) /* control [ (escape) */
+ {
+ menu_op(main_menu);
+ }
+}
+
+void
+bottom() /* go to bottom of file */
+{
+ while (curr_line->next_line != NULL)
+ curr_line = curr_line->next_line;
+ point = curr_line->line;
+ if (horiz_offset)
+ horiz_offset = 0;
+ position = 1;
+ midscreen(last_line, point);
+ scr_pos = scr_horz;
+}
+
+void
+top() /* go to top of file */
+{
+ while (curr_line->prev_line != NULL)
+ curr_line = curr_line->prev_line;
+ point = curr_line->line;
+ if (horiz_offset)
+ horiz_offset = 0;
+ position = 1;
+ midscreen(0, point);
+ scr_pos = scr_horz;
+}
+
+void
+nextline() /* move pointers to start of next line */
+{
+ curr_line = curr_line->next_line;
+ point = curr_line->line;
+ position = 1;
+ if (scr_vert == last_line)
+ {
+ wmove(text_win, 0,0);
+ wdeleteln(text_win);
+ wmove(text_win, last_line,0);
+ wclrtobot(text_win);
+ draw_line(last_line,0,point,1,curr_line->line_length);
+ }
+ else
+ scr_vert++;
+}
+
+void
+prevline() /* move pointers to start of previous line*/
+{
+ curr_line = curr_line->prev_line;
+ point = curr_line->line;
+ position = 1;
+ if (scr_vert == 0)
+ {
+ winsertln(text_win);
+ draw_line(0,0,point,1,curr_line->line_length);
+ }
+ else
+ scr_vert--;
+ while (position < curr_line->line_length)
+ {
+ position++;
+ point++;
+ }
+}
+
+void
+left(disp) /* move left one character */
+int disp;
+{
+ if (point != curr_line->line) /* if not at begin of line */
+ {
+ if ((ee_chinese) && (position >= 2) && (*(point - 2) > 127))
+ {
+ point--;
+ position--;
+ }
+ point--;
+ position--;
+ scanline(point);
+ wmove(text_win, scr_vert, (scr_horz - horiz_offset));
+ scr_pos = scr_horz;
+ }
+ else if (curr_line->prev_line != NULL)
+ {
+ if (!disp)
+ {
+ curr_line = curr_line->prev_line;
+ point = curr_line->line + curr_line->line_length;
+ position = curr_line->line_length;
+ return;
+ }
+ position = 1;
+ prevline();
+ scanline(point);
+ scr_pos = scr_horz;
+ wmove(text_win, scr_vert, (scr_horz - horiz_offset));
+ }
+}
+
+void
+right(disp) /* move right one character */
+int disp;
+{
+ if (position < curr_line->line_length)
+ {
+ if ((ee_chinese) && (*point > 127) &&
+ ((curr_line->line_length - position) >= 2))
+ {
+ point++;
+ position++;
+ }
+ point++;
+ position++;
+ scanline(point);
+ wmove(text_win, scr_vert, (scr_horz - horiz_offset));
+ scr_pos = scr_horz;
+ }
+ else if (curr_line->next_line != NULL)
+ {
+ if (!disp)
+ {
+ curr_line = curr_line->next_line;
+ point = curr_line->line;
+ position = 1;
+ return;
+ }
+ nextline();
+ scr_pos = scr_horz = 0;
+ if (horiz_offset)
+ {
+ horiz_offset = 0;
+ midscreen(scr_vert, point);
+ }
+ wmove(text_win, scr_vert, (scr_horz - horiz_offset));
+ position = 1;
+ }
+}
+
+void
+find_pos() /* move to the same column as on other line */
+{
+ scr_horz = 0;
+ position = 1;
+ while ((scr_horz < scr_pos) && (position < curr_line->line_length))
+ {
+ if (*point == 9)
+ scr_horz += tabshift(scr_horz);
+ else if (*point < ' ')
+ scr_horz += 2;
+ else if ((ee_chinese) && (*point > 127) &&
+ ((curr_line->line_length - position) >= 2))
+ {
+ scr_horz += 2;
+ point++;
+ position++;
+ }
+ else
+ scr_horz++;
+ position++;
+ point++;
+ }
+ if ((scr_horz - horiz_offset) > last_col)
+ {
+ horiz_offset = (scr_horz - (scr_horz % 8)) - (COLS - 8);
+ midscreen(scr_vert, point);
+ }
+ else if (scr_horz < horiz_offset)
+ {
+ horiz_offset = max(0, (scr_horz - (scr_horz % 8)));
+ midscreen(scr_vert, point);
+ }
+ wmove(text_win, scr_vert, (scr_horz - horiz_offset));
+}
+
+void
+up() /* move up one line */
+{
+ if (curr_line->prev_line != NULL)
+ {
+ prevline();
+ point = curr_line->line;
+ find_pos();
+ }
+}
+
+void
+down() /* move down one line */
+{
+ if (curr_line->next_line != NULL)
+ {
+ nextline();
+ find_pos();
+ }
+}
+
+void
+function_key() /* process function key */
+{
+ if (in == KEY_LEFT)
+ left(TRUE);
+ else if (in == KEY_RIGHT)
+ right(TRUE);
+ else if ( in == KEY_HOME)
+ top();
+ else if ( in == KEY_UP)
+ up();
+ else if (in == KEY_DOWN)
+ down();
+ else if (in == KEY_NPAGE)
+ move_rel("d", max( 5, (last_line - 5)));
+ else if (in == KEY_PPAGE)
+ move_rel("u", max(5, (last_line - 5)));
+ else if (in == KEY_DL)
+ del_line();
+ else if (in == KEY_DC)
+ del_char();
+ else if (in == KEY_BACKSPACE)
+ delete(TRUE);
+ else if (in == KEY_IL)
+ { /* insert a line before current line */
+ insert_line(TRUE);
+ left(TRUE);
+ }
+ else if (in == KEY_F(1))
+ gold = !gold;
+ else if (in == KEY_F(2))
+ {
+ if (gold)
+ {
+ gold = FALSE;
+ undel_line();
+ }
+ else
+ undel_char();
+ }
+ else if (in == KEY_F(3))
+ {
+ if (gold)
+ {
+ gold = FALSE;
+ undel_word();
+ }
+ else
+ del_word();
+ }
+ else if (in == KEY_F(4))
+ {
+ if (gold)
+ {
+ gold = FALSE;
+ paint_info_win();
+ midscreen(scr_vert, point);
+ }
+ else
+ adv_word();
+ }
+ else if (in == KEY_F(5))
+ {
+ if (gold)
+ {
+ gold = FALSE;
+ search_prompt();
+ }
+ else
+ search(TRUE);
+ }
+ else if (in == KEY_F(6))
+ {
+ if (gold)
+ {
+ gold = FALSE;
+ bottom();
+ }
+ else
+ top();
+ }
+ else if (in == KEY_F(7))
+ {
+ if (gold)
+ {
+ gold = FALSE;
+ eol();
+ }
+ else
+ bol();
+ }
+ else if (in == KEY_F(8))
+ {
+ if (gold)
+ {
+ gold = FALSE;
+ command_prompt();
+ }
+ else
+ adv_line();
+ }
+}
+
+void
+print_buffer()
+{
+ char buffer[256];
+
+ sprintf(buffer, ">!%s", print_command);
+ wmove(com_win, 0, 0);
+ wclrtoeol(com_win);
+ wprintw(com_win, printer_msg_str, print_command);
+ wrefresh(com_win);
+ command(buffer);
+}
+
+void
+command_prompt()
+{
+ char *cmd_str;
+ int result;
+
+ info_type = COMMANDS;
+ paint_info_win();
+ cmd_str = get_string(command_str, TRUE);
+ if ((result = unique_test(cmd_str, commands)) != 1)
+ {
+ werase(com_win);
+ wmove(com_win, 0, 0);
+ if (result == 0)
+ wprintw(com_win, unkn_cmd_str, cmd_str);
+ else
+ wprintw(com_win, non_unique_cmd_msg);
+
+ wrefresh(com_win);
+
+ info_type = CONTROL_KEYS;
+ paint_info_win();
+
+ if (cmd_str != NULL)
+ free(cmd_str);
+ return;
+ }
+ command(cmd_str);
+ wrefresh(com_win);
+ wmove(text_win, scr_vert, (scr_horz - horiz_offset));
+ info_type = CONTROL_KEYS;
+ paint_info_win();
+ if (cmd_str != NULL)
+ free(cmd_str);
+}
+
+void
+command(cmd_str1) /* process commands from keyboard */
+char *cmd_str1;
+{
+ char *cmd_str2 = NULL;
+ char *cmd_str = cmd_str1;
+
+ clear_com_win = TRUE;
+ if (compare(cmd_str, HELP, FALSE))
+ help();
+ else if (compare(cmd_str, WRITE, FALSE))
+ {
+ if (restrict_mode())
+ {
+ return;
+ }
+ cmd_str = next_word(cmd_str);
+ if (*cmd_str == (char) NULL)
+ {
+ cmd_str = cmd_str2 = get_string(file_write_prompt_str, TRUE);
+ }
+ tmp_file = resolve_name(cmd_str);
+ write_file(tmp_file);
+ if (tmp_file != cmd_str)
+ free(tmp_file);
+ }
+ else if (compare(cmd_str, READ, FALSE))
+ {
+ if (restrict_mode())
+ {
+ return;
+ }
+ cmd_str = next_word(cmd_str);
+ if (*cmd_str == (char) NULL)
+ {
+ cmd_str = cmd_str2 = get_string(file_read_prompt_str, TRUE);
+ }
+ tmp_file = cmd_str;
+ recv_file = TRUE;
+ tmp_file = resolve_name(cmd_str);
+ check_fp();
+ if (tmp_file != cmd_str)
+ free(tmp_file);
+ }
+ else if (compare(cmd_str, LINE, FALSE))
+ {
+ wmove(com_win, 0, 0);
+ wclrtoeol(com_win);
+ wprintw(com_win, line_num_str, curr_line->line_number);
+ wprintw(com_win, line_len_str, curr_line->line_length);
+ }
+ else if (compare(cmd_str, FILE_str, FALSE))
+ {
+ wmove(com_win, 0, 0);
+ wclrtoeol(com_win);
+ if (in_file_name == NULL)
+ wprintw(com_win, no_file_string);
+ else
+ wprintw(com_win, current_file_str, in_file_name);
+ }
+ else if ((*cmd_str >= '0') && (*cmd_str <= '9'))
+ goto_line(cmd_str);
+ else if (compare(cmd_str, CHARACTER, FALSE))
+ {
+ wmove(com_win, 0, 0);
+ wclrtoeol(com_win);
+ wprintw(com_win, char_str, *point);
+ }
+ else if (compare(cmd_str, REDRAW, FALSE))
+ redraw();
+ else if (compare(cmd_str, RESEQUENCE, FALSE))
+ {
+ tmp_line = first_line->next_line;
+ while (tmp_line != NULL)
+ {
+ tmp_line->line_number = tmp_line->prev_line->line_number + 1;
+ tmp_line = tmp_line->next_line;
+ }
+ }
+ else if (compare(cmd_str, AUTHOR, FALSE))
+ {
+ wmove(com_win, 0, 0);
+ wclrtoeol(com_win);
+ wprintw(com_win, "written by Hugh Mahon");
+ }
+ else if (compare(cmd_str, VERSION, FALSE))
+ {
+ wmove(com_win, 0, 0);
+ wclrtoeol(com_win);
+ wprintw(com_win, "%s", version);
+ }
+ else if (compare(cmd_str, CASE, FALSE))
+ case_sen = TRUE;
+ else if (compare(cmd_str, NOCASE, FALSE))
+ case_sen = FALSE;
+ else if (compare(cmd_str, EXPAND, FALSE))
+ expand_tabs = TRUE;
+ else if (compare(cmd_str, NOEXPAND, FALSE))
+ expand_tabs = FALSE;
+ else if (compare(cmd_str, Exit_string, FALSE))
+ finish();
+ else if (compare(cmd_str, chinese_cmd, FALSE))
+ {
+ ee_chinese = TRUE;
+#ifdef NCURSE
+ nc_setattrib(A_NC_BIG5);
+#endif /* NCURSE */
+ }
+ else if (compare(cmd_str, nochinese_cmd, FALSE))
+ {
+ ee_chinese = FALSE;
+#ifdef NCURSE
+ nc_clearattrib(A_NC_BIG5);
+#endif /* NCURSE */
+ }
+ else if (compare(cmd_str, QUIT_string, FALSE))
+ quit(0);
+ else if (*cmd_str == '!')
+ {
+ cmd_str++;
+ if ((*cmd_str == ' ') || (*cmd_str == 9))
+ cmd_str = next_word(cmd_str);
+ sh_command(cmd_str);
+ }
+ else if ((*cmd_str == '<') && (!in_pipe))
+ {
+ in_pipe = TRUE;
+ shell_fork = FALSE;
+ cmd_str++;
+ if ((*cmd_str == ' ') || (*cmd_str == '\t'))
+ cmd_str = next_word(cmd_str);
+ command(cmd_str);
+ in_pipe = FALSE;
+ shell_fork = TRUE;
+ }
+ else if ((*cmd_str == '>') && (!out_pipe))
+ {
+ out_pipe = TRUE;
+ cmd_str++;
+ if ((*cmd_str == ' ') || (*cmd_str == '\t'))
+ cmd_str = next_word(cmd_str);
+ command(cmd_str);
+ out_pipe = FALSE;
+ }
+ else
+ {
+ wmove(com_win, 0, 0);
+ wclrtoeol(com_win);
+ wprintw(com_win, unkn_cmd_str, cmd_str);
+ }
+ if (cmd_str2 != NULL)
+ free(cmd_str2);
+}
+
+int
+scan(line, offset, column) /* determine horizontal position for get_string */
+char *line;
+int offset;
+int column;
+{
+ char *stemp;
+ int i;
+ int j;
+
+ stemp = line;
+ i = 0;
+ j = column;
+ while (i < offset)
+ {
+ i++;
+ j += len_char(*stemp, j);
+ stemp++;
+ }
+ return(j);
+}
+
+char *
+get_string(prompt, advance) /* read string from input on command line */
+char *prompt; /* string containing user prompt message */
+int advance; /* if true, skip leading spaces and tabs */
+{
+ char *string;
+ char *tmp_string;
+ char *nam_str;
+ char *g_point;
+ int tmp_int;
+ int g_horz, g_position, g_pos;
+ int esc_flag;
+
+ g_point = tmp_string = malloc(512);
+ wmove(com_win,0,0);
+ wclrtoeol(com_win);
+ waddstr(com_win, prompt);
+ wrefresh(com_win);
+ nam_str = tmp_string;
+ clear_com_win = TRUE;
+ g_horz = g_position = scan(prompt, strlen(prompt), 0);
+ g_pos = 0;
+ do
+ {
+ esc_flag = FALSE;
+ in = wgetch(com_win);
+ if (in == -1)
+ exit(0);
+ if (((in == 8) || (in == 127) || (in == KEY_BACKSPACE)) && (g_pos > 0))
+ {
+ tmp_int = g_horz;
+ g_pos--;
+ g_horz = scan(g_point, g_pos, g_position);
+ tmp_int = tmp_int - g_horz;
+ for (; 0 < tmp_int; tmp_int--)
+ {
+ if ((g_horz+tmp_int) < (last_col - 1))
+ {
+ waddch(com_win, '\010');
+ waddch(com_win, ' ');
+ waddch(com_win, '\010');
+ }
+ }
+ nam_str--;
+ }
+ else if ((in != 8) && (in != 127) && (in != '\n') && (in != '\r') && (in < 256))
+ {
+ if (in == '\026') /* control-v, accept next character verbatim */
+ { /* allows entry of ^m, ^j, and ^h */
+ esc_flag = TRUE;
+ in = wgetch(com_win);
+ if (in == -1)
+ exit(0);
+ }
+ *nam_str = in;
+ g_pos++;
+ if (((in < ' ') || (in > 126)) && (g_horz < (last_col - 1)))
+ g_horz += out_char(com_win, in, g_horz);
+ else
+ {
+ g_horz++;
+ if (g_horz < (last_col - 1))
+ waddch(com_win, in);
+ }
+ nam_str++;
+ }
+ wrefresh(com_win);
+ if (esc_flag)
+ in = (char) NULL;
+ } while ((in != '\n') && (in != '\r'));
+ *nam_str = (char) NULL;
+ nam_str = tmp_string;
+ if (((*nam_str == ' ') || (*nam_str == 9)) && (advance))
+ nam_str = next_word(nam_str);
+ string = malloc(strlen(nam_str) + 1);
+ strcpy(string, nam_str);
+ free(tmp_string);
+ wrefresh(com_win);
+ return(string);
+}
+
+int
+compare(string1, string2, sensitive) /* compare two strings */
+char *string1;
+char *string2;
+int sensitive;
+{
+ char *strng1;
+ char *strng2;
+ int tmp;
+ int equal;
+
+ strng1 = string1;
+ strng2 = string2;
+ tmp = 0;
+ if ((strng1 == NULL) || (strng2 == NULL) || (*strng1 == (char) NULL) || (*strng2 == (char) NULL))
+ return(FALSE);
+ equal = TRUE;
+ while (equal)
+ {
+ if (sensitive)
+ {
+ if (*strng1 != *strng2)
+ equal = FALSE;
+ }
+ else
+ {
+ if (toupper(*strng1) != toupper(*strng2))
+ equal = FALSE;
+ }
+ strng1++;
+ strng2++;
+ if ((*strng1 == (char) NULL) || (*strng2 == (char) NULL) || (*strng1 == ' ') || (*strng2 == ' '))
+ break;
+ tmp++;
+ }
+ return(equal);
+}
+
+void
+goto_line(cmd_str)
+char *cmd_str;
+{
+ int number;
+ int i;
+ char *ptr;
+ char *direction;
+ struct text *t_line;
+
+ ptr = cmd_str;
+ i= 0;
+ while ((*ptr >='0') && (*ptr <= '9'))
+ {
+ i= i * 10 + (*ptr - '0');
+ ptr++;
+ }
+ number = i;
+ i = 0;
+ t_line = curr_line;
+ while ((t_line->line_number > number) && (t_line->prev_line != NULL))
+ {
+ i++;
+ t_line = t_line->prev_line;
+ direction = "u";
+ }
+ while ((t_line->line_number < number) && (t_line->next_line != NULL))
+ {
+ i++;
+ direction = "d";
+ t_line = t_line->next_line;
+ }
+ if ((i < 30) && (i > 0))
+ {
+ move_rel(direction, i);
+ }
+ else
+ {
+ curr_line = t_line;
+ point = curr_line->line;
+ position = 1;
+ midscreen((last_line / 2), point);
+ scr_pos = scr_horz;
+ }
+ wmove(com_win, 0, 0);
+ wclrtoeol(com_win);
+ wprintw(com_win, line_num_str, curr_line->line_number);
+ wmove(text_win, scr_vert, (scr_horz - horiz_offset));
+}
+
+void
+midscreen(line, pnt) /* put current line in middle of screen */
+int line;
+unsigned char *pnt;
+{
+ struct text *mid_line;
+ int i;
+
+ line = min(line, last_line);
+ mid_line = curr_line;
+ for (i = 0; ((i < line) && (curr_line->prev_line != NULL)); i++)
+ curr_line = curr_line->prev_line;
+ scr_vert = scr_horz = 0;
+ wmove(text_win, 0, 0);
+ draw_screen();
+ scr_vert = i;
+ curr_line = mid_line;
+ scanline(pnt);
+ wmove(text_win, scr_vert, (scr_horz - horiz_offset));
+}
+
+void
+get_options(numargs, arguments) /* get arguments from command line */
+int numargs;
+char *arguments[];
+{
+ char *buff;
+ int count;
+ struct files *temp_names;
+ char *name;
+ char *ptr;
+
+ /*
+ | see if editor was invoked as 'ree' (restricted mode)
+ */
+
+ if (!(name = strrchr(arguments[0], '/')))
+ name = arguments[0];
+ else
+ name++;
+ if (!strcmp(name, "ree"))
+ restricted = TRUE;
+
+ top_of_stack = NULL;
+ input_file = FALSE;
+ recv_file = FALSE;
+ count = 1;
+ while (count < numargs)
+ {
+ buff = arguments[count];
+ if (!strcmp("-i", buff))
+ {
+ info_window = FALSE;
+ }
+ else if (!strcmp("-e", buff))
+ {
+ expand_tabs = FALSE;
+ }
+ else if (!strcmp("-h", buff))
+ {
+ nohighlight = TRUE;
+ }
+ else if (!strcmp("-?", buff))
+ {
+ fprintf(stderr, usage0, arguments[0]);
+ fprintf(stderr, usage1);
+ fprintf(stderr, usage2);
+ fprintf(stderr, usage3);
+ fprintf(stderr, usage4);
+ exit(1);
+ }
+ else if (*buff == '+')
+ {
+ buff++;
+ start_at_line = buff;
+ }
+
+ else
+ {
+ if (top_of_stack == NULL)
+ {
+ temp_names = top_of_stack = name_alloc();
+ }
+ else
+ {
+ temp_names->next_name = name_alloc();
+ temp_names = temp_names->next_name;
+ }
+ ptr = temp_names->name = malloc(strlen(buff) + 1);
+ while (*buff != (char) NULL)
+ {
+ *ptr = *buff;
+ buff++;
+ ptr++;
+ }
+ *ptr = (char) NULL;
+ temp_names->next_name = NULL;
+ input_file = TRUE;
+ recv_file = TRUE;
+ }
+ count++;
+ }
+}
+
+void
+check_fp() /* open or close files according to flags */
+{
+ int line_num;
+ int temp;
+ struct stat buf;
+
+ clear_com_win = TRUE;
+ tmp_vert = scr_vert;
+ tmp_horz = scr_horz;
+ tmp_line = curr_line;
+ if (input_file)
+ {
+ in_file_name = tmp_file = top_of_stack->name;
+ top_of_stack = top_of_stack->next_name;
+ }
+ temp = stat(tmp_file, &buf);
+ buf.st_mode &= ~07777;
+ if ((temp != -1) && (buf.st_mode != 0100000) && (buf.st_mode != 0))
+ {
+ wprintw(com_win, file_is_dir_msg, tmp_file);
+ wrefresh(com_win);
+ if (input_file)
+ {
+ quit(0);
+ return;
+ }
+ else
+ return;
+ }
+ if ((get_fd = open(tmp_file, O_RDONLY)) == -1)
+ {
+ wmove(com_win, 0, 0);
+ wclrtoeol(com_win);
+ if (input_file)
+ wprintw(com_win, new_file_msg, tmp_file);
+ else
+ wprintw(com_win, cant_open_msg, tmp_file);
+ wrefresh(com_win);
+ wmove(text_win, scr_vert, (scr_horz - horiz_offset));
+ wrefresh(text_win);
+ recv_file = FALSE;
+ input_file = FALSE;
+ return;
+ }
+ else
+ get_file(tmp_file);
+
+ recv_file = FALSE;
+ line_num = curr_line->line_number;
+ scr_vert = tmp_vert;
+ scr_horz = tmp_horz;
+ if (input_file)
+ curr_line= first_line;
+ else
+ curr_line = tmp_line;
+ point = curr_line->line;
+ draw_screen();
+ if (input_file)
+ {
+ input_file = FALSE;
+ if (start_at_line != NULL)
+ {
+ line_num = atoi(start_at_line) - 1;
+ move_rel("d", line_num);
+ line_num = 0;
+ start_at_line = NULL;
+ }
+ }
+ else
+ {
+ wmove(com_win, 0, 0);
+ wclrtoeol(com_win);
+ text_changes = TRUE;
+ if ((tmp_file != NULL) && (*tmp_file != (char) NULL))
+ wprintw(com_win, file_read_fin_msg, tmp_file);
+ }
+ wrefresh(com_win);
+ wmove(text_win, scr_vert, (scr_horz - horiz_offset));
+ wrefresh(text_win);
+}
+
+void
+get_file(file_name) /* read specified file into current buffer */
+char *file_name;
+{
+ int can_read; /* file has at least one character */
+ int length; /* length of line read by read */
+ int append; /* should text be appended to current line */
+ struct text *temp_line;
+ char ro_flag = FALSE;
+
+ if (recv_file) /* if reading a file */
+ {
+ wmove(com_win, 0, 0);
+ wclrtoeol(com_win);
+ wprintw(com_win, reading_file_msg, file_name);
+ if (access(file_name, 2)) /* check permission to write */
+ {
+ if ((errno == ENOTDIR) || (errno == EACCES) || (errno == EROFS) || (errno == ETXTBSY) || (errno == EFAULT))
+ {
+ wprintw(com_win, read_only_msg);
+ ro_flag = TRUE;
+ }
+ }
+ wrefresh(com_win);
+ }
+ if (curr_line->line_length > 1) /* if current line is not blank */
+ {
+ insert_line(FALSE);
+ left(FALSE);
+ append = FALSE;
+ }
+ else
+ append = TRUE;
+ can_read = FALSE; /* test if file has any characters */
+ while (((length = read(get_fd, in_string, 512)) != 0) && (length != -1))
+ {
+ can_read = TRUE; /* if set file has at least 1 character */
+ get_line(length, in_string, &append);
+ }
+ if ((can_read) && (curr_line->line_length == 1))
+ {
+ temp_line = curr_line->prev_line;
+ temp_line->next_line = curr_line->next_line;
+ if (temp_line->next_line != NULL)
+ temp_line->next_line->prev_line = temp_line;
+ if (curr_line->line != NULL)
+ free(curr_line->line);
+ free(curr_line);
+ curr_line = temp_line;
+ }
+ if (input_file) /* if this is the file to be edited display number of lines */
+ {
+ wmove(com_win, 0, 0);
+ wclrtoeol(com_win);
+ wprintw(com_win, file_read_lines_msg, in_file_name, curr_line->line_number);
+ if (ro_flag)
+ wprintw(com_win, read_only_msg);
+ wrefresh(com_win);
+ }
+ else if (can_read) /* not input_file and file is non-zero size */
+ text_changes = TRUE;
+
+ if (recv_file) /* if reading a file */
+ {
+ in = EOF;
+ }
+}
+
+void
+get_line(length, in_string, append) /* read string and split into lines */
+int length; /* length of string read by read */
+unsigned char *in_string; /* string read by read */
+int *append; /* TRUE if must append more text to end of current line */
+{
+ unsigned char *str1;
+ unsigned char *str2;
+ int num; /* offset from start of string */
+ int char_count; /* length of new line (or added portion */
+ int temp_counter; /* temporary counter value */
+ struct text *tline; /* temporary pointer to new line */
+ int first_time; /* if TRUE, the first time through the loop */
+
+ str2 = in_string;
+ num = 0;
+ first_time = TRUE;
+ while (num < length)
+ {
+ if (!first_time)
+ {
+ if (num < length)
+ {
+ str2++;
+ num++;
+ }
+ }
+ else
+ first_time = FALSE;
+ str1 = str2;
+ char_count = 1;
+ /* find end of line */
+ while ((*str2 != '\n') && (num < length))
+ {
+ str2++;
+ num++;
+ char_count++;
+ }
+ if (!(*append)) /* if not append to current line, insert new one */
+ {
+ tline = txtalloc(); /* allocate data structure for next line */
+ tline->line_number = curr_line->line_number + 1;
+ tline->next_line = curr_line->next_line;
+ tline->prev_line = curr_line;
+ curr_line->next_line = tline;
+ if (tline->next_line != NULL)
+ tline->next_line->prev_line = tline;
+ curr_line = tline;
+ curr_line->line = point = (unsigned char *) malloc(char_count);
+ curr_line->line_length = char_count;
+ curr_line->max_length = char_count;
+ }
+ else
+ {
+ point = resiz_line(char_count, curr_line, curr_line->line_length);
+ curr_line->line_length += (char_count - 1);
+ }
+ for (temp_counter = 1; temp_counter < char_count; temp_counter++)
+ {
+ *point = *str1;
+ point++;
+ str1++;
+ }
+ *point = (char) NULL;
+ *append = FALSE;
+ if ((num == length) && (*str2 != '\n'))
+ *append = TRUE;
+ }
+}
+
+void
+draw_screen() /* redraw the screen from current postion */
+{
+ struct text *temp_line;
+ unsigned char *line_out;
+ int temp_vert;
+
+ temp_line = curr_line;
+ temp_vert = scr_vert;
+ wclrtobot(text_win);
+ while ((temp_line != NULL) && (temp_vert <= last_line))
+ {
+ line_out = temp_line->line;
+ draw_line(temp_vert, 0, line_out, 1, temp_line->line_length);
+ temp_vert++;
+ temp_line = temp_line->next_line;
+ }
+ wmove(text_win, temp_vert, 0);
+ wmove(text_win, scr_vert, (scr_horz - horiz_offset));
+}
+
+void
+finish() /* prepare to exit edit session */
+{
+ char *file_name = in_file_name;
+
+ /*
+ | changes made here should be reflected in the 'save'
+ | portion of file_op()
+ */
+
+ if ((file_name == NULL) || (*file_name == (char) NULL))
+ file_name = get_string(save_file_name_prompt, TRUE);
+
+ if ((file_name == NULL) || (*file_name == (char) NULL))
+ {
+ wmove(com_win, 0, 0);
+ wprintw(com_win, file_not_saved_msg);
+ wclrtoeol(com_win);
+ wrefresh(com_win);
+ clear_com_win = TRUE;
+ return;
+ }
+
+ tmp_file = resolve_name(file_name);
+ if (tmp_file != file_name)
+ {
+ free(file_name);
+ file_name = tmp_file;
+ }
+
+ if (write_file(file_name))
+ {
+ text_changes = FALSE;
+ quit(0);
+ }
+}
+
+int
+quit(noverify) /* exit editor */
+int noverify;
+{
+ char *ans;
+
+ touchwin(text_win);
+ wrefresh(text_win);
+ if ((text_changes) && (!noverify))
+ {
+ ans = get_string(changes_made_prompt, TRUE);
+ if (toupper(*ans) == toupper(*yes_char))
+ text_changes = FALSE;
+ else
+ return(0);
+ free(ans);
+ }
+ if (top_of_stack == NULL)
+ {
+ if (info_window)
+ wrefresh(info_win);
+ wrefresh(com_win);
+ resetty();
+ endwin();
+ putchar('\n');
+ exit(0);
+ }
+ else
+ {
+ delete_text();
+ recv_file = TRUE;
+ input_file = TRUE;
+ check_fp();
+ }
+ return(0);
+}
+
+void
+edit_abort(arg)
+int arg;
+{
+ wrefresh(com_win);
+ resetty();
+ endwin();
+ putchar('\n');
+ exit(1);
+}
+
+void
+delete_text()
+{
+ while (curr_line->next_line != NULL)
+ curr_line = curr_line->next_line;
+ while (curr_line != first_line)
+ {
+ free(curr_line->line);
+ curr_line = curr_line->prev_line;
+ free(curr_line->next_line);
+ }
+ curr_line->next_line = NULL;
+ *curr_line->line = (char) NULL;
+ curr_line->line_length = 1;
+ curr_line->line_number = 1;
+ point = curr_line->line;
+ scr_pos = scr_vert = scr_horz = 0;
+ position = 1;
+}
+
+int
+write_file(file_name)
+char *file_name;
+{
+ char cr;
+ char *tmp_point;
+ struct text *out_line;
+ int lines, charac;
+ int temp_pos;
+ int write_flag = TRUE;
+
+ charac = lines = 0;
+ if ((in_file_name == NULL) || strcmp(in_file_name, file_name))
+ {
+ if ((temp_fp = fopen(file_name, "r")))
+ {
+ tmp_point = get_string(file_exists_prompt, TRUE);
+ if (toupper(*tmp_point) == toupper(*yes_char))
+ write_flag = TRUE;
+ else
+ write_flag = FALSE;
+ fclose(temp_fp);
+ free(tmp_point);
+ }
+ }
+
+ clear_com_win = TRUE;
+
+ if (write_flag)
+ {
+ if ((temp_fp = fopen(file_name, "w")) == NULL)
+ {
+ clear_com_win = TRUE;
+ wmove(com_win,0,0);
+ wclrtoeol(com_win);
+ wprintw(com_win, create_file_fail_msg, file_name);
+ wrefresh(com_win);
+ return(FALSE);
+ }
+ else
+ {
+ wmove(com_win,0,0);
+ wclrtoeol(com_win);
+ wprintw(com_win, writing_file_msg, file_name);
+ wrefresh(com_win);
+ cr = '\n';
+ out_line = first_line;
+ while (out_line != NULL)
+ {
+ temp_pos = 1;
+ tmp_point= out_line->line;
+ while (temp_pos < out_line->line_length)
+ {
+ putc(*tmp_point, temp_fp);
+ tmp_point++;
+ temp_pos++;
+ }
+ charac += out_line->line_length;
+ out_line = out_line->next_line;
+ putc(cr, temp_fp);
+ lines++;
+ }
+ fclose(temp_fp);
+ wmove(com_win,0,0);
+ wclrtoeol(com_win);
+ wprintw(com_win, file_written_msg, file_name, lines, charac);
+ wrefresh(com_win);
+ return(TRUE);
+ }
+ }
+ else
+ return(FALSE);
+}
+
+int
+search(display_message) /* search for string in srch_str */
+int display_message;
+{
+ int lines_moved;
+ int iter;
+ int found;
+
+ if ((srch_str == NULL) || (*srch_str == (char) NULL))
+ return(FALSE);
+ if (display_message)
+ {
+ wmove(com_win, 0, 0);
+ wclrtoeol(com_win);
+ wprintw(com_win, searching_msg);
+ wrefresh(com_win);
+ clear_com_win = TRUE;
+ }
+ lines_moved = 0;
+ found = FALSE;
+ srch_line = curr_line;
+ srch_1 = point;
+ if (position < curr_line->line_length)
+ srch_1++;
+ iter = position + 1;
+ while ((!found) && (srch_line != NULL))
+ {
+ while ((iter < srch_line->line_length) && (!found))
+ {
+ srch_2 = srch_1;
+ if (case_sen) /* if case sensitive */
+ {
+ srch_3 = srch_str;
+ while ((*srch_2 == *srch_3) && (*srch_3 != (char) NULL))
+ {
+ found = TRUE;
+ srch_2++;
+ srch_3++;
+ } /* end while */
+ }
+ else /* if not case sensitive */
+ {
+ srch_3 = u_srch_str;
+ while ((toupper(*srch_2) == *srch_3) && (*srch_3 != (char) NULL))
+ {
+ found = TRUE;
+ srch_2++;
+ srch_3++;
+ }
+ } /* end else */
+ if (!((*srch_3 == (char) NULL) && (found)))
+ {
+ found = FALSE;
+ if (iter < srch_line->line_length)
+ srch_1++;
+ iter++;
+ }
+ }
+ if (!found)
+ {
+ srch_line = srch_line->next_line;
+ if (srch_line != NULL)
+ srch_1 = srch_line->line;
+ iter = 1;
+ lines_moved++;
+ }
+ }
+ if (found)
+ {
+ if (display_message)
+ {
+ wmove(com_win, 0, 0);
+ wclrtoeol(com_win);
+ wrefresh(com_win);
+ }
+ if (lines_moved == 0)
+ {
+ while (position < iter)
+ right(TRUE);
+ }
+ else
+ {
+ if (lines_moved < 30)
+ {
+ move_rel("d", lines_moved);
+ while (position < iter)
+ right(TRUE);
+ }
+ else
+ {
+ curr_line = srch_line;
+ point = srch_1;
+ position = iter;
+ scanline(point);
+ scr_pos = scr_horz;
+ midscreen((last_line / 2), point);
+ }
+ }
+ }
+ else
+ {
+ if (display_message)
+ {
+ wmove(com_win, 0, 0);
+ wclrtoeol(com_win);
+ wprintw(com_win, str_not_found_msg, srch_str);
+ wrefresh(com_win);
+ }
+ wmove(text_win, scr_vert,(scr_horz - horiz_offset));
+ }
+ return(found);
+}
+
+void
+search_prompt() /* prompt and read search string (srch_str) */
+{
+ if (srch_str != NULL)
+ free(srch_str);
+ if ((u_srch_str != NULL) && (*u_srch_str != (char) NULL))
+ free(u_srch_str);
+ srch_str = get_string(search_prompt_str, FALSE);
+ gold = FALSE;
+ srch_3 = srch_str;
+ srch_1 = u_srch_str = malloc(strlen(srch_str) + 1);
+ while (*srch_3 != (char) NULL)
+ {
+ *srch_1 = toupper(*srch_3);
+ srch_1++;
+ srch_3++;
+ }
+ *srch_1 = (char) NULL;
+ search(TRUE);
+}
+
+void
+del_char() /* delete current character */
+{
+ in = 8; /* backspace */
+ if (position < curr_line->line_length) /* if not end of line */
+ {
+ if ((ee_chinese) && (*point > 127) &&
+ ((curr_line->line_length - position) >= 2))
+ {
+ point++;
+ position++;
+ }
+ position++;
+ point++;
+ scanline(point);
+ delete(TRUE);
+ }
+ else
+ {
+ right(FALSE);
+ delete(FALSE);
+ }
+}
+
+void
+undel_char() /* undelete last deleted character */
+{
+ if (d_char[0] == '\n') /* insert line if last del_char deleted eol */
+ insert_line(TRUE);
+ else
+ {
+ in = d_char[0];
+ insert(in);
+ if (d_char[1] != (unsigned char) NULL)
+ {
+ in = d_char[1];
+ insert(in);
+ }
+ }
+}
+
+void
+del_word() /* delete word in front of cursor */
+{
+ int tposit;
+ int difference;
+ unsigned char *d_word2;
+ unsigned char *d_word3;
+ unsigned char tmp_char[3];
+
+ if (d_word != NULL)
+ free(d_word);
+ d_word = malloc(curr_line->line_length);
+ tmp_char[0] = d_char[0];
+ tmp_char[1] = d_char[1];
+ tmp_char[2] = d_char[2];
+ d_word3 = point;
+ d_word2 = d_word;
+ tposit = position;
+ while ((tposit < curr_line->line_length) &&
+ ((*d_word3 != ' ') && (*d_word3 != '\t')))
+ {
+ tposit++;
+ *d_word2 = *d_word3;
+ d_word2++;
+ d_word3++;
+ }
+ while ((tposit < curr_line->line_length) &&
+ ((*d_word3 == ' ') || (*d_word3 == '\t')))
+ {
+ tposit++;
+ *d_word2 = *d_word3;
+ d_word2++;
+ d_word3++;
+ }
+ *d_word2 = (char) NULL;
+ d_wrd_len = difference = d_word2 - d_word;
+ d_word2 = point;
+ while (tposit < curr_line->line_length)
+ {
+ tposit++;
+ *d_word2 = *d_word3;
+ d_word2++;
+ d_word3++;
+ }
+ curr_line->line_length -= difference;
+ *d_word2 = (char) NULL;
+ draw_line(scr_vert, scr_horz,point,position,curr_line->line_length);
+ d_char[0] = tmp_char[0];
+ d_char[1] = tmp_char[1];
+ d_char[2] = tmp_char[2];
+ text_changes = TRUE;
+ formatted = FALSE;
+}
+
+void
+undel_word() /* undelete last deleted word */
+{
+ int temp;
+ int tposit;
+ unsigned char *tmp_old_ptr;
+ unsigned char *tmp_space;
+ unsigned char *tmp_ptr;
+ unsigned char *d_word_ptr;
+
+ /*
+ | resize line to handle undeleted word
+ */
+ if ((curr_line->max_length - (curr_line->line_length + d_wrd_len)) < 5)
+ point = resiz_line(d_wrd_len, curr_line, position);
+ tmp_ptr = tmp_space = malloc(curr_line->line_length + d_wrd_len);
+ d_word_ptr = d_word;
+ temp = 1;
+ /*
+ | copy d_word contents into temp space
+ */
+ while (temp <= d_wrd_len)
+ {
+ temp++;
+ *tmp_ptr = *d_word_ptr;
+ tmp_ptr++;
+ d_word_ptr++;
+ }
+ tmp_old_ptr = point;
+ tposit = position;
+ /*
+ | copy contents of line from curent position to eol into
+ | temp space
+ */
+ while (tposit < curr_line->line_length)
+ {
+ temp++;
+ tposit++;
+ *tmp_ptr = *tmp_old_ptr;
+ tmp_ptr++;
+ tmp_old_ptr++;
+ }
+ curr_line->line_length += d_wrd_len;
+ tmp_old_ptr = point;
+ *tmp_ptr = (char) NULL;
+ tmp_ptr = tmp_space;
+ tposit = 1;
+ /*
+ | now copy contents from temp space back to original line
+ */
+ while (tposit < temp)
+ {
+ tposit++;
+ *tmp_old_ptr = *tmp_ptr;
+ tmp_ptr++;
+ tmp_old_ptr++;
+ }
+ *tmp_old_ptr = (char) NULL;
+ free(tmp_space);
+ draw_line(scr_vert, scr_horz, point, position, curr_line->line_length);
+}
+
+void
+del_line() /* delete from cursor to end of line */
+{
+ unsigned char *dl1;
+ unsigned char *dl2;
+ int tposit;
+
+ if (d_line != NULL)
+ free(d_line);
+ d_line = malloc(curr_line->line_length);
+ dl1 = d_line;
+ dl2 = point;
+ tposit = position;
+ while (tposit < curr_line->line_length)
+ {
+ *dl1 = *dl2;
+ dl1++;
+ dl2++;
+ tposit++;
+ }
+ dlt_line->line_length = 1 + tposit - position;
+ *dl1 = (char) NULL;
+ *point = (char) NULL;
+ curr_line->line_length = position;
+ wclrtoeol(text_win);
+ if (curr_line->next_line != NULL)
+ {
+ right(FALSE);
+ delete(FALSE);
+ }
+ text_changes = TRUE;
+}
+
+void
+undel_line() /* undelete last deleted line */
+{
+ unsigned char *ud1;
+ unsigned char *ud2;
+ int tposit;
+
+ if (dlt_line->line_length == 0)
+ return;
+
+ insert_line(TRUE);
+ left(TRUE);
+ point = resiz_line(dlt_line->line_length, curr_line, position);
+ curr_line->line_length += dlt_line->line_length - 1;
+ ud1 = point;
+ ud2 = d_line;
+ tposit = 1;
+ while (tposit < dlt_line->line_length)
+ {
+ tposit++;
+ *ud1 = *ud2;
+ ud1++;
+ ud2++;
+ }
+ *ud1 = (char) NULL;
+ draw_line(scr_vert, scr_horz,point,position,curr_line->line_length);
+}
+
+void
+adv_word() /* advance to next word */
+{
+while ((position < curr_line->line_length) && ((*point != 32) && (*point != 9)))
+ right(TRUE);
+while ((position < curr_line->line_length) && ((*point == 32) || (*point == 9)))
+ right(TRUE);
+}
+
+void
+move_rel(direction, lines) /* move relative to current line */
+char *direction;
+int lines;
+{
+ int i;
+ char *tmp;
+
+ if (*direction == 'u')
+ {
+ scr_pos = 0;
+ while (position > 1)
+ left(TRUE);
+ for (i = 0; i < lines; i++)
+ {
+ up();
+ }
+ if ((last_line > 5) && ( scr_vert < 4))
+ {
+ tmp = point;
+ tmp_line = curr_line;
+ for (i= 0;(i<5)&&(curr_line->prev_line != NULL); i++)
+ {
+ up();
+ }
+ scr_vert = scr_vert + i;
+ curr_line = tmp_line;
+ point = tmp;
+ scanline(point);
+ }
+ }
+ else
+ {
+ if ((position != 1) && (curr_line->next_line != NULL))
+ {
+ nextline();
+ scr_pos = scr_horz = 0;
+ if (horiz_offset)
+ {
+ horiz_offset = 0;
+ midscreen(scr_vert, point);
+ }
+ }
+ else
+ adv_line();
+ for (i = 1; i < lines; i++)
+ {
+ down();
+ }
+ if ((last_line > 10) && (scr_vert > (last_line - 5)))
+ {
+ tmp = point;
+ tmp_line = curr_line;
+ for (i=0; (i<5) && (curr_line->next_line != NULL); i++)
+ {
+ down();
+ }
+ scr_vert = scr_vert - i;
+ curr_line = tmp_line;
+ point = tmp;
+ scanline(point);
+ }
+ }
+ wmove(text_win, scr_vert, (scr_horz - horiz_offset));
+}
+
+void
+eol() /* go to end of line */
+{
+ if (position < curr_line->line_length)
+ {
+ while (position < curr_line->line_length)
+ right(TRUE);
+ }
+ else if (curr_line->next_line != NULL)
+ {
+ right(TRUE);
+ while (position < curr_line->line_length)
+ right(TRUE);
+ }
+}
+
+void
+bol() /* move to beginning of line */
+{
+ if (point != curr_line->line)
+ {
+ while (point != curr_line->line)
+ left(TRUE);
+ }
+ else if (curr_line->prev_line != NULL)
+ {
+ scr_pos = 0;
+ up();
+ }
+}
+
+void
+adv_line() /* advance to beginning of next line */
+{
+ if ((point != curr_line->line) || (scr_pos > 0))
+ {
+ while (position < curr_line->line_length)
+ right(TRUE);
+ right(TRUE);
+ }
+ else if (curr_line->next_line != NULL)
+ {
+ scr_pos = 0;
+ down();
+ }
+}
+
+void
+sh_command(string) /* execute shell command */
+char *string; /* string containing user command */
+{
+ char *temp_point;
+ char *last_slash;
+ char *path; /* directory path to executable */
+ int parent; /* zero if child, child's pid if parent */
+ int value;
+ int return_val;
+ struct text *line_holder;
+
+ if (restrict_mode())
+ {
+ return;
+ }
+
+ if (!(path = getenv("SHELL")))
+ path = "/bin/sh";
+ last_slash = temp_point = path;
+ while (*temp_point != (char) NULL)
+ {
+ if (*temp_point == '/')
+ last_slash = ++temp_point;
+ else
+ temp_point++;
+ }
+
+ /*
+ | if in_pipe is true, then output of the shell operation will be
+ | read by the editor, and curses doesn't need to be turned off
+ */
+
+ if (!in_pipe)
+ {
+ keypad(com_win, FALSE);
+ keypad(text_win, FALSE);
+ echo();
+ nl();
+ noraw();
+ resetty();
+
+#ifndef NCURSE
+ endwin();
+#endif
+ }
+
+ if (in_pipe)
+ {
+ pipe(pipe_in); /* create a pipe */
+ parent = fork();
+ if (!parent) /* if the child */
+ {
+/*
+ | child process which will fork and exec shell command (if shell output is
+ | to be read by editor)
+ */
+ in_pipe = FALSE;
+/*
+ | redirect stdout to pipe
+ */
+ temp_stdout = dup(1);
+ close(1);
+ dup(pipe_in[1]);
+/*
+ | redirect stderr to pipe
+ */
+ temp_stderr = dup(2);
+ close(2);
+ dup(pipe_in[1]);
+ close(pipe_in[1]);
+ /*
+ | child will now continue down 'if (!in_pipe)'
+ | path below
+ */
+ }
+ else /* if the parent */
+ {
+/*
+ | prepare editor to read from the pipe
+ */
+ signal(SIGCHLD, SIG_IGN);
+ line_holder = curr_line;
+ tmp_vert = scr_vert;
+ close(pipe_in[1]);
+ get_fd = pipe_in[0];
+ get_file("");
+ close(pipe_in[0]);
+ scr_vert = tmp_vert;
+ scr_horz = scr_pos = 0;
+ position = 1;
+ curr_line = line_holder;
+ point = curr_line->line;
+ out_pipe = FALSE;
+ signal(SIGCHLD, SIG_DFL);
+/*
+ | since flag "in_pipe" is still TRUE, the path which waits for the child
+ | process to die will be avoided.
+ | (the pipe is closed, no more output can be expected)
+ */
+ }
+ }
+ if (!in_pipe)
+ {
+ signal(SIGINT, SIG_IGN);
+ if (out_pipe)
+ {
+ pipe(pipe_out);
+ }
+/*
+ | fork process which will exec command
+ */
+ parent = fork();
+ if (!parent) /* if the child */
+ {
+ if (shell_fork)
+ putchar('\n');
+ if (out_pipe)
+ {
+/*
+ | prepare the child process (soon to exec a shell command) to read from the
+ | pipe (which will be output from the editor's buffer)
+ */
+ close(0);
+ dup(pipe_out[0]);
+ close(pipe_out[0]);
+ close(pipe_out[1]);
+ }
+ for (value = 1; value < 24; value++)
+ signal(value, SIG_DFL);
+ execl(path, last_slash, "-c", string, NULL);
+ printf(exec_err_msg, path);
+ exit(-1);
+ }
+ else /* if the parent */
+ {
+ if (out_pipe)
+ {
+/*
+ | output the contents of the buffer to the pipe (to be read by the
+ | process forked and exec'd above as stdin)
+ */
+ close(pipe_out[0]);
+ line_holder = first_line;
+ while (line_holder != NULL)
+ {
+ write(pipe_out[1], line_holder->line, (line_holder->line_length-1));
+ write(pipe_out[1], "\n", 1);
+ line_holder = line_holder->next_line;
+ }
+ close(pipe_out[1]);
+ out_pipe = FALSE;
+ }
+ do
+ {
+ return_val = wait((int *) 0);
+ }
+ while ((return_val != parent) && (return_val != -1));
+/*
+ | if this process is actually the child of the editor, exit. Here's how it
+ | works:
+ | The editor forks a process. If output must be sent to the command to be
+ | exec'd another process is forked, and that process (the child's child)
+ | will exec the command. In this case, "shell_fork" will be FALSE. If no
+ | output is to be performed to the shell command, "shell_fork" will be TRUE.
+ | If this is the editor process, shell_fork will be true, otherwise this is
+ | the child of the edit process.
+ */
+ if (!shell_fork)
+ exit(0);
+ }
+ signal(SIGINT, edit_abort);
+ }
+ if (shell_fork)
+ {
+ printf(continue_msg);
+ fflush(stdout);
+ while ((in = getchar()) != '\n')
+ ;
+ }
+
+ if (!in_pipe)
+ {
+ fixterm();
+ noecho();
+ nonl();
+ raw();
+ keypad(text_win, TRUE);
+ keypad(com_win, TRUE);
+ if (info_window)
+ clearok(info_win, TRUE);
+ }
+
+ redraw();
+}
+
+void
+set_up_term() /* set up the terminal for operating with ae */
+{
+ if (!curses_initialized)
+ {
+ initscr();
+ savetty();
+ noecho();
+ raw();
+ nonl();
+ curses_initialized = TRUE;
+ }
+
+ if (((LINES > 15) && (COLS >= 80)) && info_window)
+ last_line = LINES - 8;
+ else
+ {
+ info_window = FALSE;
+ last_line = LINES - 2;
+ }
+
+ idlok(stdscr, TRUE);
+ com_win = newwin(1, COLS, (LINES - 1), 0);
+ keypad(com_win, TRUE);
+ idlok(com_win, TRUE);
+ wrefresh(com_win);
+ if (!info_window)
+ text_win = newwin((LINES - 1), COLS, 0, 0);
+ else
+ text_win = newwin((LINES - 7), COLS, 6, 0);
+ keypad(text_win, TRUE);
+ idlok(text_win, TRUE);
+ wrefresh(text_win);
+ help_win = newwin((LINES - 1), COLS, 0, 0);
+ keypad(help_win, TRUE);
+ idlok(help_win, TRUE);
+ if (info_window)
+ {
+ info_type = CONTROL_KEYS;
+ info_win = newwin(6, COLS, 0, 0);
+ werase(info_win);
+ paint_info_win();
+ }
+
+ last_col = COLS - 1;
+ local_LINES = LINES;
+ local_COLS = COLS;
+
+#ifdef NCURSE
+ if (ee_chinese)
+ nc_setattrib(A_NC_BIG5);
+#endif /* NCURSE */
+
+}
+
+void
+resize_check()
+{
+ if ((LINES == local_LINES) && (COLS == local_COLS))
+ return;
+
+ if (info_window)
+ delwin(info_win);
+ delwin(text_win);
+ delwin(com_win);
+ delwin(help_win);
+ set_up_term();
+ redraw();
+ wrefresh(text_win);
+}
+
+static char item_alpha[] = "abcdefghijklmnopqrstuvwxyz0123456789 ";
+
+int
+menu_op(menu_list)
+struct menu_entries menu_list[];
+{
+ WINDOW *temp_win;
+ int max_width, max_height;
+ int x_off, y_off;
+ int counter;
+ int length;
+ int input;
+ int temp;
+ int list_size;
+ int top_offset; /* offset from top where menu items start */
+ int vert_pos; /* vertical position */
+ int vert_size; /* vertical size for menu list item display */
+ int off_start = 1; /* offset from start of menu items to start display */
+
+
+ /*
+ | determine number and width of menu items
+ */
+
+ list_size = 1;
+ while (menu_list[list_size + 1].item_string != NULL)
+ list_size++;
+ max_width = 0;
+ for (counter = 0; counter <= list_size; counter++)
+ {
+ if ((length = strlen(menu_list[counter].item_string)) > max_width)
+ max_width = length;
+ }
+ max_width += 3;
+ max_width = max(max_width, strlen(menu_cancel_msg));
+ max_width = max(max_width, max(strlen(more_above_str), strlen(more_below_str)));
+ max_width += 6;
+
+ /*
+ | make sure that window is large enough to handle menu
+ | if not, print error message and return to calling function
+ */
+
+ if (max_width > COLS)
+ {
+ wmove(com_win, 0, 0);
+ werase(com_win);
+ wprintw(com_win, menu_too_lrg_msg);
+ wrefresh(com_win);
+ clear_com_win = TRUE;
+ return(0);
+ }
+
+ top_offset = 0;
+
+ if (list_size > LINES)
+ {
+ max_height = LINES;
+ if (max_height > 11)
+ vert_size = max_height - 8;
+ else
+ vert_size = max_height;
+ }
+ else
+ {
+ vert_size = list_size;
+ max_height = list_size;
+ }
+
+ if (LINES >= (vert_size + 8))
+ {
+ if (menu_list[0].argument != MENU_WARN)
+ max_height = vert_size + 8;
+ else
+ max_height = vert_size + 7;
+ top_offset = 4;
+ }
+ x_off = (COLS - max_width) / 2;
+ y_off = (LINES - max_height - 1) / 2;
+ temp_win = newwin(max_height, max_width, y_off, x_off);
+ keypad(temp_win, TRUE);
+
+ paint_menu(menu_list, max_width, max_height, list_size, top_offset, temp_win, off_start, vert_size);
+
+ counter = 1;
+ vert_pos = 0;
+ do
+ {
+ if (off_start > 2)
+ wmove(temp_win, (1 + counter + top_offset - off_start), 3);
+ else
+ wmove(temp_win, (counter + top_offset - off_start), 3);
+
+ wrefresh(temp_win);
+ in = wgetch(temp_win);
+ input = in;
+ if (input == -1)
+ exit(0);
+
+ if (((tolower(input) >= 'a') && (tolower(input) <= 'z')) ||
+ ((input >= '0') && (input <= '9')))
+ {
+ if ((tolower(input) >= 'a') && (tolower(input) <= 'z'))
+ {
+ temp = 1 + tolower(input) - 'a';
+ }
+ else if ((input >= '0') && (input <= '9'))
+ {
+ temp = (2 + 'z' - 'a') + (input - '0');
+ }
+
+ if (temp <= list_size)
+ {
+ input = '\n';
+ counter = temp;
+ }
+ }
+ else
+ {
+ switch (input)
+ {
+ case ' ': /* space */
+ case '\004': /* ^d, down */
+ case KEY_RIGHT:
+ case KEY_DOWN:
+ counter++;
+ if (counter > list_size)
+ counter = 1;
+ break;
+ case '\010': /* ^h, backspace*/
+ case '\025': /* ^u, up */
+ case 127: /* ^?, delete */
+ case KEY_BACKSPACE:
+ case KEY_LEFT:
+ case KEY_UP:
+ counter--;
+ if (counter == 0)
+ counter = list_size;
+ break;
+ case '\033': /* escape key */
+ if (menu_list[0].argument != MENU_WARN)
+ counter = 0;
+ break;
+ case '\014': /* ^l */
+ case '\022': /* ^r, redraw */
+ paint_menu(menu_list, max_width, max_height,
+ list_size, top_offset, temp_win,
+ off_start, vert_size);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (((list_size - off_start) >= (vert_size - 1)) &&
+ (counter > (off_start + vert_size - 3)) &&
+ (off_start > 1))
+ {
+ if (counter == list_size)
+ off_start = (list_size - vert_size) + 2;
+ else
+ off_start++;
+
+ paint_menu(menu_list, max_width, max_height,
+ list_size, top_offset, temp_win, off_start,
+ vert_size);
+ }
+ else if ((list_size != vert_size) &&
+ (counter > (off_start + vert_size - 2)))
+ {
+ if (counter == list_size)
+ off_start = 2 + (list_size - vert_size);
+ else if (off_start == 1)
+ off_start = 3;
+ else
+ off_start++;
+
+ paint_menu(menu_list, max_width, max_height,
+ list_size, top_offset, temp_win, off_start,
+ vert_size);
+ }
+ else if (counter < off_start)
+ {
+ if (counter <= 2)
+ off_start = 1;
+ else
+ off_start = counter;
+
+ paint_menu(menu_list, max_width, max_height,
+ list_size, top_offset, temp_win, off_start,
+ vert_size);
+ }
+ }
+ while ((input != '\r') && (input != '\n') && (counter != 0));
+
+ werase(temp_win);
+ wrefresh(temp_win);
+ delwin(temp_win);
+
+ if ((menu_list[counter].procedure != NULL) ||
+ (menu_list[counter].iprocedure != NULL) ||
+ (menu_list[counter].nprocedure != NULL))
+ {
+ if (menu_list[counter].argument != -1)
+ (*menu_list[counter].iprocedure)(menu_list[counter].argument);
+ else if (menu_list[counter].ptr_argument != NULL)
+ (*menu_list[counter].procedure)(menu_list[counter].ptr_argument);
+ else
+ (*menu_list[counter].nprocedure)();
+ }
+
+ if (info_window)
+ paint_info_win();
+ redraw();
+
+ return(counter);
+}
+
+void
+paint_menu(menu_list, max_width, max_height, list_size, top_offset, menu_win,
+ off_start, vert_size)
+struct menu_entries menu_list[];
+int max_width, max_height, list_size, top_offset;
+WINDOW *menu_win;
+int off_start, vert_size;
+{
+ int counter, temp_int;
+
+ werase(menu_win);
+
+ /*
+ | output top and bottom portions of menu box only if window
+ | large enough
+ */
+
+ if (max_height > vert_size)
+ {
+ wmove(menu_win, 1, 1);
+ if (!nohighlight)
+ wstandout(menu_win);
+ waddch(menu_win, '+');
+ for (counter = 0; counter < (max_width - 4); counter++)
+ waddch(menu_win, '-');
+ waddch(menu_win, '+');
+
+ wmove(menu_win, (max_height - 2), 1);
+ waddch(menu_win, '+');
+ for (counter = 0; counter < (max_width - 4); counter++)
+ waddch(menu_win, '-');
+ waddch(menu_win, '+');
+ wstandend(menu_win);
+ wmove(menu_win, 2, 3);
+ waddstr(menu_win, menu_list[0].item_string);
+ wmove(menu_win, (max_height - 3), 3);
+ if (menu_list[0].argument != MENU_WARN)
+ waddstr(menu_win, menu_cancel_msg);
+ }
+ if (!nohighlight)
+ wstandout(menu_win);
+
+ for (counter = 0; counter < (vert_size + top_offset); counter++)
+ {
+ if (top_offset == 4)
+ {
+ temp_int = counter + 2;
+ }
+ else
+ temp_int = counter;
+
+ wmove(menu_win, temp_int, 1);
+ waddch(menu_win, '|');
+ wmove(menu_win, temp_int, (max_width - 2));
+ waddch(menu_win, '|');
+ }
+ wstandend(menu_win);
+
+ if (list_size > vert_size)
+ {
+ if (off_start >= 3)
+ {
+ temp_int = 1;
+ wmove(menu_win, top_offset, 3);
+ waddstr(menu_win, more_above_str);
+ }
+ else
+ temp_int = 0;
+
+ for (counter = off_start;
+ ((temp_int + counter - off_start) < (vert_size - 1));
+ counter++)
+ {
+ wmove(menu_win, (top_offset + temp_int +
+ (counter - off_start)), 3);
+ if (list_size > 1)
+ wprintw(menu_win, "%c) ", item_alpha[min((counter - 1), max_alpha_char)]);
+ waddstr(menu_win, menu_list[counter].item_string);
+ }
+
+ wmove(menu_win, (top_offset + (vert_size - 1)), 3);
+
+ if (counter == list_size)
+ {
+ if (list_size > 1)
+ wprintw(menu_win, "%c) ", item_alpha[min((counter - 1), max_alpha_char)]);
+ wprintw(menu_win, menu_list[counter].item_string);
+ }
+ else
+ wprintw(menu_win, more_below_str);
+ }
+ else
+ {
+ for (counter = 1; counter <= list_size; counter++)
+ {
+ wmove(menu_win, (top_offset + counter - 1), 3);
+ if (list_size > 1)
+ wprintw(menu_win, "%c) ", item_alpha[min((counter - 1), max_alpha_char)]);
+ waddstr(menu_win, menu_list[counter].item_string);
+ }
+ }
+}
+
+void
+help()
+{
+ int counter;
+
+ werase(help_win);
+ clearok(help_win, TRUE);
+ for (counter = 0; counter < 22; counter++)
+ {
+ wmove(help_win, counter, 0);
+ waddstr(help_win, (emacs_keys_mode) ?
+ emacs_help_text[counter] : help_text[counter]);
+ }
+ wrefresh(help_win);
+ werase(com_win);
+ wmove(com_win, 0, 0);
+ wprintw(com_win, press_any_key_msg);
+ wrefresh(com_win);
+ counter = wgetch(com_win);
+ if (counter == -1)
+ exit(0);
+ werase(com_win);
+ wmove(com_win, 0, 0);
+ werase(help_win);
+ wrefresh(help_win);
+ wrefresh(com_win);
+ redraw();
+}
+
+void
+paint_info_win()
+{
+ int counter;
+
+ if (!info_window)
+ return;
+
+ werase(info_win);
+ for (counter = 0; counter < 5; counter++)
+ {
+ wmove(info_win, counter, 0);
+ wclrtoeol(info_win);
+ if (info_type == CONTROL_KEYS)
+ waddstr(info_win, (emacs_keys_mode) ?
+ emacs_control_keys[counter] : control_keys[counter]);
+ else if (info_type == COMMANDS)
+ waddstr(info_win, command_strings[counter]);
+ }
+ wmove(info_win, 5, 0);
+ if (!nohighlight)
+ wstandout(info_win);
+ waddstr(info_win, "===============================================================================");
+ wstandend(info_win);
+ wrefresh(info_win);
+}
+
+void
+no_info_window()
+{
+ if (!info_window)
+ return;
+ delwin(info_win);
+ delwin(text_win);
+ info_window = FALSE;
+ last_line = LINES - 2;
+ text_win = newwin((LINES - 1), COLS, 0, 0);
+ keypad(text_win, TRUE);
+ idlok(text_win, TRUE);
+ clearok(text_win, TRUE);
+ midscreen(scr_vert, point);
+ wrefresh(text_win);
+ clear_com_win = TRUE;
+}
+
+void
+create_info_window()
+{
+ if (info_window)
+ return;
+ last_line = LINES - 8;
+ delwin(text_win);
+ text_win = newwin((LINES - 7), COLS, 6, 0);
+ keypad(text_win, TRUE);
+ idlok(text_win, TRUE);
+ werase(text_win);
+ info_window = TRUE;
+ info_win = newwin(6, COLS, 0, 0);
+ werase(info_win);
+ info_type = CONTROL_KEYS;
+ midscreen(min(scr_vert, last_line), point);
+ clearok(info_win, TRUE);
+ paint_info_win();
+ wrefresh(text_win);
+ clear_com_win = TRUE;
+}
+
+int
+file_op(arg)
+int arg;
+{
+ char *string;
+ int flag;
+
+ if (restrict_mode())
+ {
+ return(0);
+ }
+
+ if (arg == READ_FILE)
+ {
+ string = get_string(file_read_prompt_str, TRUE);
+ recv_file = TRUE;
+ tmp_file = resolve_name(string);
+ check_fp();
+ if (tmp_file != string)
+ free(tmp_file);
+ free(string);
+ }
+ else if (arg == WRITE_FILE)
+ {
+ string = get_string(file_write_prompt_str, TRUE);
+ tmp_file = resolve_name(string);
+ write_file(tmp_file);
+ if (tmp_file != string)
+ free(tmp_file);
+ free(string);
+ }
+ else if (arg == SAVE_FILE)
+ {
+ /*
+ | changes made here should be reflected in finish()
+ */
+
+ if (in_file_name)
+ flag = TRUE;
+ else
+ flag = FALSE;
+
+ string = in_file_name;
+ if ((string == NULL) || (*string == (char) NULL))
+ string = get_string(save_file_name_prompt, TRUE);
+ if ((string == NULL) || (*string == (char) NULL))
+ {
+ wmove(com_win, 0, 0);
+ wprintw(com_win, file_not_saved_msg);
+ wclrtoeol(com_win);
+ wrefresh(com_win);
+ clear_com_win = TRUE;
+ return(0);
+ }
+ if (!flag)
+ {
+ tmp_file = resolve_name(string);
+ if (tmp_file != string)
+ {
+ free(string);
+ string = tmp_file;
+ }
+ }
+ if (write_file(string))
+ {
+ in_file_name = string;
+ text_changes = FALSE;
+ }
+ else if (!flag)
+ free(string);
+ }
+ return(0);
+}
+
+void
+shell_op()
+{
+ char *string;
+
+ if (((string = get_string(shell_prompt, TRUE)) != NULL) &&
+ (*string != (char) NULL))
+ {
+ sh_command(string);
+ free(string);
+ }
+}
+
+void
+leave_op()
+{
+ if (text_changes)
+ {
+ menu_op(leave_menu);
+ }
+ else
+ quit(TRUE);
+}
+
+void
+redraw()
+{
+ if (info_window)
+ {
+ clearok(info_win, TRUE);
+ paint_info_win();
+ }
+ else
+ clearok(text_win, TRUE);
+ midscreen(scr_vert, point);
+}
+
+/*
+ | The following routines will "format" a paragraph (as defined by a
+ | block of text with blank lines before and after the block).
+ */
+
+int
+Blank_Line(test_line) /* test if line has any non-space characters */
+struct text *test_line;
+{
+ unsigned char *line;
+ int length;
+
+ if (test_line == NULL)
+ return(TRUE);
+
+ length = 1;
+ line = test_line->line;
+
+ /*
+ | To handle troff/nroff documents, consider a line with a
+ | period ('.') in the first column to be blank. To handle mail
+ | messages with included text, consider a line with a '>' blank.
+ */
+
+ if ((*line == '.') || (*line == '>'))
+ return(TRUE);
+
+ while (((*line == ' ') || (*line == '\t')) && (length < test_line->line_length))
+ {
+ length++;
+ line++;
+ }
+ if (length != test_line->line_length)
+ return(FALSE);
+ else
+ return(TRUE);
+}
+
+void
+Format() /* format the paragraph according to set margins */
+{
+ int string_count;
+ int offset;
+ int temp_case;
+ int status;
+ int tmp_af;
+ int counter;
+ unsigned char *line;
+ unsigned char *tmp_srchstr;
+ unsigned char *temp1, *temp2;
+ unsigned char *temp_dword;
+ unsigned char temp_d_char[3];
+
+ temp_d_char[0] = d_char[0];
+ temp_d_char[1] = d_char[1];
+ temp_d_char[2] = d_char[2];
+
+/*
+ | if observ_margins is not set, or the current line is blank,
+ | do not format the current paragraph
+ */
+
+ if ((!observ_margins) || (Blank_Line(curr_line)))
+ return;
+
+/*
+ | save the currently set flags, and clear them
+ */
+
+ wmove(com_win, 0, 0);
+ wclrtoeol(com_win);
+ wprintw(com_win, formatting_msg);
+ wrefresh(com_win);
+
+/*
+ | get current position in paragraph, so after formatting, the cursor
+ | will be in the same relative position
+ */
+
+ tmp_af = auto_format;
+ auto_format = FALSE;
+ offset = position;
+ if (position != 1)
+ prev_word();
+ temp_dword = d_word;
+ d_word = NULL;
+ temp_case = case_sen;
+ case_sen = TRUE;
+ tmp_srchstr = srch_str;
+ temp2 = srch_str = (unsigned char *) malloc(1 + curr_line->line_length - position);
+ if ((*point == ' ') || (*point == '\t'))
+ adv_word();
+ offset -= position;
+ counter = position;
+ line = temp1 = point;
+ while ((*temp1 != (char) NULL) && (*temp1 != ' ') && (*temp1 != '\t') && (counter < curr_line->line_length))
+ {
+ *temp2 = *temp1;
+ temp2++;
+ temp1++;
+ counter++;
+ }
+ *temp2 = (char) NULL;
+ if (position != 1)
+ bol();
+ while (!Blank_Line(curr_line->prev_line))
+ bol();
+ string_count = 0;
+ status = TRUE;
+ while ((line != point) && (status))
+ {
+ status = search(FALSE);
+ string_count++;
+ }
+
+ wmove(com_win, 0, 0);
+ wclrtoeol(com_win);
+ wprintw(com_win, formatting_msg);
+ wrefresh(com_win);
+
+/*
+ | now get back to the start of the paragraph to start formatting
+ */
+
+ if (position != 1)
+ bol();
+ while (!Blank_Line(curr_line->prev_line))
+ bol();
+
+ observ_margins = FALSE;
+
+/*
+ | Start going through lines, putting spaces at end of lines if they do
+ | not already exist. Append lines together to get one long line, and
+ | eliminate spacing at begin of lines.
+ */
+
+ while (!Blank_Line(curr_line->next_line))
+ {
+ eol();
+ left(TRUE);
+ if (*point != ' ')
+ {
+ right(TRUE);
+ insert(' ');
+ }
+ else
+ right(TRUE);
+ del_char();
+ if ((*point == ' ') || (*point == '\t'))
+ del_word();
+ }
+
+/*
+ | Now there is one long line. Eliminate extra spaces within the line
+ | after the first word (so as not to blow away any indenting the user
+ | may have put in).
+ */
+
+ bol();
+ adv_word();
+ while (position < curr_line->line_length)
+ {
+ if ((*point == ' ') && (*(point + 1) == ' '))
+ del_char();
+ else
+ right(TRUE);
+ }
+
+/*
+ | Now make sure there are two spaces after a '.'.
+ */
+
+ bol();
+ while (position < curr_line->line_length)
+ {
+ if ((*point == '.') && (*(point + 1) == ' '))
+ {
+ right(TRUE);
+ insert(' ');
+ insert(' ');
+ while (*point == ' ')
+ del_char();
+ }
+ right(TRUE);
+ }
+
+ observ_margins = TRUE;
+ bol();
+
+ wmove(com_win, 0, 0);
+ wclrtoeol(com_win);
+ wprintw(com_win, formatting_msg);
+ wrefresh(com_win);
+
+/*
+ | create lines between margins
+ */
+
+ while (position < curr_line->line_length)
+ {
+ while ((scr_pos < right_margin) && (position < curr_line->line_length))
+ right(TRUE);
+ if (position < curr_line->line_length)
+ {
+ prev_word();
+ if (position == 1)
+ adv_word();
+ insert_line(TRUE);
+ }
+ }
+
+/*
+ | go back to begin of paragraph, put cursor back to original position
+ */
+
+ bol();
+ while (!Blank_Line(curr_line->prev_line))
+ bol();
+
+/*
+ | find word cursor was in
+ */
+
+ while ((status) && (string_count > 0))
+ {
+ search(FALSE);
+ string_count--;
+ }
+
+/*
+ | offset the cursor to where it was before from the start of the word
+ */
+
+ while (offset > 0)
+ {
+ offset--;
+ right(TRUE);
+ }
+
+/*
+ | reset flags and strings to what they were before formatting
+ */
+
+ if (d_word != NULL)
+ free(d_word);
+ d_word = temp_dword;
+ case_sen = temp_case;
+ free(srch_str);
+ srch_str = tmp_srchstr;
+ d_char[0] = temp_d_char[0];
+ d_char[1] = temp_d_char[1];
+ d_char[2] = temp_d_char[2];
+ auto_format = tmp_af;
+
+ midscreen(scr_vert, point);
+ werase(com_win);
+ wrefresh(com_win);
+}
+
+unsigned char *init_name[3] = {
+ "/usr/local/lib/init.ee",
+ NULL,
+ ".init.ee"
+ };
+
+void
+ee_init() /* check for init file and read it if it exists */
+{
+ FILE *init_file;
+ unsigned char *string;
+ unsigned char *str1;
+ unsigned char *str2;
+ char *home;
+ int counter;
+ int temp_int;
+
+ string = getenv("HOME");
+ str1 = home = malloc(strlen(string)+10);
+ strcpy(home, string);
+ strcat(home, "/.init.ee");
+ init_name[1] = home;
+ string = malloc(512);
+
+ for (counter = 0; counter < 3; counter++)
+ {
+ if (!(access(init_name[counter], 4)))
+ {
+ init_file = fopen(init_name[counter], "r");
+ while ((str2 = fgets(string, 512, init_file)) != NULL)
+ {
+ str1 = str2 = string;
+ while (*str2 != '\n')
+ str2++;
+ *str2 = (char) NULL;
+
+ if (unique_test(string, init_strings) != 1)
+ continue;
+
+ if (compare(str1, CASE, FALSE))
+ case_sen = TRUE;
+ else if (compare(str1, NOCASE, FALSE))
+ case_sen = FALSE;
+ else if (compare(str1, EXPAND, FALSE))
+ expand_tabs = TRUE;
+ else if (compare(str1, NOEXPAND, FALSE))
+ expand_tabs = FALSE;
+ else if (compare(str1, INFO, FALSE))
+ info_window = TRUE;
+ else if (compare(str1, NOINFO, FALSE))
+ info_window = FALSE;
+ else if (compare(str1, MARGINS, FALSE))
+ observ_margins = TRUE;
+ else if (compare(str1, NOMARGINS, FALSE))
+ observ_margins = FALSE;
+ else if (compare(str1, AUTOFORMAT, FALSE))
+ {
+ auto_format = TRUE;
+ observ_margins = TRUE;
+ }
+ else if (compare(str1, NOAUTOFORMAT, FALSE))
+ auto_format = FALSE;
+ else if (compare(str1, Echo, FALSE))
+ {
+ str1 = next_word(str1);
+ if (*str1 != (char) NULL)
+ echo_string(str1);
+ }
+ else if (compare(str1, PRINTCOMMAND, FALSE))
+ {
+ str1 = next_word(str1);
+ print_command = malloc(strlen(str1)+1);
+ strcpy(print_command, str1);
+ }
+ else if (compare(str1, RIGHTMARGIN, FALSE))
+ {
+ str1 = next_word(str1);
+ if ((*str1 >= '0') && (*str1 <= '9'))
+ {
+ temp_int = atoi(str1);
+ if (temp_int > 0)
+ right_margin = temp_int;
+ }
+ }
+ else if (compare(str1, HIGHLIGHT, FALSE))
+ nohighlight = FALSE;
+ else if (compare(str1, NOHIGHLIGHT, FALSE))
+ nohighlight = TRUE;
+ else if (compare(str1, EIGHTBIT, FALSE))
+ eightbit = TRUE;
+ else if (compare(str1, NOEIGHTBIT, FALSE))
+ {
+ eightbit = FALSE;
+ ee_chinese = FALSE;
+ }
+ else if (compare(str1, EMACS_string, FALSE))
+ emacs_keys_mode = TRUE;
+ else if (compare(str1, NOEMACS_string, FALSE))
+ emacs_keys_mode = FALSE;
+ else if (compare(str1, chinese_cmd, FALSE))
+ {
+ ee_chinese = TRUE;
+ eightbit = TRUE;
+ }
+ else if (compare(str1, nochinese_cmd, FALSE))
+ ee_chinese = FALSE;
+ }
+ fclose(init_file);
+ }
+ }
+ free(string);
+ free(home);
+
+ string = getenv("LANG");
+ if (string != NULL)
+ {
+ if (strcmp(string, "zh_TW.big5") == 0)
+ {
+ ee_chinese = TRUE;
+ eightbit = TRUE;
+ }
+ }
+}
+
+/*
+ | Save current configuration to .init.ee file in the current directory.
+ */
+
+void
+dump_ee_conf()
+{
+ FILE *init_file;
+ FILE *old_init_file = NULL;
+ char *file_name = ".init.ee";
+ char *home_dir = "~/.init.ee";
+ char buffer[512];
+ struct stat buf;
+ char *string;
+ int length;
+ int option = 0;
+
+ if (restrict_mode())
+ {
+ return;
+ }
+
+ option = menu_op(config_dump_menu);
+
+ werase(com_win);
+ wmove(com_win, 0, 0);
+
+ if (option == 0)
+ {
+ wprintw(com_win, conf_not_saved_msg);
+ wrefresh(com_win);
+ return;
+ }
+ else if (option == 2)
+ file_name = resolve_name(home_dir);
+
+ /*
+ | If a .init.ee file exists, move it to .init.ee.old.
+ */
+
+ if (stat(file_name, &buf) != -1)
+ {
+ sprintf(buffer, "%s.old", file_name);
+ unlink(buffer);
+ link(file_name, buffer);
+ unlink(file_name);
+ old_init_file = fopen(buffer, "r");
+ }
+
+ init_file = fopen(file_name, "w");
+ if (init_file == NULL)
+ {
+ wprintw(com_win, conf_dump_err_msg);
+ wrefresh(com_win);
+ return;
+ }
+
+ if (old_init_file != NULL)
+ {
+ /*
+ | Copy non-configuration info into new .init.ee file.
+ */
+ while ((string = fgets(buffer, 512, old_init_file)) != NULL)
+ {
+ length = strlen(string);
+ string[length - 1] = (char) NULL;
+
+ if (unique_test(string, init_strings) == 1)
+ {
+ if (compare(string, Echo, FALSE))
+ {
+ fprintf(init_file, "%s\n", string);
+ }
+ }
+ else
+ fprintf(init_file, "%s\n", string);
+ }
+
+ fclose(old_init_file);
+ }
+
+ fprintf(init_file, "%s\n", case_sen ? CASE : NOCASE);
+ fprintf(init_file, "%s\n", expand_tabs ? EXPAND : NOEXPAND);
+ fprintf(init_file, "%s\n", info_window ? INFO : NOINFO );
+ fprintf(init_file, "%s\n", observ_margins ? MARGINS : NOMARGINS );
+ fprintf(init_file, "%s\n", auto_format ? AUTOFORMAT : NOAUTOFORMAT );
+ fprintf(init_file, "%s %s\n", PRINTCOMMAND, print_command);
+ fprintf(init_file, "%s %d\n", RIGHTMARGIN, right_margin);
+ fprintf(init_file, "%s\n", nohighlight ? NOHIGHLIGHT : HIGHLIGHT );
+ fprintf(init_file, "%s\n", eightbit ? EIGHTBIT : NOEIGHTBIT );
+ fprintf(init_file, "%s\n", emacs_keys_mode ? EMACS_string : NOEMACS_string );
+ fprintf(init_file, "%s\n", ee_chinese ? chinese_cmd : nochinese_cmd );
+
+ fclose(init_file);
+
+ wprintw(com_win, conf_dump_success_msg, file_name);
+ wrefresh(com_win);
+
+ if ((option == 2) && (file_name != home_dir))
+ {
+ free(file_name);
+ }
+}
+
+void
+echo_string(string) /* echo the given string */
+char *string;
+{
+ char *temp;
+ int Counter;
+
+ temp = string;
+ while (*temp != (char) NULL)
+ {
+ if (*temp == '\\')
+ {
+ temp++;
+ if (*temp == 'n')
+ putchar('\n');
+ else if (*temp == 't')
+ putchar('\t');
+ else if (*temp == 'b')
+ putchar('\b');
+ else if (*temp == 'r')
+ putchar('\r');
+ else if (*temp == 'f')
+ putchar('\f');
+ else if ((*temp == 'e') || (*temp == 'E'))
+ putchar('\033'); /* escape */
+ else if (*temp == '\\')
+ putchar('\\');
+ else if (*temp == '\'')
+ putchar('\'');
+ else if ((*temp >= '0') && (*temp <= '9'))
+ {
+ Counter = 0;
+ while ((*temp >= '0') && (*temp <= '9'))
+ {
+ Counter = (8 * Counter) + (*temp - '0');
+ temp++;
+ }
+ putchar(Counter);
+ temp--;
+ }
+ temp++;
+ }
+ else
+ {
+ putchar(*temp);
+ temp++;
+ }
+ }
+
+ fflush(stdout);
+}
+
+void
+spell_op() /* check spelling of words in the editor */
+{
+ if (restrict_mode())
+ {
+ return;
+ }
+ top(); /* go to top of file */
+ insert_line(FALSE); /* create two blank lines */
+ insert_line(FALSE);
+ top();
+ command(shell_echo_msg);
+ adv_line();
+ wmove(com_win, 0, 0);
+ wprintw(com_win, spell_in_prog_msg);
+ wrefresh(com_win);
+ command("<>!spell"); /* send contents of buffer to command 'spell'
+ and read the results back into the editor */
+}
+
+void
+ispell_op()
+{
+ char name[128];
+ char string[256];
+ int pid;
+
+ if (restrict_mode())
+ {
+ return;
+ }
+ pid = getpid();
+ sprintf(name, "/tmp/ee.%d", pid);
+ if (write_file(name))
+ {
+ sprintf(string, "ispell %s", name);
+ sh_command(string);
+ delete_text();
+ tmp_file = name;
+ recv_file = TRUE;
+ check_fp();
+ unlink(name);
+ }
+}
+
+int
+first_word_len(test_line)
+struct text *test_line;
+{
+ int counter;
+ unsigned char *pnt;
+
+ if (test_line == NULL)
+ return(0);
+
+ pnt = test_line->line;
+ if ((pnt == NULL) || (*pnt == (char) NULL) ||
+ (*pnt == '.') || (*pnt == '>'))
+ return(0);
+
+ if ((*pnt == ' ') || (*pnt == '\t'))
+ {
+ pnt = next_word(pnt);
+ }
+
+ if (*pnt == (char) NULL)
+ return(0);
+
+ counter = 0;
+ while ((*pnt != (char) NULL) && ((*pnt != ' ') && (*pnt != '\t')))
+ {
+ pnt++;
+ counter++;
+ }
+ while ((*pnt != (char) NULL) && ((*pnt == ' ') || (*pnt == '\t')))
+ {
+ pnt++;
+ counter++;
+ }
+ return(counter);
+}
+
+void
+Auto_Format() /* format the paragraph according to set margins */
+{
+ int string_count;
+ int offset;
+ int temp_case;
+ int word_len;
+ int temp_dwl;
+ int tmp_d_line_length;
+ int leave_loop = FALSE;
+ int status;
+ int counter;
+ char not_blank;
+ unsigned char *line;
+ unsigned char *tmp_srchstr;
+ unsigned char *temp1, *temp2;
+ unsigned char *temp_dword;
+ unsigned char temp_d_char[3];
+ unsigned char *tmp_d_line;
+
+
+ temp_d_char[0] = d_char[0];
+ temp_d_char[1] = d_char[1];
+ temp_d_char[2] = d_char[2];
+
+/*
+ | if observ_margins is not set, or the current line is blank,
+ | do not format the current paragraph
+ */
+
+ if ((!observ_margins) || (Blank_Line(curr_line)))
+ return;
+
+/*
+ | get current position in paragraph, so after formatting, the cursor
+ | will be in the same relative position
+ */
+
+ tmp_d_line = d_line;
+ tmp_d_line_length = dlt_line->line_length;
+ d_line = NULL;
+ auto_format = FALSE;
+ offset = position;
+ if ((position != 1) && ((*point == ' ') || (*point == '\t') || (position == curr_line->line_length) || (*point == (char) NULL)))
+ prev_word();
+ temp_dword = d_word;
+ temp_dwl = d_wrd_len;
+ d_wrd_len = 0;
+ d_word = NULL;
+ temp_case = case_sen;
+ case_sen = TRUE;
+ tmp_srchstr = srch_str;
+ temp2 = srch_str = (unsigned char *) malloc(1 + curr_line->line_length - position);
+ if ((*point == ' ') || (*point == '\t'))
+ adv_word();
+ offset -= position;
+ counter = position;
+ line = temp1 = point;
+ while ((*temp1 != (char) NULL) && (*temp1 != ' ') && (*temp1 != '\t') && (counter < curr_line->line_length))
+ {
+ *temp2 = *temp1;
+ temp2++;
+ temp1++;
+ counter++;
+ }
+ *temp2 = (char) NULL;
+ if (position != 1)
+ bol();
+ while (!Blank_Line(curr_line->prev_line))
+ bol();
+ string_count = 0;
+ status = TRUE;
+ while ((line != point) && (status))
+ {
+ status = search(FALSE);
+ string_count++;
+ }
+
+/*
+ | now get back to the start of the paragraph to start checking
+ */
+
+ if (position != 1)
+ bol();
+ while (!Blank_Line(curr_line->prev_line))
+ bol();
+
+/*
+ | Start going through lines, putting spaces at end of lines if they do
+ | not already exist. Check line length, and move words to the next line
+ | if they cross the margin. Then get words from the next line if they
+ | will fit in before the margin.
+ */
+
+ counter = 0;
+
+ while (!leave_loop)
+ {
+ if (position != curr_line->line_length)
+ eol();
+ left(TRUE);
+ if (*point != ' ')
+ {
+ right(TRUE);
+ insert(' ');
+ }
+ else
+ right(TRUE);
+
+ not_blank = FALSE;
+
+ /*
+ | fill line if first word on next line will fit
+ | in the line without crossing the margin
+ */
+
+ while ((curr_line->next_line != NULL) &&
+ ((word_len = first_word_len(curr_line->next_line)) > 0)
+ && ((scr_pos + word_len) < right_margin))
+ {
+ adv_line();
+ if ((*point == ' ') || (*point == '\t'))
+ adv_word();
+ del_word();
+ if (position != 1)
+ bol();
+
+ /*
+ | We know this line was not blank before, so
+ | make sure that it doesn't have one of the
+ | leading characters that indicate the line
+ | should not be modified.
+ |
+ | We also know that this character should not
+ | be left as the first character of this line.
+ */
+
+ if ((Blank_Line(curr_line)) &&
+ (curr_line->line[0] != '.') &&
+ (curr_line->line[0] != '>'))
+ {
+ del_line();
+ not_blank = FALSE;
+ }
+ else
+ not_blank = TRUE;
+
+ /*
+ | go to end of previous line
+ */
+ left(TRUE);
+ undel_word();
+ eol();
+ /*
+ | make sure there's a space at the end of the line
+ */
+ left(TRUE);
+ if (*point != ' ')
+ {
+ right(TRUE);
+ insert(' ');
+ }
+ else
+ right(TRUE);
+ }
+
+ /*
+ | make sure line does not cross right margin
+ */
+
+ while (right_margin <= scr_pos)
+ {
+ prev_word();
+ if (position != 1)
+ {
+ del_word();
+ if (Blank_Line(curr_line->next_line))
+ insert_line(TRUE);
+ else
+ adv_line();
+ if ((*point == ' ') || (*point == '\t'))
+ adv_word();
+ undel_word();
+ not_blank = TRUE;
+ if (position != 1)
+ bol();
+ left(TRUE);
+ }
+ }
+
+ if ((!Blank_Line(curr_line->next_line)) || (not_blank))
+ {
+ adv_line();
+ counter++;
+ }
+ else
+ leave_loop = TRUE;
+ }
+
+/*
+ | go back to begin of paragraph, put cursor back to original position
+ */
+
+ if (position != 1)
+ bol();
+ while ((counter-- > 0) || (!Blank_Line(curr_line->prev_line)))
+ bol();
+
+/*
+ | find word cursor was in
+ */
+
+ status = TRUE;
+ while ((status) && (string_count > 0))
+ {
+ status = search(FALSE);
+ string_count--;
+ }
+
+/*
+ | offset the cursor to where it was before from the start of the word
+ */
+
+ while (offset > 0)
+ {
+ offset--;
+ right(TRUE);
+ }
+
+ if ((string_count > 0) && (offset < 0))
+ {
+ while (offset < 0)
+ {
+ offset++;
+ left(TRUE);
+ }
+ }
+
+/*
+ | reset flags and strings to what they were before formatting
+ */
+
+ if (d_word != NULL)
+ free(d_word);
+ d_word = temp_dword;
+ d_wrd_len = temp_dwl;
+ case_sen = temp_case;
+ free(srch_str);
+ srch_str = tmp_srchstr;
+ d_char[0] = temp_d_char[0];
+ d_char[1] = temp_d_char[1];
+ d_char[2] = temp_d_char[2];
+ auto_format = TRUE;
+ dlt_line->line_length = tmp_d_line_length;
+ d_line = tmp_d_line;
+
+ formatted = TRUE;
+ midscreen(scr_vert, point);
+}
+
+void
+modes_op()
+{
+ int ret_value;
+ int counter;
+ char *string;
+
+ do
+ {
+ sprintf(modes_menu[1].item_string, "%s %s", mode_strings[1],
+ (expand_tabs ? ON : OFF));
+ sprintf(modes_menu[2].item_string, "%s %s", mode_strings[2],
+ (case_sen ? ON : OFF));
+ sprintf(modes_menu[3].item_string, "%s %s", mode_strings[3],
+ (observ_margins ? ON : OFF));
+ sprintf(modes_menu[4].item_string, "%s %s", mode_strings[4],
+ (auto_format ? ON : OFF));
+ sprintf(modes_menu[5].item_string, "%s %s", mode_strings[5],
+ (eightbit ? ON : OFF));
+ sprintf(modes_menu[6].item_string, "%s %s", mode_strings[6],
+ (info_window ? ON : OFF));
+ sprintf(modes_menu[7].item_string, "%s %s", mode_strings[7],
+ (emacs_keys_mode ? ON : OFF));
+ sprintf(modes_menu[8].item_string, "%s %d", mode_strings[8],
+ right_margin);
+ sprintf(modes_menu[9].item_string, "%s %s", mode_strings[9],
+ (ee_chinese ? ON : OFF));
+
+ ret_value = menu_op(modes_menu);
+
+ switch (ret_value)
+ {
+ case 1:
+ expand_tabs = !expand_tabs;
+ break;
+ case 2:
+ case_sen = !case_sen;
+ break;
+ case 3:
+ observ_margins = !observ_margins;
+ break;
+ case 4:
+ auto_format = !auto_format;
+ if (auto_format)
+ observ_margins = TRUE;
+ break;
+ case 5:
+ eightbit = !eightbit;
+ if (!eightbit)
+ ee_chinese = FALSE;
+#ifdef NCURSE
+ if (ee_chinese)
+ nc_setattrib(A_NC_BIG5);
+ else
+ nc_clearattrib(A_NC_BIG5);
+#endif /* NCURSE */
+
+ redraw();
+ wnoutrefresh(text_win);
+ break;
+ case 6:
+ if (info_window)
+ no_info_window();
+ else
+ create_info_window();
+ break;
+ case 7:
+ emacs_keys_mode = !emacs_keys_mode;
+ if (info_window)
+ paint_info_win();
+ break;
+ case 8:
+ string = get_string(margin_prompt, TRUE);
+ if (string != NULL)
+ {
+ counter = atoi(string);
+ if (counter > 0)
+ right_margin = counter;
+ free(string);
+ }
+ break;
+ case 9:
+ ee_chinese = !ee_chinese;
+ if (ee_chinese != FALSE)
+ eightbit = TRUE;
+#ifdef NCURSE
+ if (ee_chinese)
+ nc_setattrib(A_NC_BIG5);
+ else
+ nc_clearattrib(A_NC_BIG5);
+#endif /* NCURSE */
+ redraw();
+ break;
+ default:
+ break;
+ }
+ }
+ while (ret_value != 0);
+}
+
+char *
+is_in_string(string, substring) /* a strchr() look-alike for systems without
+ strchr() */
+char * string, *substring;
+{
+ char *full, *sub;
+
+ for (sub = substring; (sub != NULL) && (*sub != (char)NULL); sub++)
+ {
+ for (full = string; (full != NULL) && (*full != (char)NULL);
+ full++)
+ {
+ if (*sub == *full)
+ return(full);
+ }
+ }
+ return(NULL);
+}
+
+/*
+ | handle names of the form "~/file", "~user/file",
+ | "$HOME/foo", "~/$FOO", etc.
+ */
+
+char *
+resolve_name(name)
+char *name;
+{
+ char long_buffer[1024];
+ char short_buffer[128];
+ char *buffer;
+ char *slash;
+ char *tmp;
+ char *start_of_var;
+ int offset;
+ int index;
+ int counter;
+ struct passwd *user;
+
+ if (name[0] == '~')
+ {
+ if (name[1] == '/')
+ {
+ index = getuid();
+ user = (struct passwd *) getpwuid(index);
+ slash = name + 1;
+ }
+ else
+ {
+ slash = strchr(name, '/');
+ if (slash == NULL)
+ return(name);
+ *slash = (char) NULL;
+ user = (struct passwd *) getpwnam((name + 1));
+ *slash = '/';
+ }
+ if (user == NULL)
+ {
+ return(name);
+ }
+ buffer = malloc(strlen(user->pw_dir) + strlen(slash) + 1);
+ strcpy(buffer, user->pw_dir);
+ strcat(buffer, slash);
+ }
+ else
+ buffer = name;
+
+ if (is_in_string(buffer, "$"))
+ {
+ tmp = buffer;
+ index = 0;
+
+ while ((*tmp != (char) NULL) && (index < 1024))
+ {
+
+ while ((*tmp != (char) NULL) && (*tmp != '$') &&
+ (index < 1024))
+ {
+ long_buffer[index] = *tmp;
+ tmp++;
+ index++;
+ }
+
+ if ((*tmp == '$') && (index < 1024))
+ {
+ counter = 0;
+ start_of_var = tmp;
+ tmp++;
+ if (*tmp == '{') /* } */ /* bracketed variable name */
+ {
+ tmp++; /* { */
+ while ((*tmp != (char) NULL) &&
+ (*tmp != '}') &&
+ (counter < 128))
+ {
+ short_buffer[counter] = *tmp;
+ counter++;
+ tmp++;
+ } /* { */
+ if (*tmp == '}')
+ tmp++;
+ }
+ else
+ {
+ while ((*tmp != (char) NULL) &&
+ (*tmp != '/') &&
+ (*tmp != '$') &&
+ (counter < 128))
+ {
+ short_buffer[counter] = *tmp;
+ counter++;
+ tmp++;
+ }
+ }
+ short_buffer[counter] = (char) NULL;
+ if ((slash = getenv(short_buffer)) != NULL)
+ {
+ offset = strlen(slash);
+ if ((offset + index) < 1024)
+ strcpy(&long_buffer[index], slash);
+ index += offset;
+ }
+ else
+ {
+ while ((start_of_var != tmp) && (index < 1024))
+ {
+ long_buffer[index] = *start_of_var;
+ start_of_var++;
+ index++;
+ }
+ }
+ }
+ }
+
+ if (index == 1024)
+ return(buffer);
+ else
+ long_buffer[index] = (char) NULL;
+
+ if (name != buffer)
+ free(buffer);
+ buffer = malloc(index + 1);
+ strcpy(buffer, long_buffer);
+ }
+
+ return(buffer);
+}
+
+int
+restrict_mode()
+{
+ if (!restricted)
+ return(FALSE);
+
+ wmove(com_win, 0, 0);
+ wprintw(com_win, restricted_msg);
+ wclrtoeol(com_win);
+ wrefresh(com_win);
+ clear_com_win = TRUE;
+ return(TRUE);
+}
+
+/*
+ | The following routine tests the input string against the list of
+ | strings, to determine if the string is a unique match with one of the
+ | valid values.
+ */
+
+int
+unique_test(string, list)
+char *string;
+char *list[];
+{
+ int counter;
+ int num_match;
+ int result;
+
+ num_match = 0;
+ counter = 0;
+ while (list[counter] != NULL)
+ {
+ result = compare(string, list[counter], FALSE);
+ if (result)
+ num_match++;
+ counter++;
+ }
+ return(num_match);
+}
+
+#ifndef NO_CATGETS
+/*
+ | Get the catalog entry, and if it got it from the catalog,
+ | make a copy, since the buffer will be overwritten by the
+ | next call to catgets().
+ */
+
+char *
+catgetlocal(number, string)
+int number;
+char *string;
+{
+ char *temp1;
+ char *temp2;
+
+ temp1 = catgets(catalog, 1, number, string);
+ if (temp1 != string)
+ {
+ temp2 = malloc(strlen(temp1) + 1);
+ strcpy(temp2, temp1);
+ temp1 = temp2;
+ }
+ return(temp1);
+}
+#endif /* NO_CATGETS */
+
+/*
+ | The following is to allow for using message catalogs which allow
+ | the software to be 'localized', that is, to use different languages
+ | all with the same binary. For more information, see your system
+ | documentation, or the X/Open Internationalization Guide.
+ */
+
+void
+strings_init()
+{
+ int counter;
+
+#ifndef NO_CATGETS
+ setlocale(LC_ALL, "");
+ catalog = catopen("ee", 0);
+#endif /* NO_CATGETS */
+
+ modes_menu[0].item_string = catgetlocal( 1, "modes menu");
+ mode_strings[1] = catgetlocal( 2, "tabs to spaces ");
+ mode_strings[2] = catgetlocal( 3, "case sensitive search");
+ mode_strings[3] = catgetlocal( 4, "margins observed ");
+ mode_strings[4] = catgetlocal( 5, "auto-paragraph format");
+ mode_strings[5] = catgetlocal( 6, "eightbit characters ");
+ mode_strings[6] = catgetlocal( 7, "info window ");
+ mode_strings[8] = catgetlocal( 8, "right margin ");
+ leave_menu[0].item_string = catgetlocal( 9, "leave menu");
+ leave_menu[1].item_string = catgetlocal( 10, "save changes");
+ leave_menu[2].item_string = catgetlocal( 11, "no save");
+ file_menu[0].item_string = catgetlocal( 12, "file menu");
+ file_menu[1].item_string = catgetlocal( 13, "read a file");
+ file_menu[2].item_string = catgetlocal( 14, "write a file");
+ file_menu[3].item_string = catgetlocal( 15, "save file");
+ file_menu[4].item_string = catgetlocal( 16, "print editor contents");
+ search_menu[0].item_string = catgetlocal( 17, "search menu");
+ search_menu[1].item_string = catgetlocal( 18, "search for ...");
+ search_menu[2].item_string = catgetlocal( 19, "search");
+ spell_menu[0].item_string = catgetlocal( 20, "spell menu");
+ spell_menu[1].item_string = catgetlocal( 21, "use 'spell'");
+ spell_menu[2].item_string = catgetlocal( 22, "use 'ispell'");
+ misc_menu[0].item_string = catgetlocal( 23, "miscellaneous menu");
+ misc_menu[1].item_string = catgetlocal( 24, "format paragraph");
+ misc_menu[2].item_string = catgetlocal( 25, "shell command");
+ misc_menu[3].item_string = catgetlocal( 26, "check spelling");
+ main_menu[0].item_string = catgetlocal( 27, "main menu");
+ main_menu[1].item_string = catgetlocal( 28, "leave editor");
+ main_menu[2].item_string = catgetlocal( 29, "help");
+ main_menu[3].item_string = catgetlocal( 30, "file operations");
+ main_menu[4].item_string = catgetlocal( 31, "redraw screen");
+ main_menu[5].item_string = catgetlocal( 32, "settings");
+ main_menu[6].item_string = catgetlocal( 33, "search");
+ main_menu[7].item_string = catgetlocal( 34, "miscellaneous");
+ help_text[0] = catgetlocal( 35, "Control keys: ");
+ help_text[1] = catgetlocal( 36, "^a ascii code ^i tab ^r right ");
+ help_text[2] = catgetlocal( 37, "^b bottom of text ^j newline ^t top of text ");
+ help_text[3] = catgetlocal( 38, "^c command ^k delete char ^u up ");
+ help_text[4] = catgetlocal( 39, "^d down ^l left ^v undelete word ");
+ help_text[5] = catgetlocal( 40, "^e search prompt ^m newline ^w delete word ");
+ help_text[6] = catgetlocal( 41, "^f undelete char ^n next page ^x search ");
+ help_text[7] = catgetlocal( 42, "^g begin of line ^o end of line ^y delete line ");
+ help_text[8] = catgetlocal( 43, "^h backspace ^p prev page ^z undelete line ");
+ help_text[9] = catgetlocal( 44, "^[ (escape) menu ");
+ help_text[10] = catgetlocal( 45, " ");
+ help_text[11] = catgetlocal( 46, "Commands: ");
+ help_text[12] = catgetlocal( 47, "help : get this info file : print file name ");
+ help_text[13] = catgetlocal( 48, "read : read a file char : ascii code of char ");
+ help_text[14] = catgetlocal( 49, "write : write a file case : case sensitive search ");
+ help_text[15] = catgetlocal( 50, "exit : leave and save nocase : case insensitive search ");
+ help_text[16] = catgetlocal( 51, "quit : leave, no save !cmd : execute \"cmd\" in shell ");
+ help_text[17] = catgetlocal( 52, "line : display line # 0-9 : go to line \"#\" ");
+ help_text[18] = catgetlocal( 53, "expand : expand tabs noexpand: do not expand tabs ");
+ help_text[19] = catgetlocal( 54, " ");
+ help_text[20] = catgetlocal( 55, " ee [+#] [-i] [-e] [-h] [file(s)] ");
+ help_text[21] = catgetlocal( 56, "+# :go to line # -i :no info window -e : don't expand tabs -h :no highlight");
+ control_keys[0] = catgetlocal( 57, "^[ (escape) menu ^e search prompt ^y delete line ^u up ^p prev page ");
+ control_keys[1] = catgetlocal( 58, "^a ascii code ^x search ^z undelete line ^d down ^n next page ");
+ control_keys[2] = catgetlocal( 59, "^b bottom of text ^g begin of line ^w delete word ^l left ");
+ control_keys[3] = catgetlocal( 60, "^t top of text ^o end of line ^v undelete word ^r right ");
+ control_keys[4] = catgetlocal( 61, "^c command ^k delete char ^f undelete char ");
+ command_strings[0] = catgetlocal( 62, "help : get help info |file : print file name |line : print line # ");
+ command_strings[1] = catgetlocal( 63, "read : read a file |char : ascii code of char |0-9 : go to line \"#\"");
+ command_strings[2] = catgetlocal( 64, "write: write a file |case : case sensitive search |exit : leave and save ");
+ command_strings[3] = catgetlocal( 65, "!cmd : shell \"cmd\" |nocase: ignore case in search |quit : leave, no save");
+ command_strings[4] = catgetlocal( 66, "expand: expand tabs |noexpand: do not expand tabs ");
+ com_win_message = catgetlocal( 67, " press Escape (^[) for menu");
+ no_file_string = catgetlocal( 68, "no file");
+ ascii_code_str = catgetlocal( 69, "ascii code: ");
+ printer_msg_str = catgetlocal( 70, "sending contents of buffer to \"%s\" ");
+ command_str = catgetlocal( 71, "command: ");
+ file_write_prompt_str = catgetlocal( 72, "name of file to write: ");
+ file_read_prompt_str = catgetlocal( 73, "name of file to read: ");
+ char_str = catgetlocal( 74, "character = %d");
+ unkn_cmd_str = catgetlocal( 75, "unknown command \"%s\"");
+ non_unique_cmd_msg = catgetlocal( 76, "entered command is not unique");
+ line_num_str = catgetlocal( 77, "line %d ");
+ line_len_str = catgetlocal( 78, "length = %d");
+ current_file_str = catgetlocal( 79, "current file is \"%s\" ");
+ usage0 = catgetlocal( 80, "usage: %s [-i] [-e] [-h] [+line_number] [file(s)]\n");
+ usage1 = catgetlocal( 81, " -i turn off info window\n");
+ usage2 = catgetlocal( 82, " -e do not convert tabs to spaces\n");
+ usage3 = catgetlocal( 83, " -h do not use highlighting\n");
+ file_is_dir_msg = catgetlocal( 84, "file \"%s\" is a directory");
+ new_file_msg = catgetlocal( 85, "new file \"%s\"");
+ cant_open_msg = catgetlocal( 86, "can't open \"%s\"");
+ open_file_msg = catgetlocal( 87, "file \"%s\", %d lines");
+ file_read_fin_msg = catgetlocal( 88, "finished reading file \"%s\"");
+ reading_file_msg = catgetlocal( 89, "reading file \"%s\"");
+ read_only_msg = catgetlocal( 90, ", read only");
+ file_read_lines_msg = catgetlocal( 91, "file \"%s\", %d lines");
+ save_file_name_prompt = catgetlocal( 92, "enter name of file: ");
+ file_not_saved_msg = catgetlocal( 93, "no filename entered: file not saved");
+ changes_made_prompt = catgetlocal( 94, "changes have been made, are you sure? (y/n [n]) ");
+ yes_char = catgetlocal( 95, "y");
+ file_exists_prompt = catgetlocal( 96, "file already exists, overwrite? (y/n) [n] ");
+ create_file_fail_msg = catgetlocal( 97, "unable to create file \"%s\"");
+ writing_file_msg = catgetlocal( 98, "writing file \"%s\"");
+ file_written_msg = catgetlocal( 99, "\"%s\" %d lines, %d characters");
+ searching_msg = catgetlocal( 100, " ...searching");
+ str_not_found_msg = catgetlocal( 101, "string \"%s\" not found");
+ search_prompt_str = catgetlocal( 102, "search for: ");
+ exec_err_msg = catgetlocal( 103, "could not exec %s\n");
+ continue_msg = catgetlocal( 104, "press return to continue ");
+ menu_cancel_msg = catgetlocal( 105, "press Esc to cancel");
+ menu_size_err_msg = catgetlocal( 106, "menu too large for window");
+ press_any_key_msg = catgetlocal( 107, "press any key to continue ");
+ shell_prompt = catgetlocal( 108, "shell command: ");
+ formatting_msg = catgetlocal( 109, "...formatting paragraph...");
+ shell_echo_msg = catgetlocal( 110, "<!echo 'list of unrecognized words'; echo -=-=-=-=-=-");
+ spell_in_prog_msg = catgetlocal( 111, "sending contents of edit buffer to 'spell'");
+ margin_prompt = catgetlocal( 112, "right margin is: ");
+ restricted_msg = catgetlocal( 113, "restricted mode: unable to perform requested operation");
+ ON = catgetlocal( 114, "ON");
+ OFF = catgetlocal( 115, "OFF");
+ HELP = catgetlocal( 116, "HELP");
+ WRITE = catgetlocal( 117, "WRITE");
+ READ = catgetlocal( 118, "READ");
+ LINE = catgetlocal( 119, "LINE");
+ FILE_str = catgetlocal( 120, "FILE");
+ CHARACTER = catgetlocal( 121, "CHARACTER");
+ REDRAW = catgetlocal( 122, "REDRAW");
+ RESEQUENCE = catgetlocal( 123, "RESEQUENCE");
+ AUTHOR = catgetlocal( 124, "AUTHOR");
+ VERSION = catgetlocal( 125, "VERSION");
+ CASE = catgetlocal( 126, "CASE");
+ NOCASE = catgetlocal( 127, "NOCASE");
+ EXPAND = catgetlocal( 128, "EXPAND");
+ NOEXPAND = catgetlocal( 129, "NOEXPAND");
+ Exit_string = catgetlocal( 130, "EXIT");
+ QUIT_string = catgetlocal( 131, "QUIT");
+ INFO = catgetlocal( 132, "INFO");
+ NOINFO = catgetlocal( 133, "NOINFO");
+ MARGINS = catgetlocal( 134, "MARGINS");
+ NOMARGINS = catgetlocal( 135, "NOMARGINS");
+ AUTOFORMAT = catgetlocal( 136, "AUTOFORMAT");
+ NOAUTOFORMAT = catgetlocal( 137, "NOAUTOFORMAT");
+ Echo = catgetlocal( 138, "ECHO");
+ PRINTCOMMAND = catgetlocal( 139, "PRINTCOMMAND");
+ RIGHTMARGIN = catgetlocal( 140, "RIGHTMARGIN");
+ HIGHLIGHT = catgetlocal( 141, "HIGHLIGHT");
+ NOHIGHLIGHT = catgetlocal( 142, "NOHIGHLIGHT");
+ EIGHTBIT = catgetlocal( 143, "EIGHTBIT");
+ NOEIGHTBIT = catgetlocal( 144, "NOEIGHTBIT");
+ /*
+ | additions
+ */
+ mode_strings[7] = catgetlocal( 145, "emacs key bindings ");
+ emacs_help_text[0] = help_text[0];
+ emacs_help_text[1] = catgetlocal( 146, "^a beginning of line ^i tab ^r restore word ");
+ emacs_help_text[2] = catgetlocal( 147, "^b back 1 char ^j undel char ^t top of text ");
+ emacs_help_text[3] = catgetlocal( 148, "^c command ^k delete line ^u bottom of text ");
+ emacs_help_text[4] = catgetlocal( 149, "^d delete char ^l undelete line ^v next page ");
+ emacs_help_text[5] = catgetlocal( 150, "^e end of line ^m newline ^w delete word ");
+ emacs_help_text[6] = catgetlocal( 151, "^f forward 1 char ^n next line ^x search ");
+ emacs_help_text[7] = catgetlocal( 152, "^g go back 1 page ^o ascii char insert ^y search prompt ");
+ emacs_help_text[8] = catgetlocal( 153, "^h backspace ^p prev line ^z next word ");
+ emacs_help_text[9] = help_text[9];
+ emacs_help_text[10] = help_text[10];
+ emacs_help_text[11] = help_text[11];
+ emacs_help_text[12] = help_text[12];
+ emacs_help_text[13] = help_text[13];
+ emacs_help_text[14] = help_text[14];
+ emacs_help_text[15] = help_text[15];
+ emacs_help_text[16] = help_text[16];
+ emacs_help_text[17] = help_text[17];
+ emacs_help_text[18] = help_text[18];
+ emacs_help_text[19] = help_text[19];
+ emacs_help_text[20] = help_text[20];
+ emacs_help_text[21] = help_text[21];
+ emacs_control_keys[0] = catgetlocal( 154, "^[ (escape) menu ^y search prompt ^k delete line ^p prev li ^g prev page");
+ emacs_control_keys[1] = catgetlocal( 155, "^o ascii code ^x search ^l undelete line ^n next li ^v next page");
+ emacs_control_keys[2] = catgetlocal( 156, "^u end of file ^a begin of line ^w delete word ^b back 1 char ");
+ emacs_control_keys[3] = catgetlocal( 157, "^t top of text ^e end of line ^r restore word ^f forward 1 char ");
+ emacs_control_keys[4] = catgetlocal( 158, "^c command ^d delete char ^j undelete char ^z next word ");
+ EMACS_string = catgetlocal( 159, "EMACS");
+ NOEMACS_string = catgetlocal( 160, "NOEMACS");
+ usage4 = catgetlocal( 161, " +# put cursor at line #\n");
+ conf_dump_err_msg = catgetlocal( 162, "unable to open .init.ee for writing, no configuration saved!");
+ conf_dump_success_msg = catgetlocal( 163, "ee configuration saved in file %s");
+ modes_menu[10].item_string = catgetlocal( 164, "save editor configuration");
+ config_dump_menu[0].item_string = catgetlocal( 165, "save ee configuration");
+ config_dump_menu[1].item_string = catgetlocal( 166, "save in current directory");
+ config_dump_menu[2].item_string = catgetlocal( 167, "save in home directory");
+ conf_not_saved_msg = catgetlocal( 168, "ee configuration not saved");
+ ree_no_file_msg = catgetlocal( 169, "must specify a file when invoking ree");
+ menu_too_lrg_msg = catgetlocal( 180, "menu too large for window");
+ more_above_str = catgetlocal( 181, "^^more^^");
+ more_below_str = catgetlocal( 182, "VVmoreVV");
+ mode_strings[9] = catgetlocal( 183, "16 bit characters ");
+ chinese_cmd = catgetlocal( 184, "16BIT");
+ nochinese_cmd = catgetlocal( 185, "NO16BIT");
+
+ commands[0] = HELP;
+ commands[1] = WRITE;
+ commands[2] = READ;
+ commands[3] = LINE;
+ commands[4] = FILE_str;
+ commands[5] = REDRAW;
+ commands[6] = RESEQUENCE;
+ commands[7] = AUTHOR;
+ commands[8] = VERSION;
+ commands[9] = CASE;
+ commands[10] = NOCASE;
+ commands[11] = EXPAND;
+ commands[12] = NOEXPAND;
+ commands[13] = Exit_string;
+ commands[14] = QUIT_string;
+ commands[15] = "<";
+ commands[16] = ">";
+ commands[17] = "!";
+ commands[18] = "0";
+ commands[19] = "1";
+ commands[20] = "2";
+ commands[21] = "3";
+ commands[22] = "4";
+ commands[23] = "5";
+ commands[24] = "6";
+ commands[25] = "7";
+ commands[26] = "8";
+ commands[27] = "9";
+ commands[28] = CHARACTER;
+ commands[29] = chinese_cmd;
+ commands[30] = nochinese_cmd;
+ commands[31] = NULL;
+ init_strings[0] = CASE;
+ init_strings[1] = NOCASE;
+ init_strings[2] = EXPAND;
+ init_strings[3] = NOEXPAND;
+ init_strings[4] = INFO;
+ init_strings[5] = NOINFO;
+ init_strings[6] = MARGINS;
+ init_strings[7] = NOMARGINS;
+ init_strings[8] = AUTOFORMAT;
+ init_strings[9] = NOAUTOFORMAT;
+ init_strings[10] = Echo;
+ init_strings[11] = PRINTCOMMAND;
+ init_strings[12] = RIGHTMARGIN;
+ init_strings[13] = HIGHLIGHT;
+ init_strings[14] = NOHIGHLIGHT;
+ init_strings[15] = EIGHTBIT;
+ init_strings[16] = NOEIGHTBIT;
+ init_strings[17] = EMACS_string;
+ init_strings[18] = NOEMACS_string;
+ init_strings[19] = chinese_cmd;
+ init_strings[20] = nochinese_cmd;
+ init_strings[21] = NULL;
+
+ /*
+ | allocate space for strings here for settings menu
+ */
+
+ for (counter = 1; counter < NUM_MODES_ITEMS; counter++)
+ {
+ modes_menu[counter].item_string = malloc(80);
+ }
+
+#ifndef NO_CATGETS
+ catclose(catalog);
+#endif /* NO_CATGETS */
+}
+
diff --git a/contrib/ee/ee.i18n.guide b/contrib/ee/ee.i18n.guide
new file mode 100644
index 0000000..eef836a
--- /dev/null
+++ b/contrib/ee/ee.i18n.guide
@@ -0,0 +1,158 @@
+Easy Editor ("ee") provides the ability to translate the messages
+displayed to the user and the commands entered. This is done via message
+catalogs, following X/Open standards. ee supports eight bit characters,
+as well as 16-bit characters. The Chinese Big 5 code set is the 16-bit
+code set that ee was modified to handle, as it is relatively easy to
+support since two byte characters also take up two columns on the screen,
+thereby simplifying the screen position calculations. Other multibyte
+code sets may function, but have not been tested.
+
+(The name ee.i18n.guide is for "ee internationalization guide". The i18n
+abbreviation is used because there are 18 characters between the first
+letter ("i") and last ("n") of "internationalization".)
+
+All of the messages, warnings, information, and commands, are contained
+in the message catalog. Each numbered entry represents an individual
+string used by ee. Some strings contain formatting information for
+formatted print statements, which are of the form "%s", or "%d", these
+must be preserved in the translation, or the correct information will not
+be displayed. For those strings containing multiple formatting codes,
+the order of each item must be preserved as well.
+
+Message content
+1 title for modes, or settings menu
+2 - 8 entries for modes menu, each line should be the same length
+ (padded with spaces)
+9 - 34 other menu titles and entries
+35 - 56 help screen
+57 - 61 actions assigned to control keys
+62 - 66 commands information
+67 message displayed when info window turned off
+68 indication that no file name was entered when invoking ee
+69 prompt for decimal value of character to be entered
+70 message displaying the print command being invoked
+71 prompt for command
+72 prompt for name of file to be written
+73 prompt for name of file to be read
+74 string used to display the decimal value of the character
+ the cursor is on
+75 string displaying an unrecognized command
+76 string indicating that the command entered is not a unique
+ substring of a valid command
+77 string indicating the current line number
+78 string for displaying the length of the line
+79 string for displaying the name of the file
+80 - 83 strings showing how to invoke ee, and its options
+84 message indicating that the file entered is a directory, not a
+ text file
+85 message informing that the entered file does not yet exist
+86 message informing that the file can't be opened (because of
+ permission problems)
+87 message after file has been read with the file name and number
+ of lines read
+88 message indicating that the file has been read
+89 message indicating that the file is being read
+90 message indicating that permissions only allow the file to be
+ read, not written
+91 message after file has been read with the file name and number
+ of lines read
+92 prompt for name of file to be saved (used when no name was
+ entered for a file to edit)
+93 message indicating that the file was not written, since no
+ name was entered at the prompt
+94 prompt asking user if changes should not be saved ("yes_char"
+ will be expected for affirmative response)
+95 "yes" character, single character expected to confirm action
+ (can be upper or lower case, will be converted to upper-case
+ during test)
+96 prompt
+97 error message
+98 message indicating that the named file is being written
+99 message indicating the name of the file written, the number of
+ lines, and the number of characters (order of items must be
+ maintained)
+100 search in progress message
+101 message that the string was not found
+102 prompt for search
+103 message that string could not be executed
+104 self-explanatory
+105 message for menus, indicating that the Escape character will
+ allow the user to exit the menu
+106 error message indicating the menu won't fit on the screen
+107 self-explanatory
+108 prompt for shell command
+109 message displayed while formatting a paragraph
+110 string which places message for spell checking at top of
+ buffer (the portions 'list of unrecognized words' and
+ '-=-=-=-=-=-' may be replaced, but the rest must remain the
+ same)
+111 message informing that spell checking is in progress
+112 prompt for right margin
+113 error informing user that operation is not permitted in ree
+114 string indicating mode is turned 'on' in modes menu
+115 string indicating mode is turned 'off' in modes menu
+116 - 131 strings used for commands (some also used for initialization)
+132 - 144 strings used for initialization
+145 entry for settings menu for emacs key bindings settings
+146 - 153 help screen entries for emacs key bindings info
+154 - 158 info window entries for emacs key bindings info
+159 string for turning on emacs key bindings in the init file
+160 string for turning off emacs key bindings in the init file
+161 fifth line of usage statement
+162 error message when unable to save configuration file
+163 positive feedback about saving the configuration file
+164 - 167 menu items for saving editor configuration
+168 error message when unable to save configuration file
+169 error message for ree when not specifying the file
+180 self-explanatory
+181 - 182 indicators of more information in menu (for when scrolling
+ menus because menu contents won't fit vertically on screen)
+183 menu entry for modes menu for 16 bit characters
+184 - 185 strings for initialization to turn on or off 16 bit
+ character handling
+
+Care should be taken when translating commands and initialization keywords
+because the algorithm used for detecting uniqueness of entered commands
+will not be able to distinguish words that are not unique before the end
+of the shorter word, for example, it would not be able to distinguish the
+command 'abcd' from 'abcde'.
+
+After translating the messages, use the 'gencat' command to create the compiled
+catalog used when running the software. The standard syntax would be:
+
+ gencat ee.cat ee.msg
+
+Where ee.msg is the file containing the translations, and ee.cat is the
+compiled catalog. If the file ee.cat does not exist, it will be created.
+Check the documentation for your system for proper syntax.
+
+Message catalog placement varies from system to system. A common location
+for message catalogs is in /usr/lib/nls. In this directory are
+directories with the names of other languages. The default language is
+'C'. There is also an environment variable, named NLSPATH used to
+determine where message catalogs can be found. This variable is similar
+to the PATH variable used for commands, but with some differences. The
+NLSPATH variable must have the ability to handle different names for
+languages and the catalog files, so it has field descriptors for these. A
+typical setting for NLSPATH could be:
+
+ NLSPATH=/usr/lib/nls/%L/%N.cat:/usr/local/lib/nls/%L/%N.cat
+
+Where "%L" is the field descriptor for the language (obtained from the
+LANG environment variable) and "%N" is the name of the file (with the
+".cat" appended by the path variable, it is not passed from the requesting
+program). The colon (:) is used to separate paths, so in the above
+example there are two paths possible for message catalogs. You may wish
+to maintain catalogs for applications that are not supported by your
+system vendor in a location unique for you, and this is facilitated by the
+NLSPATH variable. Remember to set and export both the LANG and NLSPATH
+variables for each user that expects to use localization either in a
+system-wide profile or in each user's profile. See your system
+documentation for more information.
+
+The message catalog supplied with ee also uses the '$quote' directive to
+specify a quote around strings to ensure proper padding. This directive
+may not be supported on all systems, and lead to quotes being included in
+the string used in ee, which will cause incorrect behavior. If the
+'$quote' directive is not supported by your system's gencat command, edit
+the msg file to remove the leading and trailing quotation marks.
diff --git a/contrib/ee/ee.msg b/contrib/ee/ee.msg
new file mode 100644
index 0000000..f7c209c
--- /dev/null
+++ b/contrib/ee/ee.msg
@@ -0,0 +1,185 @@
+$ This file contains the messages for ee ("easy editor"). See the file
+$ ee.i18n.guide for more information
+$
+$ For ee patchlevel 3
+$
+$ $Header: /home/hugh/sources/old_ae/RCS/ee.msg,v 1.8 1996/11/30 03:23:40 hugh Exp $
+$
+$
+$set 1
+$quote "
+1 "modes menu"
+2 "tabs to spaces "
+3 "case sensitive search"
+4 "margins observed "
+5 "auto-paragraph format"
+6 "eightbit characters "
+7 "info window "
+8 "right margin "
+9 "leave menu"
+10 "save changes"
+11 "no save"
+12 "file menu"
+13 "read a file"
+14 "write a file"
+15 "save file"
+16 "print editor contents"
+17 "search menu"
+18 "search for ..."
+19 "search"
+20 "spell menu"
+21 "use 'spell'"
+22 "use 'ispell'"
+23 "miscellaneous menu"
+24 "format paragraph"
+25 "shell command"
+26 "check spelling"
+27 "main menu"
+28 "leave editor"
+29 "help"
+30 "file operations"
+31 "redraw screen"
+32 "settings"
+33 "search"
+34 "miscellaneous"
+35 "Control keys: "
+36 "^a ascii code ^i tab ^r right "
+37 "^b bottom of text ^j newline ^t top of text "
+38 "^c command ^k delete char ^u up "
+39 "^d down ^l left ^v undelete word "
+40 "^e search prompt ^m newline ^w delete word "
+41 "^f undelete char ^n next page ^x search "
+42 "^g begin of line ^o end of line ^y delete line "
+43 "^h backspace ^p prev page ^z undelete line "
+44 "^[ (escape) menu "
+45 " "
+46 "Commands: "
+47 "help : get this info file : print file name "
+48 "read : read a file char : ascii code of char "
+49 "write : write a file case : case sensitive search "
+50 "exit : leave and save nocase : case insensitive search "
+51 "quit : leave, no save !cmd : execute \"cmd\" in shell "
+52 "line : display line # 0-9 : go to line \"#\" "
+53 "expand : expand tabs noexpand: do not expand tabs "
+54 " "
+55 " ee [+#] [-i] [-e] [-h] [file(s)] "
+56 "+# :go to line # -i :no info window -e : don't expand tabs -h :no highlight"
+57 "^[ (escape) menu ^e search prompt ^y delete line ^u up ^p prev page "
+58 "^a ascii code ^x search ^z undelete line ^d down ^n next page "
+59 "^b bottom of text ^g begin of line ^w delete word ^l left "
+60 "^t top of text ^o end of line ^v undelete word ^r right "
+61 "^c command ^k delete char ^f undelete char "
+62 "help : get help info |file : print file name |line : print line # "
+63 "read : read a file |char : ascii code of char |0-9 : go to line \"#\""
+64 "write: write a file |case : case sensitive search |exit : leave and save "
+65 "!cmd : shell \"cmd\" |nocase: ignore case in search |quit : leave, no save"
+66 "expand: expand tabs |noexpand: do not expand tabs "
+67 " press Escape (^[) for menu"
+68 "no file"
+69 "ascii code: "
+70 "sending contents of buffer to \"%s\" "
+71 "command: "
+72 "name of file to write: "
+73 "name of file to read: "
+74 "character = %d"
+75 "unknown command \"%s\""
+76 "entered command is not unique"
+77 "line %d "
+78 "length = %d"
+79 "current file is \"%s\" "
+80 "usage: %s [-i] [-e] [-h] [+line_number] [file(s)]\n"
+81 " -i turn off info window\n"
+82 " -e do not convert tabs to spaces\n"
+83 " -h do not use highlighting\n"
+84 "file \"%s\" is a directory"
+85 "new file \"%s\""
+86 "can't open \"%s\""
+87 "file \"%s\", %d lines"
+88 "finished reading file \"%s\""
+89 "reading file \"%s\""
+90 ", read only"
+91 "file \"%s\", %d lines"
+92 "enter name of file: "
+93 "no filename entered: file not saved"
+94 "changes have been made, are you sure? (y/n [n]) "
+95 "y"
+96 "file already exists, overwrite? (y/n) [n] "
+97 "unable to create file \"%s\""
+98 "writing file \"%s\""
+99 "\"%s\" %d lines, %d characters"
+100 " ...searching"
+101 "string \"%s\" not found"
+102 "search for: "
+103 "could not exec %s\n"
+104 "press return to continue "
+105 "press Esc to cancel"
+106 "menu too large for window"
+107 "press any key to continue "
+108 "shell command: "
+109 "...formatting paragraph..."
+110 "<!echo 'list of unrecognized words'; echo -=-=-=-=-=-"
+111 "sending contents of edit buffer to 'spell'"
+112 "right margin is: "
+113 "restricted mode: unable to perform requested operation"
+114 "ON"
+115 "OFF"
+116 "HELP"
+117 "WRITE"
+118 "READ"
+119 "LINE"
+120 "FILE"
+121 "CHARACTER"
+122 "REDRAW"
+123 "RESEQUENCE"
+124 "AUTHOR"
+125 "VERSION"
+126 "CASE"
+127 "NOCASE"
+128 "EXPAND"
+129 "NOEXPAND"
+130 "EXIT"
+131 "QUIT"
+132 "INFO"
+133 "NOINFO"
+134 "MARGINS"
+135 "NOMARGINS"
+136 "AUTOFORMAT"
+137 "NOAUTOFORMAT"
+138 "ECHO"
+139 "PRINTCOMMAND"
+140 "RIGHTMARGIN"
+141 "HIGHLIGHT"
+142 "NOHIGHLIGHT"
+143 "EIGHTBIT"
+144 "NOEIGHTBIT"
+145 "emacs key bindings "
+146 "^a beginning of line ^i tab ^r restore word "
+147 "^b back 1 char ^j undel char ^t top of text "
+148 "^c command ^k delete line ^u bottom of text "
+149 "^d delete char ^l undelete line ^v next page "
+150 "^e end of line ^m newline ^w delete word "
+151 "^f forward 1 char ^n next line ^x search "
+152 "^g go back 1 page ^o ascii char insert ^y search prompt "
+153 "^h backspace ^p prev line ^z next word "
+154 "^[ (escape) menu ^y search prompt ^k delete line ^p prev li ^g prev page"
+155 "^o ascii code ^x search ^l undelete line ^n next li ^v next page"
+156 "^u end of file ^a begin of line ^w delete word ^b back 1 char "
+157 "^t top of text ^e end of line ^r restore word ^f forward 1 char "
+158 "^c command ^d delete char ^j undelete char ^z next word "
+159 "EMACS"
+160 "NOEMACS"
+161 " +# put cursor at line #\n"
+162 "unable to open .init.ee for writing, no configuration saved!"
+163 "ee configuration saved in file %s"
+164 "save editor configuration"
+165 "save ee configuration"
+166 "save in current directory"
+167 "save in home directory"
+168 "ee configuration not saved"
+169 "must specify a file when invoking ree"
+180 "menu too large for window"
+181 "^^more^^"
+182 "VVmoreVV"
+183 "16 bit characters "
+184 "16BIT"
+185 "NO16BIT"
diff --git a/contrib/ee/genstr b/contrib/ee/genstr
new file mode 100755
index 0000000..429f960
--- /dev/null
+++ b/contrib/ee/genstr
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+set -x
+
+if [ $# -lt 2 ]
+then
+ echo usage $0 source_file dest_file
+ exit 1
+fi
+
+trap 'rm -f /tmp/$$.out; exit 0' 0 # set up traps to clean up
+trap 'rm -f /tmp/$$.out; exit 1' 1 2 3 15 # on errors AND normal exit
+
+if [ -f $2 ]
+then
+ rm $2
+fi
+
+cat $1 | grep 'catgetlocal.*\"*\"' |
+ sed -e 's/^.*catgetlocal(//' |
+ sed -e 's/^[ ]*//' |
+ sed -e 's/, \"/ \"/' |
+ sed -e 's/);//' > /tmp/$$.out
+
+cat > $2 <<EOF
+\$
+\$
+\$set 1
+\$quote "
+EOF
+
+sort -n < /tmp/$$.out >> $2
diff --git a/contrib/ee/make.default b/contrib/ee/make.default
new file mode 100644
index 0000000..32ff05d
--- /dev/null
+++ b/contrib/ee/make.default
@@ -0,0 +1,57 @@
+# This is the make file for ee, the "easy editor".
+#
+# If building ee using curses, type "make curses", otherwise new_curse (a
+# subset of curses that supports ee) will be built and ee will use new_curse
+# instead of curses.
+#
+# The "install" target ("make install") will copy the ee binary to
+# the /usr/local/bin directory on the local system. The man page (ee.1)
+# will be copied into the /usr/local/man/man1 directory.
+#
+# The "clean" target ("make clean") will remove the ee and new_curse.o
+# object files, and the ee binary.
+#
+# If the system does not have localization routines, use the -DNO_CATGETS
+# define. If the system supports setlocale(), catopen(), and catgets() and
+# localization is desired, do not use -DNO_CATGETS.
+#
+# DEFINES is used for new_curse.c, and CFLAGS is used for ee.c.
+#
+
+# for System V, using new_curse with terminfo
+DEFINES = -DSYS5 -DNCURSE
+
+# for BSD, using new_curse with termcap
+#DEFINES = -DCAP -DNCURSE
+
+# for BSD systems with select(), using new_curse with termcap, use:
+#DEFINES = -DCAP -DNCURSE -DBSD_SELECT
+
+# flags for compilation
+CFLAGS = -s -DNO_CATGETS
+
+# For Sun systems, remove the '#' from the front of the next two lines:
+#DEFINES = -DSYS5 -DNCURSE
+#CFLAGS = -I/usr/5include -L/usr/5lib -DNO_CATGETS -s
+
+all : ee
+
+curses : ee.c
+ cc ee.c -o ee $(CFLAGS) -lcurses
+
+ee : ee.o new_curse.o
+ cc -o ee ee.o new_curse.o $(CFLAGS)
+
+ee.o : ee.c new_curse.h
+ cc -c ee.c $(DEFINES) $(CFLAGS)
+
+new_curse.o : new_curse.c new_curse.h
+ cc new_curse.c -c $(DEFINES) $(CFLAGS)
+
+install :
+ cp ee /usr/local/bin/ee
+ cp ee.1 /usr/local/man/man1/ee.1
+
+clean :
+ rm -f ee.o new_curse.o ee
+
diff --git a/contrib/ee/new_curse.c b/contrib/ee/new_curse.c
new file mode 100644
index 0000000..9ea8269
--- /dev/null
+++ b/contrib/ee/new_curse.c
@@ -0,0 +1,3813 @@
+/*
+ | new_curse.c
+ |
+ | A subset of curses developed for use with ae.
+ |
+ | written by Hugh Mahon
+ |
+ | THIS MATERIAL IS PROVIDED "AS IS". THERE ARE
+ | NO WARRANTIES OF ANY KIND WITH REGARD TO THIS
+ | MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE
+ | IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ | FITNESS FOR A PARTICULAR PURPOSE. Neither
+ | Hewlett-Packard nor Hugh Mahon shall be liable
+ | for errors contained herein, nor for
+ | incidental or consequential damages in
+ | connection with the furnishing, performance or
+ | use of this material. Neither Hewlett-Packard
+ | nor Hugh Mahon assumes any responsibility for
+ | the use or reliability of this software or
+ | documentation. This software and
+ | documentation is totally UNSUPPORTED. There
+ | is no support contract available. Hewlett-
+ | Packard has done NO Quality Assurance on ANY
+ | of the program or documentation. You may find
+ | the quality of the materials inferior to
+ | supported materials.
+ |
+ | This software is not a product of Hewlett-Packard, Co., or any
+ | other company. No support is implied or offered with this software.
+ | You've got the source, and you're on your own.
+ |
+ | This software may be distributed under the terms of Larry Wall's
+ | Artistic license, a copy of which is included in this distribution.
+ |
+ | This notice must be included with this software and any derivatives.
+ |
+ | Copyright (c) 1986, 1987, 1988, 1991, 1992, 1993, 1994, 1995 Hugh Mahon
+ | All are rights reserved.
+ |
+ | $Header: /home/hugh/sources/old_ae/RCS/new_curse.c,v 1.50 2001/01/19 02:53:40 hugh Exp hugh $
+ |
+ */
+
+char *copyright_message[] = { "Copyright (c) 1986, 1987, 1988, 1991, 1992, 1993, 1994, 1995 Hugh Mahon",
+ "All rights are reserved."};
+
+char * new_curse_name= "@(#) new_curse.c $Revision: 1.50 $";
+
+#include "new_curse.h"
+#include <signal.h>
+#include <fcntl.h>
+
+#ifdef SYS5
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+
+#ifdef BSD_SELECT
+#include <sys/types.h>
+#include <sys/time.h>
+
+#ifdef SLCT_HDR
+#include <sys/select.h> /* on AIX */
+#endif /* SLCT_HDR */
+
+#endif /* BSD_SELECT */
+
+#ifdef HAS_STDLIB
+#include <stdlib.h>
+#endif
+
+#if defined(__STDC__)
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#ifdef HAS_UNISTD
+#include <unistd.h>
+#endif
+
+#ifdef HAS_SYS_IOCTL
+#include <sys/ioctl.h>
+#endif
+
+
+WINDOW *curscr;
+static WINDOW *virtual_scr;
+WINDOW *stdscr;
+WINDOW *last_window_refreshed;
+
+#ifdef TIOCGWINSZ
+ struct winsize ws;
+#endif
+
+#define min(a, b) (a < b ? a : b)
+#define highbitset(a) ((a) & 0x80)
+
+#ifndef CAP
+#define String_Out(table, stack, place) Info_Out(table, stack, place)
+#else
+#define String_Out(table, stack, place) Cap_Out(table, stack, place)
+#endif
+
+#define bw__ 0 /* booleans */
+#define am__ 1
+#define xb__ 2
+#define xs__ 3 /* hp glitch (standout not erased by overwrite) */
+#define xn__ 4
+#define eo__ 5
+#define gn__ 6 /* generic type terminal */
+#define hc__ 7 /* hardcopy terminal */
+#define km__ 8
+#define hs__ 9
+#define in__ 10
+#define da__ 11
+#define db__ 12
+#define mi__ 13 /* safe to move during insert mode */
+#define ms__ 14 /* safe to move during standout mode */
+#define os__ 15
+#define es__ 16
+#define xt__ 17
+#define hz__ 18 /* hazeltine glitch */
+#define ul__ 19
+#define xo__ 20
+#define chts__ 21
+#define nxon__ 22
+#define nrrmc__ 23
+#define npc__ 24
+#define mc5i__ 25
+
+#define co__ 0 /* number of columns */ /* numbers */
+#define it__ 1 /* spaces per tab */
+#define li__ 2 /* number of lines */
+#define lm__ 3
+#define sg__ 4 /* magic cookie glitch */
+#define pb__ 5
+#define vt__ 6
+#define ws__ 7
+
+#define cols__ 0
+#define lines__ 2
+#define xmc__ 4
+#define vt__ 6
+#define wsl__ 7
+#define nlab__ 8
+#define lh__ 9
+#define lw__ 10
+
+#define bt__ 0 /* back tab */ /* strings */
+#define bl__ 1 /* bell */
+#define cr__ 2 /* carriage return */
+#define cs__ 3 /* change scroll region */
+#define ct__ 4 /* clear all tab stops */
+#define cl__ 5 /* clear screen and home cursor */
+#define ce__ 6 /* clear to end of line */
+#define cd__ 7 /* clear to end of display */
+#define ch__ 8 /* set cursor column */
+#define CC__ 9 /* term, settable cmd char in */
+#define cm__ 10 /* screen rel cursor motion, row, column */
+#define do__ 11 /* down one line */
+#define ho__ 12 /* home cursor */
+#define vi__ 13 /* make cursor invisible */
+#define le__ 14 /* move cursor left one space */
+#define CM__ 15 /* memory rel cursor addressing */
+#define ve__ 16 /* make cursor appear normal */
+#define nd__ 17 /* non-destructive space (cursor right) */
+#define ll__ 18 /* last line, first col */
+#define up__ 19 /* cursor up */
+#define vs__ 20
+#define dc__ 21 /* delete character */
+#define dl__ 22 /* delete line */
+#define ds__ 23
+#define hd__ 24
+#define as__ 25
+#define mb__ 26
+#define md__ 27 /* turn on bold */
+#define ti__ 28
+#define dm__ 29 /* turn on delete mode */
+#define mh__ 30 /* half bright mode */
+#define im__ 31 /* insert mode */
+#define mk__ 32
+#define mp__ 33
+#define mr__ 34
+#define so__ 35 /* enter standout mode */
+#define us__ 36
+#define ec__ 37
+#define ae__ 38
+#define me__ 39
+#define te__ 40
+#define ed__ 41
+#define ei__ 42 /* exit insert mode */
+#define se__ 43 /* exit standout mode */
+#define ue__ 44
+#define vb__ 45
+#define ff__ 46
+#define fs__ 47
+#define i1__ 48
+#define i2__ 49
+#define i3__ 50
+#define if__ 51
+#define ic__ 52
+#define al__ 53
+#define ip__ 54
+#define kb__ 55 /* backspace key */
+#define ka__ 56
+#define kC__ 57
+#define kt__ 58
+#define kD__ 59
+#define kL__ 60
+#define kd__ 61
+#define kM__ 62
+#define kE__ 63
+#define kS__ 64
+#define k0__ 65
+#define k1__ 66
+#define kf10__ 67
+#define k2__ 68
+#define k3__ 69
+#define k4__ 70
+#define k5__ 71
+#define k6__ 72
+#define k7__ 73
+#define k8__ 74
+#define k9__ 75
+#define kh__ 76
+#define kI__ 77
+#define kA__ 78
+#define kl__ 79
+#define kH__ 80
+#define kN__ 81
+#define kP__ 82
+#define kr__ 83
+#define kF__ 84
+#define kR__ 85
+#define kT__ 86
+#define ku__ 87 /* key up */
+#define ke__ 88
+#define ks__ 89
+#define l0__ 90
+#define l1__ 91
+#define la__ 92
+#define l2__ 93
+#define l3__ 94
+#define l4__ 95
+#define l5__ 96
+#define l6__ 97
+#define l7__ 98
+#define l8__ 99
+#define l9__ 100
+#define mo__ 101
+#define mm__ 102
+#define nw__ 103
+#define pc__ 104
+#define DC__ 105
+#define DL__ 106
+#define DO__ 107
+#define IC__ 118
+#define SF__ 109
+#define AL__ 110
+#define LE__ 111
+#define RI__ 112
+#define SR__ 113
+#define UP__ 114
+#define pk__ 115
+#define pl__ 116
+#define px__ 117
+#define ps__ 118
+#define pf__ 119
+#define po__ 120
+#define rp__ 121
+#define r1__ 122
+#define r2__ 123
+#define r3__ 124
+#define rf__ 125
+#define rc__ 126
+#define cv__ 127
+#define sc__ 128
+#define sf__ 129
+#define sr__ 130
+#define sa__ 131 /* sgr */
+#define st__ 132
+#define wi__ 133
+#define ta__ 134
+#define ts__ 135
+#define uc__ 136
+#define hu__ 137
+#define iP__ 138
+#define K1__ 139
+#define K2__ 140
+#define K3__ 141
+#define K4__ 142
+#define K5__ 143
+#define pO__ 144
+#define ml__ 145
+#define mu__ 146
+#define rmp__ 145
+#define acsc__ 146
+#define pln__ 147
+#define kcbt__ 148
+#define smxon__ 149
+#define rmxon__ 150
+#define smam__ 151
+#define rmam__ 152
+#define xonc__ 153
+#define xoffc__ 154
+#define enacs__ 155
+#define smln__ 156
+#define rmln__ 157
+#define kbeg__ 158
+#define kcan__ 159
+#define kclo__ 160
+#define kcmd__ 161
+#define kcpy__ 162
+#define kcrt__ 163
+#define kend__ 164
+#define kent__ 165
+#define kext__ 166
+#define kfnd__ 167
+#define khlp__ 168
+#define kmrk__ 169
+#define kmsg__ 170
+#define kmov__ 171
+#define knxt__ 172
+#define kopn__ 173
+#define kopt__ 174
+#define kprv__ 175
+#define kprt__ 176
+#define krdo__ 177
+#define kref__ 178
+#define krfr__ 179
+#define krpl__ 180
+#define krst__ 181
+#define kres__ 182
+#define ksav__ 183
+#define kspd__ 184
+#define kund__ 185
+#define kBEG__ 186
+#define kCAN__ 187
+#define kCMD__ 188
+#define kCPY__ 189
+#define kCRT__ 190
+#define kDC__ 191
+#define kDL__ 192
+#define kslt__ 193
+#define kEND__ 194
+#define kEOL__ 195
+#define kEXT__ 196
+#define kFND__ 197
+#define kHLP__ 198
+#define kHOM__ 199
+#define kIC__ 200
+#define kLFT__ 201
+#define kMSG__ 202
+#define kMOV__ 203
+#define kNXT__ 204
+#define kOPT__ 205
+#define kPRV__ 206
+#define kPRT__ 207
+#define kRDO__ 208
+#define kRPL__ 209
+#define kRIT__ 210
+#define kRES__ 211
+#define kSAV__ 212
+#define kSPD__ 213
+#define kUND__ 214
+#define rfi__ 215
+#define kf11__ 216
+#define kf12__ 217
+#define kf13__ 218
+#define kf14__ 219
+#define kf15__ 220
+#define kf16__ 221
+#define kf17__ 222
+#define kf18__ 223
+#define kf19__ 224
+#define kf20__ 225
+#define kf21__ 226
+#define kf22__ 227
+#define kf23__ 228
+#define kf24__ 229
+#define kf25__ 230
+#define kf26__ 231
+#define kf27__ 232
+#define kf28__ 233
+#define kf29__ 234
+#define kf30__ 235
+#define kf31__ 236
+#define kf32__ 237
+#define kf33__ 238
+#define kf34__ 239
+#define kf35__ 240
+#define kf36__ 241
+#define kf37__ 242
+#define kf38__ 243
+#define kf39__ 244
+#define kf40__ 245
+#define kf41__ 246
+#define kf42__ 247
+#define kf43__ 248
+#define kf44__ 249
+#define kf45__ 250
+#define kf46__ 251
+#define kf47__ 252
+#define kf48__ 253
+#define kf49__ 254
+#define kf50__ 255
+#define kf51__ 256
+#define kf52__ 257
+#define kf53__ 258
+#define kf54__ 259
+#define kf55__ 260
+#define kf56__ 261
+#define kf57__ 262
+#define kf58__ 263
+#define kf59__ 264
+#define kf60__ 265
+#define kf61__ 266
+#define kf62__ 267
+#define kf63__ 268
+#define el1__ 269
+#define mgc__ 270
+#define smgl__ 271
+#define smgr__ 272
+
+#ifdef CAP
+char *Boolean_names[] = {
+"bw", "am", "xb", "xs", "xn", "eo", "gn", "hc", "km", "hs", "in", "da", "db",
+"mi", "ms", "os", "es", "xt", "hz", "ul", "xo", "HC", "nx", "NR", "NP", "5i"
+};
+
+char *Number_names[] = {
+"co#", "it#", "li#", "lm#", "sg#", "pb#", "vt#", "ws#", "Nl#", "lh#", "lw#"
+};
+
+char *String_names[] = {
+"bt=", "bl=", "cr=", "cs=", "ct=", "cl=", "ce=", "cd=", "ch=", "CC=", "cm=",
+"do=", "ho=", "vi=", "le=", "CM=", "ve=", "nd=", "ll=", "up=", "vs=", "dc=",
+"dl=", "ds=", "hd=", "as=", "mb=", "md=", "ti=", "dm=", "mh=", "im=", "mk=",
+"mp=", "mr=", "so=", "us=", "ec=", "ae=", "me=", "te=", "ed=", "ei=", "se=",
+"ue=", "vb=", "ff=", "fs=", "i1=", "i2=", "i3=", "if=", "ic=", "al=", "ip=",
+"kb=", "ka=", "kC=", "kt=", "kD=", "kL=", "kd=", "kM=", "kE=", "kS=", "k0=",
+"k1=", "k;=", "k2=", "k3=", "k4=", "k5=", "k6=", "k7=", "k8=", "k9=", "kh=",
+"kI=", "kA=", "kl=", "kH=", "kN=", "kP=", "kr=", "kF=", "kR=", "kT=", "ku=",
+"ke=", "ks=", "l0=", "l1=", "la=", "l2=", "l3=", "l4=", "l5=", "l6=", "l7=",
+"l8=", "l9=", "mo=", "mm=", "nw=", "pc=", "DC=", "DL=", "DO=", "IC=", "SF=",
+"AL=", "LE=", "RI=", "SR=", "UP=", "pk=", "pl=", "px=", "ps=", "pf=", "po=",
+"rp=", "r1=", "r2=", "r3=", "rf=", "rc=", "cv=", "sc=", "sf=", "sr=", "sa=",
+"st=", "wi=", "ta=", "ts=", "uc=", "hu=", "iP=", "K1=", "K3=", "K2=", "K4=",
+"K5=", "pO=", "rP=", "ac=", "pn=", "kB=", "SX=", "RX=", "SA=", "RA=", "XN=",
+"XF=", "eA=", "LO=", "LF=", "@1=", "@2=", "@3=", "@4=", "@5=", "@6=", "@7=",
+"@8=", "@9=", "@0=", "%1=", "%2=", "%3=", "%4=", "%5=", "%6=", "%7=", "%8=",
+"%9=", "%0=", "&1=", "&2=", "&3=", "&4=", "&5=", "&6=", "&7=", "&8=", "&9=",
+"&0=", "*1=", "*2=", "*3=", "*4=", "*5=", "*6=", "*7=", "*8=", "*9=", "*0=",
+"#1=", "#2=", "#3=", "#4=", "%a=", "%b=", "%c=", "%d=", "%e=", "%f=", "%g=",
+"%h=", "%i=", "%j=", "!1=", "!2=", "!3=", "RF=", "F1=", "F2=", "F3=", "F4=",
+"F5=", "F6=", "F7=", "F8=", "F9=", "FA=", "FB=", "FC=", "FD=", "FE=", "FF=",
+"FG=", "FH=", "FI=", "FJ=", "FK=", "FL=", "FM=", "FN=", "FO=", "FP=", "FQ=",
+"FR=", "FS=", "FT=", "FU=", "FV=", "FW=", "FX=", "FY=", "FZ=", "Fa=", "Fb=",
+"Fc=", "Fd=", "Fe=", "Ff=", "Fg=", "Fh=", "Fi=", "Fj=", "Fk=", "Fl=", "Fm=",
+"Fn=", "Fo=", "Fp=", "Fq=", "Fr=", "cb=", "MC=", "ML=", "MR="
+};
+#endif
+
+char *new_curse = "October 1987";
+
+char in_buff[100]; /* buffer for ungetch */
+int bufp; /* next free position in in_buff */
+
+char *TERMINAL_TYPE = NULL; /* terminal type to be gotten from environment */
+int CFOUND = FALSE;
+int Data_Line_len = 0;
+int Max_Key_len; /* max length of a sequence sent by a key */
+char *Data_Line = NULL;
+char *TERM_PATH = NULL;
+char *TERM_data_ptr = NULL;
+char *Term_File_name = NULL; /* name of file containing terminal description */
+FILE *TFP; /* file pointer to file with terminal des. */
+int Fildes; /* file descriptor for terminfo file */
+int STAND = FALSE; /* is standout mode activated? */
+int TERM_INFO = FALSE; /* is terminfo being used (TRUE), or termcap (FALSE) */
+int Time_Out; /* set when time elapsed while trying to read function key */
+int Curr_x; /* current x position on screen */
+int Curr_y; /* current y position on the screen */
+int LINES;
+int COLS;
+int Move_It; /* flag to move cursor if magic cookie glitch */
+int initialized = FALSE; /* tells whether new_curse is initialized */
+float speed;
+float chars_per_millisecond;
+int Repaint_screen; /* if an operation to change screen impossible, repaint screen */
+int Intr; /* storeage for interrupt character */
+int Parity; /* 0 = no parity, 1 = odd parity, 2 = even parity */
+int Noblock; /* for BSD systems */
+int Num_bits; /* number of bits per character */
+int Flip_Bytes; /* some systems have byte order reversed */
+int interrupt_flag = FALSE; /* set true if SIGWINCH received */
+
+#ifndef CAP
+char *Strings;
+#endif
+
+struct KEYS {
+ int length; /* length of string sent by key */
+ char *string; /* string sent by key */
+ int value; /* CURSES value of key (9-bit) */
+ };
+
+struct KEY_STACK {
+ struct KEYS *element;
+ struct KEY_STACK *next;
+ };
+
+struct KEY_STACK *KEY_TOS = NULL;
+struct KEY_STACK *KEY_POINT;
+
+/*
+ |
+ | Not all systems have good terminal information, so we will define
+ | keyboard information here for the most widely used terminal type,
+ | the VT100.
+ |
+ */
+
+struct KEYS vt100[] =
+ {
+ { 3, "\033[A", 0403 }, /* key up */
+ { 3, "\033[C", 0405 }, /* key right */
+ { 3, "\033[D", 0404 }, /* key left */
+
+ { 4, "\033[6~", 0522 }, /* key next page */
+ { 4, "\033[5~", 0523 }, /* key prev page */
+ { 3, "\033[[", 0550 }, /* key end */
+ { 3, "\033[@", 0406 }, /* key home */
+ { 4, "\033[2~", 0513 }, /* key insert char */
+
+ { 3, "\033[y", 0410 }, /* key F0 */
+ { 3, "\033[P", 0411 }, /* key F1 */
+ { 3, "\033[Q", 0412 }, /* key F2 */
+ { 3, "\033[R", 0413 }, /* key F3 */
+ { 3, "\033[S", 0414 }, /* key F4 */
+ { 3, "\033[t", 0415 }, /* key F5 */
+ { 3, "\033[u", 0416 }, /* key F6 */
+ { 3, "\033[v", 0417 }, /* key F7 */
+ { 3, "\033[l", 0420 }, /* key F8 */
+ { 3, "\033[w", 0421 }, /* key F9 */
+ { 3, "\033[x", 0422 }, /* key F10 */
+
+ { 5, "\033[10~", 0410 }, /* key F0 */
+ { 5, "\033[11~", 0411 }, /* key F1 */
+ { 5, "\033[12~", 0412 }, /* key F2 */
+ { 5, "\033[13~", 0413 }, /* key F3 */
+ { 5, "\033[14~", 0414 }, /* key F4 */
+ { 5, "\033[15~", 0415 }, /* key F5 */
+ { 5, "\033[17~", 0416 }, /* key F6 */
+ { 5, "\033[18~", 0417 }, /* key F7 */
+ { 5, "\033[19~", 0420 }, /* key F8 */
+ { 5, "\033[20~", 0421 }, /* key F9 */
+ { 5, "\033[21~", 0422 }, /* key F10 */
+ { 5, "\033[23~", 0423 }, /* key F11 */
+ { 5, "\033[24~", 0424 }, /* key F12 */
+ { 3, "\033[q", 0534 }, /* ka1 upper-left of keypad */
+ { 3, "\033[s", 0535 }, /* ka3 upper-right of keypad */
+ { 3, "\033[r", 0536 }, /* kb2 center of keypad */
+ { 3, "\033[p", 0537 }, /* kc1 lower-left of keypad */
+ { 3, "\033[n", 0540 }, /* kc3 lower-right of keypad */
+
+ /*
+ | The following are the same keys as above, but with
+ | a different character following the escape char.
+ */
+
+ { 3, "\033OA", 0403 }, /* key up */
+ { 3, "\033OC", 0405 }, /* key right */
+ { 3, "\033OD", 0404 }, /* key left */
+ { 3, "\033OB", 0402 }, /* key down */
+ { 4, "\033O6~", 0522 }, /* key next page */
+ { 4, "\033O5~", 0523 }, /* key prev page */
+ { 3, "\033O[", 0550 }, /* key end */
+ { 3, "\033O@", 0406 }, /* key home */
+ { 4, "\033O2~", 0513 }, /* key insert char */
+
+ { 3, "\033Oy", 0410 }, /* key F0 */
+ { 3, "\033OP", 0411 }, /* key F1 */
+ { 3, "\033OQ", 0412 }, /* key F2 */
+ { 3, "\033OR", 0413 }, /* key F3 */
+ { 3, "\033OS", 0414 }, /* key F4 */
+ { 3, "\033Ot", 0415 }, /* key F5 */
+ { 3, "\033Ou", 0416 }, /* key F6 */
+ { 3, "\033Ov", 0417 }, /* key F7 */
+ { 3, "\033Ol", 0420 }, /* key F8 */
+ { 3, "\033Ow", 0421 }, /* key F9 */
+ { 3, "\033Ox", 0422 }, /* key F10 */
+
+ { 5, "\033O10~", 0410 }, /* key F0 */
+ { 5, "\033O11~", 0411 }, /* key F1 */
+ { 5, "\033O12~", 0412 }, /* key F2 */
+ { 5, "\033O13~", 0413 }, /* key F3 */
+ { 5, "\033O14~", 0414 }, /* key F4 */
+ { 5, "\033O15~", 0415 }, /* key F5 */
+ { 5, "\033O17~", 0416 }, /* key F6 */
+ { 5, "\033O18~", 0417 }, /* key F7 */
+ { 5, "\033O19~", 0420 }, /* key F8 */
+ { 5, "\033O20~", 0421 }, /* key F9 */
+ { 5, "\033O21~", 0422 }, /* key F10 */
+ { 5, "\033O23~", 0423 }, /* key F11 */
+ { 5, "\033O24~", 0424 }, /* key F12 */
+ { 3, "\033Oq", 0534 }, /* ka1 upper-left of keypad */
+ { 3, "\033Os", 0535 }, /* ka3 upper-right of keypad */
+ { 3, "\033Or", 0536 }, /* kb2 center of keypad */
+ { 3, "\033Op", 0537 }, /* kc1 lower-left of keypad */
+ { 3, "\033On", 0540 }, /* kc3 lower-right of keypad */
+
+ { 0, "", 0 } /* end */
+ };
+
+struct Parameters {
+ int value;
+ struct Parameters *next;
+ };
+
+int Key_vals[] = {
+ 0407, 0526, 0515, 0525, 0512, 0510, 0402, 0514, 0517, 0516, 0410, 0411,
+ 0422, 0412, 0413, 0414, 0415, 0416, 0417, 0420, 0421, 0406, 0513, 0511,
+ 0404, 0533, 0522, 0523, 0405, 0520, 0521, 0524, 0403,
+ 0534, 0535, 0536, 0537, 0540, 0541, 0542, 0543, 0544, 0545, 0546, 0547,
+ 0550, 0527, 0551, 0552, 0553, 0554, 0555, 0556, 0557, 0560, 0561, 0562,
+ 0532, 0563, 0564, 0565, 0566, 0567, 0570, 0571, 0627, 0630, 0572, 0573,
+ 0574, 0575, 0576, 0577, 0600, 0601, 0602, 0603, 0604, 0605, 0606, 0607,
+ 0610, 0611, 0612, 0613, 0614, 0615, 0616, 0617, 0620, 0621, 0622, 0623,
+ 0624, 0625, 0626, 0423, 0424, 0425, 0426, 0427, 0430, 0431,
+ 0432, 0433, 0434, 0435, 0436, 0437, 0440, 0441, 0442, 0443, 0444, 0445,
+ 0446, 0447, 0450, 0451, 0452, 0453, 0454, 0455, 0456, 0457, 0460, 0461,
+ 0462, 0463, 0464, 0465, 0466, 0467, 0470, 0471, 0472, 0473, 0474, 0475,
+ 0476, 0477, 0500, 0501, 0502, 0503, 0504, 0505, 0506, 0507
+};
+
+int attributes_set[9];
+
+static int nc_attributes = 0; /* global attributes for new_curse to observe */
+
+#ifdef SYS5
+struct termio Terminal;
+struct termio Saved_tty;
+#else
+struct sgttyb Terminal;
+struct sgttyb Saved_tty;
+#endif
+
+char *tc_;
+
+int Booleans[128];
+int Numbers[128];
+char *String_table[1024];
+
+int *virtual_lines;
+
+static char nc_scrolling_ability = FALSE;
+
+#ifdef CAP
+
+#if defined(__STDC__) || defined(__cplusplus)
+#define P_(s) s
+#else
+#define P_(s) ()
+#endif /* __STDC__ */
+
+int tc_Get_int P_((int));
+void CAP_PARSE P_((void));
+void Find_term P_((void));
+
+#undef P_
+
+#endif /* CAP */
+
+
+#ifndef __STDC__
+#ifndef HAS_STDLIB
+extern char *fgets();
+extern char *malloc();
+extern char *getenv();
+FILE *fopen(); /* declaration for open function */
+#endif /* HAS_STDLIB */
+#endif /* __STDC__ */
+
+#ifdef SIGWINCH
+
+/*
+ | Copy the contents of one window to another.
+ */
+
+void
+copy_window(origin, destination)
+WINDOW *origin, *destination;
+{
+ int row, column;
+ struct _line *orig, *dest;
+
+ orig = origin->first_line;
+ dest = destination->first_line;
+
+ for (row = 0;
+ row < (min(origin->Num_lines, destination->Num_lines));
+ row++)
+ {
+ for (column = 0;
+ column < (min(origin->Num_cols, destination->Num_cols));
+ column++)
+ {
+ dest->row[column] = orig->row[column];
+ dest->attributes[column] = orig->attributes[column];
+ }
+ dest->changed = orig->changed;
+ dest->scroll = orig->scroll;
+ dest->last_char = min(orig->last_char, destination->Num_cols);
+ orig = orig->next_screen;
+ dest = dest->next_screen;
+ }
+ destination->LX = min((destination->Num_cols - 1), origin->LX);
+ destination->LY = min((destination->Num_lines - 1), origin->LY);
+ destination->Attrib = origin->Attrib;
+ destination->scroll_up = origin->scroll_up;
+ destination->scroll_down = origin->scroll_down;
+ destination->SCROLL_CLEAR = origin->SCROLL_CLEAR;
+}
+
+void
+reinitscr(foo)
+int foo;
+{
+ WINDOW *local_virt;
+ WINDOW *local_std;
+ WINDOW *local_cur;
+
+ signal(SIGWINCH, reinitscr);
+#ifdef TIOCGWINSZ
+ if (ioctl(0, TIOCGWINSZ, &ws) >= 0)
+ {
+ if (ws.ws_row == LINES && ws.ws_col == COLS)
+ return;
+ if (ws.ws_row > 0)
+ LINES = ws.ws_row;
+ if (ws.ws_col > 0)
+ COLS = ws.ws_col;
+ }
+#endif /* TIOCGWINSZ */
+ local_virt = newwin(LINES, COLS, 0, 0);
+ local_std = newwin(LINES, COLS, 0, 0);
+ local_cur = newwin(LINES, COLS, 0, 0);
+ copy_window(virtual_scr, local_virt);
+ copy_window(stdscr, local_std);
+ copy_window(curscr, local_cur);
+ delwin(virtual_scr);
+ delwin(stdscr);
+ delwin(curscr);
+ virtual_scr = local_virt;
+ stdscr = local_std;
+ curscr = local_cur;
+ free(virtual_lines);
+ virtual_lines = (int *) malloc(LINES * (sizeof(int)));
+ interrupt_flag = TRUE;
+}
+#endif /* SIGWINCH */
+
+void
+initscr() /* initialize terminal for operations */
+{
+ int value;
+ char *lines_string;
+ char *columns_string;
+#ifdef CAP
+ char *pointer;
+#endif /* CAP */
+
+#ifdef DIAG
+printf("starting initscr \n");fflush(stdout);
+#endif
+ if (initialized)
+ return;
+#ifdef BSD_SELECT
+ setbuf(stdin, NULL);
+#endif /* BSD_SELECT */
+ Flip_Bytes = FALSE;
+ Parity = 0;
+ Time_Out = FALSE;
+ bufp = 0;
+ Move_It = FALSE;
+ Noblock = FALSE;
+#ifdef SYS5
+ value = ioctl(0, TCGETA, &Terminal);
+ if (Terminal.c_cflag & PARENB)
+ {
+ if (Terminal.c_cflag & PARENB)
+ Parity = 1;
+ else
+ Parity = 2;
+ }
+ if ((Terminal.c_cflag & CS8) == CS8)
+ {
+ Num_bits = 8;
+ }
+ else if ((Terminal.c_cflag & CS7) == CS7)
+ Num_bits = 7;
+ else if ((Terminal.c_cflag & CS6) == CS6)
+ Num_bits = 6;
+ else
+ Num_bits = 5;
+ value = Terminal.c_cflag & 037;
+ switch (value) {
+ case 01: speed = 50.0;
+ break;
+ case 02: speed = 75.0;
+ break;
+ case 03: speed = 110.0;
+ break;
+ case 04: speed = 134.5;
+ break;
+ case 05: speed = 150.0;
+ break;
+ case 06: speed = 200.0;
+ break;
+ case 07: speed = 300.0;
+ break;
+ case 010: speed = 600.0;
+ break;
+ case 011: speed = 900.0;
+ break;
+ case 012: speed = 1200.0;
+ break;
+ case 013: speed = 1800.0;
+ break;
+ case 014: speed = 2400.0;
+ break;
+ case 015: speed = 3600.0;
+ break;
+ case 016: speed = 4800.0;
+ break;
+ case 017: speed = 7200.0;
+ break;
+ case 020: speed = 9600.0;
+ break;
+ case 021: speed = 19200.0;
+ break;
+ case 022: speed = 38400.0;
+ break;
+ default: speed = 0.0;
+ }
+#else
+ value = ioctl(0, TIOCGETP, &Terminal);
+ if (Terminal.sg_flags & EVENP)
+ Parity = 2;
+ else if (Terminal.sg_flags & ODDP)
+ Parity = 1;
+ value = Terminal.sg_ospeed;
+ switch (value) {
+ case 01: speed = 50.0;
+ break;
+ case 02: speed = 75.0;
+ break;
+ case 03: speed = 110.0;
+ break;
+ case 04: speed = 134.5;
+ break;
+ case 05: speed = 150.0;
+ break;
+ case 06: speed = 200.0;
+ break;
+ case 07: speed = 300.0;
+ break;
+ case 010: speed = 600.0;
+ break;
+ case 011: speed = 1200.0;
+ break;
+ case 012: speed = 1800.0;
+ break;
+ case 013: speed = 2400.0;
+ break;
+ case 014: speed = 4800.0;
+ break;
+ case 015: speed = 9600.0;
+ break;
+ default: speed = 0.0;
+ }
+#endif
+ chars_per_millisecond = (0.001 * speed) / 8.0;
+ TERMINAL_TYPE = getenv("TERM");
+ if (TERMINAL_TYPE == NULL)
+ {
+ printf("unknown terminal type\n");
+ exit(0);
+ }
+#ifndef CAP
+ Fildes = -1;
+ TERM_PATH = getenv("TERMINFO");
+ if (TERM_PATH != NULL)
+ {
+ Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
+ Term_File_name = malloc(Data_Line_len);
+ sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
+ Fildes = open(Term_File_name, O_RDONLY);
+ }
+ if (Fildes == -1)
+ {
+ TERM_PATH = "/usr/lib/terminfo";
+ Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
+ Term_File_name = malloc(Data_Line_len);
+ sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
+ Fildes = open(Term_File_name, O_RDONLY);
+ }
+ if (Fildes == -1)
+ {
+ TERM_PATH = "/usr/share/lib/terminfo";
+ Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
+ Term_File_name = malloc(Data_Line_len);
+ sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
+ Fildes = open(Term_File_name, O_RDONLY);
+ }
+ if (Fildes == -1)
+ {
+ TERM_PATH = "/usr/share/terminfo";
+ Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE);
+ Term_File_name = malloc(Data_Line_len);
+ sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE);
+ Fildes = open(Term_File_name, O_RDONLY);
+ }
+ if (Fildes == -1)
+ {
+ free(Term_File_name);
+ Term_File_name = NULL;
+ }
+ else
+ TERM_INFO = INFO_PARSE();
+#else
+ /*
+ | termcap information can be in the TERMCAP env variable, if so
+ | use that, otherwise check the /etc/termcap file
+ */
+ if ((pointer = Term_File_name = getenv("TERMCAP")) != NULL)
+ {
+ if (*Term_File_name != '/')
+ Term_File_name = "/etc/termcap";
+ }
+ else
+ {
+ Term_File_name = "/etc/termcap";
+ }
+ if ((TFP = fopen(Term_File_name, "r")) == NULL)
+ {
+ printf("unable to open /etc/termcap file \n");
+ exit(0);
+ }
+ for (value = 0; value < 1024; value++)
+ String_table[value] = NULL;
+ for (value = 0; value < 128; value++)
+ Booleans[value] = 0;
+ for (value = 0; value < 128; value++)
+ Numbers[value] = 0;
+ Data_Line = malloc(512);
+ if (pointer && *pointer != '/')
+ {
+ TERM_data_ptr = pointer;
+ CAP_PARSE();
+ }
+ else
+ {
+ Find_term();
+ CAP_PARSE();
+ }
+#endif
+ if (String_table[pc__] == NULL)
+ String_table[pc__] = "\0";
+ if ((String_table[cm__] == NULL) || (Booleans[hc__]))
+ {
+ fprintf(stderr, "sorry, unable to use this terminal type for screen editing\n");
+ exit(0);
+ }
+ Key_Get();
+ keys_vt100();
+ LINES = Numbers[li__];
+ COLS = Numbers[co__];
+ if ((lines_string = getenv("LINES")) != NULL)
+ {
+ value = atoi(lines_string);
+ if (value > 0)
+ LINES = value;
+ }
+ if ((columns_string = getenv("COLUMNS")) != NULL)
+ {
+ value = atoi(columns_string);
+ if (value > 0)
+ COLS = value;
+ }
+#ifdef TIOCGWINSZ
+ /*
+ | get the window size
+ */
+ if (ioctl(0, TIOCGWINSZ, &ws) >= 0)
+ {
+ if (ws.ws_row > 0)
+ LINES = ws.ws_row;
+ if (ws.ws_col > 0)
+ COLS = ws.ws_col;
+ }
+#endif
+ virtual_scr = newwin(LINES, COLS, 0, 0);
+ stdscr = newwin(LINES, COLS, 0, 0);
+ curscr = newwin(LINES, COLS, 0, 0);
+ wmove(stdscr, 0, 0);
+ werase(stdscr);
+ Repaint_screen = TRUE;
+ initialized = TRUE;
+ virtual_lines = (int *) malloc(LINES * (sizeof(int)));
+
+#ifdef SIGWINCH
+ /*
+ | reset size of windows and LINES and COLS if term window
+ | changes size
+ */
+ signal(SIGWINCH, reinitscr);
+#endif /* SIGWINCH */
+
+ /*
+ | check if scrolling is available
+ */
+
+ nc_scrolling_ability = ((String_table[al__] != NULL) &&
+ (String_table[dl__])) || ((String_table[cs__])
+ && (String_table[sr__]));
+
+}
+
+#ifndef CAP
+int
+Get_int() /* get a two-byte integer from the terminfo file */
+{
+ int High_byte;
+ int Low_byte;
+ int temp;
+
+ Low_byte = *((unsigned char *) TERM_data_ptr++);
+ High_byte = *((unsigned char *) TERM_data_ptr++);
+ if (Flip_Bytes)
+ {
+ temp = Low_byte;
+ Low_byte = High_byte;
+ High_byte = temp;
+ }
+ if ((High_byte == 255) && (Low_byte == 255))
+ return (-1);
+ else
+ return(Low_byte + (High_byte * 256));
+}
+
+int
+INFO_PARSE() /* parse off the data in the terminfo data file */
+{
+ int offset;
+ int magic_number = 0;
+ int counter = 0;
+ int Num_names = 0;
+ int Num_bools = 0;
+ int Num_ints = 0;
+ int Num_strings = 0;
+ int string_table_len = 0;
+ char *temp_ptr;
+
+ TERM_data_ptr = Data_Line = malloc((10240 * (sizeof(char))));
+ Data_Line_len = read(Fildes, Data_Line, 10240);
+ if ((Data_Line_len >= 10240) || (Data_Line_len < 0))
+ return(0);
+ /*
+ | get magic number
+ */
+ magic_number = Get_int();
+ /*
+ | if magic number not right, reverse byte order and check again
+ */
+ if (magic_number != 282)
+ {
+ Flip_Bytes = TRUE;
+ TERM_data_ptr--;
+ TERM_data_ptr--;
+ magic_number = Get_int();
+ if (magic_number != 282)
+ return(0);
+ }
+ /*
+ | get the number of each type in the terminfo data file
+ */
+ Num_names = Get_int();
+ Num_bools = Get_int();
+ Num_ints = Get_int();
+ Num_strings = Get_int();
+ string_table_len = Get_int();
+ Strings = malloc(string_table_len);
+ while (Num_names > 0)
+ {
+ TERM_data_ptr++;
+ Num_names--;
+ }
+ counter = 0;
+ while (Num_bools)
+ {
+ Num_bools--;
+ Booleans[counter++] = *TERM_data_ptr++;
+ }
+ if (((unsigned int) TERM_data_ptr) & 1) /* force alignment */
+ TERM_data_ptr++;
+ counter = 0;
+ while (Num_ints)
+ {
+ Num_ints--;
+ Numbers[counter] = Get_int();
+ counter++;
+ }
+ temp_ptr = TERM_data_ptr + Num_strings + Num_strings;
+ memcpy(Strings, temp_ptr, string_table_len);
+ counter = bt__;
+ while (Num_strings)
+ {
+ Num_strings--;
+ if ((offset=Get_int()) != -1)
+ {
+ if (String_table[counter] == NULL)
+ String_table[counter] = Strings + offset;
+ }
+ else
+ String_table[counter] = NULL;
+ counter++;
+ }
+ close(Fildes);
+ free(Data_Line);
+ return(TRUE);
+}
+#endif /* ifndef CAP */
+
+int
+AtoI() /* convert ascii text to integers */
+{
+ int Temp;
+
+ Temp = 0;
+ while ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
+ {
+ Temp = (Temp * 10) + (*TERM_data_ptr - '0');
+ TERM_data_ptr++;
+ }
+ return(Temp);
+}
+
+void
+Key_Get() /* create linked list with all key sequences obtained from terminal database */
+{
+ int Counter;
+ int Klen;
+ int key_def;
+ struct KEY_STACK *Spoint;
+
+ Max_Key_len = 0;
+ Counter = 0;
+ key_def = kb__;
+ while (key_def <= kf63__)
+ {
+ if (key_def == ke__)
+ key_def = K1__;
+ else if (key_def == (K5__ + 1))
+ key_def = kcbt__;
+ else if (key_def == (kcbt__ + 1))
+ key_def = kbeg__;
+ else if (key_def == (kUND__ + 1))
+ key_def = kf11__;
+ if (String_table[key_def] != NULL)
+ {
+ if (KEY_TOS == NULL)
+ Spoint = KEY_TOS = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
+ else
+ {
+ Spoint = KEY_TOS;
+ while (Spoint->next != NULL)
+ Spoint = Spoint->next;
+ Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
+ Spoint = Spoint->next;
+ }
+ Spoint->next = NULL;
+ Spoint->element = (struct KEYS *) malloc(sizeof(struct KEYS));
+ Spoint->element->string = String_table[key_def];
+ Spoint->element->length = strlen(String_table[key_def]);
+ Spoint->element->value = Key_vals[Counter];
+ Klen = strlen(Spoint->element->string);
+ if (Klen > Max_Key_len)
+ Max_Key_len = Klen;
+ /*
+ | Some terminal types accept keystrokes of the form
+ | \E[A and \EOA, substituting '[' for 'O'. Make a
+ | duplicate of such key strings (since the
+ | database will only have one version) so new_curse
+ | can understand both.
+ */
+ if ((Spoint->element->length > 1) &&
+ ((String_table[key_def][1] == '[') ||
+ (String_table[key_def][1] == 'O')))
+ {
+ Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
+ Spoint = Spoint->next;
+ Spoint->next = NULL;
+ Spoint->element = (struct KEYS *) malloc(sizeof(struct KEYS));
+ Spoint->element->length = strlen(String_table[key_def]);
+ Spoint->element->string = malloc(Spoint->element->length + 1);
+ strcpy(Spoint->element->string, String_table[key_def]);
+ Spoint->element->value = Key_vals[Counter];
+ Klen = strlen(Spoint->element->string);
+ if (Klen > Max_Key_len)
+ Max_Key_len = Klen;
+
+ if (String_table[key_def][1] == '[')
+ Spoint->element->string[1] = 'O';
+ else
+ Spoint->element->string[1] = '[';
+ }
+ }
+ key_def++;
+ Counter++;
+ }
+}
+
+/*
+ | insert information about keys for a vt100 terminal
+ */
+
+void
+keys_vt100()
+{
+ int counter;
+ int Klen;
+ struct KEY_STACK *Spoint;
+
+ Spoint = KEY_TOS;
+ while (Spoint->next != NULL)
+ Spoint = Spoint->next;
+ for (counter = 0; vt100[counter].length != 0; counter++)
+ {
+ Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK));
+ Spoint = Spoint->next;
+ Spoint->next = NULL;
+ Spoint->element = &vt100[counter];
+ Klen = strlen(Spoint->element->string);
+ if (Klen > Max_Key_len)
+ Max_Key_len = Klen;
+ }
+}
+
+#ifdef CAP
+char *
+String_Get(param) /* read the string */
+char *param;
+{
+ char *String;
+ char *Temp;
+ int Counter;
+
+ if (param == NULL)
+ {
+ while (*TERM_data_ptr != '=')
+ TERM_data_ptr++;
+ Temp = ++TERM_data_ptr;
+ Counter = 1;
+ while ((*Temp != ':') && (*Temp != (char)NULL))
+ {
+ Counter++;
+ Temp++;
+ }
+ if (Counter == 1) /* no data */
+ return(NULL);
+ String = Temp = malloc(Counter);
+ while ((*TERM_data_ptr != ':') && (*TERM_data_ptr != (char)NULL))
+ {
+ if (*TERM_data_ptr == '\\')
+ {
+ TERM_data_ptr++;
+ if (*TERM_data_ptr == 'n')
+ *Temp = '\n';
+ else if (*TERM_data_ptr == 't')
+ *Temp = '\t';
+ else if (*TERM_data_ptr == 'b')
+ *Temp = '\b';
+ else if (*TERM_data_ptr == 'r')
+ *Temp = '\r';
+ else if (*TERM_data_ptr == 'f')
+ *Temp = '\f';
+ else if ((*TERM_data_ptr == 'e') || (*TERM_data_ptr == 'E'))
+ *Temp = '\033'; /* escape */
+ else if (*TERM_data_ptr == '\\')
+ *Temp = '\\';
+ else if (*TERM_data_ptr == '\'')
+ *Temp = '\'';
+ else if ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
+ {
+ Counter = 0;
+ while ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9'))
+ {
+ Counter = (8 * Counter) + (*TERM_data_ptr - '0');
+ TERM_data_ptr++; /* ? */
+ }
+ *Temp = Counter;
+ TERM_data_ptr--;
+ }
+ TERM_data_ptr++;
+ Temp++;
+ }
+ else if (*TERM_data_ptr == '^')
+ {
+ TERM_data_ptr++;
+ if ((*TERM_data_ptr >= '@') && (*TERM_data_ptr <= '_'))
+ *Temp = *TERM_data_ptr - '@';
+ else if (*TERM_data_ptr == '?')
+ *Temp = 127;
+ TERM_data_ptr++;
+ Temp++;
+ }
+ else
+ *Temp++ = *TERM_data_ptr++;
+ }
+ *Temp = (char)NULL;
+ param = String;
+ }
+ else
+ {
+ while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != ':'))
+ TERM_data_ptr++;
+ }
+ return(param);
+}
+
+int
+tc_Get_int(param) /* read the integer */
+int param;
+{
+ int Itemp;
+
+ if (param == 0)
+ {
+ while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != '#'))
+ TERM_data_ptr++;
+ TERM_data_ptr++;
+ Itemp = AtoI();
+ param = Itemp;
+ }
+ else
+ {
+ while (*TERM_data_ptr != ':')
+ TERM_data_ptr++;
+ }
+ return(param);
+}
+
+void
+Find_term() /* find terminal description in termcap file */
+{
+ char *Name;
+ char *Ftemp;
+
+ Ftemp = Name = malloc(strlen(TERMINAL_TYPE + 1) + 1);
+ strcpy(Name, TERMINAL_TYPE);
+ while (*Ftemp != (char)NULL)
+ Ftemp++;
+ *Ftemp++ = '|';
+ *Ftemp = (char)NULL;
+ CFOUND = FALSE;
+ Data_Line_len = strlen(TERMINAL_TYPE) + 1;
+ while ((!CFOUND) && ((TERM_data_ptr=fgets(Data_Line, 512, TFP)) != NULL))
+ {
+ if ((*TERM_data_ptr != ' ') && (*TERM_data_ptr != '\t') && (*TERM_data_ptr != '#'))
+ {
+ while ((!CFOUND) && (*TERM_data_ptr != (char)NULL))
+ {
+ CFOUND = !strncmp(TERM_data_ptr, Name, Data_Line_len);
+ while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != '|') && (*TERM_data_ptr != '#') && (*TERM_data_ptr != ':'))
+ TERM_data_ptr++;
+ if (*TERM_data_ptr == '|')
+ TERM_data_ptr++;
+ else if (!CFOUND)
+ *TERM_data_ptr = (char)NULL;
+ }
+ }
+ }
+ if (!CFOUND)
+ {
+ printf("terminal type %s not found\n", TERMINAL_TYPE);
+ exit(0);
+ }
+}
+
+void
+CAP_PARSE() /* parse off the data in the termcap data file */
+{
+ int offset;
+ int found;
+
+ do
+ {
+ while (*TERM_data_ptr != (char)NULL)
+ {
+ for (found = FALSE, offset = 0; (!found) && (offset < 26); offset++)
+ {
+ if (!strncmp(TERM_data_ptr, Boolean_names[offset], 2))
+ {
+ found = TRUE;
+ Booleans[offset] = TRUE;
+ }
+ }
+ if (!found)
+ {
+ for (found = FALSE, offset = 0; (!found) && (offset < lw__); offset++)
+ {
+ if (!strncmp(TERM_data_ptr, Number_names[offset], 3))
+ {
+ found = TRUE;
+ Numbers[offset] = tc_Get_int(Numbers[offset]);
+ }
+ }
+ }
+ if (!found)
+ {
+ for (found = FALSE, offset = 0; (!found) && (offset < smgr__); offset++)
+ {
+ if (!strncmp(TERM_data_ptr, String_names[offset], 3))
+ {
+ found = TRUE;
+ String_table[offset] = String_Get(String_table[offset]);
+ }
+ }
+ }
+
+ if (!strncmp(TERM_data_ptr, "tc=", 3))
+ tc_ = String_Get(NULL);
+ while ((*TERM_data_ptr != ':') && (*TERM_data_ptr != (char)NULL))
+ TERM_data_ptr++;
+ if (*TERM_data_ptr == ':')
+ TERM_data_ptr++;
+ }
+ } while (((TERM_data_ptr = fgets(Data_Line, 512, TFP)) != NULL) && ((*TERM_data_ptr == ' ') || (*TERM_data_ptr == '\t')));
+ if (tc_ != NULL)
+ {
+ TERMINAL_TYPE = tc_;
+ rewind(TFP);
+ Find_term();
+ tc_ = NULL;
+ CAP_PARSE();
+ }
+ else
+ fclose(TFP);
+}
+#endif /* ifdef CAP */
+
+struct _line *
+Screenalloc(columns)
+int columns;
+{
+ int i;
+ struct _line *tmp;
+
+ tmp = (struct _line *) malloc(sizeof (struct _line));
+ tmp->row = malloc(columns + 1);
+ tmp->attributes = malloc(columns + 1);
+ tmp->prev_screen = NULL;
+ tmp->next_screen = NULL;
+ for (i = 0; i < columns; i++)
+ {
+ tmp->row[i] = ' ';
+ tmp->attributes[i] = (char) NULL;
+ }
+ tmp->scroll = tmp->changed = FALSE;
+ tmp->row[0] = (char) NULL;
+ tmp->attributes[0] = (char) NULL;
+ tmp->row[columns] = (char) NULL;
+ tmp->attributes[columns] = (char) NULL;
+ tmp->last_char = 0;
+ return(tmp);
+}
+
+WINDOW *newwin(lines, cols, start_l, start_c)
+int lines, cols; /* number of lines and columns to be in window */
+int start_l, start_c; /* starting line and column to be inwindow */
+{
+ WINDOW *Ntemp;
+ struct _line *temp_screen;
+ int i;
+
+ Ntemp = (WINDOW *) malloc(sizeof(WINDOW));
+ Ntemp->SR = start_l;
+ Ntemp->SC = start_c;
+ Ntemp->Num_lines = lines;
+ Ntemp->Num_cols = cols;
+ Ntemp->LX = 0;
+ Ntemp->LY = 0;
+ Ntemp->scroll_down = Ntemp->scroll_up = 0;
+ Ntemp->SCROLL_CLEAR = FALSE;
+ Ntemp->Attrib = FALSE;
+ Ntemp->first_line = temp_screen = Screenalloc(cols);
+ Ntemp->first_line->number = 0;
+ Ntemp->line_array = (struct _line **) malloc(LINES * sizeof(struct _line *));
+
+ Ntemp->line_array[0] = Ntemp->first_line;
+
+ for (i = 1; i < lines; i++)
+ {
+ temp_screen->next_screen = Screenalloc(cols);
+ temp_screen->next_screen->number = i;
+ temp_screen->next_screen->prev_screen = temp_screen;
+ temp_screen = temp_screen->next_screen;
+ Ntemp->line_array[i] = temp_screen;
+ }
+ Ntemp->first_line->prev_screen = NULL;
+ temp_screen->next_screen = NULL;
+ return(Ntemp);
+}
+
+#ifdef CAP
+void
+Cap_Out(string, p_list, place) /* interpret the output string if necessary */
+char *string;
+int p_list[]; /* stack of values */
+int place; /* place keeper of top of stack */
+{
+ char *Otemp; /* temporary string pointer to parse output */
+ int delay;
+ int p1, p2, temp;
+ float chars;
+
+ if (string == NULL)
+ return;
+
+ if (p_list != NULL)
+ {
+ p1 = p_list[--place];
+ p2 = p_list[--place];
+ }
+ delay = 0;
+ Otemp = string;
+ if ((*Otemp >= '0') && (*Otemp <= '9'))
+ {
+ delay = atoi(Otemp);
+ while ((*Otemp >= '0') && (*Otemp <= '9'))
+ Otemp++;
+ if (*Otemp == '*')
+ Otemp++;
+ }
+ while (*Otemp != (char)NULL)
+ {
+ if (*Otemp == '%')
+ {
+ Otemp++;
+ if ((*Otemp == 'd') || (*Otemp == '2') || (*Otemp == '3') || (*Otemp == '.') || (*Otemp == '+'))
+ {
+ if (*Otemp == 'd')
+ printf("%d", p1);
+ else if (*Otemp == '2')
+ printf("%02d", p1);
+ else if (*Otemp == '3')
+ printf("%03d", p1);
+ else if (*Otemp == '+')
+ {
+ Otemp++;
+ p1 += *Otemp;
+ putchar(p1);
+ }
+ else if (*Otemp == '.')
+ putchar(p1);
+ p1 = p2;
+ p2 = 0;
+ }
+ else if (*Otemp == '>')
+ {
+ Otemp++;
+ if (p1 > *Otemp)
+ {
+ Otemp++;
+ p1 += *Otemp;
+ }
+ else
+ Otemp++;
+ }
+ else if (*Otemp == 'r')
+ {
+ temp = p1;
+ p1 = p2;
+ p2 = temp;
+ }
+ else if (*Otemp == 'i')
+ {
+ p1++;
+ p2++;
+ }
+ else if (*Otemp == '%')
+ putchar(*Otemp);
+ else if (*Otemp == 'n')
+ {
+ p1 ^= 0140;
+ p2 ^= 0140;
+ }
+ else if (*Otemp == 'B')
+ {
+ p1 = (16 * (p1/10)) + (p1 % 10);
+ p2 = (16 * (p2/10)) + (p2 % 10);
+ }
+ else if (*Otemp == 'D')
+ {
+ p1 = (p1 - 2 * (p1 % 16));
+ p2 = (p2 - 2 * (p2 % 16));
+ }
+ }
+ else
+ putchar (*Otemp);
+ Otemp++;
+ }
+ if (delay != 0)
+ {
+ chars = delay * chars_per_millisecond;
+ delay = chars;
+ if ((chars - delay) > 0.0)
+ delay++;
+ for (; delay > 0; delay--)
+ putchar(*String_table[pc__]);
+ }
+ fflush(stdout);
+}
+
+#else
+
+ char *Otemp; /* temporary string pointer to parse output */
+ float chars;
+ int p[10];
+ int variable[27];
+
+int
+Operation(Temp_Stack, place) /* handle conditional operations */
+int Temp_Stack[];
+int place;
+{
+ int temp;
+
+ if (*Otemp == 'd')
+ {
+ Otemp++;
+ temp = Temp_Stack[--place];
+ printf("%d", temp);
+ }
+ else if (!strncmp(Otemp, "2d", 2))
+ {
+ temp = Temp_Stack[--place];
+ printf("%2d", temp);
+ Otemp++;
+ Otemp++;
+ }
+ else if (!strncmp(Otemp, "3d", 2))
+ {
+ temp = Temp_Stack[--place];
+ printf("%0d", temp);
+ Otemp++;
+ Otemp++;
+ }
+ else if (!strncmp(Otemp, "02d", 3))
+ {
+ temp = Temp_Stack[--place];
+ printf("%02d", temp);
+ Otemp++;
+ Otemp++;
+ Otemp++;
+ }
+ else if (!strncmp(Otemp, "03d", 3))
+ {
+ temp = Temp_Stack[--place];
+ printf("%03d", temp);
+ Otemp++;
+ Otemp++;
+ Otemp++;
+ }
+ else if (*Otemp == '+')
+ {
+ Otemp++;
+ temp = Temp_Stack[--place];
+ temp += Temp_Stack[--place];
+ Temp_Stack[place++] = temp;
+ }
+ else if (*Otemp == '-')
+ {
+ Otemp++;
+ temp = Temp_Stack[--place];
+ temp -= Temp_Stack[--place];
+ Temp_Stack[place++] = temp;
+ }
+ else if (*Otemp == '*')
+ {
+ Otemp++;
+ temp = Temp_Stack[--place];
+ temp *= Temp_Stack[--place];
+ Temp_Stack[place++] = temp;
+ }
+ else if (*Otemp == '/')
+ {
+ Otemp++;
+ temp = Temp_Stack[--place];
+ temp /= Temp_Stack[--place];
+ Temp_Stack[place++] = temp;
+ }
+ else if (*Otemp == 'm')
+ {
+ Otemp++;
+ temp = Temp_Stack[--place];
+ temp %= Temp_Stack[--place];
+ Temp_Stack[place++] = temp;
+ }
+ else if (*Otemp == '&')
+ {
+ Otemp++;
+ temp = Temp_Stack[--place];
+ temp &= Temp_Stack[--place];
+ Temp_Stack[place++] = temp;
+ }
+ else if (*Otemp == '|')
+ {
+ Otemp++;
+ temp = Temp_Stack[--place];
+ temp |= Temp_Stack[--place];
+ Temp_Stack[place++] = temp;
+ }
+ else if (*Otemp == '^')
+ {
+ Otemp++;
+ temp = Temp_Stack[--place];
+ temp ^= Temp_Stack[--place];
+ Temp_Stack[place++] = temp;
+ }
+ else if (*Otemp == '=')
+ {
+ Otemp++;
+ temp = Temp_Stack[--place];
+ temp = (temp == Temp_Stack[--place]);
+ Temp_Stack[place++] = temp;
+ }
+ else if (*Otemp == '>')
+ {
+ Otemp++;
+ temp = Temp_Stack[--place];
+ temp = temp > Temp_Stack[--place];
+ Temp_Stack[place++] = temp;
+ }
+ else if (*Otemp == '<')
+ {
+ Otemp++;
+ temp = Temp_Stack[--place];
+ temp = temp < Temp_Stack[--place];
+ Temp_Stack[place++] = temp;
+ }
+ else if (*Otemp == 'c')
+ {
+ Otemp++;
+ putchar(Temp_Stack[--place]);
+ }
+ else if (*Otemp == 'i')
+ {
+ Otemp++;
+ p[1]++;
+ p[2]++;
+ }
+ else if (*Otemp == '%')
+ {
+ putchar(*Otemp);
+ Otemp++;
+ }
+ else if (*Otemp == '!')
+ {
+ temp = ! Temp_Stack[--place];
+ Temp_Stack[place++] = temp;
+ Otemp++;
+ }
+ else if (*Otemp == '~')
+ {
+ temp = ~Temp_Stack[--place];
+ Temp_Stack[place++] = temp;
+ Otemp++;
+ }
+ else if (*Otemp == 'p')
+ {
+ Otemp++;
+ Temp_Stack[place++] = p[*Otemp - '0'];
+ Otemp++;
+ }
+ else if (*Otemp == 'P')
+ {
+ Otemp++;
+ Temp_Stack[place++] = variable[*Otemp - 'a'];
+ Otemp++;
+ }
+ else if (*Otemp == 'g')
+ {
+ Otemp++;
+ variable[*Otemp - 'a'] = Temp_Stack[--place];
+ Otemp++;
+ }
+ else if (*Otemp == '\'')
+ {
+ Otemp++;
+ Temp_Stack[place++] = *Otemp;
+ Otemp++;
+ Otemp++;
+ }
+ else if (*Otemp == '{')
+ {
+ Otemp++;
+ temp = atoi(Otemp);
+ Temp_Stack[place++] = temp;
+ while (*Otemp != '}')
+ Otemp++;
+ Otemp++;
+ }
+ return(place);
+}
+
+void
+Info_Out(string, p_list, place) /* interpret the output string if necessary */
+char *string;
+int p_list[];
+int place;
+{
+ char *tchar;
+ int delay;
+ int temp;
+ int Cond_FLAG;
+ int EVAL;
+ int Cond_Stack[128];
+ int Cond_place;
+ int Stack[128];
+ int Top_of_stack;
+
+ if (string == NULL)
+ return;
+
+ Cond_FLAG = FALSE;
+ Cond_place = 0;
+ Top_of_stack = 0;
+ p[0] = 0;
+ p[1] = 0;
+ p[2] = 0;
+ p[3] = 0;
+ p[4] = 0;
+ p[5] = 0;
+ p[6] = 0;
+ p[7] = 0;
+ p[8] = 0;
+ p[9] = 0;
+ if (p_list != NULL)
+ {
+ for (temp = 1; (place != 0); temp++)
+ {
+ p[temp] = p_list[--place];
+ }
+ }
+ delay = 0;
+ Otemp = string;
+ while (*Otemp != (char) NULL)
+ {
+ if (*Otemp == '%')
+ {
+ Otemp++;
+ if ((*Otemp == '?') || (*Otemp == 't') || (*Otemp == 'e') || (*Otemp == ';'))
+ {
+ if (*Otemp == '?')
+ {
+ Otemp++;
+ Cond_FLAG = TRUE;
+ EVAL = TRUE;
+ while (EVAL)
+ {
+ /*
+ | find the end of the
+ | conditional statement
+ */
+ while ((strncmp(Otemp, "%t", 2)) && (*Otemp != (char) NULL))
+ {
+ /*
+ | move past '%'
+ */
+ Otemp++;
+ Cond_place = Operation(Cond_Stack, Cond_place);
+ }
+
+ /*
+ | if condition is true
+ */
+ if ((Cond_place > 0) && (Cond_Stack[Cond_place-1]))
+ {
+ /*
+ | end conditional
+ | parsing
+ */
+ EVAL = FALSE;
+ Otemp++;
+ Otemp++;
+ }
+ else /* condition is false */
+ {
+ /*
+ | find 'else' or end
+ | of if statement
+ */
+ while ((strncmp(Otemp, "%e", 2)) && (strncmp(Otemp, "%;", 2)) && (*Otemp != (char) NULL))
+ Otemp++;
+ /*
+ | if an 'else' found
+ */
+ if ((*Otemp != (char) NULL) && (!strncmp(Otemp, "%e", 2)))
+ {
+ Otemp++;
+ Otemp++;
+ tchar = Otemp;
+ /*
+ | check for 'then' part
+ */
+ while ((*tchar != (char) NULL) && (strncmp(tchar, "%t", 2)) && (strncmp(tchar, "%;", 2)))
+ tchar++;
+ /*
+ | if end of string
+ */
+ if (*tchar == (char) NULL)
+ {
+ EVAL = FALSE;
+ Cond_FLAG = FALSE;
+ Otemp = tchar;
+ }
+ /*
+ | if end of if found,
+ | set up to parse
+ | info
+ */
+ else if (!strncmp(tchar, "%;", 2))
+ EVAL = FALSE;
+ /*
+ | otherwise, check
+ | conditional in
+ | 'else'
+ */
+ }
+ /*
+ | if end of if found,
+ | get out of if
+ | statement
+ */
+ else if ((*Otemp != (char) NULL) && (!strncmp(Otemp, "%;", 2)))
+ {
+ EVAL = FALSE;
+ Otemp++;
+ Otemp++;
+ }
+ else /* Otemp == NULL */
+ {
+ EVAL = FALSE;
+ Cond_FLAG = FALSE;
+ }
+ }
+ }
+ }
+ else
+ {
+ Otemp++;
+ Cond_FLAG = FALSE;
+ if (*Otemp != ';')
+ {
+ while ((*Otemp != (char) NULL) && (strncmp(Otemp, "%;", 2)))
+ Otemp++;
+ if (*Otemp != (char) NULL)
+ {
+ Otemp++;
+ Otemp++;
+ }
+ }
+ else
+ Otemp++;
+ }
+ }
+ else
+ {
+ Top_of_stack = Operation(Stack, Top_of_stack);
+ }
+ }
+ else if (!strncmp(Otemp, "$<", 2))
+ {
+ Otemp++;
+ Otemp++;
+ delay = atoi(Otemp);
+ while (*Otemp != '>')
+ Otemp++;
+ Otemp++;
+ chars = delay * chars_per_millisecond;
+ delay = chars;
+ if ((chars - delay) > 0.0)
+ delay++;
+ if (String_table[pc__] == NULL)
+ temp = 0;
+ else
+ temp = *String_table[pc__];
+ for (; delay > 0; delay--)
+ putc(temp, stdout);
+ }
+ else
+ {
+ putchar(*Otemp);
+ Otemp++;
+ }
+ }
+ fflush(stdout);
+}
+#endif
+
+void
+wmove(window, row, column) /* move cursor to indicated position in window */
+WINDOW *window;
+int row, column;
+{
+ if ((row < window->Num_lines) && (column < window->Num_cols))
+ {
+ window->LX = column;
+ window->LY = row;
+ }
+}
+
+void
+clear_line(line, column, cols)
+struct _line *line;
+int column;
+int cols;
+{
+ int j;
+
+ if (column > line->last_char)
+ {
+ for (j = line->last_char; j < column; j++)
+ {
+ line->row[j] = ' ';
+ line->attributes[j] = (char) NULL;
+ }
+ }
+ line->last_char = column;
+ line->row[column] = (char) NULL;
+ line->attributes[column] = (char) NULL;
+ line->changed = TRUE;
+}
+
+void
+werase(window) /* clear the specified window */
+WINDOW *window;
+{
+ int i;
+ struct _line *tmp;
+
+ window->SCROLL_CLEAR = CLEAR;
+ window->scroll_up = window->scroll_down = 0;
+ for (i = 0, tmp = window->first_line; i < window->Num_lines; i++, tmp = tmp->next_screen)
+ clear_line(tmp, 0, window->Num_cols);
+}
+
+void
+wclrtoeol(window) /* erase from current cursor position to end of line */
+WINDOW *window;
+{
+ int column, row;
+ struct _line *tmp;
+
+ window->SCROLL_CLEAR = CHANGE;
+ column = window->LX;
+ row = window->LY;
+ for (row = 0, tmp = window->first_line; row < window->LY; row++)
+ tmp = tmp->next_screen;
+ clear_line(tmp, column, window->Num_cols);
+}
+
+void
+wrefresh(window) /* flush all previous output */
+WINDOW *window;
+{
+ wnoutrefresh(window);
+#ifdef DIAG
+{
+ struct _line *temp;
+ int value;
+ fprintf(stderr, "columns=%d, lines=%d, SC=%d, SR=%d\n",window->Num_cols, window->Num_lines, window->SC, window->SR);
+ for (value = 0, temp = window->first_line; value < window->Num_lines; value++, temp = temp->next_screen)
+ {
+ if (temp->number == -1)
+ fprintf(stderr, "line moved ");
+ if (temp->scroll)
+ fprintf(stderr, "scroll_x is set: ");
+ fprintf(stderr, "lc%d=%s|\n", temp->last_char, temp->row);
+ }
+ fprintf(stderr, "+-------------------- virtual screen ----------------------------------------+\n");
+ fprintf(stderr, "columns=%d, lines=%d \n",virtual_scr->Num_cols, virtual_scr->Num_lines);
+ for (value = 0, temp = virtual_scr->first_line; value < virtual_scr->Num_lines; value++, temp = temp->next_screen)
+ {
+ if (temp->number == -1)
+ fprintf(stderr, "line moved ");
+ if (temp->scroll)
+ fprintf(stderr, "scroll_x is set: ");
+ fprintf(stderr, "lc%d=%s|\n", temp->last_char, temp->row);
+ }
+ fprintf(stderr, "columns=%d, lines=%d \n",curscr->Num_cols, curscr->Num_lines);
+ for (value = 0, temp = curscr->first_line; value < curscr->Num_lines; value++, temp = temp->next_screen)
+ fprintf(stderr, "line=%s|\n", temp->row);
+}
+#endif
+ doupdate();
+ virtual_scr->SCROLL_CLEAR = FALSE;
+ virtual_scr->scroll_down = virtual_scr->scroll_up = 0;
+ fflush(stdout);
+}
+
+void
+touchwin(window)
+WINDOW *window;
+{
+ struct _line *user_line;
+ int line_counter = 0;
+
+ for (line_counter = 0, user_line = window->first_line;
+ line_counter < window->Num_lines; line_counter++)
+ {
+ user_line->changed = TRUE;
+ }
+ window->SCROLL_CLEAR = TRUE;
+}
+
+void
+wnoutrefresh(window)
+WINDOW *window;
+{
+ struct _line *user_line;
+ struct _line *virtual_line;
+ int line_counter = 0;
+ int user_col = 0;
+ int virt_col = 0;
+
+ if (window->SR >= virtual_scr->Num_lines)
+ return;
+ user_line = window->first_line;
+ virtual_line = virtual_scr->first_line;
+ virtual_scr->SCROLL_CLEAR = window->SCROLL_CLEAR;
+ virtual_scr->LX = window->LX + window->SC;
+ virtual_scr->LY = window->LY + window->SR;
+ virtual_scr->scroll_up = window->scroll_up;
+ virtual_scr->scroll_down = window->scroll_down;
+ if ((last_window_refreshed == window) && (!window->SCROLL_CLEAR))
+ return;
+ for (line_counter = 0; line_counter < window->SR; line_counter++)
+ {
+ virtual_line = virtual_line->next_screen;
+ }
+ for (line_counter = 0; (line_counter < window->Num_lines)
+ && ((line_counter + window->SR) < virtual_scr->Num_lines);
+ line_counter++)
+ {
+ if ((last_window_refreshed != window) || (user_line->changed) || ((SCROLL | CLEAR) & window->SCROLL_CLEAR))
+ {
+ for (user_col = 0, virt_col = window->SC;
+ (virt_col < virtual_scr->Num_cols)
+ && (user_col < user_line->last_char);
+ virt_col++, user_col++)
+ {
+ virtual_line->row[virt_col] = user_line->row[user_col];
+ virtual_line->attributes[virt_col] = user_line->attributes[user_col];
+ }
+ for (user_col = user_line->last_char,
+ virt_col = window->SC + user_line->last_char;
+ (virt_col < virtual_scr->Num_cols)
+ && (user_col < window->Num_cols);
+ virt_col++, user_col++)
+ {
+ virtual_line->row[virt_col] = ' ';
+ virtual_line->attributes[virt_col] = (char) NULL;
+ }
+ }
+ if (virtual_scr->Num_cols != window->Num_cols)
+ {
+ if (virtual_line->last_char < (user_line->last_char + window->SC))
+ {
+ if (virtual_line->row[virtual_line->last_char] == (char) NULL)
+ virtual_line->row[virtual_line->last_char] = ' ';
+ virtual_line->last_char =
+ min(virtual_scr->Num_cols,
+ (user_line->last_char + window->SC));
+ }
+ }
+ else
+ virtual_line->last_char = user_line->last_char;
+ virtual_line->row[virtual_line->last_char] = (char) NULL;
+ virtual_line->changed = user_line->changed;
+ virtual_line = virtual_line->next_screen;
+ user_line = user_line->next_screen;
+ }
+ window->SCROLL_CLEAR = FALSE;
+ window->scroll_up = window->scroll_down = 0;
+ last_window_refreshed = window;
+}
+
+void
+flushinp() /* flush input */
+{
+}
+
+void
+ungetch(c) /* push a character back on input */
+int c;
+{
+ if (bufp < 100)
+ in_buff[bufp++] = c;
+}
+
+#ifdef BSD_SELECT
+int
+timed_getchar()
+{
+ struct timeval tv;
+ fd_set fds;
+ int ret_val;
+ int nfds = 1;
+ char temp;
+
+ FD_ZERO(&fds);
+ tv.tv_sec = 0;
+ tv.tv_usec = 500000; /* half a second */
+ FD_SET(0, &fds);
+ Time_Out = FALSE; /* just in case */
+
+ ret_val = select(nfds, &fds, 0, 0, &tv);
+
+ /*
+ | if ret_val is less than zero, there was no input
+ | otherwise, get a character and return it
+ */
+
+ if (ret_val <= 0)
+ {
+ Time_Out = TRUE;
+ return(-1);
+ }
+
+ return(read(0, &temp, 1)? temp : -1);
+}
+#endif
+
+int
+wgetch(window) /* get character from specified window */
+WINDOW *window;
+{
+ int in_value;
+ char temp;
+#ifndef SYS5
+ int old_arg;
+#endif /* SYS5 */
+
+#ifdef BSD_SELECT
+ if (Noblock)
+ in_value = ((bufp > 0) ? in_buff[--bufp] : timed_getchar());
+ else
+ in_value = ((bufp > 0) ? in_buff[--bufp] : read(0, &temp, 1)? temp : -1);
+#else /* BSD_SELECT */
+#ifdef SYS5
+ in_value = ((bufp > 0) ? in_buff[--bufp] :
+ (read(0, &temp, 1)> 0) ? temp : -1);
+#else /* SYS5 */
+ if (Noblock)
+ {
+ Time_Out = FALSE;
+ old_arg = fcntl(0, F_GETFL, 0);
+ in_value = fcntl(0, F_SETFL, old_arg | FNDELAY);
+ }
+ in_value = ((bufp > 0) ? in_buff[--bufp] : read(0, &temp, 1)? temp : -1);
+ if (Noblock)
+ {
+ fcntl(0, F_SETFL, old_arg);
+ if (Time_Out)
+ in_value = -1;
+ }
+#endif /* SYS5 */
+#endif /* BSD_SELECT */
+
+ if (in_value != -1)
+ {
+ in_value &= 0xff;
+ if ((Parity) && (Num_bits < 8))
+ /* strip eighth bit if parity in use */
+ in_value &= 0177;
+ }
+ else if (interrupt_flag)
+ {
+ interrupt_flag = FALSE;
+ in_value = wgetch(window);
+ }
+
+ if ((in_value == '\033') || (in_value == '\037'))/* escape character */
+ in_value = Get_key(in_value);
+ return(in_value);
+}
+
+#ifndef BSD_SELECT
+void
+Clear(arg) /* notify that time out has occurred */
+int arg;
+{
+ Time_Out = TRUE;
+#ifdef DEBUG
+fprintf(stderr, "inside Clear()\n");
+fflush(stderr);
+#endif /* DEBUG */
+}
+#endif /* BSD_SELECT */
+
+int
+Get_key(first_char) /* try to decode key sequence */
+int first_char; /* first character of sequence */
+{
+ int in_char;
+ int Count;
+ char string[128];
+ char *Gtemp;
+ int Found;
+#ifdef SYS5
+ struct termio Gterminal;
+#else
+ struct sgttyb Gterminal;
+#endif
+ struct KEY_STACK *St_point;
+#if (!defined( BSD_SELECT)) || (!defined(SYS5))
+ int value;
+#endif /* BSD_SELECT */
+
+ Count = 0;
+ Gtemp = string;
+ string[Count++] = first_char;
+ string[Count] = (char) NULL;
+ Time_Out = FALSE;
+#ifndef BSD_SELECT
+ signal(SIGALRM, Clear);
+ value = alarm(1);
+#endif /* BSD_SELECT */
+ Noblock = TRUE;
+#ifdef SYS5
+ Gterminal.c_cc[VTIME] = 0; /* timeout value */
+ Gterminal.c_lflag &= ~ICANON; /* disable canonical operation */
+ Gterminal.c_lflag &= ~ECHO; /* disable echo */
+#endif
+ Count = 1;
+ Found = FALSE;
+ while ((Count < Max_Key_len) && (!Time_Out) && (!Found))
+ {
+ in_char = wgetch(stdscr);
+#ifdef DEBUG
+fprintf(stderr, "back in GetKey()\n");
+fflush(stderr);
+#endif /* DEBUG */
+ if (in_char != -1)
+ {
+ string[Count++] = in_char;
+ string[Count] = (char) NULL;
+ St_point = KEY_TOS;
+ while ((St_point != NULL) && (!Found))
+ {
+ if (!strcmp(string, St_point->element->string))
+ Found = TRUE;
+ else
+ St_point = St_point->next;
+ }
+ }
+ }
+#ifndef BSD_SELECT
+ if (!Time_Out)
+ value = alarm(0);
+#endif /* BSD_SELECT */
+#ifdef SYS5
+/* value = ioctl(0, TCSETA, &Terminal);*/
+#else
+ value = ioctl(0, TIOCSETP, &Terminal);
+/* value = fcntl(0, F_SETFL, old_arg);*/
+#endif
+ Noblock = FALSE;
+ if (Found)
+ {
+ return(St_point->element->value);
+ }
+ else
+ {
+ while (Count > 1)
+ {
+ if ((string[--Count] != -1) &&
+ ((unsigned char) (string[Count]) != 255))
+ {
+#ifdef DIAG
+fprintf(stderr, "ungetting character %d\n", string[Count]);fflush(stdout);
+#endif
+ ungetch(string[Count]);
+ }
+ }
+ return(first_char);
+ }
+}
+
+void
+waddch(window, c) /* output the character in the specified window */
+WINDOW *window;
+int c;
+{
+ int column, j;
+ int shift; /* number of spaces to shift if a tab */
+ struct _line *tmpline;
+
+#ifdef DIAG
+/*printf("starting waddch \n");fflush(stdout);*/
+#endif
+ column = window->LX;
+ if (c == '\t')
+ {
+ shift = (column + 1) % 8;
+ if (shift == 0)
+ shift++;
+ else
+ shift = 9 - shift;
+ while (shift > 0)
+ {
+ shift--;
+ waddch(window, ' ');
+ }
+ }
+ else if ((column < window->Num_cols) && (window->LY < window->Num_lines))
+ {
+ if ((c == '~') && (Booleans[hz__]))
+ c = '@';
+
+ if (( c != '\b') && (c != '\n') && (c != '\r'))
+ {
+ tmpline = window->line_array[window->LY];
+ tmpline->row[column] = c;
+ tmpline->attributes[column] = window->Attrib;
+ tmpline->changed = TRUE;
+ if (column >= tmpline->last_char)
+ {
+ if (column > tmpline->last_char)
+ for (j = tmpline->last_char; j < column; j++)
+ {
+ tmpline->row[j] = ' ';
+ tmpline->attributes[j] = (char) NULL;
+ }
+ tmpline->row[column + 1] = (char) NULL;
+ tmpline->attributes[column + 1] = (char) NULL;
+ tmpline->last_char = column + 1;
+ }
+ }
+ if (c == '\n')
+ {
+ wclrtoeol(window);
+ window->LX = window->Num_cols;
+ }
+ else if (c == '\r')
+ window->LX = 0;
+ else if (c == '\b')
+ window->LX--;
+ else
+ window->LX++;
+ }
+ if (window->LX >= window->Num_cols)
+ {
+ window->LX = 0;
+ window->LY++;
+ if (window->LY >= window->Num_lines)
+ {
+ window->LY = window->Num_lines - 1;
+/* window->LY = row;
+ wmove(window, 0, 0);
+ wdeleteln(window);
+ wmove(window, row, 0);*/
+ }
+ }
+ window->SCROLL_CLEAR = CHANGE;
+}
+
+void
+winsertln(window) /* insert a blank line into the specified window */
+WINDOW *window;
+{
+ int row, column;
+ struct _line *tmp;
+ struct _line *tmp1;
+
+ window->scroll_down += 1;
+ window->SCROLL_CLEAR = SCROLL;
+ column = window->LX;
+ row = window->LY;
+ for (row = 0, tmp = window->first_line; (row < window->Num_lines) && (tmp->next_screen != NULL); row++)
+ tmp = tmp->next_screen;
+ if (tmp->prev_screen != NULL)
+ tmp->prev_screen->next_screen = NULL;
+ tmp1 = tmp;
+ clear_line(tmp1, 0, window->Num_cols);
+ tmp1->number = -1;
+ for (row = 0, tmp = window->first_line; (row < window->LY) && (tmp->next_screen != NULL); row++)
+ tmp = tmp->next_screen;
+ if ((window->LY == (window->Num_lines - 1)) && (window->Num_lines > 1))
+ {
+ tmp1->next_screen = tmp->next_screen;
+ tmp->next_screen = tmp1;
+ tmp->changed = TRUE;
+ tmp->next_screen->prev_screen = tmp;
+ }
+ else if (window->Num_lines > 1)
+ {
+ if (tmp->prev_screen != NULL)
+ tmp->prev_screen->next_screen = tmp1;
+ tmp1->prev_screen = tmp->prev_screen;
+ tmp->prev_screen = tmp1;
+ tmp1->next_screen = tmp;
+ tmp->changed = TRUE;
+ tmp->scroll = DOWN;
+ }
+ if (window->LY == 0)
+ window->first_line = tmp1;
+
+ for (row = 0, tmp1 = window->first_line;
+ row < window->Num_lines; row++)
+ {
+ window->line_array[row] = tmp1;
+ tmp1 = tmp1->next_screen;
+ }
+}
+
+void
+wdeleteln(window) /* delete a line in the specified window */
+WINDOW *window;
+{
+ int row, column;
+ struct _line *tmp;
+ struct _line *tmpline;
+
+ if (window->Num_lines > 1)
+ {
+ window->scroll_up += 1;
+ window->SCROLL_CLEAR = SCROLL;
+ column = window->LX;
+ row = window->LY;
+ for (row = 0, tmp = window->first_line; row < window->LY; row++)
+ tmp = tmp->next_screen;
+ if (window->LY == 0)
+ window->first_line = tmp->next_screen;
+ if (tmp->prev_screen != NULL)
+ tmp->prev_screen->next_screen = tmp->next_screen;
+ if (tmp->next_screen != NULL)
+ {
+ tmp->next_screen->changed = TRUE;
+ tmp->next_screen->scroll = UP;
+ tmp->next_screen->prev_screen = tmp->prev_screen;
+ }
+ tmpline = tmp;
+ clear_line(tmpline, 0, window->Num_cols);
+ tmpline->number = -1;
+ for (row = 0, tmp = window->first_line; tmp->next_screen != NULL; row++)
+ tmp = tmp->next_screen;
+ if (tmp != NULL)
+ {
+ tmp->next_screen = tmpline;
+ tmp->next_screen->prev_screen = tmp;
+ tmp->changed = TRUE;
+ tmp = tmp->next_screen;
+ }
+ else
+ tmp = tmpline;
+ tmp->next_screen = NULL;
+
+ for (row = 0, tmp = window->first_line; row < window->Num_lines; row++)
+ {
+ window->line_array[row] = tmp;
+ tmp = tmp->next_screen;
+ }
+ }
+ else
+ {
+ clear_line(window->first_line, 0, window->Num_cols);
+ }
+}
+
+void
+wclrtobot(window) /* delete from current position to end of the window */
+WINDOW *window;
+{
+ int row, column;
+ struct _line *tmp;
+
+ window->SCROLL_CLEAR |= CLEAR;
+ column = window->LX;
+ row = window->LY;
+ for (row = 0, tmp = window->first_line; row < window->LY; row++)
+ tmp = tmp->next_screen;
+ clear_line(tmp, column, window->Num_cols);
+ for (row = (window->LY + 1); row < window->Num_lines; row++)
+ {
+ tmp = tmp->next_screen;
+ clear_line(tmp, 0, window->Num_cols);
+ }
+ wmove(window, row, column);
+}
+
+void
+wstandout(window) /* begin standout mode in window */
+WINDOW *window;
+{
+ if (Numbers[sg__] < 1) /* if not magic cookie glitch */
+ window->Attrib |= A_STANDOUT;
+}
+
+void
+wstandend(window) /* end standout mode in window */
+WINDOW *window;
+{
+ window->Attrib &= ~A_STANDOUT;
+}
+
+void
+waddstr(window, string) /* write 'string' in window */
+WINDOW *window;
+char *string;
+{
+ char *wstring;
+
+ for (wstring = string; *wstring != (char) NULL; wstring++)
+ waddch(window, *wstring);
+}
+
+void
+clearok(window, flag) /* erase screen and redraw at next refresh */
+WINDOW *window;
+int flag;
+{
+ Repaint_screen = TRUE;
+}
+
+
+void
+echo() /* turn on echoing */
+{
+ int value;
+
+#ifdef SYS5
+ Terminal.c_lflag |= ECHO; /* enable echo */
+ value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
+#else
+ Terminal.sg_flags |= ECHO; /* enable echo */
+ value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
+#endif
+}
+
+void
+noecho() /* turn off echoing */
+{
+ int value;
+
+#ifdef SYS5
+ Terminal.c_lflag &= ~ECHO; /* disable echo */
+ value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
+#else
+ Terminal.sg_flags &= ~ECHO; /* disable echo */
+ value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
+#endif
+}
+
+void
+raw() /* set to read characters immediately */
+{
+ int value;
+
+#ifdef SYS5
+ Intr = Terminal.c_cc[VINTR]; /* get the interrupt character */
+ Terminal.c_lflag &= ~ICANON; /* disable canonical operation */
+ Terminal.c_lflag &= ~ISIG; /* disable signal checking */
+#ifdef FLUSHO
+ Terminal.c_lflag &= ~FLUSHO;
+#endif
+#ifdef PENDIN
+ Terminal.c_lflag &= ~PENDIN;
+#endif
+#ifdef IEXTEN
+ Terminal.c_lflag &= ~IEXTEN;
+#endif
+ Terminal.c_cc[VMIN] = 1; /* minimum of one character */
+ Terminal.c_cc[VTIME] = 0; /* timeout value */
+ Terminal.c_cc[VINTR] = 0; /* eliminate interrupt */
+ value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
+#else
+ Terminal.sg_flags |= RAW; /* enable raw mode */
+ value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
+#endif
+}
+
+void
+noraw() /* set to normal character read mode */
+{
+ int value;
+
+#ifdef SYS5
+ Terminal.c_lflag |= ICANON; /* enable canonical operation */
+ Terminal.c_lflag |= ISIG; /* enable signal checking */
+ Terminal.c_cc[VEOF] = 4; /* EOF character = 4 */
+ Terminal.c_cc[VEOL] = (char) NULL; /* EOL = 0 */
+ Terminal.c_cc[VINTR] = Intr; /* reset interrupt char */
+ value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
+#else
+ Terminal.sg_flags &= ~RAW; /* disable raw mode */
+ value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */
+/* old_arg = fcntl(0, F_GETFL, 0);
+ value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/
+#endif
+}
+
+void
+nl()
+{
+ int value;
+
+#ifdef SYS5
+ Terminal.c_iflag |= ICRNL; /* enable carriage-return to line-feed mapping */
+ value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
+#endif
+}
+
+void
+nonl()
+{
+ int value;
+
+#ifdef SYS5
+ Terminal.c_iflag &= ~ICRNL; /* disable carriage-return to line-feed mapping */
+ Terminal.c_iflag &= ~IGNCR; /* do not ignore carriage-return */
+ value = ioctl(0, TCSETA, &Terminal); /* set characteristics */
+#endif
+}
+
+void
+saveterm()
+{
+}
+
+void
+fixterm()
+{
+}
+
+void
+resetterm()
+{
+}
+
+void
+nodelay(window, flag)
+WINDOW *window;
+int flag;
+{
+}
+
+void
+idlok(window, flag)
+WINDOW *window;
+int flag;
+{
+}
+
+void
+keypad(window, flag)
+WINDOW *window;
+int flag;
+{
+ if (flag)
+ String_Out(String_table[ks__], NULL, 0);
+ else
+ String_Out(String_table[ke__], NULL, 0);
+}
+
+void
+savetty() /* save current tty stats */
+{
+ int value;
+
+#ifdef SYS5
+ value = ioctl(0, TCGETA, &Saved_tty); /* set characteristics */
+#else
+ value = ioctl(0, TIOCGETP, &Saved_tty); /* set characteristics */
+#endif
+}
+
+void
+resetty() /* restore previous tty stats */
+{
+ int value;
+
+#ifdef SYS5
+ value = ioctl(0, TCSETA, &Saved_tty); /* set characteristics */
+#else
+ value = ioctl(0, TIOCSETP, &Saved_tty); /* set characteristics */
+#endif
+}
+
+void
+endwin() /* end windows */
+{
+ keypad(stdscr, FALSE);
+ initialized = FALSE;
+ delwin(curscr);
+ delwin(virtual_scr);
+ delwin(stdscr);
+#ifndef SYS5
+{
+ int old_arg, value;
+/* old_arg = fcntl(0, F_GETFL, 0);
+ value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/
+}
+#endif
+}
+
+void
+delwin(window) /* delete the window structure */
+WINDOW *window;
+{
+ int i;
+
+ for (i = 1; (i < window->Num_lines) && (window->first_line->next_screen != NULL); i++)
+ {
+ window->first_line = window->first_line->next_screen;
+ free(window->first_line->prev_screen->row);
+ free(window->first_line->prev_screen->attributes);
+ free(window->first_line->prev_screen);
+ }
+ if (window == last_window_refreshed)
+ last_window_refreshed = 0;
+ if (window->first_line != NULL)
+ {
+ free(window->first_line->row);
+ free(window->first_line->attributes);
+ free(window->first_line);
+ free(window);
+ }
+}
+
+#ifndef __STDC__
+void
+wprintw(va_alist)
+va_dcl
+#else /* __STDC__ */
+void
+wprintw(WINDOW *window, const char *format, ...)
+#endif /* __STDC__ */
+{
+#ifndef __STDC__
+ WINDOW *window;
+ char *format;
+ va_list ap;
+#else
+ va_list ap;
+#endif
+ int value;
+ char *fpoint;
+ char *wtemp;
+
+#ifndef __STDC__
+ va_start(ap);
+ window = va_arg(ap, WINDOW *);
+ format = va_arg(ap, char *);
+#else /* __STDC__ */
+ va_start(ap, format);
+#endif /* __STDC__ */
+
+ fpoint = (char *) format;
+ while (*fpoint != (char) NULL)
+ {
+ if (*fpoint == '%')
+ {
+ fpoint++;
+ if (*fpoint == 'd')
+ {
+ value = va_arg(ap, int);
+ iout(window, value);
+ }
+ else if (*fpoint == 'c')
+ {
+ value = va_arg(ap, int);
+ waddch(window, value);
+ }
+ else if (*fpoint == 's')
+ {
+ wtemp = va_arg(ap, char *);
+ waddstr(window, wtemp);
+ }
+ fpoint++;
+ }
+ else if (*fpoint == '\\')
+ {
+ fpoint++;
+ if (*fpoint == 'n')
+ waddch(window, '\n');
+ else if ((*fpoint >= '0') && (*fpoint <= '9'))
+ {
+ value = 0;
+ while ((*fpoint >= '0') && (*fpoint <= '9'))
+ {
+ value = (value * 8) + (*fpoint - '0');
+ fpoint++;
+ }
+ waddch(window, value);
+ }
+ fpoint++;
+ }
+ else
+ waddch(window, *fpoint++);
+ }
+#ifdef __STDC__
+ va_end(ap);
+#endif /* __STDC__ */
+}
+
+void
+iout(window, value) /* output characters */
+WINDOW *window;
+int value;
+{
+ int i;
+
+ if ((i = value / 10) != 0)
+ iout(window, i);
+ waddch(window, ((value % 10) + '0'));
+}
+
+int
+Comp_line(line1, line2) /* compare lines */
+struct _line *line1;
+struct _line *line2;
+{
+ int count1;
+ int i;
+ char *att1, *att2;
+ char *c1, *c2;
+
+ if (line1->last_char != line2->last_char)
+ return(2);
+
+ c1 = line1->row;
+ c2 = line2->row;
+ att1 = line1->attributes;
+ att2 = line2->attributes;
+ i = 0;
+ while ((c1[i] != (char) NULL) && (c2[i] != (char) NULL) && (c1[i] == c2[i]) && (att1[i] == att2[i]))
+ i++;
+ count1 = i + 1;
+ if ((count1 == 1) && (c1[i] == (char) NULL) && (c2[i] == (char) NULL))
+ count1 = 0; /* both lines blank */
+ else if ((c1[i] == (char) NULL) && (c2[i] == (char) NULL))
+ count1 = -1; /* equal */
+ else
+ count1 = 1; /* lines unequal */
+ return(count1);
+}
+
+struct _line *
+Insert_line(row, end_row, window) /* insert line into screen */
+int row;
+int end_row;
+WINDOW *window;
+{
+ int i;
+ struct _line *tmp;
+ struct _line *tmp1;
+
+ for (i = 0, tmp = curscr->first_line; i < window->SR; i++)
+ tmp = tmp->next_screen;
+ if ((end_row + window->SR) == 0)
+ curscr->first_line = curscr->first_line->next_screen;
+ top_of_win = tmp;
+ /*
+ | find bottom line to delete
+ */
+ for (i = 0, tmp = top_of_win; (tmp->next_screen != NULL) && (i < end_row); i++)
+ tmp = tmp->next_screen;
+ if (tmp->prev_screen != NULL)
+ tmp->prev_screen->next_screen = tmp->next_screen;
+ if (tmp->next_screen != NULL)
+ tmp->next_screen->prev_screen = tmp->prev_screen;
+ tmp1 = tmp;
+ /*
+ | clear deleted line
+ */
+ clear_line(tmp, 0, window->Num_cols);
+ tmp1->number = -1;
+ for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++)
+ tmp = tmp->next_screen;
+ top_of_win = tmp;
+ for (i = 0, tmp = top_of_win; i < row; i++)
+ tmp = tmp->next_screen;
+ if ((tmp->prev_screen != NULL) && (window->Num_lines > 0))
+ tmp->prev_screen->next_screen = tmp1;
+ tmp1->prev_screen = tmp->prev_screen;
+ tmp->prev_screen = tmp1;
+ tmp1->next_screen = tmp;
+ if ((row + window->SR) == 0)
+ curscr->first_line = tmp1;
+ if (tmp1->next_screen != NULL)
+ tmp1 = tmp1->next_screen;
+
+ if ((!String_table[cs__]) && (end_row < window->Num_lines))
+ {
+ Position(window, (window->SR + end_row), 0);
+ String_Out(String_table[dl__], NULL, 0);
+ }
+ Position(window, (window->SR + row), 0);
+ if (String_table[al__] != NULL)
+ String_Out(String_table[al__], NULL, 0);
+ else
+ String_Out(String_table[sr__], NULL, 0);
+
+ for (i = 0, top_of_win = curscr->first_line; (top_of_win->next_screen != NULL) && (i < window->SR); i++)
+ top_of_win = top_of_win->next_screen;
+ return(tmp1);
+}
+
+
+struct _line *
+Delete_line(row, end_row, window) /* delete a line on screen */
+int row;
+int end_row;
+WINDOW *window;
+{
+ int i;
+ struct _line *tmp;
+ struct _line *tmp1;
+ struct _line *tmp2;
+
+ i = 0;
+ tmp = curscr->first_line;
+ while (i < window->SR)
+ {
+ i++;
+ tmp = tmp->next_screen;
+ }
+ /*
+ | find line to delete
+ */
+ top_of_win = tmp;
+ if ((row + window->SR) == 0)
+ curscr->first_line = top_of_win->next_screen;
+ for (i = 0, tmp = top_of_win; i < row; i++)
+ tmp = tmp->next_screen;
+ if (tmp->prev_screen != NULL)
+ tmp->prev_screen->next_screen = tmp->next_screen;
+ if (tmp->next_screen != NULL)
+ tmp->next_screen->prev_screen = tmp->prev_screen;
+ tmp2 = tmp->next_screen;
+ tmp1 = tmp;
+ /*
+ | clear deleted line
+ */
+ clear_line(tmp1, 0, window->Num_cols);
+ tmp1->number = -1;
+ /*
+ | find location to insert deleted line
+ */
+ for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++)
+ tmp = tmp->next_screen;
+ top_of_win = tmp;
+ for (i = 0, tmp = top_of_win; (i < end_row) && (tmp->next_screen != NULL); i++)
+ tmp = tmp->next_screen;
+ tmp1->next_screen = tmp;
+ tmp1->prev_screen = tmp->prev_screen;
+ if (tmp1->prev_screen != NULL)
+ tmp1->prev_screen->next_screen = tmp1;
+ tmp->prev_screen = tmp1;
+
+ Position(window, (window->SR + row), 0);
+ String_Out(String_table[dl__], NULL, 0);
+ if ((!String_table[cs__]) && (end_row < window->Num_lines))
+ {
+ Position(window, (window->SR + end_row), 0);
+ String_Out(String_table[al__], NULL, 0);
+ }
+ else if ((String_table[cs__] != NULL) && (String_table[dl__] == NULL))
+ {
+ Position(window, (window->SR + end_row), 0);
+ putchar('\n');
+ }
+
+ if (row == (window->Num_lines-1))
+ tmp2 = tmp1;
+ if ((row + window->SR) == 0)
+ curscr->first_line = top_of_win = tmp2;
+ return(tmp2);
+}
+
+void
+CLEAR_TO_EOL(window, row, column)
+WINDOW *window;
+int row, column;
+{
+ int x, y;
+ struct _line *tmp1;
+
+ for (y = 0, tmp1 = curscr->first_line; (y < (window->SR+row)) && (tmp1->next_screen != NULL); y++)
+ tmp1 = tmp1->next_screen;
+ for (x = column; x<window->Num_cols; x++)
+ {
+ tmp1->row[x] = ' ';
+ tmp1->attributes[x] = (char) NULL;
+ }
+ tmp1->row[column] = (char) NULL;
+ tmp1->last_char = column;
+ if (column < COLS)
+ {
+ if (STAND)
+ {
+ STAND = FALSE;
+ Position(window, row, column);
+ attribute_off();
+ }
+ if (String_table[ce__] != NULL)
+ String_Out(String_table[ce__], NULL, 0);
+ else
+ {
+ for (x = column; x < window->Num_cols; x++)
+ putchar(' ');
+ Curr_x = x;
+ }
+ }
+}
+
+int
+check_delete(window, line, offset, pointer_new, pointer_old)
+WINDOW *window;
+int line, offset;
+struct _line *pointer_new, *pointer_old;
+{
+ int end_old;
+ int end_new;
+ int k;
+ int changed;
+ char *old_lin;
+ char *new_lin;
+ char *old_att;
+ char *new_att;
+
+ changed = FALSE;
+ new_lin = pointer_new->row;
+ new_att = pointer_new->attributes;
+ old_lin = pointer_old->row;
+ old_att = pointer_old->attributes;
+ end_old = end_new = offset;
+ while (((new_lin[end_new] != old_lin[end_old]) || (new_att[end_new] != old_att[end_old])) && (old_lin[end_old] != (char) NULL) && (new_lin[end_old] != (char) NULL))
+ end_old++;
+ if (old_lin[end_old] != (char) NULL)
+ {
+ k = 0;
+ while ((old_lin[end_old+k] == new_lin[end_new+k]) && (new_att[end_new+k] == old_att[end_old+k]) && (new_lin[end_new+k] != (char) NULL) && (old_lin[end_old+k] != (char) NULL) && (k < 10))
+ k++;
+ if ((k > 8) || ((new_lin[end_new+k] == (char) NULL) && (k != 0)))
+ {
+ if (new_lin[end_new+k] == (char) NULL)
+ {
+ Position(window, line, (end_new+k));
+ CLEAR_TO_EOL(window, line, (end_new+k));
+ }
+ Position(window, line, offset);
+ for (k = offset; k < end_old; k++)
+ Char_del(old_lin, old_att, offset, window->Num_cols);
+ while ((old_lin[offset] != (char) NULL) && (offset < COLS))
+ offset++;
+ pointer_old->last_char = offset;
+ changed = TRUE;
+ }
+ }
+ return(changed);
+}
+
+/*
+ | Check if characters were inserted in the middle of a line, and if
+ | so, insert them.
+ */
+
+int
+check_insert(window, line, offset, pointer_new, pointer_old)
+WINDOW *window;
+int line, offset;
+struct _line *pointer_new, *pointer_old;
+{
+ int changed;
+ int end_old, end_new;
+ int k;
+ int same = FALSE;
+ int old_off;
+ int insert;
+ char *old_lin;
+ char *new_lin;
+ char *old_att;
+ char *new_att;
+
+ changed = FALSE;
+ new_lin = pointer_new->row;
+ new_att = pointer_new->attributes;
+ old_lin = pointer_old->row;
+ old_att = pointer_old->attributes;
+ end_old = end_new = offset;
+ while (((new_lin[end_new] != old_lin[end_old]) || (new_att[end_new] != old_att[end_old])) && (new_lin[end_new] != (char) NULL) && (old_lin[end_new] != (char) NULL))
+ end_new++;
+ if (new_lin[end_new] != (char) NULL)
+ {
+ k = 0;
+ while ((old_lin[end_old+k] == new_lin[end_new+k]) && (old_att[end_old+k] == new_att[end_new+k]) && (new_lin[end_new+k] != (char) NULL) && (old_lin[end_old+k] != (char) NULL) && (k < 10))
+ k++;
+ /*
+ | check for commonality between rest of lines (are the old
+ | and new lines the same, except for a chunk in the middle?)
+ | if the rest of the lines are common, do not insert text
+ */
+ old_off = end_new;
+ while ((old_lin[old_off] != (char) NULL) && (new_lin[old_off] != (char) NULL) && (old_lin[old_off] == new_lin[old_off]) && (old_att[old_off] == new_att[old_off]))
+ old_off++;
+ if ((old_lin[old_off] == new_lin[old_off]) && (old_att[old_off] == new_att[old_off]))
+ same = TRUE;
+ if ((!same) && ((k > 8) || ((new_lin[end_new+k] == (char) NULL) && (k != 0))))
+ {
+ Position(window, line, offset);
+ insert = FALSE;
+ if (String_table[ic__] == NULL)
+ {
+ String_Out(String_table[im__], NULL, 0);
+ insert = TRUE;
+ }
+ for (k = offset; k < end_new; k++)
+ {
+ if (!insert)
+ String_Out(String_table[ic__], NULL, 0);
+ Char_ins(old_lin, old_att, new_lin[k], new_att[k], k, window->Num_cols);
+ }
+ if (insert)
+ String_Out(String_table[ei__], NULL, 0);
+ while ((old_lin[offset] != (char) NULL) && (offset < COLS))
+ offset++;
+ pointer_old->last_char = offset;
+ changed = TRUE;
+ }
+ }
+ return(changed);
+}
+
+void
+doupdate()
+{
+ WINDOW *window;
+ int similar;
+ int diff;
+ int begin_old, begin_new;
+ int end_old, end_new;
+ int count1, j;
+ int from_top, tmp_ft, offset;
+ int changed;
+ int first_time;
+ int first_same;
+ int last_same;
+ int list[10];
+ int bottom;
+
+ struct _line *curr;
+ struct _line *virt;
+ struct _line *old;
+
+ struct _line *new;
+
+ struct _line *old1, *new1;
+
+ char *cur_lin;
+ char *vrt_lin;
+ char *cur_att;
+ char *vrt_att;
+ char *att1, *att2;
+ char *c1, *c2;
+
+ char NC_chinese = FALSE; /* flag to indicate handling Chinese */
+
+ window = virtual_scr;
+
+ if ((nc_attributes & A_NC_BIG5) != 0)
+ NC_chinese = TRUE;
+
+ if (Repaint_screen)
+ {
+ if (String_table[cl__])
+ String_Out(String_table[cl__], NULL, 0);
+ else
+ {
+ from_top = 0;
+ while (from_top < LINES)
+ {
+ Position(curscr, from_top, 0);
+ if (String_table[ce__] != NULL)
+ String_Out(String_table[ce__], NULL, 0);
+ else
+ {
+ for (j = 0; j < window->Num_cols; j++)
+ putchar(' ');
+ }
+ from_top++;
+ }
+ }
+ for (from_top = 0, curr = curscr->first_line; from_top < curscr->Num_lines; from_top++, curr = curr->next_screen)
+ {
+ Position(curscr, from_top, 0);
+ for (j = 0; (curr->row[j] != (char) NULL) && (j < curscr->Num_cols); j++)
+ {
+ Char_out(curr->row[j], curr->attributes[j], curr->row, curr->attributes, j);
+ }
+ if (STAND)
+ {
+ STAND = FALSE;
+ Position(curscr, from_top, j);
+ attribute_off();
+ }
+ }
+ Repaint_screen = FALSE;
+ }
+
+ similar = 0;
+ diff = FALSE;
+ top_of_win = curscr->first_line;
+
+ for (from_top = 0, curr = top_of_win, virt = window->first_line;
+ from_top < window->Num_lines; from_top++)
+ {
+ virtual_lines[from_top] = TRUE;
+ if ((similar = Comp_line(curr, virt)) > 0)
+ {
+ virtual_lines[from_top] = FALSE;
+ diff = TRUE;
+ }
+ curr = curr->next_screen;
+ virt = virt->next_screen;
+ }
+
+ from_top = 0;
+ virt = window->first_line;
+ curr = top_of_win;
+ similar = 0;
+ /*
+ | if the window has lines that are different, check for scrolling
+ */
+ if (diff)
+ {
+ last_same = -1;
+ changed = FALSE;
+ for (first_same = window->Num_lines;
+ (first_same > from_top) && (virtual_lines[first_same - 1]);
+ first_same--)
+ ;
+ for (last_same = 0;
+ (last_same < window->Num_lines) && (virtual_lines[last_same]== FALSE);
+ last_same++)
+ ;
+ while ((from_top < first_same) && nc_scrolling_ability)
+ /* check entire lines for diffs */
+ {
+
+ if (from_top >= last_same)
+ {
+ for (last_same = from_top;
+ (last_same < window->Num_lines) &&
+ (virtual_lines[last_same] == FALSE);
+ last_same++)
+ ;
+ }
+ if (!virtual_lines[from_top])
+ {
+ diff = TRUE;
+ /*
+ | check for lines deleted (scroll up)
+ */
+ for (tmp_ft = from_top+1, old = curr->next_screen;
+ ((window->scroll_up) && (diff) &&
+ (tmp_ft < last_same) &&
+ (!virtual_lines[tmp_ft]));
+ tmp_ft++)
+ {
+ if ((Comp_line(old, virt) == -1) && (!virtual_lines[from_top]))
+ {
+ /*
+ | Find the bottom of the
+ | area that should be
+ | scrolled.
+ */
+ for (bottom = tmp_ft, old1 = old,
+ new1 = virt, count1 = 0;
+ (bottom < window->Num_lines) &&
+ (Comp_line(old1, new1) <= 0);
+ bottom++, old1 = old1->next_screen,
+ new1 = new1->next_screen,
+ count1++)
+ ;
+ if (count1 > 3)
+ {
+ if (String_table[cs__]) /* scrolling region */
+ {
+ list[1] = from_top;
+ list[0] = min((bottom - 1), (window->Num_lines - 1));
+ String_Out(String_table[cs__], list, 2);
+ Curr_y = Curr_x = -1;
+ }
+
+ for (offset = (tmp_ft - from_top); (offset > 0); offset--)
+ {
+ old = Delete_line(from_top, min((bottom - 1), (window->Num_lines - 1)), window);
+ diff = FALSE;
+ }
+
+ if (String_table[cs__]) /* scrolling region */
+ {
+ list[1] = 0;
+ list[0] = LINES - 1;
+ String_Out(String_table[cs__], list, 2);
+ Curr_y = Curr_x = -1;
+ }
+
+ top_of_win = curscr->first_line;
+ curr = top_of_win;
+ for (offset = 0; offset < from_top; offset++)
+ curr = curr->next_screen;
+ for (offset = from_top, old=curr, new=virt;
+ offset < window->Num_lines;
+ old=old->next_screen, new=new->next_screen,
+ offset++)
+ {
+ similar = Comp_line(old, new);
+ virtual_lines[offset] = (similar > 0 ? FALSE : TRUE);
+ }
+ }
+ }
+ else
+ old = old->next_screen;
+ }
+ /*
+ | check for lines inserted (scroll down)
+ */
+ for (tmp_ft = from_top-1, old = curr->prev_screen;
+ ((window->scroll_down) && (tmp_ft >= 0) &&
+ (diff) &&
+ (!virtual_lines[tmp_ft]));
+ tmp_ft--)
+ {
+ if (Comp_line(old, virt) == -1)
+ {
+ /*
+ | Find the bottom of the
+ | area that should be
+ | scrolled.
+ */
+ for (bottom = from_top, old1 = old,
+ new1 = virt, count1 = 0;
+ (bottom < window->Num_lines) &&
+ (Comp_line(old1, new1) <= 0);
+ bottom++, old1 = old1->next_screen,
+ new1 = new1->next_screen,
+ count1++)
+ ;
+ if (count1 > 3)
+ {
+ if (String_table[cs__]) /* scrolling region */
+ {
+ list[1] = tmp_ft;
+ list[0] = min((bottom - 1), (window->Num_lines - 1));
+ String_Out(String_table[cs__], list, 2);
+ Curr_y = Curr_x = -1;
+ }
+
+ for (offset = (from_top - tmp_ft); (offset > 0); offset--)
+ {
+ old = Insert_line(tmp_ft, min((bottom - 1), (window->Num_lines -1)), window);
+ diff = FALSE;
+ }
+
+ if (String_table[cs__]) /* scrolling region */
+ {
+ list[1] = 0;
+ list[0] = LINES - 1;
+ String_Out(String_table[cs__], list, 2);
+ Curr_y = Curr_x = -1;
+ }
+
+ top_of_win = curscr->first_line;
+ curr = top_of_win;
+ for (offset = 0; offset < from_top; offset++)
+ curr = curr->next_screen;
+ for (offset = from_top, old=curr, new=virt;
+ offset < window->Num_lines;
+ old=old->next_screen, new=new->next_screen,
+ offset++)
+ {
+ similar = Comp_line(old, new);
+ virtual_lines[offset] = (similar > 0 ? FALSE : TRUE);
+ }
+ }
+ }
+ else
+ old = old->prev_screen;
+ }
+ }
+ from_top++;
+ curr = curr->next_screen;
+ virt = virt->next_screen;
+ }
+ }
+
+
+ /*
+ | Scrolling done, now need to insert, delete, or modify text
+ | within lines.
+ */
+
+ for (from_top = 0, curr = curscr->first_line; from_top < window->SR; from_top++)
+ curr = curr->next_screen;
+ top_of_win = curr;
+ for (from_top = 0, curr = top_of_win, virt = window->first_line; from_top < window->Num_lines; from_top++, curr = curr->next_screen, virt = virt->next_screen)
+ {
+
+ /*
+ | If either 'insert mode' or 'insert char' are
+ | available, enter the following 'if' statement,
+ | else, need to simply rewrite the contents of the line
+ | at the point where the contents of the line change.
+ */
+
+ if (((String_table[ic__]) || (String_table[im__])) &&
+ (String_table[dc__]) && (curr->row[0] != (char) NULL) &&
+ (!NC_chinese))
+ {
+ j = 0;
+ first_time = TRUE;
+ vrt_lin = virt->row;
+ vrt_att = virt->attributes;
+ cur_lin = curr->row;
+ cur_att = curr->attributes;
+ while ((vrt_lin[j] != (char) NULL) && (j < window->Num_cols))
+ {
+ if ((STAND) && (Booleans[xs__]))
+ {
+ while ((vrt_lin[j] == cur_lin[j]) && (vrt_att[j] == cur_att[j]) && (vrt_lin[j] != (char) NULL) && (vrt_att[j]))
+ j++;
+ if ((STAND) && (!vrt_att[j]))
+ {
+ STAND = FALSE;
+ Position(window, from_top, j);
+ attribute_off();
+ attribute_off();
+ }
+ }
+ else
+ {
+ while ((vrt_lin[j] == cur_lin[j]) && (vrt_att[j] == cur_att[j]) && (vrt_lin[j] != (char) NULL))
+ j++;
+ }
+ if ((vrt_att[j] != cur_att[j]) && (cur_att[j]) && (Booleans[xs__]))
+ {
+ Position(window, from_top, j);
+/* CLEAR_TO_EOL(window, from_top, j);*/
+ attribute_off();
+ attribute_off();
+ }
+ if (vrt_lin[j] != (char) NULL)
+ {
+ begin_new = j;
+ begin_old = j;
+ end_old = j;
+ end_new = j;
+ if ((first_time) && (virt->changed))
+ {
+ if (curr->last_char <= virt->last_char)
+ changed = check_insert(window, from_top, j, virt, curr);
+ }
+ changed = check_delete(window, from_top, j, virt, curr);
+ first_time = FALSE;
+ virt->changed = FALSE;
+ if (!changed)
+ changed = check_insert(window, from_top, j, virt, curr);
+ if (((!changed) || (cur_lin[j] != vrt_lin[j]) || (cur_att[j] != vrt_att[j])) && (j < window->Num_cols))
+ {
+ if ((vrt_lin[j] == ' ') && (cur_lin[j] == (char) NULL) && (vrt_att[j] == cur_att[j]))
+ cur_lin[j] = ' ';
+ else
+ {
+ Position(window, from_top, j);
+ Char_out(vrt_lin[j], vrt_att[j], cur_lin, cur_att, j);
+ }
+ }
+ if ((vrt_lin[j] != (char) NULL))
+ j++;
+ }
+ if ((STAND) && (!vrt_att[j]))
+ {
+ STAND = FALSE;
+ Position(window, from_top, j);
+ attribute_off();
+ }
+ }
+ if ((vrt_lin[j] == (char) NULL) && (cur_lin[j] != (char) NULL))
+ {
+ Position(window, from_top, j);
+ CLEAR_TO_EOL(window, from_top, j);
+ }
+ }
+ else /*if ((similar != -1) && (similar != 0))*/
+ {
+ j = 0;
+ c1 = curr->row;
+ att1 = curr->attributes;
+ c2 = virt->row;
+ att2 = virt->attributes;
+ while ((j < window->Num_cols) && (c2[j] != (char) NULL))
+ {
+ while ((c1[j] == c2[j]) && (att1[j] == att2[j]) && (j < window->Num_cols) && (c2[j] != (char) NULL))
+ j++;
+
+ /*
+ | if previous character is an eight bit
+ | char, start redraw from that character
+ */
+
+ if ((NC_chinese) && (highbitset(c1[j - 1])))
+ j--;
+ begin_old = j;
+ begin_new = j;
+ if ((j < window->Num_cols) && (c2[j] != (char) NULL))
+ {
+ Position(window, from_top, begin_old);
+ CLEAR_TO_EOL(window, from_top, j);
+ Position(window, from_top, begin_old);
+ for (j = begin_old; (c2[j] != (char) NULL) && (j < window->Num_cols); j++)
+ Char_out(c2[j], att2[j], c1, att1, j);
+ }
+ }
+ if ((c2[j] == (char) NULL) && (c1[j] != (char) NULL))
+ {
+ Position(window, from_top, j);
+ CLEAR_TO_EOL(window, from_top, j);
+ }
+ }
+ if (STAND)
+ {
+ STAND = FALSE;
+ Position(window, from_top, j);
+ attribute_off();
+ }
+ virt->number = from_top;
+ }
+ Position(window, window->LY, window->LX);
+}
+
+void
+Position(window, row, col) /* position the cursor for output on the screen */
+WINDOW *window;
+int row;
+int col;
+{
+ int list[10];
+ int place;
+
+ int pos_row;
+ int pos_column;
+
+ pos_row = row + window->SR;
+ pos_column = col + window->SC;
+ if ((pos_row != Curr_y) || (pos_column != Curr_x))
+ {
+ if (String_table[cm__] != NULL) /* && (row < window->Num_lines) && (column < window->Num_cols))*/
+ {
+ place = 0;
+ list[place++] = pos_column;
+ list[place++] = pos_row;
+ String_Out(String_table[cm__], list, place);
+ if ((STAND) && (!Booleans[ms__]))
+ attribute_on();
+ }
+ Curr_x = pos_column;
+ Curr_y = pos_row;
+ }
+}
+
+void
+Char_del(line, attrib, offset, maxlen) /* delete chars from line */
+char *line;
+char *attrib;
+int offset;
+int maxlen;
+{
+ int one, two;
+
+ for (one = offset, two = offset+1; (line[one] != (char) NULL) && (one < maxlen); one++, two++)
+ {
+ line[one] = line[two];
+ attrib[one] = attrib[two];
+ }
+ String_Out(String_table[dc__], NULL, 0);
+}
+
+void
+Char_ins(line, attrib, newc, newatt, offset, maxlen) /* insert chars in line */
+char *line;
+char *attrib;
+char newc;
+char newatt;
+int offset;
+int maxlen;
+{
+ int one, two;
+
+ one = 0;
+ while ((line[one] != (char) NULL) && (one < (maxlen - 2)))
+ one++;
+ for (two = one + 1; (two > offset); one--, two--)
+ {
+ line[two] = line[one];
+ attrib[two] = attrib[one];
+ }
+ line[offset] = newc;
+ attrib[offset] = newatt;
+ Char_out(newc, newatt, line, attrib, offset);
+}
+
+void
+attribute_on()
+{
+ if (String_table[sa__])
+ {
+ attributes_set[0] = 1;
+ String_Out(String_table[sa__], attributes_set, 1);
+ }
+ else if (String_table[so__])
+ String_Out(String_table[so__], NULL, 0);
+}
+
+void
+attribute_off()
+{
+ if (String_table[me__])
+ String_Out(String_table[me__], NULL, 0);
+ else if (String_table[sa__])
+ {
+ attributes_set[0] = 0;
+ String_Out(String_table[sa__], attributes_set, 1);
+ }
+ else if (String_table[se__])
+ String_Out(String_table[se__], NULL, 0);
+}
+
+void
+Char_out(newc, newatt, line, attrib, offset) /* output character with proper attribute */
+char newc;
+char newatt;
+char *line;
+char *attrib;
+int offset;
+{
+
+
+ if ((newatt) && (!STAND))
+ {
+ STAND = TRUE;
+ attribute_on();
+ }
+ else if ((STAND) && (!newatt))
+ {
+ STAND = FALSE;
+ attribute_off();
+ }
+
+ if ((newatt) && (STAND) && (Booleans[xs__]))
+ {
+ attribute_on();
+ }
+
+ if (!((Curr_y >= (LINES - 1)) && (Curr_x >= (COLS - 1))))
+ {
+ putchar(newc);
+ line[offset] = newc;
+ attrib[offset] = newatt;
+ }
+ Curr_x++;
+}
+
+/*
+ |
+ | The two routines that follow, nc_setattrib(), nc_clearattrib(), are
+ | hacks that notify new_curse to handle characters that have the high
+ | bit set as the first of two bytes of a multi-byte string.
+ |
+ */
+
+void
+nc_setattrib(flag)
+int flag;
+{
+ nc_attributes |= flag;
+}
+
+void
+nc_clearattrib(flag)
+int flag;
+{
+ nc_attributes &= ~flag;
+}
+
diff --git a/contrib/ee/new_curse.h b/contrib/ee/new_curse.h
new file mode 100644
index 0000000..db538bb
--- /dev/null
+++ b/contrib/ee/new_curse.h
@@ -0,0 +1,260 @@
+/*
+ | new_curse.h
+ |
+ | A subset of curses developed for use with ae.
+ |
+ | written by Hugh Mahon
+ |
+ | THIS MATERIAL IS PROVIDED "AS IS". THERE ARE
+ | NO WARRANTIES OF ANY KIND WITH REGARD TO THIS
+ | MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE
+ | IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ | FITNESS FOR A PARTICULAR PURPOSE. Neither
+ | Hewlett-Packard nor Hugh Mahon shall be liable
+ | for errors contained herein, nor for
+ | incidental or consequential damages in
+ | connection with the furnishing, performance or
+ | use of this material. Neither Hewlett-Packard
+ | nor Hugh Mahon assumes any responsibility for
+ | the use or reliability of this software or
+ | documentation. This software and
+ | documentation is totally UNSUPPORTED. There
+ | is no support contract available. Hewlett-
+ | Packard has done NO Quality Assurance on ANY
+ | of the program or documentation. You may find
+ | the quality of the materials inferior to
+ | supported materials.
+ |
+ | This software is not a product of Hewlett-Packard, Co., or any
+ | other company. No support is implied or offered with this software.
+ | You've got the source, and you're on your own.
+ |
+ | This software may be distributed under the terms of Larry Wall's
+ | Artistic license, a copy of which is included in this distribution.
+ |
+ | This notice must be included with this software and any derivatives.
+ |
+ | Copyright (c) 1986, 1987, 1988, 1991, 1995 Hugh Mahon
+ | All are rights reserved.
+ |
+ */
+
+#include <stdio.h>
+
+#ifdef SYS5
+#include <termio.h>
+#else
+#include <sgtty.h>
+#include <fcntl.h>
+#endif
+
+#define KEY_BREAK 0401
+#define KEY_DOWN 0402
+#define KEY_UP 0403
+#define KEY_LEFT 0404
+#define KEY_RIGHT 0405
+#define KEY_HOME 0406
+#define KEY_BACKSPACE 0407
+#define KEY_F0 0410
+#define KEY_F(n) (KEY_F0+(n))
+#define KEY_DL 0510
+#define KEY_IL 0511
+#define KEY_DC 0512
+#define KEY_IC 0513
+#define KEY_EIC 0514
+#define KEY_CLEAR 0515
+#define KEY_EOS 0516
+#define KEY_EOL 0517
+#define KEY_SF 0520
+#define KEY_SR 0521
+#define KEY_NPAGE 0522
+#define KEY_PPAGE 0523
+#define KEY_STAB 0524
+#define KEY_CTAB 0525
+#define KEY_CATAB 0526
+#define KEY_ENTER 0527
+#define KEY_SRESET 0530
+#define KEY_RESET 0531
+#define KEY_PRINT 0532
+#define KEY_LL 0533
+#define KEY_A1 0534
+#define KEY_A3 0535
+#define KEY_B2 0536
+#define KEY_C1 0537
+#define KEY_C3 0540
+#define KEY_BTAB 0541
+#define KEY_BEG 0542
+#define KEY_CANCEL 0543
+#define KEY_CLOSE 0544
+#define KEY_COMMAND 0545
+#define KEY_COPY 0546
+#define KEY_CREATE 0547
+#define KEY_END 0550
+#define KEY_EXIT 0551
+#define KEY_FIND 0552
+#define KEY_HELP 0553
+#define KEY_MARK 0554
+#define KEY_MESSAGE 0555
+#define KEY_MOVE 0556
+#define KEY_NEXT 0557
+#define KEY_OPEN 0560
+#define KEY_OPTIONS 0561
+#define KEY_PREVIOUS 0562
+#define KEY_REDO 0563
+#define KEY_REFERENCE 0564
+#define KEY_REFRESH 0565
+#define KEY_REPLACE 0566
+#define KEY_RESTART 0567
+#define KEY_RESUME 0570
+#define KEY_SAVE 0571
+#define KEY_SBEG 0572
+#define KEY_SCANCEL 0573
+#define KEY_SCOMMAND 0574
+#define KEY_SCOPY 0575
+#define KEY_SCREATE 0576
+#define KEY_SDC 0577
+#define KEY_SDL 0600
+#define KEY_SELECT 0601
+#define KEY_SEND 0602
+#define KEY_SEOL 0603
+#define KEY_SEXIT 0604
+#define KEY_SFIND 0605
+#define KEY_SHELP 0606
+#define KEY_SHOME 0607
+#define KEY_SIC 0610
+#define KEY_SLEFT 0611
+#define KEY_SMESSAGE 0612
+#define KEY_SMOVE 0613
+#define KEY_SNEXT 0614
+#define KEY_SOPTIONS 0615
+#define KEY_SPREVIOUS 0616
+#define KEY_SPRINT 0617
+#define KEY_SREDO 0620
+#define KEY_SREPLACE 0621
+#define KEY_SRIGHT 0622
+#define KEY_SRSUME 0623
+#define KEY_SSAVE 0624
+#define KEY_SSUSPEND 0625
+#define KEY_SUNDO 0626
+#define KEY_SUSPEND 0627
+#define KEY_UNDO 0630
+
+#define TRUE 1
+#define FALSE 0
+
+#define A_STANDOUT 0001 /* standout mode */
+#define A_NC_BIG5 0x0100 /* Handle Chinese Big5 characters */
+#define SCROLL 1 /* text has been scrolled */
+#define CLEAR 2 /* window has been cleared */
+#define CHANGE 3 /* window has been changed */
+#define UP 1 /* direction of scroll */
+#define DOWN 2
+
+struct _line {
+ struct _line *next_screen;
+ struct _line *prev_screen;
+ char *row;
+ char *attributes;
+ int last_char;
+ int changed;
+ int scroll;
+ int number;
+ };
+
+struct _line *top_of_win;
+
+typedef struct WIND {
+ int SR; /* starting row */
+ int SC; /* starting column */
+ int LC; /* last column */
+ int LX; /* last cursor column position */
+ int LY; /* last cursor row position */
+ int Attrib; /* attributes active in window */
+ int Num_lines; /* number of lines */
+ int Num_cols; /* number of columns */
+ int scroll_up; /* number of lines moved */
+ int scroll_down;
+ int SCROLL_CLEAR; /* indicates that window has been scrolled or cleared */
+ struct _line *first_line;
+ struct _line **line_array;
+ } WINDOW;
+
+extern WINDOW *curscr;
+extern WINDOW *stdscr;
+
+extern int LINES, COLS;
+
+#if defined(__STDC__) || defined(__cplusplus)
+#define P_(s) s
+#else
+#define P_(s) ()
+#endif
+
+extern void copy_window P_((WINDOW *origin, WINDOW *destination));
+extern void reinitscr P_((int));
+extern void initscr P_((void));
+extern int Get_int P_((void));
+extern int INFO_PARSE P_((void));
+extern int AtoI P_((void));
+extern void Key_Get P_((void));
+extern void keys_vt100 P_((void));
+extern struct _line *Screenalloc P_((int columns));
+extern WINDOW *newwin P_((int lines, int cols, int start_l, int start_c));
+extern int Operation P_((int Temp_Stack[], int place));
+extern void Info_Out P_((char *string, int p_list[], int place));
+extern void wmove P_((WINDOW *window, int row, int column));
+extern void clear_line P_((struct _line *line, int column, int cols));
+extern void werase P_((WINDOW *window));
+extern void wclrtoeol P_((WINDOW *window));
+extern void wrefresh P_((WINDOW *window));
+extern void touchwin P_((WINDOW *window));
+extern void wnoutrefresh P_((WINDOW *window));
+extern void flushinp P_((void));
+extern void ungetch P_((int c));
+extern int wgetch P_((WINDOW *window));
+extern void Clear P_((int));
+extern int Get_key P_((int first_char));
+extern void waddch P_((WINDOW *window, int c));
+extern void winsertln P_((WINDOW *window));
+extern void wdeleteln P_((WINDOW *window));
+extern void wclrtobot P_((WINDOW *window));
+extern void wstandout P_((WINDOW *window));
+extern void wstandend P_((WINDOW *window));
+extern void waddstr P_((WINDOW *window, char *string));
+extern void clearok P_((WINDOW *window, int flag));
+extern void echo P_((void));
+extern void noecho P_((void));
+extern void raw P_((void));
+extern void noraw P_((void));
+extern void nl P_((void));
+extern void nonl P_((void));
+extern void saveterm P_((void));
+extern void fixterm P_((void));
+extern void resetterm P_((void));
+extern void nodelay P_((WINDOW *window, int flag));
+extern void idlok P_((WINDOW *window, int flag));
+extern void keypad P_((WINDOW *window, int flag));
+extern void savetty P_((void));
+extern void resetty P_((void));
+extern void endwin P_((void));
+extern void delwin P_((WINDOW *window));
+extern void wprintw P_((WINDOW *window, const char* format, ...));
+extern void iout P_((WINDOW *window, int value));
+extern int Comp_line P_((struct _line *line1, struct _line *line2));
+extern struct _line *Insert_line P_((int row, int end_row, WINDOW *window));
+extern struct _line *Delete_line P_((int row, int end_row, WINDOW *window));
+extern void CLEAR_TO_EOL P_((WINDOW *window, int row, int column));
+extern int check_delete P_((WINDOW *window, int line, int offset, struct _line *pointer_new, struct _line *pointer_old));
+extern int check_insert P_((WINDOW *window, int line, int offset, struct _line *pointer_new, struct _line *pointer_old));
+extern void doupdate P_((void));
+extern void Position P_((WINDOW *window, int row, int col));
+extern void Char_del P_((char *line, char *attrib, int offset, int maxlen));
+extern void Char_ins P_((char *line, char *attrib, int newc, int newatt, int offset, int maxlen));
+extern void attribute_on P_((void));
+extern void attribute_off P_((void));
+extern void Char_out P_((int newc, int newatt, char *line, char *attrib, int offset));
+
+extern void nc_setattrib P_((int));
+extern void nc_clearattrib P_((int));
+#undef P_
+
OpenPOWER on IntegriCloud