├── ee_version.h ├── genstr ├── Makefile ├── Changes ├── make.default ├── create.make ├── README.ee ├── ee.msg ├── ee.i18n.guide ├── new_curse.h ├── ee.1 └── new_curse.c /ee_version.h: -------------------------------------------------------------------------------- 1 | /* 2 | | provide a version number for ee 3 | */ 4 | 5 | #define EE_VERSION "1.5.2" 6 | #define DATE_STRING "$Date: 2010/06/04 02:35:35 $" 7 | -------------------------------------------------------------------------------- /genstr: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -x 4 | 5 | if [ $# -lt 2 ] 6 | then 7 | echo usage $0 source_file dest_file 8 | exit 1 9 | fi 10 | 11 | trap 'rm -f /tmp/$$.out; exit 0' 0 # set up traps to clean up 12 | trap 'rm -f /tmp/$$.out; exit 1' 1 2 3 15 # on errors AND normal exit 13 | 14 | if [ -f $2 ] 15 | then 16 | rm $2 17 | fi 18 | 19 | cat $1 | grep 'catgetlocal.*\"*\"' | 20 | sed -e 's/^.*catgetlocal(//' | 21 | sed -e 's/^[ ]*//' | 22 | sed -e 's/, \"/ \"/' | 23 | sed -e 's/);//' > /tmp/$$.out 24 | 25 | cat > $2 <> $2 33 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # This is the make file for ee, the "easy editor". 2 | # 3 | # A file called 'make.local' will be generated which will contain information 4 | # specific to the local system, such as if it is a BSD or System V based 5 | # version of UNIX, whether or not it has catgets, or select. 6 | # 7 | # The "install" target ("make install") will copy the ee binary to 8 | # the /usr/local/bin directory on the local system. The man page (ee.1) 9 | # will be copied into the /usr/local/man/man1 directory. 10 | # 11 | # The "clean" target ("make clean") will remove the ee and new_curse.o 12 | # object files, and the ee binary. 13 | # 14 | 15 | all : localmake buildee 16 | 17 | buildee : 18 | make -f make.local 19 | 20 | localmake: 21 | @./create.make 22 | 23 | install : 24 | cp ee /usr/local/bin/ee 25 | cp ee.1 /usr/local/man/man1/ee.1 26 | 27 | clean : 28 | rm -f ee.o new_curse.o ee 29 | 30 | -------------------------------------------------------------------------------- /Changes: -------------------------------------------------------------------------------- 1 | version 1.5.0 (2/16/2009) 2 | - added display of line number, column, and lines from top to separator line 3 | for info window 4 | - minor changes to reduce number of warnings when using -pedantic option 5 | 6 | version 1.4.7 (2/10/2009) 7 | - changed how strings are terminated from the old usage of NULL to the current 8 | use of character zero, '\0' 9 | - changed the licensing since the Artistic License is now considered 10 | restrictive 11 | 12 | version 1.4.6 13 | - modified new_curse.c to handle different subdirectory naming in terminfo 14 | directory; first noted on Mac OS 10.2 15 | 16 | version 1.4.5a (12/23/2001) 17 | - modified get_options to be cleaner for arg handling 18 | 19 | version 1.4.5 (12/15/2001) 20 | - made changes to check usage of arguments provided so that if a file is 21 | specified options are no longer accepted (that is, they are treated as file 22 | names) 23 | - changed to use ee_version.h to allow changing version number without need 24 | to change ee.c directly 25 | 26 | version 1.4.4 (8/17/2001) 27 | - added code to check if the parent process has died, and if so to exit 28 | gracefully 29 | 30 | version 1.4.3 (6/25/2001) 31 | - modified create.make and new_curse.c to allow defining TERMCAP file 32 | location (since some distributions move the file) 33 | - source directory now has version number attached to directory name 34 | 35 | version 1.4.2 (1/19/2001) 36 | - change to create.make script to add unistd.h to files to search for 37 | select() declaration 38 | - change to new_curse.c for proper raw mode operation 39 | 40 | 41 | -------------------------------------------------------------------------------- /make.default: -------------------------------------------------------------------------------- 1 | # This is the make file for ee, the "easy editor". 2 | # 3 | # If building ee using curses, type "make curses", otherwise new_curse (a 4 | # subset of curses that supports ee) will be built and ee will use new_curse 5 | # instead of curses. 6 | # 7 | # The "install" target ("make install") will copy the ee binary to 8 | # the /usr/local/bin directory on the local system. The man page (ee.1) 9 | # will be copied into the /usr/local/man/man1 directory. 10 | # 11 | # The "clean" target ("make clean") will remove the ee and new_curse.o 12 | # object files, and the ee binary. 13 | # 14 | # If the system does not have localization routines, use the -DNO_CATGETS 15 | # define. If the system supports setlocale(), catopen(), and catgets() and 16 | # localization is desired, do not use -DNO_CATGETS. 17 | # 18 | # DEFINES is used for new_curse.c, and CFLAGS is used for ee.c. 19 | # 20 | 21 | # for System V, using new_curse with terminfo 22 | DEFINES = -DSYS5 -DNCURSE 23 | 24 | # for BSD, using new_curse with termcap 25 | #DEFINES = -DCAP -DNCURSE 26 | 27 | # for BSD systems with select(), using new_curse with termcap, use: 28 | #DEFINES = -DCAP -DNCURSE -DBSD_SELECT 29 | 30 | # flags for compilation 31 | CFLAGS = -s -DNO_CATGETS 32 | 33 | # For Sun systems, remove the '#' from the front of the next two lines: 34 | #DEFINES = -DSYS5 -DNCURSE 35 | #CFLAGS = -I/usr/5include -L/usr/5lib -DNO_CATGETS -s 36 | 37 | all : ee 38 | 39 | curses : ee.c 40 | cc ee.c -o ee $(CFLAGS) -lcurses 41 | 42 | ee : ee.o new_curse.o 43 | cc -o ee ee.o new_curse.o $(CFLAGS) 44 | 45 | ee.o : ee.c new_curse.h 46 | cc -c ee.c $(DEFINES) $(CFLAGS) 47 | 48 | new_curse.o : new_curse.c new_curse.h 49 | cc new_curse.c -c $(DEFINES) $(CFLAGS) 50 | 51 | install : 52 | cp ee /usr/local/bin/ee 53 | cp ee.1 /usr/local/man/man1/ee.1 54 | 55 | clean : 56 | rm -f ee.o new_curse.o ee 57 | 58 | -------------------------------------------------------------------------------- /create.make: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # This script will determine if the system is a System V or BSD based 5 | # UNIX system and create a makefile for ee appropriate for the system. 6 | # 7 | # $Header: /home/hugh/sources/old_ae/RCS/create.make,v 1.13 2002/09/23 04:18:13 hugh Exp $ 8 | # 9 | 10 | #set -x 11 | 12 | name_string="`uname`" 13 | 14 | # test for existence of termcap (exists on both BSD and SysV systems) 15 | 16 | if [ -f /etc/termcap -o -f /usr/share/lib/termcap -o -f /usr/share/misc/termcap ] 17 | then 18 | if [ -f /usr/share/lib/termcap ] 19 | then 20 | termcap_exists="-DTERMCAP=\"\\\"/usr/share/lib/termcap\\\"\"" 21 | elif [ -f /usr/share/misc/termcap ] 22 | then 23 | termcap_exists="-DTERMCAP=\"\\\"/usr/share/misc/termcap\\\"\"" 24 | elif [ -f /etc/termcap ] 25 | then 26 | termcap_exists="-DTERMCAP=\"\\\"/etc/termcap\\\"\"" 27 | fi 28 | else 29 | termcap_exists="" 30 | fi 31 | 32 | # test for terminfo directory (exists on SysV systems) 33 | 34 | if [ -d /usr/lib/terminfo -o -d /usr/share/lib/terminfo -o -d /usr/share/terminfo ] 35 | then 36 | terminfo_exists="" 37 | else 38 | terminfo_exists="-DCAP" 39 | fi 40 | 41 | # test for existence of termio header (on SysV systems) 42 | 43 | if [ -f /usr/include/termio.h ] 44 | then 45 | termio="-DSYS5" 46 | else 47 | termio="" 48 | fi 49 | 50 | # test for sgtty header (on BSD systems) 51 | 52 | if [ -f /usr/include/sgtty.h ] 53 | then 54 | sgtty="TRUE" 55 | else 56 | sgtty="" 57 | fi 58 | 59 | # look for select call in headers, make sure headers exist 60 | 61 | HEADER_FILES="" 62 | 63 | if [ -f /usr/include/sys/time.h ] 64 | then 65 | HEADER_FILES="/usr/include/sys/time.h " 66 | fi 67 | 68 | if [ -f /usr/include/sys/types.h ] 69 | then 70 | HEADER_FILES="$HEADER_FILES /usr/include/sys/types.h" 71 | fi 72 | 73 | # check for unistd.h 74 | 75 | if [ -f /usr/include/unistd.h ] 76 | then 77 | HAS_UNISTD=-DHAS_UNISTD 78 | HEADER_FILES="$HEADER_FILES /usr/include/unistd.h" 79 | else 80 | HAS_UNISTD="" 81 | fi 82 | 83 | if [ -n "$HEADER_FILES" ] 84 | then 85 | string="`grep select $HEADER_FILES`" 86 | if [ -n "$string" ] 87 | then 88 | BSD_SELECT="-DBSD_SELECT" 89 | else 90 | BSD_SELECT="" 91 | fi 92 | fi 93 | 94 | # check for existence of select.h (on AIX) 95 | 96 | if [ -f /usr/include/sys/select.h ] 97 | then 98 | select_hdr="-DSLCT_HDR" 99 | else 100 | select_hdr="" 101 | fi 102 | 103 | # check for stdlib.h 104 | 105 | if [ -f /usr/include/stdlib.h ] 106 | then 107 | HAS_STDLIB=-DHAS_STDLIB 108 | else 109 | HAS_STDLIB="" 110 | fi 111 | 112 | # check for stdarg.h 113 | 114 | if [ -f /usr/include/stdarg.h ] 115 | then 116 | HAS_STDARG=-DHAS_STDARG 117 | else 118 | HAS_STDARG="" 119 | fi 120 | 121 | # check for ctype.h 122 | 123 | if [ -f /usr/include/ctype.h ] 124 | then 125 | HAS_CTYPE=-DHAS_CTYPE 126 | else 127 | HAS_CTYPE="" 128 | fi 129 | 130 | # check for sys/ioctl.h 131 | 132 | if [ -f /usr/include/sys/ioctl.h ] 133 | then 134 | HAS_SYS_IOCTL=-DHAS_SYS_IOCTL 135 | else 136 | HAS_SYS_IOCTL="" 137 | fi 138 | 139 | # check for sys/wait.h 140 | 141 | if [ -f /usr/include/sys/wait.h ] 142 | then 143 | HAS_SYS_WAIT=-DHAS_SYS_WAIT 144 | else 145 | HAS_SYS_WAIT="" 146 | fi 147 | 148 | # check for localization headers 149 | 150 | if [ -f /usr/include/locale.h -a -f /usr/include/nl_types.h ] 151 | then 152 | catgets="" 153 | else 154 | catgets="-DNO_CATGETS" 155 | fi 156 | 157 | # make decisions about use of new_curse.c (use of new_curse is recommended 158 | # rather than local curses) 159 | 160 | if [ -n "$terminfo_exists" -a -z "$termcap_exists" ] 161 | then 162 | echo "Neither terminfo or termcap are on this system! " 163 | if [ -f /usr/include/curses.h ] 164 | then 165 | echo "Relying on local curses implementation." 166 | else 167 | cat <<-EOF 168 | Don't know where to find curses, you'll need to modify 169 | source code to be able to build! 170 | 171 | Modify the file make.default and build ee by typing: 172 | 173 | make -f make.default 174 | 175 | EOF 176 | 177 | exit 1 178 | fi 179 | 180 | TARGET="curses" 181 | curses="" 182 | else 183 | curses="-DNCURSE" 184 | TARGET="ee" 185 | fi 186 | 187 | if [ -z "$termio" -a -z "$sgtty" ] 188 | then 189 | echo "Neither termio.h or sgtty.h are on this system! " 190 | if [ -f /usr/include/curses.h ] 191 | then 192 | echo "Relying on local curses implementation." 193 | else 194 | cat <<-EOF 195 | Don't know where to find curses, you'll need to modify 196 | source code to be able to build! 197 | 198 | Modify the file make.default and build ee by typing: 199 | 200 | make -f make.default 201 | 202 | EOF 203 | 204 | exit 1 205 | fi 206 | 207 | TARGET="curses" 208 | curses="" 209 | fi 210 | 211 | # check if this is a SunOS system 212 | 213 | if [ -d /usr/5include ] 214 | then 215 | five_include="-I/usr/5include" 216 | else 217 | five_include="" 218 | fi 219 | 220 | if [ -d /usr/5lib ] 221 | then 222 | five_lib="-L/usr/5lib" 223 | else 224 | five_lib="" 225 | fi 226 | 227 | 228 | if [ "$name_string" = "Darwin" ] 229 | then 230 | if [ -n "$CFLAGS" ] 231 | then 232 | other_cflags="${CFLAGS} -DNO_CATGETS" 233 | else 234 | other_cflags="-DNO_CATGETS" 235 | fi 236 | else 237 | 238 | if [ -n "$CFLAGS" ] 239 | then 240 | if [ -z "`echo $CFLAGS | grep '[-]g'`" ] 241 | then 242 | other_cflags="${CFLAGS} -s" 243 | else 244 | other_cflags="${CFLAGS}" 245 | fi 246 | else 247 | other_cflags="-s" 248 | fi 249 | fi 250 | 251 | # time to write the makefile 252 | 253 | echo "Generating make.local" 254 | 255 | if [ -f make.local ] 256 | then 257 | mv make.local make.lcl.old 258 | fi 259 | 260 | echo "DEFINES = $termio $terminfo_exists $BSD_SELECT $catgets $select $curses " > make.local 261 | echo "" >> make.local 262 | echo "CFLAGS = $HAS_UNISTD $HAS_STDARG $HAS_STDLIB $HAS_CTYPE $HAS_SYS_IOCTL $HAS_SYS_WAIT $five_lib $five_include $select_hdr $other_cflags $termcap_exists" >> make.local 263 | echo "" >> make.local 264 | echo "" >> make.local 265 | echo "all : $TARGET" >> make.local 266 | 267 | cat >> make.local << EOF 268 | 269 | curses : ee.c 270 | cc ee.c -o ee \$(CFLAGS) -lcurses 271 | 272 | ee : ee.o new_curse.o 273 | cc -o ee ee.o new_curse.o \$(CFLAGS) 274 | 275 | ee.o : ee.c new_curse.h 276 | cc -c ee.c \$(DEFINES) \$(CFLAGS) 277 | 278 | new_curse.o : new_curse.c new_curse.h 279 | cc new_curse.c -c \$(DEFINES) \$(CFLAGS) 280 | 281 | EOF 282 | 283 | if [ -f make.lcl.old ] 284 | then 285 | diffs="`cmp make.lcl.old make.local`" 286 | if [ -n "${diffs}" ] 287 | then 288 | rm -f ee.o new_curse.o ee 289 | fi 290 | rm -f make.lcl.old 291 | fi 292 | 293 | -------------------------------------------------------------------------------- /README.ee: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009, Hugh Mahon 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions 6 | are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above 11 | copyright notice, this list of conditions and the following 12 | disclaimer in the documentation and/or other materials provided 13 | with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | POSSIBILITY OF SUCH DAMAGE. 27 | 28 | 29 | The editor 'ee' (easy editor) is intended to be a simple, easy to use 30 | terminal-based screen oriented editor that requires no instruction to 31 | use. Its primary use would be for people who are new to computers, or who 32 | use computers only for things like e-mail. 33 | 34 | ee's simplified interface is highlighted by the use of pop-up menus which 35 | make it possible for users to carry out tasks without the need to 36 | remember commands. An information window at the top of the screen shows 37 | the user the operations available with control-keys. 38 | 39 | ee allows users to use full eight-bit characters. If the host system has 40 | the capabilities, ee can use message catalogs, which would allow users to 41 | translate the message catalog into other languages which use eight-bit 42 | characters. See the file ee.i18n.guide for more details. 43 | 44 | ee relies on the virtual memory abilities of the platform it is running on 45 | and does not have its own memory management capabilities. 46 | 47 | I am releasing ee because I hate to see new users and non-computer types 48 | get frustrated by vi, and would like to see more intuitive interfaces for 49 | basic tools (both character-based and graphical) become more pervasive. 50 | Terminal capabilities and communication speeds have evolved considerably 51 | since the time in which vi's interface was created, allowing much more 52 | intuitive interfaces to be used. Since character-based I/O won't be 53 | completely replaced by graphical user interfaces for at least a few more 54 | years, I'd like to do what I can to make using computers with less 55 | glamorous interfaces as easy to use as possible. If terminal interfaces 56 | are still used in ten years, I hope neophytes won't still be stuck with 57 | only vi. 58 | 59 | For a text editor to be easy to use requires a certain set of abilities. In 60 | order for ee to work, a terminal must have the ability to position the cursor 61 | on the screen, and should have arrow keys that send unique sequences 62 | (multiple characters, the first character is an "escape", octal code 63 | '\033'). All of this information needs to be in a database called "terminfo" 64 | (System V implementations) or "termcap" (usually used for BSD systems). In 65 | case the arrow keys do not transmit unique sequences, motion operations are 66 | mapped to control keys as well, but this at least partially defeats the 67 | purpose. The curses package is used to handle the I/O which deals with the 68 | terminal's capabilities. 69 | 70 | While ee is based on curses, I have included here the source code to 71 | new_curse, a subset of curses developed for use with ee. 'curses' often 72 | will have a defect that reduces the usefulness of the editor relying upon 73 | it. 74 | 75 | The file new_curse.c contains a subset of 'curses', a package for 76 | applications to use to handle screen output. Unfortunately, curses 77 | varies from system to system, so I developed new_curse to provide 78 | consistent behavior across systems. It works on both SystemV and BSD 79 | systems, and while it can sometimes be slower than other curses packages, 80 | it will get the information on the screen painted correctly more often 81 | than vendor supplied curses. Unless problems occur during the building 82 | of ee, it is recommended that you use new_curse rather than the curses 83 | supplied with your system. 84 | 85 | If you experience problems with data being displayed improperly, check 86 | your terminal configuration, especially if you're using a terminal 87 | emulator, and make sure that you are using the right terminfo entry 88 | before rummaging through code. Terminfo entries often contain 89 | inaccuracies, or incomplete information, or may not totally match the 90 | terminal or emulator the terminal information is being used with. 91 | Complaints that ee isn't working quite right often end up being something 92 | else (like the terminal emulator being used). 93 | 94 | Both ee and new_curse were developed using K&R C (also known as "classic 95 | C"), but it can also be compiled with ANSI C. You should be able to 96 | build ee by simply typing "make". A make file which takes into account 97 | the characteristics of your system will be created, and then ee will be 98 | built. If there are problems encountered, you will be notified about 99 | them. 100 | 101 | ee is the result of several conflicting design goals. While I know that it 102 | solves the problems of some users, I also have no doubt that some will decry 103 | its lack of more features. I will settle for knowing that ee does fulfill 104 | the needs of a minority (but still large number) of users. The goals of ee 105 | are: 106 | 107 | 1. To be so easy to use as to require no instruction. 108 | 2. To be easy to compile and, if necessary, port to new platforms 109 | by people with relatively little knowledge of C and UNIX. 110 | 3. To have a minimum number of files to be dealt with, for compile 111 | and installation. 112 | 4. To have enough functionality to be useful to a large number of 113 | people. 114 | 115 | Hugh Mahon |___| 116 | hugh4242@yahoo.com | | 117 | |\ /| 118 | | \/ | 119 | 120 | -------------------------------------------------------------------------------- /ee.msg: -------------------------------------------------------------------------------- 1 | $ This file contains the messages for ee ("easy editor"). See the file 2 | $ ee.i18n.guide for more information 3 | $ 4 | $ For ee patchlevel 3 5 | $ 6 | $ $Header: /home/hugh/sources/old_ae/RCS/ee.msg,v 1.8 1996/11/30 03:23:40 hugh Exp $ 7 | $ $FreeBSD$ 8 | $ 9 | $ 10 | $set 1 11 | $quote " 12 | 1 "modes menu" 13 | 2 "tabs to spaces " 14 | 3 "case sensitive search" 15 | 4 "margins observed " 16 | 5 "auto-paragraph format" 17 | 6 "eightbit characters " 18 | 7 "info window " 19 | 8 "right margin " 20 | 9 "leave menu" 21 | 10 "save changes" 22 | 11 "no save" 23 | 12 "file menu" 24 | 13 "read a file" 25 | 14 "write a file" 26 | 15 "save file" 27 | 16 "print editor contents" 28 | 17 "search menu" 29 | 18 "search for ..." 30 | 19 "search" 31 | 20 "spell menu" 32 | 21 "use 'spell'" 33 | 22 "use 'ispell'" 34 | 23 "miscellaneous menu" 35 | 24 "format paragraph" 36 | 25 "shell command" 37 | 26 "check spelling" 38 | 27 "main menu" 39 | 28 "leave editor" 40 | 29 "help" 41 | 30 "file operations" 42 | 31 "redraw screen" 43 | 32 "settings" 44 | 33 "search" 45 | 34 "miscellaneous" 46 | 35 "Control keys: " 47 | 36 "^a ascii code ^i tab ^r right " 48 | 37 "^b bottom of text ^j newline ^t top of text " 49 | 38 "^c command ^k delete char ^u up " 50 | 39 "^d down ^l left ^v undelete word " 51 | 40 "^e search prompt ^m newline ^w delete word " 52 | 41 "^f undelete char ^n next page ^x search " 53 | 42 "^g begin of line ^o end of line ^y delete line " 54 | 43 "^h backspace ^p prev page ^z undelete line " 55 | 44 "^[ (escape) menu " 56 | 45 " " 57 | 46 "Commands: " 58 | 47 "help : get this info file : print file name " 59 | 48 "read : read a file char : ascii code of char " 60 | 49 "write : write a file case : case sensitive search " 61 | 50 "exit : leave and save nocase : case insensitive search " 62 | 51 "quit : leave, no save !cmd : execute \"cmd\" in shell " 63 | 52 "line : display line # 0-9 : go to line \"#\" " 64 | 53 "expand : expand tabs noexpand: do not expand tabs " 65 | 54 " " 66 | 55 " ee [+#] [-i] [-e] [-h] [file(s)] " 67 | 56 "+# :go to line # -i :no info window -e : don't expand tabs -h :no highlight" 68 | 57 "^[ (escape) menu ^e search prompt ^y delete line ^u up ^p prev page " 69 | 58 "^a ascii code ^x search ^z undelete line ^d down ^n next page " 70 | 59 "^b bottom of text ^g begin of line ^w delete word ^l left " 71 | 60 "^t top of text ^o end of line ^v undelete word ^r right " 72 | 61 "^c command ^k delete char ^f undelete char " 73 | 62 "help : get help info |file : print file name |line : print line # " 74 | 63 "read : read a file |char : ascii code of char |0-9 : go to line \"#\"" 75 | 64 "write: write a file |case : case sensitive search |exit : leave and save " 76 | 65 "!cmd : shell \"cmd\" |nocase: ignore case in search |quit : leave, no save" 77 | 66 "expand: expand tabs |noexpand: do not expand tabs " 78 | 67 " press Escape (^[) for menu" 79 | 68 "no file" 80 | 69 "ascii code: " 81 | 70 "sending contents of buffer to \"%s\" " 82 | 71 "command: " 83 | 72 "name of file to write: " 84 | 73 "name of file to read: " 85 | 74 "character = %d" 86 | 75 "unknown command \"%s\"" 87 | 76 "entered command is not unique" 88 | 77 "line %d " 89 | 78 "length = %d" 90 | 79 "current file is \"%s\" " 91 | 80 "usage: %s [-i] [-e] [-h] [+line_number] [file(s)]\n" 92 | 81 " -i turn off info window\n" 93 | 82 " -e do not convert tabs to spaces\n" 94 | 83 " -h do not use highlighting\n" 95 | 84 "file \"%s\" is a directory" 96 | 85 "new file \"%s\"" 97 | 86 "can't open \"%s\"" 98 | 87 "file \"%s\", %d lines" 99 | 88 "finished reading file \"%s\"" 100 | 89 "reading file \"%s\"" 101 | 90 ", read only" 102 | 91 "file \"%s\", %d lines" 103 | 92 "enter name of file: " 104 | 93 "no filename entered: file not saved" 105 | 94 "changes have been made, are you sure? (y/n [n]) " 106 | 95 "y" 107 | 96 "file already exists, overwrite? (y/n) [n] " 108 | 97 "unable to create file \"%s\"" 109 | 98 "writing file \"%s\"" 110 | 99 "\"%s\" %d lines, %d characters" 111 | 100 " ...searching" 112 | 101 "string \"%s\" not found" 113 | 102 "search for: " 114 | 103 "could not exec %s\n" 115 | 104 "press return to continue " 116 | 105 "press Esc to cancel" 117 | 106 "menu too large for window" 118 | 107 "press any key to continue " 119 | 108 "shell command: " 120 | 109 "...formatting paragraph..." 121 | 110 " 43 | 44 | #ifdef SYS5 45 | #include 46 | #else 47 | #include 48 | #include 49 | #endif 50 | 51 | #define KEY_BREAK 0401 52 | #define KEY_DOWN 0402 53 | #define KEY_UP 0403 54 | #define KEY_LEFT 0404 55 | #define KEY_RIGHT 0405 56 | #define KEY_HOME 0406 57 | #define KEY_BACKSPACE 0407 58 | #define KEY_F0 0410 59 | #define KEY_F(n) (KEY_F0+(n)) 60 | #define KEY_DL 0510 61 | #define KEY_IL 0511 62 | #define KEY_DC 0512 63 | #define KEY_IC 0513 64 | #define KEY_EIC 0514 65 | #define KEY_CLEAR 0515 66 | #define KEY_EOS 0516 67 | #define KEY_EOL 0517 68 | #define KEY_SF 0520 69 | #define KEY_SR 0521 70 | #define KEY_NPAGE 0522 71 | #define KEY_PPAGE 0523 72 | #define KEY_STAB 0524 73 | #define KEY_CTAB 0525 74 | #define KEY_CATAB 0526 75 | #define KEY_ENTER 0527 76 | #define KEY_SRESET 0530 77 | #define KEY_RESET 0531 78 | #define KEY_PRINT 0532 79 | #define KEY_LL 0533 80 | #define KEY_A1 0534 81 | #define KEY_A3 0535 82 | #define KEY_B2 0536 83 | #define KEY_C1 0537 84 | #define KEY_C3 0540 85 | #define KEY_BTAB 0541 86 | #define KEY_BEG 0542 87 | #define KEY_CANCEL 0543 88 | #define KEY_CLOSE 0544 89 | #define KEY_COMMAND 0545 90 | #define KEY_COPY 0546 91 | #define KEY_CREATE 0547 92 | #define KEY_END 0550 93 | #define KEY_EXIT 0551 94 | #define KEY_FIND 0552 95 | #define KEY_HELP 0553 96 | #define KEY_MARK 0554 97 | #define KEY_MESSAGE 0555 98 | #define KEY_MOVE 0556 99 | #define KEY_NEXT 0557 100 | #define KEY_OPEN 0560 101 | #define KEY_OPTIONS 0561 102 | #define KEY_PREVIOUS 0562 103 | #define KEY_REDO 0563 104 | #define KEY_REFERENCE 0564 105 | #define KEY_REFRESH 0565 106 | #define KEY_REPLACE 0566 107 | #define KEY_RESTART 0567 108 | #define KEY_RESUME 0570 109 | #define KEY_SAVE 0571 110 | #define KEY_SBEG 0572 111 | #define KEY_SCANCEL 0573 112 | #define KEY_SCOMMAND 0574 113 | #define KEY_SCOPY 0575 114 | #define KEY_SCREATE 0576 115 | #define KEY_SDC 0577 116 | #define KEY_SDL 0600 117 | #define KEY_SELECT 0601 118 | #define KEY_SEND 0602 119 | #define KEY_SEOL 0603 120 | #define KEY_SEXIT 0604 121 | #define KEY_SFIND 0605 122 | #define KEY_SHELP 0606 123 | #define KEY_SHOME 0607 124 | #define KEY_SIC 0610 125 | #define KEY_SLEFT 0611 126 | #define KEY_SMESSAGE 0612 127 | #define KEY_SMOVE 0613 128 | #define KEY_SNEXT 0614 129 | #define KEY_SOPTIONS 0615 130 | #define KEY_SPREVIOUS 0616 131 | #define KEY_SPRINT 0617 132 | #define KEY_SREDO 0620 133 | #define KEY_SREPLACE 0621 134 | #define KEY_SRIGHT 0622 135 | #define KEY_SRSUME 0623 136 | #define KEY_SSAVE 0624 137 | #define KEY_SSUSPEND 0625 138 | #define KEY_SUNDO 0626 139 | #define KEY_SUSPEND 0627 140 | #define KEY_UNDO 0630 141 | 142 | #define TRUE 1 143 | #define FALSE 0 144 | 145 | #define A_STANDOUT 0001 /* standout mode */ 146 | #define A_NC_BIG5 0x0100 /* Handle Chinese Big5 characters */ 147 | #define SCROLL 1 /* text has been scrolled */ 148 | #define CLEAR 2 /* window has been cleared */ 149 | #define CHANGE 3 /* window has been changed */ 150 | #define UP 1 /* direction of scroll */ 151 | #define DOWN 2 152 | 153 | struct _line { 154 | struct _line *next_screen; 155 | struct _line *prev_screen; 156 | char *row; 157 | char *attributes; 158 | int last_char; 159 | int changed; 160 | int scroll; 161 | int number; 162 | }; 163 | 164 | struct _line *top_of_win; 165 | 166 | typedef struct WIND { 167 | int SR; /* starting row */ 168 | int SC; /* starting column */ 169 | int LC; /* last column */ 170 | int LX; /* last cursor column position */ 171 | int LY; /* last cursor row position */ 172 | int Attrib; /* attributes active in window */ 173 | int Num_lines; /* number of lines */ 174 | int Num_cols; /* number of columns */ 175 | int scroll_up; /* number of lines moved */ 176 | int scroll_down; 177 | int SCROLL_CLEAR; /* indicates that window has been scrolled or cleared */ 178 | struct _line *first_line; 179 | struct _line **line_array; 180 | } WINDOW; 181 | 182 | extern WINDOW *curscr; 183 | extern WINDOW *stdscr; 184 | 185 | extern int LINES, COLS; 186 | 187 | #if defined(__STDC__) || defined(__cplusplus) 188 | #define P_(s) s 189 | #else 190 | #define P_(s) () 191 | #endif 192 | 193 | extern void copy_window P_((WINDOW *origin, WINDOW *destination)); 194 | extern void reinitscr P_((int)); 195 | extern void initscr P_((void)); 196 | extern int Get_int P_((void)); 197 | extern int INFO_PARSE P_((void)); 198 | extern int AtoI P_((void)); 199 | extern void Key_Get P_((void)); 200 | extern void keys_vt100 P_((void)); 201 | extern struct _line *Screenalloc P_((int columns)); 202 | extern WINDOW *newwin P_((int lines, int cols, int start_l, int start_c)); 203 | extern int Operation P_((int Temp_Stack[], int place)); 204 | extern void Info_Out P_((char *string, int p_list[], int place)); 205 | extern void wmove P_((WINDOW *window, int row, int column)); 206 | extern void clear_line P_((struct _line *line, int column, int cols)); 207 | extern void werase P_((WINDOW *window)); 208 | extern void wclrtoeol P_((WINDOW *window)); 209 | extern void wrefresh P_((WINDOW *window)); 210 | extern void touchwin P_((WINDOW *window)); 211 | extern void wnoutrefresh P_((WINDOW *window)); 212 | extern void flushinp P_((void)); 213 | extern void ungetch P_((int c)); 214 | extern int wgetch P_((WINDOW *window)); 215 | extern void Clear P_((int)); 216 | extern int Get_key P_((int first_char)); 217 | extern void waddch P_((WINDOW *window, int c)); 218 | extern void winsertln P_((WINDOW *window)); 219 | extern void wdeleteln P_((WINDOW *window)); 220 | extern void wclrtobot P_((WINDOW *window)); 221 | extern void wstandout P_((WINDOW *window)); 222 | extern void wstandend P_((WINDOW *window)); 223 | extern void waddstr P_((WINDOW *window, char *string)); 224 | extern void clearok P_((WINDOW *window, int flag)); 225 | extern void echo P_((void)); 226 | extern void noecho P_((void)); 227 | extern void raw P_((void)); 228 | extern void noraw P_((void)); 229 | extern void nl P_((void)); 230 | extern void nonl P_((void)); 231 | extern void saveterm P_((void)); 232 | extern void fixterm P_((void)); 233 | extern void resetterm P_((void)); 234 | extern void nodelay P_((WINDOW *window, int flag)); 235 | extern void idlok P_((WINDOW *window, int flag)); 236 | extern void keypad P_((WINDOW *window, int flag)); 237 | extern void savetty P_((void)); 238 | extern void resetty P_((void)); 239 | extern void endwin P_((void)); 240 | extern void delwin P_((WINDOW *window)); 241 | extern void wprintw P_((WINDOW *window, const char* format, ...)); 242 | extern void iout P_((WINDOW *window, int value)); 243 | extern int Comp_line P_((struct _line *line1, struct _line *line2)); 244 | extern struct _line *Insert_line P_((int row, int end_row, WINDOW *window)); 245 | extern struct _line *Delete_line P_((int row, int end_row, WINDOW *window)); 246 | extern void CLEAR_TO_EOL P_((WINDOW *window, int row, int column)); 247 | extern int check_delete P_((WINDOW *window, int line, int offset, struct _line *pointer_new, struct _line *pointer_old)); 248 | extern int check_insert P_((WINDOW *window, int line, int offset, struct _line *pointer_new, struct _line *pointer_old)); 249 | extern void doupdate P_((void)); 250 | extern void Position P_((WINDOW *window, int row, int col)); 251 | extern void Char_del P_((char *line, char *attrib, int offset, int maxlen)); 252 | extern void Char_ins P_((char *line, char *attrib, int newc, int newatt, int offset, int maxlen)); 253 | extern void attribute_on P_((void)); 254 | extern void attribute_off P_((void)); 255 | extern void Char_out P_((int newc, int newatt, char *line, char *attrib, int offset)); 256 | 257 | extern void nc_setattrib P_((int)); 258 | extern void nc_clearattrib P_((int)); 259 | #undef P_ 260 | 261 | -------------------------------------------------------------------------------- /ee.1: -------------------------------------------------------------------------------- 1 | .\" 2 | .\" 3 | .\" To format this reference page, use the command: 4 | .\" 5 | .\" nroff -man ee.1 6 | .\" 7 | .\" $Header: /home/hugh/sources/old_ae/RCS/ee.1,v 1.22 2001/12/16 04:49:27 hugh Exp $ 8 | .\" 9 | .\" 10 | .TH ee 1 "" "" "" 11 | .SH NAME 12 | ee \- easy editor 13 | .SH SYNOPSIS 14 | .nf 15 | ee [-e] [-i] [-h] [+#] [\fIfile\fR ...] 16 | ree [-e] [-i] [-h] [+#] [\fIfile\fR ...] 17 | .ta 18 | .fi 19 | .ad b 20 | .SH DESCRIPTION 21 | The command 22 | .I ee 23 | is a simple screen oriented text editor. It is always in text insertion 24 | mode unless there is a prompt at the bottom of the terminal, or a 25 | menu present (in a box in the middle of the terminal). The command 26 | .I ree 27 | is the same as 28 | .I ee, 29 | but restricted to editing the named 30 | file (no file operations, or shell escapes are allowed). 31 | .PP 32 | An editor with similar user-friendly qualities but more features is available 33 | and is called 34 | .I aee. 35 | .PP 36 | For 37 | .I ee 38 | to work properly, the environment variable 39 | .SM TERM 40 | must be set to indicate the type of terminal being used. For 41 | example, for an 42 | .SM HP 700/92 43 | terminal, the 44 | .SM TERM 45 | variable should be set to "70092". See your System Administrator if 46 | you need more information. 47 | .\" 48 | .\" options 49 | .\" 50 | .SS Options 51 | The following options are available from the command line: 52 | .PP 53 | .TP 4 54 | .B -e 55 | Turns off expansion of tab character to spaces. 56 | .TP 57 | .B -i 58 | Turns off display of information window at top of terminal. 59 | .TP 60 | .B -h 61 | Turns off highlighting of borders of windows and menus (improves 62 | performance on some terminals). 63 | .TP 64 | .B +# 65 | Moves the cursor to line '#' at startup. 66 | .br 67 | .\" 68 | .\" control keys 69 | .\" 70 | .SS "Control keys" 71 | To do anything other than insert text, the user must use the control 72 | keys (the 73 | .B Control 74 | key, represented by a "^", pressed in conjunction with an 75 | alphabetic key, e.g., ^a) and function keys available on the keyboard 76 | (such as 77 | .BR "Next Page" ", " "Prev Page" , 78 | arrow keys, etc.). 79 | .PP 80 | Since not all terminals have function keys, 81 | .I ee 82 | has the basic cursor movement functions assigned to control keys as 83 | well as more intuitive keys on the keyboard when available. For 84 | instance, to move the cursor up, the user can use the up arrow key, 85 | or 86 | .BR ^u . 87 | .RS 4 88 | .nf 89 | .ta 1.4i 90 | .sp 91 | ^a Prompt for the decimal value of a character to insert. 92 | ^b Move to the bottom of the text. 93 | ^c Get the prompt for a command. 94 | ^d Move the cursor down. 95 | ^e Prompt for the string to search for. 96 | ^f Undelete the last deleted character. 97 | ^g Move to the beginning of the line. 98 | ^h Backspace. 99 | ^i Tab. 100 | ^j Insert a newline. 101 | ^k Delete the character the cursor is sitting on. 102 | ^l Move the cursor left. 103 | ^m Insert a newline. 104 | ^n Move to the next page. 105 | ^o Move to the end of the line. 106 | ^p Move to the previous page. 107 | ^r Move the cursor to the right. 108 | ^t Move to the top of the text. 109 | ^u Move the cursor up. 110 | ^v Undelete the last deleted word. 111 | ^w Delete the word beginning at the cursor position. 112 | ^x Search. 113 | ^y Delete from the cursor position to the end of line. 114 | ^z Undelete the last deleted line. 115 | ^[ (ESC) Pop up menu. 116 | .ta 117 | .fi 118 | .RE 119 | .sp 120 | .SS "EMACS keys mode" 121 | .PP 122 | Since many shells provide an Emacs mode (for cursor movement and other editing 123 | operations), some bindings that may be more useful for people familiar with 124 | those bindings have been provided. These are accessible via the 125 | .B settings 126 | menu, or via the initialization file (see below). The mappings are as follows: 127 | .RS 128 | .nf 129 | .ta 1.4i 130 | ^a Move to the beginning of the line. 131 | ^b Back 1 character. 132 | ^c Command prompt. 133 | ^d Delete character the cursor is sitting on. 134 | ^e End of line. 135 | ^f Forward 1 character. 136 | ^g Go back 1 page. 137 | ^h Backspace. 138 | ^i Tab. 139 | ^j Undelete last deleted character. 140 | ^k Delete line. 141 | ^l Undelete last deleted line. 142 | ^m Insert a newline. 143 | ^n Move to the next line. 144 | ^o Prompt for the decimal value of a character to insert. 145 | ^p Previous line. 146 | ^r Restore last deleted word. 147 | ^t Move to the top of the text. 148 | ^u Move to the bottom of the text. 149 | ^v Move to the next page. 150 | ^w Delete the word beginning at the cursor position. 151 | ^y Prompt for the string to search for. 152 | ^z Next word. 153 | ^[ (ESC) Pop up menu. 154 | .ta 155 | .fi 156 | .RE 157 | .sp 158 | .\" 159 | .\" function keys 160 | .\" 161 | .SS "Function Keys" 162 | .RS 4 163 | .IP "\fBNext Page\fR" 164 | Move to the next page. 165 | .IP "\fBPrev Page\fR" 166 | Move to the previous page. 167 | .IP "\fBDelete Char\fR" 168 | Delete the character the cursor is on. 169 | .IP "\fBDelete Line\fR" 170 | Delete from the cursor to the end of line. 171 | .IP "\fBInsert line\fR" 172 | Insert a newline at the cursor position. 173 | .IP "\fBArrow keys\fR" 174 | Move the cursor in the direction indicated. 175 | .RE 176 | .\" 177 | .\" commands 178 | .\" 179 | .SS Commands 180 | .PP 181 | Some operations require more information than a single keystroke can 182 | provide. For the most basic operations, there is a menu that can be 183 | obtained by pressing the 184 | .SM \fBESC\fR 185 | key. The same operations, and more can be performed by obtaining the 186 | command prompt (^c) and typing in one of the commands below. 187 | .RS 4 188 | .IP "!\fBcmd\fR" 189 | Execute \fBcmd\fR in a shell. 190 | .IP "\fB0-9\fR" 191 | Move to the line indicated. 192 | .IP "\fBcase\fR" 193 | Make searches case sensitive. 194 | .IP "\fBcharacter\fR" 195 | Display the ascii value of the character at the cursor. 196 | .IP "\fBexit\fR" 197 | Save the edited text, and leave the editor. 198 | .IP "\fBexpand\fR" 199 | Expand tabs to spaces. 200 | .IP "\fBfile\fR" 201 | Print the name of the file. 202 | .IP "\fBhelp\fR" 203 | Display help screen. 204 | .IP "\fBline\fR" 205 | Display the current line number. 206 | .IP "\fBnocase\fR 207 | Make searches insensitive to case (the default). 208 | .IP "\fBnoexpand\fR" 209 | Don't expand tab to spaces when the TAB key is pressed. 210 | .IP "\fBquit\fR" 211 | Leave the editor without saving changes. 212 | .IP "\fBread\fR \fIfile\fR" 213 | Read the named \fIfile\fR. 214 | .IP "\fBwrite\fR \fIfile\fR" 215 | Write the text to the named \fIfile\fR. 216 | .RE 217 | .\" 218 | .\" menu operations 219 | .\" 220 | .SS "Menu Operations" 221 | .PP 222 | Pop-up menus can be obtained by pressing the 223 | .B escape 224 | key (or 225 | .B ^[ 226 | if no 227 | .B escape 228 | key is present). When in the menu, the escape key can be 229 | used to leave the menu without performing any operations. Use the up and 230 | down arrow keys, or 231 | .B ^u 232 | for moving up and 233 | .B ^d 234 | for moving down to move to the desired items in the menu, then press 235 | .B return 236 | to perform the indicated task. 237 | .PP 238 | To the left of each menu item is a letter, which if the corresponding 239 | letter is pressed on the keyboard selects that menu entry. 240 | .PP 241 | The main menu in \fIee\fR is as follows: 242 | .RS 4 243 | .IP "\fBleave editor\fR" 244 | If changes have been made, the user will get a menu prompting whether or 245 | not the changes should be saved. 246 | .IP "\fBhelp\fR" 247 | Displays a help screen, with all of the keyboard operations and commands. 248 | .IP "\fBfile operations\fR" 249 | Pops up a menu for selecting whether to read a file, write to a file, or 250 | save the current contents of the editor, as well as send the contents of 251 | the editor to a print command (see the section \fBInitializing ee from a 252 | file\fR). 253 | .IP "\fBredraw screen\fR" 254 | Provides a means to repaint the screen if the screen has been corrupted. 255 | .IP "\fBsettings\fR" 256 | Shows the current values of the operating modes, and right margin. By 257 | pressing return when the cursor is on a particular item, the value can be 258 | changed. To leave this menu, press the \fBescape\fR key. (See \fBModes\fR 259 | below.) 260 | .IP "\fBsearch\fR" 261 | .br 262 | Pops up a menu in which the user may choose to enter a string to search 263 | for, or search for a string already entered. 264 | .IP "\fBmiscellaneous\fR" 265 | Pops up a menu that allows the user to format the current paragraph, 266 | execute a shell command, or check the spelling of the text in the editor. 267 | .RE 268 | .\" 269 | .\" paragraph formatting 270 | .\" 271 | .SS "Paragraph Formatting" 272 | .PP 273 | Paragraphs are defined for \fIee\fR by a block of text bounded by: 274 | .sp 275 | .RS 8 276 | .IP \(bu 277 | Begin or end of file. 278 | .IP \(bu 279 | Line with no characters, or only spaces and/or tabs. 280 | .IP \(bu 281 | Line starting with a period ('.') or right angle bracket ('>'). 282 | .RE 283 | .PP 284 | A paragraph may be formatted two ways: explicitly by choosing the 285 | \fBformat paragraph\fR menu item, or by setting \fIee\fR to automatically 286 | format paragraphs. The automatic mode may be set via a menu, or via the 287 | initialization file. 288 | .PP 289 | There are three states for text operation in \fIee\fR: free-form, margins, 290 | and automatic formatting. 291 | .PP 292 | "Free-form" is best used for things like programming. There are no 293 | restrictions on the length of lines, and no formatting takes place. 294 | .PP 295 | "Margins" allows the user to type in text without having to worry about going 296 | beyond the right margin (the right margin may be set in the \fBsettings\fR 297 | menu, the default is for the margin to be the right edge of the 298 | terminal). This is the mode that allows the \fBformat paragraph\fR menu 299 | item to work. 300 | .PP 301 | "Automatic formatting" provides word-processor-like behavior. The user 302 | may type in text, while \fIee\fR will make sure the entire paragraph fits 303 | within the width of the terminal every time the user inserts a space after 304 | typing or deleting text. Margin observation must also be enabled in order for 305 | automatic formatting to occur. 306 | .\" 307 | .\" modes 308 | .\" 309 | .SS Modes 310 | .PP 311 | Although ee is a 'modeless' editor (it is in text insertion mode all the 312 | time), there are modes in some of the things it does. These include: 313 | .RS 4 314 | .IP "\fBtab expansion\fR" 315 | Tabs may be inserted as a single tab character, or replaced with spaces. 316 | .IP "\fBcase sensitivity\fR" 317 | The search operation can be sensitive to whether characters are upper- or 318 | lower-case, or ignore case completely. 319 | .IP "\fBmargins observed\fR" 320 | Lines can either be truncated at the right margin, or extend on forever. 321 | .IP "\fBauto paragraph formatting\fR" 322 | While typing in text, the editor can try to keep it looking reasonably well 323 | within the width of the screen. 324 | .IP "\fBeightbit characters\fR" 325 | Toggles whether eight bit characters are displayed as their value in angle 326 | brackets (e.g. "<220>") or as a character. 327 | .IP "\fBinfo window\fR" 328 | A window showing the keyboard operations that can be performed can be 329 | displayed or not. 330 | .IP "\fBemacs keys\fR" 331 | Control keys may be given bindings similar to emacs, or not. 332 | .IP "\fB16 bit characters\fR" 333 | Toggles whether sixteen bit characters are handled as one 16-bit quantity or 334 | two 8-bit quantities. This works primarily with the Chinese Big 5 code set. 335 | .RE 336 | .PP 337 | You may set these modes via the initialization file (see below), or with a 338 | menu (see above). 339 | .\" 340 | .\" spell checking 341 | .\" 342 | .SS "Spell Checking" 343 | .PP 344 | There are two ways to have the spelling in the text checked from \fIee\fR. 345 | One is by the traditional \fIspell\fR(1) command, the other is with the 346 | optional \fIispell\fR(1) command. 347 | .PP 348 | Using \fIspell\fR, the words that are not recognized will be placed at the top 349 | of the file. For the \fIispell\fR option, the file is written to disk, 350 | then \fIispell\fR run on the file, and the file read back in once 351 | \fIispell\fR has completed making changes to the file. 352 | .\" 353 | .\" printing 354 | .\" 355 | .SS "Printing the contents of the editor" 356 | .PP 357 | The user may select a menu item which prints the contents of the editor. 358 | .I ee 359 | pipes the text in the editor to the command specified by the 360 | initialization command 361 | .B printcommand 362 | (see the section 363 | .B Initializing ee from a file 364 | below). The default is to send the contents to "lp". 365 | .PP 366 | Whatever the user assigns to 367 | .B printcommand 368 | must take input from 369 | standard input. See your system administrator for more details. 370 | .\" 371 | .\" shell operations 372 | .\" 373 | .SS "Shell operations" 374 | .PP 375 | Shell commands can be executed from within 376 | .I ee 377 | by selecting the 378 | .B shell command 379 | item in the 380 | .B miscellaneous 381 | menu, or by placing an exclamation mark ("!") before the command to 382 | execute at the 383 | .B command: 384 | prompt. Additionally, the user may direct the contents of the edit buffer 385 | out to a shell operation (via a pipe) by using the left angle bracket 386 | (">"), followed by a "!" and the shell command to execute. The output of 387 | a shell operation can also be directed into the edit buffer by using a 388 | right angle bracket ("<") before the exclamation mark. These can even be 389 | used together to send output to a shell operation and read back the 390 | results into the editor. So, if the editor contained a list of words 391 | to be sorted, they could be sorted by typing the following at the command 392 | prompt: 393 | .RS 4 394 | .sp 395 | >"). 462 | .IP \fB16bit\fR 463 | Turns on handling of 16-bit characters. 464 | .IP \fBno16bit\fR 465 | Turns off handling of 16-bit characters. 466 | .IP \fBemacs\fR 467 | Turns on emacs key bindings. 468 | .IP \fBnoemacs\fR 469 | Turns off emacs key bindings. 470 | .RE 471 | .\" 472 | .\" save editor configuration 473 | .\" 474 | .SS "Save Editor Configuration" 475 | .PP 476 | When using this entry from the 477 | .B settings 478 | menu, the user may choose to save the current configuration of 479 | the editor (see \fBInitializing ee from a 480 | file\fR above) to a file named 481 | .I .init.ee 482 | in the current directory or the user's home directory. If a file named 483 | .I .init.ee 484 | already exists, it will be renamed 485 | .IR .init.ee.old . 486 | .\" 487 | .\" Caveats 488 | .\" 489 | .SH CAVEATS 490 | .PP 491 | THIS MATERIAL IS PROVIDED "AS IS". THERE ARE 492 | NO WARRANTIES OF ANY KIND WITH REGARD TO THIS 493 | MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE 494 | IMPLIED WARRANTIES OF MERCHANTABILITY AND 495 | FITNESS FOR A PARTICULAR PURPOSE. Neither 496 | Hewlett-Packard nor Hugh Mahon shall be liable 497 | for errors contained herein, nor for 498 | incidental or consequential damages in 499 | connection with the furnishing, performance or 500 | use of this material. Neither Hewlett-Packard 501 | nor Hugh Mahon assumes any responsibility for 502 | the use or reliability of this software or 503 | documentation. This software and 504 | documentation is totally UNSUPPORTED. There 505 | is no support contract available. Hewlett-Packard 506 | has done NO Quality Assurance on ANY 507 | of the program or documentation. You may find 508 | the quality of the materials inferior to 509 | supported materials. 510 | .PP 511 | Always make a copy of files that cannot be easily reproduced before 512 | editing. Save files early, and save often. 513 | .SS "International Code Set Support" 514 | .I ee 515 | supports single-byte character code sets (eight-bit clean), or the 516 | Chinese Big-5 code set. (Other multi-byte code sets may function, but the 517 | reason Big-5 works is that a two-byte character also takes up two columns on 518 | the screen.) 519 | .SH WARNINGS 520 | The automatic paragraph formatting operation 521 | may be too slow for slower systems. 522 | .SH FILES 523 | .PP 524 | .I /usr/share/misc/init.ee 525 | .br 526 | .I $HOME/.init.ee 527 | .br 528 | .I .init.ee 529 | .SH AUTHOR 530 | .PP 531 | The software 532 | .I ee 533 | was developed by Hugh Mahon. 534 | .PP 535 | This software and documentation contains 536 | proprietary information which is protected by 537 | copyright. All rights are reserved. 538 | .PP 539 | Copyright (c) 1990, 1991, 1992, 1993, 1995, 1996, 2001 Hugh Mahon. 540 | .SH "SEE ALSO" 541 | .PP 542 | termcap(4), terminfo(4), environ(5), spell(1), ispell(1), lp(1), aee(1) 543 | 544 | -------------------------------------------------------------------------------- /new_curse.c: -------------------------------------------------------------------------------- 1 | /* 2 | | new_curse.c 3 | | 4 | | A subset of curses developed for use with ae. 5 | | 6 | | written by Hugh Mahon 7 | | 8 | | Copyright (c) 1986, 1987, 1988, 1991, 1992, 1993, 1994, 1995, 2009 Hugh Mahon 9 | | All rights reserved. 10 | | 11 | | Redistribution and use in source and binary forms, with or without 12 | | modification, are permitted provided that the following conditions 13 | | are met: 14 | | 15 | | * Redistributions of source code must retain the above copyright 16 | | notice, this list of conditions and the following disclaimer. 17 | | * Redistributions in binary form must reproduce the above 18 | | copyright notice, this list of conditions and the following 19 | | disclaimer in the documentation and/or other materials provided 20 | | with the distribution. 21 | | 22 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 | | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 | | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25 | | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26 | | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27 | | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 | | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32 | | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 | | POSSIBILITY OF SUCH DAMAGE. 34 | | 35 | | 36 | | All are rights reserved. 37 | | 38 | | $Header: /home/hugh/sources/old_ae/RCS/new_curse.c,v 1.54 2002/09/21 00:47:14 hugh Exp $ 39 | | 40 | */ 41 | 42 | char *copyright_message[] = { "Copyright (c) 1986, 1987, 1988, 1991, 1992, 1993, 1994, 1995, 2009 Hugh Mahon", 43 | "All rights are reserved."}; 44 | 45 | char * new_curse_name= "@(#) new_curse.c $Revision: 1.54 $"; 46 | 47 | #include "new_curse.h" 48 | #include 49 | #include 50 | 51 | #ifdef SYS5 52 | #include 53 | #else 54 | #include 55 | #endif 56 | 57 | #ifdef BSD_SELECT 58 | #include 59 | #include 60 | 61 | #ifdef SLCT_HDR 62 | #include /* on AIX */ 63 | #endif /* SLCT_HDR */ 64 | 65 | #endif /* BSD_SELECT */ 66 | 67 | #ifdef HAS_STDLIB 68 | #include 69 | #endif 70 | 71 | #if defined(__STDC__) 72 | #include 73 | #else 74 | #include 75 | #endif 76 | 77 | #ifdef HAS_UNISTD 78 | #include 79 | #endif 80 | 81 | #ifdef HAS_SYS_IOCTL 82 | #include 83 | #endif 84 | 85 | 86 | WINDOW *curscr; 87 | static WINDOW *virtual_scr; 88 | WINDOW *stdscr; 89 | WINDOW *last_window_refreshed; 90 | 91 | #ifdef TIOCGWINSZ 92 | struct winsize ws; 93 | #endif 94 | 95 | #define min(a, b) (a < b ? a : b) 96 | #define highbitset(a) ((a) & 0x80) 97 | 98 | #ifndef CAP 99 | #define String_Out(table, stack, place) Info_Out(table, stack, place) 100 | #else 101 | #define String_Out(table, stack, place) Cap_Out(table, stack, place) 102 | #endif 103 | 104 | #define bw__ 0 /* booleans */ 105 | #define am__ 1 106 | #define xb__ 2 107 | #define xs__ 3 /* hp glitch (standout not erased by overwrite) */ 108 | #define xn__ 4 109 | #define eo__ 5 110 | #define gn__ 6 /* generic type terminal */ 111 | #define hc__ 7 /* hardcopy terminal */ 112 | #define km__ 8 113 | #define hs__ 9 114 | #define in__ 10 115 | #define da__ 11 116 | #define db__ 12 117 | #define mi__ 13 /* safe to move during insert mode */ 118 | #define ms__ 14 /* safe to move during standout mode */ 119 | #define os__ 15 120 | #define es__ 16 121 | #define xt__ 17 122 | #define hz__ 18 /* hazeltine glitch */ 123 | #define ul__ 19 124 | #define xo__ 20 125 | #define chts__ 21 126 | #define nxon__ 22 127 | #define nrrmc__ 23 128 | #define npc__ 24 129 | #define mc5i__ 25 130 | 131 | #define co__ 0 /* number of columns */ /* numbers */ 132 | #define it__ 1 /* spaces per tab */ 133 | #define li__ 2 /* number of lines */ 134 | #define lm__ 3 135 | #define sg__ 4 /* magic cookie glitch */ 136 | #define pb__ 5 137 | #define vt__ 6 138 | #define ws__ 7 139 | 140 | #define cols__ 0 141 | #define lines__ 2 142 | #define xmc__ 4 143 | #define vt__ 6 144 | #define wsl__ 7 145 | #define nlab__ 8 146 | #define lh__ 9 147 | #define lw__ 10 148 | 149 | #define bt__ 0 /* back tab */ /* strings */ 150 | #define bl__ 1 /* bell */ 151 | #define cr__ 2 /* carriage return */ 152 | #define cs__ 3 /* change scroll region */ 153 | #define ct__ 4 /* clear all tab stops */ 154 | #define cl__ 5 /* clear screen and home cursor */ 155 | #define ce__ 6 /* clear to end of line */ 156 | #define cd__ 7 /* clear to end of display */ 157 | #define ch__ 8 /* set cursor column */ 158 | #define CC__ 9 /* term, settable cmd char in */ 159 | #define cm__ 10 /* screen rel cursor motion, row, column */ 160 | #define do__ 11 /* down one line */ 161 | #define ho__ 12 /* home cursor */ 162 | #define vi__ 13 /* make cursor invisible */ 163 | #define le__ 14 /* move cursor left one space */ 164 | #define CM__ 15 /* memory rel cursor addressing */ 165 | #define ve__ 16 /* make cursor appear normal */ 166 | #define nd__ 17 /* non-destructive space (cursor right) */ 167 | #define ll__ 18 /* last line, first col */ 168 | #define up__ 19 /* cursor up */ 169 | #define vs__ 20 170 | #define dc__ 21 /* delete character */ 171 | #define dl__ 22 /* delete line */ 172 | #define ds__ 23 173 | #define hd__ 24 174 | #define as__ 25 175 | #define mb__ 26 176 | #define md__ 27 /* turn on bold */ 177 | #define ti__ 28 178 | #define dm__ 29 /* turn on delete mode */ 179 | #define mh__ 30 /* half bright mode */ 180 | #define im__ 31 /* insert mode */ 181 | #define mk__ 32 182 | #define mp__ 33 183 | #define mr__ 34 184 | #define so__ 35 /* enter standout mode */ 185 | #define us__ 36 186 | #define ec__ 37 187 | #define ae__ 38 188 | #define me__ 39 189 | #define te__ 40 190 | #define ed__ 41 191 | #define ei__ 42 /* exit insert mode */ 192 | #define se__ 43 /* exit standout mode */ 193 | #define ue__ 44 194 | #define vb__ 45 195 | #define ff__ 46 196 | #define fs__ 47 197 | #define i1__ 48 198 | #define i2__ 49 199 | #define i3__ 50 200 | #define if__ 51 201 | #define ic__ 52 202 | #define al__ 53 203 | #define ip__ 54 204 | #define kb__ 55 /* backspace key */ 205 | #define ka__ 56 206 | #define kC__ 57 207 | #define kt__ 58 208 | #define kD__ 59 209 | #define kL__ 60 210 | #define kd__ 61 211 | #define kM__ 62 212 | #define kE__ 63 213 | #define kS__ 64 214 | #define k0__ 65 215 | #define k1__ 66 216 | #define kf10__ 67 217 | #define k2__ 68 218 | #define k3__ 69 219 | #define k4__ 70 220 | #define k5__ 71 221 | #define k6__ 72 222 | #define k7__ 73 223 | #define k8__ 74 224 | #define k9__ 75 225 | #define kh__ 76 226 | #define kI__ 77 227 | #define kA__ 78 228 | #define kl__ 79 229 | #define kH__ 80 230 | #define kN__ 81 231 | #define kP__ 82 232 | #define kr__ 83 233 | #define kF__ 84 234 | #define kR__ 85 235 | #define kT__ 86 236 | #define ku__ 87 /* key up */ 237 | #define ke__ 88 238 | #define ks__ 89 239 | #define l0__ 90 240 | #define l1__ 91 241 | #define la__ 92 242 | #define l2__ 93 243 | #define l3__ 94 244 | #define l4__ 95 245 | #define l5__ 96 246 | #define l6__ 97 247 | #define l7__ 98 248 | #define l8__ 99 249 | #define l9__ 100 250 | #define mo__ 101 251 | #define mm__ 102 252 | #define nw__ 103 253 | #define pc__ 104 254 | #define DC__ 105 255 | #define DL__ 106 256 | #define DO__ 107 257 | #define IC__ 118 258 | #define SF__ 109 259 | #define AL__ 110 260 | #define LE__ 111 261 | #define RI__ 112 262 | #define SR__ 113 263 | #define UP__ 114 264 | #define pk__ 115 265 | #define pl__ 116 266 | #define px__ 117 267 | #define ps__ 118 268 | #define pf__ 119 269 | #define po__ 120 270 | #define rp__ 121 271 | #define r1__ 122 272 | #define r2__ 123 273 | #define r3__ 124 274 | #define rf__ 125 275 | #define rc__ 126 276 | #define cv__ 127 277 | #define sc__ 128 278 | #define sf__ 129 279 | #define sr__ 130 280 | #define sa__ 131 /* sgr */ 281 | #define st__ 132 282 | #define wi__ 133 283 | #define ta__ 134 284 | #define ts__ 135 285 | #define uc__ 136 286 | #define hu__ 137 287 | #define iP__ 138 288 | #define K1__ 139 289 | #define K2__ 140 290 | #define K3__ 141 291 | #define K4__ 142 292 | #define K5__ 143 293 | #define pO__ 144 294 | #define ml__ 145 295 | #define mu__ 146 296 | #define rmp__ 145 297 | #define acsc__ 146 298 | #define pln__ 147 299 | #define kcbt__ 148 300 | #define smxon__ 149 301 | #define rmxon__ 150 302 | #define smam__ 151 303 | #define rmam__ 152 304 | #define xonc__ 153 305 | #define xoffc__ 154 306 | #define enacs__ 155 307 | #define smln__ 156 308 | #define rmln__ 157 309 | #define kbeg__ 158 310 | #define kcan__ 159 311 | #define kclo__ 160 312 | #define kcmd__ 161 313 | #define kcpy__ 162 314 | #define kcrt__ 163 315 | #define kend__ 164 316 | #define kent__ 165 317 | #define kext__ 166 318 | #define kfnd__ 167 319 | #define khlp__ 168 320 | #define kmrk__ 169 321 | #define kmsg__ 170 322 | #define kmov__ 171 323 | #define knxt__ 172 324 | #define kopn__ 173 325 | #define kopt__ 174 326 | #define kprv__ 175 327 | #define kprt__ 176 328 | #define krdo__ 177 329 | #define kref__ 178 330 | #define krfr__ 179 331 | #define krpl__ 180 332 | #define krst__ 181 333 | #define kres__ 182 334 | #define ksav__ 183 335 | #define kspd__ 184 336 | #define kund__ 185 337 | #define kBEG__ 186 338 | #define kCAN__ 187 339 | #define kCMD__ 188 340 | #define kCPY__ 189 341 | #define kCRT__ 190 342 | #define kDC__ 191 343 | #define kDL__ 192 344 | #define kslt__ 193 345 | #define kEND__ 194 346 | #define kEOL__ 195 347 | #define kEXT__ 196 348 | #define kFND__ 197 349 | #define kHLP__ 198 350 | #define kHOM__ 199 351 | #define kIC__ 200 352 | #define kLFT__ 201 353 | #define kMSG__ 202 354 | #define kMOV__ 203 355 | #define kNXT__ 204 356 | #define kOPT__ 205 357 | #define kPRV__ 206 358 | #define kPRT__ 207 359 | #define kRDO__ 208 360 | #define kRPL__ 209 361 | #define kRIT__ 210 362 | #define kRES__ 211 363 | #define kSAV__ 212 364 | #define kSPD__ 213 365 | #define kUND__ 214 366 | #define rfi__ 215 367 | #define kf11__ 216 368 | #define kf12__ 217 369 | #define kf13__ 218 370 | #define kf14__ 219 371 | #define kf15__ 220 372 | #define kf16__ 221 373 | #define kf17__ 222 374 | #define kf18__ 223 375 | #define kf19__ 224 376 | #define kf20__ 225 377 | #define kf21__ 226 378 | #define kf22__ 227 379 | #define kf23__ 228 380 | #define kf24__ 229 381 | #define kf25__ 230 382 | #define kf26__ 231 383 | #define kf27__ 232 384 | #define kf28__ 233 385 | #define kf29__ 234 386 | #define kf30__ 235 387 | #define kf31__ 236 388 | #define kf32__ 237 389 | #define kf33__ 238 390 | #define kf34__ 239 391 | #define kf35__ 240 392 | #define kf36__ 241 393 | #define kf37__ 242 394 | #define kf38__ 243 395 | #define kf39__ 244 396 | #define kf40__ 245 397 | #define kf41__ 246 398 | #define kf42__ 247 399 | #define kf43__ 248 400 | #define kf44__ 249 401 | #define kf45__ 250 402 | #define kf46__ 251 403 | #define kf47__ 252 404 | #define kf48__ 253 405 | #define kf49__ 254 406 | #define kf50__ 255 407 | #define kf51__ 256 408 | #define kf52__ 257 409 | #define kf53__ 258 410 | #define kf54__ 259 411 | #define kf55__ 260 412 | #define kf56__ 261 413 | #define kf57__ 262 414 | #define kf58__ 263 415 | #define kf59__ 264 416 | #define kf60__ 265 417 | #define kf61__ 266 418 | #define kf62__ 267 419 | #define kf63__ 268 420 | #define el1__ 269 421 | #define mgc__ 270 422 | #define smgl__ 271 423 | #define smgr__ 272 424 | 425 | #ifdef CAP 426 | char *Boolean_names[] = { 427 | "bw", "am", "xb", "xs", "xn", "eo", "gn", "hc", "km", "hs", "in", "da", "db", 428 | "mi", "ms", "os", "es", "xt", "hz", "ul", "xo", "HC", "nx", "NR", "NP", "5i" 429 | }; 430 | 431 | char *Number_names[] = { 432 | "co#", "it#", "li#", "lm#", "sg#", "pb#", "vt#", "ws#", "Nl#", "lh#", "lw#" 433 | }; 434 | 435 | char *String_names[] = { 436 | "bt=", "bl=", "cr=", "cs=", "ct=", "cl=", "ce=", "cd=", "ch=", "CC=", "cm=", 437 | "do=", "ho=", "vi=", "le=", "CM=", "ve=", "nd=", "ll=", "up=", "vs=", "dc=", 438 | "dl=", "ds=", "hd=", "as=", "mb=", "md=", "ti=", "dm=", "mh=", "im=", "mk=", 439 | "mp=", "mr=", "so=", "us=", "ec=", "ae=", "me=", "te=", "ed=", "ei=", "se=", 440 | "ue=", "vb=", "ff=", "fs=", "i1=", "i2=", "i3=", "if=", "ic=", "al=", "ip=", 441 | "kb=", "ka=", "kC=", "kt=", "kD=", "kL=", "kd=", "kM=", "kE=", "kS=", "k0=", 442 | "k1=", "k;=", "k2=", "k3=", "k4=", "k5=", "k6=", "k7=", "k8=", "k9=", "kh=", 443 | "kI=", "kA=", "kl=", "kH=", "kN=", "kP=", "kr=", "kF=", "kR=", "kT=", "ku=", 444 | "ke=", "ks=", "l0=", "l1=", "la=", "l2=", "l3=", "l4=", "l5=", "l6=", "l7=", 445 | "l8=", "l9=", "mo=", "mm=", "nw=", "pc=", "DC=", "DL=", "DO=", "IC=", "SF=", 446 | "AL=", "LE=", "RI=", "SR=", "UP=", "pk=", "pl=", "px=", "ps=", "pf=", "po=", 447 | "rp=", "r1=", "r2=", "r3=", "rf=", "rc=", "cv=", "sc=", "sf=", "sr=", "sa=", 448 | "st=", "wi=", "ta=", "ts=", "uc=", "hu=", "iP=", "K1=", "K3=", "K2=", "K4=", 449 | "K5=", "pO=", "rP=", "ac=", "pn=", "kB=", "SX=", "RX=", "SA=", "RA=", "XN=", 450 | "XF=", "eA=", "LO=", "LF=", "@1=", "@2=", "@3=", "@4=", "@5=", "@6=", "@7=", 451 | "@8=", "@9=", "@0=", "%1=", "%2=", "%3=", "%4=", "%5=", "%6=", "%7=", "%8=", 452 | "%9=", "%0=", "&1=", "&2=", "&3=", "&4=", "&5=", "&6=", "&7=", "&8=", "&9=", 453 | "&0=", "*1=", "*2=", "*3=", "*4=", "*5=", "*6=", "*7=", "*8=", "*9=", "*0=", 454 | "#1=", "#2=", "#3=", "#4=", "%a=", "%b=", "%c=", "%d=", "%e=", "%f=", "%g=", 455 | "%h=", "%i=", "%j=", "!1=", "!2=", "!3=", "RF=", "F1=", "F2=", "F3=", "F4=", 456 | "F5=", "F6=", "F7=", "F8=", "F9=", "FA=", "FB=", "FC=", "FD=", "FE=", "FF=", 457 | "FG=", "FH=", "FI=", "FJ=", "FK=", "FL=", "FM=", "FN=", "FO=", "FP=", "FQ=", 458 | "FR=", "FS=", "FT=", "FU=", "FV=", "FW=", "FX=", "FY=", "FZ=", "Fa=", "Fb=", 459 | "Fc=", "Fd=", "Fe=", "Ff=", "Fg=", "Fh=", "Fi=", "Fj=", "Fk=", "Fl=", "Fm=", 460 | "Fn=", "Fo=", "Fp=", "Fq=", "Fr=", "cb=", "MC=", "ML=", "MR=" 461 | }; 462 | #endif 463 | 464 | char *new_curse = "October 1987"; 465 | 466 | char in_buff[100]; /* buffer for ungetch */ 467 | int bufp; /* next free position in in_buff */ 468 | 469 | char *TERMINAL_TYPE = NULL; /* terminal type to be gotten from environment */ 470 | int CFOUND = FALSE; 471 | int Data_Line_len = 0; 472 | int Max_Key_len; /* max length of a sequence sent by a key */ 473 | char *Data_Line = NULL; 474 | char *TERM_PATH = NULL; 475 | char *TERM_data_ptr = NULL; 476 | char *Term_File_name = NULL; /* name of file containing terminal description */ 477 | FILE *TFP; /* file pointer to file with terminal des. */ 478 | int Fildes; /* file descriptor for terminfo file */ 479 | int STAND = FALSE; /* is standout mode activated? */ 480 | int TERM_INFO = FALSE; /* is terminfo being used (TRUE), or termcap (FALSE) */ 481 | int Time_Out; /* set when time elapsed while trying to read function key */ 482 | int Curr_x; /* current x position on screen */ 483 | int Curr_y; /* current y position on the screen */ 484 | int LINES; 485 | int COLS; 486 | int Move_It; /* flag to move cursor if magic cookie glitch */ 487 | int initialized = FALSE; /* tells whether new_curse is initialized */ 488 | float speed; 489 | float chars_per_millisecond; 490 | int Repaint_screen; /* if an operation to change screen impossible, repaint screen */ 491 | int Intr; /* storeage for interrupt character */ 492 | int Parity; /* 0 = no parity, 1 = odd parity, 2 = even parity */ 493 | int Noblock; /* for BSD systems */ 494 | int Num_bits; /* number of bits per character */ 495 | int Flip_Bytes; /* some systems have byte order reversed */ 496 | int interrupt_flag = FALSE; /* set true if SIGWINCH received */ 497 | 498 | #ifndef CAP 499 | char *Strings; 500 | #endif 501 | 502 | #if !defined(TERMCAP) 503 | #define TERMCAP "/etc/termcap" 504 | #endif 505 | 506 | struct KEYS { 507 | int length; /* length of string sent by key */ 508 | char *string; /* string sent by key */ 509 | int value; /* CURSES value of key (9-bit) */ 510 | }; 511 | 512 | struct KEY_STACK { 513 | struct KEYS *element; 514 | struct KEY_STACK *next; 515 | }; 516 | 517 | struct KEY_STACK *KEY_TOS = NULL; 518 | struct KEY_STACK *KEY_POINT; 519 | 520 | /* 521 | | 522 | | Not all systems have good terminal information, so we will define 523 | | keyboard information here for the most widely used terminal type, 524 | | the VT100. 525 | | 526 | */ 527 | 528 | struct KEYS vt100[] = 529 | { 530 | { 3, "\033[A", 0403 }, /* key up */ 531 | { 3, "\033[C", 0405 }, /* key right */ 532 | { 3, "\033[D", 0404 }, /* key left */ 533 | 534 | { 4, "\033[6~", 0522 }, /* key next page */ 535 | { 4, "\033[5~", 0523 }, /* key prev page */ 536 | { 3, "\033[[", 0550 }, /* key end */ 537 | { 3, "\033[@", 0406 }, /* key home */ 538 | { 4, "\033[2~", 0513 }, /* key insert char */ 539 | 540 | { 3, "\033[y", 0410 }, /* key F0 */ 541 | { 3, "\033[P", 0411 }, /* key F1 */ 542 | { 3, "\033[Q", 0412 }, /* key F2 */ 543 | { 3, "\033[R", 0413 }, /* key F3 */ 544 | { 3, "\033[S", 0414 }, /* key F4 */ 545 | { 3, "\033[t", 0415 }, /* key F5 */ 546 | { 3, "\033[u", 0416 }, /* key F6 */ 547 | { 3, "\033[v", 0417 }, /* key F7 */ 548 | { 3, "\033[l", 0420 }, /* key F8 */ 549 | { 3, "\033[w", 0421 }, /* key F9 */ 550 | { 3, "\033[x", 0422 }, /* key F10 */ 551 | 552 | { 5, "\033[10~", 0410 }, /* key F0 */ 553 | { 5, "\033[11~", 0411 }, /* key F1 */ 554 | { 5, "\033[12~", 0412 }, /* key F2 */ 555 | { 5, "\033[13~", 0413 }, /* key F3 */ 556 | { 5, "\033[14~", 0414 }, /* key F4 */ 557 | { 5, "\033[15~", 0415 }, /* key F5 */ 558 | { 5, "\033[17~", 0416 }, /* key F6 */ 559 | { 5, "\033[18~", 0417 }, /* key F7 */ 560 | { 5, "\033[19~", 0420 }, /* key F8 */ 561 | { 5, "\033[20~", 0421 }, /* key F9 */ 562 | { 5, "\033[21~", 0422 }, /* key F10 */ 563 | { 5, "\033[23~", 0423 }, /* key F11 */ 564 | { 5, "\033[24~", 0424 }, /* key F12 */ 565 | { 3, "\033[q", 0534 }, /* ka1 upper-left of keypad */ 566 | { 3, "\033[s", 0535 }, /* ka3 upper-right of keypad */ 567 | { 3, "\033[r", 0536 }, /* kb2 center of keypad */ 568 | { 3, "\033[p", 0537 }, /* kc1 lower-left of keypad */ 569 | { 3, "\033[n", 0540 }, /* kc3 lower-right of keypad */ 570 | 571 | /* 572 | | The following are the same keys as above, but with 573 | | a different character following the escape char. 574 | */ 575 | 576 | { 3, "\033OA", 0403 }, /* key up */ 577 | { 3, "\033OC", 0405 }, /* key right */ 578 | { 3, "\033OD", 0404 }, /* key left */ 579 | { 3, "\033OB", 0402 }, /* key down */ 580 | { 4, "\033O6~", 0522 }, /* key next page */ 581 | { 4, "\033O5~", 0523 }, /* key prev page */ 582 | { 3, "\033O[", 0550 }, /* key end */ 583 | { 3, "\033O@", 0406 }, /* key home */ 584 | { 4, "\033O2~", 0513 }, /* key insert char */ 585 | 586 | { 3, "\033Oy", 0410 }, /* key F0 */ 587 | { 3, "\033OP", 0411 }, /* key F1 */ 588 | { 3, "\033OQ", 0412 }, /* key F2 */ 589 | { 3, "\033OR", 0413 }, /* key F3 */ 590 | { 3, "\033OS", 0414 }, /* key F4 */ 591 | { 3, "\033Ot", 0415 }, /* key F5 */ 592 | { 3, "\033Ou", 0416 }, /* key F6 */ 593 | { 3, "\033Ov", 0417 }, /* key F7 */ 594 | { 3, "\033Ol", 0420 }, /* key F8 */ 595 | { 3, "\033Ow", 0421 }, /* key F9 */ 596 | { 3, "\033Ox", 0422 }, /* key F10 */ 597 | 598 | { 5, "\033O10~", 0410 }, /* key F0 */ 599 | { 5, "\033O11~", 0411 }, /* key F1 */ 600 | { 5, "\033O12~", 0412 }, /* key F2 */ 601 | { 5, "\033O13~", 0413 }, /* key F3 */ 602 | { 5, "\033O14~", 0414 }, /* key F4 */ 603 | { 5, "\033O15~", 0415 }, /* key F5 */ 604 | { 5, "\033O17~", 0416 }, /* key F6 */ 605 | { 5, "\033O18~", 0417 }, /* key F7 */ 606 | { 5, "\033O19~", 0420 }, /* key F8 */ 607 | { 5, "\033O20~", 0421 }, /* key F9 */ 608 | { 5, "\033O21~", 0422 }, /* key F10 */ 609 | { 5, "\033O23~", 0423 }, /* key F11 */ 610 | { 5, "\033O24~", 0424 }, /* key F12 */ 611 | { 3, "\033Oq", 0534 }, /* ka1 upper-left of keypad */ 612 | { 3, "\033Os", 0535 }, /* ka3 upper-right of keypad */ 613 | { 3, "\033Or", 0536 }, /* kb2 center of keypad */ 614 | { 3, "\033Op", 0537 }, /* kc1 lower-left of keypad */ 615 | { 3, "\033On", 0540 }, /* kc3 lower-right of keypad */ 616 | 617 | { 0, "", 0 } /* end */ 618 | }; 619 | 620 | struct Parameters { 621 | int value; 622 | struct Parameters *next; 623 | }; 624 | 625 | int Key_vals[] = { 626 | 0407, 0526, 0515, 0525, 0512, 0510, 0402, 0514, 0517, 0516, 0410, 0411, 627 | 0422, 0412, 0413, 0414, 0415, 0416, 0417, 0420, 0421, 0406, 0513, 0511, 628 | 0404, 0533, 0522, 0523, 0405, 0520, 0521, 0524, 0403, 629 | 0534, 0535, 0536, 0537, 0540, 0541, 0542, 0543, 0544, 0545, 0546, 0547, 630 | 0550, 0527, 0551, 0552, 0553, 0554, 0555, 0556, 0557, 0560, 0561, 0562, 631 | 0532, 0563, 0564, 0565, 0566, 0567, 0570, 0571, 0627, 0630, 0572, 0573, 632 | 0574, 0575, 0576, 0577, 0600, 0601, 0602, 0603, 0604, 0605, 0606, 0607, 633 | 0610, 0611, 0612, 0613, 0614, 0615, 0616, 0617, 0620, 0621, 0622, 0623, 634 | 0624, 0625, 0626, 0423, 0424, 0425, 0426, 0427, 0430, 0431, 635 | 0432, 0433, 0434, 0435, 0436, 0437, 0440, 0441, 0442, 0443, 0444, 0445, 636 | 0446, 0447, 0450, 0451, 0452, 0453, 0454, 0455, 0456, 0457, 0460, 0461, 637 | 0462, 0463, 0464, 0465, 0466, 0467, 0470, 0471, 0472, 0473, 0474, 0475, 638 | 0476, 0477, 0500, 0501, 0502, 0503, 0504, 0505, 0506, 0507 639 | }; 640 | 641 | int attributes_set[9]; 642 | 643 | static int nc_attributes = 0; /* global attributes for new_curse to observe */ 644 | 645 | #ifdef SYS5 646 | struct termio Terminal; 647 | struct termio Saved_tty; 648 | #else 649 | struct sgttyb Terminal; 650 | struct sgttyb Saved_tty; 651 | #endif 652 | 653 | char *tc_; 654 | 655 | int Booleans[128]; 656 | int Numbers[128]; 657 | char *String_table[1024]; 658 | 659 | int *virtual_lines; 660 | 661 | static char nc_scrolling_ability = FALSE; 662 | 663 | char *terminfo_path[] = { 664 | "/usr/lib/terminfo", 665 | "/usr/share/lib/terminfo", 666 | "/usr/share/terminfo", 667 | NULL 668 | }; 669 | 670 | #ifdef CAP 671 | 672 | #if defined(__STDC__) || defined(__cplusplus) 673 | #define P_(s) s 674 | #else 675 | #define P_(s) () 676 | #endif /* __STDC__ */ 677 | 678 | int tc_Get_int P_((int)); 679 | void CAP_PARSE P_((void)); 680 | void Find_term P_((void)); 681 | 682 | #undef P_ 683 | 684 | #endif /* CAP */ 685 | 686 | 687 | #ifndef __STDC__ 688 | #ifndef HAS_STDLIB 689 | extern char *fgets(); 690 | extern char *malloc(); 691 | extern char *getenv(); 692 | FILE *fopen(); /* declaration for open function */ 693 | #endif /* HAS_STDLIB */ 694 | #endif /* __STDC__ */ 695 | 696 | #ifdef SIGWINCH 697 | 698 | /* 699 | | Copy the contents of one window to another. 700 | */ 701 | 702 | void 703 | copy_window(origin, destination) 704 | WINDOW *origin, *destination; 705 | { 706 | int row, column; 707 | struct _line *orig, *dest; 708 | 709 | orig = origin->first_line; 710 | dest = destination->first_line; 711 | 712 | for (row = 0; 713 | row < (min(origin->Num_lines, destination->Num_lines)); 714 | row++) 715 | { 716 | for (column = 0; 717 | column < (min(origin->Num_cols, destination->Num_cols)); 718 | column++) 719 | { 720 | dest->row[column] = orig->row[column]; 721 | dest->attributes[column] = orig->attributes[column]; 722 | } 723 | dest->changed = orig->changed; 724 | dest->scroll = orig->scroll; 725 | dest->last_char = min(orig->last_char, destination->Num_cols); 726 | orig = orig->next_screen; 727 | dest = dest->next_screen; 728 | } 729 | destination->LX = min((destination->Num_cols - 1), origin->LX); 730 | destination->LY = min((destination->Num_lines - 1), origin->LY); 731 | destination->Attrib = origin->Attrib; 732 | destination->scroll_up = origin->scroll_up; 733 | destination->scroll_down = origin->scroll_down; 734 | destination->SCROLL_CLEAR = origin->SCROLL_CLEAR; 735 | } 736 | 737 | void 738 | reinitscr(foo) 739 | int foo; 740 | { 741 | WINDOW *local_virt; 742 | WINDOW *local_std; 743 | WINDOW *local_cur; 744 | 745 | signal(SIGWINCH, reinitscr); 746 | #ifdef TIOCGWINSZ 747 | if (ioctl(0, TIOCGWINSZ, &ws) >= 0) 748 | { 749 | if (ws.ws_row == LINES && ws.ws_col == COLS) 750 | return; 751 | if (ws.ws_row > 0) 752 | LINES = ws.ws_row; 753 | if (ws.ws_col > 0) 754 | COLS = ws.ws_col; 755 | } 756 | #endif /* TIOCGWINSZ */ 757 | local_virt = newwin(LINES, COLS, 0, 0); 758 | local_std = newwin(LINES, COLS, 0, 0); 759 | local_cur = newwin(LINES, COLS, 0, 0); 760 | copy_window(virtual_scr, local_virt); 761 | copy_window(stdscr, local_std); 762 | copy_window(curscr, local_cur); 763 | delwin(virtual_scr); 764 | delwin(stdscr); 765 | delwin(curscr); 766 | virtual_scr = local_virt; 767 | stdscr = local_std; 768 | curscr = local_cur; 769 | free(virtual_lines); 770 | virtual_lines = (int *) malloc(LINES * (sizeof(int))); 771 | interrupt_flag = TRUE; 772 | } 773 | #endif /* SIGWINCH */ 774 | 775 | void 776 | initscr() /* initialize terminal for operations */ 777 | { 778 | int value; 779 | int counter; 780 | char *lines_string; 781 | char *columns_string; 782 | #ifdef CAP 783 | char *pointer; 784 | #endif /* CAP */ 785 | 786 | #ifdef DIAG 787 | printf("starting initscr \n");fflush(stdout); 788 | #endif 789 | if (initialized) 790 | return; 791 | #ifdef BSD_SELECT 792 | setbuf(stdin, NULL); 793 | #endif /* BSD_SELECT */ 794 | Flip_Bytes = FALSE; 795 | Parity = 0; 796 | Time_Out = FALSE; 797 | bufp = 0; 798 | Move_It = FALSE; 799 | Noblock = FALSE; 800 | #ifdef SYS5 801 | value = ioctl(0, TCGETA, &Terminal); 802 | if (Terminal.c_cflag & PARENB) 803 | { 804 | if (Terminal.c_cflag & PARENB) 805 | Parity = 1; 806 | else 807 | Parity = 2; 808 | } 809 | if ((Terminal.c_cflag & CS8) == CS8) 810 | { 811 | Num_bits = 8; 812 | } 813 | else if ((Terminal.c_cflag & CS7) == CS7) 814 | Num_bits = 7; 815 | else if ((Terminal.c_cflag & CS6) == CS6) 816 | Num_bits = 6; 817 | else 818 | Num_bits = 5; 819 | value = Terminal.c_cflag & 037; 820 | switch (value) { 821 | case 01: speed = 50.0; 822 | break; 823 | case 02: speed = 75.0; 824 | break; 825 | case 03: speed = 110.0; 826 | break; 827 | case 04: speed = 134.5; 828 | break; 829 | case 05: speed = 150.0; 830 | break; 831 | case 06: speed = 200.0; 832 | break; 833 | case 07: speed = 300.0; 834 | break; 835 | case 010: speed = 600.0; 836 | break; 837 | case 011: speed = 900.0; 838 | break; 839 | case 012: speed = 1200.0; 840 | break; 841 | case 013: speed = 1800.0; 842 | break; 843 | case 014: speed = 2400.0; 844 | break; 845 | case 015: speed = 3600.0; 846 | break; 847 | case 016: speed = 4800.0; 848 | break; 849 | case 017: speed = 7200.0; 850 | break; 851 | case 020: speed = 9600.0; 852 | break; 853 | case 021: speed = 19200.0; 854 | break; 855 | case 022: speed = 38400.0; 856 | break; 857 | default: speed = 0.0; 858 | } 859 | #else 860 | value = ioctl(0, TIOCGETP, &Terminal); 861 | if (Terminal.sg_flags & EVENP) 862 | Parity = 2; 863 | else if (Terminal.sg_flags & ODDP) 864 | Parity = 1; 865 | value = Terminal.sg_ospeed; 866 | switch (value) { 867 | case 01: speed = 50.0; 868 | break; 869 | case 02: speed = 75.0; 870 | break; 871 | case 03: speed = 110.0; 872 | break; 873 | case 04: speed = 134.5; 874 | break; 875 | case 05: speed = 150.0; 876 | break; 877 | case 06: speed = 200.0; 878 | break; 879 | case 07: speed = 300.0; 880 | break; 881 | case 010: speed = 600.0; 882 | break; 883 | case 011: speed = 1200.0; 884 | break; 885 | case 012: speed = 1800.0; 886 | break; 887 | case 013: speed = 2400.0; 888 | break; 889 | case 014: speed = 4800.0; 890 | break; 891 | case 015: speed = 9600.0; 892 | break; 893 | default: speed = 0.0; 894 | } 895 | #endif 896 | chars_per_millisecond = (0.001 * speed) / 8.0; 897 | TERMINAL_TYPE = getenv("TERM"); 898 | if (TERMINAL_TYPE == NULL) 899 | { 900 | printf("unknown terminal type\n"); 901 | exit(0); 902 | } 903 | #ifndef CAP 904 | Fildes = -1; 905 | TERM_PATH = getenv("TERMINFO"); 906 | if (TERM_PATH != NULL) 907 | { 908 | Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE); 909 | Term_File_name = malloc(Data_Line_len); 910 | sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE); 911 | Fildes = open(Term_File_name, O_RDONLY); 912 | if (Fildes == -1) 913 | { 914 | sprintf(Term_File_name, "%s/%x/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE); 915 | Fildes = open(Term_File_name, O_RDONLY); 916 | } 917 | } 918 | counter = 0; 919 | while ((Fildes == -1) && (terminfo_path[counter] != NULL)) 920 | { 921 | TERM_PATH = terminfo_path[counter]; 922 | Data_Line_len = 23 + strlen(TERM_PATH) + strlen(TERMINAL_TYPE); 923 | Term_File_name = malloc(Data_Line_len); 924 | sprintf(Term_File_name, "%s/%c/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE); 925 | Fildes = open(Term_File_name, O_RDONLY); 926 | if (Fildes == -1) 927 | { 928 | sprintf(Term_File_name, "%s/%x/%s", TERM_PATH, *TERMINAL_TYPE, TERMINAL_TYPE); 929 | Fildes = open(Term_File_name, O_RDONLY); 930 | } 931 | counter++; 932 | } 933 | if (Fildes == -1) 934 | { 935 | free(Term_File_name); 936 | Term_File_name = NULL; 937 | } 938 | else 939 | TERM_INFO = INFO_PARSE(); 940 | #else 941 | /* 942 | | termcap information can be in the TERMCAP env variable, if so 943 | | use that, otherwise check the /etc/termcap file 944 | */ 945 | if ((pointer = Term_File_name = getenv("TERMCAP")) != NULL) 946 | { 947 | if (*Term_File_name != '/') 948 | Term_File_name = TERMCAP; 949 | } 950 | else 951 | { 952 | Term_File_name = TERMCAP; 953 | } 954 | if ((TFP = fopen(Term_File_name, "r")) == NULL) 955 | { 956 | printf("unable to open %s file \n", TERMCAP); 957 | exit(0); 958 | } 959 | for (value = 0; value < 1024; value++) 960 | String_table[value] = NULL; 961 | for (value = 0; value < 128; value++) 962 | Booleans[value] = 0; 963 | for (value = 0; value < 128; value++) 964 | Numbers[value] = 0; 965 | Data_Line = malloc(512); 966 | if (pointer && *pointer != '/') 967 | { 968 | TERM_data_ptr = pointer; 969 | CAP_PARSE(); 970 | } 971 | else 972 | { 973 | Find_term(); 974 | CAP_PARSE(); 975 | } 976 | #endif 977 | if (String_table[pc__] == NULL) 978 | String_table[pc__] = "\0"; 979 | if ((String_table[cm__] == NULL) || (Booleans[hc__])) 980 | { 981 | fprintf(stderr, "sorry, unable to use this terminal type for screen editing\n"); 982 | exit(0); 983 | } 984 | Key_Get(); 985 | keys_vt100(); 986 | LINES = Numbers[li__]; 987 | COLS = Numbers[co__]; 988 | if ((lines_string = getenv("LINES")) != NULL) 989 | { 990 | value = atoi(lines_string); 991 | if (value > 0) 992 | LINES = value; 993 | } 994 | if ((columns_string = getenv("COLUMNS")) != NULL) 995 | { 996 | value = atoi(columns_string); 997 | if (value > 0) 998 | COLS = value; 999 | } 1000 | #ifdef TIOCGWINSZ 1001 | /* 1002 | | get the window size 1003 | */ 1004 | if (ioctl(0, TIOCGWINSZ, &ws) >= 0) 1005 | { 1006 | if (ws.ws_row > 0) 1007 | LINES = ws.ws_row; 1008 | if (ws.ws_col > 0) 1009 | COLS = ws.ws_col; 1010 | } 1011 | #endif 1012 | virtual_scr = newwin(LINES, COLS, 0, 0); 1013 | stdscr = newwin(LINES, COLS, 0, 0); 1014 | curscr = newwin(LINES, COLS, 0, 0); 1015 | wmove(stdscr, 0, 0); 1016 | werase(stdscr); 1017 | Repaint_screen = TRUE; 1018 | initialized = TRUE; 1019 | virtual_lines = (int *) malloc(LINES * (sizeof(int))); 1020 | 1021 | #ifdef SIGWINCH 1022 | /* 1023 | | reset size of windows and LINES and COLS if term window 1024 | | changes size 1025 | */ 1026 | signal(SIGWINCH, reinitscr); 1027 | #endif /* SIGWINCH */ 1028 | 1029 | /* 1030 | | check if scrolling is available 1031 | */ 1032 | 1033 | nc_scrolling_ability = ((String_table[al__] != NULL) && 1034 | (String_table[dl__])) || ((String_table[cs__]) 1035 | && (String_table[sr__])); 1036 | 1037 | } 1038 | 1039 | #ifndef CAP 1040 | int 1041 | Get_int() /* get a two-byte integer from the terminfo file */ 1042 | { 1043 | int High_byte; 1044 | int Low_byte; 1045 | int temp; 1046 | 1047 | Low_byte = *((unsigned char *) TERM_data_ptr++); 1048 | High_byte = *((unsigned char *) TERM_data_ptr++); 1049 | if (Flip_Bytes) 1050 | { 1051 | temp = Low_byte; 1052 | Low_byte = High_byte; 1053 | High_byte = temp; 1054 | } 1055 | if ((High_byte == 255) && (Low_byte == 255)) 1056 | return (-1); 1057 | else 1058 | return(Low_byte + (High_byte * 256)); 1059 | } 1060 | 1061 | int 1062 | INFO_PARSE() /* parse off the data in the terminfo data file */ 1063 | { 1064 | int offset; 1065 | int magic_number = 0; 1066 | int counter = 0; 1067 | int Num_names = 0; 1068 | int Num_bools = 0; 1069 | int Num_ints = 0; 1070 | int Num_strings = 0; 1071 | int string_table_len = 0; 1072 | char *temp_ptr; 1073 | 1074 | TERM_data_ptr = Data_Line = malloc((10240 * (sizeof(char)))); 1075 | Data_Line_len = read(Fildes, Data_Line, 10240); 1076 | if ((Data_Line_len >= 10240) || (Data_Line_len < 0)) 1077 | return(0); 1078 | /* 1079 | | get magic number 1080 | */ 1081 | magic_number = Get_int(); 1082 | /* 1083 | | if magic number not right, reverse byte order and check again 1084 | */ 1085 | if (magic_number != 282) 1086 | { 1087 | Flip_Bytes = TRUE; 1088 | TERM_data_ptr--; 1089 | TERM_data_ptr--; 1090 | magic_number = Get_int(); 1091 | if (magic_number != 282) 1092 | return(0); 1093 | } 1094 | /* 1095 | | get the number of each type in the terminfo data file 1096 | */ 1097 | Num_names = Get_int(); 1098 | Num_bools = Get_int(); 1099 | Num_ints = Get_int(); 1100 | Num_strings = Get_int(); 1101 | string_table_len = Get_int(); 1102 | Strings = malloc(string_table_len); 1103 | while (Num_names > 0) 1104 | { 1105 | TERM_data_ptr++; 1106 | Num_names--; 1107 | } 1108 | counter = 0; 1109 | while (Num_bools) 1110 | { 1111 | Num_bools--; 1112 | Booleans[counter++] = *TERM_data_ptr++; 1113 | } 1114 | if ((unsigned long)TERM_data_ptr & 1) /* force alignment */ 1115 | TERM_data_ptr++; 1116 | counter = 0; 1117 | while (Num_ints) 1118 | { 1119 | Num_ints--; 1120 | Numbers[counter] = Get_int(); 1121 | counter++; 1122 | } 1123 | temp_ptr = TERM_data_ptr + Num_strings + Num_strings; 1124 | memcpy(Strings, temp_ptr, string_table_len); 1125 | counter = bt__; 1126 | while (Num_strings) 1127 | { 1128 | Num_strings--; 1129 | if ((offset=Get_int()) != -1) 1130 | { 1131 | if (String_table[counter] == NULL) 1132 | String_table[counter] = Strings + offset; 1133 | } 1134 | else 1135 | String_table[counter] = NULL; 1136 | counter++; 1137 | } 1138 | close(Fildes); 1139 | free(Data_Line); 1140 | return(TRUE); 1141 | } 1142 | #endif /* ifndef CAP */ 1143 | 1144 | int 1145 | AtoI() /* convert ascii text to integers */ 1146 | { 1147 | int Temp; 1148 | 1149 | Temp = 0; 1150 | while ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9')) 1151 | { 1152 | Temp = (Temp * 10) + (*TERM_data_ptr - '0'); 1153 | TERM_data_ptr++; 1154 | } 1155 | return(Temp); 1156 | } 1157 | 1158 | void 1159 | Key_Get() /* create linked list with all key sequences obtained from terminal database */ 1160 | { 1161 | int Counter; 1162 | int Klen; 1163 | int key_def; 1164 | struct KEY_STACK *Spoint; 1165 | 1166 | Max_Key_len = 0; 1167 | Counter = 0; 1168 | key_def = kb__; 1169 | while (key_def <= kf63__) 1170 | { 1171 | if (key_def == ke__) 1172 | key_def = K1__; 1173 | else if (key_def == (K5__ + 1)) 1174 | key_def = kcbt__; 1175 | else if (key_def == (kcbt__ + 1)) 1176 | key_def = kbeg__; 1177 | else if (key_def == (kUND__ + 1)) 1178 | key_def = kf11__; 1179 | if (String_table[key_def] != NULL) 1180 | { 1181 | if (KEY_TOS == NULL) 1182 | Spoint = KEY_TOS = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK)); 1183 | else 1184 | { 1185 | Spoint = KEY_TOS; 1186 | while (Spoint->next != NULL) 1187 | Spoint = Spoint->next; 1188 | Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK)); 1189 | Spoint = Spoint->next; 1190 | } 1191 | Spoint->next = NULL; 1192 | Spoint->element = (struct KEYS *) malloc(sizeof(struct KEYS)); 1193 | Spoint->element->string = String_table[key_def]; 1194 | Spoint->element->length = strlen(String_table[key_def]); 1195 | Spoint->element->value = Key_vals[Counter]; 1196 | Klen = strlen(Spoint->element->string); 1197 | if (Klen > Max_Key_len) 1198 | Max_Key_len = Klen; 1199 | /* 1200 | | Some terminal types accept keystrokes of the form 1201 | | \E[A and \EOA, substituting '[' for 'O'. Make a 1202 | | duplicate of such key strings (since the 1203 | | database will only have one version) so new_curse 1204 | | can understand both. 1205 | */ 1206 | if ((Spoint->element->length > 1) && 1207 | ((String_table[key_def][1] == '[') || 1208 | (String_table[key_def][1] == 'O'))) 1209 | { 1210 | Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK)); 1211 | Spoint = Spoint->next; 1212 | Spoint->next = NULL; 1213 | Spoint->element = (struct KEYS *) malloc(sizeof(struct KEYS)); 1214 | Spoint->element->length = strlen(String_table[key_def]); 1215 | Spoint->element->string = malloc(Spoint->element->length + 1); 1216 | strcpy(Spoint->element->string, String_table[key_def]); 1217 | Spoint->element->value = Key_vals[Counter]; 1218 | Klen = strlen(Spoint->element->string); 1219 | if (Klen > Max_Key_len) 1220 | Max_Key_len = Klen; 1221 | 1222 | if (String_table[key_def][1] == '[') 1223 | Spoint->element->string[1] = 'O'; 1224 | else 1225 | Spoint->element->string[1] = '['; 1226 | } 1227 | } 1228 | key_def++; 1229 | Counter++; 1230 | } 1231 | } 1232 | 1233 | /* 1234 | | insert information about keys for a vt100 terminal 1235 | */ 1236 | 1237 | void 1238 | keys_vt100() 1239 | { 1240 | int counter; 1241 | int Klen; 1242 | struct KEY_STACK *Spoint; 1243 | 1244 | Spoint = KEY_TOS; 1245 | while (Spoint->next != NULL) 1246 | Spoint = Spoint->next; 1247 | for (counter = 0; vt100[counter].length != 0; counter++) 1248 | { 1249 | Spoint->next = (struct KEY_STACK *) malloc(sizeof(struct KEY_STACK)); 1250 | Spoint = Spoint->next; 1251 | Spoint->next = NULL; 1252 | Spoint->element = &vt100[counter]; 1253 | Klen = strlen(Spoint->element->string); 1254 | if (Klen > Max_Key_len) 1255 | Max_Key_len = Klen; 1256 | } 1257 | } 1258 | 1259 | #ifdef CAP 1260 | char * 1261 | String_Get(param) /* read the string */ 1262 | char *param; 1263 | { 1264 | char *String; 1265 | char *Temp; 1266 | int Counter; 1267 | 1268 | if (param == NULL) 1269 | { 1270 | while (*TERM_data_ptr != '=') 1271 | TERM_data_ptr++; 1272 | Temp = ++TERM_data_ptr; 1273 | Counter = 1; 1274 | while ((*Temp != ':') && (*Temp != (char)NULL)) 1275 | { 1276 | Counter++; 1277 | Temp++; 1278 | } 1279 | if (Counter == 1) /* no data */ 1280 | return(NULL); 1281 | String = Temp = malloc(Counter); 1282 | while ((*TERM_data_ptr != ':') && (*TERM_data_ptr != (char)NULL)) 1283 | { 1284 | if (*TERM_data_ptr == '\\') 1285 | { 1286 | TERM_data_ptr++; 1287 | if (*TERM_data_ptr == 'n') 1288 | *Temp = '\n'; 1289 | else if (*TERM_data_ptr == 't') 1290 | *Temp = '\t'; 1291 | else if (*TERM_data_ptr == 'b') 1292 | *Temp = '\b'; 1293 | else if (*TERM_data_ptr == 'r') 1294 | *Temp = '\r'; 1295 | else if (*TERM_data_ptr == 'f') 1296 | *Temp = '\f'; 1297 | else if ((*TERM_data_ptr == 'e') || (*TERM_data_ptr == 'E')) 1298 | *Temp = '\033'; /* escape */ 1299 | else if (*TERM_data_ptr == '\\') 1300 | *Temp = '\\'; 1301 | else if (*TERM_data_ptr == '\'') 1302 | *Temp = '\''; 1303 | else if ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9')) 1304 | { 1305 | Counter = 0; 1306 | while ((*TERM_data_ptr >= '0') && (*TERM_data_ptr <= '9')) 1307 | { 1308 | Counter = (8 * Counter) + (*TERM_data_ptr - '0'); 1309 | TERM_data_ptr++; /* ? */ 1310 | } 1311 | *Temp = Counter; 1312 | TERM_data_ptr--; 1313 | } 1314 | TERM_data_ptr++; 1315 | Temp++; 1316 | } 1317 | else if (*TERM_data_ptr == '^') 1318 | { 1319 | TERM_data_ptr++; 1320 | if ((*TERM_data_ptr >= '@') && (*TERM_data_ptr <= '_')) 1321 | *Temp = *TERM_data_ptr - '@'; 1322 | else if (*TERM_data_ptr == '?') 1323 | *Temp = 127; 1324 | TERM_data_ptr++; 1325 | Temp++; 1326 | } 1327 | else 1328 | *Temp++ = *TERM_data_ptr++; 1329 | } 1330 | *Temp = (char)NULL; 1331 | param = String; 1332 | } 1333 | else 1334 | { 1335 | while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != ':')) 1336 | TERM_data_ptr++; 1337 | } 1338 | return(param); 1339 | } 1340 | 1341 | int 1342 | tc_Get_int(param) /* read the integer */ 1343 | int param; 1344 | { 1345 | int Itemp; 1346 | 1347 | if (param == 0) 1348 | { 1349 | while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != '#')) 1350 | TERM_data_ptr++; 1351 | TERM_data_ptr++; 1352 | Itemp = AtoI(); 1353 | param = Itemp; 1354 | } 1355 | else 1356 | { 1357 | while (*TERM_data_ptr != ':') 1358 | TERM_data_ptr++; 1359 | } 1360 | return(param); 1361 | } 1362 | 1363 | void 1364 | Find_term() /* find terminal description in termcap file */ 1365 | { 1366 | char *Name; 1367 | char *Ftemp; 1368 | 1369 | Ftemp = Name = malloc(strlen(TERMINAL_TYPE) + 2); 1370 | strcpy(Name, TERMINAL_TYPE); 1371 | while (*Ftemp != (char)NULL) 1372 | Ftemp++; 1373 | *Ftemp++ = '|'; 1374 | *Ftemp = (char)NULL; 1375 | CFOUND = FALSE; 1376 | Data_Line_len = strlen(TERMINAL_TYPE) + 1; 1377 | while ((!CFOUND) && ((TERM_data_ptr=fgets(Data_Line, 512, TFP)) != NULL)) 1378 | { 1379 | if ((*TERM_data_ptr != ' ') && (*TERM_data_ptr != '\t') && (*TERM_data_ptr != '#')) 1380 | { 1381 | while ((!CFOUND) && (*TERM_data_ptr != (char)NULL)) 1382 | { 1383 | CFOUND = !strncmp(TERM_data_ptr, Name, Data_Line_len); 1384 | while ((*TERM_data_ptr != (char)NULL) && (*TERM_data_ptr != '|') && (*TERM_data_ptr != '#') && (*TERM_data_ptr != ':')) 1385 | TERM_data_ptr++; 1386 | if (*TERM_data_ptr == '|') 1387 | TERM_data_ptr++; 1388 | else if (!CFOUND) 1389 | *TERM_data_ptr = (char)NULL; 1390 | } 1391 | } 1392 | } 1393 | if (!CFOUND) 1394 | { 1395 | printf("terminal type %s not found\n", TERMINAL_TYPE); 1396 | exit(0); 1397 | } 1398 | } 1399 | 1400 | void 1401 | CAP_PARSE() /* parse off the data in the termcap data file */ 1402 | { 1403 | int offset; 1404 | int found; 1405 | 1406 | do 1407 | { 1408 | while (*TERM_data_ptr != (char)NULL) 1409 | { 1410 | for (found = FALSE, offset = 0; (!found) && (offset < 26); offset++) 1411 | { 1412 | if (!strncmp(TERM_data_ptr, Boolean_names[offset], 2)) 1413 | { 1414 | found = TRUE; 1415 | Booleans[offset] = TRUE; 1416 | } 1417 | } 1418 | if (!found) 1419 | { 1420 | for (found = FALSE, offset = 0; (!found) && (offset < lw__); offset++) 1421 | { 1422 | if (!strncmp(TERM_data_ptr, Number_names[offset], 3)) 1423 | { 1424 | found = TRUE; 1425 | Numbers[offset] = tc_Get_int(Numbers[offset]); 1426 | } 1427 | } 1428 | } 1429 | if (!found) 1430 | { 1431 | for (found = FALSE, offset = 0; (!found) && (offset < smgr__); offset++) 1432 | { 1433 | if (!strncmp(TERM_data_ptr, String_names[offset], 3)) 1434 | { 1435 | found = TRUE; 1436 | String_table[offset] = String_Get(String_table[offset]); 1437 | } 1438 | } 1439 | } 1440 | 1441 | if (!strncmp(TERM_data_ptr, "tc=", 3)) 1442 | tc_ = String_Get(NULL); 1443 | while ((*TERM_data_ptr != ':') && (*TERM_data_ptr != (char)NULL)) 1444 | TERM_data_ptr++; 1445 | if (*TERM_data_ptr == ':') 1446 | TERM_data_ptr++; 1447 | } 1448 | } while (((TERM_data_ptr = fgets(Data_Line, 512, TFP)) != NULL) && ((*TERM_data_ptr == ' ') || (*TERM_data_ptr == '\t'))); 1449 | if (tc_ != NULL) 1450 | { 1451 | TERMINAL_TYPE = tc_; 1452 | rewind(TFP); 1453 | Find_term(); 1454 | tc_ = NULL; 1455 | CAP_PARSE(); 1456 | } 1457 | else 1458 | fclose(TFP); 1459 | } 1460 | #endif /* ifdef CAP */ 1461 | 1462 | struct _line * 1463 | Screenalloc(columns) 1464 | int columns; 1465 | { 1466 | int i; 1467 | struct _line *tmp; 1468 | 1469 | tmp = (struct _line *) malloc(sizeof (struct _line)); 1470 | tmp->row = malloc(columns + 1); 1471 | tmp->attributes = malloc(columns + 1); 1472 | tmp->prev_screen = NULL; 1473 | tmp->next_screen = NULL; 1474 | for (i = 0; i < columns; i++) 1475 | { 1476 | tmp->row[i] = ' '; 1477 | tmp->attributes[i] = '\0'; 1478 | } 1479 | tmp->scroll = tmp->changed = FALSE; 1480 | tmp->row[0] = '\0'; 1481 | tmp->attributes[0] = '\0'; 1482 | tmp->row[columns] = '\0'; 1483 | tmp->attributes[columns] = '\0'; 1484 | tmp->last_char = 0; 1485 | return(tmp); 1486 | } 1487 | 1488 | WINDOW *newwin(lines, cols, start_l, start_c) 1489 | int lines, cols; /* number of lines and columns to be in window */ 1490 | int start_l, start_c; /* starting line and column to be inwindow */ 1491 | { 1492 | WINDOW *Ntemp; 1493 | struct _line *temp_screen; 1494 | int i; 1495 | 1496 | Ntemp = (WINDOW *) malloc(sizeof(WINDOW)); 1497 | Ntemp->SR = start_l; 1498 | Ntemp->SC = start_c; 1499 | Ntemp->Num_lines = lines; 1500 | Ntemp->Num_cols = cols; 1501 | Ntemp->LX = 0; 1502 | Ntemp->LY = 0; 1503 | Ntemp->scroll_down = Ntemp->scroll_up = 0; 1504 | Ntemp->SCROLL_CLEAR = FALSE; 1505 | Ntemp->Attrib = FALSE; 1506 | Ntemp->first_line = temp_screen = Screenalloc(cols); 1507 | Ntemp->first_line->number = 0; 1508 | Ntemp->line_array = (struct _line **) malloc(LINES * sizeof(struct _line *)); 1509 | 1510 | Ntemp->line_array[0] = Ntemp->first_line; 1511 | 1512 | for (i = 1; i < lines; i++) 1513 | { 1514 | temp_screen->next_screen = Screenalloc(cols); 1515 | temp_screen->next_screen->number = i; 1516 | temp_screen->next_screen->prev_screen = temp_screen; 1517 | temp_screen = temp_screen->next_screen; 1518 | Ntemp->line_array[i] = temp_screen; 1519 | } 1520 | Ntemp->first_line->prev_screen = NULL; 1521 | temp_screen->next_screen = NULL; 1522 | return(Ntemp); 1523 | } 1524 | 1525 | #ifdef CAP 1526 | void 1527 | Cap_Out(string, p_list, place) /* interpret the output string if necessary */ 1528 | char *string; 1529 | int p_list[]; /* stack of values */ 1530 | int place; /* place keeper of top of stack */ 1531 | { 1532 | char *Otemp; /* temporary string pointer to parse output */ 1533 | int delay; 1534 | int p1, p2, temp; 1535 | float chars; 1536 | 1537 | if (string == NULL) 1538 | return; 1539 | 1540 | if (p_list != NULL) 1541 | { 1542 | p1 = p_list[--place]; 1543 | p2 = p_list[--place]; 1544 | } 1545 | delay = 0; 1546 | Otemp = string; 1547 | if ((*Otemp >= '0') && (*Otemp <= '9')) 1548 | { 1549 | delay = atoi(Otemp); 1550 | while ((*Otemp >= '0') && (*Otemp <= '9')) 1551 | Otemp++; 1552 | if (*Otemp == '*') 1553 | Otemp++; 1554 | } 1555 | while (*Otemp != (char)NULL) 1556 | { 1557 | if (*Otemp == '%') 1558 | { 1559 | Otemp++; 1560 | if ((*Otemp == 'd') || (*Otemp == '2') || (*Otemp == '3') || (*Otemp == '.') || (*Otemp == '+')) 1561 | { 1562 | if (*Otemp == 'd') 1563 | printf("%d", p1); 1564 | else if (*Otemp == '2') 1565 | printf("%02d", p1); 1566 | else if (*Otemp == '3') 1567 | printf("%03d", p1); 1568 | else if (*Otemp == '+') 1569 | { 1570 | Otemp++; 1571 | p1 += *Otemp; 1572 | putchar(p1); 1573 | } 1574 | else if (*Otemp == '.') 1575 | putchar(p1); 1576 | p1 = p2; 1577 | p2 = 0; 1578 | } 1579 | else if (*Otemp == '>') 1580 | { 1581 | Otemp++; 1582 | if (p1 > *Otemp) 1583 | { 1584 | Otemp++; 1585 | p1 += *Otemp; 1586 | } 1587 | else 1588 | Otemp++; 1589 | } 1590 | else if (*Otemp == 'r') 1591 | { 1592 | temp = p1; 1593 | p1 = p2; 1594 | p2 = temp; 1595 | } 1596 | else if (*Otemp == 'i') 1597 | { 1598 | p1++; 1599 | p2++; 1600 | } 1601 | else if (*Otemp == '%') 1602 | putchar(*Otemp); 1603 | else if (*Otemp == 'n') 1604 | { 1605 | p1 ^= 0140; 1606 | p2 ^= 0140; 1607 | } 1608 | else if (*Otemp == 'B') 1609 | { 1610 | p1 = (16 * (p1/10)) + (p1 % 10); 1611 | p2 = (16 * (p2/10)) + (p2 % 10); 1612 | } 1613 | else if (*Otemp == 'D') 1614 | { 1615 | p1 = (p1 - 2 * (p1 % 16)); 1616 | p2 = (p2 - 2 * (p2 % 16)); 1617 | } 1618 | } 1619 | else 1620 | putchar (*Otemp); 1621 | Otemp++; 1622 | } 1623 | if (delay != 0) 1624 | { 1625 | chars = delay * chars_per_millisecond; 1626 | delay = chars; 1627 | if ((chars - delay) > 0.0) 1628 | delay++; 1629 | for (; delay > 0; delay--) 1630 | putchar(*String_table[pc__]); 1631 | } 1632 | fflush(stdout); 1633 | } 1634 | 1635 | #else 1636 | 1637 | char *Otemp; /* temporary string pointer to parse output */ 1638 | float chars; 1639 | int p[10]; 1640 | int variable[27]; 1641 | 1642 | int 1643 | Operation(Temp_Stack, place) /* handle conditional operations */ 1644 | int Temp_Stack[]; 1645 | int place; 1646 | { 1647 | int temp; 1648 | 1649 | if (*Otemp == 'd') 1650 | { 1651 | Otemp++; 1652 | temp = Temp_Stack[--place]; 1653 | printf("%d", temp); 1654 | } 1655 | else if (!strncmp(Otemp, "2d", 2)) 1656 | { 1657 | temp = Temp_Stack[--place]; 1658 | printf("%2d", temp); 1659 | Otemp++; 1660 | Otemp++; 1661 | } 1662 | else if (!strncmp(Otemp, "3d", 2)) 1663 | { 1664 | temp = Temp_Stack[--place]; 1665 | printf("%0d", temp); 1666 | Otemp++; 1667 | Otemp++; 1668 | } 1669 | else if (!strncmp(Otemp, "02d", 3)) 1670 | { 1671 | temp = Temp_Stack[--place]; 1672 | printf("%02d", temp); 1673 | Otemp++; 1674 | Otemp++; 1675 | Otemp++; 1676 | } 1677 | else if (!strncmp(Otemp, "03d", 3)) 1678 | { 1679 | temp = Temp_Stack[--place]; 1680 | printf("%03d", temp); 1681 | Otemp++; 1682 | Otemp++; 1683 | Otemp++; 1684 | } 1685 | else if (*Otemp == '+') 1686 | { 1687 | Otemp++; 1688 | temp = Temp_Stack[--place]; 1689 | temp += Temp_Stack[--place]; 1690 | Temp_Stack[place++] = temp; 1691 | } 1692 | else if (*Otemp == '-') 1693 | { 1694 | Otemp++; 1695 | temp = Temp_Stack[--place]; 1696 | temp -= Temp_Stack[--place]; 1697 | Temp_Stack[place++] = temp; 1698 | } 1699 | else if (*Otemp == '*') 1700 | { 1701 | Otemp++; 1702 | temp = Temp_Stack[--place]; 1703 | temp *= Temp_Stack[--place]; 1704 | Temp_Stack[place++] = temp; 1705 | } 1706 | else if (*Otemp == '/') 1707 | { 1708 | Otemp++; 1709 | temp = Temp_Stack[--place]; 1710 | temp /= Temp_Stack[--place]; 1711 | Temp_Stack[place++] = temp; 1712 | } 1713 | else if (*Otemp == 'm') 1714 | { 1715 | Otemp++; 1716 | temp = Temp_Stack[--place]; 1717 | temp %= Temp_Stack[--place]; 1718 | Temp_Stack[place++] = temp; 1719 | } 1720 | else if (*Otemp == '&') 1721 | { 1722 | Otemp++; 1723 | temp = Temp_Stack[--place]; 1724 | temp &= Temp_Stack[--place]; 1725 | Temp_Stack[place++] = temp; 1726 | } 1727 | else if (*Otemp == '|') 1728 | { 1729 | Otemp++; 1730 | temp = Temp_Stack[--place]; 1731 | temp |= Temp_Stack[--place]; 1732 | Temp_Stack[place++] = temp; 1733 | } 1734 | else if (*Otemp == '^') 1735 | { 1736 | Otemp++; 1737 | temp = Temp_Stack[--place]; 1738 | temp ^= Temp_Stack[--place]; 1739 | Temp_Stack[place++] = temp; 1740 | } 1741 | else if (*Otemp == '=') 1742 | { 1743 | Otemp++; 1744 | temp = Temp_Stack[--place]; 1745 | temp = (temp == Temp_Stack[--place]); 1746 | Temp_Stack[place++] = temp; 1747 | } 1748 | else if (*Otemp == '>') 1749 | { 1750 | Otemp++; 1751 | temp = Temp_Stack[--place]; 1752 | temp = temp > Temp_Stack[--place]; 1753 | Temp_Stack[place++] = temp; 1754 | } 1755 | else if (*Otemp == '<') 1756 | { 1757 | Otemp++; 1758 | temp = Temp_Stack[--place]; 1759 | temp = temp < Temp_Stack[--place]; 1760 | Temp_Stack[place++] = temp; 1761 | } 1762 | else if (*Otemp == 'c') 1763 | { 1764 | Otemp++; 1765 | putchar(Temp_Stack[--place]); 1766 | } 1767 | else if (*Otemp == 'i') 1768 | { 1769 | Otemp++; 1770 | p[1]++; 1771 | p[2]++; 1772 | } 1773 | else if (*Otemp == '%') 1774 | { 1775 | putchar(*Otemp); 1776 | Otemp++; 1777 | } 1778 | else if (*Otemp == '!') 1779 | { 1780 | temp = ! Temp_Stack[--place]; 1781 | Temp_Stack[place++] = temp; 1782 | Otemp++; 1783 | } 1784 | else if (*Otemp == '~') 1785 | { 1786 | temp = ~Temp_Stack[--place]; 1787 | Temp_Stack[place++] = temp; 1788 | Otemp++; 1789 | } 1790 | else if (*Otemp == 'p') 1791 | { 1792 | Otemp++; 1793 | Temp_Stack[place++] = p[*Otemp - '0']; 1794 | Otemp++; 1795 | } 1796 | else if (*Otemp == 'P') 1797 | { 1798 | Otemp++; 1799 | Temp_Stack[place++] = variable[*Otemp - 'a']; 1800 | Otemp++; 1801 | } 1802 | else if (*Otemp == 'g') 1803 | { 1804 | Otemp++; 1805 | variable[*Otemp - 'a'] = Temp_Stack[--place]; 1806 | Otemp++; 1807 | } 1808 | else if (*Otemp == '\'') 1809 | { 1810 | Otemp++; 1811 | Temp_Stack[place++] = *Otemp; 1812 | Otemp++; 1813 | Otemp++; 1814 | } 1815 | else if (*Otemp == '{') 1816 | { 1817 | Otemp++; 1818 | temp = atoi(Otemp); 1819 | Temp_Stack[place++] = temp; 1820 | while (*Otemp != '}') 1821 | Otemp++; 1822 | Otemp++; 1823 | } 1824 | return(place); 1825 | } 1826 | 1827 | void 1828 | Info_Out(string, p_list, place) /* interpret the output string if necessary */ 1829 | char *string; 1830 | int p_list[]; 1831 | int place; 1832 | { 1833 | char *tchar; 1834 | int delay; 1835 | int temp; 1836 | int Cond_FLAG; 1837 | int EVAL; 1838 | int Cond_Stack[128]; 1839 | int Cond_place; 1840 | int Stack[128]; 1841 | int Top_of_stack; 1842 | 1843 | if (string == NULL) 1844 | return; 1845 | 1846 | Cond_FLAG = FALSE; 1847 | Cond_place = 0; 1848 | Top_of_stack = 0; 1849 | p[0] = 0; 1850 | p[1] = 0; 1851 | p[2] = 0; 1852 | p[3] = 0; 1853 | p[4] = 0; 1854 | p[5] = 0; 1855 | p[6] = 0; 1856 | p[7] = 0; 1857 | p[8] = 0; 1858 | p[9] = 0; 1859 | if (p_list != NULL) 1860 | { 1861 | for (temp = 1; (place != 0); temp++) 1862 | { 1863 | p[temp] = p_list[--place]; 1864 | } 1865 | } 1866 | delay = 0; 1867 | Otemp = string; 1868 | while (*Otemp != '\0') 1869 | { 1870 | if (*Otemp == '%') 1871 | { 1872 | Otemp++; 1873 | if ((*Otemp == '?') || (*Otemp == 't') || (*Otemp == 'e') || (*Otemp == ';')) 1874 | { 1875 | if (*Otemp == '?') 1876 | { 1877 | Otemp++; 1878 | Cond_FLAG = TRUE; 1879 | EVAL = TRUE; 1880 | while (EVAL) 1881 | { 1882 | /* 1883 | | find the end of the 1884 | | conditional statement 1885 | */ 1886 | while ((strncmp(Otemp, "%t", 2)) && (*Otemp != '\0')) 1887 | { 1888 | /* 1889 | | move past '%' 1890 | */ 1891 | Otemp++; 1892 | Cond_place = Operation(Cond_Stack, Cond_place); 1893 | } 1894 | 1895 | /* 1896 | | if condition is true 1897 | */ 1898 | if ((Cond_place > 0) && (Cond_Stack[Cond_place-1])) 1899 | { 1900 | /* 1901 | | end conditional 1902 | | parsing 1903 | */ 1904 | EVAL = FALSE; 1905 | Otemp++; 1906 | Otemp++; 1907 | } 1908 | else /* condition is false */ 1909 | { 1910 | /* 1911 | | find 'else' or end 1912 | | of if statement 1913 | */ 1914 | while ((strncmp(Otemp, "%e", 2)) && (strncmp(Otemp, "%;", 2)) && (*Otemp != '\0')) 1915 | Otemp++; 1916 | /* 1917 | | if an 'else' found 1918 | */ 1919 | if ((*Otemp != '\0') && (!strncmp(Otemp, "%e", 2))) 1920 | { 1921 | Otemp++; 1922 | Otemp++; 1923 | tchar = Otemp; 1924 | /* 1925 | | check for 'then' part 1926 | */ 1927 | while ((*tchar != '\0') && (strncmp(tchar, "%t", 2)) && (strncmp(tchar, "%;", 2))) 1928 | tchar++; 1929 | /* 1930 | | if end of string 1931 | */ 1932 | if (*tchar == '\0') 1933 | { 1934 | EVAL = FALSE; 1935 | Cond_FLAG = FALSE; 1936 | Otemp = tchar; 1937 | } 1938 | /* 1939 | | if end of if found, 1940 | | set up to parse 1941 | | info 1942 | */ 1943 | else if (!strncmp(tchar, "%;", 2)) 1944 | EVAL = FALSE; 1945 | /* 1946 | | otherwise, check 1947 | | conditional in 1948 | | 'else' 1949 | */ 1950 | } 1951 | /* 1952 | | if end of if found, 1953 | | get out of if 1954 | | statement 1955 | */ 1956 | else if ((*Otemp != '\0') && (!strncmp(Otemp, "%;", 2))) 1957 | { 1958 | EVAL = FALSE; 1959 | Otemp++; 1960 | Otemp++; 1961 | } 1962 | else /* Otemp == NULL */ 1963 | { 1964 | EVAL = FALSE; 1965 | Cond_FLAG = FALSE; 1966 | } 1967 | } 1968 | } 1969 | } 1970 | else 1971 | { 1972 | Otemp++; 1973 | Cond_FLAG = FALSE; 1974 | if (*Otemp != ';') 1975 | { 1976 | while ((*Otemp != '\0') && (strncmp(Otemp, "%;", 2))) 1977 | Otemp++; 1978 | if (*Otemp != '\0') 1979 | { 1980 | Otemp++; 1981 | Otemp++; 1982 | } 1983 | } 1984 | else 1985 | Otemp++; 1986 | } 1987 | } 1988 | else 1989 | { 1990 | Top_of_stack = Operation(Stack, Top_of_stack); 1991 | } 1992 | } 1993 | else if (!strncmp(Otemp, "$<", 2)) 1994 | { 1995 | Otemp++; 1996 | Otemp++; 1997 | delay = atoi(Otemp); 1998 | while (*Otemp != '>') 1999 | Otemp++; 2000 | Otemp++; 2001 | chars = delay * chars_per_millisecond; 2002 | delay = chars; 2003 | if ((chars - delay) > 0.0) 2004 | delay++; 2005 | if (String_table[pc__] == NULL) 2006 | temp = 0; 2007 | else 2008 | temp = *String_table[pc__]; 2009 | for (; delay > 0; delay--) 2010 | putc(temp, stdout); 2011 | } 2012 | else 2013 | { 2014 | putchar(*Otemp); 2015 | Otemp++; 2016 | } 2017 | } 2018 | fflush(stdout); 2019 | } 2020 | #endif 2021 | 2022 | void 2023 | wmove(window, row, column) /* move cursor to indicated position in window */ 2024 | WINDOW *window; 2025 | int row, column; 2026 | { 2027 | if ((row < window->Num_lines) && (column < window->Num_cols)) 2028 | { 2029 | window->LX = column; 2030 | window->LY = row; 2031 | } 2032 | } 2033 | 2034 | void 2035 | clear_line(line, column, cols) 2036 | struct _line *line; 2037 | int column; 2038 | int cols; 2039 | { 2040 | int j; 2041 | 2042 | if (column > line->last_char) 2043 | { 2044 | for (j = line->last_char; j < column; j++) 2045 | { 2046 | line->row[j] = ' '; 2047 | line->attributes[j] = '\0'; 2048 | } 2049 | } 2050 | line->last_char = column; 2051 | line->row[column] = '\0'; 2052 | line->attributes[column] = '\0'; 2053 | line->changed = TRUE; 2054 | } 2055 | 2056 | void 2057 | werase(window) /* clear the specified window */ 2058 | WINDOW *window; 2059 | { 2060 | int i; 2061 | struct _line *tmp; 2062 | 2063 | window->SCROLL_CLEAR = CLEAR; 2064 | window->scroll_up = window->scroll_down = 0; 2065 | for (i = 0, tmp = window->first_line; i < window->Num_lines; i++, tmp = tmp->next_screen) 2066 | clear_line(tmp, 0, window->Num_cols); 2067 | } 2068 | 2069 | void 2070 | wclrtoeol(window) /* erase from current cursor position to end of line */ 2071 | WINDOW *window; 2072 | { 2073 | int column, row; 2074 | struct _line *tmp; 2075 | 2076 | window->SCROLL_CLEAR = CHANGE; 2077 | column = window->LX; 2078 | row = window->LY; 2079 | for (row = 0, tmp = window->first_line; row < window->LY; row++) 2080 | tmp = tmp->next_screen; 2081 | clear_line(tmp, column, window->Num_cols); 2082 | } 2083 | 2084 | void 2085 | wrefresh(window) /* flush all previous output */ 2086 | WINDOW *window; 2087 | { 2088 | wnoutrefresh(window); 2089 | #ifdef DIAG 2090 | { 2091 | struct _line *temp; 2092 | int value; 2093 | fprintf(stderr, "columns=%d, lines=%d, SC=%d, SR=%d\n",window->Num_cols, window->Num_lines, window->SC, window->SR); 2094 | for (value = 0, temp = window->first_line; value < window->Num_lines; value++, temp = temp->next_screen) 2095 | { 2096 | if (temp->number == -1) 2097 | fprintf(stderr, "line moved "); 2098 | if (temp->scroll) 2099 | fprintf(stderr, "scroll_x is set: "); 2100 | fprintf(stderr, "lc%d=%s|\n", temp->last_char, temp->row); 2101 | } 2102 | fprintf(stderr, "+-------------------- virtual screen ----------------------------------------+\n"); 2103 | fprintf(stderr, "columns=%d, lines=%d \n",virtual_scr->Num_cols, virtual_scr->Num_lines); 2104 | for (value = 0, temp = virtual_scr->first_line; value < virtual_scr->Num_lines; value++, temp = temp->next_screen) 2105 | { 2106 | if (temp->number == -1) 2107 | fprintf(stderr, "line moved "); 2108 | if (temp->scroll) 2109 | fprintf(stderr, "scroll_x is set: "); 2110 | fprintf(stderr, "lc%d=%s|\n", temp->last_char, temp->row); 2111 | } 2112 | fprintf(stderr, "columns=%d, lines=%d \n",curscr->Num_cols, curscr->Num_lines); 2113 | for (value = 0, temp = curscr->first_line; value < curscr->Num_lines; value++, temp = temp->next_screen) 2114 | fprintf(stderr, "line=%s|\n", temp->row); 2115 | } 2116 | #endif 2117 | doupdate(); 2118 | virtual_scr->SCROLL_CLEAR = FALSE; 2119 | virtual_scr->scroll_down = virtual_scr->scroll_up = 0; 2120 | fflush(stdout); 2121 | } 2122 | 2123 | void 2124 | touchwin(window) 2125 | WINDOW *window; 2126 | { 2127 | struct _line *user_line; 2128 | int line_counter = 0; 2129 | 2130 | for (line_counter = 0, user_line = window->first_line; 2131 | line_counter < window->Num_lines; line_counter++) 2132 | { 2133 | user_line->changed = TRUE; 2134 | } 2135 | window->SCROLL_CLEAR = TRUE; 2136 | } 2137 | 2138 | void 2139 | wnoutrefresh(window) 2140 | WINDOW *window; 2141 | { 2142 | struct _line *user_line; 2143 | struct _line *virtual_line; 2144 | int line_counter = 0; 2145 | int user_col = 0; 2146 | int virt_col = 0; 2147 | 2148 | if (window->SR >= virtual_scr->Num_lines) 2149 | return; 2150 | user_line = window->first_line; 2151 | virtual_line = virtual_scr->first_line; 2152 | virtual_scr->SCROLL_CLEAR = window->SCROLL_CLEAR; 2153 | virtual_scr->LX = window->LX + window->SC; 2154 | virtual_scr->LY = window->LY + window->SR; 2155 | virtual_scr->scroll_up = window->scroll_up; 2156 | virtual_scr->scroll_down = window->scroll_down; 2157 | if ((last_window_refreshed == window) && (!window->SCROLL_CLEAR)) 2158 | return; 2159 | for (line_counter = 0; line_counter < window->SR; line_counter++) 2160 | { 2161 | virtual_line = virtual_line->next_screen; 2162 | } 2163 | for (line_counter = 0; (line_counter < window->Num_lines) 2164 | && ((line_counter + window->SR) < virtual_scr->Num_lines); 2165 | line_counter++) 2166 | { 2167 | if ((last_window_refreshed != window) || (user_line->changed) || ((SCROLL | CLEAR) & window->SCROLL_CLEAR)) 2168 | { 2169 | for (user_col = 0, virt_col = window->SC; 2170 | (virt_col < virtual_scr->Num_cols) 2171 | && (user_col < user_line->last_char); 2172 | virt_col++, user_col++) 2173 | { 2174 | virtual_line->row[virt_col] = user_line->row[user_col]; 2175 | virtual_line->attributes[virt_col] = user_line->attributes[user_col]; 2176 | } 2177 | for (user_col = user_line->last_char, 2178 | virt_col = window->SC + user_line->last_char; 2179 | (virt_col < virtual_scr->Num_cols) 2180 | && (user_col < window->Num_cols); 2181 | virt_col++, user_col++) 2182 | { 2183 | virtual_line->row[virt_col] = ' '; 2184 | virtual_line->attributes[virt_col] = '\0'; 2185 | } 2186 | } 2187 | if (virtual_scr->Num_cols != window->Num_cols) 2188 | { 2189 | if (virtual_line->last_char < (user_line->last_char + window->SC)) 2190 | { 2191 | if (virtual_line->row[virtual_line->last_char] == '\0') 2192 | virtual_line->row[virtual_line->last_char] = ' '; 2193 | virtual_line->last_char = 2194 | min(virtual_scr->Num_cols, 2195 | (user_line->last_char + window->SC)); 2196 | } 2197 | } 2198 | else 2199 | virtual_line->last_char = user_line->last_char; 2200 | virtual_line->row[virtual_line->last_char] = '\0'; 2201 | virtual_line->changed = user_line->changed; 2202 | virtual_line = virtual_line->next_screen; 2203 | user_line = user_line->next_screen; 2204 | } 2205 | window->SCROLL_CLEAR = FALSE; 2206 | window->scroll_up = window->scroll_down = 0; 2207 | last_window_refreshed = window; 2208 | } 2209 | 2210 | void 2211 | flushinp() /* flush input */ 2212 | { 2213 | } 2214 | 2215 | void 2216 | ungetch(c) /* push a character back on input */ 2217 | int c; 2218 | { 2219 | if (bufp < 100) 2220 | in_buff[bufp++] = c; 2221 | } 2222 | 2223 | #ifdef BSD_SELECT 2224 | int 2225 | timed_getchar() 2226 | { 2227 | struct timeval tv; 2228 | fd_set fds; 2229 | int ret_val; 2230 | int nfds = 1; 2231 | char temp; 2232 | 2233 | FD_ZERO(&fds); 2234 | tv.tv_sec = 0; 2235 | tv.tv_usec = 500000; /* half a second */ 2236 | FD_SET(0, &fds); 2237 | Time_Out = FALSE; /* just in case */ 2238 | 2239 | ret_val = select(nfds, &fds, 0, 0, &tv); 2240 | 2241 | /* 2242 | | if ret_val is less than zero, there was no input 2243 | | otherwise, get a character and return it 2244 | */ 2245 | 2246 | if (ret_val <= 0) 2247 | { 2248 | Time_Out = TRUE; 2249 | return(-1); 2250 | } 2251 | 2252 | return(read(0, &temp, 1)? temp : -1); 2253 | } 2254 | #endif 2255 | 2256 | int 2257 | wgetch(window) /* get character from specified window */ 2258 | WINDOW *window; 2259 | { 2260 | int in_value; 2261 | char temp; 2262 | #ifndef SYS5 2263 | int old_arg; 2264 | #endif /* SYS5 */ 2265 | 2266 | #ifdef BSD_SELECT 2267 | if (Noblock) 2268 | in_value = ((bufp > 0) ? in_buff[--bufp] : timed_getchar()); 2269 | else 2270 | in_value = ((bufp > 0) ? in_buff[--bufp] : read(0, &temp, 1)? temp : -1); 2271 | #else /* BSD_SELECT */ 2272 | #ifdef SYS5 2273 | in_value = ((bufp > 0) ? in_buff[--bufp] : 2274 | (read(0, &temp, 1)> 0) ? temp : -1); 2275 | #else /* SYS5 */ 2276 | if (Noblock) 2277 | { 2278 | Time_Out = FALSE; 2279 | old_arg = fcntl(0, F_GETFL, 0); 2280 | in_value = fcntl(0, F_SETFL, old_arg | FNDELAY); 2281 | } 2282 | in_value = ((bufp > 0) ? in_buff[--bufp] : read(0, &temp, 1)? temp : -1); 2283 | if (Noblock) 2284 | { 2285 | fcntl(0, F_SETFL, old_arg); 2286 | if (Time_Out) 2287 | in_value = -1; 2288 | } 2289 | #endif /* SYS5 */ 2290 | #endif /* BSD_SELECT */ 2291 | 2292 | if (in_value != -1) 2293 | { 2294 | in_value &= 0xff; 2295 | if ((Parity) && (Num_bits < 8)) 2296 | /* strip eighth bit if parity in use */ 2297 | in_value &= 0177; 2298 | } 2299 | else if (interrupt_flag) 2300 | { 2301 | interrupt_flag = FALSE; 2302 | in_value = wgetch(window); 2303 | } 2304 | 2305 | if ((in_value == '\033') || (in_value == '\037'))/* escape character */ 2306 | in_value = Get_key(in_value); 2307 | return(in_value); 2308 | } 2309 | 2310 | #ifndef BSD_SELECT 2311 | void 2312 | Clear(arg) /* notify that time out has occurred */ 2313 | int arg; 2314 | { 2315 | Time_Out = TRUE; 2316 | #ifdef DEBUG 2317 | fprintf(stderr, "inside Clear()\n"); 2318 | fflush(stderr); 2319 | #endif /* DEBUG */ 2320 | } 2321 | #endif /* BSD_SELECT */ 2322 | 2323 | int 2324 | Get_key(first_char) /* try to decode key sequence */ 2325 | int first_char; /* first character of sequence */ 2326 | { 2327 | int in_char; 2328 | int Count; 2329 | char string[128]; 2330 | char *Gtemp; 2331 | int Found; 2332 | #ifdef SYS5 2333 | struct termio Gterminal; 2334 | #else 2335 | struct sgttyb Gterminal; 2336 | #endif 2337 | struct KEY_STACK *St_point; 2338 | #if (!defined( BSD_SELECT)) || (!defined(SYS5)) 2339 | int value; 2340 | #endif /* BSD_SELECT */ 2341 | 2342 | Count = 0; 2343 | Gtemp = string; 2344 | string[Count++] = first_char; 2345 | string[Count] = '\0'; 2346 | Time_Out = FALSE; 2347 | #ifndef BSD_SELECT 2348 | signal(SIGALRM, Clear); 2349 | value = alarm(1); 2350 | #endif /* BSD_SELECT */ 2351 | Noblock = TRUE; 2352 | #ifdef SYS5 2353 | Gterminal.c_cc[VTIME] = 0; /* timeout value */ 2354 | Gterminal.c_lflag &= ~ICANON; /* disable canonical operation */ 2355 | Gterminal.c_lflag &= ~ECHO; /* disable echo */ 2356 | #endif 2357 | Count = 1; 2358 | Found = FALSE; 2359 | while ((Count < Max_Key_len) && (!Time_Out) && (!Found)) 2360 | { 2361 | in_char = wgetch(stdscr); 2362 | #ifdef DEBUG 2363 | fprintf(stderr, "back in GetKey()\n"); 2364 | fflush(stderr); 2365 | #endif /* DEBUG */ 2366 | if (in_char != -1) 2367 | { 2368 | string[Count++] = in_char; 2369 | string[Count] = '\0'; 2370 | St_point = KEY_TOS; 2371 | while ((St_point != NULL) && (!Found)) 2372 | { 2373 | if (!strcmp(string, St_point->element->string)) 2374 | Found = TRUE; 2375 | else 2376 | St_point = St_point->next; 2377 | } 2378 | } 2379 | } 2380 | #ifndef BSD_SELECT 2381 | if (!Time_Out) 2382 | value = alarm(0); 2383 | #endif /* BSD_SELECT */ 2384 | #ifdef SYS5 2385 | /* value = ioctl(0, TCSETA, &Terminal);*/ 2386 | #else 2387 | value = ioctl(0, TIOCSETP, &Terminal); 2388 | /* value = fcntl(0, F_SETFL, old_arg);*/ 2389 | #endif 2390 | Noblock = FALSE; 2391 | if (Found) 2392 | { 2393 | return(St_point->element->value); 2394 | } 2395 | else 2396 | { 2397 | while (Count > 1) 2398 | { 2399 | if ((string[--Count] != -1) && 2400 | ((unsigned char) (string[Count]) != 255)) 2401 | { 2402 | #ifdef DIAG 2403 | fprintf(stderr, "ungetting character %d\n", string[Count]);fflush(stdout); 2404 | #endif 2405 | ungetch(string[Count]); 2406 | } 2407 | } 2408 | return(first_char); 2409 | } 2410 | } 2411 | 2412 | void 2413 | waddch(window, c) /* output the character in the specified window */ 2414 | WINDOW *window; 2415 | int c; 2416 | { 2417 | int column, j; 2418 | int shift; /* number of spaces to shift if a tab */ 2419 | struct _line *tmpline; 2420 | 2421 | #ifdef DIAG 2422 | /*printf("starting waddch \n");fflush(stdout);*/ 2423 | #endif 2424 | column = window->LX; 2425 | if (c == '\t') 2426 | { 2427 | shift = (column + 1) % 8; 2428 | if (shift == 0) 2429 | shift++; 2430 | else 2431 | shift = 9 - shift; 2432 | while (shift > 0) 2433 | { 2434 | shift--; 2435 | waddch(window, ' '); 2436 | } 2437 | } 2438 | else if ((column < window->Num_cols) && (window->LY < window->Num_lines)) 2439 | { 2440 | if ((c == '~') && (Booleans[hz__])) 2441 | c = '@'; 2442 | 2443 | if (( c != '\b') && (c != '\n') && (c != '\r')) 2444 | { 2445 | tmpline = window->line_array[window->LY]; 2446 | tmpline->row[column] = c; 2447 | tmpline->attributes[column] = window->Attrib; 2448 | tmpline->changed = TRUE; 2449 | if (column >= tmpline->last_char) 2450 | { 2451 | if (column > tmpline->last_char) 2452 | for (j = tmpline->last_char; j < column; j++) 2453 | { 2454 | tmpline->row[j] = ' '; 2455 | tmpline->attributes[j] = '\0'; 2456 | } 2457 | tmpline->row[column + 1] = '\0'; 2458 | tmpline->attributes[column + 1] = '\0'; 2459 | tmpline->last_char = column + 1; 2460 | } 2461 | } 2462 | if (c == '\n') 2463 | { 2464 | wclrtoeol(window); 2465 | window->LX = window->Num_cols; 2466 | } 2467 | else if (c == '\r') 2468 | window->LX = 0; 2469 | else if (c == '\b') 2470 | window->LX--; 2471 | else 2472 | window->LX++; 2473 | } 2474 | if (window->LX >= window->Num_cols) 2475 | { 2476 | window->LX = 0; 2477 | window->LY++; 2478 | if (window->LY >= window->Num_lines) 2479 | { 2480 | window->LY = window->Num_lines - 1; 2481 | /* window->LY = row; 2482 | wmove(window, 0, 0); 2483 | wdeleteln(window); 2484 | wmove(window, row, 0);*/ 2485 | } 2486 | } 2487 | window->SCROLL_CLEAR = CHANGE; 2488 | } 2489 | 2490 | void 2491 | winsertln(window) /* insert a blank line into the specified window */ 2492 | WINDOW *window; 2493 | { 2494 | int row, column; 2495 | struct _line *tmp; 2496 | struct _line *tmp1; 2497 | 2498 | window->scroll_down += 1; 2499 | window->SCROLL_CLEAR = SCROLL; 2500 | column = window->LX; 2501 | row = window->LY; 2502 | for (row = 0, tmp = window->first_line; (row < window->Num_lines) && (tmp->next_screen != NULL); row++) 2503 | tmp = tmp->next_screen; 2504 | if (tmp->prev_screen != NULL) 2505 | tmp->prev_screen->next_screen = NULL; 2506 | tmp1 = tmp; 2507 | clear_line(tmp1, 0, window->Num_cols); 2508 | tmp1->number = -1; 2509 | for (row = 0, tmp = window->first_line; (row < window->LY) && (tmp->next_screen != NULL); row++) 2510 | tmp = tmp->next_screen; 2511 | if ((window->LY == (window->Num_lines - 1)) && (window->Num_lines > 1)) 2512 | { 2513 | tmp1->next_screen = tmp->next_screen; 2514 | tmp->next_screen = tmp1; 2515 | tmp->changed = TRUE; 2516 | tmp->next_screen->prev_screen = tmp; 2517 | } 2518 | else if (window->Num_lines > 1) 2519 | { 2520 | if (tmp->prev_screen != NULL) 2521 | tmp->prev_screen->next_screen = tmp1; 2522 | tmp1->prev_screen = tmp->prev_screen; 2523 | tmp->prev_screen = tmp1; 2524 | tmp1->next_screen = tmp; 2525 | tmp->changed = TRUE; 2526 | tmp->scroll = DOWN; 2527 | } 2528 | if (window->LY == 0) 2529 | window->first_line = tmp1; 2530 | 2531 | for (row = 0, tmp1 = window->first_line; 2532 | row < window->Num_lines; row++) 2533 | { 2534 | window->line_array[row] = tmp1; 2535 | tmp1 = tmp1->next_screen; 2536 | } 2537 | } 2538 | 2539 | void 2540 | wdeleteln(window) /* delete a line in the specified window */ 2541 | WINDOW *window; 2542 | { 2543 | int row, column; 2544 | struct _line *tmp; 2545 | struct _line *tmpline; 2546 | 2547 | if (window->Num_lines > 1) 2548 | { 2549 | window->scroll_up += 1; 2550 | window->SCROLL_CLEAR = SCROLL; 2551 | column = window->LX; 2552 | row = window->LY; 2553 | for (row = 0, tmp = window->first_line; row < window->LY; row++) 2554 | tmp = tmp->next_screen; 2555 | if (window->LY == 0) 2556 | window->first_line = tmp->next_screen; 2557 | if (tmp->prev_screen != NULL) 2558 | tmp->prev_screen->next_screen = tmp->next_screen; 2559 | if (tmp->next_screen != NULL) 2560 | { 2561 | tmp->next_screen->changed = TRUE; 2562 | tmp->next_screen->scroll = UP; 2563 | tmp->next_screen->prev_screen = tmp->prev_screen; 2564 | } 2565 | tmpline = tmp; 2566 | clear_line(tmpline, 0, window->Num_cols); 2567 | tmpline->number = -1; 2568 | for (row = 0, tmp = window->first_line; tmp->next_screen != NULL; row++) 2569 | tmp = tmp->next_screen; 2570 | if (tmp != NULL) 2571 | { 2572 | tmp->next_screen = tmpline; 2573 | tmp->next_screen->prev_screen = tmp; 2574 | tmp->changed = TRUE; 2575 | tmp = tmp->next_screen; 2576 | } 2577 | else 2578 | tmp = tmpline; 2579 | tmp->next_screen = NULL; 2580 | 2581 | for (row = 0, tmp = window->first_line; row < window->Num_lines; row++) 2582 | { 2583 | window->line_array[row] = tmp; 2584 | tmp = tmp->next_screen; 2585 | } 2586 | } 2587 | else 2588 | { 2589 | clear_line(window->first_line, 0, window->Num_cols); 2590 | } 2591 | } 2592 | 2593 | void 2594 | wclrtobot(window) /* delete from current position to end of the window */ 2595 | WINDOW *window; 2596 | { 2597 | int row, column; 2598 | struct _line *tmp; 2599 | 2600 | window->SCROLL_CLEAR |= CLEAR; 2601 | column = window->LX; 2602 | row = window->LY; 2603 | for (row = 0, tmp = window->first_line; row < window->LY; row++) 2604 | tmp = tmp->next_screen; 2605 | clear_line(tmp, column, window->Num_cols); 2606 | for (row = (window->LY + 1); row < window->Num_lines; row++) 2607 | { 2608 | tmp = tmp->next_screen; 2609 | clear_line(tmp, 0, window->Num_cols); 2610 | } 2611 | wmove(window, row, column); 2612 | } 2613 | 2614 | void 2615 | wstandout(window) /* begin standout mode in window */ 2616 | WINDOW *window; 2617 | { 2618 | if (Numbers[sg__] < 1) /* if not magic cookie glitch */ 2619 | window->Attrib |= A_STANDOUT; 2620 | } 2621 | 2622 | void 2623 | wstandend(window) /* end standout mode in window */ 2624 | WINDOW *window; 2625 | { 2626 | window->Attrib &= ~A_STANDOUT; 2627 | } 2628 | 2629 | void 2630 | waddstr(window, string) /* write 'string' in window */ 2631 | WINDOW *window; 2632 | char *string; 2633 | { 2634 | char *wstring; 2635 | 2636 | for (wstring = string; *wstring != '\0'; wstring++) 2637 | waddch(window, *wstring); 2638 | } 2639 | 2640 | void 2641 | clearok(window, flag) /* erase screen and redraw at next refresh */ 2642 | WINDOW *window; 2643 | int flag; 2644 | { 2645 | Repaint_screen = TRUE; 2646 | } 2647 | 2648 | 2649 | void 2650 | echo() /* turn on echoing */ 2651 | { 2652 | int value; 2653 | 2654 | #ifdef SYS5 2655 | Terminal.c_lflag |= ECHO; /* enable echo */ 2656 | value = ioctl(0, TCSETA, &Terminal); /* set characteristics */ 2657 | #else 2658 | Terminal.sg_flags |= ECHO; /* enable echo */ 2659 | value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */ 2660 | #endif 2661 | } 2662 | 2663 | void 2664 | noecho() /* turn off echoing */ 2665 | { 2666 | int value; 2667 | 2668 | #ifdef SYS5 2669 | Terminal.c_lflag &= ~ECHO; /* disable echo */ 2670 | value = ioctl(0, TCSETA, &Terminal); /* set characteristics */ 2671 | #else 2672 | Terminal.sg_flags &= ~ECHO; /* disable echo */ 2673 | value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */ 2674 | #endif 2675 | } 2676 | 2677 | void 2678 | raw() /* set to read characters immediately */ 2679 | { 2680 | int value; 2681 | 2682 | #ifdef SYS5 2683 | Intr = Terminal.c_cc[VINTR]; /* get the interrupt character */ 2684 | Terminal.c_lflag &= ~ICANON; /* disable canonical operation */ 2685 | Terminal.c_lflag &= ~ISIG; /* disable signal checking */ 2686 | #ifdef FLUSHO 2687 | Terminal.c_lflag &= ~FLUSHO; 2688 | #endif 2689 | #ifdef PENDIN 2690 | Terminal.c_lflag &= ~PENDIN; 2691 | #endif 2692 | #ifdef IEXTEN 2693 | Terminal.c_lflag &= ~IEXTEN; 2694 | #endif 2695 | Terminal.c_cc[VMIN] = 1; /* minimum of one character */ 2696 | Terminal.c_cc[VTIME] = 0; /* timeout value */ 2697 | Terminal.c_cc[VINTR] = 0; /* eliminate interrupt */ 2698 | value = ioctl(0, TCSETA, &Terminal); /* set characteristics */ 2699 | #else 2700 | Terminal.sg_flags |= RAW; /* enable raw mode */ 2701 | value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */ 2702 | #endif 2703 | } 2704 | 2705 | void 2706 | noraw() /* set to normal character read mode */ 2707 | { 2708 | int value; 2709 | 2710 | #ifdef SYS5 2711 | Terminal.c_lflag |= ICANON; /* enable canonical operation */ 2712 | Terminal.c_lflag |= ISIG; /* enable signal checking */ 2713 | Terminal.c_cc[VEOF] = 4; /* EOF character = 4 */ 2714 | Terminal.c_cc[VEOL] = '\0'; /* EOL = 0 */ 2715 | Terminal.c_cc[VINTR] = Intr; /* reset interrupt char */ 2716 | value = ioctl(0, TCSETA, &Terminal); /* set characteristics */ 2717 | #else 2718 | Terminal.sg_flags &= ~RAW; /* disable raw mode */ 2719 | value = ioctl(0, TIOCSETP, &Terminal); /* set characteristics */ 2720 | /* old_arg = fcntl(0, F_GETFL, 0); 2721 | value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/ 2722 | #endif 2723 | } 2724 | 2725 | void 2726 | nl() 2727 | { 2728 | int value; 2729 | 2730 | #ifdef SYS5 2731 | Terminal.c_iflag |= ICRNL; /* enable carriage-return to line-feed mapping */ 2732 | value = ioctl(0, TCSETA, &Terminal); /* set characteristics */ 2733 | #endif 2734 | } 2735 | 2736 | void 2737 | nonl() 2738 | { 2739 | int value; 2740 | 2741 | #ifdef SYS5 2742 | Terminal.c_iflag &= ~ICRNL; /* disable carriage-return to line-feed mapping */ 2743 | Terminal.c_iflag &= ~IGNCR; /* do not ignore carriage-return */ 2744 | value = ioctl(0, TCSETA, &Terminal); /* set characteristics */ 2745 | #endif 2746 | } 2747 | 2748 | void 2749 | saveterm() 2750 | { 2751 | } 2752 | 2753 | void 2754 | fixterm() 2755 | { 2756 | } 2757 | 2758 | void 2759 | resetterm() 2760 | { 2761 | } 2762 | 2763 | void 2764 | nodelay(window, flag) 2765 | WINDOW *window; 2766 | int flag; 2767 | { 2768 | } 2769 | 2770 | void 2771 | idlok(window, flag) 2772 | WINDOW *window; 2773 | int flag; 2774 | { 2775 | } 2776 | 2777 | void 2778 | keypad(window, flag) 2779 | WINDOW *window; 2780 | int flag; 2781 | { 2782 | if (flag) 2783 | String_Out(String_table[ks__], NULL, 0); 2784 | else 2785 | String_Out(String_table[ke__], NULL, 0); 2786 | } 2787 | 2788 | void 2789 | savetty() /* save current tty stats */ 2790 | { 2791 | int value; 2792 | 2793 | #ifdef SYS5 2794 | value = ioctl(0, TCGETA, &Saved_tty); /* set characteristics */ 2795 | #else 2796 | value = ioctl(0, TIOCGETP, &Saved_tty); /* set characteristics */ 2797 | #endif 2798 | } 2799 | 2800 | void 2801 | resetty() /* restore previous tty stats */ 2802 | { 2803 | int value; 2804 | 2805 | #ifdef SYS5 2806 | value = ioctl(0, TCSETA, &Saved_tty); /* set characteristics */ 2807 | #else 2808 | value = ioctl(0, TIOCSETP, &Saved_tty); /* set characteristics */ 2809 | #endif 2810 | } 2811 | 2812 | void 2813 | endwin() /* end windows */ 2814 | { 2815 | keypad(stdscr, FALSE); 2816 | initialized = FALSE; 2817 | delwin(curscr); 2818 | delwin(virtual_scr); 2819 | delwin(stdscr); 2820 | #ifndef SYS5 2821 | { 2822 | int old_arg, value; 2823 | /* old_arg = fcntl(0, F_GETFL, 0); 2824 | value = fcntl(0, F_SETFL, old_arg & ~FNDELAY);*/ 2825 | } 2826 | #endif 2827 | } 2828 | 2829 | void 2830 | delwin(window) /* delete the window structure */ 2831 | WINDOW *window; 2832 | { 2833 | int i; 2834 | 2835 | for (i = 1; (i < window->Num_lines) && (window->first_line->next_screen != NULL); i++) 2836 | { 2837 | window->first_line = window->first_line->next_screen; 2838 | free(window->first_line->prev_screen->row); 2839 | free(window->first_line->prev_screen->attributes); 2840 | free(window->first_line->prev_screen); 2841 | } 2842 | if (window == last_window_refreshed) 2843 | last_window_refreshed = 0; 2844 | if (window->first_line != NULL) 2845 | { 2846 | free(window->first_line->row); 2847 | free(window->first_line->attributes); 2848 | free(window->first_line); 2849 | free(window); 2850 | } 2851 | } 2852 | 2853 | #ifndef __STDC__ 2854 | void 2855 | wprintw(va_alist) 2856 | va_dcl 2857 | #else /* __STDC__ */ 2858 | void 2859 | wprintw(WINDOW *window, const char *format, ...) 2860 | #endif /* __STDC__ */ 2861 | { 2862 | #ifndef __STDC__ 2863 | WINDOW *window; 2864 | char *format; 2865 | va_list ap; 2866 | #else 2867 | va_list ap; 2868 | #endif 2869 | int value; 2870 | char *fpoint; 2871 | char *wtemp; 2872 | 2873 | #ifndef __STDC__ 2874 | va_start(ap); 2875 | window = va_arg(ap, WINDOW *); 2876 | format = va_arg(ap, char *); 2877 | #else /* __STDC__ */ 2878 | va_start(ap, format); 2879 | #endif /* __STDC__ */ 2880 | 2881 | fpoint = (char *) format; 2882 | while (*fpoint != '\0') 2883 | { 2884 | if (*fpoint == '%') 2885 | { 2886 | fpoint++; 2887 | if (*fpoint == 'd') 2888 | { 2889 | value = va_arg(ap, int); 2890 | iout(window, value); 2891 | } 2892 | else if (*fpoint == 'c') 2893 | { 2894 | value = va_arg(ap, int); 2895 | waddch(window, value); 2896 | } 2897 | else if (*fpoint == 's') 2898 | { 2899 | wtemp = va_arg(ap, char *); 2900 | waddstr(window, wtemp); 2901 | } 2902 | fpoint++; 2903 | } 2904 | else if (*fpoint == '\\') 2905 | { 2906 | fpoint++; 2907 | if (*fpoint == 'n') 2908 | waddch(window, '\n'); 2909 | else if ((*fpoint >= '0') && (*fpoint <= '9')) 2910 | { 2911 | value = 0; 2912 | while ((*fpoint >= '0') && (*fpoint <= '9')) 2913 | { 2914 | value = (value * 8) + (*fpoint - '0'); 2915 | fpoint++; 2916 | } 2917 | waddch(window, value); 2918 | } 2919 | fpoint++; 2920 | } 2921 | else 2922 | waddch(window, *fpoint++); 2923 | } 2924 | #ifdef __STDC__ 2925 | va_end(ap); 2926 | #endif /* __STDC__ */ 2927 | } 2928 | 2929 | void 2930 | iout(window, value) /* output characters */ 2931 | WINDOW *window; 2932 | int value; 2933 | { 2934 | int i; 2935 | 2936 | if ((i = value / 10) != 0) 2937 | iout(window, i); 2938 | waddch(window, ((value % 10) + '0')); 2939 | } 2940 | 2941 | int 2942 | Comp_line(line1, line2) /* compare lines */ 2943 | struct _line *line1; 2944 | struct _line *line2; 2945 | { 2946 | int count1; 2947 | int i; 2948 | char *att1, *att2; 2949 | char *c1, *c2; 2950 | 2951 | if (line1->last_char != line2->last_char) 2952 | return(2); 2953 | 2954 | c1 = line1->row; 2955 | c2 = line2->row; 2956 | att1 = line1->attributes; 2957 | att2 = line2->attributes; 2958 | i = 0; 2959 | while ((c1[i] != '\0') && (c2[i] != '\0') && (c1[i] == c2[i]) && (att1[i] == att2[i])) 2960 | i++; 2961 | count1 = i + 1; 2962 | if ((count1 == 1) && (c1[i] == '\0') && (c2[i] == '\0')) 2963 | count1 = 0; /* both lines blank */ 2964 | else if ((c1[i] == '\0') && (c2[i] == '\0')) 2965 | count1 = -1; /* equal */ 2966 | else 2967 | count1 = 1; /* lines unequal */ 2968 | return(count1); 2969 | } 2970 | 2971 | struct _line * 2972 | Insert_line(row, end_row, window) /* insert line into screen */ 2973 | int row; 2974 | int end_row; 2975 | WINDOW *window; 2976 | { 2977 | int i; 2978 | struct _line *tmp; 2979 | struct _line *tmp1; 2980 | 2981 | for (i = 0, tmp = curscr->first_line; i < window->SR; i++) 2982 | tmp = tmp->next_screen; 2983 | if ((end_row + window->SR) == 0) 2984 | curscr->first_line = curscr->first_line->next_screen; 2985 | top_of_win = tmp; 2986 | /* 2987 | | find bottom line to delete 2988 | */ 2989 | for (i = 0, tmp = top_of_win; (tmp->next_screen != NULL) && (i < end_row); i++) 2990 | tmp = tmp->next_screen; 2991 | if (tmp->prev_screen != NULL) 2992 | tmp->prev_screen->next_screen = tmp->next_screen; 2993 | if (tmp->next_screen != NULL) 2994 | tmp->next_screen->prev_screen = tmp->prev_screen; 2995 | tmp1 = tmp; 2996 | /* 2997 | | clear deleted line 2998 | */ 2999 | clear_line(tmp, 0, window->Num_cols); 3000 | tmp1->number = -1; 3001 | for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++) 3002 | tmp = tmp->next_screen; 3003 | top_of_win = tmp; 3004 | for (i = 0, tmp = top_of_win; i < row; i++) 3005 | tmp = tmp->next_screen; 3006 | if ((tmp->prev_screen != NULL) && (window->Num_lines > 0)) 3007 | tmp->prev_screen->next_screen = tmp1; 3008 | tmp1->prev_screen = tmp->prev_screen; 3009 | tmp->prev_screen = tmp1; 3010 | tmp1->next_screen = tmp; 3011 | if ((row + window->SR) == 0) 3012 | curscr->first_line = tmp1; 3013 | if (tmp1->next_screen != NULL) 3014 | tmp1 = tmp1->next_screen; 3015 | 3016 | if ((!String_table[cs__]) && (end_row < window->Num_lines)) 3017 | { 3018 | Position(window, (window->SR + end_row), 0); 3019 | String_Out(String_table[dl__], NULL, 0); 3020 | } 3021 | Position(window, (window->SR + row), 0); 3022 | if (String_table[al__] != NULL) 3023 | String_Out(String_table[al__], NULL, 0); 3024 | else 3025 | String_Out(String_table[sr__], NULL, 0); 3026 | 3027 | for (i = 0, top_of_win = curscr->first_line; (top_of_win->next_screen != NULL) && (i < window->SR); i++) 3028 | top_of_win = top_of_win->next_screen; 3029 | return(tmp1); 3030 | } 3031 | 3032 | 3033 | struct _line * 3034 | Delete_line(row, end_row, window) /* delete a line on screen */ 3035 | int row; 3036 | int end_row; 3037 | WINDOW *window; 3038 | { 3039 | int i; 3040 | struct _line *tmp; 3041 | struct _line *tmp1; 3042 | struct _line *tmp2; 3043 | 3044 | i = 0; 3045 | tmp = curscr->first_line; 3046 | while (i < window->SR) 3047 | { 3048 | i++; 3049 | tmp = tmp->next_screen; 3050 | } 3051 | /* 3052 | | find line to delete 3053 | */ 3054 | top_of_win = tmp; 3055 | if ((row + window->SR) == 0) 3056 | curscr->first_line = top_of_win->next_screen; 3057 | for (i = 0, tmp = top_of_win; i < row; i++) 3058 | tmp = tmp->next_screen; 3059 | if (tmp->prev_screen != NULL) 3060 | tmp->prev_screen->next_screen = tmp->next_screen; 3061 | if (tmp->next_screen != NULL) 3062 | tmp->next_screen->prev_screen = tmp->prev_screen; 3063 | tmp2 = tmp->next_screen; 3064 | tmp1 = tmp; 3065 | /* 3066 | | clear deleted line 3067 | */ 3068 | clear_line(tmp1, 0, window->Num_cols); 3069 | tmp1->number = -1; 3070 | /* 3071 | | find location to insert deleted line 3072 | */ 3073 | for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++) 3074 | tmp = tmp->next_screen; 3075 | top_of_win = tmp; 3076 | for (i = 0, tmp = top_of_win; (i < end_row) && (tmp->next_screen != NULL); i++) 3077 | tmp = tmp->next_screen; 3078 | tmp1->next_screen = tmp; 3079 | tmp1->prev_screen = tmp->prev_screen; 3080 | if (tmp1->prev_screen != NULL) 3081 | tmp1->prev_screen->next_screen = tmp1; 3082 | tmp->prev_screen = tmp1; 3083 | 3084 | Position(window, (window->SR + row), 0); 3085 | String_Out(String_table[dl__], NULL, 0); 3086 | if ((!String_table[cs__]) && (end_row < window->Num_lines)) 3087 | { 3088 | Position(window, (window->SR + end_row), 0); 3089 | String_Out(String_table[al__], NULL, 0); 3090 | } 3091 | else if ((String_table[cs__] != NULL) && (String_table[dl__] == NULL)) 3092 | { 3093 | Position(window, (window->SR + end_row), 0); 3094 | putchar('\n'); 3095 | } 3096 | 3097 | if (row == (window->Num_lines-1)) 3098 | tmp2 = tmp1; 3099 | if ((row + window->SR) == 0) 3100 | curscr->first_line = top_of_win = tmp2; 3101 | return(tmp2); 3102 | } 3103 | 3104 | void 3105 | CLEAR_TO_EOL(window, row, column) 3106 | WINDOW *window; 3107 | int row, column; 3108 | { 3109 | int x, y; 3110 | struct _line *tmp1; 3111 | 3112 | for (y = 0, tmp1 = curscr->first_line; (y < (window->SR+row)) && (tmp1->next_screen != NULL); y++) 3113 | tmp1 = tmp1->next_screen; 3114 | for (x = column; xNum_cols; x++) 3115 | { 3116 | tmp1->row[x] = ' '; 3117 | tmp1->attributes[x] = '\0'; 3118 | } 3119 | tmp1->row[column] = '\0'; 3120 | tmp1->last_char = column; 3121 | if (column < COLS) 3122 | { 3123 | if (STAND) 3124 | { 3125 | STAND = FALSE; 3126 | Position(window, row, column); 3127 | attribute_off(); 3128 | } 3129 | if (String_table[ce__] != NULL) 3130 | String_Out(String_table[ce__], NULL, 0); 3131 | else 3132 | { 3133 | for (x = column; x < window->Num_cols; x++) 3134 | putchar(' '); 3135 | Curr_x = x; 3136 | } 3137 | } 3138 | } 3139 | 3140 | int 3141 | check_delete(window, line, offset, pointer_new, pointer_old) 3142 | WINDOW *window; 3143 | int line, offset; 3144 | struct _line *pointer_new, *pointer_old; 3145 | { 3146 | int end_old; 3147 | int end_new; 3148 | int k; 3149 | int changed; 3150 | char *old_lin; 3151 | char *new_lin; 3152 | char *old_att; 3153 | char *new_att; 3154 | 3155 | changed = FALSE; 3156 | new_lin = pointer_new->row; 3157 | new_att = pointer_new->attributes; 3158 | old_lin = pointer_old->row; 3159 | old_att = pointer_old->attributes; 3160 | end_old = end_new = offset; 3161 | while (((new_lin[end_new] != old_lin[end_old]) || (new_att[end_new] != old_att[end_old])) && (old_lin[end_old] != '\0') && (new_lin[end_old] != '\0')) 3162 | end_old++; 3163 | if (old_lin[end_old] != '\0') 3164 | { 3165 | k = 0; 3166 | 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] != '\0') && (old_lin[end_old+k] != '\0') && (k < 10)) 3167 | k++; 3168 | if ((k > 8) || ((new_lin[end_new+k] == '\0') && (k != 0))) 3169 | { 3170 | if (new_lin[end_new+k] == '\0') 3171 | { 3172 | Position(window, line, (end_new+k)); 3173 | CLEAR_TO_EOL(window, line, (end_new+k)); 3174 | } 3175 | Position(window, line, offset); 3176 | for (k = offset; k < end_old; k++) 3177 | Char_del(old_lin, old_att, offset, window->Num_cols); 3178 | while ((old_lin[offset] != '\0') && (offset < COLS)) 3179 | offset++; 3180 | pointer_old->last_char = offset; 3181 | changed = TRUE; 3182 | } 3183 | } 3184 | return(changed); 3185 | } 3186 | 3187 | /* 3188 | | Check if characters were inserted in the middle of a line, and if 3189 | | so, insert them. 3190 | */ 3191 | 3192 | int 3193 | check_insert(window, line, offset, pointer_new, pointer_old) 3194 | WINDOW *window; 3195 | int line, offset; 3196 | struct _line *pointer_new, *pointer_old; 3197 | { 3198 | int changed; 3199 | int end_old, end_new; 3200 | int k; 3201 | int same = FALSE; 3202 | int old_off; 3203 | int insert; 3204 | char *old_lin; 3205 | char *new_lin; 3206 | char *old_att; 3207 | char *new_att; 3208 | 3209 | changed = FALSE; 3210 | new_lin = pointer_new->row; 3211 | new_att = pointer_new->attributes; 3212 | old_lin = pointer_old->row; 3213 | old_att = pointer_old->attributes; 3214 | end_old = end_new = offset; 3215 | while (((new_lin[end_new] != old_lin[end_old]) || (new_att[end_new] != old_att[end_old])) && (new_lin[end_new] != '\0') && (old_lin[end_new] != '\0')) 3216 | end_new++; 3217 | if (new_lin[end_new] != '\0') 3218 | { 3219 | k = 0; 3220 | 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] != '\0') && (old_lin[end_old+k] != '\0') && (k < 10)) 3221 | k++; 3222 | /* 3223 | | check for commonality between rest of lines (are the old 3224 | | and new lines the same, except for a chunk in the middle?) 3225 | | if the rest of the lines are common, do not insert text 3226 | */ 3227 | old_off = end_new; 3228 | while ((old_lin[old_off] != '\0') && (new_lin[old_off] != '\0') && (old_lin[old_off] == new_lin[old_off]) && (old_att[old_off] == new_att[old_off])) 3229 | old_off++; 3230 | if ((old_lin[old_off] == new_lin[old_off]) && (old_att[old_off] == new_att[old_off])) 3231 | same = TRUE; 3232 | if ((!same) && ((k > 8) || ((new_lin[end_new+k] == '\0') && (k != 0)))) 3233 | { 3234 | Position(window, line, offset); 3235 | insert = FALSE; 3236 | if (String_table[ic__] == NULL) 3237 | { 3238 | String_Out(String_table[im__], NULL, 0); 3239 | insert = TRUE; 3240 | } 3241 | for (k = offset; k < end_new; k++) 3242 | { 3243 | if (!insert) 3244 | String_Out(String_table[ic__], NULL, 0); 3245 | Char_ins(old_lin, old_att, new_lin[k], new_att[k], k, window->Num_cols); 3246 | } 3247 | if (insert) 3248 | String_Out(String_table[ei__], NULL, 0); 3249 | while ((old_lin[offset] != '\0') && (offset < COLS)) 3250 | offset++; 3251 | pointer_old->last_char = offset; 3252 | changed = TRUE; 3253 | } 3254 | } 3255 | return(changed); 3256 | } 3257 | 3258 | void 3259 | doupdate() 3260 | { 3261 | WINDOW *window; 3262 | int similar; 3263 | int diff; 3264 | int begin_old, begin_new; 3265 | int end_old, end_new; 3266 | int count1, j; 3267 | int from_top, tmp_ft, offset; 3268 | int changed; 3269 | int first_time; 3270 | int first_same; 3271 | int last_same; 3272 | int list[10]; 3273 | int bottom; 3274 | 3275 | struct _line *curr; 3276 | struct _line *virt; 3277 | struct _line *old; 3278 | 3279 | struct _line *new; 3280 | 3281 | struct _line *old1, *new1; 3282 | 3283 | char *cur_lin; 3284 | char *vrt_lin; 3285 | char *cur_att; 3286 | char *vrt_att; 3287 | char *att1, *att2; 3288 | char *c1, *c2; 3289 | 3290 | char NC_chinese = FALSE; /* flag to indicate handling Chinese */ 3291 | 3292 | window = virtual_scr; 3293 | 3294 | if ((nc_attributes & A_NC_BIG5) != 0) 3295 | NC_chinese = TRUE; 3296 | 3297 | if (Repaint_screen) 3298 | { 3299 | if (String_table[cl__]) 3300 | String_Out(String_table[cl__], NULL, 0); 3301 | else 3302 | { 3303 | from_top = 0; 3304 | while (from_top < LINES) 3305 | { 3306 | Position(curscr, from_top, 0); 3307 | if (String_table[ce__] != NULL) 3308 | String_Out(String_table[ce__], NULL, 0); 3309 | else 3310 | { 3311 | for (j = 0; j < window->Num_cols; j++) 3312 | putchar(' '); 3313 | } 3314 | from_top++; 3315 | } 3316 | } 3317 | for (from_top = 0, curr = curscr->first_line; from_top < curscr->Num_lines; from_top++, curr = curr->next_screen) 3318 | { 3319 | Position(curscr, from_top, 0); 3320 | for (j = 0; (curr->row[j] != '\0') && (j < curscr->Num_cols); j++) 3321 | { 3322 | Char_out(curr->row[j], curr->attributes[j], curr->row, curr->attributes, j); 3323 | } 3324 | if (STAND) 3325 | { 3326 | STAND = FALSE; 3327 | Position(curscr, from_top, j); 3328 | attribute_off(); 3329 | } 3330 | } 3331 | Repaint_screen = FALSE; 3332 | } 3333 | 3334 | similar = 0; 3335 | diff = FALSE; 3336 | top_of_win = curscr->first_line; 3337 | 3338 | for (from_top = 0, curr = top_of_win, virt = window->first_line; 3339 | from_top < window->Num_lines; from_top++) 3340 | { 3341 | virtual_lines[from_top] = TRUE; 3342 | if ((similar = Comp_line(curr, virt)) > 0) 3343 | { 3344 | virtual_lines[from_top] = FALSE; 3345 | diff = TRUE; 3346 | } 3347 | curr = curr->next_screen; 3348 | virt = virt->next_screen; 3349 | } 3350 | 3351 | from_top = 0; 3352 | virt = window->first_line; 3353 | curr = top_of_win; 3354 | similar = 0; 3355 | /* 3356 | | if the window has lines that are different, check for scrolling 3357 | */ 3358 | if (diff) 3359 | { 3360 | last_same = -1; 3361 | changed = FALSE; 3362 | for (first_same = window->Num_lines; 3363 | (first_same > from_top) && (virtual_lines[first_same - 1]); 3364 | first_same--) 3365 | ; 3366 | for (last_same = 0; 3367 | (last_same < window->Num_lines) && (virtual_lines[last_same]== FALSE); 3368 | last_same++) 3369 | ; 3370 | while ((from_top < first_same) && nc_scrolling_ability) 3371 | /* check entire lines for diffs */ 3372 | { 3373 | 3374 | if (from_top >= last_same) 3375 | { 3376 | for (last_same = from_top; 3377 | (last_same < window->Num_lines) && 3378 | (virtual_lines[last_same] == FALSE); 3379 | last_same++) 3380 | ; 3381 | } 3382 | if (!virtual_lines[from_top]) 3383 | { 3384 | diff = TRUE; 3385 | /* 3386 | | check for lines deleted (scroll up) 3387 | */ 3388 | for (tmp_ft = from_top+1, old = curr->next_screen; 3389 | ((window->scroll_up) && (diff) && 3390 | (tmp_ft < last_same) && 3391 | (!virtual_lines[tmp_ft])); 3392 | tmp_ft++) 3393 | { 3394 | if ((Comp_line(old, virt) == -1) && (!virtual_lines[from_top])) 3395 | { 3396 | /* 3397 | | Find the bottom of the 3398 | | area that should be 3399 | | scrolled. 3400 | */ 3401 | for (bottom = tmp_ft, old1 = old, 3402 | new1 = virt, count1 = 0; 3403 | (bottom < window->Num_lines) && 3404 | (Comp_line(old1, new1) <= 0); 3405 | bottom++, old1 = old1->next_screen, 3406 | new1 = new1->next_screen, 3407 | count1++) 3408 | ; 3409 | if (count1 > 3) 3410 | { 3411 | if (String_table[cs__]) /* scrolling region */ 3412 | { 3413 | list[1] = from_top; 3414 | list[0] = min((bottom - 1), (window->Num_lines - 1)); 3415 | String_Out(String_table[cs__], list, 2); 3416 | Curr_y = Curr_x = -1; 3417 | } 3418 | 3419 | for (offset = (tmp_ft - from_top); (offset > 0); offset--) 3420 | { 3421 | old = Delete_line(from_top, min((bottom - 1), (window->Num_lines - 1)), window); 3422 | diff = FALSE; 3423 | } 3424 | 3425 | if (String_table[cs__]) /* scrolling region */ 3426 | { 3427 | list[1] = 0; 3428 | list[0] = LINES - 1; 3429 | String_Out(String_table[cs__], list, 2); 3430 | Curr_y = Curr_x = -1; 3431 | } 3432 | 3433 | top_of_win = curscr->first_line; 3434 | curr = top_of_win; 3435 | for (offset = 0; offset < from_top; offset++) 3436 | curr = curr->next_screen; 3437 | for (offset = from_top, old=curr, new=virt; 3438 | offset < window->Num_lines; 3439 | old=old->next_screen, new=new->next_screen, 3440 | offset++) 3441 | { 3442 | similar = Comp_line(old, new); 3443 | virtual_lines[offset] = (similar > 0 ? FALSE : TRUE); 3444 | } 3445 | } 3446 | } 3447 | else 3448 | old = old->next_screen; 3449 | } 3450 | /* 3451 | | check for lines inserted (scroll down) 3452 | */ 3453 | for (tmp_ft = from_top-1, old = curr->prev_screen; 3454 | ((window->scroll_down) && (tmp_ft >= 0) && 3455 | (diff) && 3456 | (!virtual_lines[tmp_ft])); 3457 | tmp_ft--) 3458 | { 3459 | if (Comp_line(old, virt) == -1) 3460 | { 3461 | /* 3462 | | Find the bottom of the 3463 | | area that should be 3464 | | scrolled. 3465 | */ 3466 | for (bottom = from_top, old1 = old, 3467 | new1 = virt, count1 = 0; 3468 | (bottom < window->Num_lines) && 3469 | (Comp_line(old1, new1) <= 0); 3470 | bottom++, old1 = old1->next_screen, 3471 | new1 = new1->next_screen, 3472 | count1++) 3473 | ; 3474 | if (count1 > 3) 3475 | { 3476 | if (String_table[cs__]) /* scrolling region */ 3477 | { 3478 | list[1] = tmp_ft; 3479 | list[0] = min((bottom - 1), (window->Num_lines - 1)); 3480 | String_Out(String_table[cs__], list, 2); 3481 | Curr_y = Curr_x = -1; 3482 | } 3483 | 3484 | for (offset = (from_top - tmp_ft); (offset > 0); offset--) 3485 | { 3486 | old = Insert_line(tmp_ft, min((bottom - 1), (window->Num_lines -1)), window); 3487 | diff = FALSE; 3488 | } 3489 | 3490 | if (String_table[cs__]) /* scrolling region */ 3491 | { 3492 | list[1] = 0; 3493 | list[0] = LINES - 1; 3494 | String_Out(String_table[cs__], list, 2); 3495 | Curr_y = Curr_x = -1; 3496 | } 3497 | 3498 | top_of_win = curscr->first_line; 3499 | curr = top_of_win; 3500 | for (offset = 0; offset < from_top; offset++) 3501 | curr = curr->next_screen; 3502 | for (offset = from_top, old=curr, new=virt; 3503 | offset < window->Num_lines; 3504 | old=old->next_screen, new=new->next_screen, 3505 | offset++) 3506 | { 3507 | similar = Comp_line(old, new); 3508 | virtual_lines[offset] = (similar > 0 ? FALSE : TRUE); 3509 | } 3510 | } 3511 | } 3512 | else 3513 | old = old->prev_screen; 3514 | } 3515 | } 3516 | from_top++; 3517 | curr = curr->next_screen; 3518 | virt = virt->next_screen; 3519 | } 3520 | } 3521 | 3522 | 3523 | /* 3524 | | Scrolling done, now need to insert, delete, or modify text 3525 | | within lines. 3526 | */ 3527 | 3528 | for (from_top = 0, curr = curscr->first_line; from_top < window->SR; from_top++) 3529 | curr = curr->next_screen; 3530 | top_of_win = curr; 3531 | 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) 3532 | { 3533 | 3534 | /* 3535 | | If either 'insert mode' or 'insert char' are 3536 | | available, enter the following 'if' statement, 3537 | | else, need to simply rewrite the contents of the line 3538 | | at the point where the contents of the line change. 3539 | */ 3540 | 3541 | if (((String_table[ic__]) || (String_table[im__])) && 3542 | (String_table[dc__]) && (curr->row[0] != '\0') && 3543 | (!NC_chinese)) 3544 | { 3545 | j = 0; 3546 | first_time = TRUE; 3547 | vrt_lin = virt->row; 3548 | vrt_att = virt->attributes; 3549 | cur_lin = curr->row; 3550 | cur_att = curr->attributes; 3551 | while ((vrt_lin[j] != '\0') && (j < window->Num_cols)) 3552 | { 3553 | if ((STAND) && (Booleans[xs__])) 3554 | { 3555 | while ((vrt_lin[j] == cur_lin[j]) && (vrt_att[j] == cur_att[j]) && (vrt_lin[j] != '\0') && (vrt_att[j])) 3556 | j++; 3557 | if ((STAND) && (!vrt_att[j])) 3558 | { 3559 | STAND = FALSE; 3560 | Position(window, from_top, j); 3561 | attribute_off(); 3562 | attribute_off(); 3563 | } 3564 | } 3565 | else 3566 | { 3567 | while ((vrt_lin[j] == cur_lin[j]) && (vrt_att[j] == cur_att[j]) && (vrt_lin[j] != '\0')) 3568 | j++; 3569 | } 3570 | if ((vrt_att[j] != cur_att[j]) && (cur_att[j]) && (Booleans[xs__])) 3571 | { 3572 | Position(window, from_top, j); 3573 | /* CLEAR_TO_EOL(window, from_top, j);*/ 3574 | attribute_off(); 3575 | attribute_off(); 3576 | } 3577 | if (vrt_lin[j] != '\0') 3578 | { 3579 | begin_new = j; 3580 | begin_old = j; 3581 | end_old = j; 3582 | end_new = j; 3583 | if ((first_time) && (virt->changed)) 3584 | { 3585 | if (curr->last_char <= virt->last_char) 3586 | changed = check_insert(window, from_top, j, virt, curr); 3587 | } 3588 | changed = check_delete(window, from_top, j, virt, curr); 3589 | first_time = FALSE; 3590 | virt->changed = FALSE; 3591 | if (!changed) 3592 | changed = check_insert(window, from_top, j, virt, curr); 3593 | if (((!changed) || (cur_lin[j] != vrt_lin[j]) || (cur_att[j] != vrt_att[j])) && (j < window->Num_cols)) 3594 | { 3595 | if ((vrt_lin[j] == ' ') && (cur_lin[j] == '\0') && (vrt_att[j] == cur_att[j])) 3596 | cur_lin[j] = ' '; 3597 | else 3598 | { 3599 | Position(window, from_top, j); 3600 | Char_out(vrt_lin[j], vrt_att[j], cur_lin, cur_att, j); 3601 | } 3602 | } 3603 | if ((vrt_lin[j] != '\0')) 3604 | j++; 3605 | } 3606 | if ((STAND) && (!vrt_att[j])) 3607 | { 3608 | STAND = FALSE; 3609 | Position(window, from_top, j); 3610 | attribute_off(); 3611 | } 3612 | } 3613 | if ((vrt_lin[j] == '\0') && (cur_lin[j] != '\0')) 3614 | { 3615 | Position(window, from_top, j); 3616 | CLEAR_TO_EOL(window, from_top, j); 3617 | } 3618 | } 3619 | else /*if ((similar != -1) && (similar != 0))*/ 3620 | { 3621 | j = 0; 3622 | c1 = curr->row; 3623 | att1 = curr->attributes; 3624 | c2 = virt->row; 3625 | att2 = virt->attributes; 3626 | while ((j < window->Num_cols) && (c2[j] != '\0')) 3627 | { 3628 | while ((c1[j] == c2[j]) && (att1[j] == att2[j]) && (j < window->Num_cols) && (c2[j] != '\0')) 3629 | j++; 3630 | 3631 | /* 3632 | | if previous character is an eight bit 3633 | | char, start redraw from that character 3634 | */ 3635 | 3636 | if ((NC_chinese) && (highbitset(c1[j - 1]))) 3637 | j--; 3638 | begin_old = j; 3639 | begin_new = j; 3640 | if ((j < window->Num_cols) && (c2[j] != '\0')) 3641 | { 3642 | Position(window, from_top, begin_old); 3643 | CLEAR_TO_EOL(window, from_top, j); 3644 | Position(window, from_top, begin_old); 3645 | for (j = begin_old; (c2[j] != '\0') && (j < window->Num_cols); j++) 3646 | Char_out(c2[j], att2[j], c1, att1, j); 3647 | } 3648 | } 3649 | if ((c2[j] == '\0') && (c1[j] != '\0')) 3650 | { 3651 | Position(window, from_top, j); 3652 | CLEAR_TO_EOL(window, from_top, j); 3653 | } 3654 | } 3655 | if (STAND) 3656 | { 3657 | STAND = FALSE; 3658 | Position(window, from_top, j); 3659 | attribute_off(); 3660 | } 3661 | virt->number = from_top; 3662 | } 3663 | Position(window, window->LY, window->LX); 3664 | } 3665 | 3666 | void 3667 | Position(window, row, col) /* position the cursor for output on the screen */ 3668 | WINDOW *window; 3669 | int row; 3670 | int col; 3671 | { 3672 | int list[10]; 3673 | int place; 3674 | 3675 | int pos_row; 3676 | int pos_column; 3677 | 3678 | pos_row = row + window->SR; 3679 | pos_column = col + window->SC; 3680 | if ((pos_row != Curr_y) || (pos_column != Curr_x)) 3681 | { 3682 | if (String_table[cm__] != NULL) /* && (row < window->Num_lines) && (column < window->Num_cols))*/ 3683 | { 3684 | place = 0; 3685 | list[place++] = pos_column; 3686 | list[place++] = pos_row; 3687 | String_Out(String_table[cm__], list, place); 3688 | if ((STAND) && (!Booleans[ms__])) 3689 | attribute_on(); 3690 | } 3691 | Curr_x = pos_column; 3692 | Curr_y = pos_row; 3693 | } 3694 | } 3695 | 3696 | void 3697 | Char_del(line, attrib, offset, maxlen) /* delete chars from line */ 3698 | char *line; 3699 | char *attrib; 3700 | int offset; 3701 | int maxlen; 3702 | { 3703 | int one, two; 3704 | 3705 | for (one = offset, two = offset+1; (line[one] != '\0') && (one < maxlen); one++, two++) 3706 | { 3707 | line[one] = line[two]; 3708 | attrib[one] = attrib[two]; 3709 | } 3710 | String_Out(String_table[dc__], NULL, 0); 3711 | } 3712 | 3713 | void 3714 | Char_ins(line, attrib, newc, newatt, offset, maxlen) /* insert chars in line */ 3715 | char *line; 3716 | char *attrib; 3717 | char newc; 3718 | char newatt; 3719 | int offset; 3720 | int maxlen; 3721 | { 3722 | int one, two; 3723 | 3724 | one = 0; 3725 | while ((line[one] != '\0') && (one < (maxlen - 2))) 3726 | one++; 3727 | for (two = one + 1; (two > offset); one--, two--) 3728 | { 3729 | line[two] = line[one]; 3730 | attrib[two] = attrib[one]; 3731 | } 3732 | line[offset] = newc; 3733 | attrib[offset] = newatt; 3734 | Char_out(newc, newatt, line, attrib, offset); 3735 | } 3736 | 3737 | void 3738 | attribute_on() 3739 | { 3740 | if (String_table[sa__]) 3741 | { 3742 | attributes_set[0] = 1; 3743 | String_Out(String_table[sa__], attributes_set, 1); 3744 | } 3745 | else if (String_table[so__]) 3746 | String_Out(String_table[so__], NULL, 0); 3747 | } 3748 | 3749 | void 3750 | attribute_off() 3751 | { 3752 | if (String_table[me__]) 3753 | String_Out(String_table[me__], NULL, 0); 3754 | else if (String_table[sa__]) 3755 | { 3756 | attributes_set[0] = 0; 3757 | String_Out(String_table[sa__], attributes_set, 1); 3758 | } 3759 | else if (String_table[se__]) 3760 | String_Out(String_table[se__], NULL, 0); 3761 | } 3762 | 3763 | void 3764 | Char_out(newc, newatt, line, attrib, offset) /* output character with proper attribute */ 3765 | char newc; 3766 | char newatt; 3767 | char *line; 3768 | char *attrib; 3769 | int offset; 3770 | { 3771 | 3772 | 3773 | if ((newatt) && (!STAND)) 3774 | { 3775 | STAND = TRUE; 3776 | attribute_on(); 3777 | } 3778 | else if ((STAND) && (!newatt)) 3779 | { 3780 | STAND = FALSE; 3781 | attribute_off(); 3782 | } 3783 | 3784 | if ((newatt) && (STAND) && (Booleans[xs__])) 3785 | { 3786 | attribute_on(); 3787 | } 3788 | 3789 | if (!((Curr_y >= (LINES - 1)) && (Curr_x >= (COLS - 1)))) 3790 | { 3791 | putchar(newc); 3792 | line[offset] = newc; 3793 | attrib[offset] = newatt; 3794 | } 3795 | Curr_x++; 3796 | } 3797 | 3798 | /* 3799 | | 3800 | | The two routines that follow, nc_setattrib(), nc_clearattrib(), are 3801 | | hacks that notify new_curse to handle characters that have the high 3802 | | bit set as the first of two bytes of a multi-byte string. 3803 | | 3804 | */ 3805 | 3806 | void 3807 | nc_setattrib(flag) 3808 | int flag; 3809 | { 3810 | nc_attributes |= flag; 3811 | } 3812 | 3813 | void 3814 | nc_clearattrib(flag) 3815 | int flag; 3816 | { 3817 | nc_attributes &= ~flag; 3818 | } 3819 | 3820 | --------------------------------------------------------------------------------