diff --git a/usr.bin/ee/Artistic b/usr.bin/ee/Artistic new file mode 100644 index 000000000000..fbf798977589 --- /dev/null +++ b/usr.bin/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/usr.bin/ee/README.ee b/usr.bin/ee/README.ee new file mode 100644 index 000000000000..8850af245dc0 --- /dev/null +++ b/usr.bin/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/usr.bin/ee/create.make b/usr.bin/ee/create.make new file mode 100755 index 000000000000..9c41f894ace3 --- /dev/null +++ b/usr.bin/ee/create.make @@ -0,0 +1,267 @@ +#!/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.6 1995/08/21 02:25:23 hugh Exp $ +# + +# test for existence of termcap (exists on both BSD and SysV systems) + +if [ -f /etc/termcap -o -f /usr/share/lib/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 ] +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 + +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 unistd.h + +if [ -f /usr/include/unistd.h ] +then + HAS_UNISTD=-DHAS_UNISTD +else + HAS_UNISTD="" +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/usr.bin/ee/ee.i18n.guide b/usr.bin/ee/ee.i18n.guide new file mode 100644 index 000000000000..0850c2e7400d --- /dev/null +++ b/usr.bin/ee/ee.i18n.guide @@ -0,0 +1,141 @@ +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 only supports eight bit characters. + +(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 + +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/usr.bin/ee/ee.msg b/usr.bin/ee/ee.msg new file mode 100644 index 000000000000..6c5ef751bc70 --- /dev/null +++ b/usr.bin/ee/ee.msg @@ -0,0 +1,179 @@ +$ 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.6 1995/10/16 05:20:50 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 " -i : no information window -e : do not 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 " +#include + +#ifdef SYS5 +#include +#else +#include +#endif + +#ifdef BSD_SELECT +#include +#include + +#ifdef SLCT_HDR +#include /* on AIX */ +#endif /* SLCT_HDR */ + +#endif /* BSD_SELECT */ + +#ifdef HAS_STDLIB +#include +#endif + +#if defined(__STDC__) +#include +#else +#include +#endif + +#ifdef HAS_UNISTD +#include +#endif + +#ifdef HAS_SYS_IOCTL +#include +#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) + +#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; + +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]; + +#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) + { + 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(); + 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++; + } +} + +#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(); + free(tc_); + 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] = 255; /* 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); + free(stdscr); + 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; xNum_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); +} + +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; + + window = virtual_scr; + + 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 + */ + 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; + 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; + 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; + } + } + + 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 (((String_table[ic__]) || (String_table[im__])) && (String_table[dc__]) && (curr->row[0] != (char) NULL)) + { + 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++; + 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++; +} + diff --git a/usr.bin/ee/new_curse.h b/usr.bin/ee/new_curse.h new file mode 100644 index 000000000000..bc46e5ba8d65 --- /dev/null +++ b/usr.bin/ee/new_curse.h @@ -0,0 +1,256 @@ +/* + | 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 + +#ifdef SYS5 +#include +#else +#include +#include +#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 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 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)); + +#undef P_ +