v08i022: The JOVE text editor, Part03/13
sources-request at mirror.UUCP
sources-request at mirror.UUCP
Wed Feb 4 14:59:07 AEST 1987
Submitted by: seismo!rochester!jpayne (Jonathan Payne)
Mod.sources: Volume 8, Issue 22
Archive-name: jove/Part03
#! /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 3 (of 13)."
# Contents: extend.c fp.c funcdefs.c insert.c table.c
PATH=/bin:/usr/bin:/usr/ucb; export PATH
echo shar: extracting "'extend.c'" '(17969 characters)'
if test -f 'extend.c' ; then
echo shar: will not over-write existing file "'extend.c'"
else
sed 's/^X//' >extend.c <<'@//E*O*F extend.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#include "io.h"
X#include "termcap.h"
X#include "ctype.h"
X#ifdef JOB_CONTROL
X# include <signal.h>
X#endif
X
X#include <varargs.h>
X
Xint InJoverc = 0;
X
Xextern int getch(),
X getchar();
X
X/* Auto execute code */
X
X#define NEXECS 20
X
Xprivate struct {
X char *a_pattern;
X data_obj *a_cmd;
X} AutoExecs[NEXECS] = {0};
X
Xprivate int ExecIndex = 0;
X
X/* Command auto-execute. */
X
XCAutoExec()
X{
X DefAutoExec(findcom);
X}
X
X/* Macro auto-execute. */
X
XMAutoExec()
X{
X DefAutoExec(findmac);
X}
X
X/* VARARGS0 */
X
XDefAutoExec(proc)
Xdata_obj *(*proc)();
X{
X data_obj *d;
X char *pattern;
X int i;
X
X if (ExecIndex >= NEXECS)
X complain("Too many auto-executes, max %d.", NEXECS);
X if ((d = (*proc)(ProcFmt)) == 0)
X return;
X pattern = ask((char *) 0, ": %f %s ", d->Name);
X for (i = 0; i < ExecIndex; i++)
X if ((AutoExecs[i].a_cmd == d) &&
X (strcmp(pattern, AutoExecs[i].a_pattern) == 0))
X return; /* Eliminate duplicates. */
X AutoExecs[ExecIndex].a_pattern = copystr(pattern);
X AutoExecs[ExecIndex].a_cmd = d;
X ExecIndex++;
X}
X
X/* DoAutoExec: NEW and OLD are file names, and if NEW and OLD aren't the
X same kind of file (i.e., match the same pattern) or OLD is 0 and it
X matches, we execute the command associated with that kind of file. */
X
XDoAutoExec(new, old)
Xregister char *new,
X *old;
X{
X register int i;
X
X exp_p = YES;
X exp = 1; /* So minor modes don't toggle. We always want
X them on. */
X if (new == 0)
X return;
X for (i = 0; i < ExecIndex; i++)
X if ((LookingAt(AutoExecs[i].a_pattern, new, 0)) &&
X (old == 0 || !LookingAt(AutoExecs[i].a_pattern, old, 0)))
X ExecCmd(AutoExecs[i].a_cmd);
X}
X
XBindAKey()
X{
X BindSomething(findcom);
X}
X
XBindMac()
X{
X BindSomething(findmac);
X}
X
Xextern int EscPrefix(),
X CtlxPrefix(),
X MiscPrefix();
X
Xdata_obj **
XIsPrefix(cp)
Xdata_obj *cp;
X{
X int (*proc)();
X
X if (cp == 0 || (cp->Type & TYPEMASK) != FUNCTION)
X return 0;
X proc = ((struct cmd *) cp)->c_proc;
X if (proc == EscPrefix)
X return pref1map;
X if (proc == CtlxPrefix)
X return pref2map;
X if (proc == MiscPrefix)
X return miscmap;
X return 0;
X}
X
Xunbind_aux(c)
X{
X if (c == CR || c == LF)
X return FALSE; /* tells do_ask to return */
X Insert(c);
X return !FALSE;
X}
X
XUnbindC()
X{
X char *keys;
X data_obj **map = mainmap;
X
X keys = do_ask("\r\n\01\02\03\04\05\06\010\011\013\014\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037", unbind_aux, (char *) 0, ProcFmt);
X if (keys == 0)
X return;
X for (;;) {
X if (keys[1] == '\0')
X break;
X if ((map = IsPrefix(map[*keys])) == 0)
X break;
X keys++;
X }
X if (keys[1] != 0)
X complain("That's not a legitimate key sequence.");
X map[keys[0]] = 0;
X}
X
Xaddgetc()
X{
X int c;
X
X if (!InJoverc)
X Asking = strlen(mesgbuf);
X c = getch();
X if (InJoverc) {
X if (c == '\n')
X return EOF; /* this isn't part of the sequence */
X else if (c == '\\') {
X if ((c = getch()) == LF)
X complain("[Premature end of line]");
X } else if (c == '^') {
X if ((c = getch()) == '?')
X c = RUBOUT;
X else if (isalpha(c) || index("[\\]^_", c))
X c = c - '@';
X else
X complain("[Unknown control character]");
X }
X }
X
X Asking = 0;
X add_mess("%p ", c);
X
X return c;
X}
X
XBindWMap(map, lastkey, cmd)
Xdata_obj **map,
X *cmd;
X{
X 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("[Premature end of key sequence]");
X } else {
X if (nextmap = IsPrefix(map[c]))
X BindWMap(nextmap, c, cmd);
X else
X map[c] = cmd;
X }
X}
X
X/* VARARGS0 */
X
XBindSomething(proc)
Xdata_obj *(*proc)();
X{
X data_obj *d;
X
X if ((d = (*proc)(ProcFmt)) == 0)
X return;
X s_mess(": %f %s ", d->Name);
X BindWMap(mainmap, EOF, d);
X}
X
X/* Describe key */
X
XDescWMap(map, key)
Xdata_obj **map;
X{
X data_obj *cp = map[key],
X **prefp;
X
X if (cp == 0)
X add_mess("is unbound.");
X else if (prefp = IsPrefix(cp))
X DescWMap(prefp, addgetc());
X else
X add_mess("is bound to %s.", cp->Name);
X}
X
XKeyDesc()
X{
X s_mess(ProcFmt);
X DescWMap(mainmap, addgetc());
X}
X
XDescCom()
X{
X data_obj *dp;
X char pattern[100],
X doc_type[40],
X *file = CmdDb;
X File *fp;
X
X if (!strcmp(LastCmd->Name, "describe-variable"))
X dp = (data_obj *) findvar(ProcFmt);
X else
X dp = (data_obj *) findcom(ProcFmt);
X
X if (dp == 0)
X return;
X fp = open_file(file, iobuff, F_READ, COMPLAIN, QUIET);
X Placur(ILI, 0);
X flusho();
X sprintf(pattern, "^:entry \"%s\" \"\\([^\"]*\\)\"", dp->Name);
X TOstart("Help", TRUE);
X for (;;) {
X if (f_gets(fp, genbuf, LBSIZE) == EOF) {
X Typeout("There is no documentation for \"%s\".", dp->Name);
X goto outahere;
X }
X if ((strncmp(genbuf, ":entry", 6) == 0) && LookingAt(pattern, genbuf, 0))
X break;
X }
X /* found it ... let's print it */
X putmatch(1, doc_type, sizeof doc_type);
X if (strcmp("Variable", doc_type) == 0)
X Typeout(dp->Name);
X else if (strcmp("Command", doc_type) == 0) {
X char binding[128];
X
X find_binds(dp, binding);
X if (blnkp(binding))
X Typeout("To invoke %s, type \"ESC X %s<cr>\".",
X dp->Name,
X dp->Name);
X else
X Typeout("Type \"%s\" to invoke %s.", binding, dp->Name);
X }
X Typeout("");
X while (f_gets(fp, genbuf, LBSIZE) != EOF)
X if (strncmp(genbuf, ":entry", 6) == 0)
X goto outahere;
X else
X Typeout("%s", genbuf);
Xoutahere:
X f_close(fp);
X TOstop();
X}
X
XDescBindings()
X{
X extern int Typeout();
X
X TOstart("Key Bindings", TRUE);
X DescMap(mainmap, NullStr);
X TOstop();
X}
X
XDescMap(map, pref)
Xdata_obj **map;
Xchar *pref;
X{
X int c1,
X c2 = 0,
X numbetween;
X char keydescbuf[40];
X data_obj **prefp;
X
X for (c1 = 0; c1 < 0200 && c2 < 0200; c1 = c2 + 1) {
X c2 = c1;
X if (map[c1] == 0)
X continue;
X while (++c2 < 0200 && map[c1] == map[c2])
X ;
X c2--;
X numbetween = c2 - c1;
X if (numbetween == 1)
X sprintf(keydescbuf, "%s {%p,%p}", pref, c1, c2);
X else if (numbetween == 0)
X sprintf(keydescbuf, "%s %p", pref, c1);
X else
X sprintf(keydescbuf, "%s [%p-%p]", pref, c1, c2);
X if (prefp = IsPrefix(map[c1]))
X DescMap(prefp, keydescbuf);
X else
X Typeout("%-14s%s", keydescbuf, map[c1]->Name);
X }
X}
X
Xprivate
Xfind_binds(dp, buf)
Xdata_obj *dp;
Xchar *buf;
X{
X char *endp;
X
X buf[0] = '\0';
X fb_aux(dp, mainmap, (char *) 0, buf);
X endp = buf + strlen(buf) - 2;
X if ((endp > buf) && (strcmp(endp, ", ") == 0))
X *endp = '\0';
X}
X
Xprivate
Xfb_aux(cp, map, prefix, buf)
Xregister data_obj *cp,
X **map;
Xchar *buf,
X *prefix;
X{
X int c1,
X c2;
X char *bufp = buf + strlen(buf),
X prefbuf[20];
X data_obj **prefp;
X
X for (c1 = c2 = 0; c1 < 0200 && c2 < 0200; c1 = c2 + 1) {
X c2 = c1;
X if (map[c1] == cp) {
X while (++c2 < 0200 && map[c1] == map[c2])
X ;
X c2--;
X if (prefix)
X sprintf(bufp, "%s ", prefix);
X bufp += strlen(bufp);
X switch (c2 - c1) {
X case 0:
X sprintf(bufp, "%p, ", c1);
X break;
X
X case 1:
X sprintf(bufp, "{%p,%p}, ", c1, c2);
X break;
X
X default:
X sprintf(bufp, "[%p-%p], ", c1, c2);
X break;
X }
X }
X if (prefp = IsPrefix(map[c1])) {
X sprintf(prefbuf, "%p", c1);
X fb_aux(cp, prefp, prefbuf, bufp);
X }
X bufp += strlen(bufp);
X }
X}
X
XApropos()
X{
X register struct cmd *cp;
X register struct macro *m;
X register struct variable *v;
X char *ans;
X int anyfs = 0,
X anyvs = 0,
X anyms = 0;
X char buf[256];
X
X ans = ask((char *) 0, ": %f (keyword) ");
X TOstart("Help", TRUE);
X for (cp = commands; cp->Name != 0; cp++)
X if (sindex(ans, cp->Name)) {
X if (anyfs == 0) {
X Typeout("Commands");
X Typeout("--------");
X }
X find_binds((data_obj *) cp, buf);
X if (buf[0])
X Typeout(": %-35s(%s)", cp->Name, buf);
X else
X Typeout(": %s", cp->Name);
X anyfs++;
X }
X if (anyfs)
X Typeout(NullStr);
X for (v = variables; v->Name != 0; v++)
X if (sindex(ans, v->Name)) {
X if (anyvs == 0) {
X Typeout("Variables");
X Typeout("---------");
X }
X anyvs++;
X vpr_aux(v, buf);
X Typeout(": set %-26s%s", v->Name, buf);
X }
X if (anyvs)
X Typeout(NullStr);
X for (m = macros; m != 0; m = m->m_nextm)
X if (sindex(ans, m->Name)) {
X if (anyms == 0) {
X Typeout("Macros");
X Typeout("------");
X }
X anyms++;
X find_binds((data_obj *) m, buf);
X if (buf[0])
X Typeout(": %-35s(%s)", m->Name, buf);
X else
X Typeout(": %-35s%s", "execute-macro", m->Name);
X }
X TOstop();
X}
X
XExtend()
X{
X data_obj *d;
X
X if (d = findcom(": "))
X ExecCmd(d);
X}
X
X/* Read a positive integer from CP. It must be in base BASE, and
X complains if it isn't. If allints is nonzero, all the characters
X in the string must be integers or we return -1; otherwise we stop
X reading at the first nondigit. */
X
Xchr_to_int(cp, base, allints)
Xregister char *cp;
X{
X register int c;
X int value = 0;
X
X while (c = *cp++) {
X if (!isdigit(c)) {
X if (allints)
X return -1;
X break;
X }
X c = c - '0';
X if (c >= base)
X complain("You must specify in base %d.", base);
X value = value * base + c;
X }
X return value;
X}
X
Xask_int(prompt, base)
Xchar *prompt;
Xint base;
X{
X char *val = ask((char *) 0, prompt);
X int value = chr_to_int(val, base, 1);
X
X if (value < 0)
X complain("That's not a number!");
X return value;
X}
X
Xprivate
Xvpr_aux(vp, buf)
Xregister struct variable *vp;
Xchar *buf;
X{
X switch (vp->v_flags & V_TYPEMASK) {
X case V_BASE10:
X sprintf(buf, "%d", *(vp->v_value));
X break;
X
X case V_BASE8:
X sprintf(buf, "%o", *(vp->v_value));
X break;
X
X case V_BOOL:
X sprintf(buf, (*(vp->v_value)) ? "on" : "off");
X break;
X
X case V_STRING:
X case V_FILENAME:
X sprintf(buf, "%s", (char *) vp->v_value);
X break;
X
X case V_CHAR:
X sprintf(buf, "%p", *(vp->v_value));
X break;
X }
X}
X
XPrVar()
X{
X struct variable *vp;
X char prbuf[256];
X
X if ((vp = (struct variable *) findvar(ProcFmt)) == 0)
X return;
X vpr_aux(vp, prbuf);
X s_mess(": %f %s => %s", vp->Name, prbuf);
X}
X
XSetVar()
X{
X struct variable *vp;
X char *prompt;
X
X if ((vp = (struct variable *) findvar(ProcFmt)) == 0)
X return;
X prompt = sprint(": %f %s ", vp->Name);
X
X switch (vp->v_flags & V_TYPEMASK) {
X case V_BASE10:
X case V_BASE8:
X {
X int value;
X
X value = ask_int(prompt, ((vp->v_flags & V_TYPEMASK) == V_BASE10)
X ? 10 : 8);
X *(vp->v_value) = value;
X break;
X }
X
X case V_BOOL:
X {
X char *def = *(vp->v_value) ? "off" : "on",
X *on_off;
X int value;
X
X on_off = ask(def, prompt);
X if (casecmp(on_off, "on") == 0)
X value = ON;
X else if (casecmp(on_off, "off") == 0)
X value = OFF;
X else
X complain("Boolean variables must be ON or OFF.");
X *(vp->v_value) = value;
X s_mess("%s%s", prompt, value ? "on" : "off");
X break;
X }
X
X case V_FILENAME:
X {
X char fbuf[FILESIZE];
X
X sprintf(&prompt[strlen(prompt)], "(default %s) ", vp->v_value);
X (void) ask_file(prompt, (char *) vp->v_value, fbuf);
X strcpy((char *) vp->v_value, fbuf);
X break;
X }
X
X case V_STRING:
X {
X char *str;
X
X /* Do_ask() so you can set string to "" if you so desire. */
X str = do_ask("\r\n", (int (*)()) 0, (char *) vp->v_value, prompt);
X if (str == 0)
X str = NullStr;
X strcpy((char *) vp->v_value, str);
X /* ... and hope there is enough room. */
X break;
X }
X case V_CHAR:
X f_mess(prompt);
X *(vp->v_value) = addgetc();
X break;
X
X }
X if (vp->v_flags & V_MODELINE)
X UpdModLine++;
X if (vp->v_flags & V_CLRSCREEN)
X ClAndRedraw();
X if (vp->v_flags & V_TTY_RESET)
X tty_reset();
X}
X
X/* Command completion - possible is an array of strings, prompt is
X the prompt to use, and flags are ... well read jove.h.
X
X If flags are RET_STATE, and the user hits <return> what they typed
X so far is in the Minibuf string. */
X
Xprivate char **Possible;
Xprivate int comp_value,
X comp_flags;
X
Xaux_complete(c)
X{
X int command,
X length,
X i;
X
X if (comp_flags & CASEIND) {
X char *lp;
X
X for (lp = linebuf; *lp != '\0'; lp++)
X if (isupper(*lp))
X *lp = tolower(*lp);
X }
X switch (c) {
X case EOF:
X comp_value = -1;
X return 0;
X
X case '\r':
X case '\n':
X command = match(Possible, linebuf);
X if (command >= 0) {
X comp_value = command;
X return 0; /* tells ask to stop */
X }
X if (eolp() && bolp()) {
X comp_value = NULLSTRING;
X return 0;
X }
X if (comp_flags & RET_STATE) switch (command) {
X case UNIQUE:
X case ORIGINAL:
X case NULLSTRING:
X comp_value = command;
X return 0;
X
X default:
X break;
X }
X if (InJoverc)
X complain("[\"%s\" unknown]", linebuf);
X rbell();
X break;
X
X case '\t':
X case ' ':
X {
X int minmatch = 1000,
X maxmatch = 0,
X numfound = 0,
X lastmatch = -1,
X length = strlen(linebuf);
X
X for (i = 0; Possible[i] != 0; i++) {
X int this_len;
X
X this_len = numcomp(Possible[i], linebuf);
X maxmatch = max(maxmatch, this_len);
X if (this_len >= length) {
X if (numfound)
X minmatch = min(minmatch, numcomp(Possible[lastmatch], Possible[i]));
X else
X minmatch = strlen(Possible[i]);
X numfound++;
X lastmatch = i;
X if (strcmp(linebuf, Possible[i]) == 0)
X break;
X }
X }
X
X if (numfound == 0) {
X rbell();
X if (InJoverc)
X complain("[\"%s\" unknown]", linebuf);
X /* If we're not in the .joverc then
X let's do something helpful for the
X user. */
X if (maxmatch < length) {
X char *cp;
X
X cp = linebuf + maxmatch;
X *cp = 0;
X Eol();
X }
X break;
X }
X if (c != '\t' && numfound == 1) {
X comp_value = lastmatch;
X return 0;
X }
X null_ncpy(linebuf, Possible[lastmatch], minmatch);
X Eol();
X if (minmatch == length) /* No difference */
X rbell();
X break;
X }
X
X case '?':
X if (InJoverc)
X complain((char *) 0);
X /* kludge: in case we're using UseBuffers, in which case
X linebuf gets written all over */
X strcpy(Minibuf, linebuf);
X length = strlen(Minibuf);
X TOstart("Completion", TRUE); /* for now ... */
X for (i = 0; Possible[i]; i++)
X if (numcomp(Possible[i], Minibuf) >= length) {
X Typeout(Possible[i]);
X if (TOabort != 0)
X break;
X }
X
X TOstop();
X break;
X }
X return !FALSE;
X}
X
Xcomplete(possible, prompt, flags)
Xregister char *possible[];
Xchar *prompt;
X{
X Possible = possible;
X comp_flags = flags;
X (void) do_ask("\r\n \t?", aux_complete, NullStr, prompt);
X return comp_value;
X}
X
Xmatch(choices, what)
Xregister char **choices,
X *what;
X{
X register int len;
X int i,
X found = 0,
X save,
X exactmatch = -1;
X
X len = strlen(what);
X if (len == 0)
X return NULLSTRING;
X for (i = 0; choices[i]; i++) {
X if (strncmp(what, choices[i], len) == 0) {
X if (strcmp(what, choices[i]) == 0)
X exactmatch = i;
X save = i;
X found++; /* Found one. */
X }
X }
X
X if (found == 0)
X save = ORIGINAL;
X else if (found > 1) {
X if (exactmatch != -1)
X save = exactmatch;
X else
X save = AMBIGUOUS;
X }
X
X return save;
X}
X
XSource()
X{
X char *com,
X buf[FILESIZE];
X
X sprintf(buf, "%s/.joverc", getenv("HOME"));
X com = ask_file((char *) 0, buf, buf);
X if (joverc(buf) == NIL)
X complain(IOerr("read", com));
X}
X
XBufPos()
X{
X register Line *lp = curbuf->b_first;
X register int i,
X dotline;
X long dotchar,
X nchars;
X
X for (i = nchars = 0; lp != 0; i++, lp = lp->l_next) {
X if (lp == curline) {
X dotchar = nchars + curchar;
X dotline = i + 1;
X }
X nchars += length(lp) + (lp->l_next != 0); /* include the NL */
X }
X
X s_mess("[\"%s\" line %d of %d, char %D of %D (%d%%)]",
X filename(curbuf),
X dotline,
X i,
X dotchar,
X nchars,
X (int) (((long) dotchar * 100) / nchars));
X}
X
X#define IF_UNBOUND -1
X#define IF_TRUE 1
X#define IF_FALSE !IF_TRUE
X
Xdo_if(cmd)
Xchar *cmd;
X{
X int pid,
X status;
X
X switch (pid = fork()) {
X case -1:
X complain("[Fork failed: if]");
X
X case 0:
X {
X char *args[12],
X *cp = cmd,
X **ap = args;
X
X *ap++ = cmd;
X for (;;) {
X if ((cp = index(cp, ' ')) == 0)
X break;
X *cp++ = '\0';
X *ap++ = cp;
X }
X *ap = 0;
X
X close(0); /* we want reads to fail */
X /* close(1); but not writes or ioctl's
X close(2); */
X
X (void) execvp(args[0], args);
X _exit(-10); /* signals exec error (see below) */
X }
X }
X#ifdef IPROCS
X sighold(SIGCHLD);
X#endif
X dowait(pid, &status);
X#ifdef IPROCS
X sigrelse(SIGCHLD);
X#endif
X if (status == -10)
X complain("[Exec failed]");
X if (status < 0)
X complain("[Exit %d]", status);
X return (status == 0); /* 0 means successful */
X}
X
Xjoverc(file)
Xchar *file;
X{
X char buf[LBSIZE],
X lbuf[128];
X int lnum = 0,
X eof = FALSE;
X jmp_buf savejmp;
X int IfStatus = IF_UNBOUND;
X File *fp;
X
X fp = open_file(file, buf, F_READ, !COMPLAIN, QUIET);
X if (fp == NIL)
X return NIL;
X
X /* Catch any errors, here, and do the right thing with them,
X and then restore the error handle to whoever did a setjmp
X last. */
X
X push_env(savejmp);
X if (setjmp(mainjmp)) {
X Buffer *savebuf = curbuf;
X
X SetBuf(do_select((Window *) 0, "RC errors"));
X ins_str(sprint("%s:%d:%s\t%s\n", pr_name(file), lnum, lbuf, mesgbuf), NO);
X unmodify();
X SetBuf(savebuf);
X Asking = 0;
X }
X InJoverc = 1;
X if (!eof) do {
X eof = (f_gets(fp, lbuf, sizeof lbuf) == EOF);
X lnum++;
X if (casencmp(lbuf, "if", 2) == 0) {
X char cmd[128];
X
X if (IfStatus != IF_UNBOUND)
X complain("[Cannot have nested if's]");
X if (LookingAt("if[ \t]*\\(.*\\)$", lbuf, 0) == 0)
X complain("[If syntax error]");
X putmatch(1, cmd, sizeof cmd);
X IfStatus = do_if(cmd) ? IF_TRUE : IF_FALSE;
X continue;
X } else if (casencmp(lbuf, "else", 4) == 0) {
X if (IfStatus == IF_UNBOUND)
X complain("[Unexpected `else']");
X IfStatus = !IfStatus;
X continue;
X } else if (casencmp(lbuf, "endif", 5) == 0) {
X if (IfStatus == IF_UNBOUND)
X complain("[Unexpected `endif']");
X IfStatus = IF_UNBOUND;
X continue;
X }
X if (IfStatus == IF_FALSE)
X continue;
X (void) strcat(lbuf, "\n");
X Inputp = lbuf;
X while (*Inputp == ' ' || *Inputp == '\t')
X Inputp++; /* skip white space */
X Extend();
X } while (!eof);
X
X f_close(fp);
X pop_env(savejmp);
X Inputp = 0;
X Asking = 0;
X InJoverc = 0;
X if (IfStatus != IF_UNBOUND)
X complain("[Missing endif]");
X return !NIL;
X}
@//E*O*F extend.c//
if test 17969 -ne "`wc -c <'extend.c'`"; then
echo shar: error transmitting "'extend.c'" '(should have been 17969 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'fp.c'" '(5151 characters)'
if test -f 'fp.c' ; then
echo shar: will not over-write existing file "'fp.c'"
else
sed 's/^X//' >fp.c <<'@//E*O*F fp.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#include "io.h"
X#include "termcap.h"
X#include <sys/stat.h>
X#include <sys/file.h>
X#include <errno.h>
X
X#define MAXFILES 20 /* good enough for my purposes */
X
Xstatic File _openfiles[MAXFILES] = {0};
X
Xstatic File *
Xf_alloc(name, flags, fd, buffer, buf_size)
Xchar *name,
X *buffer;
X{
X register File *fp;
X register int i;
X
X for (fp = _openfiles, i = 0; i < MAXFILES; i++, fp++)
X if (fp->f_flags == 0)
X break;
X if (i == MAXFILES)
X complain("[Too many open files!]");
X fp->f_bufsize = buf_size;
X fp->f_cnt = 0;
X fp->f_fd = fd;
X fp->f_flags = flags;
X if (buffer == 0) {
X buffer = emalloc(buf_size);
X fp->f_flags |= F_MYBUF;
X }
X fp->f_base = fp->f_ptr = buffer;
X fp->f_name = copystr(name);
X
X return fp;
X}
X
Xgc_openfiles()
X{
X register File *fp;
X
X for (fp = _openfiles; fp < &_openfiles[MAXFILES]; fp++)
X if (fp->f_flags != 0 && (fp->f_flags & F_LOCKED) == 0)
X f_close(fp);
X}
X
XFile *
Xfd_open(name, flags, fd, buffer, bsize)
Xchar *name,
X *buffer;
X{
X return f_alloc(name, flags, fd, buffer, bsize);
X}
X
XFile *
Xf_open(name, flags, buffer, buf_size)
Xchar *name,
X *buffer;
X{
X register int fd;
X int mode = F_MODE(flags);
X
X if (mode == F_READ)
X fd = open(name, 0);
X if (mode == F_APPEND) {
X fd = open(name, 1);
X if (fd == -1)
X mode = F_WRITE;
X else
X (void) lseek(fd, 0L, 2);
X }
X if (mode == F_WRITE)
X fd = creat(name, CreatMode);
X if (fd == -1)
X return NIL;
X return f_alloc(name, flags, fd, buffer, buf_size);
X}
X
Xf_close(fp)
XFile *fp;
X{
X flush(fp);
X#ifdef BSD4_2
X if (fp->f_flags & (F_WRITE|F_APPEND))
X (void) fsync(fp->f_fd);
X#endif
X (void) close(fp->f_fd);
X if (fp->f_flags & F_MYBUF)
X free(fp->f_base);
X free(fp->f_name);
X fp->f_flags = 0; /* indicates that we're available */
X}
X
Xfilbuf(fp)
XFile *fp;
X{
X if (fp->f_flags & (F_EOF|F_ERR))
X return EOF;
X fp->f_ptr = fp->f_base;
X fp->f_cnt = read(fp->f_fd, fp->f_base, fp->f_bufsize);
X if (fp->f_cnt == -1) {
X printf("[Read error %d]", errno);
X fp->f_flags |= F_ERR;
X }
X if (fp->f_cnt == 0) {
X fp->f_flags |= F_EOF;
X return EOF;
X }
X io_chars += fp->f_cnt;
X return getc(fp);
X}
X
Xputstr(s)
Xregister char *s;
X{
X register int c;
X
X while (c = *s++)
X putchar(c);
X}
X
Xfputnchar(s, n, fp)
Xregister char *s;
Xregister int n;
Xregister File *fp;
X{
X while (--n >= 0)
X putc(*s++, fp);
X}
X
Xflusho()
X{
X _flush(EOF, stdout);
X}
X
Xflush(fp)
XFile *fp;
X{
X _flush(EOF, fp);
X}
X
X_flush(c, fp)
Xregister File *fp;
X{
X register int n;
X
X if (fp->f_flags & (F_READ | F_STRING | F_ERR))
X return;
X if (((n = (fp->f_ptr - fp->f_base)) > 0) &&
X (write(fp->f_fd, fp->f_base, n) != n) &&
X (fp != stdout)) {
X fp->f_flags |= F_ERR;
X error("[I/O error(%d); file = %s, fd = %d]",
X errno, fp->f_name, fp->f_fd);
X }
X
X if (fp == stdout)
X OkayAbort = YES;
X fp->f_cnt = fp->f_bufsize;
X fp->f_ptr = fp->f_base;
X if (c != EOF)
X putc(c, fp);
X}
X
Xf_gets(fp, buf, max)
Xregister File *fp;
Xchar *buf;
X{
X register char *cp = buf;
X register int c;
X char *endp = buf + max - 1;
X
X if (fp->f_flags & F_EOF)
X return EOF;
X while (((c = getc(fp)) != EOF) && (c != '\n')) {
X if (c == NULL)
X continue; /* sorry we don't read nulls */
X if (cp >= endp) {
X add_mess(" [Line too long]");
X rbell();
X return EOF;
X }
X *cp++ = c;
X }
X *cp = '\0';
X if (c == EOF) {
X if (cp != buf)
X add_mess(" [Incomplete last line]");
X fp->f_flags |= F_EOF;
X return EOF;
X }
X io_lines++;
X return NIL; /* this means okay */
X}
X
X/* Deals with output to the terminal, setting up the amount of characters
X to be buffered depending on the output baud rate. Why it's in a
X separate file I don't know ... */
X
Xstatic char one_buf;
X
Xint BufSize = 1;
X
Xstatic File _stdout = {1, 1, 1, F_WRITE, &one_buf, &one_buf};
XFile *stdout = &_stdout;
X
X/* put a string with padding */
X
Xtputc(c)
X{
X putchar(c);
X}
X
X#undef putchar /* for files which forget to include io.h,
X here's a real putchar procedure. */
Xputchar(c)
X{
X putc(c, stdout);
X}
X
Xputpad(str, lines)
Xchar *str;
X{
X if (str)
X tputs(str, lines, tputc);
X}
X
X/* Determine the number of characters to buffer at each baud rate. The
X lower the number, the quicker the response when new input arrives. Of
X course the lower the number, the more prone the program is to stop in
X output. Decide what matters most to you. This sets BufSize to the right
X number or chars, and initiaizes `stdout'. */
X
Xsettout(ttbuf)
Xchar *ttbuf;
X{
X static int speeds[] = {
X 1, /* 0 */
X 1, /* 50 */
X 1, /* 75 */
X 1, /* 110 */
X 1, /* 134 */
X 1, /* 150 */
X 1, /* 200 */
X 2, /* 300 */
X 4, /* 600 */
X 8, /* 1200 */
X 16, /* 1800 */
X 32, /* 2400 */
X 128, /* 4800 */
X 256, /* 9600 */
X 512, /* EXTA */
X 512 /* EXT */
X };
X BufSize = min(512, (speeds[ospeed] * max(LI / 24, 1)));
X stdout = fd_open("/dev/tty", F_WRITE|F_LOCKED, 1, ttbuf, BufSize);
X}
X
@//E*O*F fp.c//
if test 5151 -ne "`wc -c <'fp.c'`"; then
echo shar: error transmitting "'fp.c'" '(should have been 5151 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'funcdefs.c'" '(15977 characters)'
if test -f 'funcdefs.c' ; then
echo shar: will not over-write existing file "'funcdefs.c'"
else
sed 's/^X//' >funcdefs.c <<'@//E*O*F funcdefs.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
X#ifndef TXT_TO_C
Xextern int
X EscPrefix(),
X CtlxPrefix(),
X MiscPrefix(),
X UnbindC(),
X ShowVersion(),
X WVisSpace(),
X#ifdef ANSICODES
X AnsiCodes(),
X#endif
X AppReg(),
X Apropos(),
X BackChar(),
X BList(),
X FList(),
X BUpList(),
X FDownList(),
X BSexpr(),
X BackWord(),
X Bof(),
X Bol(),
X Bos(),
X Bow(),
X BindAKey(),
X BindMac(),
X BufPos(),
X CasRegLower(),
X CasRegUpper(),
X CapChar(),
X CapWord(),
X LowWord(),
X UppWord(),
X#ifdef CHDIR
X Chdir(),
X prCWD(),
X prDIRS(),
X Pushd(),
X Popd(),
X#endif
X prCTIME(),
X ChrToOct(),
X ClAndRedraw(),
X MakeErrors(),
X CopyRegion(),
X BufSelect(),
X DelBlnkLines(),
X DelNChar(),
X DelNWord(),
X OneWindow(),
X DelPChar(),
X DelPWord(),
X DelReg(),
X KillSome(),
X DelWtSpace(),
X DelCurWindow(),
X KeyDesc(),
X Digit(),
X Digit0(),
X Digit1(),
X Digit2(),
X Digit3(),
X Digit4(),
X Digit5(),
X Digit6(),
X Digit7(),
X Digit8(),
X Digit9(),
X DescBindings(),
X DescCom(),
X Eof(),
X Eol(),
X Eos(),
X Eow(),
X ForPara(),
X BackPara(),
X BufErase(),
X PtToMark(),
X Extend(),
X ExecMacro(),
X RunMacro(),
X Leave(),
X FindFile(),
X WindFind(),
X FindTag(),
X FDotTag(),
X ToIndent(),
X ForChar(),
X FSexpr(),
X ForWord(),
X FourTime(),
X GoLine(),
X GrowWindow(),
X IncFSearch(),
X IncRSearch(),
X InsFile(),
X Justify(),
X RegJustify(),
X SetLMargin(),
X SetRMargin(),
X BufKill(),
X KillBos(),
X KillEos(),
X KillEOL(),
X KillExpr(),
X BufList(),
X NotModified(),
X NameMac(),
X DelMacro(),
X Newline(),
X OpenLine(),
X LineAI(),
X ShowErr(),
X NextError(),
X PrevError(),
X NextLine(),
X NextPage(),
X NextWindow(),
X Recur(),
X PopMark(),
X PageNWind(),
X Tab(),
X DoParen(),
X ParseAll(),
X XParse(),
X#ifdef SPELL
X SpelWords(),
X#endif
X#ifdef JOB_CONTROL
X PauseJove(),
X#endif
X PrevLine(),
X PrevPage(),
X PrevWindow(),
X Push(),
X RegReplace(),
X QRepSearch(),
X QuotChar(),
X ReadFile(),
X ReadMacs(),
X RedrawDisplay(),
X ReNamBuf(),
X RepSearch(),
X DownScroll(),
X UpScroll(),
X ForSearch(),
X FSrchND(),
X RevSearch(),
X RSrchND(),
X SelfInsert(),
X SetVar(),
X SetMark(),
X ShellCom(),
X ShToBuf(),
X ShrWindow(),
X Source(),
X#ifdef SPELL
X SpelBuffer(),
X#endif
X SplitWind(),
X Remember(),
X Forget(),
X StrLength(),
X TransChar(),
X TransLines(),
X SaveFile(),
X WtModBuf(),
X WriteFile(),
X WriteMacs(),
X WrtReg(),
X Yank(),
X YankPop(),
X PrVar(),
X FilterRegion(),
X WNumLines(),
X
X#ifdef IPROCS
X ShellProc(),
X ProcInt(),
X ProcQuit(),
X ProcKill(),
X# ifndef PIPEPROCS
X ProcEof(),
X ProcStop(),
X ProcCont(),
X ProcDStop(),
X# endif
X ProcSendData(),
X ProcNewline(),
X ProcList(),
X ProcBind(),
X Iprocess(),
X#endif
X
X#ifdef LISP
X GSexpr(), /* Grind S Expression. */
X AddSpecial(), /* add lisp special form */
X#endif
X CAutoExec(),
X MAutoExec(),
X
X DefMAbbrev(),
X DefGAbbrev(),
X SaveAbbrevs(),
X RestAbbrevs(),
X EditAbbrevs(),
X BindMtoW(),
X
X#ifdef CMT_FMT
X Comment(),
X#endif
X
X MacInter(); /* This is the last one. */
X
X
X# define WIRED_CMD(c) c
X
X#else TXT_TO_C
X
X# define WIRED_CMD(c) 0
X
X#endif TXT_TO_C
X
Xstruct cmd commands[] = {
X#ifdef LISP
X FUNCTION, "add-lisp-special", WIRED_CMD(AddSpecial),
X#endif
X#ifdef ANSICODES
X FUNCTION, "ansi-codes", WIRED_CMD(AnsiCodes),
X#endif
X FUNCTION, "append-region", WIRED_CMD(AppReg),
X FUNCTION, "apropos", WIRED_CMD(Apropos),
X FUNCTION, "auto-execute-command", WIRED_CMD(CAutoExec),
X FUNCTION, "auto-execute-macro", WIRED_CMD(MAutoExec),
X DefMinor(Fill), "auto-fill-mode", 0,
X DefMinor(Indent), "auto-indent-mode", 0,
X FUNCTION, "backward-character", WIRED_CMD(BackChar),
X FUNCTION, "backward-list", WIRED_CMD(BList),
X FUNCTION, "backward-paragraph", WIRED_CMD(BackPara),
X FUNCTION, "backward-s-expression", WIRED_CMD(BSexpr),
X FUNCTION, "backward-sentence", WIRED_CMD(Bos),
X FUNCTION, "backward-up-list", WIRED_CMD(BUpList),
X FUNCTION, "backward-word", WIRED_CMD(BackWord),
X FUNCTION, "beginning-of-file", WIRED_CMD(Bof),
X FUNCTION, "beginning-of-line", WIRED_CMD(Bol),
X FUNCTION, "beginning-of-window", WIRED_CMD(Bow),
X FUNCTION, "bind-to-key", WIRED_CMD(BindAKey),
X FUNCTION, "bind-macro-to-key", WIRED_CMD(BindMac),
X#ifdef ABBREV
X FUNCTION, "bind-macro-to-word-abbrev", WIRED_CMD(BindMtoW),
X#endif
X FUNCTION, "buffer-position", WIRED_CMD(BufPos),
X DefMajor(CMODE), "c-mode", 0,
X FUNCTION, "case-character-capitalize", WIRED_CMD(CapChar),
X FUNCTION, "case-region-lower", WIRED_CMD(CasRegLower),
X FUNCTION, "case-region-upper", WIRED_CMD(CasRegUpper),
X FUNCTION, "case-word-capitalize", WIRED_CMD(CapWord),
X FUNCTION, "case-word-lower", WIRED_CMD(LowWord),
X FUNCTION, "case-word-upper", WIRED_CMD(UppWord),
X FUNCTION, "character-to-octal-insert", WIRED_CMD(ChrToOct),
X#ifdef CHDIR
X FUNCTION, "cd", WIRED_CMD(Chdir),
X#endif
X FUNCTION, "clear-and-redraw", WIRED_CMD(ClAndRedraw),
X FUNCTION, "compile-it", WIRED_CMD(MakeErrors),
X#ifdef IPROCS
X# ifndef PIPEPROCS
X# ifdef TIOCSLTC
X FUNCTION, "continue-process", WIRED_CMD(ProcCont),
X# endif
X# endif
X#endif
X FUNCTION, "copy-region", WIRED_CMD(CopyRegion),
X FUNCTION, "current-error", WIRED_CMD(ShowErr),
X FUNCTION, "date", WIRED_CMD(prCTIME),
X#ifdef ABBREV
X FUNCTION, "define-mode-word-abbrev", WIRED_CMD(DefMAbbrev),
X FUNCTION, "define-global-word-abbrev", WIRED_CMD(DefGAbbrev),
X#endif
X FUNCTION, "delete-blank-lines", WIRED_CMD(DelBlnkLines),
X FUNCTION, "delete-buffer", WIRED_CMD(BufKill),
X FUNCTION, "delete-macro", WIRED_CMD(DelMacro),
X FUNCTION, "delete-next-character", WIRED_CMD(DelNChar),
X FUNCTION, "delete-other-windows", WIRED_CMD(OneWindow),
X FUNCTION, "delete-previous-character", WIRED_CMD(DelPChar),
X FUNCTION, "delete-white-space", WIRED_CMD(DelWtSpace),
X FUNCTION, "delete-current-window", WIRED_CMD(DelCurWindow),
X FUNCTION, "describe-bindings", WIRED_CMD(DescBindings),
X FUNCTION, "describe-command", WIRED_CMD(DescCom),
X FUNCTION, "describe-key", WIRED_CMD(KeyDesc),
X FUNCTION, "describe-variable", WIRED_CMD(DescCom),
X FUNCTION, "digit", WIRED_CMD(Digit),
X FUNCTION, "digit-1", WIRED_CMD(Digit1),
X FUNCTION, "digit-2", WIRED_CMD(Digit2),
X FUNCTION, "digit-3", WIRED_CMD(Digit3),
X FUNCTION, "digit-4", WIRED_CMD(Digit4),
X FUNCTION, "digit-5", WIRED_CMD(Digit5),
X FUNCTION, "digit-6", WIRED_CMD(Digit6),
X FUNCTION, "digit-7", WIRED_CMD(Digit7),
X FUNCTION, "digit-8", WIRED_CMD(Digit8),
X FUNCTION, "digit-9", WIRED_CMD(Digit9),
X FUNCTION, "digit-0", WIRED_CMD(Digit0),
X#ifdef CHDIR
X FUNCTION, "dirs", WIRED_CMD(prDIRS),
X#endif
X FUNCTION, "down-list", WIRED_CMD(FDownList),
X#ifdef IPROCS
X# ifndef PIPEPROCS
X# ifdef TIOCSLTC
X FUNCTION, "dstop-process", WIRED_CMD(ProcDStop),
X# endif
X# endif
X#endif
X#ifdef ABBREV
X FUNCTION, "edit-word-abbrevs", WIRED_CMD(EditAbbrevs),
X#endif
X FUNCTION, "end-of-file", WIRED_CMD(Eof),
X FUNCTION, "end-of-line", WIRED_CMD(Eol),
X FUNCTION, "end-of-window", WIRED_CMD(Eow),
X#ifdef IPROCS
X# ifndef PIPEPROCS
X FUNCTION, "eof-process", WIRED_CMD(ProcEof),
X# endif
X#endif
X FUNCTION, "erase-buffer", WIRED_CMD(BufErase),
X FUNCTION, "exchange-point-and-mark", WIRED_CMD(PtToMark),
X FUNCTION, "execute-named-command", WIRED_CMD(Extend),
X FUNCTION, "execute-keyboard-macro", WIRED_CMD(ExecMacro),
X FUNCTION, "execute-macro", WIRED_CMD(RunMacro),
X FUNCTION, "exit-jove", WIRED_CMD(Leave),
X#ifdef CMT_FMT
X FUNCTION, "fill-comment", WIRED_CMD(Comment),
X#endif CMT_FMT
X FUNCTION, "fill-paragraph", WIRED_CMD(Justify),
X FUNCTION, "fill-region", WIRED_CMD(RegJustify),
X FUNCTION, "filter-region", WIRED_CMD(FilterRegion),
X FUNCTION, "find-file", WIRED_CMD(FindFile),
X FUNCTION, "find-tag", WIRED_CMD(FindTag),
X FUNCTION, "find-tag-at-point", WIRED_CMD(FDotTag),
X FUNCTION, "first-non-blank", WIRED_CMD(ToIndent),
X FUNCTION, "forward-character", WIRED_CMD(ForChar),
X FUNCTION, "forward-list", WIRED_CMD(FList),
X FUNCTION, "forward-paragraph", WIRED_CMD(ForPara),
X FUNCTION, "forward-s-expression", WIRED_CMD(FSexpr),
X FUNCTION, "forward-sentence", WIRED_CMD(Eos),
X FUNCTION, "forward-word", WIRED_CMD(ForWord),
X DefMajor(FUNDAMENTAL), "fundamental-mode", 0,
X#ifdef LISP
X FUNCTION, "grind-s-expr", WIRED_CMD(GSexpr),
X#endif
X FUNCTION, "goto-line", WIRED_CMD(GoLine),
X FUNCTION, "grow-window", WIRED_CMD(GrowWindow),
X FUNCTION, "handle-tab", WIRED_CMD(Tab),
X FUNCTION, "i-search-forward", WIRED_CMD(IncFSearch),
X FUNCTION, "i-search-reverse", WIRED_CMD(IncRSearch),
X FUNCTION, "insert-file", WIRED_CMD(InsFile),
X#ifdef IPROCS
X FUNCTION, "interrupt-process", WIRED_CMD(ProcInt),
X FUNCTION, "i-shell-command", WIRED_CMD(Iprocess),
X#endif
X FUNCTION, "kill-next-word", WIRED_CMD(DelNWord),
X FUNCTION, "kill-previous-word", WIRED_CMD(DelPWord),
X#ifdef IPROCS
X FUNCTION, "kill-process", WIRED_CMD(ProcKill),
X#endif
X FUNCTION, "kill-region", WIRED_CMD(DelReg),
X FUNCTION, "kill-s-expression", WIRED_CMD(KillExpr),
X FUNCTION, "kill-some-buffers", WIRED_CMD(KillSome),
X FUNCTION, "kill-to-beginning-of-sentence", WIRED_CMD(KillBos),
X FUNCTION, "kill-to-end-of-line", WIRED_CMD(KillEOL),
X FUNCTION, "kill-to-end-of-sentence", WIRED_CMD(KillEos),
X FUNCTION, "left-margin-here", WIRED_CMD(SetLMargin),
X#ifdef LISP
X DefMajor(LISPMODE), "lisp-mode", 0,
X#endif
X FUNCTION, "list-buffers", WIRED_CMD(BufList),
X#ifdef IPROCS
X FUNCTION, "list-processes", WIRED_CMD(ProcList),
X#endif
X FUNCTION, "make-buffer-unmodified", WIRED_CMD(NotModified),
X FUNCTION, "make-macro-interactive", WIRED_CMD(MacInter),
X FUNCTION, "name-keyboard-macro", WIRED_CMD(NameMac),
X FUNCTION, "newline", WIRED_CMD(Newline),
X FUNCTION, "newline-and-backup", WIRED_CMD(OpenLine),
X FUNCTION, "newline-and-indent", WIRED_CMD(LineAI),
X FUNCTION, "next-error", WIRED_CMD(NextError),
X FUNCTION, "next-line", WIRED_CMD(NextLine),
X FUNCTION, "next-page", WIRED_CMD(NextPage),
X FUNCTION, "next-window", WIRED_CMD(NextWindow),
X FUNCTION, "number-lines-in-window", WIRED_CMD(WNumLines),
X DefMinor(OverWrite), "over-write-mode", 0,
X FUNCTION, "page-next-window", WIRED_CMD(PageNWind),
X FUNCTION, "paren-flash", WIRED_CMD(DoParen),
X FUNCTION, "parse-errors", WIRED_CMD(ParseAll),
X FUNCTION, "parse-special-errors", WIRED_CMD(XParse),
X#ifdef SPELL
X FUNCTION, "parse-spelling-errors-in-buffer", WIRED_CMD(SpelWords),
X#endif
X#ifdef JOB_CONTROL
X FUNCTION, "pause-jove", WIRED_CMD(PauseJove),
X#else
X FUNCTION, "pause-jove", WIRED_CMD(Push),
X#endif
X FUNCTION, "pop-mark", WIRED_CMD(PopMark),
X#ifdef CHDIR
X FUNCTION, "popd", WIRED_CMD(Popd),
X#endif
X FUNCTION, "prefix-1", WIRED_CMD(EscPrefix),
X FUNCTION, "prefix-2", WIRED_CMD(CtlxPrefix),
X FUNCTION, "prefix-3", WIRED_CMD(MiscPrefix),
X FUNCTION, "previous-error", WIRED_CMD(PrevError),
X FUNCTION, "previous-line", WIRED_CMD(PrevLine),
X FUNCTION, "previous-page", WIRED_CMD(PrevPage),
X FUNCTION, "previous-window", WIRED_CMD(PrevWindow),
X FUNCTION, "print", WIRED_CMD(PrVar),
X#ifdef IPROCS
X FUNCTION, "process-bind-to-key", WIRED_CMD(ProcBind),
X FUNCTION, "process-newline", WIRED_CMD(ProcNewline),
X FUNCTION, "process-send-data-no-return", WIRED_CMD(ProcSendData),
X#endif
X FUNCTION, "push-shell", WIRED_CMD(Push),
X#ifdef CHDIR
X FUNCTION, "pushd", WIRED_CMD(Pushd),
X FUNCTION, "pwd", WIRED_CMD(prCWD),
X#endif
X FUNCTION, "quadruple-numeric-argument", WIRED_CMD(FourTime),
X FUNCTION, "query-replace-string", WIRED_CMD(QRepSearch),
X#ifdef IPROCS
X FUNCTION, "quit-process", WIRED_CMD(ProcQuit),
X#endif
X FUNCTION, "quoted-insert", WIRED_CMD(QuotChar),
X#ifdef ABBREV
X FUNCTION, "read-word-abbrev-file", WIRED_CMD(RestAbbrevs),
X#endif
X FUNCTION, "read-macros-from-file", WIRED_CMD(ReadMacs),
X FUNCTION, "redraw-display", WIRED_CMD(RedrawDisplay),
X FUNCTION, "recursive-edit", WIRED_CMD(Recur),
X FUNCTION, "rename-buffer", WIRED_CMD(ReNamBuf),
X FUNCTION, "replace-in-region", WIRED_CMD(RegReplace),
X FUNCTION, "replace-string", WIRED_CMD(RepSearch),
X FUNCTION, "right-margin-here", WIRED_CMD(SetRMargin),
X FUNCTION, "save-file", WIRED_CMD(SaveFile),
X FUNCTION, "scroll-down", WIRED_CMD(DownScroll),
X FUNCTION, "scroll-up", WIRED_CMD(UpScroll),
X FUNCTION, "search-forward", WIRED_CMD(ForSearch),
X FUNCTION, "search-forward-nd", WIRED_CMD(FSrchND),
X FUNCTION, "search-reverse", WIRED_CMD(RevSearch),
X FUNCTION, "search-reverse-nd", WIRED_CMD(RSrchND),
X FUNCTION, "select-buffer", WIRED_CMD(BufSelect),
X FUNCTION, "self-insert", WIRED_CMD(SelfInsert),
X FUNCTION, "set", WIRED_CMD(SetVar),
X FUNCTION, "set-mark", WIRED_CMD(SetMark),
X#ifdef IPROCS /* for GNU compatibility */
X FUNCTION, "shell", WIRED_CMD(ShellProc),
X#endif
X FUNCTION, "shell-command", WIRED_CMD(ShellCom),
X FUNCTION, "shell-command-to-buffer", WIRED_CMD(ShToBuf),
X DefMinor(ShowMatch), "show-match-mode", 0,
X FUNCTION, "shrink-window", WIRED_CMD(ShrWindow),
X FUNCTION, "source", WIRED_CMD(Source),
X#ifdef SPELL
X FUNCTION, "spell-buffer", WIRED_CMD(SpelBuffer),
X#endif
X FUNCTION, "split-current-window", WIRED_CMD(SplitWind),
X FUNCTION, "start-remembering", WIRED_CMD(Remember),
X#ifdef IPROCS
X# ifndef PIPEPROCS
X FUNCTION, "stop-process", WIRED_CMD(ProcStop),
X# endif
X#endif
X FUNCTION, "stop-remembering", WIRED_CMD(Forget),
X FUNCTION, "string-length", WIRED_CMD(StrLength),
X#ifdef JOB_CONTROL
X FUNCTION, "suspend-jove", WIRED_CMD(PauseJove),
X#endif
X DefMajor(TEXT), "text-mode", 0,
X FUNCTION, "transpose-characters", WIRED_CMD(TransChar),
X FUNCTION, "transpose-lines", WIRED_CMD(TransLines),
X FUNCTION, "unbind-key", WIRED_CMD(UnbindC),
X FUNCTION, "version", WIRED_CMD(ShowVersion),
X FUNCTION, "visible-spaces-in-window", WIRED_CMD(WVisSpace),
X FUNCTION, "visit-file", WIRED_CMD(ReadFile),
X FUNCTION, "window-find", WIRED_CMD(WindFind),
X#ifdef ABBREV
X DefMinor(Abbrev), "word-abbrev-mode", 0,
X FUNCTION, "write-word-abbrev-file", WIRED_CMD(SaveAbbrevs),
X#endif
X FUNCTION, "write-file", WIRED_CMD(WriteFile),
X FUNCTION, "write-macros-to-file", WIRED_CMD(WriteMacs),
X FUNCTION, "write-modified-files", WIRED_CMD(WtModBuf),
X FUNCTION, "write-region", WIRED_CMD(WrtReg),
X FUNCTION, "yank", WIRED_CMD(Yank),
X FUNCTION, "yank-pop", WIRED_CMD(YankPop),
X FUNCTION, 0, 0
X};
X
X#ifndef TXT_TO_C
Xdata_obj *
Xfindcom(prompt)
Xchar *prompt;
X{
X /* This is for faster startup. This just reads until a space or a
X tab or a newline character is reached, and then does a
X semi-hashed lookup on that string. This should be much faster
X than initializing the minibuffer for each line. */
X if (InJoverc) {
X char cmdbuf[128];
X register struct cmd *cmd;
X register char *cp = cmdbuf;
X register int c;
X struct cmd *which;
X int cmdlen,
X found = 0;
X static struct cmd *cmdhash[1 + 26];
X static int beenhere = NO;
X
X/* special case for prefix commands--only upper case ones */
X#define hash(c) ((c == 'P') ? 0 : 1 + (c - 'a'))
X
X /* initialize the hash table */
X if (beenhere == NO) {
X int lastc = 0;
X
X for (cmd = commands; cmd->Name != 0; cmd++)
X if (lastc != cmd->Name[0]) {
X lastc = cmd->Name[0];
X cmdhash[hash(lastc)] = cmd;
X }
X beenhere = YES;
X }
X
X /* gather the cmd name */
X while (((c = getch()) != EOF) && !index(" \t\r\n", c))
X *cp++ = c;
X if (c == EOF)
X return 0;
X *cp = '\0';
X cmdlen = cp - cmdbuf;
X if (cmdlen == 0)
X return 0;
X
X /* look it up (in the reduced search space) */
X for (cmd = cmdhash[hash(cmdbuf[0])]; cmd->Name[0] == cmdbuf[0]; cmd++) {
X if (strncmp(cmd->Name, cmdbuf, cmdlen) == 0) {
X if (strcmp(cmd->Name, cmdbuf) == 0)
X return (data_obj *) cmd;
X found++;
X which = cmd;
X }
X }
X if (found > 1)
X complain("[\"%s\" ambiguous]", cmdbuf);
X else if (found == 0)
X complain("[\"%s\" unknown]", cmdbuf);
X else
X return (data_obj *) which;
X } else {
X static char *strings[(sizeof commands) / sizeof (commands[0])];
X static int beenhere = 0;
X register int com;
X
X if (beenhere == 0) {
X register char **strs = strings;
X register struct cmd *c = commands;
X
X beenhere = 1;
X for (; c->Name; c++)
X *strs++ = c->Name;
X *strs = 0;
X }
X
X if ((com = complete(strings, prompt, CASEIND)) < 0)
X return 0;
X return (data_obj *) &commands[com];
X }
X /* NOTREACHED */
X}
X#endif
@//E*O*F funcdefs.c//
if test 15977 -ne "`wc -c <'funcdefs.c'`"; then
echo shar: error transmitting "'funcdefs.c'" '(should have been 15977 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'insert.c'" '(13582 characters)'
if test -f 'insert.c' ; then
echo shar: will not over-write existing file "'insert.c'"
else
sed 's/^X//' >insert.c <<'@//E*O*F insert.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#include "ctype.h"
X#include "table.h"
X
X/* Make a newline after AFTER in buffer BUF, UNLESS after is 0,
X in which case we insert the newline before after. */
X
XLine *
Xlistput(buf, after)
Xregister Buffer *buf;
Xregister Line *after;
X{
X register Line *newline = nbufline();
X
X if (after == 0) { /* Before the first line */
X newline->l_next = buf->b_first;
X newline->l_prev = 0;
X buf->b_first = newline;
X } else {
X newline->l_prev = after;
X newline->l_next = after->l_next;
X after->l_next = newline;
X }
X if (newline->l_next)
X newline->l_next->l_prev = newline;
X else
X if (buf)
X buf->b_last = newline;
X if (buf && buf->b_dot == 0)
X buf->b_dot = newline;
X return newline;
X}
X
X/* Divide the current line and move the current line to the next one */
X
XLineInsert(num)
Xregister int num;
X{
X char newline[LBSIZE];
X register Line *newdot,
X *olddot;
X int oldchar;
X
X olddot = curline;
X oldchar = curchar;
X
X newdot = curline;
X while (--num >= 0) {
X newdot = listput(curbuf, newdot);
X SavLine(newdot, NullStr);
X }
X
X modify();
X if (curchar != 0) {
X strcpy(newline, &linebuf[curchar]);
X linebuf[curchar] = '\0'; /* Shorten this line */
X SavLine(curline, linebuf);
X strcpy(linebuf, newline);
X } else { /* Redisplay optimization */
X newdot->l_dline = curline->l_dline;
X SavLine(curline, NullStr);
X }
X
X makedirty(curline);
X curline = newdot;
X curchar = 0;
X makedirty(curline);
X IFixMarks(olddot, oldchar, curline, curchar);
X}
X
X/* Makes the indent of the current line == goal. If the current indent
X is greater than GOAL it deletes. If more indent is needed, it uses
X tabs and spaces to get to where it's going. */
X
Xn_indent(goal)
Xregister int goal;
X{
X int dotcol,
X incrmt;
X
X ToIndent();
X dotcol = calc_pos(linebuf, curchar);
X if (goal < dotcol) {
X DelWtSpace();
X dotcol = 0;
X }
X
X for (;;) {
X incrmt = (tabstop - (dotcol % tabstop));
X if (dotcol + incrmt > goal)
X break;
X Insert('\t');
X dotcol += incrmt;
X }
X if (dotcol != goal)
X DoTimes(Insert(' '), (goal - dotcol));
X exp_p = NO;
X exp = 1;
X}
X
XSelfInsert()
X{
X#ifdef ABBREV
X if (MinorMode(Abbrev) && !ismword(LastKeyStruck) &&
X !bolp() && ismword(linebuf[curchar - 1]))
X AbbrevExpand();
X#endif
X if (MinorMode(OverWrite)) {
X register int num,
X i;
X
X for (i = 0, num = exp, exp = 1; i < num; i++) {
X int pos = calc_pos(linebuf, curchar);
X
X if (!eolp()) {
X if (linebuf[curchar] == '\t') {
X if ((pos + 1) == ((pos + tabstop) - (pos % tabstop)))
X DelNChar();
X } else
X DelNChar();
X }
X Insert(LastKeyStruck);
X }
X } else
X Insert(LastKeyStruck);
X
X if (MinorMode(Fill) && (curchar >= RMargin ||
X (calc_pos(linebuf, curchar) >= RMargin)))
X DoJustify(curline, 0, curline,
X curchar + strlen(&linebuf[curchar]), 1, LMargin);
X}
X
XInsert(c)
X{
X if (exp <= 0)
X return;
X modify();
X makedirty(curline);
X ins_c(c, linebuf, curchar, exp, LBSIZE);
X IFixMarks(curline, curchar, curline, curchar + exp);
X curchar += exp;
X}
X
X/* Tab in to the right place for C mode */
X
XTab()
X{
X#ifdef LISP
X if (MajorMode(LISPMODE)) {
X int dotchar = curchar;
X Mark *m = 0;
X
X ToIndent();
X if (dotchar > curchar)
X m = MakeMark(curline, dotchar, FLOATER);
X (void) lisp_indent();
X if (m) {
X ToMark(m);
X DelMark(m);
X } else
X ToIndent();
X return;
X }
X#endif
X if (MajorMode(CMODE) && strlen(linebuf) == 0)
X (void) c_indent(CIndIncrmt);
X else
X SelfInsert();
X}
X
XQuotChar()
X{
X int c;
X extern int alarmed; /* If waitfor had to wait. */
X
X c = waitchar();
X if (alarmed)
X message(key_strokes);
X if (c == CTL(J))
X LineInsert(exp);
X else if (c != CTL(@))
X Insert(c);
X}
X
X/* Insert the paren. If in C mode and c is a '}' then insert the
X '}' in the "right" place for C indentation; that is indented
X the same amount as the matching '{' is indented. */
X
Xint PDelay = 5, /* 1/2 a second */
X CIndIncrmt = 8;
X
XDoParen()
X{
X Bufpos *bp = (Bufpos *) -1;
X int nx,
X c = LastKeyStruck;
X
X if (!isclosep(c)) {
X SelfInsert();
X return;
X }
X
X if (MajorMode(CMODE) && c == '}' && blnkp(linebuf))
X bp = c_indent(0);
X#ifdef LISP
X if (MajorMode(LISPMODE) && c == ')' && blnkp(linebuf))
X bp = lisp_indent();
X#endif
X SelfInsert();
X if (MinorMode(ShowMatch) && !charp() && !in_macro()) {
X BackChar(); /* Back onto the ')' */
X if ((int) bp == -1)
X bp = m_paren(c, BACKWARD, NO, YES);
X ForChar();
X if (bp != 0) {
X nx = in_window(curwind, bp->p_line);
X if (nx != -1) { /* is visible */
X Bufpos b;
X
X DOTsave(&b);
X SetDot(bp);
X SitFor(PDelay);
X SetDot(&b);
X } else
X s_mess("%s", lcontents(bp->p_line));
X }
X mp_error(); /* display error message */
X }
X}
X
XLineAI()
X{
X DoNewline(TRUE);
X}
X
XNewline()
X{
X DoNewline(MinorMode(Indent));
X}
X
XDoNewline(indentp)
X{
X Bufpos save;
X int indent;
X
X /* first we calculate the indent of the current line */
X DOTsave(&save);
X ToIndent();
X indent = calc_pos(linebuf, curchar);
X SetDot(&save);
X
X#ifdef ABBREV
X if (MinorMode(Abbrev) && !ismword(LastKeyStruck) &&
X !bolp() && ismword(linebuf[curchar - 1]))
X AbbrevExpand();
X#endif
X#ifdef LISP
X if (MajorMode(LISPMODE))
X DelWtSpace();
X#endif
X else if (blnkp(linebuf))
X DelWtSpace();
X
X /* If there is more than 2 blank lines in a row then don't make
X a newline, just move down one. */
X if (exp == 1 && eolp() && TwoBlank())
X SetLine(curline->l_next);
X else
X LineInsert(exp);
X
X if (indentp)
X#ifdef LISP
X if (MajorMode(LISPMODE))
X (void) lisp_indent();
X else
X#endif
X n_indent((LMargin == 0) ? indent : LMargin);
X}
X
Xins_str(str, ok_nl)
Xregister char *str;
X{
X register char c;
X Bufpos save;
X int llen;
X
X if (*str == 0)
X return; /* ain't nothing to insert! */
X DOTsave(&save);
X llen = strlen(linebuf);
X while (c = *str++) {
X if (c == '\n' || (ok_nl && llen >= LBSIZE - 2)) {
X IFixMarks(save.p_line, save.p_char, curline, curchar);
X modify();
X makedirty(curline);
X LineInsert(1);
X DOTsave(&save);
X llen = strlen(linebuf);
X }
X if (c != '\n') {
X ins_c(c, linebuf, curchar++, 1, LBSIZE);
X llen++;
X }
X }
X IFixMarks(save.p_line, save.p_char, curline, curchar);
X modify();
X makedirty(curline);
X}
X
XOpenLine()
X{
X Bufpos dot;
X
X DOTsave(&dot);
X LineInsert(exp); /* Open the lines... */
X SetDot(&dot);
X}
X
X/* Take the region FLINE/FCHAR to TLINE/TCHAR and insert it at
X ATLINE/ATCHAR in WHATBUF. */
X
XBufpos *
XDoYank(fline, fchar, tline, tchar, atline, atchar, whatbuf)
XLine *fline,
X *tline,
X *atline;
XBuffer *whatbuf;
X{
X register Line *newline;
X static Bufpos bp;
X char save[LBSIZE],
X buf[LBSIZE];
X Line *startline = atline;
X int startchar = atchar;
X
X lsave();
X if (whatbuf)
X modify();
X (void) ltobuf(atline, genbuf);
X strcpy(save, &genbuf[atchar]);
X
X (void) ltobuf(fline, buf);
X if (fline == tline)
X buf[tchar] = '\0';
X
X linecopy(genbuf, atchar, &buf[fchar]);
X atline->l_dline = putline(genbuf);
X makedirty(atline);
X
X fline = fline->l_next;
X while (fline != tline->l_next) {
X newline = listput(whatbuf, atline);
X newline->l_dline = fline->l_dline;
X makedirty(newline);
X fline = fline->l_next;
X atline = newline;
X atchar = 0;
X }
X
X getline(atline->l_dline, genbuf);
X atchar += tchar;
X linecopy(genbuf, atchar, save);
X atline->l_dline = putline(genbuf);
X makedirty(atline);
X IFixMarks(startline, startchar, atline, atchar);
X bp.p_line = atline;
X bp.p_char = atchar;
X this_cmd = YANKCMD;
X getDOT(); /* Whatever used to be in linebuf */
X return &bp;
X}
X
XYankPop()
X{
X Line *line,
X *last;
X Mark *mp = CurMark();
X Bufpos *dot;
X int dir = -1; /* Direction to rotate the ring */
X
X if (last_cmd != YANKCMD)
X complain("Yank something first!");
X
X lfreelist(reg_delete(mp->m_line, mp->m_char, curline, curchar));
X
X /* Now must find a recently killed region. */
X
X if (exp < 0)
X dir = 1;
X
X killptr += dir;
X for (;;) {
X if (killptr < 0)
X killptr = NUMKILLS - 1;
X else if (killptr >= NUMKILLS)
X killptr = 0;
X if (killbuf[killptr])
X break;
X killptr += dir;
X }
X
X this_cmd = YANKCMD;
X
X line = killbuf[killptr];
X last = lastline(line);
X dot = DoYank(line, 0, last, length(last), curline, curchar, curbuf);
X MarkSet(CurMark(), curline, curchar);
X SetDot(dot);
X}
X
X/* This is an attempt to reduce the amount of memory taken up by each line.
X Without this each malloc of a line uses sizeof (line) + sizeof(HEADER)
X where line is 3 words and HEADER is 1 word.
X This is going to allocate memory in chucks of CHUNKSIZE * sizeof (line)
X and divide each chuck into lineS. A line is free in a chunk when its
X line->l_dline == 0, so freeline sets dline to 0. */
X
X#define CHUNKSIZE 300
X
Xstruct chunk {
X int c_nlines; /* Number of lines in this chunk (so they
X don't all have to be CHUNKSIZE long). */
X Line *c_block; /* Chunk of memory */
X struct chunk *c_nextfree; /* Next chunk of lines */
X};
X
Xstatic struct chunk *fchunk = 0;
Xstatic Line *ffline = 0; /* First free line */
X
Xfreeline(line)
Xregister Line *line;
X{
X line->l_dline = 0;
X line->l_next = ffline;
X if (ffline)
X ffline->l_prev = line;
X line->l_prev = 0;
X ffline = line;
X}
X
Xlfreelist(first)
Xregister Line *first;
X{
X if (first)
X lfreereg(first, lastline(first));
X}
X
X/* Append region from line1 to line2 onto the free list of lines */
X
Xlfreereg(line1, line2)
Xregister Line *line1,
X *line2;
X{
X register Line *next,
X *last = line2->l_next;
X
X while (line1 != last) {
X next = line1->l_next;
X freeline(line1);
X line1 = next;
X }
X}
X
Xstatic
Xnewchunk()
X{
X register Line *newline;
X register int i;
X struct chunk *f;
X int nlines = CHUNKSIZE;
X
X f = (struct chunk *) emalloc(sizeof (struct chunk));
X if (f == 0)
X return 0;
X
X if ((f->c_block = (Line *) malloc((unsigned) (sizeof (Line) * nlines))) == 0) {
X while (nlines > 0) {
X f->c_block = (Line *) malloc((unsigned) (sizeof (Line) * nlines));
X if (f->c_block != 0)
X break;
X nlines /= 2;
X }
X }
X
X if (nlines <= 0)
X return 0;
X
X f->c_nlines = nlines;
X for (i = 0, newline = f->c_block; i < nlines; newline++, i++)
X freeline(newline);
X f->c_nextfree = fchunk;
X fchunk = f;
X return 1;
X}
X
X/* New BUFfer LINE */
X
XLine *
Xnbufline()
X{
X register Line *newline;
X
X if (ffline == 0) /* No free list */
X if (newchunk() == 0)
X complain("[Out of lines] ");
X newline = ffline;
X ffline = ffline->l_next;
X if (ffline)
X ffline->l_prev = 0;
X return newline;
X}
X
X/* Remove the free lines, in chunk c, from the free list because they are
X no longer free. */
X
Xstatic
Xremfreelines(c)
Xregister struct chunk *c;
X{
X register Line *lp;
X register int i;
X
X for (lp = c->c_block, i = 0; i < c->c_nlines; i++, lp++) {
X if (lp->l_prev)
X lp->l_prev->l_next = lp->l_next;
X else
X ffline = lp->l_next;
X if (lp->l_next)
X lp->l_next->l_prev = lp->l_prev;
X }
X}
X
X/* This is used to garbage collect the chunks of lines when malloc fails
X and we are NOT looking for a new buffer line. This goes through each
X chunk, and if every line in a given chunk is not allocated, the entire
X chunk is `free'd by "free()". */
X
XGCchunks()
X{
X register struct chunk *cp;
X struct chunk *prev = 0,
X *next = 0;
X register int i;
X register Line *newline;
X
X for (cp = fchunk; cp != 0; cp = next) {
X for (i = 0, newline = cp->c_block; i < cp->c_nlines; newline++, i++)
X if (newline->l_dline != 0)
X break;
X
X next = cp->c_nextfree;
X
X if (i == cp->c_nlines) { /* Unlink it!!! */
X if (prev)
X prev->c_nextfree = cp->c_nextfree;
X else
X fchunk = cp->c_nextfree;
X remfreelines(cp);
X free((char *) cp->c_block);
X free((char *) cp);
X } else
X prev = cp;
X }
X}
X
X#ifdef LISP
X
X/* Grind S-Expr */
X
XGSexpr()
X{
X Bufpos dot,
X end;
X
X if (linebuf[curchar] != '(')
X complain((char *) 0);
X DOTsave(&dot);
X FSexpr();
X DOTsave(&end);
X exp = 1;
X SetDot(&dot);
X for (;;) {
X if (curline == end.p_line)
X break;
X line_move(FORWARD, NO);
X if (!blnkp(linebuf))
X (void) lisp_indent();
X }
X SetDot(&dot);
X}
X
X/* lisp_indent() indents a new line in Lisp Mode, according to where
X the matching close-paren would go if we typed that (sort of). */
X
Xprivate Table *specials = NIL;
X
Xprivate
Xinit_specials()
X{
X static char *words[] = {
X "case",
X "def",
X "dolist",
X "fluid-let",
X "lambda",
X "let",
X "lexpr",
X "macro",
X "named-l", /* named-let and named-lambda */
X "nlambda",
X "prog",
X "selectq",
X 0
X };
X char **wordp = words;
X
X specials = make_table();
X while (*wordp)
X add_word(*wordp++, specials);
X}
X
XAddSpecial()
X{
X char *word;
X
X word = ask((char *) 0, ProcFmt);
X if (specials == NIL)
X init_specials();
X add_word(copystr(word), specials);
X}
X
XBufpos *
Xlisp_indent()
X{
X Bufpos *bp,
X savedot;
X int goal;
X
X bp = m_paren(')', BACKWARD, NO, YES);
X
X if (bp == 0)
X return 0;
X
X /* We want to end up
X
X (atom atom atom ...
X ^ here.
X */
X
X DOTsave(&savedot);
X SetDot(bp);
X DoTimes(ForChar(), 1);
X if (linebuf[curchar] != '(') {
X register Word *wp;
X
X if (specials == NIL)
X init_specials();
X for (wp = table_top(specials); wp != NIL; wp = next_word(wp))
X if (casencmp(word_text(wp), &linebuf[curchar], word_length(wp)) == 0)
X break;
X if (wp == NIL) { /* not special */
X int c_char = curchar;
X
X WITH_TABLE(curbuf->b_major)
X ForWord();
X END_TABLE();
X if (LookingAt("[ \t]*;\\|[ \t]*$", linebuf, curchar))
X curchar = c_char;
X else while (linebuf[curchar] == ' ')
X curchar++;
X } else
X curchar++;
X }
X goal = calc_pos(linebuf, curchar);
X SetDot(&savedot);
X n_indent(goal);
X
X return bp;
X}
X#endif LISP
@//E*O*F insert.c//
if test 13582 -ne "`wc -c <'insert.c'`"; then
echo shar: error transmitting "'insert.c'" '(should have been 13582 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'table.c'" '(1122 characters)'
if test -f 'table.c' ; then
echo shar: will not over-write existing file "'table.c'"
else
sed 's/^X//' >table.c <<'@//E*O*F table.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#include "table.h"
X
Xprivate Table *tables = NIL;
X
XTable *
Xmake_table()
X{
X Table *tab = (Table *) emalloc(sizeof *tab);
X
X tab->t_next = tables;
X tables = tab;
X tab->t_wordlist = NIL;
X
X return tab;
X}
X
XWord *
Xword_in_table(text, table)
Xchar *text;
XTable *table;
X{
X register Word *w;
X
X for (w = table_top(table); w != NIL; w = next_word(w))
X if (strcmp(word_text(w), text) == 0)
X break; /* already in list */
X return w;
X}
X
Xadd_word(wname, table)
Xchar *wname;
XTable *table;
X{
X register Word *w;
X
X if (w = word_in_table(wname, table))
X return;
X w = (Word *) emalloc(sizeof *w);
X word_text(w) = wname;
X next_word(w) = table_top(table);
X table_top(table) = w;
X}
@//E*O*F table.c//
if test 1122 -ne "`wc -c <'table.c'`"; then
echo shar: error transmitting "'table.c'" '(should have been 1122 characters)'
fi
fi # end of overwriting check
echo shar: "End of archive 3 (of 13)."
cp /dev/null ark3isdone
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