sources-request@mirror.UUCP (02/04/87)
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