v14i066: Jove, an emacs variant, version 4.9, Part10/21
Rich Salz
rsalz at bbn.com
Wed Apr 27 02:40:04 AEST 1988
Submitted-by: Jonathan Payne <jpayne at cs.rochester.edu>
Posting-number: Volume 14, Issue 66
Archive-name: jove4.9/part10
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 10 (of 21)."
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f './extend.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'./extend.c'\"
else
echo shar: Extracting \"'./extend.c'\" \(19914 characters\)
sed "s/^X//" >'./extend.c' <<'END_OF_FILE'
X/***************************************************************************
X * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
X * is provided to you without charge, and with no warranty. You may give *
X * away copies of JOVE, including sources, provided that this notice is *
X * included in all the files. *
X ***************************************************************************/
X
X#include "jove.h"
X#include "io.h"
X#include "termcap.h"
X#include "ctype.h"
X#ifdef JOB_CONTROL
X# include <signal.h>
X#endif
X
X#ifdef MAC
X# include "mac.h"
X#else
X# include <varargs.h>
X#endif
X
X#ifdef MSDOS
X#include <process.h>
X#endif
X
X#ifdef MAC
X# undef private
X# define private
X#endif
X
X#ifdef LINT_ARGS
private void
X fb_aux(data_obj *, data_obj **, char *, char *),
X find_binds(data_obj *, char *),
X vpr_aux(struct variable *, char *);
X#else
private void
X fb_aux(),
X find_binds(),
X vpr_aux();
X#endif /* LINT_ARGS */
X
X#ifdef MAC
X# undef private
X# define private static
X#endif
X
X
int InJoverc = 0;
X
extern int getch(),
X getchar();
X
X/* Auto execute code */
X
X#define NEXECS 20
X
private struct {
X char *a_pattern;
X data_obj *a_cmd;
X} AutoExecs[NEXECS] = {0};
X
private int ExecIndex = 0;
X
X/* Command auto-execute. */
X
void
CAutoExec()
X{
X DefAutoExec(findcom);
X}
X
X/* Macro auto-execute. */
X
void
MAutoExec()
X{
X DefAutoExec(findmac);
X}
X
X/* VARARGS0 */
X
void
DefAutoExec(proc)
X#ifdef LINT_ARGS
data_obj *(*proc)();
X#else
data_obj *(*proc)();
X#endif
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 = do_ask("\r\n", (int (*)()) 0, (char *) 0, ": %f %s ", d->Name);
X if (pattern != 0)
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 += 1;
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, OR if the pattern is 0 (none was specified) then, we execute
X the command associated with that kind of file. */
X
void
DoAutoExec(new, old)
register char *new,
X *old;
X{
X register int i;
X
X set_arg_value(1);
X for (i = 0; i < ExecIndex; i++)
X if ((AutoExecs[i].a_pattern == 0) ||
X ((new != 0 && 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
void
BindAKey()
X{
X BindSomething(findcom);
X}
X
void
BindMac()
X{
X BindSomething(findmac);
X}
X
extern void EscPrefix(),
X CtlxPrefix(),
X MiscPrefix();
X
data_obj **
IsPrefix(cp)
data_obj *cp;
X{
X#ifdef MAC
X void (*proc)();
X#else
X int (*proc)();
X#endif
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
void
UnbindC()
X{
X char *keys;
X data_obj **map = mainmap;
X
X keys = ask((char *) 0, ProcFmt);
X for (;;) {
X if (keys[1] == '\0')
X break;
X if ((map = IsPrefix(map[*keys])) == 0)
X break;
X keys += 1;
X }
X if (keys[1] != 0)
X complain("That's not a legitimate key sequence.");
X map[keys[0]] = 0;
X}
X
int
addgetc()
X{
X int c;
X
X if (!InJoverc) {
X Asking = strlen(mesgbuf);
X c = getch();
X Asking = 0;
X add_mess("%p ", c);
X } else {
X c = getch();
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 = CTL(c);
X else
X complain("[Unknown control character]");
X }
X }
X return c;
X}
X
void
BindWMap(map, lastkey, cmd)
data_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#ifdef MAC
X ((struct cmd *) cmd)->c_key = c; /* see about_j() in mac.c */
X if(map == mainmap) ((struct cmd *) cmd)->c_map = F_MAINMAP;
X else if(map == pref1map) ((struct cmd *) cmd)->c_map = F_PREF1MAP;
X else if(map == pref2map) ((struct cmd *) cmd)->c_map = F_PREF2MAP;
X#endif
X }
X }
X}
X
X/* VARARGS0 */
X
void
BindSomething(proc)
X#ifdef LINT_ARGS
data_obj *(*proc)();
X#else
data_obj *(*proc)();
X#endif
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
void
DescWMap(map, key)
data_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
void
KeyDesc()
X{
X s_mess(ProcFmt);
X DescWMap(mainmap, addgetc());
X}
X
void
DescCom()
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 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);
outahere:
X f_close(fp);
X TOstop();
X}
X
void
DescBindings()
X{
X extern void Typeout();
X
X TOstart("Key Bindings", TRUE);
X DescMap(mainmap, NullStr);
X TOstop();
X}
X
extern int specialmap;
X
void
DescMap(map, pref)
data_obj **map;
char *pref;
X{
X int c1,
X c2 = 0,
X numbetween;
X char keydescbuf[40];
X data_obj **prefp;
X
X#ifdef IBMPC
X specialmap = (map == miscmap);
X#endif
X
X for (c1 = 0; c1 < NCHARS && c2 < NCHARS; c1 = c2 + 1) {
X c2 = c1;
X if (map[c1] == 0)
X continue;
X while (++c2 < NCHARS && map[c1] == map[c2])
X ;
X c2 -= 1;
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])) && (prefp != map))
X DescMap(prefp, keydescbuf);
X else
X Typeout("%-18s%s", keydescbuf, map[c1]->Name);
X }
X}
X
private void
find_binds(dp, buf)
data_obj *dp;
char *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
private void
fb_aux(cp, map, prefix, buf)
register data_obj *cp,
X **map;
char *buf,
X *prefix;
X{
X int c1,
X c2;
X char *bufp = buf + strlen(buf),
X prefbuf[20];
X data_obj **prefp;
X
X#ifdef IBMPC
X specialmap = (map == miscmap);
X#endif
X
X for (c1 = c2 = 0; c1 < NCHARS && c2 < NCHARS; c1 = c2 + 1) {
X c2 = c1;
X if (map[c1] == cp) {
X while (++c2 < NCHARS && map[c1] == map[c2])
X ;
X c2 -= 1;
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])) && (prefp != map)) {
X sprintf(prefbuf, "%p", c1);
X fb_aux(cp, prefp, prefbuf, bufp);
X }
X bufp += strlen(bufp);
X }
X}
X
void
Apropos()
X{
X register struct cmd *cp;
X register struct macro *m;
X register struct variable *v;
X char *ans;
X int anyfs = NO,
X anyvs = NO,
X anyms = NO;
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 = YES;
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 = YES;
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 = YES;
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
void
Extend()
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
int
chr_to_int(cp, base, allints, result)
register char *cp;
register int *result;
X{
X register int c;
X int value = 0,
X sign;
X
X if ((c = *cp) == '-') {
X sign = -1;
X cp += 1;
X } else
X sign = 1;
X while (c = *cp++) {
X if (!isdigit(c)) {
X if (allints == YES)
X return INT_BAD;
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 *result = value * sign;
X return INT_OKAY;
X}
X
int
ask_int(prompt, base)
char *prompt;
int base;
X{
X char *val = ask((char *) 0, prompt);
X int value;
X
X if (chr_to_int(val, base, YES, &value) == INT_BAD)
X complain("That's not a number!");
X return value;
X}
X
private void
vpr_aux(vp, buf)
register struct variable *vp;
char *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
void
PrVar()
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
void
SetVar()
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#ifdef MAC
X MarkVar(vp,-1,0); /* mark the menu item */
X#endif
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 = YES;
X if (vp->v_flags & V_CLRSCREEN) {
X#ifdef IBMPC
X setcolor(Fgcolor, Bgcolor);
X#endif /* IBMPC */
X ClAndRedraw();
X }
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
private char **Possible;
private int comp_value,
X comp_flags;
X
int
aux_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 (defined(IBMPC) || defined(MAC))
X lower(lp);
X#else
X if (isupper(*lp))
X *lp = tolower(*lp);
X#endif
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) {
X comp_value = command;
X return 0;
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 += 1;
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
int
complete(possible, prompt, flags)
register char *possible[];
char *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
int
match(choices, what)
register 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 += 1; /* 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
void
Source()
X{
X char *com, *getenv(),
X buf[FILESIZE];
X
X#ifndef MSDOS
X sprintf(buf, "%s/.joverc", getenv("HOME"));
X#else /* MSDOS */
X if (com = getenv("JOVERC"))
X strcpy(buf, com);
X else
X strcpy(buf, Joverc);
X#endif /* MSDOS */
X com = ask_file((char *) 0, buf, buf);
X if (joverc(buf) == 0)
X complain(IOerr("read", com));
X}
X
void
BufPos()
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/%d, char %D/%D (%d%%), cursor = %d/%d]",
X filename(curbuf), dotline, i, dotchar, nchars,
X (nchars == 0) ? 100 : (int) (((long) dotchar * 100) / nchars),
X calc_pos(linebuf, curchar),
X calc_pos(linebuf, strlen(linebuf)));
X}
X
X#define IF_UNBOUND -1
X#define IF_TRUE 1
X#define IF_FALSE !IF_TRUE
X
X#ifndef MAC
int
do_if(cmd)
char *cmd;
X{
X#ifdef MSDOS
X int status;
X#else
X int pid,
X status;
X#endif /* MSDOS */
X#ifndef MSDOS
X
X switch (pid = fork()) {
X case -1:
X complain("[Fork failed: if]");
X
X case 0:
X {
X#endif /* MSDOS */
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#ifndef MSDOS
X close(0); /* we want reads to fail */
X /* close(1); but not writes or ioctl's
X close(2); */
X#else /* MSDOS */
X if ((status = spawnvp(0, args[0], args)) < 0)
X complain("[Spawn failed: if]");
X#endif /* MSDOS */
X
X#ifndef MSDOS
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#endif /* MSDOS */
X return (status == 0); /* 0 means successful */
X}
X#endif /* MAC */
X
int
joverc(file)
char *file;
X{
X char buf[LBSIZE],
X lbuf[LBSIZE];
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 NO; /* joverc returns an integer */
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 InJoverc += 1;
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, YES), lnum, lbuf, mesgbuf), NO);
X unmodify();
X SetBuf(savebuf);
X Asking = 0;
X }
X if (!eof) do {
X eof = (f_gets(fp, lbuf, sizeof lbuf) == EOF);
X lnum += 1;
X if (lbuf[0] == '#') /* a comment */
X continue;
X#ifndef MAC
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#endif
X if (IfStatus == IF_FALSE)
X continue;
X (void) strcat(lbuf, "\n");
X Inputp = lbuf;
X while (*Inputp == ' ' || *Inputp == '\t')
X Inputp += 1; /* 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 -= 1;
X if (IfStatus != IF_UNBOUND)
X complain("[Missing endif]");
X return 1;
X}
END_OF_FILE
if test 19914 -ne `wc -c <'./extend.c'`; then
echo shar: \"'./extend.c'\" unpacked with wrong size!
fi
# end of './extend.c'
fi
if test -f './re.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'./re.c'\"
else
echo shar: Extracting \"'./re.c'\" \(18437 characters\)
sed "s/^X//" >'./re.c' <<'END_OF_FILE'
X/***************************************************************************
X * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
X * is provided to you without charge, and with no warranty. You may give *
X * away copies of JOVE, including sources, provided that this notice is *
X * included in all the files. *
X ***************************************************************************/
X
X/* search package */
X
X#include "jove.h"
X#include "ctype.h"
X#ifdef MAC
X# undef private
X# define private
X#endif
X
X#ifdef LINT_ARGS
private char * insert(char *, char *, int);
X
private void
X REreset(void),
X search(int, int, int);
private int
X backref(int, char *),
X do_comp(int),
X member(char *, int, int),
X REgetc(void),
X REmatch(char *, char *);
X#else
private char * insert();
X
private void
X REreset(),
X search();
private int
X backref(),
X do_comp(),
X member(),
X REgetc(),
X REmatch();
X#endif /* LINT_ARGS */
X
X#ifdef MAC
X# undef private
X# define private static
X#endif
X
X#define NALTS 16 /* number of alternate search strings */
X
char searchstr[128],
X compbuf[256], /* global default compbuf */
X rep_search[128], /* replace search string */
X rep_str[128], /* contains replacement string */
X *cur_compb, /* usually points at compbuf */
X REbuf[LBSIZE], /* points at line we're scanning */
X *alternates[NALTS];
X
int REdirection;
X
int CaseIgnore = 0,
X WrapScan = 0,
X UseRE = 0;
X
X#define cind_cmp(a, b) (CaseEquiv[a] == CaseEquiv[b])
X
private int REpeekc;
private char *REptr;
X
private int
REgetc()
X{
X int c;
X
X if ((c = REpeekc) != -1)
X REpeekc = -1;
X else if (*REptr)
X c = *REptr++;
X else
X c = 0;
X
X return c;
X}
X
X#define STAR 01 /* Match any number of last RE. */
X#define AT_BOL 2 /* ^ */
X#define AT_EOL 4 /* $ */
X#define AT_BOW 6 /* \< */
X#define AT_EOW 8 /* \> */
X#define OPENP 10 /* \( */
X#define CLOSEP 12 /* \) */
X#define CURLYB 14 /* \{ */
X
X#define NOSTR 14 /* Codes <= NOSTR can't be *'d. */
X
X#define ANYC NOSTR+2 /* . */
X#define NORMC ANYC+2 /* normal character */
X#define CINDC NORMC+2 /* case independent character */
X#define ONE_OF CINDC+2 /* [xxx] */
X#define NONE_OF ONE_OF+2 /* [^xxx] */
X#define BACKREF NONE_OF+2 /* \# */
X#define EOP BACKREF+2 /* end of pattern */
X
X#define NPAR 10 /* [0-9] - 0th is the entire matched string, i.e. & */
private int nparens;
private char *comp_p,
X *start_p,
X **alt_p,
X **alt_endp;
X
void
REcompile(pattern, re, into_buf, alt_bufp)
char *pattern,
X *into_buf,
X **alt_bufp;
X{
X REptr = pattern;
X REpeekc = -1;
X comp_p = cur_compb = start_p = into_buf;
X alt_p = alt_bufp;
X alt_endp = alt_p + NALTS;
X *alt_p++ = comp_p;
X nparens = 0;
X (void) do_comp(re ? OKAY_RE : NORM);
X *alt_p = 0;
X}
X
X/* compile the pattern into an internal code */
X
private int
do_comp(kind)
X{
X char *last_p,
X *chr_cnt = 0;
X int parens[NPAR],
X *parenp,
X c,
X ret_code;
X
X parenp = parens;
X last_p = 0;
X ret_code = 1;
X
X if (kind == OKAY_RE) {
X *comp_p++ = OPENP;
X *comp_p++ = nparens;
X *parenp++ = nparens++;
X start_p = comp_p;
X }
X
X while (c = REgetc()) {
X if (comp_p > &cur_compb[(sizeof compbuf) - 6])
toolong: complain("Search string too long/complex.");
X if (c != '*')
X last_p = comp_p;
X
X if (kind == NORM && index(".[*", c) != 0)
X goto defchar;
X switch (c) {
X case '\\':
X switch (c = REgetc()) {
X case 0:
X complain("Premature end of pattern.");
X
X case '{':
X {
X char *wcntp; /* word count */
X
X *comp_p++ = CURLYB;
X wcntp = comp_p;
X *comp_p++ = 0;
X for (;;) {
X int comp_val;
X char *comp_len;
X
X comp_len = comp_p++;
X comp_val = do_comp(IN_CB);
X *comp_len = comp_p - comp_len;
X (*wcntp) += 1;
X if (comp_val == 0)
X break;
X }
X break;
X }
X
X case '}':
X if (kind != IN_CB)
X complain("Unexpected \}.");
X ret_code = 0;
X goto outahere;
X
X case '(':
X if (nparens >= NPAR)
X complain("Too many ('s; max is %d.", NPAR);
X *comp_p++ = OPENP;
X *comp_p++ = nparens;
X *parenp++ = nparens++;
X break;
X
X case ')':
X if (parenp == parens)
X complain("Too many )'s.");
X *comp_p++ = CLOSEP;
X *comp_p++ = *--parenp;
X break;
X
X case '|':
X if (alt_p >= alt_endp)
X complain("Too many alternates; max %d.", NALTS);
X *comp_p++ = CLOSEP;
X *comp_p++ = *--parenp;
X *comp_p++ = EOP;
X *alt_p++ = comp_p;
X nparens = 0;
X *comp_p++ = OPENP;
X *comp_p++ = nparens;
X *parenp++ = nparens++;
X start_p = comp_p;
X break;
X
X case '1':
X case '2':
X case '3':
X case '4':
X case '5':
X case '6':
X case '7':
X case '8':
X case '9':
X *comp_p++ = BACKREF;
X *comp_p++ = c - '0';
X break;
X
X case '<':
X *comp_p++ = AT_BOW;
X break;
X
X case '>':
X *comp_p++ = AT_EOW;
X break;
X
X default:
X goto defchar;
X }
X break;
X
X case ',':
X if (kind != IN_CB)
X goto defchar;
X goto outahere;
X
X case '.':
X *comp_p++ = ANYC;
X break;
X
X case '^':
X if (comp_p == start_p) {
X *comp_p++ = AT_BOL;
X break;
X }
X goto defchar;
X
X case '$':
X if ((REpeekc = REgetc()) != 0 && REpeekc != '\\')
X goto defchar;
X *comp_p++ = AT_EOL;
X break;
X
X case '[':
X {
X int chrcnt;
X
X *comp_p++ = ONE_OF;
X if (comp_p + 16 >= &cur_compb[(sizeof compbuf)])
X goto toolong;
X bzero(comp_p, 16);
X if ((REpeekc = REgetc()) == '^') {
X *last_p = NONE_OF;
X /* Get it for real this time. */
X (void) REgetc();
X }
X chrcnt = 1;
X while ((c = REgetc()) != ']' && c != 0) {
X if (c == '\\')
X c = REgetc();
X else if ((REpeekc = REgetc()) == '-') {
X int c2;
X
X (void) REgetc(); /* reread '-' */
X c2 = REgetc();
X while (c < c2) {
X comp_p[c/8] |= (1 << (c%8));
X c += 1;
X }
X }
X comp_p[c/8] |= (1 << (c%8));
X chrcnt += 1;
X }
X if (c == 0)
X complain("Missing ].");
X if (chrcnt == 1)
X complain("Empty [].");
X comp_p += 16;
X break;
X }
X
X case '*':
X if (last_p == 0 || *last_p <= NOSTR)
X goto defchar;
X
X /* The * operator applies only to the previous
X character. If we were building a chr_cnt at
X the time we got the *, we have to remove the
X last character from the chr_cnt (by decrementing
X *chr_cnt) and replacing it with a new STAR entry.
X
X If we are decrementing the count to 0, we just
X delete the chr_cnt entry altogether, replacing
X it with the STAR entry. */
X
X if (chr_cnt) {
X char lastc = chr_cnt[*chr_cnt];
X
X /* The * operator applies only to the previous
X character. If we were building a chr_cnt at
X the time we got the *, we have to remove the
X last character from the chr_cnt (by decrementing
X *chr_cnt) and replacing it with a new STAR entry.
X
X If we are decrementing the count to 0, we just
X delete the chr_cnt entry altogether, replacing
X it with the STAR entry. */
X
X if (*chr_cnt == 1) {
X comp_p = chr_cnt;
X comp_p[-1] |= STAR;
X *comp_p++ = lastc;
X } else {
X comp_p = chr_cnt + *chr_cnt;
X (*chr_cnt) -= 1;
X *comp_p++ = chr_cnt[-1] | STAR;
X *comp_p++ = lastc;
X }
X } else
X *last_p |= STAR;
X break;
X default:
defchar: if (chr_cnt)
X (*chr_cnt) += 1;
X else {
X *comp_p++ = (CaseIgnore) ? CINDC : NORMC;
X chr_cnt = comp_p++;
X *chr_cnt = 1; /* last_p[1] = 1; */
X }
X *comp_p++ = c;
X continue;
X }
X chr_cnt = FALSE;
X }
outahere:
X /* End of pattern, let's do some error checking. */
X if (kind == OKAY_RE) {
X *comp_p++ = CLOSEP;
X *comp_p++ = *--parenp;
X }
X if (parenp != parens)
X complain("Unmatched ()'s.");
X if (kind == IN_CB && c == 0) /* End of pattern with \}. */
X complain("Missing \}.");
X *comp_p++ = EOP;
X
X return ret_code;
X}
X
private char *pstrtlst[NPAR], /* index into REbuf */
X *pendlst[NPAR],
X *REbolp,
X *locs,
X *loc1,
X *loc2;
X
int REbom,
X REeom, /* beginning and end of match */
X REalt_num; /* if alternatives, which one matched? */
X
private int
backref(n, linep)
register char *linep;
X{
X register char *backsp,
X *backep;
X
X backsp = pstrtlst[n];
X backep = pendlst[n];
X while (*backsp++ == *linep++)
X if (backsp >= backep)
X return 1;
X return 0;
X}
X
private int
member(comp_p, c, af)
register char *comp_p;
register int c,
X af;
X{
X if (c == 0)
X return 0; /* try to match EOL always fails */
X if (comp_p[c/8] & (1 << (c%8)))
X return af;
X return !af;
X}
X
private int
REmatch(linep, comp_p)
register char *linep,
X *comp_p;
X{
X char *first_p = linep;
X register int n;
X
X for (;;) switch (*comp_p++) {
X case NORMC:
X n = *comp_p++;
X while (--n >= 0)
X if (*linep++ != *comp_p++)
X return 0;
X continue;
X
X case CINDC: /* case independent comparison */
X n = *comp_p++;
X while (--n >= 0)
X if (!cind_cmp(*linep++, *comp_p++))
X return 0;
X continue;
X
X case EOP:
X loc2 = linep;
X REeom = (loc2 - REbolp);
X return 1; /* Success! */
X
X case AT_BOL:
X if (linep == REbolp)
X continue;
X return 0;
X
X case AT_EOL:
X if (*linep == 0)
X continue;
X return 0;
X
X case ANYC:
X if (*linep++ != 0)
X continue;
X return 0;
X
X case AT_BOW:
X if (ismword(*linep) && (linep == REbolp || !ismword(linep[-1])))
X continue;
X return 0;
X
X case AT_EOW:
X if ((*linep == 0 || !ismword(*linep)) &&
X (linep != REbolp && ismword(linep[-1])))
X continue;
X return 0;
X
X case ONE_OF:
X case NONE_OF:
X if (member(comp_p, *linep++, comp_p[-1] == ONE_OF)) {
X comp_p += 16;
X continue;
X }
X return 0;
X
X case OPENP:
X pstrtlst[*comp_p++] = linep;
X continue;
X
X case CLOSEP:
X pendlst[*comp_p++] = linep;
X continue;
X
X case BACKREF:
X if (pstrtlst[n = *comp_p++] == 0) {
X s_mess("\\%d was not specified.", n + 1);
X return 0;
X }
X if (backref(n, linep)) {
X linep += pendlst[n] - pstrtlst[n];
X continue;
X }
X return 0;
X
X case CURLYB:
X {
X int wcnt,
X any;
X
X wcnt = *comp_p++;
X any = 0;
X
X while (--wcnt >= 0) {
X if (any == 0)
X any = REmatch(linep, comp_p + 1);
X comp_p += *comp_p;
X }
X if (any == 0)
X return 0;
X linep = loc2;
X continue;
X }
X
X case ANYC | STAR:
X first_p = linep;
X while (*linep++)
X ;
X goto star;
X
X case NORMC | STAR:
X first_p = linep;
X while (*comp_p == *linep++)
X ;
X comp_p += 1;
X goto star;
X
X case CINDC | STAR:
X first_p = linep;
X while (cind_cmp(*comp_p, *linep++))
X ;
X comp_p += 1;
X goto star;
X
X case ONE_OF | STAR:
X case NONE_OF | STAR:
X first_p = linep;
X while (member(comp_p, *linep++, comp_p[-1] == (ONE_OF | STAR)))
X ;
X comp_p += 16;
X goto star;
X
X case BACKREF | STAR:
X first_p = linep;
X n = *comp_p++;
X while (backref(n, linep))
X linep += pendlst[n] - pstrtlst[n];
X while (linep >= first_p) {
X if (REmatch(linep, comp_p))
X return 1;
X linep -= pendlst[n] - pstrtlst[n];
X }
X continue;
X
star: do {
X linep -= 1;
X if (linep < locs)
X break;
X if (REmatch(linep, comp_p))
X return 1;
X } while (linep > first_p);
X return 0;
X
X default:
X complain("RE error match (%d).", comp_p[-1]);
X }
X /* NOTREACHED. */
X}
X
private void
REreset()
X{
X register int i;
X
X for (i = 0; i < NPAR; i++)
X pstrtlst[i] = pendlst[i] = 0;
X}
X
X/* Index LINE at OFFSET, the compiled EXPR, with alternates ALTS. If
X lbuf_okay is nonzero it's okay to use linebuf if LINE is the current
X line. This should save lots of time in things like paren matching in
X LISP mode. Saves all that copying from linebuf to REbuf. substitute()
X is the guy who calls re_lindex with lbuf_okay as 0, since the substitution
X gets placed in linebuf ... doesn't work too well when the source and
X destination strings are the same. I hate all these arguments!
X
X This code is cumbersome, repetetive for reasons of efficiency. Fast
X search is a must as far as I am concerned. */
X
int
re_lindex(line, offset, expr, alts, lbuf_okay)
Line *line;
char *expr,
X **alts;
X{
X int isquick;
X register int firstc,
X c;
X register char *resp;
X
X REreset();
X if (lbuf_okay) {
X REbolp = lbptr(line);
X if (offset == -1)
X offset = strlen(REbolp); /* arg! */
X } else {
X REbolp = ltobuf(line, REbuf);
X if (offset == -1) { /* Reverse search, find end of line. */
X extern int Jr_Len;
X
X offset = Jr_Len; /* Just Read Len. */
X }
X }
X resp = REbolp;
X isquick = ((expr[0] == NORMC || expr[0] == CINDC) &&
X (alternates[1] == 0));
X if (isquick) {
X firstc = expr[2];
X if (expr[0] == CINDC)
X firstc = CaseEquiv[firstc];
X }
X locs = REbolp + offset;
X
X if (REdirection == FORWARD) {
X do {
X char **altp = alts;
X
X if (isquick) {
X if (expr[0] == NORMC)
X while ((c = *locs++) != 0 && c != firstc)
X ;
X else
X while (((c = *locs++) != 0) &&
X (CaseEquiv[c] != firstc))
X ;
X if (*--locs == 0)
X break;
X }
X REalt_num = 1;
X while (*altp) {
X if (REmatch(locs, *altp++)) {
X loc1 = locs;
X REbom = loc1 - REbolp;
X return 1;
X }
X REalt_num += 1;
X }
X } while (*locs++);
X } else {
X do {
X char **altp = alts;
X
X if (isquick) {
X if (expr[0] == NORMC) {
X while (locs >= REbolp && *locs-- != firstc)
X ;
X if (*++locs != firstc)
X break;
X } else {
X while (locs >= REbolp && CaseEquiv[*locs--] != firstc)
X ;
X if (CaseEquiv[*++locs] != firstc)
X break;
X }
X }
X REalt_num = 1;
X while (*altp) {
X if (REmatch(locs, *altp++)) {
X loc1 = locs;
X REbom = loc1 - REbolp;
X return 1;
X }
X REalt_num += 1;
X }
X } while (--locs >= resp);
X }
X
X return 0;
X}
X
int okay_wrap = 0; /* Do a wrap search ... not when we're
X parsing errors ... */
X
Bufpos *
dosearch(pattern, dir, re)
char *pattern;
X{
X Bufpos *pos;
X
X if (bobp() && eobp()) /* Can't match! There's no buffer. */
X return 0;
X
X REcompile(pattern, re, compbuf, alternates);
X
X pos = docompiled(dir, compbuf, alternates);
X return pos;
X}
X
Bufpos *
docompiled(dir, expr, alts)
char *expr,
X **alts;
X{
X static Bufpos ret;
X register Line *lp;
X register int offset;
X int we_wrapped = NO;
X
X lsave();
X /* Search now lsave()'s so it doesn't make any assumptions on
X whether the the contents of curline/curchar are in linebuf.
X Nowhere does search write all over linebuf. However, we have to
X be careful about what calls we make here, because many of them
X assume (and rightly so) that curline is in linebuf. */
X
X REdirection = dir;
X lp = curline;
X offset = curchar;
X if (dir == BACKWARD) {
X if (bobp()) {
X if (okay_wrap && WrapScan)
X goto doit;
X return 0;
X }
X /* here we simulate BackChar() */
X if (bolp()) {
X lp = lp->l_prev;
X offset = strlen(lbptr(lp));
X } else
X offset -= 1;
X } else if ((dir == FORWARD) &&
X (lbptr(lp)[offset] == '\0') &&
X !lastp(lp)) {
X lp = lp->l_next;
X offset = 0;
X }
X
X do {
X if (re_lindex(lp, offset, expr, alts, YES))
X break;
doit: lp = (dir == FORWARD) ? lp->l_next : lp->l_prev;
X if (lp == 0) {
X if (okay_wrap && WrapScan) {
X lp = (dir == FORWARD) ?
X curbuf->b_first : curbuf->b_last;
X we_wrapped = YES;
X } else
X break;
X }
X if (dir == FORWARD)
X offset = 0;
X else
X offset = -1; /* signals re_lindex ... */
X } while (lp != curline);
X
X if (lp == curline && we_wrapped)
X lp = 0;
X if (lp == 0)
X return 0;
X ret.p_line = lp;
X ret.p_char = (dir == FORWARD) ? REeom : REbom;
X return &ret;
X}
X
private char *
insert(off, endp, which)
char *off,
X *endp;
X{
X register char *pp;
X register int n;
X
X n = pendlst[which] - pstrtlst[which];
X pp = pstrtlst[which];
X while (--n >= 0) {
X *off++ = *pp++;
X if (off >= endp)
X len_error(ERROR);
X }
X return off;
X}
X
X/* Perform the substitution. If DELP is nonzero the matched string is
X deleted, i.e., the substitution string is not inserted. */
X
void
re_dosub(tobuf, delp)
char *tobuf;
X{
X register char *tp,
X *rp,
X *repp;
X int c;
X char *endp;
X
X tp = tobuf;
X endp = tp + LBSIZE;
X rp = REbuf;
X repp = rep_str;
X
X while (rp < loc1)
X *tp++ = *rp++;
X
X if (!delp) while (c = *repp++) {
X if (c == '\\') {
X c = *repp++;
X if (c == '\0') {
X *tp++ = '\\';
X goto endchk;
X } else if (c >= '1' && c <= nparens + '1') {
X tp = insert(tp, endp, c - '0');
X continue;
X }
X } else if (c == '&') {
X tp = insert(tp, endp, 0);
X continue;
X }
X *tp++ = c;
endchk: if (tp >= endp)
X len_error(ERROR);
X }
X rp = loc2;
X loc2 = REbuf + max(1, tp - tobuf);
X REeom = loc2 - REbuf;
X /* At least one character past the match, to prevent an infinite
X number of replacements in the same position, e.g.,
X replace "^" with "". */
X while (*tp++ = *rp++)
X if (tp >= endp)
X len_error(ERROR);
X}
X
void
putmatch(which, buf, size)
char *buf;
X{
X *(insert(buf, buf + size, which)) = 0;
X}
X
void
setsearch(str)
char *str;
X{
X strcpy(searchstr, str);
X}
X
char *
getsearch()
X{
X return searchstr;
X}
X
void
RErecur()
X{
X char sbuf[sizeof searchstr],
X cbuf[sizeof compbuf],
X repbuf[sizeof rep_str],
X *altbuf[NALTS];
X int npars;
X Mark *m = MakeMark(curline, REbom, M_FLOATER);
X
X message("Type C-X C-C to continue with query replace.");
X
X npars = nparens;
X byte_copy(compbuf, cbuf, sizeof compbuf);
X byte_copy(searchstr, sbuf, sizeof searchstr);
X byte_copy(rep_str, repbuf, sizeof rep_str);
X byte_copy((char *) alternates, (char *) altbuf, sizeof alternates);
X Recur();
X nparens = npars;
X byte_copy(cbuf, compbuf, sizeof compbuf);
X byte_copy(sbuf, searchstr, sizeof searchstr);
X byte_copy(repbuf, rep_str, sizeof rep_str);
X byte_copy((char *) altbuf, (char *) alternates, sizeof alternates);
X if (!is_an_arg())
X ToMark(m);
X DelMark(m);
X}
X
void
ForSearch()
X{
X search(FORWARD, UseRE, YES);
X}
X
void
RevSearch()
X{
X search(BACKWARD, UseRE, YES);
X}
X
void
FSrchND()
X{
X search(FORWARD, UseRE, NO);
X}
X
void
RSrchND()
X{
X search(BACKWARD, UseRE, NO);
X}
X
private void
search(dir, re, setdefault)
X{
X Bufpos *newdot;
X char *s;
X
X s = ask(searchstr, ProcFmt);
X if (setdefault)
X setsearch(s);
X okay_wrap = YES;
X newdot = dosearch(s, dir, re);
X okay_wrap = NO;
X if (newdot == 0) {
X if (WrapScan)
X complain("No \"%s\" in buffer.", s);
X else
X complain("No \"%s\" found to %s.", s,
X (dir == FORWARD) ? "bottom" : "top");
X }
X PushPntp(newdot->p_line);
X SetDot(newdot);
X}
X
X/* Do we match PATTERN at OFFSET in BUF? */
X
int
LookingAt(pattern, buf, offset)
char *pattern,
X *buf;
X{
X register char **alt = alternates;
X
X REcompile(pattern, 1, compbuf, alternates);
X REreset();
X locs = buf + offset;
X REbolp = buf;
X
X while (*alt)
X if (REmatch(locs, *alt++))
X return 1;
X return 0;
X}
X
int
look_at(expr)
char *expr;
X{
X REcompile(expr, 0, compbuf, alternates);
X REreset();
X locs = linebuf + curchar;
X REbolp = linebuf;
X if (REmatch(locs, alternates[0]))
X return 1;
X return 0;
X}
X
END_OF_FILE
if test 18437 -ne `wc -c <'./re.c'`; then
echo shar: \"'./re.c'\" unpacked with wrong size!
fi
# end of './re.c'
fi
echo shar: End of archive 10 \(of 21\).
cp /dev/null ark10isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 21 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
--
Please send comp.sources.unix-related mail to rsalz at uunet.uu.net.
More information about the Comp.sources.unix
mailing list