Subject: v14i061: Jove, an emacs variant, version 4.9, Part05/21 Newsgroups: comp.sources.unix Sender: sources Approved: rsalz@uunet.UU.NET Submitted-by: Jonathan Payne Posting-number: Volume 14, Issue 61 Archive-name: jove4.9/part05 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh './Readme.dos' <<'END_OF_FILE' X########################################################################### X# This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE # X# is provided to you without charge, and with no warranty. You may give # X# away copies of JOVE, including sources, provided that this notice is # X# included in all the files. # X########################################################################### X HOW TO GET STARTED WITH JOVE: X============================= X You can immediately start using Jove if you have an IBMPC compatible PC, XT or AT. You can fine tune some things by setting certain environment variables, but it's not really necessary If your computer is not IBM BIOS compatible, you have to set some environment variables before starting Jove. What follows is a description of those variables. X ENVIRONMENT VARIABLES USED BY JOVE: X=================================== X TMP (or TMPDIR) Jove uses the value of TMP to determine the directory where it should put its temporary file. The default is the current directory, and this is probably not what you want. In general editing is faster, if TMP points to a ramdisk, like "set tmp=d:". You have to know however that the temporary file can grow quite big when editing many big files at once. So please make sure that you have enough space available on your ramdisk. If Jove runs out of space on the device which holds the temporary file, you have to leave the editor immediately. You can save your work without any trouble, but you have to start over. Please note also that the current version of Jove has a big cache for the temporary file in memory, which makes it quite fast even if you don't have a ramdisk. X DESCRIBE This variable tells Jove, where it can find the file that holds the online documentation. You should set DESCRIBE to the complete path-specification of the file "cmds.doc", which is included as part of the documentation. The default for DESCRIBE is "c:/unix/cmds.doc". X JOVERC This is the complete path for Jove's startup file. All commands in the file, that JOVERC points to, are executed every time when you run Jove. If there is a file called "jove.rc" in the current directory, then it is also "sourced", ie. the commands in that file are executed. That way you can customize Jove to your own taste. X The next two variables are not used by the IBMPC version, and have to do with specifying the type of terminal in use on a generic msdos computer. X TERM This variable should specify the name of the terminal you are using. For example, if you have a DEC vt-100 terminal attached to your msdos computer, you should give the command "set TERM=vt100" prior to starting Jove. X TERMCAP This environment variable holds the name of a database with descriptions of different terminal types. If you are familiar with the Unix operating system, you probably know about TERMCAP. For each terminal type, specified by TERM, the TERMCAP database holds an entry, which describes how to set the cursor, how to scroll, and many other things, for that particular terminal. A small example TERMCAP file comes with Jove. If your terminal is not included there, you should ask a local Unix guru for help. If you don't have one, you can ask me. X METAKEY Some kinds of terminals have a special shift key that Jove can recognize, the so called MetaKey. When the environment variable METAKEY is set, Jove assumes that you have such a terminal, and treats the codes that your terminal sends in a slightly different way. Pressing down the MetaKey and another key at the same time is a then a shorthand for pressing first the "esc" key, and then the other key. X X DIFFERENT VERSIONS OF JOVE: X=========================== X The text above already indicated that Jove comes in different versions for different types of computers. Not only that, there also exist versions that differ in the way they use the memory of the computer. X The "large" versions of Jove use all the memory available if it is necessary. The temporary file can grow infinitely large in those versions. The number of lines that can be edited with the large version is about 20000 to 25000 on a PC with 640 kB of memory. Note that there is no limit on the size of the file itself. The "medium" versions of Jove are more conservative in their use of memory. They always take up about 130 kB of memory, which leaves a big rest for executing large programs, like the C-Compiler from within Jove. The size of the temporary file is also limited to 512 kB in the medium versions. The leads to a limit of approximately 4500 to 5000 lines that can be edited at one time. The standard executable files that are distributed in binary form, are usually the large ones. If you need a medium version, you either have to recompile Jove from the sources (see below), or you can get get it from someone else who has compiled it, for example from me. X There currently exist versions of Jove for three different types of msdos computers. PCJOVE is for IBMPC compatible computers. Compatible means here that the ROM Bios of your computer has to support the same Video output calls as the PC's. So even if your "clone" has trouble with many other programs, there's a high chance that Jove will work. MSJOVE should generally run on any computer that runs the msdos operating system. It strictly uses only well documented system calls to do its task. RBJOVE is a special version of MSJOVE for DEC Rainbow computers, which uses the Rainbows Bios for screen output and keyboard input. This makes it much faster than MSJOVE on the Rainbow. X X DIFFERENCES BETWEEN JOVE UNDER MSDOS AND UNIX JOVE: X=================================================== X The msdos version of Jove currently supports all of the features that are possible to implement under msdos in a reasonable way. Version 4.8b in particular supports: X filename completion X comment filling X creation of backup files X word abbreviation mode X Lisp mode X change directory within Jove X executing commands from within Jove X filtering regions through msdos commands You have to look into the manual for more explanations of these features. The things that are missing under msdos are: X spell-buffer (obsolete under msdos) X interactive shells in a window (not possible) There are however some features added, which are specific to the PC version. X Variables: X Background-color specifies the background color of the screen. The default X value is 0, which stands for black. X Foreground-color specifies the foreground color of the screen. The default X is 1, which stands for white. The attribute used for writing to the X screen is formed by (bg&7)<<4 & (fg&7). X Mode-line-color specifies the color of the modeline. Its default X value is 0, and in that case it is drawn in reverse video. If it has X any other value, this value is used as the attribute in Bios calls. X (note that on a monochrome monitor the best thing is to leave the X default colors - anything else can lead to blank screens very easily) X Commands: X Scroll-previous-page continuously scrolls down screen-full lines. X Scroll-next-page continuously scrolls up screen-full lines. X Select-buffer-n, where n is in the range 0 to 9, selects buffer n as the X working buffer. These commands are bound to the [0-9] keys by X default. For example, pressing the alt key and 3 at the same time X switches immediately to buffer 3. X General: X PCJOVE supports the whole 8 bit character set of the IBMPC. You can X use all the line drawing characters in your files. It also knows X about some special foreign characters (Umlaute), which are treated X correctly as part of words and in case conversions. X X VIDEO MODES ON THE IBMPC: X========================= X This concerns PCJOVE only. When Jove is started, it automatically checks which video mode is currently used, and adjusts itself correspondingly. This means that Jove will work correctly even in X40x25 mode. If you have an Ega card, and want to use the special mode with 43 lines, set the environment variable TERM to the value EGA, or set the variable EGA to any value. This will tell Jove to set the screen in 80x43 mode. The regular 80x25 mode is restored upon exit. On a color monitor, you can change the screen colors by using the commands mentioned above. There is a problem in using Jove together with Hershey MicroComputing's FansiConsole screen driver. FansiConsole doesn't properly set some of the values in the Bios control area. This usually leads to a crash when Jove starts. You can restore the information Jove needs by giving the command "mode co80" before starting Jove. Note that Kermit version 2.30 has the same problem, and that it can only be fixed by fixing FansiConsole. X X COMPILING JOVE UNDER MSDOS: X=========================== X Jove can currently only be compiled with the Version 5.0 of the Microsoft C Compiler. Jove uses some library function calls that were not included with version 4.0 or earlier of Microsoft C. The makefile that is included with the sources will not work with Microsofts lousy make. I recommend that you use ndmake, a public domain (or is it shareware) make utility, which is much better than Microsofts. Jove can be compiled with the medium, or the large memory model. To get the IBMPC version, the option "-DIBMPC" should be given at the command line for the Compiler. Similarly, the define for the Rainbow version is RAINBOW. The variable MSDOS is always defined by the compiler. If you want to disable some features you can do so by making changes to tune.h. If you want to give away the version of Jove you are compiling to other people, don't use the loop optimizations or intrinsic functions!!! The compiler currently has some bugs in the optimizer, which causes it to produce wrong code sometimes, and in unpredictable places. Look at the function DoJustify(), in paragraph.c, for an example. Note that the #pragma is commented out. because compilers on other machines don't like it. If you find that the version you just compiled behaves strange in some way, and you compiled with optimizations on, check whether it works ok with optimizations disabled before you tell all the world about a new bug in Jove. If you want to compile MSJOVE or RBJOVE, you need the library MTERMLIB or LTERMLIB, for medium or large memory model, respectively. These libraries contain the functions for dealing with the termcap database. X If you want to compile Jove with Turbo-C, the port has already been done by Brian Campbell (brianc@cognos.uucp). A separate file with the diffs is currently available from him, and will probably be included as ifdefs in future versions. X If you find a bug in Jove, have some questions, or some suggestions, you are always welcome. Just send mail to me. My address is: X X Karl Gegenfurtner X arpa: karl@hipl.psych.nyu.edu uucp {ihnp4|seismo|allegra}!cmcl2!xp!hipl!karl usps: New York University X Dept. of Psychology X 6 Washington Place 8th floor X New York, NY 10003 END_OF_FILE if test 11028 -ne `wc -c <'./Readme.dos'`; then echo shar: \"'./Readme.dos'\" unpacked with wrong size! fi # end of './Readme.dos' fi if test -f './ctype.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./ctype.c'\" else echo shar: Extracting \"'./ctype.c'\" \(11238 characters\) sed "s/^X//" >'./ctype.c' <<'END_OF_FILE' X/*************************************************************************** X * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE * X * is provided to you without charge, and with no warranty. You may give * X * away copies of JOVE, including sources, provided that this notice is * X * included in all the files. * X ***************************************************************************/ X X#include "jove.h" X#include "ctype.h" X int SyntaxTable = FUNDAMENTAL; /* Current table to use. */ X X#ifdef ASCII char CharTable[NMAJORS][128] = { X#else /* IBMPC or MAC */ char CharTable[NMAJORS][256] = { X#endif /* ASCII */ X{ _C, _C, _C, _C, _C, _C, _C, _C, X _C, _C, _C, _C, _C, _C, _C, _C, X _C, _C, _C, _C, _C, _C, _C, _C, X _C, _C, _C, _C, _C, _C, _C, _C, X _P, _P, _P, _P, _P, _P, _P, _P, X _Op|_P, _Cl|_P, _P, _P, _P, _P, _P, _P, X _W|_N, _W|_N, _W|_N, _W|_N, _W|_N, _W|_N, _W|_N, _W|_N, X _W|_N, _W|_N, _P, _P, _P, _P, _P, _P, X _P, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, X _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, X _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, X _W|_U, _W|_U, _W|_U, _Op|_P, _P, _Cl|_P, _P, _P, X _P, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, X _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, X _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, X#ifdef ASCII X _W|_L, _W|_L, _W|_L, _Op|_P, _P, _Cl|_P, _P, _C }, X#endif X#ifdef IBMPC X _W|_L, _W|_L, _W|_L, _Op|_P, _P, _Cl|_P, _P, _C, X 0, _W|_L, 0, 0, _W|_L, 0, 0, 0, 0, 0, 0, 0, 0, 0, _W|_U, 0, X 0, 0, 0, 0, _W|_L, 0, 0, 0, 0, _W|_U, _W|_U, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 X }, X X#endif /* IBMPC */ X#ifdef MAC /* See Inside Macintosh Vol One p. 247 */ X _W|_L, _W|_L, _W|_L, _Op|_P, _P, _Cl|_P, _P, _C, X _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_L, X _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, X _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, X _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, X _P, _P, _P, _P, _P, _P, _P, _P, X _P, _P, _P, _P, _P, _P, _W|_U, _W|_U, X _P, _P, _P, _P, _P, _W|_U, _W|_L, _W|_U, X _W|_U, _W|_L, _P, _P, _P, _W|_U, _W|_L, _W|_L, X _P, _P, _P, _P, _P, _P, _W|_U, _P, X _P, _P, _P, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, X _P, _P, _P, _P, _P, _P, _P, _P, X _W|_U, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 X }, X#endif /* MAC */ X X{ _C, _C, _C, _C, _C, _C, _C, _C, X _C, _C, _C, _C, _C, _C, _C, _C, X _C, _C, _C, _C, _C, _C, _C, _C, X _C, _C, _C, _C, _C, _C, _C, _C, X _P, _P, _P, _P, _P, _P, _P, _P|_W, X _Op|_P, _Cl|_P, _P, _P, _P, _P, _P, _P, X _W|_N, _W|_N, _W|_N, _W|_N, _W|_N, _W|_N, _W|_N, _W|_N, X _W|_N, _W|_N, _P, _P, _P, _P, _P, _P, X _P, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, X _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, X _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, X _W|_U, _W|_U, _W|_U, _Op|_P, _P, _Cl|_P, _P, _P, X _P, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, X _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, X _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, X#ifdef ASCII X _W|_L, _W|_L, _W|_L, _Op|_P, _P, _Cl|_P, _P, _C }, X#endif /* ASCII */ X#ifdef IBMPC X _W|_L, _W|_L, _W|_L, _Op|_P, _P, _Cl|_P, _P, _C, X 0, _W|_L, 0, 0, _W|_L, 0, 0, 0, 0, 0, 0, 0, 0, 0, _W|_U, 0, X 0, 0, 0, 0, _W|_L, 0, 0, 0, 0, _W|_U, _W|_U, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 X}, X X#endif /* IBMPC */ X#ifdef MAC /* See Inside Macintosh Vol One p. 247 */ X _W|_L, _W|_L, _W|_L, _Op|_P, _P, _Cl|_P, _P, _C, X _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_L, X _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, X _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, X _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, X _P, _P, _P, _P, _P, _P, _P, _P, X _P, _P, _P, _P, _P, _P, _W|_U, _W|_U, X _P, _P, _P, _P, _P, _W|_U, _W|_L, _W|_U, X _W|_U, _W|_L, _P, _P, _P, _W|_U, _W|_L, _W|_L, X _P, _P, _P, _P, _P, _P, _W|_U, _P, X _P, _P, _P, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, X _P, _P, _P, _P, _P, _P, _P, _P, X _W|_U, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 X }, X#endif /* MAC */ X X{ _C, _C, _C, _C, _C, _C, _C, _C, X _C, _C, _C, _C, _C, _C, _C, _C, X _C, _C, _C, _C, _C, _C, _C, _C, X _C, _C, _C, _C, _C, _C, _C, _C, X _P, _P, _P, _P, _P|_W, _P, _P, _P, X _Op|_P, _Cl|_P, _P, _P, _P, _P, _P, _P, X _W|_N, _W|_N, _W|_N, _W|_N, _W|_N, _W|_N, _W|_N, _W|_N, X _W|_N, _W|_N, _P, _P, _P, _P, _P, _P, X _P, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, X _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, X _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, X _W|_U, _W|_U, _W|_U, _Op|_P, _P, _Cl|_P, _P, _P|_W, X _P, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, X _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, X _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, X#ifdef ASCII X _W|_L, _W|_L, _W|_L, _Op|_P, _P, _Cl|_P, _P, _C X#else /* IBMPC or MAC*/ X _W|_L, _W|_L, _W|_L, _Op|_P, _P, _Cl|_P, _P, _C, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 X#endif /* ASCII */ X#ifndef LISP X} X#else X}, X X{ _C, _C, _C, _C, _C, _C, _C, _C, X _C, _C, _C, _C, _C, _C, _C, _C, X _C, _C, _C, _C, _C, _C, _C, _C, X _C, _C, _C, _C, _C, _C, _C, _C, X _P, _W|_P, _P, _P, _W|_P, _W|_P, _W|_P, _P, X _Op|_P, _Cl|_P, _W|_P, _W|_P, _P, _W|_P, _P, _W, X _W|_N, _W|_N, _W|_N, _W|_N, _W|_N, _W|_N, _W|_N, _W|_N, X _W|_N, _W|_N, _W|_P, _P, _W|_P, _W|_P, _W|_P, _W|_P, X _W|_P, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, X _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, X _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, _W|_U, X _W|_U, _W|_U, _W|_U, _Op|_P, _P, _Cl|_P, _W|_P, _W|_P, X _P, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, X _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, X _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, _W|_L, X#ifdef ASCII X _W|_L, _W|_L, _W|_L, _Op|_W|_P, _W|_P, _Cl|_W|_P, _W|_P, _W|_C }, X#else /* IBMPC or MAC */ X _W|_L, _W|_L, _W|_L, _Op|_W|_P, _W|_P, _Cl|_W|_P, _W|_P, _W|_C, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 X }, X#endif /* ASCII */ X#endif /* LISP */ X}; X int ismword(c) X{ X return ((CharTable[curbuf->b_major])[c]&(_W)); X} X X#ifdef IBMPC char CaseEquiv[256] = { X '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', X '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', X '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', X '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', X '\040', '!', '"', '#', '$', '%', '&', '\'', X '(', ')', '*', '+', ',', '-', '.', '/', X '0', '1', '2', '3', '4', '5', '6', '7', X '8', '9', ':', ';', '<', '=', '>', '?', X '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', X 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', X 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', X 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', X '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', X 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', X 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', X 'X', 'Y', 'Z', '{', '|', '}', '~', '\177', X 128, 154, 130, 131, 142, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, X 144, 145, 146, 147, 153, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, X 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, X 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, X 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, X 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, X 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, X 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 X}; X X#endif /* IBMPC */ X#ifdef MAC char CaseEquiv[256] = { X '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', X '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', X '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', X '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', X '\040', '!', '"', '#', '$', '%', '&', '\'', X '(', ')', '*', '+', ',', '-', '.', '/', X '0', '1', '2', '3', '4', '5', '6', '7', X '8', '9', ':', ';', '<', '=', '>', '?', X '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', X 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', X 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', X 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', X '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', X 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', X 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', X 'X', 'Y', 'Z', '{', '|', '}', '~', '\177', X 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, X 0xCB, 0x89, 0x80, 0xCC, 0x81, 0x82, 0x83, 0x8F, X 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x84, 0x97, X 0x98, 0x99, 0x85, 0xCD, 0x9C, 0x9D, 0x9E, 0x86, X 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, X 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, X 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xC6, 0xB7, X 0xB8, 0xB8, 0xBA, 0xBB, 0xBC, 0xBD, 0xAE, 0xAF, X 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, X 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCE, X 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, X 0xD8, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0 X}; X#endif /* MAC */ X#ifdef ASCII char CaseEquiv[] = { X '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', X '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', X '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', X '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', X '\040', '!', '"', '#', '$', '%', '&', '\'', X '(', ')', '*', '+', ',', '-', '.', '/', X '0', '1', '2', '3', '4', '5', '6', '7', X '8', '9', ':', ';', '<', '=', '>', '?', X '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', X 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', X 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', X 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', X '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', X 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', X 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', X 'X', 'Y', 'Z', '{', '|', '}', '~', '\177' X}; X X#endif /* ASCII */ END_OF_FILE if test 11238 -ne `wc -c <'./ctype.c'`; then echo shar: \"'./ctype.c'\" unpacked with wrong size! fi # end of './ctype.c' fi if test -f './doc/jove.nr' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./doc/jove.nr'\" else echo shar: Extracting \"'./doc/jove.nr'\" \(11791 characters\) sed "s/^X//" >'./doc/jove.nr' <<'END_OF_FILE' X.hy 0 X.TH JOVE 1 "12 February 1986" X.ad X.SH NAME jove - an interactive display-oriented text editor X.SH SYNOPSIS X.nf jove [-d directory] [-w] [-t tag] [+[n] file] [-p file] [files] jove -r X.fi X.SH DESCRIPTION JOVE is Jonathan's Own Version of Emacs. It is based on the original EMACS editor written at MIT by Richard Stallman. Although JOVE is meant to be compatible with EMACS, there are some major differences between the two editors and you shouldn't rely on their behaving identically. X.LP JOVE works on any reasonable display terminal that is described in the X.I termcap file (see TERMCAP(5) for more details). When you start up JOVE, it checks to see whether you have your X.I TERM environment variable set. On most systems that will automatically be set up for you, but if it's not JOVE will ask you what kind of terminal you are using. To avoid having to type this every time you run JOVE you can set your X.I TERM environment variable yourself. How you do this depends on which shell you are running. If you are running the C Shell, as most of you are, you type X.sp 1 X % setenv TERM X.I type X.sp 1 and with the Bourne Shell, you type X.sp 1 X $ TERM= X.I type X; export TERM X.sp 1 where X.I type is the name of the kind of terminal you are using (e.g., vt100). If neither of these works get somebody to help you. X.SH INVOKING JOVE If you run JOVE with no arguments you will be placed in an empty buffer, called X.I Main. Otherwise, any arguments you supply are considered file names and each is X"given" its own buffer. Only the first file is actually read in--reading other files is deferred until you actually try to use the buffers they are attached to. This is for efficiency's sake: most of the time, when you run JOVE on a big list of files, you end up editing only a few of them. X.LP The names of all of the files specified on the command line are saved in a buffer, called X.I *minibuf*. The mini-buffer is a special JOVE buffer that is used when JOVE is prompting for some input to many commands (for example, when JOVE is prompting for a file name). When you are being prompted for a file name, you can type C-N X(that's Control-N) and C-P to cycle through the list of files that were specified on the command line. The file name will be inserted where you are typing and then you can edit it as if you typed it in yourself. X.LP JOVE recognizes the following switches: X.TP X.I -d The following argument is taken to be the name of the current directory. This is for systems that don't have a version of C shell that automatically maintains the X.I CWD environment variable. If X.I -d is not specified on a system without a modified C shell, JOVE will have to figure out the current directory itself, and that can be VERY slow. You can simulate the modified C shell by putting the following lines in your C shell initialization file (.cshrc): X.nf X.sp 1 X alias cd 'cd \\!*; setenv CWD $cwd' X alias popd 'popd \\!*; setenv CWD $cwd' X alias pushd 'pushd \\!*; setenv CWD $cwd' X.fi X.TP X.I +n Reads the file, designated by the following argument, and positions point at the X.I n'th line instead of the (default) 1'st line. This can be specified more than once but it doesn't make sense to use it twice on the same file; in that case the second one wins. If no numeric argument is given after the +, the point is positioned at the end of the file. X.TP X.I -p Parses the error messages in the file designated by the following argument. The error messages are assumed to be in a format similar to the C compiler, LINT, or GREP output. X.TP X.I -t Runs the X.I find-tag command on the string of characters immediately following the -t if there is one (as in -tTagname), or on the following argument (as in -t Tagname) otherwise (see ctags(1)). X.TP X.I -w Divides the window in two. When this happens, either the same file is displayed in both windows, or the second file in the list is read in and displayed in its window. X.SH "RECOVERING BUFFERS AFTER A CRASH" The X.I -r option of jove runs the JOVE recover program. Use this when the system crashes, or JOVE crashes, or you accidently get logged out while in JOVE. If there are any buffers to be recovered, this will find them. X.LP Recover looks for JOVE buffers that are left around and are owned by you. (You cannot recover other peoples' buffers, obviously.) If there were no buffers that were modified at the time of the crash or there were but recover can't get its hands on them, you will be informed with the message, "There is nothing to recover." Otherwise, recover prints the date and time of the version of the buffers it has, and then waits for you type a command. X.LP To get a list of the buffers recover knows about, use the X.I list command. This will list all the buffers and the files and the number of lines associated with them. Next to each buffer is a number. When you want to recover a buffer, use the X.I get command. The syntax is X.I get buffer filename where X.I buffer is either the buffer's name or the number at the beginning of the line. If you don't type the buffer name or the filename, recover will prompt you for them. X.LP If there are a lot of buffers and you want to recover all of them, use the X.I recover command. This will recover each buffer to the name of the buffer with ".#" prepended to the name (so that the original isn't over-written). It asks for each file and if you want to restore that buffer to that name you type X"yes". If you want to recover the file but to a different name, just type the new name in. If you type "no" recover will skip that file and go on to the next one. X.LP If you want to look at a buffer before deciding to recover it, use the X.I print command. The syntax for this is X.I print buffer where X.I buffer again is either its name or the number. You can type ^C if you want to abort printing the file to the terminal, and recover will respond with an appropriate message. X.LP When you're done and have all the buffers you want, type the X.I quit command to leave. You will then be asked whether it's okay to delete the tmp files. Most of the time that's okay and you should type "yes". When you say that, JOVE removes all traces of those buffers and you won't be able to look at them again. (If you recovered some buffers they will still be around, so don't worry.) So, if you're not sure whether you've gotten all the buffers, you should answer "no" so that you'll be able to run recover again at a later time (presumably after you've figured out which ones you want to save). X.LP If you type ^C at any time other than when you're printing a file to the terminal, recover will exit without a word. If you do this but wish you hadn't, just type "jove -r" to the shell again, and you will be put back with no loss. X.SH GETTING HELP Once in JOVE, there are several commands available to get help. To execute any JOVE command, you type " X command-name" followed by . To get a list of all the JOVE commands you type " X" followed by "?". The X.I describe-bindings command can be used to get a list containing each key, and its associated command (that is, the command that gets executed when you type that key). If you want to save the list of bindings, you can set the jove variable X.I send-typeout-to-buffer to ON (using the X.I set command), and then execute the X.I describe-bindings command. This will create a buffer and put in it the bindings list it normally would have printed on the screen. Then you can save that buffer to a file and print it to use as a quick reference card. (See VARIABLES below.) X.LP Once you know the name of a command, you can find out what it does with the X.I describe-command command, which you can invoke quickly by typing "ESC ?". The X.I apropos command will give you a list of all the command with a specific string in their names. For example, if you want to know the names of all the commands that are concerned with windows, you can run "apropos" with the keyword X.I window. X.LP If you're not familar with the EMACS command set, it would be worth your while to use run TEACHJOVE. Do do that, just type "teachjove" to your shell and you will be placed in JOVE in a file which contains directions. I highly recommend this for beginners; you may save yourself a lot of time and headaches. X.SH KEY BINDINGS and VARIABLES You can alter the key bindings in JOVE to fit your personal tastes. That is, you can change what a key does every time you strike it. For example, by default the C-N key is bound to the command X.I next-line and so when you type it you move down a line. If you want to change a binding or add a new one, you use the X.I bind-to-key command. The syntax is "bind-to-key key". X.LP You can also change the way JOVE behaves in little ways by changing the value of some variables with the X.I set command. The syntax is "set value", where value is a number or a string, or "on" or "off", depending on the context. For example, if you want JOVE to make backup files, you set the "make-backup-files" variable to X"on". To see the value of a variable, use the "print " command. X.SH INITIALIZATION JOVE automatically reads commands from an initialization file in your HOME directory, called ".joverc". In this file you can place commands that you would normally type in JOVE. If you like to rearrange the key bindings and set some variables every time you get into JOVE, you should put them in your initialization file. Here are a few lines from mine: X.nf X set match-regular-expressions on X auto-execute-command auto-fill /tmp/Re\\|.*drft X bind-to-key i-search-forward ^\\ X bind-to-key i-search-reverse ^R X bind-to-key find-tag-at-point ^[^T X bind-to-key scroll-down ^C X bind-to-key grow-window ^Xg X bind-to-key shrink-window ^Xs X.fi X(Note that the Control Characters can be either two character sequences X(e.g. ^ and C together as ^C) or the actual control character. If you want to use an ^ by itself you must BackSlash it (e.g., bind-to-key grow-window X^X\\^ binds grow-window to "^X^"). X.SH SOME MINOR DETAILS You should type C-\\ instead of C-S in many instances. For example, the way to search for a string is documented as being "C-S" but in reality you should type "C-\\". This is because C-S is the XOFF character (what gets sent when you type the NO SCROLL key), and clearly that won't work. The XON character is "C-Q" (what gets sent when you type NO SCROLL again) which is documented as the way to do a quoted-insert. The alternate key for this is X"C-^" (typed as "C-`" on vt100's and its look-alikes). If you want to enable C-S and C-Q and you know what you are doing, you can put the line: X.nf X set allow-^S-and-^Q on X.fi in your initialization file. X.LP If your terminal has a metakey, JOVE will use it if you turn on the X"meta-key" variable. JOVE will automatically turn on "meta-key" if the METAKEY environment variable exists. This is useful for if you have different terminals (e.g., one at home and one at work) and one has a metakey and the other doesn't. X.SH FILES LIBDIR/.joverc - system wide initialization file X.sp 0 X~/.joverc - personal initialization file X.sp 0 TMPDIR - where temporary files are stored X.sp 0 LIBDIR/teach-jove - the interactive tutorial X.sp 0 LIBDIR/portsrv - for running shells in windows (pdp11 only) X.SH SEE ALSO X.nf ed(1) - for a description of regular expressions X.sp 0 teachjove(1) - for an interactive JOVE tutorial. X.fi X.SH DIAGNOSTICS JOVE diagnostics are meant to be self-explanatory, but you are advised to seek help whenever you are confused. You can easily lose a lot of work if you don't know EXACTLY what you are doing. X.SH BUGS Lines can't be more than 1024 characters long. X.sp 1 Searches can't cross line boundaries. X.SH AUTHOR Jonathan Payne END_OF_FILE if test 11791 -ne `wc -c <'./doc/jove.nr'`; then echo shar: \"'./doc/jove.nr'\" unpacked with wrong size! fi # end of './doc/jove.nr' fi if test -f './re1.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./re1.c'\" else echo shar: Extracting \"'./re1.c'\" \(11936 characters\) sed "s/^X//" >'./re1.c' <<'END_OF_FILE' X/*************************************************************************** X * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE * X * is provided to you without charge, and with no warranty. You may give * X * away copies of JOVE, including sources, provided that this notice is * X * included in all the files. * X ***************************************************************************/ X X#include "jove.h" X#include "io.h" X#include "re.h" X#include "ctype.h" X X#ifdef MAC X# include "mac.h" X#else X# include X#endif X X#ifdef MAC X# undef private X# define private X#endif X X#ifdef LINT_ARGS private Bufpos * doisearch(int, int, int); X private void X IncSearch(int), X replace(int, int); private int X isearch(int, Bufpos *), X lookup(char *, char *, char *, char *), X substitute(int, Line *, int, Line *, int); X#else private Bufpos * doisearch(); X private void X IncSearch(), X replace(); private int X isearch(), X lookup(), X substitute(); X#endif /* LINT_ARGS */ X X#ifdef MAC X# undef private X# define private static X#endif X private int substitute(query, l1, char1, l2, char2) Line *l1, X *l2; X{ X Line *lp; X int numdone = 0, X offset = curchar, X stop = NO; X disk_line UNDO_da = 0; X Line *UNDO_lp = 0; X X lsave(); X REdirection = FORWARD; X X lp = l1; X for (lp = l1; (lp != l2->l_next) && !stop; lp = lp->l_next) { X offset = (lp == l1) ? char1 : 0; X while (!stop && re_lindex(lp, offset, compbuf, alternates, 0)) { X if (lp == l2 && REeom > char2) /* nope, leave this alone */ X break; X DotTo(lp, REeom); X offset = curchar; X if (query) { X message("Replace (Type '?' for help)? "); reswitch: redisplay(); X switch (CharUpcase(getchar())) { X case '.': X stop = YES; X /* Fall into ... */ X X case ' ': X case 'Y': X break; X X case BS: X case RUBOUT: X case 'N': X if (linebuf[offset++] == '\0') X goto nxtline; X continue; X X case CTL('W'): X re_dosub(linebuf, YES); X numdone += 1; X offset = curchar = REbom; X makedirty(curline); X /* Fall into ... */ X X case CTL('R'): X case 'R': X RErecur(); X offset = curchar; X lp = curline; X continue; X X case CTL('U'): X case 'U': X if (UNDO_lp == 0) X continue; X lp = UNDO_lp; X lp->l_dline = UNDO_da | DIRTY; X offset = 0; X numdone -= 1; X continue; X X case 'P': X case '!': X query = 0; X break; X X case CR: X case LF: X case 'Q': X goto done; X X case CTL('L'): X RedrawDisplay(); X goto reswitch; X X default: X rbell(); message("Space or Y, Period, Rubout or N, C-R or R, C-W, C-U or U, P or !, Return."); X goto reswitch; X } X } X re_dosub(linebuf, NO); X numdone += 1; X modify(); X offset = curchar = REeom; X makedirty(curline); X if (query) { X message(mesgbuf); /* no blinking */ X redisplay(); /* show the change */ X } X UNDO_da = curline->l_dline; X UNDO_lp = curline; X if (linebuf[offset] == 0) nxtline: break; X } X } done: return numdone; X} X X/* prompt for search and replacement strings and do the substitution */ private void replace(query, inreg) X{ X Mark *m; X char *rep_ptr; X Line *l1 = curline, X *l2 = curbuf->b_last; X int char1 = curchar, X char2 = length(curbuf->b_last), X numdone; X X if (inreg) { X m = CurMark(); X l2 = m->m_line; X char2 = m->m_char; X (void) fixorder(&l1, &char1, &l2, &char2); X } X X /* get search string */ X strcpy(rep_search, ask(rep_search[0] ? rep_search : (char *) 0, ProcFmt)); X REcompile(rep_search, UseRE, compbuf, alternates); X /* Now the replacement string. Do_ask() so the user can play with X the default (previous) replacement string by typing C-R in ask(), X OR, he can just hit Return to replace with nothing. */ X rep_ptr = do_ask("\r\n", (int (*)()) 0, rep_str, ": %f %s with ", rep_search); X if (rep_ptr == 0) X rep_ptr = NullStr; X strcpy(rep_str, rep_ptr); X X if (((numdone = substitute(query, l1, char1, l2, char2)) != 0) && X (inreg == NO)) { X do_set_mark(l1, char1); X add_mess(" "); /* just making things pretty */ X } else X message(""); X add_mess("(%d substitution%n)", numdone, numdone); X} X void RegReplace() X{ X replace(0, YES); X} X void QRepSearch() X{ X replace(1, NO); X} X void RepSearch() X{ X replace(0, NO); X} X X/* Lookup a tag in tag file FILE. FILE is assumed to be sorted X alphabetically. The FASTTAGS code, which is implemented with X a binary search, depends on this assumption. If it's not true X it is possible to comment out the fast tag code (which is clearly X labeled) and everything else will just work. */ X private int lookup(searchbuf, filebuf, tag, file) char *searchbuf, X *filebuf, X *tag, X *file; X{ X register int taglen = strlen(tag); X char line[BUFSIZ], X pattern[128]; X register File *fp; X struct stat stbuf; X int fast = YES, X success = NO; X register off_t lower, upper; X X sprintf(pattern, "^%s[^\t]*\t*\\([^\t]*\\)\t*[?/]\\([^?/]*\\)[?/]", tag); X fp = open_file(file, iobuff, F_READ, !COMPLAIN, QUIET); X if (fp == NIL) X return 0; X X /* ********BEGIN FAST TAG CODE******** */ X X if (stat(file, &stbuf) < 0) X fast = NO; X else { X lower = 0; X upper = stbuf.st_size; X if (upper - lower < BUFSIZ) X fast = NO; X } X if (fast == YES) for (;;) { X off_t mid; X int whichway, X chars_eq; X X if (upper - lower < BUFSIZ) { X f_seek(fp, lower); X break; /* stop this nonsense */ X } X mid = (lower + upper) / 2; X f_seek(fp, mid); X f_toNL(fp); X if (f_gets(fp, line, sizeof line) == EOF) X break; X chars_eq = numcomp(line, tag); X if (chars_eq == taglen && iswhite(line[chars_eq])) X goto found; X whichway = line[chars_eq] - tag[chars_eq]; X if (whichway < 0) { /* line is BEFORE tag */ X lower = mid; X continue; X } else if (whichway > 0) { /* line is AFTER tag */ X upper = mid; X continue; X } X } X f_toNL(fp); X /* END FAST TAG CODE */ X X while (f_gets(fp, line, sizeof line) != EOF) { X int cmp; X X if (line[0] > *tag) X break; X else if ((cmp = strncmp(line, tag, taglen)) > 0) X break; X else if (cmp < 0) X continue; X /* if we get here, we've found the match */ found: if (!LookingAt(pattern, line, 0)) { X complain("I thought I saw it!"); X break; X } else { X putmatch(1, filebuf, FILESIZE); X putmatch(2, searchbuf, 100); X success = YES; X break; X } X } X close_file(fp); X X if (success == NO) X s_mess("Can't find tag \"%s\".", tag); X return success; X} X X#ifndef MSDOS char TagFile[FILESIZE] = "./tags"; X#else /* MSDOS */ char TagFile[FILESIZE] = "tags"; X#endif /* MSDOS */ X void find_tag(tag, localp) char *tag; X{ X char filebuf[FILESIZE], X sstr[100], X tfbuf[FILESIZE]; X register Bufpos *bp; X register Buffer *b; X char *tagfname; X X if (!localp) { X char prompt[128]; X X sprintf(prompt, "With tag file (%s default): ", TagFile); X tagfname = ask_file(prompt, TagFile, tfbuf); X } else X tagfname = TagFile; X if (lookup(sstr, filebuf, tag, tagfname) == 0) X return; X set_mark(); X b = do_find(curwind, filebuf, 0); X if (curbuf != b) X SetABuf(curbuf); X SetBuf(b); X if ((bp = dosearch(sstr, BACKWARD, 0)) == 0 && X ((bp = dosearch(sstr, FORWARD, 0)) == 0)) X message("Well, I found the file, but the tag is missing."); X else X SetDot(bp); X} X void FindTag() X{ X int localp = !is_an_arg(); X char tag[128]; X X strcpy(tag, ask((char *) 0, ProcFmt)); X find_tag(tag, localp); X} X X/* Find Tag at Dot. */ X void FDotTag() X{ X int c1 = curchar, X c2 = c1; X char tagname[50]; X X if (!ismword(linebuf[curchar])) X complain("Not a tag!"); X while (c1 > 0 && ismword(linebuf[c1 - 1])) X c1 -= 1; X while (ismword(linebuf[c2])) X c2 += 1; X X null_ncpy(tagname, linebuf + c1, c2 - c1); X find_tag(tagname, !is_an_arg()); X} X X/* I-search returns a code saying what to do: X STOP: We found the match, so unwind the stack and leave X where it is. X DELETE: Rubout the last command. X BACKUP: Back up to where the isearch was last NOT failing. X X When a character is typed it is appended to the search string, and X then, isearch is called recursively. When C-S or C-R is typed, isearch X is again called recursively. */ X X#define STOP 1 X#define DELETE 2 X#define BACKUP 3 X#define TOSTART 4 X static char ISbuf[128], X *incp = 0; int SExitChar = CR; X X#define cmp_char(a, b) ((a) == (b) || (CaseIgnore && (CharUpcase(a) == CharUpcase(b)))) X static Bufpos * doisearch(dir, c, failing) register int c, X dir, X failing; X{ X static Bufpos buf; X Bufpos *bp; X extern int okay_wrap; X X if (c == CTL('S') || c == CTL('R')) X goto dosrch; X X if (failing) X return 0; X DOTsave(&buf); X if (dir == FORWARD) { X if (cmp_char(linebuf[curchar], c)) { X buf.p_char = curchar + 1; X return &buf; X } X } else { X if (look_at(ISbuf)) X return &buf; X } dosrch: okay_wrap = YES; X if ((bp = dosearch(ISbuf, dir, 0)) == 0) X rbell(); /* ring the first time there's no match */ X okay_wrap = NO; X return bp; X} X void IncFSearch() X{ X IncSearch(FORWARD); X} X void IncRSearch() X{ X IncSearch(BACKWARD); X} X private void IncSearch(dir) X{ X Bufpos save_env; X X DOTsave(&save_env); X ISbuf[0] = 0; X incp = ISbuf; X if (isearch(dir, &save_env) == TOSTART) X SetDot(&save_env); X else { X if (LineDist(curline, save_env.p_line) >= MarkThresh) X do_set_mark(save_env.p_line, save_env.p_char); X } X setsearch(ISbuf); X} X X/* Nicely recursive. */ X private int isearch(dir, bp) Bufpos *bp; X{ X Bufpos pushbp; X int c, X ndir, X failing; X char *orig_incp; X X if (bp != 0) { /* Move to the new position. */ X pushbp.p_line = bp->p_line; X pushbp.p_char = bp->p_char; X SetDot(bp); X failing = 0; X } else { X DOTsave(&pushbp); X failing = 1; X } X orig_incp = incp; X ndir = dir; /* Same direction as when we got here, unless X we change it with C-S or C-R. */ X for (;;) { X SetDot(&pushbp); X message(NullStr); X if (failing) X add_mess("Failing "); X if (dir == BACKWARD) X add_mess("reverse-"); X add_mess("I-search: %s", ISbuf); X DrawMesg(NO); X add_mess(NullStr); /* tell me this is disgusting ... */ X c = getch(); X if (c == SExitChar) X return STOP; X if (c == AbortChar) { X /* If we're failing, we backup until we're no longer X failing or we've reached the beginning; else, we X just about the search and go back to the start. */ X if (failing) X return BACKUP; X return TOSTART; X } X switch (c) { X case RUBOUT: X case BS: X return DELETE; X X case CTL('\\'): X c = CTL('S'); X X case CTL('S'): X case CTL('R'): X /* If this is the first time through and we have a X search string left over from last time, use that X one now. */ X if (incp == ISbuf) { X strcpy(ISbuf, getsearch()); X incp = &ISbuf[strlen(ISbuf)]; X } X ndir = (c == CTL('S')) ? FORWARD : BACKWARD; X /* If we're failing and we're not changing our X direction, don't recur since there's no way X the search can work. */ X if (failing && ndir == dir) { X rbell(); X continue; X } X break; X X case '\\': X if (incp > &ISbuf[(sizeof ISbuf) - 1]) { X rbell(); X continue; X } X *incp++ = '\\'; X add_mess("\\"); X /* Fall into ... */ X X case CTL('Q'): X case CTL('^'): X add_mess(""); X c = getch() | 0400; X /* Fall into ... */ X X default: X if (c & 0400) X c &= CHARMASK; X else { X#ifdef IBMPC X if (c == RUBOUT || c == 0xff || (c < ' ' && c != '\t')) { X#else X if (c > RUBOUT || (c < ' ' && c != '\t')) { X#endif X Ungetc(c); X return STOP; X } X } X if (incp > &ISbuf[(sizeof ISbuf) - 1]) { X rbell(); X continue; X } X *incp++ = c; X *incp = 0; X break; X } X add_mess("%s", orig_incp); X add_mess(" ..."); /* so we know what's going on */ X DrawMesg(NO); /* do it now */ X switch (isearch(ndir, doisearch(ndir, c, failing))) { X case TOSTART: X return TOSTART; X X case STOP: X return STOP; X X case BACKUP: X /* If we're not failing, we just continue to to the X for loop; otherwise we keep returning to the X previous levels until we find one that isn't X failing OR we reach the beginning. */ X if (failing) X return BACKUP; X /* Fall into ... */ X X case DELETE: X incp = orig_incp; X *incp = 0; X continue; X } X } X} END_OF_FILE if test 11936 -ne `wc -c <'./re1.c'`; then echo shar: \"'./re1.c'\" unpacked with wrong size! fi # end of './re1.c' fi echo shar: End of archive 5 \(of 21\). cp /dev/null ark5isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 21 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0