rsalz@bbn.com (Rich Salz) (04/26/88)
Submitted-by: Jonathan Payne <jpayne@cs.rochester.edu> Posting-number: Volume 14, Issue 60 Archive-name: jove4.9/part04 #! /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 <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 4 (of 21)." PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f './Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./Makefile'\" else echo shar: Extracting \"'./Makefile'\" \(8207 characters\) sed "s/^X//" >'./Makefile' <<'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# TMPDIR is where the tmp files get stored, usually /tmp or /tmp/jove. If X# your system does not remove subdirectories of /tmp on reboot (lots do X# remove them these days) then it makes sense to make TMPDIR be /tmp/jove. X# But if you want to recover buffers on system crashes, you should create a X# directory that doesn't get clearned upon reboot, and use that instead. X# You would probably want to clean out that directory periodically with X# /etc/cron. LIBDIR is for online documentation, the PORTSRV process, X# RECOVER, and the system-wide .joverc file. BINDIR is where to put the X# executables JOVE and TEACHJOVE. MANDIR is where the manual pages go for X# JOVE, RECOVER and TEACHJOVE. MANEXT is the extension for the man pages, X# e.g., jove.1 or jove.l or jove.m. X DESTDIR = TMPDIR = /tmp LIBDIR = /usr/local/lib/jove BINDIR = /usr/local MANDIR = /usr/man/manl MANEXT = l SHELL = /bin/csh X X# These should all just be right if the above ones are. JOVE = $(DESTDIR)$(BINDIR)/jove TEACHJOVE = $(DESTDIR)$(BINDIR)/teachjove RECOVER = $(DESTDIR)$(LIBDIR)/recover PORTSRV = $(DESTDIR)$(LIBDIR)/portsrv JOVERC = $(DESTDIR)$(LIBDIR)/.joverc CMDS.DOC = $(DESTDIR)$(LIBDIR)/cmds.doc TEACH-JOVE = $(DESTDIR)$(LIBDIR)/teach-jove JOVEM = $(DESTDIR)$(MANDIR)/jove.$(MANEXT) TEACHJOVEM = $(DESTDIR)$(MANDIR)/teachjove.$(MANEXT) X X# Select the right libraries for your system. X# 2.10BSD:LIBS = -ltermcap X# v7: LIBS = -ltermcap X# 4.1BSD: LIBS = -ltermcap -ljobs X# 4.2BSD: LIBS = -ltermcap X# 4.3BSD: LIBS = -ltermcap X# SysV Rel. 2: LIBS = -lcurses X# SCO Xenix: LIBS = -ltermcap -lx X LIBS = -ltermcap X X# If you are not VMUNIX (vax running Berkeley Version 4), you must specify X# the -i flags (split I/D space) and maybe the -x option (for adb to work). X# 2.10BSD:LDFLAGS = X# v7: LDFLAGS = X# 4.1BSD: LDFLAGS = X# 4.2BSD: LDFLAGS = X# 4.3BSD: LDFLAGS = X# SysV Rel. 2: LDFLAGS = -Ml X# SCO Xenix: LDFLAGS = -Ml -F 3000 X# X# SEPFLAG should be: X# not on a PDP-11: SEPFLAG = X# PDP-11 with separate I&D: SEPFLAG = -i X# PDP-11 without separate I&D: SEPFLAG = -n X# X LDFLAGS = X SEPFLAG = X X# for SCO Xenix, set X# MEMFLAGS = -Mle X# CFLAGS = -LARGE -O -F 3000 -K -Mle (say -Mle2 for an 80286) X CFLAGS = -O X BASESEG = funcdefs.o keymaps.o argcount.o ask.o buf.o ctype.o delete.o \ X disp.o insert.o io.o jove.o malloc.o marks.o misc.o re.o \ X screen.o table.o tune.o util.o vars.o version.o OVLAY1 = abbrev.o rec.o paragraph.o fmt.o OVLAY2 = c.o wind.o fp.o move.o OVLAY3 = extend.o macros.o OVLAY4 = iproc.o re1.o OVLAY5 = proc.o scandir.o term.o case.o X OBJECTS = $(BASESEG) $(OVLAY1) $(OVLAY2) $(OVLAY3) $(OVLAY4) $(OVLAY5) X C_SRC = funcdefs.c abbrev.c argcount.c ask.c buf.c c.c case.c ctype.c \ X delete.c disp.c extend.c fp.c fmt.c insert.c io.c iproc.c \ X jove.c macros.c malloc.c marks.c misc.c move.c paragraph.c \ X proc.c re.c re1.c rec.c scandir.c screen.c table.c term.c util.c \ X vars.c version.c wind.c getch.c mac.c X SOURCES = $(C_SRC) portsrv.c recover.c setmaps.c teachjove.c X HEADERS = ctype.h io.h jove.h re.h rec.h table.h temp.h termcap.h \ X tune.h externs.h mac.h X DOCS = doc/cmds.doc.nr doc/example.rc doc/jove.1 doc/jove.2 doc/jove.3 \ X doc/jove.4 doc/jove.5 doc/jove.nr doc/system.rc \ X doc/teach-jove doc/teachjove.nr doc/README doc/jove.qref X MISC = Makefile Ovmakefile Makefile.dos tune.dos tune.template \ X README Readme.dos Readme.mac iproc-pipes.c iproc-ptys.c X SUPPORT = teachjove.c recover.c setmaps.c portsrv.c keymaps.txt \ X macvert.c menumaps.txt mjovers.Hqx X BACKUPS = $(HEADERS) $(C_SRC) $(DOCS) $(SUPPORT) $(MISC) X all: sdate xjove recover teachjove portsrv macvert edate X sdate: X @echo "**** make started at `date` ****" X edate: X @echo "**** make completed at `date` ****" X xjove: $(OBJECTS) X $(CC) $(LDFLAGS) -o xjove $(OBJECTS) $(LIBS) X @-size xjove X gjove: $(OBJECTS) X ld -X /lib/gcrt0.o -o gjove $(OBJECTS) -lc $(LIBS) X @-size gjove X ovjove: $(OBJECTS) X ld $(SEPFLAG) $(LDFLAGS) -X /lib/crt0.o \ X -Z $(OVLAY1) \ X -Z $(OVLAY2) \ X -Z $(OVLAY3) \ X -Z $(OVLAY4) \ X -Z $(OVLAY5) \ X -Y $(BASESEG) \ X -o xjove $(LIBS) -lc; \ X @-size xjove X portsrv: portsrv.o X $(CC) $(LDFLAGS) -o portsrv $(SEPFLAG) portsrv.o $(LIBS) X recover: recover.o tune.o rec.h temp.h X $(CC) $(LDFLAGS) -o recover $(SEPFLAG) recover.o tune.o $(LIBS) X teachjove: teachjove.o X $(CC) $(LDFLAGS) -o teachjove $(SEPFLAG) teachjove.o $(LIBS) X setmaps: setmaps.o funcdefs.c X $(CC) $(LDFLAGS) -o setmaps setmaps.o X teachjove.o: teachjove.c /usr/include/sys/types.h /usr/include/sys/file.h X cc -c $(CFLAGS) -DTEACHJOVE=\"$(TEACH-JOVE)\" teachjove.c X X# don't optimize setmaps.c because it produces bad code in some places X# for some reason setmaps.o: funcdefs.c keymaps.txt X $(CC) $(MEMFLAGS) -c setmaps.c X X# ignore error messages from setmaps X# it doesn't understand ifdefs X keymaps.c: setmaps keymaps.txt X -setmaps < keymaps.txt > keymaps.c X keymaps.o: keymaps.c jove.h X tune.c: Makefile tune.template X @echo "/* Changes should be made in Makefile, not to this file! */" > tune.c X @echo "" >> tune.c X @sed -e 's;TMPDIR;$(TMPDIR);' \ X -e 's;LIBDIR;$(LIBDIR);' \ X -e 's;BINDIR;$(BINDIR);' \ X -e 's;SHELL;$(SHELL);' tune.template >> tune.c X iproc.o: iproc-ptys.c iproc-pipes.c iproc.c X $(CC) -c $(CFLAGS) iproc.c X macvert: macvert.c X $(CC) $(CFLAGS) -o macvert macvert.c X X# install doesn't work for Xenix (no install program) X install: $(DESTDIR)$(LIBDIR) $(TEACH-JOVE) $(CMDS.DOC) $(JOVERC) \ X $(PORTSRV) $(RECOVER) $(JOVE) $(TEACHJOVE) $(JOVEM) \ X $(RECOVERM) $(TEACHJOVEM) X X$(DESTDIR)$(LIBDIR): X -mkdir $(DESTDIR)$(LIBDIR) X X$(TEACH-JOVE): doc/teach-jove X install -c -m 644 doc/teach-jove $(TEACH-JOVE) X doc/cmds.doc: doc/cmds.doc.nr doc/jove.4 doc/jove.5 X nroff doc/cmds.doc.nr doc/jove.4 doc/jove.5 > doc/cmds.doc X X$(CMDS.DOC): doc/cmds.doc X install -c -m 644 doc/cmds.doc $(CMDS.DOC) X X$(JOVERC): doc/system.rc X install -c -m 644 doc/system.rc $(JOVERC) X X$(PORTSRV): portsrv X install -c -s -m 755 portsrv $(PORTSRV) X X$(RECOVER): recover X install -c -s -m 755 recover $(RECOVER) X X$(JOVE): xjove X install -c -m 755 xjove $(JOVE) X X$(TEACHJOVE): teachjove X install -c -s -m 755 teachjove $(TEACHJOVE) X X$(JOVEM): doc/jove.nr X @sed -e 's;TMPDIR;$(TMPDIR);' \ X -e 's;LIBDIR;$(LIBDIR);' \ X -e 's;SHELL;$(SHELL);' doc/jove.nr > /tmp/jove.nr X install -m 644 /tmp/jove.nr $(JOVEM) X X$(TEACHJOVEM): doc/teachjove.nr X @sed -e 's;TMPDIR;$(TMPDIR);' \ X -e 's;LIBDIR;$(LIBDIR);' \ X -e 's;SHELL;$(SHELL);' doc/teachjove.nr > /tmp/teachjove.nr X install -m 644 /tmp/teachjove.nr $(TEACHJOVEM) X echo: X @echo $(C-FILES) $(HEADERS) X lint: X lint -n $(C_SRC) tune.c keymaps.c X @echo Done X tags: X ctags -w $(C_SRC) $(HEADERS) iproc-ptys.c X ciall: X ci $(BACKUPS) X coall: X co $(BACKUPS) X jove.shar: X shar $(BACKUPS) > jove.shar X backup: $(BACKUPS) X tar chf backup $(BACKUPS) X tape-backup: X tar c $(BACKUPS) X srcdownload: X kermit -s $(SUPPORT) $(MISC) $(HEADERS) $(C_SRC) X docdownload: X kermit -s $(DOCS) X touch: X touch $(OBJECTS) X clean: X rm -f a.out core *.o keymaps.c tune.c xjove portsrv recover setmaps \ X teachjove macvert X X# This version only works under 4.3BSD X#depend: X# for i in ${SOURCES} ; do \ X# cc -M ${CFLAGS} $$i | awk ' { if ($$1 != prev) \ X# { if (rec != "") print rec; rec = $$0; prev = $$1; } \ X# else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \ X# else rec = rec " " $$2 } } \ X# END { print rec } ' >> makedep; done X# echo '/^# DO NOT DELETE THIS LINE/+2,$$d' >eddep X# echo '$$r makedep' >>eddep X# echo 'w' >>eddep X# cp Makefile Makefile.bak X# ed - Makefile < eddep X# rm eddep makedep X# echo '# DEPENDENCIES MUST END AT END OF FILE' >> Makefile X# echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile X# echo '# see make depend above' >> Makefile X# X## DO NOT DELETE THIS LINE -- make depend uses it END_OF_FILE if test 8207 -ne `wc -c <'./Makefile'`; then echo shar: \"'./Makefile'\" unpacked with wrong size! fi # end of './Makefile' fi if test -f './README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./README'\" else echo shar: Extracting \"'./README'\" \(8923 characters\) sed "s/^X//" >'./README' <<'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 To make JOVE edit Makefile to set the right directories for the binaries, on line documentation, the man pages, and the TMP files and select the appropriate load command (see SEPFLAG in Makefile). (IMPORTANT! read the Makefile carefully.) "tune.c" will be created from "tune.template" by MAKE automatically, and it will use the directories you specified in the Makefile. (NOTE: You should never edit tune.c directly because your changes will be undone by the next make. If you want to make a change to a part of tune.c that isn't a directory name, you should edit tune.template.) Next you must edit "tune.h" selecting the compile time options you care about. See below for a description of all the compile time options. You can type "make" to compile XJOVE, PORTSRV (this is compiled but not used on 4.2+ systems), RECOVER TEACHJOVE, and MACVERT. NOTE: make won't work if it fires up /bin/csh for the shell commands. Test them out to see if they work. If they do, type "make install" to install everything where it belongs. X Here are some things to consider for deciding where to put the tmp files. TMPDIR is where the tmp files get stored, usually /tmp or /tmp/jove. If your system does not remove subdirectories of /tmp on reboot (lots do remove them these days) then it makes sense to make TMPDIR be /tmp/jove. But if you want to recover buffers on system crashes, you should create a directory that doesn't get cleared upon reboot, and use that instead. You would probably want to clean out that directory periodically with X/etc/cron. X For the pdp11 version there is the Ovmakefile. This has only been tested on 2.9bsd. It works pretty well, actually, and it is possible to turn on all the compile time options with this version. X Bug reports: If you find bugs in JOVE I would appreciate hearing about them. (My net address is at end of this message.) So, send me the bug reports. If the bug isn't already fixed, I will ask you to send me the fix. If you haven't found the bug, I may be able to, so don't wait until you have found it. If you make improvements to JOVE and want them incorporated into the official version, send me a message explaining what the change is, and I will decide whether I want to include it. If it is possible for your change to be #ifdef'd in, that would be best, since I want to avoid making JOVE huge. For instance, if it's a new package type thing (say, like word abbrev. mode, or something) then it would be best if that were a compile-time option. I will send out periodic updates to mod.sources. I will report all significant bug fixes there, and to net.emacs as well. X Here's a list of the compile time options and what they mean: X ABBREV - Enables word-abbrev-mode which again is nice for paper writers. X BACKUPFILES - This enables backing up files on write. I guess lots of X people like this feature. It enables the feature but you X can still control whether files are backed up with the X make-backup-files variable. X BIFF - This enables turning on and off BIFF so your screen doesn't X get messed up with messages from BIFF. X BSD4_2 - Obviously, if you're a Berkeley 4.2 system. X BSD4_3 - If you're running a Berkeley 4.3 or 2.10 system. X This will automatically define BSD4_2, also. X CHDIR - This enables the directory commands; PUSHD, POPD, DIRS and X CD. These simulate the csh commands exactly, I think. As X a side-effect, absolute path names are enabled, which means X JOVE parses file names for "." and ".." and all that to get X at what you REALLY mean. It's nicer when this is enabled, X but not essential. X CMT_FMT - This enables code to format and indent C comments. X ID_CHAR - Enables support for Insert/Delete character on terminals X that have those capabilities. Couple of problems with this code: X it's large, takes up lots of I space which is a problem for the X smaller computers (pdp11). Also, it isn't particularly smart X and sometimes does really stupid things. It sometimes uses X insert/delete character when simply redrawing would have been X faster. And if you look at code you'll understand why I don't X like it all that much. X IPROCS - Nice feature which lets you run interactive UNIX commands in X windows. In particular, there is a shell command built X in which starts up an interactive shell in a window. This works X only on systems with JOB_CONTROL since it relies on the fancy X signal mechanism. X JOB_CONTROL - Versions of UNIX that have the job control facility. X Berkeley 2.9-10 systems, and the 4.1-3 systems I know have X job stopping, so if you're one of those, define X this. The reason MENLO_JCL is defined when JOB_CONTROL X is that the 2.9 signal.h file only defines all of the job X stopping signals only when MENLO_JCL is defined. X LISP - Enables Lisp Mode. This includes code to indent "properly" X for Lisp code and new routines to move over s-expressions. X You probably won't want (or need) this on PDP-11's. X MY_MALLOC - Use the older version of malloc that is more memory efficient X than the newer 4BSD version. The 4BSD version places more X importance on the speed of the allocation than the amount of X memory it uses. Make your choice ... JOVE hardly ever calls X malloc, anyway, relatively speaking, since it allocates X lines in big chunks. NOTE: This doesn't seem to work on suns X and the iAPX286. X PIPEPROCS - If NOT defined, JOVE will use Berkeley pseudo-ttys when X doing interactive processes. This is infinitely better, X since you get job control and all that stuff on i-procs. X If defined, the portsrv program will have to be made, and X all communication between jove and i-procs will be done using X pipes. X RESHAPING - This is for BRL or Berkeley 4.3 and 2.10 systems. When the X window size of the terminal jove is running in is changed X a SIGWINCH is sent to all processes in the tty group. This X define enables code in jove to catch that signal and reshape X its windows. X SPELL - Enables the spell-buffer and parse-spelling-errors commands. X They are nice especially if you have lots of paper writers. X WIRED_TERMS - Include compiled-in hard-wired code for certain terminals, X like the Concept 100. If you don't have these terminals, X you probably don't need this (but no point in taking it X out unless you're low on space). X The macros have been rewritten from scratch. The most noteable change is that they are no longer stored in binary files. The write-macros-to-file command writes a file which is suitable for use with the source command. So you can have actual macro definitions in your .joverc if you want. If you have lots of macros defined in the old format, you can use the macvert program to convert them to the new style. You say X macvert old-style-macros-file > new-style-macro-file X X"doc/system.rc" and "doc/example.rc" are jove initialization files. X"system.rc" is the "system" rc file here at UoR, and it gets ready every time JOVE starts up FOR EVERYONE. ("make install" should copy the system-wide .joverc to the right place automatically.) After that JOVE reads an initialization file in the user's home directory. "example.rc" is my personal .joverc. X The files "jove.[12345]" in DOC are the official JOVE manual. I got permission from Richard Stallman to use his manual for the original EMACS, modifying it where necessary for JOVE. Lots of work was done by Brian Harvey on this manual. X There are man pages for jove and teachjove. Teachjove is for people who have never used EMACS style editors. It is an interactive tutorial, THE tutorial written by Stallman for the original EMACS, only slightly modified for JOVE in the appropriate places. The man pages are completely up to date, thanks to me. X Thanks to Jay (hack) Fenlason for writing the original pty code. X Thanks to Dave Curry at Purdue for putting in tons of time and effort into getting JOVE ready. It just wouldn't be working without his help. X Thanks to Jeff Mc Carrell at Berkeley for finding bugs and adding features, in particular, the comment formatter. X Thanks to Karl Gegenfurtner for making the PC version. X X(Thanks to Brian Harvey for teaching me about linked lists ...) X Good luck, have fun. X X Jonathan Payne (jpayne@cs.rochester.edu until '88) END_OF_FILE if test 8923 -ne `wc -c <'./README'`; then echo shar: \"'./README'\" unpacked with wrong size! fi # end of './README' fi if test -f './fmt.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./fmt.c'\" else echo shar: Extracting \"'./fmt.c'\" \(7964 characters\) sed "s/^X//" >'./fmt.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 "termcap.h" X X#ifdef MAC X# include "mac.h" X#else X# include <varargs.h> X#endif X X#ifdef MAC X# undef private X# define private X#endif X X#ifdef LINT_ARGS private void X doformat(File *, char *, ...), X outld(long, int), X pad(int, int), X PPchar(int, char *), X putld(long, int), X puts(char *); X#else private void X doformat(), X outld(), X pad(), X PPchar(), X putld(), X puts(); X#endif /* LINT_ARGS */ X X#ifdef MAC X# undef private X# define private static X#endif X X char mesgbuf[MESG_SIZE]; X X/* VARARGS2 */ X void format(buf, len, fmt, ap) char *buf, X *fmt; va_list ap; X{ X File strbuf, X *sp = &strbuf; X X sp->f_ptr = sp->f_base = buf; X sp->f_fd = -1; /* Not legit for files */ X sp->f_cnt = len; X sp->f_flags = F_STRING; X sp->f_bufsize = len; X X doformat(sp, fmt, ap); X putc('\0', sp); X} X X#ifdef IBMPC int specialmap = 0, X specialkey = 0; X X#define Empty "" X char *altseq[133] = { Empty, Empty, Empty, "Ctrl-@", Empty, Empty, Empty, Empty, Empty, Empty, Empty, Empty, Empty, Empty, Empty, "Left", X"Alt-Q", "Alt-W", "Alt-E", "Alt-R", "Alt-T", "Alt-Y", "Alt-U", "Alt-I", X"Alt-O", "Alt-P", Empty, Empty, Empty, Empty, "Alt-A", "Alt-S", X"Alt-D", "Alt-F", "Alt-G", "Alt-H", "Alt-J", "Alt-K", "Alt-L", Empty, Empty, Empty, Empty, Empty, "Alt-Z", "Alt-X", "Alt-C", "Alt-V", X"Alt-B", "Alt-N", "Alt-M", Empty, Empty, Empty, Empty, Empty, Empty, Empty, Empty, "F1", "F2", "F3", "F4", "F5", X"F6", "F7", "F8", "F9", "F10", Empty, Empty, "Home", X"Up", "PageUp", Empty, "Left", Empty, "Right", Empty, "End", X"Down", "PageDown", "Ins", "Del", "Shift F1", "Shift F2", "Shift F3", "Shift F4", X"Shift F5", "Shift F6", "Shift F7", "Shift F8", "Shift F9", "Shift F10", "Ctrl F1", "Ctrl F2", X"Ctrl F3", "Ctrl F4", "Ctrl F5", "Ctrl F6", "Ctrl F7", "Ctrl F8", "Ctrl F9", "Ctrl F10", X"Alt F1", "Alt F2", "Alt F3", "Alt F4", "Alt F5", "Alt F6", "Alt F7", "Alt F8", X"Alt F9", "Alt F10", "Ctrl PrtSc", "Ctrl Left", "Ctrl Right", "Ctrl End", "Ctrl PageDown", "Ctrl Home", X"Alt 1", "Alt 2", "Alt 3", "Alt 4", "Alt 5", "Alt 6", "Alt 7", "Alt 8", X"Alt 9", "Alt 0", "Alt Minus", "Alt Equals", "Ctrl PageUp" X}; X#endif X X private void PPchar(c, str) int c; char *str; X{ X char *cp = str; X X#ifdef IBMPC X if (specialmap || specialkey) { X if (c < 0 || c > 132) X c = 0; X strcpy(cp, altseq[c]); X } else X#endif X if (c == '\033') X strcpy(cp, "ESC"); X#ifdef IBMPC /* this character is invisible */ X else if (c == '\377') { X *cp = 0; X } X#endif /* IBMPC */ X else if (c < ' ') X sprintf(cp, "C-%c", c + '@'); X else if (c == '\177') X strcpy(cp, "^?"); X else X sprintf(cp, "%c", c); X} X private struct fmt_state { X int precision, X width, X leftadj; X char padc; X File *iop; X} current_fmt; X private void putld(d, base) long d; X{ X int length = 1; X long tmpd = d; X X if (current_fmt.width == 0 && current_fmt.precision) { X current_fmt.width = current_fmt.precision; X current_fmt.padc = '0'; X } X while (tmpd = (tmpd / base)) X length += 1; X if (d < 0) X length += 1; X if (!current_fmt.leftadj) X pad(current_fmt.padc, current_fmt.width - length); X if (d < 0) { X putc('-', current_fmt.iop); X d = -d; X } X outld(d, base); X if (current_fmt.leftadj) X pad(current_fmt.padc, current_fmt.width - length); X} X private void outld(d, base) long d; X{ X register long n; X static char chars[] = {'0', '1', '2', '3', '4', '5', '6', X '7', '8', '9', 'a', 'b', 'c', 'd', X 'e', 'f'}; X X if (n = (d / base)) X outld(n, base); X putc((int) (chars[(int) (d % base)]), current_fmt.iop); X} X private void puts(str) char *str; X{ X int length; X register char *cp; X X if (str == 0) X#if pyr X str = ""; X#else X str = "(null)"; X#endif X length = strlen(str); X if (current_fmt.precision == 0 || length < current_fmt.precision) X current_fmt.precision = length; X else X length = current_fmt.precision; X cp = str; X if (!current_fmt.leftadj) X pad(' ', current_fmt.width - length); X while (--current_fmt.precision >= 0) X putc(*cp++, current_fmt.iop); X if (current_fmt.leftadj) X pad(' ', current_fmt.width - length); X} X private void pad(c, amount) register int c, X amount; X{ X while (--amount >= 0) X putc(c, current_fmt.iop); X} X private void doformat(sp, fmt, ap) register File *sp; register char *fmt; va_list ap; X{ X register char c; X struct fmt_state prev_fmt; X X prev_fmt = current_fmt; X current_fmt.iop = sp; X X while (c = *fmt++) { X if (c != '%') { X putc(c, current_fmt.iop); X continue; X } X X current_fmt.padc = ' '; X current_fmt.precision = current_fmt.leftadj = current_fmt.width = 0; X c = *fmt++; X if (c == '-') { X current_fmt.leftadj = YES; X c = *fmt++; X } X if (c == '0') { X current_fmt.padc = '0'; X c = *fmt++; X } X while (c >= '0' && c <= '9') { X current_fmt.width = current_fmt.width * 10 + (c - '0'); X c = *fmt++; X } X if (c == '*') { X current_fmt.width = va_arg(ap, int); X c = *fmt++; X } X if (c == '.') { X c = *fmt++; X while (c >= '0' && c <= '9') { X current_fmt.precision = current_fmt.precision * 10 + (c - '0'); X c = *fmt++; X } X if (c == '*') { X current_fmt.precision = va_arg(ap, int); X c = *fmt++; X } X } X reswitch: X /* At this point, fmt points at one past the format letter. */ X switch (c) { X case '%': X putc('%', current_fmt.iop); X break; X X case 'O': X case 'D': X case 'X': X putld(va_arg(ap, long), (c == 'O') ? 8 : X (c == 'D') ? 10 : 16); X break; X X case 'b': X { X Buffer *b = va_arg(ap, Buffer *); X X puts(b->b_name); X break; X } X X case 'c': X putc(va_arg(ap, int), current_fmt.iop); X break; X X case 'o': X case 'd': X case 'x': X putld((long) va_arg(ap, int), (c == 'o') ? 8 : X (c == 'd') ? 10 : 16); X break; X X case 'f': /* current command name gets inserted here! */ X puts(LastCmd->Name); X break; X X case 'l': X c = CharUpcase(*++fmt); X goto reswitch; X X case 'n': X if (va_arg(ap, int) != 1) X puts("s"); X break; X X case 'p': X { X char cbuf[20]; X X PPchar(va_arg(ap, int), cbuf); X puts(cbuf); X break; X } X X case 's': X puts(va_arg(ap, char *)); X break; X X default: X complain("Unknown format directive: \"%%%c\"", c); X } X } X current_fmt = prev_fmt; X} X X/* VARARGS1 */ X char * sprint(fmt, va_alist) char *fmt; va_dcl X{ X va_list ap; X static char line[100]; X X va_start(ap); X format(line, sizeof line, fmt, ap); X va_end(ap); X return line; X} X X/* VARARGS1 */ X void printf(fmt, va_alist) char *fmt; va_dcl X{ X va_list ap; X X va_start(ap); X#ifndef IBMPC X doformat(stdout, fmt, ap); X#else /* IBMPC */ X write_em(sprint(fmt, ap)); X /* doformat(stdout, fmt, ap); */ X#endif /* IBMPC */ X va_end(ap); X} X X/* VARARGS1 */ X void fprintf(fp, fmt, va_alist) File *fp; char *fmt; va_dcl X{ X va_list ap; X X va_start(ap); X doformat(fp, fmt, ap); X va_end(ap); X} X X/* VARARGS2 */ X void sprintf(str, fmt, va_alist) char *str, X *fmt; va_dcl X{ X va_list ap; X X va_start(ap); X format(str, 130, fmt, ap); X va_end(ap); X} X X/* VARARGS1 */ X void s_mess(fmt, va_alist) char *fmt; va_dcl X{ X va_list ap; X X if (InJoverc) X return; X va_start(ap); X format(mesgbuf, sizeof mesgbuf, fmt, ap); X va_end(ap); X message(mesgbuf); X} X X/* VARARGS1 */ X void f_mess(fmt, va_alist) char *fmt; va_dcl X{ X va_list ap; X X va_start(ap); X format(mesgbuf, sizeof mesgbuf, fmt, ap); X va_end(ap); X DrawMesg(NO); X UpdMesg = YES; /* still needs updating (for convenience) */ X} X X/* VARARGS1 */ X void add_mess(fmt, va_alist) char *fmt; va_dcl X{ X int mesg_len = strlen(mesgbuf); X va_list ap; X X if (InJoverc) X return; X va_start(ap); X format(&mesgbuf[mesg_len], (sizeof mesgbuf) - mesg_len, fmt, ap); X va_end(ap); X message(mesgbuf); X} END_OF_FILE if test 7964 -ne `wc -c <'./fmt.c'`; then echo shar: \"'./fmt.c'\" unpacked with wrong size! fi # end of './fmt.c' fi if test -f './iproc.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./iproc.c'\" else echo shar: Extracting \"'./iproc.c'\" \(9262 characters\) sed "s/^X//" >'./iproc.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 "re.h" X#include <varargs.h> X X#ifdef IPROCS X int proc_child(); X X#ifdef PIPEPROCS X# include "iproc-pipes.c" X#else X# include "iproc-ptys.c" X#endif X char proc_prompt[128] = "% "; X KillProcs() X{ X register Process *p; X register int killem = -1; /* -1 means undetermined */ X register char *yorn; X X for (p = procs; p != 0; p = p->p_next) X if (!isdead(p)) { X if (killem == -1) { X yorn = ask("y", "Should I kill your i-processes? "); X killem = (CharUpcase(*yorn) == 'Y'); X } X if (killem) X proc_kill(p, SIGKILL); X } X} X pbuftiedp(b) register Buffer *b; X{ X register Process *p = b->b_process; X X if (!isdead(p)) X complain("Process %s, attached to %b, is %s.", X proc_cmd(p), b, pstate(p)); X} X X/* Process receive: receives the characters in buf, and appends them to X the buffer associated with p. */ X private proc_rec(p, buf) register Process *p; char *buf; X{ X Buffer *saveb = curbuf; X register Window *w; X register Mark *savepoint; X int sameplace = NO, X do_disp = NO; X X if (curwind->w_bufp == p->p_buffer) X w = curwind; X else X w = windbp(p->p_buffer); /* Is this window visible? */ X if (w != 0) X do_disp = (in_window(w, p->p_mark->m_line) != -1); X SetBuf(p->p_buffer); X savepoint = MakeMark(curline, curchar, M_FLOATER); X ToMark(p->p_mark); /* where output last stopped */ X if (savepoint->m_line == curline && savepoint->m_char == curchar) X sameplace = YES; X X ins_str(buf, YES); X MarkSet(p->p_mark, curline, curchar); X if (!sameplace) X ToMark(savepoint); /* back to where we were */ X DelMark(savepoint); X /* redisplay now, instead of right after the ins_str, so that X we don't get a bouncing effect if point is not the same as X the process output position */ X if (do_disp) { X w->w_line = curline; X w->w_char = curchar; X redisplay(); X } X SetBuf(saveb); X} X proc_kill(p, sig) register Process *p; X{ X if (isdead(p)) X return; X if (killpg(p->p_pid, sig) == -1) X s_mess("Cannot kill %s!", proc_buf(p)); X} X X/* Free process CHILD. Do all the necessary cleaning up (closing fd's, X etc.). */ X free_proc(child) Process *child; X{ X register Process *p, X *prev = 0; X X if (!isdead(child)) X return; X for (p = procs; p != child; prev = p, p = p->p_next) X ; X if (prev == 0) X procs = child->p_next; X else X prev->p_next = child->p_next; X proc_close(child); /* if not already closed */ X X /* It's possible that the buffer has been given another process X between the time CHILD dies and CHILD's death is noticed (via X list-processes). So we only set it the buffer's process to X 0 if CHILD is still the controlling process. */ X if (child->p_buffer->b_process == child) { X child->p_buffer->b_process = 0; X if (curbuf == child->p_buffer) X PopPBs(); X } X { X Buffer *old = curbuf; X X SetBuf(child->p_buffer); X DelMark(child->p_mark); X SetBuf(old); X } X free((char *) child->p_name); X free((char *) child); X} X ProcList() X{ X register Process *p, X *next; X char *fmt = "%-15s %-15s %-8s %s", X pidstr[16]; X X if (procs == 0) { X message("[No subprocesses]"); X return; X } X TOstart("Process list", TRUE); X X Typeout(fmt, "Buffer", "Status", "Pid ", "Command"); X Typeout(fmt, "------", "------", "--- ", "-------"); X for (p = procs; p != 0; p = next) { X next = p->p_next; X sprintf(pidstr, "%d", p->p_pid); X Typeout(fmt, proc_buf(p), pstate(p), pidstr, p->p_name); X if (isdead(p)) { X free_proc(p); X UpdModLine = YES; X } X } X TOstop(); X} X ProcNewline() X{ X#ifdef ABBREV X MaybeAbbrevExpand(); X#endif X SendData(YES); X} X ProcSendData() X{ X#ifdef ABBREV X MaybeAbbrevExpand(); X#endif X SendData(NO); X} X private SendData(newlinep) X{ X register Process *p = curbuf->b_process; X register char *lp, X *gp; /* JF fix for better prompt handling */ X X if (isdead(p)) X return; X /* If the process mark was involved in a big deletion, because X the user hit ^W or something, then let's do some magic with X the process mark. Problem is that if the user yanks back the X text he deleted, the mark stays at the beginning of the region, X and so the next time SendData() is called the entire region X will be sent. That's not good. So, to deal with that we reset X the mark to the last line, after skipping over the prompt, etc. */ X if (p->p_mark->m_flags & M_BIG_DELETE) { X Bufpos bp; X X p->p_mark->m_flags &= ~M_BIG_DELETE; X X DOTsave(&bp); X ToLast(); X Bol(); X /* While we're looking at a prompt, and while we're X moving forward. This is for people who accidently X set their process-prompt to ">*" which will always X match! */ X while ((LookingAt(proc_prompt, linebuf, curchar)) && X (REeom > curchar)) X curchar = REeom; X MarkSet(p->p_mark, curline, curchar); X SetDot(&bp); X } X X if (lastp(curline)) { X Eol(); X if (newlinep) X LineInsert(1); X do_rtp(p->p_mark); X MarkSet(p->p_mark, curline, curchar); X } else { X /* Either we're looking at a prompt, or we're not, in X which case we want to strip off the beginning of the X line anything that looks like what the prompt at the X end of the file is. In other words, if "(dbx) stop in X ProcessNewline" is the line we're on, and the last X line in the buffer is "(dbx) ", then we strip off the X leading "(dbx) " from this line, because we know it's X part of the prompt. But this only happens if "(dbx) " X isn't one of the process prompts ... follow what I'm X saying? */ X Bol(); X if (LookingAt(proc_prompt, linebuf, curchar)) { X do X curchar = REeom; X while ((LookingAt(proc_prompt, linebuf, curchar)) && X (REeom > curchar)); X strcpy(genbuf, linebuf + curchar); X Eof(); X ins_str(genbuf, NO); X } else { X strcpy(genbuf, linebuf + curchar); X Eof(); X gp = genbuf; X lp = linebuf; X while (*lp == *gp && *lp != '\0') { X lp += 1; X gp += 1; X } X ins_str(gp, NO); X } X } X} X ShellProc() X{ X char *shbuf = "*shell*"; X register Buffer *b; X X b = buf_exists(shbuf); X if (b == 0 || isdead(b->b_process)) X proc_strt(shbuf, NO, Shell, "-i", (char *) 0); X pop_wind(shbuf, NO, -1); X} X Iprocess() X{ X extern char ShcomBuf[100], X *MakeName(); X register char *command; X char scratch[64], X *bufname; X int cnt = 1; X Buffer *bp; X X command = ask(ShcomBuf, ProcFmt); X null_ncpy(ShcomBuf, command, (sizeof ShcomBuf) - 1); X bufname = MakeName(command); X strcpy(scratch, bufname); X while ((bp = buf_exists(scratch)) && !isdead(bp->b_process)) X sprintf(scratch, "%s.%d", bufname, cnt++); X proc_strt(scratch, YES, Shell, ShFlags, command, (char *) 0); X} X proc_child() X{ X union wait w; X register int pid; X X for (;;) { X#ifndef BSD4_2 X pid = wait2(&w.w_status, (WNOHANG | WUNTRACED)); X#else X pid = wait3(&w, (WNOHANG | WUNTRACED), (struct rusage *) 0); X#endif X if (pid <= 0) X break; X kill_off(pid, w); X } X} X kill_off(pid, w) register int pid; union wait w; X{ X register Process *child; X X if ((child = proc_pid(pid)) == 0) X return; X X UpdModLine = YES; /* we're changing state ... */ X if (WIFSTOPPED(w)) X child->p_state = STOPPED; X else { X child->p_state = DEAD; X if (WIFEXITED(w)) X child->p_howdied = EXITED; X else if (WIFSIGNALED(w)) { X child->p_reason = w.w_termsig; X child->p_howdied = KILLED; X } X { X Buffer *save = curbuf; X char mesg[128]; X X /* insert status message now */ X sprintf(mesg, "[Process %s: %s]\n", X proc_cmd(child), X pstate(child)); X SetBuf(child->p_buffer); X ins_str(mesg, NO); X SetBuf(save); X redisplay(); X } X } X} X X/* Push/pod process bindings. I openly acknowledge that this is a X kludge, but I can't be bothered making it right. */ X struct proc_bind { X int pb_key; X data_obj **pb_map; X data_obj *pb_push; X data_obj *pb_cmd; X struct proc_bind *pb_next; X}; X struct proc_bind *PBinds = 0; X PopPBs() X{ X register struct proc_bind *p; X X for (p = PBinds; p != 0; p = p->pb_next) X p->pb_map[p->pb_key] = p->pb_push; X} X PushPBs() X{ X register struct proc_bind *p; X X for (p = PBinds; p != 0; p = p->pb_next) { X p->pb_push = p->pb_map[p->pb_key]; X p->pb_map[p->pb_key] = p->pb_cmd; X } X} X/* VARARGS0 */ X ProcBind() X{ X register data_obj *d; X X if ((d = findcom(ProcFmt)) == 0) X return; X s_mess(": %f %s ", d->Name); X ProcB2(mainmap, EOF, d); X} X ProcB2(map, lastkey, cmd) data_obj **map, X *cmd; X{ X register struct proc_bind *p; X register data_obj **nextmap; X int c; X X c = addgetc(); X if (c == EOF) { X if (lastkey == EOF) X complain("[Empty key sequence]"); X complain("[Unexpected end-of-line]"); X } else { X if (nextmap = IsPrefix(map[c])) X ProcB2(nextmap, c, cmd); X else { X if (curbuf->b_process) X PopPBs(); X X for (p = PBinds; p != 0; p = p->pb_next) X if (p->pb_key == c && p->pb_map == map) X break; X if (p == 0) { X p = (struct proc_bind *) emalloc(sizeof *p); X p->pb_next = PBinds; X PBinds = p; X } X p->pb_map = map; X p->pb_key = c; X p->pb_cmd = cmd; X X if (curbuf->b_process) X PushPBs(); X } X } X} X X#endif /* IPROCS */ X END_OF_FILE if test 9262 -ne `wc -c <'./iproc.c'`; then echo shar: \"'./iproc.c'\" unpacked with wrong size! fi # end of './iproc.c' fi if test -f './misc.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./misc.c'\" else echo shar: Extracting \"'./misc.c'\" \(7989 characters\) sed "s/^X//" >'./misc.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#include <signal.h> X#ifdef ANSICODES X#include "termcap.h" X#endif X void prCTIME() X{ X s_mess(": %f %s", get_time((time_t *) 0, (char *) 0, 0, -1)); X} X void ChrToOct() X{ X int c, X slow; X X c = waitchar(&slow); X if (slow) X message(key_strokes); X ins_str(sprint("\\%03o", c), NO); X} X void StrLength() X{ X static char inquotes[] = "Where are the quotes?"; X char *first = StrIndex(-1, linebuf, curchar, '"'), X *last = StrIndex(1, linebuf, curchar + 1, '"'), X c; X int numchars = 0; X X if (first == 0 || last == 0) X complain(inquotes); X first += 1; X while (first < last) { X c = *first++; X if (c == '\\') { X int num; X X if (!isdigit(*first)) X first += 1; X else { X num = 3; X while (num-- && isdigit(*first++) && first < last) X ; X } X } X numchars += 1; X } X s_mess("%d characters", numchars); X} X X/* Transpos cur_char with cur_char - 1 */ X void TransChar() X{ X char before; X X if (curchar == 0 || (eolp() && curchar == 1)) X complain((char *) 0); /* BEEP */ X if (eolp()) X b_char(1); X before = linebuf[curchar - 1]; X del_char(BACKWARD, 1); X f_char(1); X insert_c(before, 1); X} X X/* Switch current line with previous one */ X void TransLines() X{ X disk_line old_prev; X X if (firstp(curline)) X return; X lsave(); X old_prev = curline->l_prev->l_dline; X curline->l_prev->l_dline = curline->l_dline; X curline->l_dline = old_prev; X getDOT(); X if (!lastp(curline)) X line_move(FORWARD, 1, NO); X modify(); X} X void Leave() X{ X longjmp(mainjmp, QUIT); X} X X/* If argument is specified, kill that many lines down. Otherwise, X if we "appear" to be at the end of a line, i.e. everything to the X right of the cursor is white space, we delete the line separator X as if we were at the end of the line. */ X void KillEOL() X{ X Line *line2; X int char2; X int num = arg_value(); X X if (is_an_arg()) { X if (num == 0) { /* Kill to beginning of line */ X line2 = curline; X char2 = 0; X } else { X line2 = next_line(curline, num); X if ((LineDist(curline, line2) < num) || (line2 == curline)) X char2 = length(line2); X else X char2 = 0; X } X } else if (blnkp(&linebuf[curchar])) { X line2 = next_line(curline, 1); X if (line2 == curline) X char2 = length(curline); X else X char2 = 0; X } else { X line2 = curline; X char2 = length(curline); X } X reg_kill(line2, char2, 0); X} X X/* kill to beginning of sentence */ X void KillBos() X{ X negate_arg_value(); X KillEos(); X} X X/* Kill to end of sentence */ X void KillEos() X{ X Line *line1; X int char1; X X line1 = curline; X char1 = curchar; X Eos(); X reg_kill(line1, char1, 1); X} X void KillExpr() X{ X Line *line1; X int char1; X X line1 = curline; X char1 = curchar; X FSexpr(); X reg_kill(line1, char1, 1); X} X void EscPrefix() X{ X HandlePref(pref1map); X} X void CtlxPrefix() X{ X HandlePref(pref2map); X} X void MiscPrefix() X{ X HandlePref(miscmap); X} X void HandlePref(map) data_obj **map; X{ X register data_obj *cp; X register int c; X int slow; X X c = waitchar(&slow); X if (c == AbortChar) { X message("[Aborted]"); X rbell(); X return; X } X X if (slow) X message(key_strokes); X X cp = map[c]; X if (cp == 0) { X s_mess("[%sunbound]", key_strokes); X rbell(); X } else X ExecCmd(cp); X} X void Yank() X{ X Line *line, X *lp; X Bufpos *dot; X X if (killbuf[killptr] == 0) X complain("[Nothing to yank!]"); X lsave(); X this_cmd = YANKCMD; X line = killbuf[killptr]; X lp = lastline(line); X dot = DoYank(line, 0, lp, length(lp), curline, curchar, curbuf); X set_mark(); X SetDot(dot); X} X void WtModBuf() X{ X if (!ModBufs(NO)) X message("[No buffers need saving]"); X else X put_bufs(is_an_arg()); X} X void put_bufs(askp) X{ X register Buffer *oldb = curbuf, X *b; X X for (b = world; b != 0; b = b->b_next) { X if (!IsModified(b) || b->b_type != B_FILE) X continue; X SetBuf(b); /* Make this current Buffer */ X if (curbuf->b_fname == 0) { X char *newname; X X newname = ask(NullStr, "Buffer \"%s\" needs a file name; type Return to skip: ", b->b_name); X if (*newname == 0) X continue; X setfname(b, newname); X } X if (askp && (yes_or_no_p("Write %s? ", curbuf->b_fname) == NO)) X continue; X filemunge(curbuf->b_fname); X#ifndef MAC X#ifndef MSDOS X chk_mtime(curbuf, curbuf->b_fname, "save"); X#endif /* MSDOS */ X#endif /* MAC */ X file_write(curbuf->b_fname, 0); X unmodify(); X } X SetBuf(oldb); X} X void ToIndent() X{ X register char *cp, X c; X X for (cp = linebuf; c = *cp; cp++) X if (c != ' ' && c != '\t') X break; X curchar = cp - linebuf; X} X X/* GoLine -- go to a line, usually wired to goto-line, ESC g or ESC G. X If no argument is specified it asks for a line number. */ void GoLine() X{ X Line *newline; X X#ifndef ANSICODES X if (!is_an_arg()) X set_arg_value(ask_int("Line: ",10)); X#else /* not ANSICODES */ X if (!is_an_arg() || arg_value() <= 0) { X if (SP) { X putpad(SP, 1); /* Ask for cursor position */ X return; X } X set_arg_value(ask_int("Line: ", 10)); X } X#endif /* ANSICODES */ X newline = next_line(curbuf->b_first, arg_value() - 1); X PushPntp(newline); X SetLine(newline); X} X X#ifdef ANSICODES void MoveToCursor(line, col) X{ X register struct scrimage *sp = &PhysScreen[line]; X X while (sp->s_id == 0) X sp = &PhysScreen[--line]; X if (sp->s_flags & MODELINE) X complain((char *) 0); X if (curwind != sp->s_window) X SetWind(sp->s_window); X SetLine(sp->s_lp); X curchar = how_far(sp->s_lp, col); X} X void AnsiCodes() X{ X int c; X int num1 = 0; X int num2; X static char *unsupported = "[Unsupported ANSI code received]"; X X while (isdigit(c = getch())) X num1 = (num1 * 10) + (c - '0'); X X switch (c) { X case ';': X num2 = 0; X while (isdigit(c = getch())) X num2 = (num2 * 10) + (c - '0'); X switch (c) { X case 'R': X MoveToCursor(--num1, --num2); X break; X case 'H': X Eow(); X Bol(); X break; X default: X complain(unsupported); X } X break; X case 'A': X PrevLine(); X break; X case 'B': X NextLine(); X break; X case 'C': X ForChar(); X break; X case 'D': X BackChar(); X break; X case 'H': X Bow(); X break; X case 'J': X if (num1 == 2) { X ClAndRedraw(); X break; X } X case 'z': /* Sun function keys send <esc>[Nz */ X switch(num1) { X case 193: /* L2 */ X SetMark(); X break; X case 194: /* L3 */ X PopMark(); X break; X case 195: /* L4 */ X DelReg(); X break; X case 208: /* R1 */ X QRepSearch(); X break; X case 209: /* R2 */ X IncFSearch(); X break; X case 210: /* R3 */ X WtModBuf(); X break; X case 211: /* R4 */ X RepSearch(); X break; X case 212: /* R5 */ X IncRSearch(); X break; X case 213: /* R6 */ X Leave(); X break; X case 214: /* R7 */ X BackWord(); X break; X case 215: /* R8 == UpArrow */ X break; X case 216: /* R9 */ X ForWord(); X break; X case 217: /* R10 == LeftArrow */ X break; X case 218: /* R11 */ X NextWindow(); X break; X case 219: /* R12 == RightArrow */ X break; X case 220: /* R13 */ X case 221: /* R14 == DownArrow */ X break; X case 222: /* R15 */ X case 225: /* F2 */ X case 226: /* F3 */ X case 227: /* F4 */ X break; X case 228: /* F5 */ X break; X case 229: /* F6 */ X break; X case 230: /* F7 */ X break; X case 231: /* F8 */ X break; X case 232: /* F9 */ X break; X default: X num1 = -1; /* Hack flags failure */ X break; X } X if (num1 >= 0) X break; X case 'P': X PrevPage(); X break; X X case 'Q': X NextPage(); X break; X X case 'R': X UpScroll(); X break; X X case 'S': X DownScroll(); X break; X default: X complain(unsupported); X } X} X#endif /* ANSICODES */ X void NotModified() X{ X unmodify(); X} X void SetLMargin() X{ X LMargin = calc_pos(linebuf, curchar); X} X void SetRMargin() X{ X RMargin = calc_pos(linebuf, curchar); X} END_OF_FILE if test 7989 -ne `wc -c <'./misc.c'`; then echo shar: \"'./misc.c'\" unpacked with wrong size! fi # end of './misc.c' fi if test -f './wind.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'./wind.c'\" else echo shar: Extracting \"'./wind.c'\" \(9907 characters\) sed "s/^X//" >'./wind.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/* This creates/deletes/divides/grows/shrinks windows. */ X X#include "jove.h" X#include "termcap.h" X private char onlyone[] = "You only have one window!", X toosmall[] = "Resulting window would be too small."; X Window *curwind, X *fwind = 0; X X/* First line in a Window */ X int FLine(w) register Window *w; X{ X register Window *wp = fwind; X register int lineno = -1; X X do { X if (wp == w) X return lineno + 1; X lineno += wp->w_height; X wp = wp->w_next; X } while (wp != fwind); X complain("window?"); X /* NOTREACHED */ X} X X/* Delete `wp' from the screen. If it is the only window left X on the screen, then complain. It gives its body X to the next window if there is one, otherwise the previous X window gets the body. */ X void del_wind(wp) register Window *wp; X{ X register Window *prev = wp->w_prev; X X if (one_windp()) X complain(onlyone); X X wp->w_prev->w_next = wp->w_next; X wp->w_next->w_prev = wp->w_prev; X X if (fwind == wp) { X fwind = wp->w_next; X fwind->w_height += wp->w_height; X /* Here try to do something intelligent for redisplay() */ X SetTop(fwind, prev_line(fwind->w_top, wp->w_height)); X if (curwind == wp) X SetWind(fwind); X } else { X prev->w_height += wp->w_height; X if (curwind == wp) X SetWind(prev); X } X#ifdef MAC X RemoveScrollBar(wp); X Windchange++; X#endif X free((char *) wp); X} X X/* Divide the window WP N times, or at least once. Complains if WP is too X small to be split into that many pieces. It returns the new window. */ X Window * div_wind(wp, n) register Window *wp; X{ X register Window *new; X int amt; X X if (n < 1) X n = 1; X amt = wp->w_height / (n + 1); X if (amt < 2) X complain(toosmall); X X while (--n >= 0) { X new = (Window *) emalloc(sizeof (Window)); X new->w_flags = 0; X new->w_LRscroll = 0; X X new->w_height = amt; X wp->w_height -= amt; X X /* set the lines such that w_line is the center in X each Window */ X new->w_line = wp->w_line; X new->w_char = wp->w_char; X new->w_bufp = wp->w_bufp; X new->w_top = prev_line(new->w_line, HALF(new)); X X /* Link the new window into the list */ X new->w_prev = wp; X new->w_next = wp->w_next; X new->w_next->w_prev = new; X wp->w_next = new; X#ifdef MAC X new->w_control = 0; X#endif X } X#ifdef MAC X Windchange++; X#endif X return new; X} X X/* Initialze the first window setting the bounds to the size of the X screen. There is no buffer with this window. See parse for the X setting of this window. */ X void winit() X{ X register Window *w; X X w = curwind = fwind = (Window *) emalloc(sizeof (Window)); X w->w_line = w->w_top = 0; X w->w_LRscroll = 0; X w->w_flags = 0; X w->w_char = 0; X w->w_next = w->w_prev = fwind; X w->w_height = ILI; X#ifdef MAC X w->w_control = 0; X Windchange++; X#endif X} X X/* Change to previous window. */ X void PrevWindow() X{ X register Window *new = curwind->w_prev; X X if (Asking) X complain((char *) 0); X if (one_windp()) X complain(onlyone); X SetWind(new); X} X X/* Make NEW the current Window */ X void SetWind(new) register Window *new; X{ X if (!Asking) { /* can you say kludge? */ X curwind->w_line = curline; X curwind->w_char = curchar; X curwind->w_bufp = curbuf; X } X if (new == curwind) X return; X SetBuf(new->w_bufp); X if (!inlist(new->w_bufp->b_first, new->w_line)) { X new->w_line = curline; X new->w_char = curchar; X } X DotTo(new->w_line, new->w_char); X if (curchar > strlen(linebuf)) X new->w_char = curchar = strlen(linebuf); X curwind = new; X} X X/* delete the current window if it isn't the only one left */ X void DelCurWindow() X{ X SetABuf(curwind->w_bufp); X del_wind(curwind); X} X X/* put the current line of `w' in the middle of the window */ X void CentWind(w) register Window *w; X{ X SetTop(w, prev_line(w->w_line, HALF(w))); X} X int ScrollStep = 0; /* full scrolling */ X X/* Calculate the new topline of the window. If ScrollStep == 0 X it means we should center the current line in the window. */ X void CalcWind(w) register Window *w; X{ X register int up; X int scr_step; X Line *newtop; X X if (ScrollStep == 0) /* Means just center it */ X CentWind(w); X else { X up = inorder(w->w_line, 0, w->w_top, 0); X if (up == -1) { X CentWind(w); X return; X } X scr_step = (ScrollStep < 0) ? SIZE(w) + ScrollStep : X ScrollStep - 1; X if (up) /* point is above the screen */ X newtop = prev_line(w->w_line, scr_step); X else X newtop = prev_line(w->w_line, (SIZE(w) - 1 - scr_step)); X if (LineDist(newtop, w->w_top) >= SIZE(w) - 1) X CentWind(w); X else X SetTop(w, newtop); X } X} X X/* This is bound to C-X 4 [BTF]. To make the screen stay the X same we have to remember various things, like the current X top line in the current window. It's sorta gross, but it's X necessary because of the way this is implemented (i.e., in X terms of do_find(), do_select() which manipulate the windows. */ X void WindFind() X{ X register Buffer *obuf = curbuf, X *nbuf; X Line *ltop = curwind->w_top; X Bufpos savedot; X extern void X FindTag(), X BufSelect(), X FindFile(); X X DOTsave(&savedot); X X switch (waitchar((int *) 0)) { X case 't': X case 'T': X ExecCmd((data_obj *) FindCmd(FindTag)); X break; X X case 'b': X case 'B': X ExecCmd((data_obj *) FindCmd(BufSelect)); X break; X X case 'f': X case 'F': X ExecCmd((data_obj *) FindCmd(FindFile)); X break; X X default: X complain("T: find-tag, F: find-file, B: select-buffer."); X } X X nbuf = curbuf; X SetBuf(obuf); X SetDot(&savedot); X SetTop(curwind, ltop); /* there! it's as if we did nothing */ X X if (one_windp()) X (void) div_wind(curwind, 1); X X tiewind(curwind->w_next, nbuf); X SetWind(curwind->w_next); X} X X/* Go into one window mode by deleting all the other windows */ X void OneWindow() X{ X while (curwind->w_next != curwind) X del_wind(curwind->w_next); X} X Window * windbp(bp) register Buffer *bp; X{ X X register Window *wp = fwind; X X if (bp == 0) X return 0; X do { X if (wp->w_bufp == bp) X return wp; X wp = wp->w_next; X } while (wp != fwind); X return 0; X} X X/* Change window into the next window. Curwind becomes the new window. */ X void NextWindow() X{ X register Window *new = curwind->w_next; X X if (Asking) X complain((char *) 0); X if (one_windp()) X complain(onlyone); X SetWind(new); X} X X/* Scroll the next Window */ X void PageNWind() X{ X if (one_windp()) X complain(onlyone); X NextWindow(); X NextPage(); X PrevWindow(); X} X Window * w_nam_typ(name, type) register char *name; X{ X register Window *w; X register Buffer *b; X X b = buf_exists(name); X w = fwind; X if (b) do { X if (w->w_bufp == b) X return w; X } while ((w = w->w_next) != fwind); X X w = fwind; X do { X if (w->w_bufp->b_type == type) X return w; X } while ((w = w->w_next) != fwind); X X return 0; X} X X/* Put a window with the buffer `name' in it. Erase the buffer if X `clobber' is non-zero. */ X void pop_wind(name, clobber, btype) register char *name; X{ X register Window *wp; X register Buffer *newb; X X if (newb = buf_exists(name)) X btype = -1; /* if the buffer exists, don't change X it's type */ X if ((wp = w_nam_typ(name, btype)) == 0) { X if (one_windp()) X SetWind(div_wind(curwind, 1)); X else X PrevWindow(); X } else X SetWind(wp); X X newb = do_select((Window *) 0, name); X if (clobber) { X initlist(newb); X newb->b_modified = NO; X } X tiewind(curwind, newb); X if (btype != -1) X newb->b_type = btype; X SetBuf(newb); X} X void GrowWindow() X{ X WindSize(curwind, abs(arg_value())); X} X void ShrWindow() X{ X WindSize(curwind, -abs(arg_value())); X} X X/* Change the size of the window by inc. First arg is the window, X second is the increment. */ X void WindSize(w, inc) register Window *w; register int inc; X{ X if (one_windp()) X complain(onlyone); X X if (inc == 0) X return; X else if (inc < 0) { /* Shrinking this Window. */ X if (w->w_height + inc < 2) X complain(toosmall); X w->w_height += inc; X w->w_prev->w_height -= inc; X } else /* Growing the window. */ X WindSize(w->w_next, -inc); X#ifdef MAC X Windchange++; X#endif X} X X/* Set the topline of the window, calculating its number in the buffer. X This is for numbering the lines only. */ X void SetTop(w, line) Window *w; register Line *line; X{ X register Line *lp = w->w_bufp->b_first; X register int num = 0; X X w->w_top = line; X if (w->w_flags & W_NUMLINES) { X while (lp) { X num += 1; X if (line == lp) X break; X lp = lp->l_next; X } X w->w_topnum = num; X } X} X void WNumLines() X{ X curwind->w_flags ^= W_NUMLINES; X SetTop(curwind, curwind->w_top); X} X void WVisSpace() X{ X curwind->w_flags ^= W_VISSPACE; X ClAndRedraw(); X} X X/* Return the line number that `line' occupies in `windes' */ X int in_window(windes, line) register Window *windes; register Line *line; X{ X register int i; X register Line *top = windes->w_top; X X for (i = 0; top && i < windes->w_height - 1; i++, top = top->l_next) X if (top == line) X return FLine(windes) + i; X return -1; X} X void SplitWind() X{ X SetWind(div_wind(curwind, is_an_arg() ? (arg_value() - 1) : 1)); X} X X/* Goto the window with the named buffer. If no such window X exists, pop one and attach the buffer to it. */ void GotoWind() X{ X extern Buffer *lastbuf; X char *bname; X Window *w; X X bname = ask_buf(lastbuf); X w = curwind->w_next; X do { X if (w->w_bufp->b_name == bname) { X SetABuf(curbuf); X SetWind(w); X return; X } X w = w->w_next; X } while (w != curwind); X SetABuf(curbuf); X pop_wind(bname, NO, -1); X} X void ScrollRight() X{ X int amt = (is_an_arg() ? arg_value() : 10); X X if (curwind->w_LRscroll - amt < 0) X curwind->w_LRscroll = 0; X else X curwind->w_LRscroll -= amt; X UpdModLine = YES; X} X void ScrollLeft() X{ X int amt = (is_an_arg() ? arg_value() : 10); X X curwind->w_LRscroll += amt; X UpdModLine = YES; X} END_OF_FILE if test 9907 -ne `wc -c <'./wind.c'`; then echo shar: \"'./wind.c'\" unpacked with wrong size! fi # end of './wind.c' fi echo shar: End of archive 4 \(of 21\). cp /dev/null ark4isdone 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 -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.