v08i024: The JOVE text editor, Part05/13
sources-request at mirror.UUCP
sources-request at mirror.UUCP
Wed Feb 4 15:03:20 AEST 1987
Submitted by: seismo!rochester!jpayne (Jonathan Payne)
Mod.sources: Volume 8, Issue 24
Archive-name: jove/Part05
#! /bin/sh
# This is a shell archive. Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
# If all goes well, you will see the message "End of archive 5 (of 13)."
# Contents: jove.c jove.h macros.c malloc.c marks.c setmaps.c
PATH=/bin:/usr/bin:/usr/ucb; export PATH
echo shar: extracting "'jove.c'" '(19628 characters)'
if test -f 'jove.c' ; then
echo shar: will not over-write existing file "'jove.c'"
else
sed 's/^X//' >jove.c <<'@//E*O*F jove.c//'
X/************************************************************************
X * This program is Copyright (C) 1986 by Jonathan Payne. JOVE is *
X * 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/* Contains the main loop initializations, and some system dependent
X type things, e.g. putting terminal in CBREAK mode, etc. */
X
X#include "jove.h"
X#include "io.h"
X#include "termcap.h"
X
X#include <varargs.h>
X#include <sys/stat.h>
X#include <signal.h>
X#include <errno.h>
X#ifndef SYSV
X#include <sgtty.h>
X#else
X#include <termio.h>
X#endif SYSV
X#include <fcntl.h>
X
X#ifdef TIOCSLTC
Xstruct ltchars ls1,
X ls2;
X#endif TIOCSLTC
X
X#ifdef TIOCGETC
Xstruct tchars tc1,
X tc2;
X#endif
X
X#ifdef BRLUNIX
Xstruct sg_brl sg1, sg2;
X#else
X#ifdef SYSV
Xstruct termio sg1, sg2;
X#else SYSV
Xstruct sgttyb sg1, sg2;
X#endif SYSV
X#endif BRLUNIX
X
X#ifdef BIFF
Xprivate struct stat tt_stat; /* for biff */
X#ifndef BSD4_2
Xprivate char *tt_name = 0; /* name of the control tty */
Xextern char *ttyname(); /* for systems w/o fchmod ... */
X#endif
Xprivate int dw_biff = NO; /* whether or not to fotz at all */
X#endif
X
Xtime_t time0; /* when jove started up */
Xint errormsg;
Xextern char *tfname;
Xchar NullStr[] = "";
X
Xfinish(code)
X{
X int CoreDump = (code != 0 && code != SIGHUP),
X DelTmps = 1; /* Usually we delete them. */
X
X#ifdef LSRHS
X if (CoreDump)
X setdump(1);
X#endif
X if (code == SIGINT) {
X char c;
X
X#ifndef MENLO_JCL
X (void) signal(code, finish);
X#endif
X f_mess("Abort (Type 'n' if you're not sure)? ");
X (void) read(0, &c, 1);
X message(NullStr);
X if ((c & 0377) != 'y') {
X redisplay();
X return;
X }
X }
X ttyset(OFF);
X UnsetTerm(NullStr);
X if (code != 0) {
X if (!Crashing) {
X Crashing++;
X lsave();
X SyncRec();
X printf("JOVE CRASH!! (code %d)\n", code);
X if (ModBufs(1)) {
X printf("Your buffers have been saved.\n");
X printf("Use \"jove_recover\" or \"jove -r\"\n");
X printf("to have a look at them.\n");
X DelTmps = 0; /* Don't delete anymore. */
X } else
X printf("You didn't lose any work.\n");
X } else
X printf("\r\nYou may have lost your work!\n");
X }
X flusho();
X if (DelTmps) {
X tmpclose();
X recclose();
X }
X if (CoreDump)
X abort();
X#ifdef PROFILING
X exit(exp_p);
X#else
X _exit(exp_p);
X#endif
X}
X
Xprivate char smbuf[20],
X *bp = smbuf;
Xprivate int nchars = 0;
X
Xprivate char peekbuf[10],
X *peekp = peekbuf;
X
X#ifdef SYSV
Xvoid
Xsetblock(fd, on) /* turn blocking on or off */
Xregister int fd, on;
X{
X static int blockf, nonblockf;
X static int first = 1;
X int flags;
X
X if (first) {
X first = 0;
X if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
X finish(SIGHUP);
X blockf = flags & ~O_NDELAY; /* make sure O_NDELAY is off */
X nonblockf = flags | O_NDELAY; /* make sure O_NDELAY is on */
X }
X if (fcntl(fd, F_SETFL, on ? blockf : nonblockf) == -1)
X finish(SIGHUP);
X return;
X}
X#endif SYSV
X
XPeekc()
X{
X int c;
X
X if (peekp == peekbuf)
X c = -1;
X else
X c = *--peekp & 0377;
X return c;
X}
X
XUngetc(c)
X{
X if (peekp == &peekbuf[(sizeof peekbuf) - 1])
X return; /* Sorry, can't oblige you ... */
X *peekp++ = c;
X}
X
Xchar *Inputp = 0;
X
X#ifdef IPROCS
X#ifdef PIPEPROCS
Xgetchar()
X{
X extern int errno;
X register int c;
X
X if (nchars <= 0) {
X do
X nchars = read(0, smbuf, sizeof smbuf);
X#ifdef SYSV
X while (nchars == 0 || (nchars < 0 && errno == EINTR));
X if (nchars < 0)
X#else
X while (nchars < 0 && errno == EINTR);
X if (nchars <= 0)
X#endif SYSV
X finish(SIGHUP);
X bp = smbuf;
X InputPending = nchars > 1;
X }
X if (((c = *bp) & 0200) && MetaKey != 0) {
X *bp = (c & 0177);
X return '\033';
X }
X nchars--;
X return (*bp++ & 0177);
X}
X#else PIPEPROCS
Xgetchar()
X{
X extern int global_fd,
X NumProcs,
X errno;
X register int tmp,
X nfds;
X int reads,
X c;
X
X if (nchars <= 0) {
X /* Get a character from the keyboard, first checking for
X any input from a process. Handle that first, and then
X deal with the terminal input. */
X if (NumProcs > 0) {
X do {
X do {
X reads = global_fd;
X nfds = select(32, &reads, (int *) 0, (int *) 0, (struct timeval *) 0);
X } while (nfds < 0 && errno == EINTR);
X
X switch (nfds) {
X case -1:
X printf("\rerror %d in select %d", errno, global_fd);
X global_fd = 1;
X break;
X default:
X if (reads & 01) {
X nchars = read(0, smbuf, sizeof(smbuf));
X reads &= ~01;
X --nfds;
X }
X
X while (nfds--) {
X tmp = ffs(reads) - 1;
X read_proc(tmp);
X reads &= ~tmp;
X }
X
X break;
X }
X } while (nchars <= 0);
X } else {
X do
X nchars = read(0, smbuf, sizeof(smbuf));
X while (nchars < 0 && errno == EINTR);
X }
X
X if (nchars <= 0)
X finish(SIGHUP);
X
X bp = smbuf;
X InputPending = (nchars > 1);
X }
X
X if (((c = *bp) & 0200) && MetaKey != 0) {
X *bp = (c & 0177);
X return '\033';
X }
X nchars--;
X return *bp++ & 0377;
X}
X#endif PIPEPROCS
X#else IPROCS
Xgetchar()
X{
X extern int errno;
X register int c;
X
X if (nchars <= 0) {
X do
X nchars = read(0, smbuf, sizeof smbuf);
X while (nchars < 0 && errno == EINTR);
X
X if (nchars <= 0)
X finish(SIGHUP);
X bp = smbuf;
X InputPending = nchars > 1;
X }
X if (((c = *bp) & 0200) && MetaKey != 0) {
X *bp = (c & 0177);
X return '\033';
X }
X nchars--;
X return *bp++ & 0377;
X}
X#endif IPROCS
X
Xint InputPending = 0;
X
X/* Returns non-zero if a character waiting */
X
Xcharp()
X{
X int some = 0;
X
X if (InJoverc != 0 || nchars > 0 || Inputp != 0)
X return 1;
X#ifdef BRLUNIX
X {
X static struct sg_brl gttyBuf;
X
X gtty(0, (char *) >tyBuf);
X if (gttyBuf.sg_xflags & INWAIT)
X some++;
X }
X#endif
X#ifdef FIONREAD
X {
X long c;
X
X if (ioctl(0, FIONREAD, (struct sgttyb *) &c) == -1)
X c = 0;
X some = (c > 0);
X }
X#endif FIONREAD
X#ifdef SYSV
X setblock(0, 0); /* turn blocking off */
X nchars = read(0, smbuf, sizeof smbuf); /* Is anything there? */
X setblock(0, 1); /* turn blocking on */
X if (nchars > 0) /* something was there */
X bp = smbuf; /* make sure bp points to it */
X some = (nchars > 0); /* just say we found something */
X#endif SYSV
X#ifdef c70
X some = !empty(0);
X#endif
X return some;
X}
X
XResetTerm()
X{
X putpad(TI, 1);
X putpad(VS, 1);
X putpad(KS, 1);
X#ifdef BIFF
X if (BiffChk != dw_biff)
X biff_init();
X /* just in case we changed our minds about whether to deal with
X biff */
X#endif
X (void) chkmail(YES); /* force it to check to we can be accurate */
X do_sgtty(); /* this is so if you change baudrate or stuff
X like that, JOVE will notice. */
X ttyset(ON);
X}
X
XUnsetTerm(mesg)
Xchar *mesg;
X{
X ttyset(OFF);
X putpad(KE, 1);
X putpad(VE, 1);
X putpad(TE, 1);
X#ifdef ID_CHAR
X INSmode(0);
X#endif
X Placur(ILI, 0);
X printf("%s", mesg);
X putpad(CE, 1);
X flusho();
X}
X
X#ifdef JOB_CONTROL
XPauseJove()
X{
X UnsetTerm(ModBufs(0) ? "[There are modified buffers]" : NullStr);
X (void) kill(0, SIGTSTP);
X ResetTerm();
X ClAndRedraw();
X}
X#endif
X
XPush()
X{
X int pid,
X (*old_int)() = signal(SIGINT, SIG_IGN),
X (*old_quit)() = signal(SIGQUIT, SIG_IGN);
X
X#ifdef IPROCS
X sighold(SIGCHLD);
X#endif
X switch (pid = fork()) {
X case -1:
X complain("[Fork failed]");
X
X case 0:
X UnsetTerm(NullStr);
X#ifdef IPROCS
X sigrelse(SIGCHLD);
X#endif
X (void) signal(SIGTERM, SIG_DFL);
X (void) signal(SIGINT, SIG_DFL);
X (void) signal(SIGQUIT, SIG_DFL);
X execl(Shell, basename(Shell), (char *)0);
X message("[Execl failed]");
X _exit(1);
X }
X dowait(pid, (int *) 0);
X#ifdef IPROCS
X sigrelse(SIGCHLD);
X#endif
X ResetTerm();
X ClAndRedraw();
X (void) signal(SIGQUIT, old_quit);
X (void) signal(SIGINT, old_int);
X}
X
Xint OKXonXoff = 0, /* ^S and ^Q initially DON'T work */
X IntChar = CTL(]);
X
Xttsize()
X{
X#ifdef TIOCGWINSZ
X struct winsize win;
X
X if (ioctl (0, TIOCGWINSZ, &win) == 0) {
X if (win.ws_col)
X CO = win.ws_col;
X if (win.ws_row)
X LI = win.ws_row;
X }
X#else TIOCGWINSZ
X#ifdef BTL_BLIT
X#include <sys/jioctl.h>
X struct jwinsize jwin;
X
X if (ioctl(0, JWINSIZE, &jwin) == 0) {
X if (jwin.bytesx)
X CO = jwin.bytesx;
X if (jwin.bytesy)
X LI = jwin.bytesy;
X }
X#endif BTL_BLIT
X#endif TIOCGWINSZ
X ILI = LI - 1;
X}
X
X#ifdef BIFF
Xbiff_init()
X{
X dw_biff = ((BiffChk) &&
X#ifndef BSD4_2
X ((tt_name != 0) || (tt_name = ttyname(0))) &&
X (stat(tt_name, &tt_stat) != -1) &&
X#else
X (fstat(0, &tt_stat) != -1) &&
X#endif
X (tt_stat.st_mode & S_IEXEC)); /* he's using biff */
X
X}
X
Xbiff(on)
X{
X if (dw_biff == NO)
X return;
X#ifndef BSD4_2
X (void) chmod(tt_name, on ? tt_stat.st_mode :
X (tt_stat.st_mode & ~S_IEXEC));
X#else
X (void) fchmod(0, on ? tt_stat.st_mode :
X (tt_stat.st_mode & ~S_IEXEC));
X#endif
X}
X
X#endif
X
Xttinit()
X{
X#ifdef BIFF
X biff_init();
X#endif
X#ifdef TIOCSLTC
X (void) ioctl(0, TIOCGLTC, (struct sgttyb *) &ls1);
X ls2 = ls1;
X ls2.t_suspc = (char) -1;
X ls2.t_dsuspc = (char) -1;
X ls2.t_flushc = (char) -1;
X ls2.t_lnextc = (char) -1;
X#endif
X
X#ifdef TIOCGETC
X /* Change interupt and quit. */
X (void) ioctl(0, TIOCGETC, (struct sgttyb *) &tc1);
X tc2 = tc1;
X tc2.t_intrc = IntChar;
X tc2.t_quitc = (char) -1;
X if (OKXonXoff) {
X tc2.t_stopc = (char) -1;
X tc2.t_startc = (char) -1;
X }
X#endif TIOCGETC
X do_sgtty();
X}
X
Xprivate int done_ttinit = 0;
X
Xdo_sgtty()
X{
X#ifdef SYSV
X (void) ioctl(0, TCGETA, (char *) &sg1);
X#else
X (void) gtty(0, &sg1);
X#endif SYSV
X sg2 = sg1;
X
X#ifdef SYSV
X TABS = !((sg1.c_oflag & TAB3) == TAB3);
X ospeed = sg1.c_cflag & CBAUD;
X
X sg2.c_iflag &= ~(INLCR|ICRNL|IGNCR);
X sg2.c_lflag &= ~(ISIG|ICANON|ECHO);
X sg2.c_oflag &= ~(OCRNL|ONLCR);
X sg2.c_cc[VMIN] = sizeof smbuf;
X sg2.c_cc[VTIME] = 1;
X#else
X TABS = !(sg1.sg_flags & XTABS);
X ospeed = sg1.sg_ospeed;
X#ifdef BRLUNIX
X sg2.sg_flags &= ~(ECHO | CRMOD);
X sg2.sg_flags |= CBREAK;
X
X /* VT100 Kludge: leave STALL on for flow control if DC3DC1 (Yuck.) */
X sg2.sg_xflags &= ~((sg2.sg_xflags&DC3DC1 ? 0 : STALL) | PAGE);
X#else
X sg2.sg_flags &= ~(ECHO | CRMOD);
X#endif BRLUNIX
X
X#ifdef EUNICE
X sg2.sg_flags |= RAW; /* Eunice needs RAW mode last I heard. */
X#else
X#ifdef PURDUE_EE
X# ifdef pdp11
X sg2.sg_flags |= RAW;
X# else
X sg2.sg_flags |= (MetaKey ? RAW : CBREAK);
X# endif
X#else
X sg2.sg_flags |= (MetaKey ? RAW : CBREAK);
X#endif PURDUE_EE
X#endif EUNICE
X#endif SYSV
X}
X
Xtty_reset()
X{
X if (!done_ttinit)
X return;
X ttyset(OFF); /* go back to original modes */
X ttinit();
X ttyset(ON);
X}
X
X/* If n is OFF reset to original modes */
X
Xttyset(n)
X{
X if (!done_ttinit && n == 0) /* Try to reset before we've set! */
X return;
X#ifdef SYSV
X (void) ioctl(0, TCSETAW, n == 0 ? (struct sgttyb *) &sg1 : (struct sgttyb *) &sg2);
X#else
X#ifdef BRLUNIX
X (void) stty(0, n == 0 ? (struct sgttyb *) &sg1 : (struct sgttyb *) &sg2);
X#else
X (void) ioctl(0, TIOCSETN, n == 0 ? (struct sgttyb *) &sg1 : (struct sgttyb *) &sg2);
X#endif BRLUNIX
X#endif SYSV
X
X#ifdef TIOCSETC
X (void) ioctl(0, TIOCSETC, n == 0 ? (struct sgttyb *) &tc1 : (struct sgttyb *) &tc2);
X#endif TIOCSETC
X#ifdef TIOCSLTC
X (void) ioctl(0, TIOCSLTC, n == 0 ? (struct sgttyb *) &ls1 : (struct sgttyb *) &ls2);
X#endif TIOCSLTC
X done_ttinit = 1;
X#ifdef BIFF
X biff(!n);
X#endif
X}
X
Xint this_cmd,
X last_cmd;
X
Xdispatch(c)
Xregister int c;
X{
X data_obj *cp;
X
X this_cmd = 0;
X cp = mainmap[c & 0177];
X
X if (cp == 0) {
X rbell();
X exp = 1;
X exp_p = errormsg = NO;
X message(NullStr);
X } else
X ExecCmd(cp);
X}
X
Xint LastKeyStruck,
X MetaKey = 0;
X
Xgetch()
X{
X register int c,
X peekc;
X#ifdef IPROCS
X extern int NumProcs;
X#endif
X extern int ModCount,
X Interactive;
X
X if (Inputp) {
X if ((c = *Inputp++) != 0)
X return LastKeyStruck = c;
X Inputp = 0;
X }
X
X if (InJoverc)
X return EOF; /* somethings wrong if Inputp runs out while
X we're reading a .joverc file. */
X
X if (ModCount >= SyncFreq) {
X ModCount = 0;
X SyncRec();
X }
X
X /* If we're not interactive and we're not executing a macro,
X AND there are no ungetc'd characters, we read from the
X terminal (i.e., getch()). And characters only get put
X in macros from inside this if. */
X if (((peekc = c = Peekc()) == -1) && (Interactive || ((c = mac_getc()) == -1))) {
X /* So messages that aren't error messages don't
X hang around forever. */
X if (!UpdMesg && !Asking) { /* Don't erase if we are asking */
X if (mesgbuf[0] && !errormsg)
X message(NullStr);
X }
X redisplay();
X#ifdef IPROCS
X# ifdef PIPEPROCS
X if (NumProcs > 0) {
X sigrelse(INPUT_SIG);
X sigrelse(SIGCHLD);
X }
X# endif
X#endif
X inIOread = 1;
X if ((c = getchar()) == EOF)
X finish(SIGHUP);
X inIOread = 0;
X
X#ifdef IPROCS
X# ifdef PIPEPROCS
X if (NumProcs > 0) {
X sighold(INPUT_SIG);
X sighold(SIGCHLD);
X }
X# endif
X#endif
X if (!Interactive && (KeyMacro.m_flags & DEFINE))
X mac_putc(c);
X }
X if (peekc == -1) /* Don't add_stroke peekc's */
X add_stroke(c);
X return LastKeyStruck = c;
X}
X
Xdorecover()
X{
X execl(Recover, "jove_recover", "-d", TmpFilePath, (char *)0);
X printf("%s: execl failed!\n", Recover);
X flusho();
X _exit(-1);
X}
X
X
XShowVersion()
X{
X extern char *version;
X
X s_mess("Jonathan's Own Version of Emacs (%s)", version);
X}
X
XUNIX_cmdline(argc, argv)
Xchar *argv[];
X{
X int lineno = 0,
X nwinds = 1;
X Buffer *b;
X
X ShowVersion();
X while (argc > 1) {
X if (argv[1][0] != '-' && argv[1][0] != '+') {
X int force = (nwinds > 0 || lineno != 0);
X
X minib_add(argv[1], force ? YES : NO);
X b = do_find(nwinds > 0 ? curwind : (Window *) 0,
X argv[1], force);
X if (force) {
X SetABuf(curbuf);
X SetBuf(b);
X SetLine(next_line(curbuf->b_first, lineno));
X if (nwinds > 1)
X NextWindow();
X if (nwinds)
X nwinds--;
X }
X lineno = 0;
X } else switch (argv[1][1]) {
X case 'd':
X ++argv;
X --argc;
X break;
X
X case 'j': /* Ignore .joverc in HOME */
X break;
X
X case 'p':
X ++argv;
X --argc;
X SetBuf(do_find(curwind, argv[1], 0));
X ParseAll();
X nwinds = 0;
X break;
X
X case 't':
X ++argv;
X --argc;
X exp_p = YES;
X find_tag(argv[1], YES);
X break;
X
X case 'w':
X if (argv[1][2] == '\0')
X nwinds++;
X else
X nwinds += -1 + chr_to_int(&argv[1][2], 10, NIL);
X (void) div_wind(curwind, nwinds - 1);
X break;
X
X case '0':
X case '1':
X case '2':
X case '3':
X case '4':
X case '5':
X case '6':
X case '7':
X case '8':
X case '9':
X lineno = chr_to_int(&argv[1][1], 10, 0) - 1;
X break;
X }
X ++argv;
X --argc;
X }
X}
X
X/* VARARGS1 */
X
Xerror(fmt, va_alist)
Xchar *fmt;
Xva_dcl
X{
X va_list ap;
X
X if (fmt) {
X va_start(ap);
X format(mesgbuf, sizeof mesgbuf, fmt, ap);
X va_end(ap);
X UpdMesg++;
X }
X rbell();
X (void) longjmp(mainjmp, ERROR);
X}
X
X/* VARARGS1 */
X
Xcomplain(fmt, va_alist)
Xchar *fmt;
Xva_dcl
X{
X va_list ap;
X
X if (fmt) {
X va_start(ap);
X format(mesgbuf, sizeof mesgbuf, fmt, ap);
X va_end(ap);
X UpdMesg++;
X }
X rbell();
X (void) longjmp(mainjmp, COMPLAIN);
X}
X
X/* VARARGS1 */
X
Xconfirm(fmt, va_alist)
Xchar *fmt;
Xva_dcl
X{
X char *yorn;
X va_list ap;
X
X va_start(ap);
X format(mesgbuf, sizeof mesgbuf, fmt, ap);
X va_end(ap);
X yorn = ask((char *) 0, mesgbuf);
X if (*yorn != 'Y' && *yorn != 'y')
X (void) longjmp(mainjmp, COMPLAIN);
X}
X
Xint RecDepth = 0;
X
XRecur()
X{
X char bname[128];
X Mark *m;
X
X sprintf(bname, "%s", curbuf->b_name);
X m = MakeMark(curline, curchar, FLOATER);
X
X RecDepth++;
X UpdModLine++;
X DoKeys(1); /* 1 means not first time */
X UpdModLine++;
X RecDepth--;
X SetBuf(do_select(curwind, bname));
X if (exp_p == NO)
X ToMark(m);
X DelMark(m);
X}
X
Xjmp_buf mainjmp;
Xint iniargc; /* main sets these for DoKeys() */
Xchar **iniargv;
X
XDoKeys(nocmdline)
X{
X int c;
X jmp_buf savejmp;
X
X push_env(savejmp);
X
X switch (setjmp(mainjmp)) {
X case 0:
X if (!nocmdline)
X UNIX_cmdline(iniargc, iniargv);
X break;
X
X case QUIT:
X if (RecDepth == 0) {
X if (ModMacs()) {
X rbell();
X if (Upper(*ask("No",
X"Some MACROS haven't been saved; leave anyway? ")) != 'Y')
X break;
X }
X if (ModBufs(0)) {
X rbell();
X if (Upper(*ask("No",
X"Some buffers haven't been saved; leave anyway? ")) != 'Y')
X break;
X }
X#ifdef IPROCS
X KillProcs();
X#endif
X }
X pop_env(savejmp);
X return;
X
X case ERROR:
X getDOT(); /* God knows what state linebuf was in */
X
X case COMPLAIN:
X gc_openfiles(); /* close any files we left open */
X errormsg++;
X fix_macros();
X Asking = 0;
X curwind->w_bufp = curbuf;
X redisplay();
X break;
X }
X
X this_cmd = last_cmd = 0;
X
X for (;;) {
X if (this_cmd != ARG_CMD) {
X exp = 1;
X exp_p = NO;
X last_cmd = this_cmd;
X init_strokes();
X }
X c = getch();
X if (c == -1)
X continue;
X dispatch(c);
X }
X}
X
Xint Crashing = 0;
X
Xchar **
Xscanvec(args, str)
Xregister char **args,
X *str;
X{
X while (*args) {
X if (strcmp(*args, str) == 0)
X return args;
X args++;
X }
X return 0;
X}
X
Xint UpdFreq = 30,
X inIOread = 0;
X
Xupdmode()
X{
X UpdModLine++;
X if (inIOread)
X redisplay();
X#ifndef JOB_CONTROL
X (void) signal(SIGALRM, updmode);
X#endif
X (void) alarm((unsigned) UpdFreq);
X}
X
X#ifdef TIOCGWINSZ
X#ifdef SIGWINCH
Xextern win_reshape();
X#endif
X#endif
X
X#ifdef TIOCGWINSZ
X#ifdef SIGWINCH
Xwin_reshape()
X{
X register int diff;
X
X (void) signal(SIGWINCH, SIG_IGN);
X
X /*
X * Save old number of lines.
X */
X diff = LI;
X
X /*
X * Get new line/col info.
X */
X ttsize();
X
X /*
X * LI has changed, and now holds the
X * new value. See how much the size
X * changed.
X */
X diff = LI - diff;
X
X /*
X * Change the size of the current window
X * only. If they shrank by more than
X * the window size, tough.
X */
X if ((curwind->w_height + diff) < 2)
X curwind->w_height = 2;
X else
X curwind->w_height += diff;
X
X make_scr();
X redisplay();
X
X (void) signal(SIGWINCH, win_reshape);
X}
X#endif
X#endif
X
Xmain(argc, argv)
Xchar *argv[];
X{
X char ttbuf[512],
X#ifndef VMUNIX
X s_iobuff[LBSIZE],
X s_genbuf[LBSIZE],
X s_linebuf[LBSIZE],
X#endif
X *cp;
X
X
X#ifndef VMUNIX
X /* The way I look at it, there ain't no way I is gonna run
X out of stack space UNLESS I have some kind of infinite
X recursive bug. So why use up some valuable memory, when
X there is plenty of space on the stack? (This only matters
X on wimpy pdp11's, of course.) */
X
X iobuff = s_iobuff;
X genbuf = s_genbuf;
X linebuf = s_linebuf;
X#endif
X
X errormsg = 0;
X
X iniargc = argc;
X iniargv = argv;
X
X if (setjmp(mainjmp)) {
X printf("\rAck! I can't deal with error \"%s\" now.\n\r", mesgbuf);
X finish(0);
X }
X
X getTERM(); /* Get terminal. */
X if (getenv("METAKEY"))
X MetaKey = 1;
X ttsize();
X InitCM();
X
X d_cache_init(); /* initialize the disk buffer cache */
X
X if (cp = getenv("SHELL"))
X strcpy(Shell, cp);
X
X make_scr();
X mac_init(); /* Initialize Macros */
X winit(); /* Initialize Window */
X#ifdef IPROCS
X pinit(); /* Pipes/process initialization */
X#endif
X SetBuf(do_select(curwind, Mainbuf));
X
X#ifdef CHDIR
X {
X char **argp;
X
X if ((argp = scanvec(argv, "-d")) && (argp[1][0] == '/'))
X setCWD(argp[1]);
X else
X getCWD(); /* After we setup curbuf in case we have to getwd() */
X }
X#endif
X HomeDir = getenv("HOME");
X if (HomeDir == 0)
X HomeDir = "/";
X HomeLen = strlen(HomeDir);
X#ifdef SYSV
X sprintf(Mailbox, "/usr/mail/%s", getenv("LOGNAME"));
X#else
X sprintf(Mailbox, "/usr/spool/mail/%s", getenv("USER"));
X#endif SYSV
X (void) joverc(Joverc);
X if (!scanvec(argv, "-j")) {
X char tmpbuf[100];
X
X sprintf(tmpbuf, "%s/.joverc", HomeDir);
X (void) joverc(tmpbuf);
X }
X if (scanvec(argv, "-r"))
X dorecover();
X
X (void) time(&time0);
X ttinit(); /* initialize terminal (after ~/.joverc) */
X settout(ttbuf); /* not until we know baudrate */
X ResetTerm();
X
X (void) signal(SIGHUP, finish);
X (void) signal(SIGINT, finish);
X (void) signal(SIGBUS, finish);
X (void) signal(SIGSEGV, finish);
X (void) signal(SIGPIPE, finish);
X (void) signal(SIGTERM, SIG_IGN);
X#ifdef TIOCGWINSZ
X#ifdef SIGWINCH
X (void) signal(SIGWINCH, win_reshape);
X#endif
X#endif
X
X /* set things up to update the modeline every UpdFreq seconds */
X (void) signal(SIGALRM, updmode);
X (void) alarm((unsigned) UpdFreq);
X
X cl_scr(1);
X flusho();
X RedrawDisplay(); /* start the redisplay process. */
X DoKeys(0);
X finish(0);
X}
@//E*O*F jove.c//
if test 19628 -ne "`wc -c <'jove.c'`"; then
echo shar: error transmitting "'jove.c'" '(should have been 19628 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'jove.h'" '(14747 characters)'
if test -f 'jove.h' ; then
echo shar: will not over-write existing file "'jove.h'"
else
sed 's/^X//' >jove.h <<'@//E*O*F jove.h//'
X/************************************************************************
X * This program is Copyright (C) 1986 by Jonathan Payne. JOVE is *
X * 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/* jove.h header file to be included by EVERYONE */
X
X#include <setjmp.h>
X#include <sys/types.h>
X
X#ifndef TUNED
X# include "tune.h"
X#endif
X
X#define private static
X
X#ifndef BSD4_2
X# ifdef MENLO_JCL
X# ifndef EUNICE
X# define signal sigset
X# endif
X# endif MENLO_JCL
X#endif
X
X#define EOF -1
X#define NULL 0
X#define NIL 0
X
X/* kinds of regular expression compiles */
X#define NORM 0 /* nothing special */
X#define OKAY_RE 1 /* allow regular expressions */
X#define IN_CB 2 /* in curly brace; implies OKAY_RE */
X
X/* return codes for command completion (all < 0 because >= 0 are
X legitimate offsets into array of strings */
X
X#define AMBIGUOUS -2 /* matches more than one at this point */
X#define UNIQUE -3 /* matches only one string */
X#define ORIGINAL -4 /* matches no strings at all! */
X#define NULLSTRING -5 /* just hit return without typing anything */
X
X/* values for the `flags' argument to complete */
X#define NOTHING 0 /* opposite of RET_STATE */
X#define RET_STATE 1 /* return state when we hit return */
X#define RCOMMAND 2 /* we are reading a joverc file */
X#define CASEIND 4 /* map all to lower case */
X
X#define DEFINE 01 /* defining this macro */
X#define EXECUTE 02 /* executing this macro */
X#define SAVE 04 /* this macro needs saving to a file */
X
X#define LBSIZE BUFSIZ /* same as a logical disk block */
X#define FILESIZE 256
X
X#define FORWARD 1
X#define BACKWARD -1
X
X#define CTL(c) ('c' & 037)
X#define META(c) ('c' | 0200)
X#define RUBOUT '\177'
X#define LF CTL(J)
X#define CR CTL(M)
X#define BS CTL(H)
X#define ESC '\033'
X
X#define DoTimes(f, n) exp_p = YES, exp = n, f
X#define HALF(wp) ((wp->w_height - 1) / 2)
X#define IsModified(b) (b->b_modified)
X#define SIZE(wp) (wp->w_height - 1)
X#define SavLine(a, b) (a->l_dline = putline(b))
X#define SetLine(line) DotTo(line, 0)
X#define bobp() (firstp(curline) && bolp())
X#define bolp() (curchar == 0)
X#define eobp() (lastp(curline) && eolp())
X#define eolp() (linebuf[curchar] == '\0')
X#define firstp(line) (line == curbuf->b_first)
X#define getDOT() getline(curline->l_dline, linebuf)
X#define isdirty(line) (line->l_dline & DIRTY)
X#define lastp(line) (line == curbuf->b_last)
X#define makedirty(line) line->l_dline |= DIRTY
X#define one_windp() (fwind->w_next == fwind)
X
Xextern int OkayAbort, /* okay to abort redisplay */
X BufSize;
X
X#define ARG_CMD 1
X#define LINECMD 2
X#define KILLCMD 3 /* so we can merge kills */
X#define YANKCMD 4 /* so we can do ESC Y (yank-pop) */
X
X/* Buffer type */
X
X#define B_SCRATCH 1 /* for internal things, e.g. minibuffer ... */
X#define B_FILE 2 /* normal file (We Auto-save these.) */
X#define B_PROCESS 3 /* process output in this buffer */
X
X/* Major modes */
X#define FUNDAMENTAL 0 /* Fundamental mode */
X#define TEXT 1 /* Text mode */
X#define CMODE 2 /* C mode */
X#ifdef LISP
X# define LISPMODE 3 /* Lisp mode */
X# define NMAJORS 4
X#else
X# define NMAJORS 3
X#endif
X
X/* Minor Modes */
X#define Indent (1 << 0) /* indent same as previous line after return */
X#define ShowMatch (1 << 1) /* paren flash mode */
X#define Fill (1 << 2) /* text fill mode */
X#define OverWrite (1 << 3) /* over write mode */
X#define Abbrev (1 << 4) /* abbrev mode */
X
X#define BufMinorMode(b, x) (b->b_minor & x)
X
X#define MinorMode(x) BufMinorMode(curbuf, x)
X#define MajorMode(x) (curbuf->b_major == x)
X#define SetMajor(x) ((curbuf->b_major = x), UpdModLine++)
X
Xextern char CharTable[NMAJORS][128];
X
X/* setjmp/longjmp args for DoKeys() mainjmp */
X#define FIRSTCALL 0
X#define ERROR 1
X#define COMPLAIN 2 /* do the error without a getDOT */
X#define QUIT 3 /* leave this level of recursion */
X
X#define QUIET 1 /* sure, why not? */
X
X#define YES 1
X#define NO 0
X#define TRUE 1
X#define FALSE 0
X#define ON 1
X#define OFF 0
X#define YES_NODIGIT 2
X
Xextern char *Mainbuf,
X *HomeDir, /* home directory */
X key_strokes[], /* strokes that make up current command */
X *Inputp;
X
Xextern int HomeLen; /* length of home directory */
X
Xextern char NullStr[];
X
X#ifdef VMUNIX
Xextern char genbuf[LBSIZE],
X linebuf[LBSIZE],
X iobuff[LBSIZE];
X#else
Xextern char *genbuf, /* scratch pad points at s_genbuf (see main()) */
X *linebuf, /* points at s_linebuf */
X *iobuff; /* for file reading ... points at s_iobuff */
X#endif
X
Xextern int InJoverc,
X Interactive;
X
X#define READ 0
X#define WRITE 1
Xextern int errno;
X
Xextern jmp_buf mainjmp;
X
X#ifdef IPROCS
Xtypedef struct process Process;
X#endif
Xtypedef struct window Window;
Xtypedef struct position Bufpos;
Xtypedef struct mark Mark;
Xtypedef struct buffer Buffer;
Xtypedef struct line Line;
Xtypedef struct iobuf IOBUF;
Xtypedef struct data_obj {
X int Type;
X char *Name;
X} data_obj; /* points to cmd, macro, or variable */
Xtypedef data_obj *keymap[0200];
X
Xstruct line {
X Line *l_prev, /* pointer to prev */
X *l_next; /* pointer to next */
X disk_line l_dline; /* pointer to disk location */
X};
X
X#ifdef IPROCS
Xstruct process {
X Process *p_next;
X#ifdef PIPEPROCS
X int p_toproc, /* read p_fromproc and write p_toproc */
X p_portpid, /* Pid of child (the portsrv) */
X p_pid; /* Pid of real child i.e. not portsrv */
X#else
X int p_fd, /* File descriptor of ptyp? opened r/w */
X p_pid; /* pid of child (the shell) */
X#endif
X Buffer *p_buffer; /* Add output to end of this buffer */
X char *p_name; /* ... */
X char p_state, /* State */
X p_howdied, /* Killed? or Exited? */
X p_reason, /* If signaled, p_reason is the signal; else
X it is the the exit code */
X p_eof; /* Received EOF, so can be free'd up */
X Mark *p_mark; /* Where output left us. */
X data_obj
X *p_cmd; /* Command to call when process dies */
X};
X#endif IPROCS
X
Xstruct window {
X Window *w_prev, /* circular list */
X *w_next;
X Buffer *w_bufp; /* buffer associated with this window */
X Line *w_top, /* top line */
X *w_line; /* current line */
X int w_char,
X w_height, /* window height */
X w_topnum, /* line number of the topline */
X w_dotcol, /* UpdWindow sets this ... */
X w_dotline, /* ... and this */
X w_flags;
X#define W_TOPGONE 01
X#define W_CURGONE 02 /* topline (curline) of window has been deleted
X since the last time a redisplay was called */
X#define W_VISSPACE 04
X#define W_NUMLINES 010
X};
X
Xextern Window *fwind, /* first window in list */
X *curwind; /* current window */
X
Xstruct position {
X Line *p_line;
X int p_char;
X};
X
Xstruct mark {
X Line *m_line;
X int m_char;
X Mark *m_next; /* list of marks */
X#define FLOATER 1
X char m_floater; /* FLOATERing mark? */
X};
X
Xstruct buffer {
X Buffer *b_next; /* next buffer in chain */
X char *b_name, /* buffer name */
X *b_fname; /* file name associated with buffer */
X ino_t b_ino; /* inode of file name */
X time_t b_mtime; /* last modify time ...
X to detect two people writing
X to the same file */
X Line *b_first, /* pointer to first line in list */
X *b_dot, /* current line */
X *b_last; /* last line in list */
X int b_char; /* current character in line */
X
X#define NMARKS 8 /* number of marks in the ring */
X
X Mark *b_markring[NMARKS], /* new marks are pushed saved here */
X *b_marks; /* all the marks for this buffer */
X char b_themark, /* current mark (in b_markring) */
X b_type, /* file, scratch, process, iprocess */
X b_ntbf, /* needs to be found when we
X first select? */
X b_modified; /* is the buffer modified? */
X int b_major, /* major mode */
X b_minor; /* and minor mode */
X keymap *b_keybinds; /* local bindings (if any) */
X#ifdef IPROCS
X Process *b_process; /* process we're attached to */
X#endif
X};
X
Xstruct macro {
X int Type; /* in this case a macro */
X char *Name; /* name is always second ... */
X int m_len, /* length of macro so we can use ^@ */
X m_buflen, /* memory allocated for it */
X m_offset, /* index into body for defining and running */
X m_flags, /* defining/running this macro? */
X m_ntimes; /* number of times to run this macro */
X char *m_body; /* actual body of the macro */
X struct macro
X *m_nextm;
X};
X
Xstruct variable {
X int Type; /* in this case a variable */
X char *Name; /* name is always second */
X int *v_value,
X v_flags;
X};
X
Xstruct cmd {
X int Type;
X char *Name;
X int (*c_proc)();
X};
X
Xextern keymap mainmap, /* various key maps */
X pref1map,
X pref2map,
X miscmap;
X
Xextern data_obj *LastCmd; /* last command invoked */
X
Xextern char *ProcFmt;
X
Xextern struct cmd commands[];
Xextern struct macro *macros;
Xextern struct variable variables[];
X
Xextern struct macro
X *macstack[],
X KeyMacro;
X
X#define FUNCTION 1
X#define VARIABLE 2
X#define MACRO 3
X#define TYPEMASK 07
X#define MAJOR_MODE 010
X#define MINOR_MODE 020
X#define DefMajor(x) (FUNCTION|MAJOR_MODE|(x << 8))
X#define DefMinor(x) (FUNCTION|MINOR_MODE|(x << 8))
X
Xextern Buffer *world, /* first buffer */
X *curbuf; /* pointer into world for current buffer */
X
X#define curline curbuf->b_dot
X#define curchar curbuf->b_char
X
X#define NUMKILLS 10 /* number of kills saved in the kill ring */
X
X#define DIRTY 01 /* just needs updating for some reason */
X#define MODELINE 02 /* this is a modeline */
X#define L_MOD 04 /* this line has been modified internally */
X
Xstruct scrimage {
X int s_offset, /* offset to start printing at */
X s_flags, /* various flags */
X s_id, /* which buffer line */
X s_vln; /* Visible Line Number */
X Line *s_lp; /* so we can turn off red bit */
X Window *s_window; /* window that contains this line */
X};
X
Xextern struct scrimage
X *DesiredScreen, /* what we want */
X *PhysScreen; /* what we got */
X
X/* Variable flags (that can be set). */
X#define V_BASE10 01 /* is integer in base 10 */
X#define V_BASE8 02 /* is integer in base 8 */
X#define V_BOOL 04 /* is a boolean */
X#define V_STRING 010 /* is a string */
X#define V_CHAR 020 /* is a character */
X#define V_FILENAME 040 /* a file name (implies V_STRING) */
X#define V_TYPEMASK 077 /* mask off the extra bits */
X#define V_MODELINE 0100 /* update modeline */
X#define V_CLRSCREEN 0200 /* clear and redraw screen */
X#define V_TTY_RESET 0400 /* redo the tty modes */
X
Xextern int
X OKXonXoff, /* disable start/stop characters */
X MetaKey, /* this terminal has a meta key */
X VisBell, /* use visible bell (if possible) */
X WrapScan, /* make searches wrap */
X phystab, /* terminal's tabstop settings */
X tabstop, /* expand tabs to this number of spaces */
X#ifdef BACKUPFILES
X BkupOnWrite, /* make backup files when writing */
X#endif
X RMargin, /* right margin */
X LMargin, /* left margin */
X ScrollStep, /* how should we scroll */
X WtOnMk, /* write files on compile-it command */
X EndWNewline, /* end files with a blank line */
X MarkThresh, /* moves greater than MarkThresh
X will SetMark */
X PDelay, /* paren flash delay in tenths of a second */
X CIndIncrmt, /* how much each indentation level pushes
X over in C mode */
X CreatMode, /* default mode for creat'ing files */
X CaseIgnore, /* case ignore search */
X#ifdef ABBREV
X AutoCaseAbbrev, /* automatically do case on abbreviations */
X#endif
X MarksShouldFloat, /* adjust marks on insertion/deletion */
X UseRE, /* use regular expressions in search */
X SyncFreq, /* how often to sync the file pointers */
X BriteMode, /* make the mode line inverse? */
X OkayBadChars, /* allow bad characters in files created
X by JOVE */
X UpdFreq, /* how often to update modeline */
X UseBuffers, /* use buffers with Typeout() */
X#ifdef BIFF
X BiffChk, /* turn off/on biff with entering/exiting jove */
X#endif
X MailInt, /* mail check interval */
X#ifdef ID_CHAR
X UseIC, /* whether or not to use i/d char
X processesing */
X SExitChar, /* type this to stop i-search */
X#endif
X IntChar, /* ttysets this to generate QUIT */
X EWSize; /* size to make the error window */
X
Xextern char
X#ifdef IPROCS
X proc_prompt[80], /* process prompt */
X#endif
X#ifdef F_COMPLETION
X BadExtensions[128], /* extensions (e.g., ".o" to ignore) */
X#endif
X#ifdef CMT_FMT
X CmtFmt[80],
X#endif
X ModeFmt[120], /* mode line format string */
X Mailbox[128], /* mailbox name */
X TmpFilePath[128], /* directory/device to store tmp files */
X TagFile[128], /* default tag file */
X Shell[128]; /* shell to use */
X
Xextern int
X exp, /* argument count */
X exp_p, /* argument count is supplied */
X
X TOabort, /* flag set by Typeout() */
X io, /* file descriptor for reading and writing files */
X errormsg, /* last message was an error message
X so don't erase the error before it
X has been read */
X this_cmd, /* ... */
X last_cmd, /* last command ... to implement appending
X to kill buffer */
X RecDepth, /* recursion depth */
X InputPending, /* nonzero if there is input waiting to
X be processed */
X killptr, /* index into killbuf */
X CanScroll, /* can this terminal scroll? */
X Crashing, /* we are in the middle of crashing */
X Asking, /* are we on read a string from the terminal? */
X inIOread; /* so we know whether we can do a redisplay. */
X
Xextern char Minibuf[LBSIZE];
X
X#define curmark (curbuf->b_markring[curbuf->b_themark])
X#define b_curmark(b) (b->b_markring[b->b_themark])
X
Xextern Line *killbuf[NUMKILLS]; /* array of pointers to killed stuff */
X
X#define MESG_SIZE 128
Xextern char mesgbuf[MESG_SIZE];
X
Xstruct screenline {
X char *s_line,
X *s_length;
X};
X
Xextern int
X LastKeyStruck;
X
Xextern int
X stackp,
X
X CapLine, /* cursor line and cursor column */
X CapCol,
X
X UpdModLine, /* whether we want to update the mode line */
X UpdMesg; /* update the message line */
X
X#define CATCH \
X{\
X jmp_buf sav_jmp; \
X\
X push_env(sav_jmp); \
X if (setjmp(mainjmp) == 0) {
X
X#define ONERROR \
X } else { \
X
X#define ENDCATCH \
X } \
X pop_env(sav_jmp); \
X}
X
Xextern int
X read(),
X write();
X getch();
X
Xextern time_t time();
Xextern long lseek();
X
Xextern disk_line
X putline();
X
Xextern data_obj
X *findcom(),
X *findvar(),
X *findmac();
X
Xextern Line
X *next_line(),
X *prev_line(),
X *nbufline(),
X *reg_delete(),
X *lastline(),
X *listput();
X
Xextern char
X *getsearch(),
X *pwd(),
X *itoa(),
X *get_time(),
X *copystr(),
X *basename(),
X *filename(),
X *IOerr(),
X *index(),
X *ask(),
X *do_ask(),
X *ask_buf(),
X *ask_file(),
X *lcontents(),
X *malloc(),
X *emalloc(),
X *mktemp(),
X *realloc(),
X *ltobuf(),
X *lbptr(),
X *rindex(),
X *getenv(),
X *tgoto(),
X *pr_name(),
X *sprint(),
X *StrIndex();
X
Xextern Bufpos
X *docompiled(),
X *dosearch(),
X *DoYank(),
X *c_indent(),
X#ifdef LISP
X *lisp_indent(),
X#endif
X *m_paren();
X
Xextern Mark
X *CurMark(),
X *MakeMark();
X
Xextern Window
X *windbp(),
X *div_wind();
X
Xextern data_obj
X **IsPrefix();
X
Xextern Buffer
X *do_find(),
X *do_select(),
X *mak_buf(),
X *buf_exists(),
X *file_exists();
X
Xstruct cmd *
X FindCmd();
@//E*O*F jove.h//
if test 14747 -ne "`wc -c <'jove.h'`"; then
echo shar: error transmitting "'jove.h'" '(should have been 14747 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'macros.c'" '(9026 characters)'
if test -f 'macros.c' ; then
echo shar: will not over-write existing file "'macros.c'"
else
sed 's/^X//' >macros.c <<'@//E*O*F macros.c//'
X/************************************************************************
X * This program is Copyright (C) 1986 by Jonathan Payne. JOVE is *
X * 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
Xstruct macro *macros = 0; /* Macros */
Xdata_obj *LastCmd;
X
Xprivate
Xadd_mac(new)
Xstruct macro *new;
X{
X register struct macro *mp,
X *prev = 0;
X
X for (mp = macros; mp != 0; prev = mp, mp = mp->m_nextm)
X if (mp == new)
X return;
X
X if (prev)
X prev->m_nextm = new;
X else
X macros = new;
X new->m_nextm = 0;
X new->Type = MACRO;
X}
X
Xprivate
Xdel_mac(mac)
Xstruct macro *mac;
X{
X register struct macro *m;
X
X for (m = macros; m != 0; m = m->m_nextm)
X if (m->m_nextm == mac) {
X m->m_nextm = mac->m_nextm;
X break;
X }
X free(mac->Name);
X free(mac->m_body);
X free((char *) mac);
X}
X
Xstruct macro KeyMacro; /* Macro used for defining */
X
X#define NMACROS 40 /* This is bad, bad, BAD! */
X
Xstruct macro *macstack[NMACROS];
Xprivate int stackp = 0;
X
Xfix_macros()
X{
X register int i;
X register struct macro *mp;
X
X for (i = 0; macstack[i]; i++) {
X mp = macstack[i];
X macstack[i] = 0;
X mp->m_flags = mp->m_offset = 0;
X }
X stackp = -1;
X KeyMacro.m_flags = KeyMacro.m_offset = 0;
X}
X
Xprivate
Xmac_err(err)
Xchar *err;
X{
X KeyMacro.m_flags = 0;
X MacNolen(&KeyMacro);
X complain(err);
X}
X
Xdo_macro(mac)
Xstruct macro *mac;
X{
X if (mac->m_flags & EXECUTE)
X mac_err("[Attempt to execute macro recursively!]");
X if (++stackp >= NMACROS)
X complain("[Too many macros at once!]");
X macstack[stackp] = mac;
X mac->m_offset = 0;
X mac->m_ntimes = exp;
X mac->m_flags |= EXECUTE;
X}
X
Xprivate
XMacNolen(m)
Xstruct macro *m;
X{
X m->m_len = m->m_offset = 0;
X}
X
Xprivate struct macro *
Xmac_exists(name)
Xchar *name;
X{
X register struct macro *mp;
X
X for (mp = macros; mp; mp = mp->m_nextm)
X if (strcmp(mp->Name, name) == 0)
X return mp;
X return 0;
X}
X
Xmac_init()
X{
X add_mac(&KeyMacro);
X MacNolen(&KeyMacro);
X KeyMacro.Name = "keyboard-macro";
X KeyMacro.m_buflen = 16;
X KeyMacro.m_body = emalloc(KeyMacro.m_buflen);
X KeyMacro.m_ntimes = KeyMacro.m_flags = 0;
X fix_macros();
X}
X
Xmac_putc(c)
Xint c;
X{
X if (KeyMacro.m_len >= KeyMacro.m_buflen) {
X KeyMacro.m_buflen += 16;
X KeyMacro.m_body = realloc(KeyMacro.m_body, (unsigned) KeyMacro.m_buflen);
X if (KeyMacro.m_body == 0)
X mac_err("[Can't allocate storage for keyboard macro]");
X }
X KeyMacro.m_body[KeyMacro.m_offset++] = c;
X KeyMacro.m_len++;
X}
X
Xin_macro()
X{
X return ((stackp >= 0) && ((macstack[stackp])->m_flags & EXECUTE));
X}
X
Xmac_getc()
X{
X struct macro *m;
X
X if (stackp < 0 || ((m = macstack[stackp])->m_flags & EXECUTE) == 0)
X return -1;
X if (m->m_offset == m->m_len) {
X m->m_offset = 0;
X if (--m->m_ntimes == 0) {
X m->m_flags &= ~EXECUTE;
X stackp--;
X }
X return mac_getc();
X }
X return m->m_body[m->m_offset++];
X}
X
XNameMac()
X{
X char *name;
X struct macro *m;
X
X if (KeyMacro.m_len == 0)
X complain("[No keyboard macro to name!]");
X if (KeyMacro.m_flags & (DEFINE | EXECUTE))
X complain("[Can't name while defining/executing]");
X if ((m = mac_exists(name = ask((char *) 0, ProcFmt))) == 0)
X m = (struct macro *) emalloc(sizeof *m);
X else {
X if (strcmp(name, KeyMacro.Name) == 0)
X complain("[Can't name it that!]");
X free(m->Name);
X free(m->m_body);
X }
X name = copystr(name);
X m->Type = KeyMacro.Type;
X m->m_len = KeyMacro.m_len;
X m->m_buflen = KeyMacro.m_buflen;
X m->m_body = emalloc(m->m_buflen);
X byte_copy(KeyMacro.m_body, m->m_body, m->m_len);
X m->m_ntimes = m->m_offset = 0; /* At the beginning */
X m->m_flags = SAVE;
X m->Name = name;
X add_mac(m);
X}
X
XRunMacro()
X{
X struct macro *m;
X
X if (m = (struct macro *) findmac(ProcFmt))
X do_macro(m);
X}
X
Xprivate int mac_fd;
X
Xprivate
Xmac_io(fcn, ptr, nbytes)
Xint (*fcn)();
Xchar *ptr;
X{
X int nio;
X
X if ((nio = (*fcn)(mac_fd, ptr, nbytes)) != nbytes)
X complain("[Macro %s error: %d got %d]",
X (fcn == read) ? "read" : "write",
X nbytes,
X nio);
X}
X
XWriteMacs()
X{
X struct macro *m;
X int namelen,
X netl,
X nmacs = 0;
X char *file,
X filebuf[FILESIZE];
X long htonl() ;
X
X file = ask_file((char *) 0, (char *) 0, filebuf);
X if ((mac_fd = creat(file, 0666)) == -1)
X complain(IOerr("create", file));
X f_mess("\"%s\"", file);
X
X /* Don't write the keyboard macro which is always the first */
X for (m = macros->m_nextm; m != 0; m = m->m_nextm) {
X if (m->m_len == 0)
X continue;
X nmacs++;
X netl = htonl(m->m_len);
X mac_io(write, (char *) &netl, sizeof m->m_len);
X namelen = strlen(m->Name) + 1; /* Including the null */
X netl = htonl(namelen);
X mac_io(write, (char *) &netl, sizeof namelen);
X mac_io(write, m->Name, namelen);
X mac_io(write, m->m_body, m->m_len);
X m->m_flags &= ~SAVE;
X }
X (void) close(mac_fd);
X add_mess(" %d macro%n saved.", nmacs, nmacs);
X}
X
X#define NEWWAY 1
X#define OLDWAY 0
X
Xprivate int int_how = NEWWAY;
X
X/* Formatting int's the old way or the new "improved" way? */
X
X#if vax || pdp11
Xlong htonl(x)
Xregister long x;
X{
X return( (((x >> 0) & 0377) << 24) |
X (((x >> 8) & 0377) << 16) |
X (((x >> 16) & 0377) << 8) |
X (((x >> 24) & 0377) << 0) );
X}
X
Xshort htons(x)
Xregister short x;
X{
X return( (((x >> 0) & 0377) << 8) |
X (((x >> 8) & 0377) << 0) );
X}
X
Xlong ntohl(x)
Xregister long x;
X{
X return( (((x >> 0) & 0377) << 24) |
X (((x >> 8) & 0377) << 16) |
X (((x >> 16) & 0377) << 8) |
X (((x >> 24) & 0377) << 0) );
X}
X
Xshort ntohs(x)
Xregister short x;
X{
X return( (((x >> 0) & 0377) << 8) |
X (((x >> 8) & 0377) << 0) );
X}
X#else
Xlong htonl(x)
Xregister long x;
X{
X return(x);
X}
X
Xshort htons(x)
Xregister short x;
X{
X return(x);
X}
X
Xlong ntohl(x)
Xregister long x;
X{
X return(x);
X}
X
Xshort ntohs(x)
Xregister short x;
X{
X return(x);
X}
X#endif
X
Xint_fmt(i)
X{
X if (int_how == NEWWAY)
X return ntohl(i);
X return i;
X}
X
XReadMacs()
X{
X char *file,
X filebuf[FILESIZE];
X struct macro *m;
X int nmacs = 0,
X namelen,
X bodylen,
X tmp,
X he_is_sure = 0,
X save_em = FALSE;
X
X file = ask_file((char *) 0, (char *) 0, filebuf);
X if ((mac_fd = open(file, 0)) == -1)
X complain(IOerr("open", file));
X
X f_mess("\"%s\"", file);
X while (read(mac_fd, (char *) &tmp, sizeof tmp) == (sizeof tmp)) {
Xretry: bodylen = int_fmt(tmp);
X if (!he_is_sure && (bodylen <= 0 || bodylen > 10000)) {
X if (int_how == NEWWAY) {
X int_how = OLDWAY;
X save_em = TRUE;
X goto retry;
X } else {
X confirm("Are you sure \"%s\" is a JOVE macro file? ", filebuf);
X he_is_sure = 1;
X }
X }
X nmacs++;
X m = (struct macro *) emalloc (sizeof *m);
X m->m_flags = 0;
X m->m_len = bodylen;
X m->m_buflen = m->m_len;
X mac_io(read, (char *) &namelen, sizeof namelen);
X namelen = int_fmt(namelen);
X m->Name = emalloc(namelen);
X mac_io(read, m->Name, namelen);
X m->m_body = emalloc(m->m_buflen);
X mac_io(read, m->m_body, m->m_len);
X add_mac(m);
X }
X (void) close(mac_fd);
X add_mess(" %d macro%n defined.", nmacs, nmacs);
X if (save_em) {
X char *msg = "OK to convert to the new format? ",
X ibuf[FILESIZE + 1];
X
X if (!InJoverc) {
X TOstart("Warning", TRUE);
X Typeout("Warning: your macros file is in the old format.");
X Typeout("Do you want me to convert \"%s\" to the new", pr_name(file));
X Typeout("format?");
X f_mess(msg);
X TOstop();
X confirm(msg);
X }
X /* WriteMacs requests a file name. This is what it'll get. */
X sprintf(ibuf, "%s\n", file);
X Inputp = ibuf;
X WriteMacs();
X }
X}
X
XRemember()
X{
X if (KeyMacro.m_flags & EXECUTE)
X /* We're already executing the macro; ignore any attempts
X to define the keyboard macro while we are executing. */
X return;
X if (KeyMacro.m_flags & DEFINE)
X message("[Already remembering ... continue with definition]");
X else {
X UpdModLine++;
X KeyMacro.m_flags |= DEFINE;
X MacNolen(&KeyMacro);
X message("Remembering...");
X }
X}
X
X/* Is `c' a prefix character */
X
Xprivate
XPrefChar(c)
X{
X return (int) IsPrefix(mainmap[c]);
X}
X
XForget()
X{
X char *cp;
X struct macro *m = &KeyMacro;
X
X UpdModLine++;
X if (m->m_flags & DEFINE) {
X message("Keyboard macro defined.");
X m->m_flags &= ~DEFINE;
X cp = &m->m_body[m->m_len - 2];
X if (PrefChar(*cp))
X m->m_len -= 2;
X else if (commands[*++cp].c_proc == Forget)
X m->m_len--;
X }
X}
X
XExecMacro()
X{
X do_macro(&KeyMacro);
X}
X
XMacInter()
X{
X extern int Interactive;
X
X if (!Asking)
X return;
X Interactive = 1;
X}
X
XModMacs()
X{
X register struct macro *m;
X
X for (m = macros->m_nextm; m != 0; m = m->m_nextm)
X if (m->m_flags & SAVE)
X return 1;
X return 0;
X}
X
Xdata_obj *
Xfindmac(prompt)
Xchar *prompt;
X{
X char *strings[100];
X register char **strs = strings;
X register int com;
X register struct macro *m = macros;
X
X for (; m != 0; m = m->m_nextm)
X *strs++ = m->Name;
X *strs = 0;
X
X if ((com = complete(strings, prompt, NOTHING)) < 0)
X return 0;
X m = macros;
X while (--com >= 0)
X m = m->m_nextm;
X return (data_obj *) m;
X}
X
XDelMacro()
X{
X struct macro *m;
X
X if ((m = (struct macro *) findmac(ProcFmt)) == 0)
X return;
X if (m == &KeyMacro)
X complain("[It's illegal to delete the keyboard-macro!]");
X del_mac(m);
X}
@//E*O*F macros.c//
if test 9026 -ne "`wc -c <'macros.c'`"; then
echo shar: error transmitting "'macros.c'" '(should have been 9026 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'malloc.c'" '(4003 characters)'
if test -f 'malloc.c' ; then
echo shar: will not over-write existing file "'malloc.c'"
else
sed 's/^X//' >malloc.c <<'@//E*O*F malloc.c//'
X/************************************************************************
X * This program is Copyright (C) 1986 by Jonathan Payne. JOVE is *
X * 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 "tune.h"
X
X#ifdef MY_MALLOC
X
X/* avoid break bug */
X#ifdef pdp11
X# define GRANULE 64
X#else
X# define GRANULE 0
X#endif
X
X/* C storage allocator
X * circular first-fit strategy
X * works with noncontiguous, but monotonically linked, arena
X * each block is preceded by a ptr to the (pointer of)
X * the next following block
X * blocks are exact number of words long
X * aligned to the data type requirements of ALIGN
X * pointers to blocks must have BUSY bit 0
X * bit in ptr is 1 for busy, 0 for idle
X * gaps in arena are merely noted as busy blocks
X * last block of arena (pointed to by alloct) is empty and
X * has a pointer to first
X * idle blocks are coalesced during space search
X *
X * a different implementation may need to redefine
X * ALIGN, NALIGN, BLOCK, BUSY, INT
X * where INT is integer type to which a pointer can be cast
X */
X
X#define INT int
X#define ALIGN int
X#define NALIGN 1
X#define WORD sizeof(union store)
X#define BLOCK 1024 /* a multiple of WORD*/
X#define BUSY 1
X#define NULL 0
X#define testbusy(p) ((INT)(p)&BUSY)
X#define setbusy(p) (union store *) ((INT) (p) | BUSY)
X#define clearbusy(p) (union store *) ((INT) (p) &~ BUSY)
X
Xunion store {
X union store *ptr;
X ALIGN dummy[NALIGN];
X int calloc; /*calloc clears an array of integers*/
X};
X
Xstatic union store allocs[2], /*initial arena*/
X *allocp, /*search ptr*/
X *alloct, /*arena top*/
X *allocx; /*for benefit of realloc*/
X
Xchar *sbrk();
X
Xchar *
Xmalloc(nbytes)
Xunsigned int nbytes;
X{
X register union store *p,
X *q;
X register int nw;
X static int temp; /* coroutines assume no auto */
X
X if (allocs[0].ptr == 0) { /* first time */
X allocs[0].ptr = setbusy(&allocs[1]);
X allocs[1].ptr = setbusy(&allocs[0]);
X alloct = &allocs[1];
X allocp = &allocs[0];
X }
X nw = (nbytes + WORD + WORD - 1) / WORD;
X for (p = allocp; ; ) {
X for (temp = 0; ; ) {
X if (!testbusy(p->ptr)) {
X while (!testbusy((q = p->ptr)->ptr))
X p->ptr = q->ptr;
X if(q >= p + nw && p + nw >= p)
X goto found;
X }
X q = p;
X p = clearbusy(p->ptr);
X if (p > q)
X ;
X else if (q != alloct || p != allocs)
X return NULL;
X else if (++temp > 1)
X break;
X }
X temp = ((nw + BLOCK/WORD) / (BLOCK/WORD)) * (BLOCK/WORD);
X q = (union store *) sbrk(0);
X if (q + temp + GRANULE < q)
X return NULL;
X q = (union store *) sbrk(temp * WORD);
X if ((INT) q == -1)
X return NULL;
X alloct->ptr = q;
X if (q != alloct+1)
X alloct->ptr = setbusy(alloct->ptr);
X alloct = q->ptr = q + temp - 1;
X alloct->ptr = setbusy(allocs);
X }
Xfound:
X allocp = p + nw;
X if (q > allocp) {
X allocx = allocp->ptr;
X allocp->ptr = p->ptr;
X }
X p->ptr = setbusy(allocp);
X return (char *) (p + 1);
X}
X
X/* freeing strategy tuned for LIFO allocation */
X
Xfree(ap)
Xregister char *ap;
X{
X register union store *p = (union store *) ap;
X
X allocp = --p;
X p->ptr = clearbusy(p->ptr);
X}
X
X/* realloc(p, nbytes) reallocates a block obtained from malloc()
X * and freed since last call of malloc()
X * to have new size nbytes, and old content
X * returns new location, or 0 on failure
X*/
X
Xchar *
Xrealloc(obj, nbytes)
Xchar *obj;
Xunsigned int nbytes;
X{
X register union store *q,
X *p = (union store *) obj;
X union store *s,
X *t;
X register unsigned int nw;
X unsigned int onw;
X
X if (testbusy(p[-1].ptr))
X free((char *) p);
X onw = p[-1].ptr - p;
X q = (union store *) malloc(nbytes);
X if(q == NULL || q == p)
X return((char *) q);
X s = p;
X t = q;
X nw = (nbytes + WORD - 1)/WORD;
X if (nw < onw)
X onw = nw;
X while (onw-- != 0)
X *t++ = *s++;
X if(q < p && q + nw >= p)
X (q + (q+nw-p))->ptr = allocx;
X return (char *) q;
X}
X
X#endif MY_MALLOC
@//E*O*F malloc.c//
if test 4003 -ne "`wc -c <'malloc.c'`"; then
echo shar: error transmitting "'malloc.c'" '(should have been 4003 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'marks.c'" '(4197 characters)'
if test -f 'marks.c' ; then
echo shar: will not over-write existing file "'marks.c'"
else
sed 's/^X//' >marks.c <<'@//E*O*F marks.c//'
X/************************************************************************
X * This program is Copyright (C) 1986 by Jonathan Payne. JOVE is *
X * 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
Xint MarksShouldFloat = 1;
X
X#include "jove.h"
X
XMark *
XMakeMark(line, column, type)
Xregister Line *line;
X{
X register Mark *newmark = (Mark *) emalloc(sizeof *newmark);
X
X MarkSet(newmark, line, column);
X newmark->m_next = curbuf->b_marks;
X newmark->m_floater = type;
X curbuf->b_marks = newmark;
X return newmark;
X}
X
XDelMark(m)
Xregister Mark *m;
X{
X register Mark *mp = curbuf->b_marks;
X
X if (m == mp)
X curbuf->b_marks = m->m_next;
X else {
X while (mp != 0 && mp->m_next != m)
X mp = mp->m_next;
X if (mp == 0)
X complain("Unknown mark!");
X mp->m_next = m->m_next;
X }
X free((char *) m);
X}
X
XAllMarkSet(b, line, col)
XBuffer *b;
Xregister Line *line;
X{
X register Mark *mp;
X
X for (mp = b->b_marks; mp != 0; mp = mp->m_next)
X MarkSet(mp, line, col);
X}
X
XMarkSet(m, line, column)
XMark *m;
XLine *line;
X{
X m->m_line = line;
X m->m_char = column;
X}
X
XPopMark()
X{
X int pmark;
X
X if (curmark == 0)
X return;
X if (curbuf->b_markring[(curbuf->b_themark + 1) % NMARKS] == 0) {
X pmark = curbuf->b_themark;
X do {
X if (--pmark < 0)
X pmark = NMARKS - 1;
X } while (curbuf->b_markring[pmark] != 0);
X
X curbuf->b_markring[pmark] = MakeMark(curline, curchar, MarksShouldFloat);
X ToMark(curmark);
X DelMark(curmark);
X curmark = 0;
X } else
X PtToMark();
X
X pmark = curbuf->b_themark - 1;
X if (pmark < 0)
X pmark = NMARKS - 1;
X curbuf->b_themark = pmark;
X}
X
XSetMark()
X{
X if (exp_p)
X PopMark();
X else
X DoSetMark(curline, curchar);
X}
X
XDoSetMark(l, c)
XLine *l;
X{
X curbuf->b_themark = (curbuf->b_themark + 1) % NMARKS;
X if (curmark == 0)
X curmark = MakeMark(l, c, MarksShouldFloat);
X else
X MarkSet(curmark, l, c);
X s_mess("[Point pushed]");
X}
X
X/* Move point to Mark */
X
XToMark(m)
XMark *m;
X{
X int len;
X
X if (m == 0)
X return;
X DotTo(m->m_line, m->m_char);
X if (curchar > (len = length(curline)))
X curchar = len;
X}
X
XMark *
XCurMark()
X{
X if (curmark == 0)
X complain("No mark.");
X return curmark;
X}
X
XPtToMark()
X{
X Line *mline;
X int mchar;
X Mark *m = CurMark();
X
X mline = curline;
X mchar = curchar;
X
X ToMark(m);
X MarkSet(m, mline, mchar);
X}
X
X/* Fix marks for after a deletion. For now, even marks that don't
X float will actually float, because we can't allow marks to point
X to non-existant lines. */
X
XDFixMarks(line1, char1, line2, char2)
Xregister Line *line1,
X *line2;
X{
X register Mark *m;
X Line *lp = line1;
X
X if (curbuf->b_marks == 0)
X return;
X while (lp != line2->l_next) {
X for (m = curbuf->b_marks; m != 0; m = m->m_next) {
X/* if (!m->m_floater)
X continue; */
X if (m->m_line == lp)
X m->m_char |= (1 << 15);
X }
X lp = lp->l_next;
X }
X for (m = curbuf->b_marks; m; m = m->m_next) {
X/* if (!m->m_floater)
X continue; */
X if ((m->m_char & (1 << 15)) == 0)
X continue; /* Not effected */
X m->m_char &= ~(1 << 15);
X if (m->m_line == line1 && m->m_char < char1)
X continue; /* This mark is not affected */
X if (line1 == line2) {
X if (m->m_char >= char1 && m->m_char <= char2)
X m->m_char = char1;
X else if (m->m_char > char2)
X m->m_char -= (char2 - char1);
X /* Same line move the mark backward */
X } else if (m->m_line == line2) {
X if (m->m_char > char2)
X m->m_char = char1 + (m->m_char - char2);
X else
X m->m_char = char1;
X m->m_line = line1;
X } else {
X m->m_char = char1;
X m->m_line = line1;
X }
X }
X}
X
X/* Fix marks after an insertion. Marks that don't float are ignored
X on insertion, which means PtToMark has to be careful ... */
X
XIFixMarks(line1, char1, line2, char2)
Xregister Line *line1,
X *line2;
X{
X register Mark *m;
X
X for (m = curbuf->b_marks; m != 0; m = m->m_next) {
X if (!m->m_floater)
X continue;
X if (m->m_line == line1) {
X if (m->m_char > char1) {
X m->m_line = line2;
X if (line1 == line2)
X m->m_char += (char2 - char1);
X else
X m->m_char = char2 + (m->m_char - char1);
X }
X }
X }
X}
@//E*O*F marks.c//
if test 4197 -ne "`wc -c <'marks.c'`"; then
echo shar: error transmitting "'marks.c'" '(should have been 4197 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'setmaps.c'" '(2200 characters)'
if test -f 'setmaps.c' ; then
echo shar: will not over-write existing file "'setmaps.c'"
else
sed 's/^X//' >setmaps.c <<'@//E*O*F setmaps.c//'
X/************************************************************************
X * This program is Copyright (C) 1986 by Jonathan Payne. JOVE is *
X * 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#define TXT_TO_C
X
X#include "funcdefs.c"
X#undef putchar /* From jove.h via funcdefs.c, conflicts with STDIO */
X#undef putc
X#undef getc
X#undef EOF
X#undef FILE
X#undef BUFSIZ
X#include <stdio.h>
X
Xmatch(choices, what)
Xregister struct cmd choices[];
Xregister char *what;
X{
X register int len;
X int i,
X found = 0,
X save,
X exactmatch = -1;
X
X len = strlen(what);
X for (i = 0; choices[i].Name != 0; i++) {
X if (*what != *choices[i].Name)
X continue;
X if (strncmp(what, choices[i].Name, len) == 0)
X return i;
X }
X return -1;
X}
X
Xchar *
XPPchar(c)
Xint c;
X{
X static char str[10];
X char *cp = str;
X
X if (c == '\033')
X strcpy(cp, "ESC");
X else if (c < ' ')
X (void) sprintf(cp, "C-%c", c + '@');
X else if (c == '\177')
X strcpy(cp, "^?");
X else
X (void) sprintf(cp, "%c", c);
X return cp;
X}
X
Xextract(into, from)
Xchar *into,
X *from;
X{
X from += 2; /* Past tab and first double quote. */
X while ((*into = *from++) != '"')
X into++;
X *into = 0;
X}
X
Xmain()
X{
X FILE *ifile,
X *of;
X char line[100],
X comname[70];
X int comnum,
X ch;
X
X ifile = stdin;
X of = stdout;
X if (ifile == NULL || of == NULL) {
X printf("Cannot read input or write output.\n");
X exit(1);
X }
X while (fgets(line, sizeof line, ifile) != NULL) {
X if (strncmp(line, "\t\"", 2) != 0) {
X fprintf(of, line);
X ch = 0;
X continue;
X }
X extract(comname, line);
X if (strcmp(comname, "unbound") == 0)
X comnum = 12345;
X else {
X comnum = match(commands, comname);
X if (comnum < 0) {
X fprintf(stderr, "Cannot find command \"%s\".\n", comname);
X exit(1);
X }
X }
X if (comnum == 12345)
X fprintf(of, " (data_obj *) 0, /* %s */\n", PPchar(ch++));
X else
X fprintf(of, " (data_obj *) &commands[%d], /* %s */\n", comnum, PPchar(ch++));
X }
X fclose(of);
X fclose(ifile);
X exit(0);
X}
@//E*O*F setmaps.c//
if test 2200 -ne "`wc -c <'setmaps.c'`"; then
echo shar: error transmitting "'setmaps.c'" '(should have been 2200 characters)'
fi
fi # end of overwriting check
echo shar: "End of archive 5 (of 13)."
cp /dev/null ark5isdone
DONE=true
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13; do
if test -f ark${I}isdone; then
echo "You have run archive ${I}."
else
echo "You still need to run archive ${I}."
DONE=false
fi
done
case $DONE in
true)
echo "You have run all 13 archives."
echo 'Now read the README and Makefile.'
;;
esac
## End of shell archive.
exit 0
More information about the Mod.sources
mailing list