home *** CD-ROM | disk | FTP | other *** search
- From: pgf@cayman.COM (Paul Fox)
- Newsgroups: alt.sources
- Subject: Vile 06/17 - vi feel-alike (multi-window)
- Message-ID: <4525@cayman.COM>
- Date: 7 Jun 91 22:09:32 GMT
-
- #!/bin/sh
- # this is vileshar.06 (part 6 of Vile)
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file evar.h continued
- #
- if test ! -r _shar_seq_.tmp; then
- echo 'Please unpack part 1 first!'
- exit 1
- fi
- (read Scheck
- if test "$Scheck" != 6; then
- echo Please unpack part "$Scheck" next!
- exit 1
- else
- exit 0
- fi
- ) < _shar_seq_.tmp || exit 1
- echo 'x - continuing file evar.h'
- sed 's/^X//' << 'SHAR_EOF' >> 'evar.h' &&
- X
- /* list of recognized environment variables */
- X
- char *envars[] = {
- X "fillcol", /* current fill column */
- X "pagelen", /* number of lines used by editor */
- X "curcol", /* current column pos of cursor */
- X "curline", /* current line in file */
- X "ram", /* ram in use by malloc */
- X "flicker", /* flicker supression */
- X "curwidth", /* current screen width */
- X "cbufname", /* current buffer name */
- X "cfname", /* current file name */
- X "sres", /* current screen resolution */
- X "debug", /* macro debugging */
- X "status", /* returns the status of the last command */
- X "palette", /* current palette string */
- X "asave", /* # of chars between auto-saves */
- X "acount", /* # of chars until next auto-save */
- X "lastkey", /* last keyboard char struck */
- X "curchar", /* current character under the cursor */
- X "discmd", /* display commands on command line */
- X "version", /* current version number */
- X "progname", /* returns current prog name - "vile" */
- X "seed", /* current random number seed */
- X "disinp", /* display command line input characters */
- X "wline", /* # of lines in current window */
- X "cwline", /* current screen line in window */
- X "target", /* target for line moves */
- X "search", /* search pattern */
- X "replace", /* replacement pattern */
- X "match", /* last matched magic pattern */
- X "kill", /* kill buffer (read only) */
- X "cmode", /* mode of current buffer */
- X "gmode", /* global modes */
- X "tpause", /* length to pause for paren matching */
- X "pending", /* type ahead pending flag */
- X "lwidth", /* width of current line */
- X "line", /* text of current line */
- };
- X
- #define NEVARS sizeof(envars) / sizeof(char *)
- X
- /* and its preprocesor definitions */
- X
- #define EVFILLCOL 0
- #define EVPAGELEN 1
- #define EVCURCOL 2
- #define EVCURLINE 3
- #define EVRAM 4
- #define EVFLICKER 5
- #define EVCURWIDTH 6
- #define EVCBUFNAME 7
- #define EVCFNAME 8
- #define EVSRES 9
- #define EVDEBUG 10
- #define EVSTATUS 11
- #define EVPALETTE 12
- #define EVASAVE 13
- #define EVACOUNT 14
- #define EVLASTKEY 15
- #define EVCURCHAR 16
- #define EVDISCMD 17
- #define EVVERSION 18
- #define EVPROGNAME 19
- #define EVSEED 20
- #define EVDISINP 21
- #define EVWLINE 22
- #define EVCWLINE 23
- #define EVTARGET 24
- #define EVSEARCH 25
- #define EVREPLACE 26
- #define EVMATCH 27
- #define EVKILL 28
- #define EVCMODE 29
- #define EVGMODE 30
- #define EVTPAUSE 31
- #define EVPENDING 32
- #define EVLWIDTH 33
- #define EVLINE 34
- X
- /* list of recognized user functions */
- X
- typedef struct UFUNC {
- X char *f_name; /* name of function */
- X int f_type; /* 1 = monamic, 2 = dynamic */
- } UFUNC;
- X
- #define NILNAMIC 0
- #define MONAMIC 1
- #define DYNAMIC 2
- #define TRINAMIC 3
- X
- UFUNC funcs[] = {
- X "add", DYNAMIC, /* add two numbers together */
- X "sub", DYNAMIC, /* subtraction */
- X "tim", DYNAMIC, /* multiplication */
- X "div", DYNAMIC, /* division */
- X "mod", DYNAMIC, /* mod */
- X "neg", MONAMIC, /* negate */
- X "cat", DYNAMIC, /* concatinate string */
- X "lef", DYNAMIC, /* left string(string, len) */
- X "rig", DYNAMIC, /* right string(string, pos) */
- X "mid", TRINAMIC, /* mid string(string, pos, len) */
- X "not", MONAMIC, /* logical not */
- X "equ", DYNAMIC, /* logical equality check */
- X "les", DYNAMIC, /* logical less than */
- X "gre", DYNAMIC, /* logical greater than */
- X "seq", DYNAMIC, /* string logical equality check */
- X "sle", DYNAMIC, /* string logical less than */
- X "sgr", DYNAMIC, /* string logical greater than */
- X "ind", MONAMIC, /* evaluate indirect value */
- X "and", DYNAMIC, /* logical and */
- X "or", DYNAMIC, /* logical or */
- X "len", MONAMIC, /* string length */
- X "upp", MONAMIC, /* uppercase string */
- X "low", MONAMIC, /* lower case string */
- X "tru", MONAMIC, /* Truth of the universe logical test */
- X "asc", MONAMIC, /* char to integer conversion */
- X "chr", MONAMIC, /* integer to char conversion */
- X "gtk", NILNAMIC, /* get 1 charater */
- X "rnd", MONAMIC, /* get a random number */
- X "abs", MONAMIC, /* absolute value of a number */
- X "sin", DYNAMIC, /* find the index of one string in another */
- X "env", MONAMIC, /* retrieve a system environment var */
- X "bin", MONAMIC, /* loopup what function name is bound to a key */
- };
- X
- #define NFUNCS sizeof(funcs) / sizeof(UFUNC)
- X
- /* and its preprocesor definitions */
- X
- #define UFADD 0
- #define UFSUB 1
- #define UFTIMES 2
- #define UFDIV 3
- #define UFMOD 4
- #define UFNEG 5
- #define UFCAT 6
- #define UFLEFT 7
- #define UFRIGHT 8
- #define UFMID 9
- #define UFNOT 10
- #define UFEQUAL 11
- #define UFLESS 12
- #define UFGREATER 13
- #define UFSEQUAL 14
- #define UFSLESS 15
- #define UFSGREAT 16
- #define UFIND 17
- #define UFAND 18
- #define UFOR 19
- #define UFLENGTH 20
- #define UFUPPER 21
- #define UFLOWER 22
- #define UFTRUTH 23
- #define UFASCII 24
- #define UFCHR 25
- #define UFGTKEY 26
- #define UFRND 27
- #define UFABS 28
- #define UFSINDEX 29
- #define UFENV 30
- #define UFBIND 31
- X
- #endif
- SHAR_EOF
- echo 'File evar.h is complete' &&
- chmod 0444 evar.h ||
- echo 'restore of evar.h failed'
- Wc_c="`wc -c < 'evar.h'`"
- test 5247 -eq "$Wc_c" ||
- echo 'evar.h: original size 5247, current size' "$Wc_c"
- # ============= exec.c ==============
- echo 'x - extracting exec.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'exec.c' &&
- /* This file is for functions dealing with execution of
- X commands, command lines, buffers, files and startup files
- X
- X written 1986 by Daniel Lawrence */
- X
- #include <stdio.h>
- #include "estruct.h"
- #include "edef.h"
- X
- /* namedcmd: execute a named command even if it is not bound */
- X
- namedcmd(f, n)
- int f, n;
- {
- X char *fnp; /* ptr to the name of the cmd to exec */
- X LINE *fromline; /* first linespec */
- X LINE *toline; /* second linespec */
- X char lspec[NLINE];
- X int cpos = 0;
- X int s,c,isdfl,zero,flags;
- X char *kbd_engl();
- X CMDFUNC *cfp; /* function to execute */
- X extern CMDFUNC f_gomark;
- X
- X /* prompt the user to type a named command */
- X mlwrite(": ");
- X
- X /* and now get the function name to execute */
- #if NeWS
- X newsimmediateon() ;
- #endif
- X
- X while(1) {
- X c = tgetc();
- X if (c == '\r') {
- X lspec[cpos] = 0;
- X fnp = NULL;
- X break;
- X } else if (c == kcod2key(abortc)) { /* Bell, abort */
- X isabortc:
- X lspec[0] = '\0';
- X return FALSE;
- X } else if (isbackspace(c)) {
- X if (cpos != 0) {
- X TTputc('\b');
- X TTputc(' ');
- X TTputc('\b');
- X --ttcol;
- X --cpos;
- X } else {
- X lspec[0] = '\0';
- X lineinput = FALSE;
- X return FALSE;
- X }
- X
- X } else if (c == kcod2key(killc)) { /* ^U, kill */
- X iskillc:
- X while (cpos != 0) {
- X TTputc('\b');
- X TTputc(' ');
- X TTputc('\b');
- X --cpos;
- X --ttcol;
- X }
- X } else if (islinespecchar(c) ||
- X /* special test for 'a style mark references */
- X (cpos > 0 &&
- X lspec[cpos-1] == '\'' &&
- X (islower(c) || (c == '\'') )
- X )
- X ) {
- X lspec[cpos++] = c;
- X TTputc(c);
- X ++ttcol;
- X } else {
- X int status;
- X tungetc(c);
- X lspec[cpos] = 0;
- X status = kbd_engl_stat(&fnp);
- X if (status == TRUE) {
- X break;
- X } else if (status == SORTOFTRUE) {
- X fnp = NULL;
- X continue;
- X } else {
- X return status;
- X }
- X }
- X TTflush();
- X }
- X
- X /* parse the accumulated lspec */
- X if (rangespec(lspec,&fromline,&toline,&isdfl,&zero) != TRUE) {
- X mlwrite("[Improper line range]");
- X return FALSE;
- X }
- X
- X /* if range given, and it wasn't "0" and the buffer's empty */
- X if (!isdfl && !zero && (lforw(curbp->b_linep) == curbp->b_linep)) {
- X mlwrite("[No range possible in empty buffer]", fnp);
- X return FALSE;
- X }
- X
- #if NeWS
- X newsimmediateoff() ;
- #endif
- X
- X /* did we get a name? */
- X if (fnp == NULL) {
- X if (isdfl) { /* no range, no function */
- X mlwrite("[No such function]");
- X return FALSE;
- X } else { /* range, no function */
- X cfp = &f_gomark;
- X fnp = "";
- X }
- X } else if ((cfp = engl2fnc(fnp)) == NULL) { /* bad function */
- X mlwrite("[No such function %s]",fnp);
- X return FALSE;
- X }
- X flags = cfp->c_flags;
- X
- X /* bad arguments? */
- #ifdef EXRC_FILES
- seems like we need one more check here -- is it from a .exrc file?
- X cmd not ok in .exrc empty file
- X if (!(flags & EXRCOK) && (lforw(curbp->b_linep) == curbp->b_linep)) {
- X mlwrite("[Can't use the \"%s\" command in a %s file.]",
- X cmdnames[cmdidx].name, EXRC);
- X return FALSE;
- X }
- #endif
- X
- X /* was: if (!(flags & (ZERO | EXRCOK)) && fromline == NULL ) { */
- X if (zero) {
- X extern CMDFUNC f_lineputafter, f_opendown, f_insfile;
- X extern CMDFUNC f_lineputbefore, f_openup;
- X if (!(flags & ZERO)) {
- X mlwrite("[Can't use address 0 with \"%s\" command]", fnp);
- X return FALSE;
- X }
- X /* we're positioned at fromline == curbp->b_linep, so commands
- X must be willing to go _down_ from there. Seems easiest
- X to special case the commands that prefer going up */
- X if (cfp == &f_insfile) {
- X /* works okay -- acts down normally */
- X } else if (cfp == &f_lineputafter) {
- X cfp = &f_lineputbefore;
- X fromline = lforw(fromline);
- X } else if (cfp == &f_opendown) {
- X cfp = &f_openup;
- X fromline = lforw(fromline);
- X } else {
- X mlwrite("[Configuration error: ZERO]");
- X return FALSE;
- X }
- X flags = cfp->c_flags;
- X toline = fromline;
- X }
- X
- X /* if we're not supposed to have a line no., and the line no. isn't
- X the current line, and there's more than one line */
- X if (!(flags & FROM) && fromline != curwp->w_dotp &&
- X (lforw(curbp->b_linep) != curbp->b_linep) &&
- X (lforw(lforw(curbp->b_linep)) != curbp->b_linep) ) {
- X mlwrite("[Can't use address with \"%s\" command.]", fnp);
- X return FALSE;
- X }
- X /* if we're not supposed to have a second line no., and the line no.
- X isn't the same as the first line no., and there's more than
- X one line */
- X if (!(flags & TO) && toline != fromline &&
- X (lforw(curbp->b_linep) != curbp->b_linep) &&
- X (lforw(lforw(curbp->b_linep)) != curbp->b_linep) ) {
- X mlwrite("[Can't use a range with \"%s\" command.]", fnp);
- X return FALSE;
- X }
- #ifdef NEEDED
- X if (!(flags & EXTRA) && *scan) {
- X mlwrite("[Extra characters after \"%s\" command.]",
- X cmdnames[cmdidx].name);
- X return FALSE;
- X }
- #endif
- #ifdef NEEDED
- X if ((flags & NOSPC) && !(cmd == CMD_READ && (forceit || *scan == '!'))) {
- X build = scan;
- #ifndef CRUNCH /* what is this for? -pgf */
- X if ((flags & PLUS) && *build == '+') {
- X while (*build && !(isspace(*build))) {
- X build++;
- X }
- X while (*build && isspace(*build)) {
- X build++;
- X }
- X }
- #endif /* not CRUNCH */
- X for (; *build; build++) {
- X if (isspace(*build)) {
- X mlwrite("[Too many %s to \"%s\" command.]",
- X (flags & XFILE) ? "filenames" : "arguments",
- X cmdnames[cmdidx].name);
- X return FALSE;
- X }
- X }
- X }
- #endif /* NEEDED */
- X
- X /* some commands have special default ranges */
- X if (isdfl) {
- X if (flags & DFLALL) {
- X extern CMDFUNC f_operwrite, f_filewrite, f_operglobals,
- X f_globals, f_opervglobals, f_vglobals;
- X if (cfp == &f_operwrite) {
- X cfp = &f_filewrite;
- #if GLOBALS
- X } else if (cfp == &f_operglobals) {
- X cfp = &f_globals;
- X } else if (cfp == &f_opervglobals) {
- X cfp = &f_vglobals;
- #endif
- X } else {
- X mlwrite("[Configuration error: DFLALL]");
- X return FALSE;
- X }
- X } else if (flags & DFLNONE) {
- X extern CMDFUNC f_operfilter, f_spawn;
- X if (cfp == &f_operfilter) {
- X cfp = &f_spawn;
- X setmark(); /* not that it matters */
- X } else {
- X mlwrite("[Configuration error: DFLNONE]");
- X return FALSE;
- X }
- X fromline = toline = NULL;
- X }
- X }
- X
- #ifdef NEEDED
- X /* write a newline if called from visual mode */
- X if ((flags & NL) && !exmode /* && !exwrote */) {
- X TTputc('\n');
- X /* exrefresh(); */
- X }
- #endif
- X
- X if (toline || fromline) { /* assume it's an absolute motion */
- X /* we could probably do better */
- X curwp->w_ldmkp = curwp->w_dotp;
- X curwp->w_ldmko = curwp->w_doto;
- X }
- X if (toline) {
- X curwp->w_dotp = toline;
- X firstnonwhite();
- X setmark();
- X }
- X if (fromline) {
- X curwp->w_dotp = fromline;
- X firstnonwhite();
- X if (!toline)
- X setmark();
- X }
- X
- X /* and then execute the command */
- X isnamedcmd = TRUE;
- X havemotion = &f_gomark;
- X fulllineregions = TRUE;
- X
- X s = execute(cfp,f,n);
- X
- X havemotion = NULL;
- X isnamedcmd = FALSE;
- X fulllineregions = FALSE;
- X
- X return s;
- }
- X
- /* parse an ex-style line spec -- code culled from elvis, file ex.c, by
- X Steve Kirkendall
- */
- char *
- linespec(s, markptr)
- register char *s; /* start of the line specifier */
- LINE **markptr; /* where to store the mark's value */
- {
- X long num;
- X LINE *lp; /* where the linespec takes us */
- X register char *t;
- X int status;
- X
- X setmark();
- X lp = NULL;
- X
- X /* parse each ;-delimited clause of this linespec */
- X do
- X {
- X /* skip an initial ';', if any */
- X if (*s == ';')
- X s++;
- X
- X /* skip leading spaces */
- X while (isspace(*s))
- X s++;
- X
- X /* dot means current position */
- X if (*s == '.') {
- X s++;
- X lp = curwp->w_dotp;
- X } else if (*s == '$') { /* '$' means the last line */
- X s++;
- X status = gotoeob(TRUE,1);
- X if (status) lp = curwp->w_dotp;
- X } else if (isdigit(*s)) {
- X /* digit means an absolute line number */
- X for (num = 0; isdigit(*s); s++) {
- X num = num * 10 + *s - '0';
- X }
- X status = gotoline(TRUE,num);
- X if (status) lp = curwp->w_dotp;
- X } else if (*s == '\'') {
- X /* appostrophe means go to a set mark */
- X s++;
- X status = gonmmark(*s);
- X if (status) lp = curwp->w_dotp;
- X s++;
- X }
- #if PATTERNS
- X else if (*s == '/' || *s == '?') { /* slash means do a search */
- X /* put a '\0' at the end of the search pattern */
- X t = parseptrn(s);
- X
- X /* search for the pattern */
- X lp &= ~(BLKSIZE - 1);
- X if (*s == '/') {
- X pfetch(markline(lp));
- X if (plen > 0)
- X lp += plen - 1;
- X lp = m_fsrch(lp, s);
- X } else {
- X lp = m_bsrch(lp, s);
- X }
- X
- X /* adjust command string pointer */
- X s = t;
- X }
- #endif
- X
- X /* if linespec was faulty, quit now */
- X if (!lp) {
- X *markptr = lp;
- X swapmark();
- X return s;
- X }
- X
- X /* maybe add an offset */
- X t = s;
- X if (*t == '-' || *t == '+') {
- X s++;
- X for (num = 0; *s >= '0' && *s <= '9'; s++) {
- X num = num * 10 + *s - '0';
- X }
- X if (num == 0)
- X num = 1;
- X forwline(TRUE, (*t == '+') ? num : -num);
- X lp = curwp->w_dotp;
- X }
- X } while (*s == ';' || *s == '+' || *s == '-');
- X
- X *markptr = lp;
- X swapmark();
- X return s;
- }
- X
- /* parse an ex-style line range -- code culled from elvis, file ex.c, by
- X Steve Kirkendall
- */
- rangespec(specp,fromlinep,tolinep,isdefaultp,zerop)
- char *specp; /* string containing a line range */
- LINE **fromlinep; /* first linespec */
- LINE **tolinep; /* second linespec */
- int *isdefaultp;
- int *zerop;
- {
- X register char *scan; /* used to scan thru specp */
- X LINE *fromline; /* first linespec */
- X LINE *toline; /* second linespec */
- X int noaddrallowed;
- X
- X *zerop = FALSE;
- X
- X /* ignore command lines that start with a double-quote */
- X if (*specp == '"') {
- X *fromlinep = *tolinep = curwp->w_dotp;
- X return TRUE;
- X }
- X
- X /* permit extra colons at the start of the line */
- X while (isspace(*specp) || *specp == ':') {
- X specp++;
- X }
- X
- X /* parse the line specifier */
- X scan = specp;
- X if (lforw(curbp->b_linep) == curbp->b_linep) {
- X fromline = toline = NULL;
- X } else if (*scan == '%') {
- X /* '%' means all lines */
- X fromline = lforw(curbp->b_linep);
- X toline = lback(curbp->b_linep);
- X scan++;
- X } else if (*scan == '0') {
- X fromline = toline = curbp->b_linep; /* _very_ top of buffer */
- X *zerop = TRUE;
- X scan++;
- X } else {
- X scan = linespec(scan, &fromline);
- X if (!fromline)
- X fromline = curwp->w_dotp;
- X toline = fromline;
- X if (*scan == ',') {
- X scan++;
- X scan = linespec(scan, &toline);
- X }
- X if (!toline) {
- X /* faulty line spec -- fault already described */
- X dbgwrite("null toline");
- X return FALSE;
- X }
- X }
- X
- X *isdefaultp = (scan == specp);
- X
- X /* skip whitespace */
- X while (isspace(*scan))
- X scan++;
- X
- X if (*scan) {
- X dbgwrite("crud at end %s",specp);
- X return FALSE;
- X }
- X
- X *fromlinep = fromline;
- X *tolinep = toline;
- X
- X return TRUE;
- }
- X
- /* old namedcmd: execute a named command even if it is not bound */
- onamedcmd(f, n)
- int f, n; /* command arguments [passed through to command executed] */
- {
- X register char *fnp; /* ptr to the name of the cmd to exec */
- X char *kbd_engl();
- X int s;
- X
- X /* prompt the user to type a named command */
- X mlwrite(": ");
- X
- X /* and now get the function name to execute */
- #if NeWS
- X newsimmediateon() ;
- #endif
- X
- X fnp = kbd_engl();
- X
- #if NeWS
- X newsimmediateoff() ;
- #endif
- X
- X if (fnp == NULL) {
- X mlwrite("[No such function]");
- X return FALSE;
- X }
- X
- X /* and then execute the command */
- X isnamedcmd = TRUE;
- X s = docmd(fnp,FALSE,f,n);
- X isnamedcmd = FALSE;
- X
- X return s;
- }
- X
- #if NEVER
- /* execcmd: Execute a command line command by name alone */
- execcmd(f, n)
- int f, n; /* default Flag and Numeric argument */
- {
- X register int status; /* status return */
- X char cmdbuf[NSTRING]; /* string holding command to execute */
- X
- X /* get the line wanted */
- X cmdbuf[0] = 0;
- X if ((status = mlreply("cmd: ", cmdbuf, NSTRING)) != TRUE)
- X return status;
- X
- X execlevel = 0;
- X return docmd(cmdbuf,TRUE,f,n);
- }
- #endif
- X
- /* docmd: take a passed string as a command line and translate
- X it to be executed as a command. This function will be
- X used by execute-command-line and by all source and
- X startup files.
- X
- X format of the command line is:
- X
- X {# arg} <command-name> {<argument string(s)>}
- X
- */
- X
- docmd(cline,newcle,f,n)
- char *cline; /* command line to execute */
- {
- X int status; /* return status of function */
- X int flags; /* function flags */
- X int oldcle; /* old contents of clexec flag */
- X char *oldestr; /* original exec string */
- X char tkn[NSTRING]; /* next token off of command line */
- X CMDFUNC *cfp;
- X extern CMDFUNC f_godotplus;
- X
- X /* if we are scanning and not executing..go back here */
- X if (execlevel)
- X return TRUE;
- X
- X oldestr = execstr; /* save last ptr to string to execute */
- X execstr = cline; /* and set this one as current */
- X
- X /* first set up the default command values */
- X if (newcle == TRUE) {
- X f = FALSE;
- X n = 1;
- X }
- X
- X if ((status = macarg(tkn)) != TRUE) { /* and grab the first token */
- X execstr = oldestr;
- X return status;
- X }
- X
- X /* process leadin argument */
- X if (toktyp(tkn) != TKCMD) {
- X f = TRUE;
- X strcpy(tkn, tokval(tkn));
- X n = atoi(tkn);
- X
- X /* and now get the command to execute */
- X if ((status = macarg(tkn)) != TRUE) {
- X execstr = oldestr;
- X return status;
- X }
- X }
- X
- X /* and match the token to see if it exists */
- X if ((cfp = engl2fnc(tkn)) == NULL) {
- X mlwrite("[No such function %s]",tkn);
- X execstr = oldestr;
- X return FALSE;
- X }
- X
- X /* save the arguments and go execute the command */
- X oldcle = clexec; /* save old clexec flag */
- X clexec = newcle; /* in cline execution */
- X status = execute(cfp,f,n);
- X cmdstatus = status; /* save the status */
- X clexec = oldcle; /* restore clexec flag */
- X execstr = oldestr;
- X return status;
- }
- X
- /* token: chop a token off a string
- X return a pointer past the token
- */
- X
- char *
- token(src, tok)
- char *src, *tok; /* source string, destination token string */
- {
- X register int quotef; /* is the current string quoted? */
- X
- X /* first scan past any whitespace in the source string */
- X while (isspace(*src))
- X ++src;
- X
- X /* scan through the source string */
- X quotef = FALSE;
- X while (*src) {
- X /* process special characters */
- X if (*src == '\\') {
- X ++src;
- X if (*src == 0)
- X break;
- X switch (*src++) {
- X case 'r': *tok++ = '\r'; break;
- X case 'n': *tok++ = '\n'; break;
- X case 't': *tok++ = '\t'; break;
- X case 'b': *tok++ = '\b'; break;
- X case 'f': *tok++ = '\f'; break;
- X default: *tok++ = *(src-1);
- X }
- X } else {
- X /* check for the end of the token */
- X if (quotef) {
- X if (*src == '"')
- X break;
- X } else {
- X if (*src == ' ' || *src == '\t')
- X break;
- X }
- X
- X /* set quote mode if qoute found */
- X if (*src == '"')
- X quotef = TRUE;
- X
- X /* record the character */
- X *tok++ = *src++;
- X }
- X }
- X
- X /* terminate the token and exit */
- X if (*src)
- X ++src;
- X *tok = 0;
- X return src;
- }
- X
- macarg(tok) /* get a macro line argument */
- char *tok; /* buffer to place argument */
- {
- X int savcle; /* buffer to store original clexec */
- X
- X savcle = clexec; /* save execution mode */
- X clexec = TRUE; /* get the argument */
- X /* grab token and advance past */
- X execstr = token(execstr, tok);
- X /* evaluate it */
- X strcpy(tok, tokval(tok));
- X clexec = savcle; /* restore execution mode */
- X return TRUE;
- }
- X
- /* nextarg: get the next argument */
- X
- nextarg(buffer)
- char *buffer; /* buffer to put token into */
- {
- X /* grab token and advance past */
- X execstr = token(execstr, buffer);
- X /* evaluate it */
- X strcpy(buffer, tokval(buffer));
- X return TRUE;
- }
- X
- /* storemac: Set up a macro buffer and flag to store all
- X executed command lines there */
- X
- storemac(f, n)
- int f; /* default flag */
- int n; /* macro number to use */
- {
- X register struct BUFFER *bp; /* pointer to macro buffer */
- X char bname[NBUFN]; /* name of buffer to use */
- X
- X /* must have a numeric argument to this function */
- X if (f == FALSE) {
- X mlwrite("No macro specified");
- X return FALSE;
- X }
- X
- X /* range check the macro number */
- X if (n < 1 || n > 40) {
- X mlwrite("[Macro number out of range]");
- X return FALSE;
- X }
- X
- X /* construct the macro buffer name */
- X strcpy(bname, "[Macro xx]");
- X bname[7] = '0' + (n / 10);
- X bname[8] = '0' + (n % 10);
- X
- X /* set up the new macro buffer */
- X if ((bp = bfind(bname, OK_CREAT, BFINVS)) == NULL) {
- X mlwrite("[Cannot create macro]");
- X return FALSE;
- X }
- X
- X /* and make sure it is empty */
- X bclear(bp);
- X
- X /* and set the macro store pointers to it */
- X mstore = TRUE;
- X bstore = bp;
- X return TRUE;
- }
- X
- #if PROC
- /* storeproc: Set up a procedure buffer and flag to store all
- X executed command lines there */
- X
- storeproc(f, n)
- int f; /* default flag */
- int n; /* macro number to use */
- {
- X register struct BUFFER *bp; /* pointer to macro buffer */
- X register int status; /* return status */
- X char bname[NBUFN]; /* name of buffer to use */
- X
- X /* a numeric argument means its a numbered macro */
- X if (f == TRUE)
- X return storemac(f, n);
- X
- X /* get the name of the procedure */
- X bname[1] = 0;
- X if ((status = mlreply("Procedure name: ", &bname[1], NBUFN-2)) != TRUE)
- X return status;
- X
- X /* construct the macro buffer name */
- X bname[0] = '[';
- X strcat(bname, "]");
- X
- X /* set up the new macro buffer */
- X if ((bp = bfind(bname, OK_CREAT, BFINVS)) == NULL) {
- X mlwrite("[Can not create macro]");
- X return FALSE;
- X }
- X
- X /* and make sure it is empty */
- X bclear(bp);
- X
- X /* and set the macro store pointers to it */
- X mstore = TRUE;
- X bstore = bp;
- X return TRUE;
- }
- X
- /* execproc: Execute a procedure */
- X
- execproc(f, n)
- int f, n; /* default flag and numeric arg */
- {
- X register BUFFER *bp; /* ptr to buffer to execute */
- X register int status; /* status return */
- X static char obufn[NBUFN+2]; /* name of buffer to execute */
- X char bufn[NBUFN+2]; /* name of buffer to execute */
- X
- X /* find out what buffer the user wants to execute */
- X if ((status = mlreply("Execute procedure: ", obufn, NBUFN)) != TRUE)
- X return status;
- X
- X /* construct the buffer name */
- X bufn[0] = '[';
- X strcat(bufn, obufn);
- X strcat(bufn, "]");
- X
- X /* find the pointer to that buffer */
- X if ((bp=bfind(bufn, NO_CREAT, 0)) == NULL) {
- X mlwrite("[No such procedure]");
- X return FALSE;
- X }
- X
- X /* and now execute it as asked */
- X while (n-- > 0) {
- X if ((status = dobuf(bp)) != TRUE)
- X return status;
- X }
- X return TRUE;
- }
- #endif
- X
- #if ! SMALLER
- /* execbuf: Execute the contents of a buffer of commands */
- X
- execbuf(f, n)
- int f, n; /* default flag and numeric arg */
- {
- X register BUFFER *bp; /* ptr to buffer to execute */
- X register int status; /* status return */
- X static char bufn[NSTRING]; /* name of buffer to execute */
- X
- X /* find out what buffer the user wants to execute */
- X if ((status = mlreply("Execute buffer: ", bufn, NBUFN)) != TRUE)
- X return status;
- X
- X /* find the pointer to that buffer */
- X if ((bp=bfind(bufn, NO_CREAT, 0)) == NULL) {
- X mlwrite("No such buffer");
- X return FALSE;
- X }
- X
- X /* and now execute it as asked */
- X while (n-- > 0) {
- X if ((status = dobuf(bp)) != TRUE)
- X return status;
- X }
- X return TRUE;
- }
- #endif
- X
- /* dobuf: execute the contents of the buffer pointed to
- X by the passed BP
- X
- X Directives start with a "!" and include:
- X
- #if SMALLER
- X !endm End a macro
- #else
- X !endm End a macro
- X !if (cond) conditional execution
- X !else
- X !endif
- X !return Return (terminating current macro)
- X !goto <label> Jump to a label in the current macro
- X !force Force macro to continue...even if command fails
- X !while (cond) Execute a loop if the condition is true
- X !endwhile
- X
- X Line Labels begin with a "*" as the first nonblank char, like:
- X
- X *LBL01
- #endif
- X
- */
- X
- dobuf(bp)
- BUFFER *bp; /* buffer to execute */
- {
- X register int status; /* status return */
- X register LINE *lp; /* pointer to line to execute */
- X register LINE *hlp; /* pointer to line header */
- X LINE *mp; /* Macro line storage temp */
- X int dirnum; /* directive index */
- X int linlen; /* length of line to execute */
- X int i; /* index */
- X int force; /* force TRUE result? */
- X WINDOW *wp; /* ptr to windows to scan */
- X WHBLOCK *whlist; /* ptr to !WHILE list */
- X char *einit; /* initial value of eline */
- X char *eline; /* text of line to execute */
- #if ! SMALLER
- X WHBLOCK *scanner; /* ptr during scan */
- X register LINE *glp; /* line to goto */
- X WHBLOCK *whtemp; /* temporary ptr to a WHBLOCK */
- X char tkn[NSTRING]; /* buffer to evaluate an expresion in */
- #endif
- X
- #if DEBUGM
- X char *sp; /* temp for building debug string */
- X register char *ep; /* ptr to end of outline */
- #endif
- X
- X /* clear IF level flags/while ptr */
- X execlevel = 0;
- X whlist = NULL;
- X fulllineregions = FALSE;
- X havemotion = FALSE;
- X
- #if ! SMALLER
- X scanner = NULL;
- X /* scan the buffer to execute, building WHILE header blocks */
- X hlp = bp->b_linep;
- X lp = hlp->l_fp;
- X while (lp != hlp) {
- X /* scan the current line */
- X eline = lp->l_text;
- X i = lp->l_used;
- X
- X /* trim leading whitespace */
- X while (i-- > 0 && (*eline == ' ' || *eline == '\t'))
- X ++eline;
- X
- X /* if theres nothing here, don't bother */
- X if (i <= 0)
- X goto nxtscan;
- X
- X /* if is a while directive, make a block... */
- X if (eline[0] == '!' && eline[1] == 'w' && eline[2] == 'h') {
- X whtemp = (WHBLOCK *)malloc(sizeof(WHBLOCK));
- X if (whtemp == NULL) {
- noram: mlwrite("%%Out of memory during while scan");
- failexit: freewhile(scanner);
- X freewhile(whlist);
- X mstore = FALSE;
- X return FALSE;
- X }
- X whtemp->w_begin = lp;
- X whtemp->w_type = BTWHILE;
- X whtemp->w_next = scanner;
- X scanner = whtemp;
- X }
- X
- X /* if is a BREAK directive, make a block... */
- X if (eline[0] == '!' && eline[1] == 'b' && eline[2] == 'r') {
- X if (scanner == NULL) {
- X mlwrite("%%!BREAK outside of any !WHILE loop");
- X goto failexit;
- X }
- X whtemp = (WHBLOCK *)malloc(sizeof(WHBLOCK));
- X if (whtemp == NULL)
- X goto noram;
- X whtemp->w_begin = lp;
- X whtemp->w_type = BTBREAK;
- X whtemp->w_next = scanner;
- X scanner = whtemp;
- X }
- X
- X /* if it is an endwhile directive, record the spot... */
- X if (eline[0] == '!' && strncmp(&eline[1], "endw", 4) == 0) {
- X if (scanner == NULL) {
- X mlwrite("%%!ENDWHILE with no preceding !WHILE in '%s'",
- X bp->b_bname);
- X goto failexit;
- X }
- X /* move top records from the scanner list to the
- X whlist until we have moved all BREAK records
- X and one WHILE record */
- X do {
- X scanner->w_end = lp;
- X whtemp = whlist;
- X whlist = scanner;
- X scanner = scanner->w_next;
- X whlist->w_next = whtemp;
- X } while (whlist->w_type == BTBREAK);
- X }
- X
- nxtscan: /* on to the next line */
- X lp = lp->l_fp;
- X }
- X
- X /* while and endwhile should match! */
- X if (scanner != NULL) {
- X mlwrite("%%!WHILE with no matching !ENDWHILE in '%s'",
- X bp->b_bname);
- X goto failexit;
- X }
- #endif
- X
- X /* starting at the beginning of the buffer */
- X hlp = bp->b_linep;
- X lp = hlp->l_fp;
- X while (lp != hlp) {
- X /* allocate eline and copy macro line to it */
- X linlen = lp->l_used;
- X if ((einit = eline = malloc(linlen+1)) == NULL) {
- X mlwrite("%%Out of Memory during macro execution");
- X freewhile(whlist);
- X mstore = FALSE;
- X return FALSE;
- X }
- X strncpy(eline, lp->l_text, linlen);
- X eline[linlen] = 0; /* make sure it ends */
- X
- X /* trim leading whitespace */
- X while (*eline == ' ' || *eline == '\t')
- X ++eline;
- X
- X /* dump comments and blank lines */
- X if (*eline == ';' || *eline == 0)
- X goto onward;
- X
- #if DEBUGM
- X /* if $debug == TRUE, every line to execute
- X gets echoed and a key needs to be pressed to continue
- X ^G will abort the command */
- X
- X if (macbug) {
- X strcpy(outline, "<<<");
- X
- X /* debug macro name */
- X strcat(outline, bp->b_bname);
- X strcat(outline, ":");
- X
- X /* debug if levels */
- X strcat(outline, itoa(execlevel));
- X strcat(outline, ":");
- X
- X /* and lastly the line */
- X strcat(outline, eline);
- X strcat(outline, ">>>");
- X
- X /* change all '%' to ':' so mlwrite won't expect arguments */
- X sp = outline;
- X while (*sp)
- X if (*sp++ == '%') {
- X /* advance to the end */
- X ep = --sp;
- X while (*ep++)
- X ;
- X /* null terminate the string one out */
- X *(ep + 1) = 0;
- X /* copy backwards */
- X while(ep-- > sp)
- X *(ep + 1) = *ep;
- X
- X /* and advance sp past the new % */
- X sp += 2;
- X }
- X
- X /* write out the debug line */
- X mlforce(outline);
- X update(TRUE);
- X
- X /* and get the keystroke */
- X if (kbd_key() == abortc) {
- X mlforce("[Macro aborted]");
- X freewhile(whlist);
- X mstore = FALSE;
- X return FALSE;
- X }
- X }
- #endif
- X
- X /* Parse directives here.... */
- X dirnum = -1;
- X if (*eline == '~') {
- X /* Find out which directive this is */
- X ++eline;
- X for (dirnum = 0; dirnum < NUMDIRS; dirnum++)
- X if (strncmp(eline, dname[dirnum],
- X strlen(dname[dirnum])) == 0)
- X break;
- X
- X /* and bitch if it's illegal */
- X if (dirnum == NUMDIRS) {
- X mlwrite("%%Unknown Directive");
- X freewhile(whlist);
- X mstore = FALSE;
- X return FALSE;
- X }
- X
- X /* service only the !ENDM macro here */
- X if (dirnum == DENDM) {
- X mstore = FALSE;
- X bstore = NULL;
- X goto onward;
- X }
- X
- X /* restore the original eline....*/
- X --eline;
- X }
- X
- X /* if macro store is on, just salt this away */
- X if (mstore) {
- X /* allocate the space for the line */
- X linlen = strlen(eline);
- X if ((mp=lalloc(linlen)) == NULL) {
- X mlwrite("%%Out of memory while storing macro");
- X mstore = FALSE;
- X return FALSE;
- X }
- X
- X /* copy the text into the new line */
- X for (i=0; i<linlen; ++i)
- X lputc(mp, i, eline[i]);
- X
- X /* attach the line to the end of the buffer */
- X bstore->b_linep->l_bp->l_fp = mp;
- X mp->l_bp = bstore->b_linep->l_bp;
- X bstore->b_linep->l_bp = mp;
- X mp->l_fp = bstore->b_linep;
- X goto onward;
- X }
- X
- X
- X force = FALSE;
- X
- X /* dump comments */
- X if (*eline == '*')
- X goto onward;
- X
- #if ! SMALLER
- X /* now, execute directives */
- X if (dirnum != -1) {
- X /* skip past the directive */
- X while (*eline && *eline != ' ' && *eline != '\t')
- X ++eline;
- X execstr = eline;
- X
- X switch (dirnum) {
- X case DIF: /* IF directive */
- X /* grab the value of the logical exp */
- X if (execlevel == 0) {
- X if (macarg(tkn) != TRUE)
- X goto eexec;
- X if (stol(tkn) == FALSE)
- X ++execlevel;
- X } else
- X ++execlevel;
- X goto onward;
- X
- X case DWHILE: /* WHILE directive */
- X /* grab the value of the logical exp */
- X if (execlevel == 0) {
- X if (macarg(tkn) != TRUE)
- X goto eexec;
- X if (stol(tkn) == TRUE)
- X goto onward;
- X }
- X /* drop down and act just like !BREAK */
- X
- X case DBREAK: /* BREAK directive */
- X if (dirnum == DBREAK && execlevel)
- X goto onward;
- X
- X /* jump down to the endwhile */
- X /* find the right while loop */
- X whtemp = whlist;
- X while (whtemp) {
- X if (whtemp->w_begin == lp)
- X break;
- X whtemp = whtemp->w_next;
- X }
- X
- X if (whtemp == NULL) {
- X mlwrite("%%Internal While loop error");
- X freewhile(whlist);
- X mstore = FALSE;
- X return FALSE;
- X }
- X
- X /* reset the line pointer back.. */
- X lp = whtemp->w_end;
- X goto onward;
- X
- X case DELSE: /* ELSE directive */
- X if (execlevel == 1)
- X --execlevel;
- X else if (execlevel == 0 )
- X ++execlevel;
- X goto onward;
- X
- X case DENDIF: /* ENDIF directive */
- X if (execlevel)
- X --execlevel;
- X goto onward;
- X
- X case DGOTO: /* GOTO directive */
- X /* .....only if we are currently executing */
- X if (execlevel == 0) {
- X
- X /* grab label to jump to */
- X eline = token(eline, golabel);
- X linlen = strlen(golabel);
- X glp = hlp->l_fp;
- X while (glp != hlp) {
- X if (*glp->l_text == '*' &&
- X (strncmp(&glp->l_text[1], golabel,
- X linlen) == 0)) {
- X lp = glp;
- X goto onward;
- X }
- X glp = glp->l_fp;
- X }
- X mlwrite("%%No such label");
- X freewhile(whlist);
- X mstore = FALSE;
- X return FALSE;
- X }
- X goto onward;
- X
- X case DRETURN: /* RETURN directive */
- X if (execlevel == 0)
- X goto eexec;
- X goto onward;
- X
- X case DENDWHILE: /* ENDWHILE directive */
- X if (execlevel) {
- X --execlevel;
- X goto onward;
- X } else {
- X /* find the right while loop */
- X whtemp = whlist;
- X while (whtemp) {
- X if (whtemp->w_type == BTWHILE &&
- X whtemp->w_end == lp)
- X break;
- X whtemp = whtemp->w_next;
- X }
- X
- X if (whtemp == NULL) {
- X mlwrite("%%Internal While loop error");
- X freewhile(whlist);
- X mstore = FALSE;
- X return FALSE;
- X }
- X
- X /* reset the line pointer back.. */
- X lp = whtemp->w_begin->l_bp;
- X goto onward;
- X }
- X
- X case DFORCE: /* FORCE directive */
- X force = TRUE;
- X
- X }
- X }
- #endif
- X
- X /* execute the statement */
- X status = docmd(eline,TRUE,FALSE,1);
- X if (force) /* force the status */
- X status = TRUE;
- X
- X /* check for a command error */
- X if (status != TRUE) {
- X /* look if buffer is showing */
- X wp = wheadp;
- X while (wp != NULL) {
- X if (wp->w_bufp == bp) {
- X /* and point it */
- X wp->w_dotp = lp;
- X wp->w_doto = 0;
- X wp->w_flag |= WFHARD;
- X }
- X wp = wp->w_wndp;
- X }
- X /* in any case set the buffer . */
- X bp->b_dotp = lp;
- X bp->b_doto = 0;
- X free(einit);
- X execlevel = 0;
- X mstore = FALSE;
- X freewhile(whlist);
- X return status;
- X }
- X
- onward: /* on to the next line */
- X free(einit);
- X lp = lp->l_fp;
- X }
- X
- #if ! SMALLER
- eexec: /* exit the current function */
- #endif
- X mstore = FALSE;
- X execlevel = 0;
- X freewhile(whlist);
- X return TRUE;
- }
- X
- freewhile(wp) /* free a list of while block pointers */
- WHBLOCK *wp; /* head of structure to free */
- {
- X if (wp == NULL)
- X return;
- X if (wp->w_next)
- X freewhile(wp->w_next);
- X free((char *)wp);
- }
- X
- #if ! SMALLER
- execfile(f, n) /* execute a series of commands in a file */
- int f, n; /* default flag and numeric arg to pass on to file */
- {
- X register int status; /* return status of name query */
- X static char ofname[NSTRING]; /* name of file to execute */
- X char fname[NSTRING]; /* name of file to execute */
- X char *fspec; /* full file spec */
- X
- X if ((status = mlreply("File to execute: ", ofname, NSTRING -1)) != TRUE)
- X return status;
- X strcpy(fname,ofname);
- X
- #if 1
- X /* look up the path for the file */
- X fspec = flook(fname, FL_ANYWHERE);
- X
- X /* if it isn't around */
- X if (fspec == NULL)
- X return FALSE;
- X
- #endif
- X /* otherwise, execute it */
- X while (n-- > 0)
- X if ((status=dofile(fspec)) != TRUE)
- X return status;
- X
- X return TRUE;
- }
- #endif
- X
- /* dofile: yank a file into a buffer and execute it
- X if there are no errors, delete the buffer on exit */
- X
- dofile(fname)
- char *fname; /* file name to execute */
- {
- X register BUFFER *bp; /* buffer to place file to exeute */
- X register int status; /* results of various calls */
- X register int odiscmd;
- X char bname[NBUFN]; /* name of buffer */
- X
- X makename(bname, fname); /* derive the name of the buffer */
- X if ((bp = bfind(bname, OK_CREAT, 0)) == NULL) /* get the needed buffer */
- X return FALSE;
- X
- X bp->b_mode = MDVIEW; /* mark the buffer as read only */
- X /* and try to read in the file to execute */
- X if ((status = readin(fname, FALSE, bp, TRUE)) != TRUE) {
- X return status;
- X }
- X
- X /* go execute it! */
- X odiscmd = discmd;
- X discmd = FALSE;
- X status = dobuf(bp);
- X discmd = odiscmd;
- X if (status != TRUE)
- X return status;
- X
- X /* if not displayed, remove the now unneeded buffer and exit */
- X if (bp->b_nwnd == 0)
- X zotbuf(bp);
- X return TRUE;
- }
- X
- /* cbuf: Execute the contents of a numbered buffer */
- X
- cbuf(f, n, bufnum)
- int f, n; /* default flag and numeric arg */
- int bufnum; /* number of buffer to execute */
- {
- X register BUFFER *bp; /* ptr to buffer to execute */
- X register int status; /* status return */
- X static char bufname[] = "[Macro xx]";
- X
- X /* make the buffer name */
- X bufname[7] = '0' + (bufnum / 10);
- X bufname[8] = '0' + (bufnum % 10);
- X
- X /* find the pointer to that buffer */
- X if ((bp=bfind(bufname, NO_CREAT, 0)) == NULL) {
- X mlwrite("[Macro not defined]");
- X return FALSE;
- X }
- X
- X /* and now execute it as asked */
- X while (n-- > 0)
- X if ((status = dobuf(bp)) != TRUE)
- X return status;
- X return TRUE;
- }
- X
- cbuf1(f, n)
- {
- X cbuf(f, n, 1);
- }
- X
- cbuf2(f, n)
- {
- X cbuf(f, n, 2);
- }
- X
- cbuf3(f, n)
- {
- X cbuf(f, n, 3);
- }
- X
- cbuf4(f, n)
- {
- X cbuf(f, n, 4);
- }
- X
- cbuf5(f, n)
- {
- X cbuf(f, n, 5);
- }
- X
- cbuf6(f, n)
- {
- X cbuf(f, n, 6);
- }
- X
- cbuf7(f, n)
- {
- X cbuf(f, n, 7);
- }
- X
- cbuf8(f, n)
- {
- X cbuf(f, n, 8);
- }
- X
- cbuf9(f, n)
- {
- X cbuf(f, n, 9);
- }
- X
- cbuf10(f, n)
- {
- X cbuf(f, n, 10);
- }
- X
- cbuf11(f, n)
- {
- X cbuf(f, n, 11);
- }
- X
- cbuf12(f, n)
- {
- X cbuf(f, n, 12);
- }
- X
- cbuf13(f, n)
- {
- X cbuf(f, n, 13);
- }
- X
- cbuf14(f, n)
- {
- X cbuf(f, n, 14);
- }
- X
- cbuf15(f, n)
- {
- X cbuf(f, n, 15);
- }
- X
- cbuf16(f, n)
- {
- X cbuf(f, n, 16);
- }
- X
- cbuf17(f, n)
- {
- X cbuf(f, n, 17);
- }
- X
- cbuf18(f, n)
- {
- X cbuf(f, n, 18);
- }
- X
- cbuf19(f, n)
- {
- X cbuf(f, n, 19);
- }
- X
- cbuf20(f, n)
- {
- X cbuf(f, n, 20);
- }
- X
- cbuf21(f, n)
- {
- X cbuf(f, n, 21);
- }
- X
- cbuf22(f, n)
- {
- X cbuf(f, n, 22);
- }
- X
- cbuf23(f, n)
- {
- X cbuf(f, n, 23);
- }
- X
- cbuf24(f, n)
- {
- X cbuf(f, n, 24);
- }
- X
- cbuf25(f, n)
- {
- X cbuf(f, n, 25);
- }
- X
- cbuf26(f, n)
- {
- X cbuf(f, n, 26);
- }
- X
- cbuf27(f, n)
- {
- X cbuf(f, n, 27);
- }
- X
- cbuf28(f, n)
- {
- X cbuf(f, n, 28);
- }
- X
- cbuf29(f, n)
- {
- X cbuf(f, n, 29);
- }
- X
- cbuf30(f, n)
- {
- X cbuf(f, n, 30);
- }
- X
- cbuf31(f, n)
- {
- X cbuf(f, n, 31);
- }
- X
- cbuf32(f, n)
- {
- X cbuf(f, n, 32);
- }
- X
- cbuf33(f, n)
- {
- X cbuf(f, n, 33);
- }
- X
- cbuf34(f, n)
- {
- X cbuf(f, n, 34);
- }
- X
- cbuf35(f, n)
- {
- X cbuf(f, n, 35);
- }
- X
- cbuf36(f, n)
- {
- X cbuf(f, n, 36);
- }
- X
- cbuf37(f, n)
- {
- X cbuf(f, n, 37);
- }
- X
- cbuf38(f, n)
- {
- X cbuf(f, n, 38);
- }
- X
- cbuf39(f, n)
- {
- X cbuf(f, n, 39);
- }
- X
- cbuf40(f, n)
- {
- X cbuf(f, n, 40);
- }
- X
- X
- SHAR_EOF
- chmod 0444 exec.c ||
- echo 'restore of exec.c failed'
- Wc_c="`wc -c < 'exec.c'`"
- test 32572 -eq "$Wc_c" ||
- echo 'exec.c: original size 32572, current size' "$Wc_c"
- # ============= file.c ==============
- echo 'x - extracting file.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'file.c' &&
- /* FILE.C: for MicroEMACS
- X
- X The routines in this file handle the reading, writing
- X and lookup of disk files. All of details about the
- X reading and writing of the disk are in "fileio.c".
- X
- */
- X
- #include <stdio.h>
- #include "estruct.h"
- #include "edef.h"
- X
- char *strchr();
- char *strrchr();
- X
- extern int fileispipe;
- #if DOSFILES
- extern int dosfile;
- #endif
- X
- /*
- X * Read a file into the current
- X * buffer. This is really easy; all you do it
- X * find the name of the file, and call the standard
- X * "read a file into the current buffer" code.
- X */
- fileread(f, n)
- {
- X register int s;
- X static char fname[NFILEN];
- X
- X if ((s=mlreply("Replace with file: ", fname, NFILEN)) != TRUE)
- X return s;
- X if ((s = glob(fname)) != TRUE)
- X return FALSE;
- X /* we want no errors or complaints, so mark it unchanged */
- X curbp->b_flag &= ~BFCHG;
- X return readin(fname, TRUE, curbp, TRUE);
- }
- X
- /*
- X * Select a file for editing.
- X * Look around to see if you can find the
- X * file in another buffer; if you can find it
- X * just switch to the buffer. If you cannot find
- X * the file, create a new buffer, read in the
- X * text, and switch to the new buffer.
- X * This is ": e"
- X */
- filefind(f, n)
- {
- X static char fname[NFILEN]; /* file user wishes to find */
- X char nfname[NFILEN];
- X char rnfname[NFILEN];
- X register int s; /* status return */
- X LINE *lp;
- X
- X if (clexec || isnamedcmd) {
- X if ((s=mlreply("Find file: ", fname, NFILEN)) != TRUE)
- X return s;
- X } else {
- X screen_string(fname,NFILEN,_path);
- X }
- X if ((s = glob(fname)) != TRUE)
- X return FALSE;
- X strcpy (nfname, fname);
- #if TAGS
- X if (othmode & OTH_LAZY) {
- X extern BUFFER *filesbp;
- X lp = NULL;
- X while (flook(nfname, FL_HERE) == NULL) {
- X rvstrcpy(rnfname, fname);
- X if (makeflist() == FALSE || !sortsearch(rnfname,
- X strlen(rnfname), filesbp, FALSE, &lp)) {
- X /* give up, and try what they asked for */
- X strcpy (nfname, fname);
- X break;
- X }
- X rvstrncpy(nfname, lp->l_text, llength(lp));
- X }
- X }
- #endif
- X return getfile(nfname, TRUE);
- }
- X
- viewfile(f, n) /* visit a file in VIEW mode */
- {
- X char fname[NFILEN]; /* file user wishes to find */
- X register int s; /* status return */
- X
- X fname[0] = 0;
- X if ((s=mlreply("View file: ", fname, NFILEN)) != TRUE)
- X return s;
- X if ((s = glob(fname)) != TRUE)
- X return FALSE;
- X s = getfile(fname, FALSE);
- X if (s == TRUE) { /* if we succeed, put it in view mode */
- X curwp->w_bufp->b_mode |= MDVIEW;
- X markWFMODE(curwp->w_bufp);
- X }
- X return s;
- }
- X
- /*
- X * Insert a file into the current
- X * buffer. This is really easy; all you do it
- X * find the name of the file, and call the standard
- X * "insert a file into the current buffer" code.
- X */
- static char insfname[NFILEN];
- X
- insfile(f, n)
- {
- X register int s;
- X
- X if (!calledbefore) {
- X if ((s=mlreply("Insert file: ", insfname, NFILEN)) != TRUE)
- X return s;
- X if ((s = glob(insfname)) != TRUE)
- X return FALSE;
- X }
- X if (ukb == 0)
- X return ifile(insfname,TRUE,NULL);
- X else
- X return kifile(insfname);
- }
- X
- #if BEFORE
- insfiletop(f, n)
- {
- X register int s;
- X if ((s=mlreply("Insert file: ", insfname, NFILEN)) != TRUE)
- X return s;
- X if ((s = glob(insfname)) != TRUE)
- X return FALSE;
- X curwp->w_dotp = curbp->b_linep;
- X return ifile(insfname,TRUE,NULL);
- }
- #endif
- X
- getfile(fname, lockfl)
- char fname[]; /* file name to find */
- int lockfl; /* check the file for locks? */
- {
- X register BUFFER *bp;
- X register LINE *lp;
- X register int i;
- X register int s;
- X char bname[NBUFN]; /* buffer name to put file */
- X
- #if MSDOS
- X mklower(fname); /* msdos isn't case sensitive */
- #endif
- X if ((bp=bfind(fname, NO_CREAT, 0)) == NULL) {
- X /* it's not already here by that buffer name */
- X for (bp=bheadp; bp!=NULL; bp=bp->b_bufp) {
- X /* is it here by that filename? */
- X if (strcmp(bp->b_fname, fname)==0) {
- X swbuffer(bp);
- X lp = curwp->w_dotp;
- X i = curwp->w_ntrows/2;
- X while (i-- && lback(lp)!=curbp->b_linep)
- X lp = lback(lp);
- X curwp->w_linep = lp;
- X curwp->w_flag |= WFMODE|WFHARD;
- X if (fname[0] != '!') {
- X mlwrite("[Old buffer]");
- X } else {
- X if (mlyesno(
- X "Old command output -- rerun")) {
- X return readin(fname, lockfl,
- X curbp, TRUE);
- X }
- X }
- X
- X return TRUE;
- X }
- X }
- X /* it's not here */
- X makename(bname, fname); /* New buffer name. */
- X /* make sure the buffer name doesn't exist */
- X while ((bp=bfind(bname, NO_CREAT, 0)) != NULL) {
- X if ( !(bp->b_flag & BFCHG) &&
- X lforw(bp->b_linep) == bp->b_linep ) {
- X /* empty and unmodiefied -- then its okay
- X to re-use this buffer */
- X bp->b_active = 0;
- X return readin(fname, lockfl, bp, TRUE) &&
- X swbuffer(bp);;
- X }
- X /* old buffer name conflict code */
- X unqname(bname,TRUE);
- X s = mlreply("Will use buffer name: ", bname, NBUFN);
- X if (s == ABORT)
- X return s;
- X if (s == FALSE || bname[0] == 0)
- X makename(bname, fname);
- X }
- X /* okay, we've got a unique name -- create it */
- X if (bp==NULL && (bp=bfind(bname, OK_CREAT, 0))==NULL) {
- X mlwrite("Cannot create buffer");
- X return FALSE;
- X }
- X /* switch and read it in. */
- X strcpy(bp->b_fname, fname);
- X }
- X return swbuffer(bp);
- }
- X
- /*
- X Read file "fname" into a buffer, blowing away any text
- X found there. Returns the final status of the read.
- */
- X
- readin(fname, lockfl, bp, mflg)
- char *fname; /* name of file to read */
- int lockfl; /* check for file locks? */
- register BUFFER *bp; /* read into this buffer */
- int mflg; /* print messages? */
- {
- X register WINDOW *wp;
- X register int s;
- X register int nline;
- X int len;
- X char *errst;
- X int flag = 0;
- #if UNIX
- X int done_update = FALSE;
- #endif
- #if VMALLOC
- X extern int doverifys;
- X int odv;
- #endif
- X
- #if FILOCK
- X if (lockfl && lockchk(fname) == ABORT)
- X return ABORT;
- #endif
- #if CRYPT
- X s = resetkey(bp);
- X if (s != TRUE)
- X return s;
- #endif
- X if ((s=bclear(bp)) != TRUE) /* Might be old. */
- X return s;
- X bp->b_flag &= ~(BFINVS|BFCHG);
- X strcpy(bp->b_fname, fname);
- X
- X /* turn off ALL keyboard translation in case we get a dos error */
- X TTkclose();
- X
- X if ((s=ffropen(fname)) == FIOERR) /* Hard file open. */
- X goto out;
- X
- X if (s == FIOFNF) { /* File not found. */
- X if (mflg) mlwrite("[New file]");
- X goto out;
- X }
- X
- X if (mflg) {
- X mlwrite("[Reading %s ]", fname);
- X }
- X
- #if UNIX & before
- X if (fileispipe)
- X ttclean(TRUE);
- #endif
- X /* read the file in */
- X nline = 0;
- #if VMALLOC
- X /* we really think this stuff is clean... */
- X odv = doverifys;
- X doverifys = 0;
- #endif
- X while ((s = ffgetline(&len)) == FIOSUC) {
- X if (addline(bp,fline,len) != TRUE) {
- X s = FIOMEM; /* Keep message on the */
- X break; /* display. */
- X } else {
- #if UNIX
- X /* reading from a pipe, and internal? */
- X if (fileispipe && !ffhasdata()) {
- X flag |= WFEDIT;
- X if (!done_update || bp->b_nwnd > 1)
- X flag |= WFHARD;
- X for (wp=wheadp; wp!=NULL; wp=wp->w_wndp) {
- X if (wp->w_bufp == bp) {
- X wp->w_linep=lforw(bp->b_linep);
- X wp->w_dotp =lback(bp->b_linep);
- X wp->w_doto = 0;
- X wp->w_flag |= flag;
- X }
- X }
- X update(FALSE);
- X done_update = TRUE;
- X flag = 0;
- X } else {
- X flag |= WFHARD;
- X }
- X
- X }
- #endif
- X ++nline;
- X }
- #if VMALLOC
- X doverifys = odv;
- #endif
- X bp->b_flag &= ~BFCHG;
- #if UNIX & before
- X if (fileispipe == TRUE) {
- X ttunclean();
- X TTflush();
- X sgarbf = TRUE;
- X }
- #endif
- #if FINDERR
- X if (fileispipe == TRUE) {
- X strncpy(febuff,bp->b_bname,NBUFN);
- X newfebuff = TRUE;
- X }
- #endif
- X ffclose(); /* Ignore errors. */
- #if DOSFILES
- X if (dosfile && (gmode & MDDOS))
- X bp->b_mode |= MDDOS;
- #endif
- X if (mflg)
- X readlinesmsg(nline,s,fname,ffronly(fname));
- X
- X /* set read-only mode for read-only files */
- X if (fname[0] == '!'
- #if RONLYVIEW
- X || ffronly(fname)
- #endif
- X ) {
- X bp->b_mode |= MDVIEW;
- X }
- X
- X bp->b_active = TRUE;
- X
- X /* set C mode for C files */
- X if (gmode & MDCMOD) {
- X char *cp;
- X cp = &fname[strlen(fname)-2];
- X if (cp >= fname && cp[0] == '.' && strchr("chCH",cp[1]) ) {
- X bp->b_mode |= MDCMOD;
- X }
- X }
- X
- out:
- X TTkopen(); /* open the keyboard again */
- X for (wp=wheadp; wp!=NULL; wp=wp->w_wndp) {
- X if (wp->w_bufp == bp) {
- X wp->w_linep = lforw(bp->b_linep);
- X wp->w_dotp = lforw(bp->b_linep);
- X wp->w_doto = 0;
- X wp->w_mkp = NULL;
- X wp->w_mko = 0;
- X wp->w_ldmkp = NULL;
- X wp->w_ldmko = 0;
- X wp->w_flag |= WFMODE|WFHARD;
- X }
- X }
- X if (s == FIOERR || s == FIOFNF) { /* False if error. */
- #if UNIX
- X extern int sys_nerr, errno;
- X extern char *sys_errlist[];
- X if (errno > 0 && errno < sys_nerr)
- X mlwrite("%s: %s",fname,sys_errlist[errno]);
- #endif
- X return FALSE;
- X }
- #if NeWS
- X newsreportmodes() ;
- #endif
- X return TRUE;
- }
- X
- /* utility routine for no. of lines read */
- readlinesmsg(n,s,f,rdonly)
- {
- X mlwrite("[%sRead %d line%s from \"%s\"%s]",
- X (s==FIOERR ? "I/O ERROR, " : (s == FIOMEM ? "OUT OF MEMORY, ":"")),
- X n, n != 1 ? "s":"", f, rdonly ? " (read-only)":"" );
- }
- X
- /*
- X * Take a file name, and from it
- X * fabricate a buffer name. This routine knows
- X * about the syntax of file names on the target system.
- X * I suppose that this information could be put in
- X * a better place than a line of code.
- X */
- X
- makename(bname, fname)
- char bname[];
- char fname[];
- {
- X register char *cp2;
- X register char *lastsl;
- X
- X register char *fcp;
- X register char *bcp;
- X
- X fcp = &fname[strlen(fname)];
- X /* trim trailing whitespace */
- X while (fcp != fname && (fcp[-1] == ' ' || fcp[-1] == '\t'
- #if UNIX /* trim trailing slashes as well */
- X || fcp[-1] == '/'
- #endif
- X ) )
- X *(--fcp) = '\0';
- X fcp = fname;
- X /* trim leading whitespace */
- X while (*fcp == ' ' || *fcp == '\t')
- X fcp++;
- X
- #if AMIGA
- X while (cp1!=fcp && cp1[-1]!=':' && cp1[-1]!='/')
- X --cp1;
- #endif
- #if VMS
- X while (cp1!=fcp && cp1[-1]!=':' && cp1[-1]!=']')
- X --cp1;
- #endif
- #if CPM
- X while (cp1!=fcp && cp1[-1]!=':')
- X --cp1;
- #endif
- #if MSDOS
- X while (cp1!=fcp && cp1[-1]!=':' && cp1[-1]!='\\'&&cp1[-1]!='/')
- X --cp1;
- #endif
- #if ST520
- X while (cp1!=fcp && cp1[-1]!=':' && cp1[-1]!='\\')
- X --cp1;
- #endif
- #if UNIX
- X bcp = bname;
- X if (*fcp == '!') { /* then it's a shell command. bname is first word */
- X *bcp++ = '!';
- X while (isspace(*++fcp))
- X ;
- X while (!isspace(*fcp) && bcp < &bname[NBUFN-1])
- X *bcp++ = *fcp++;
- X *bcp = '\0';
- X return;
- X }
- X if (lastsl = strrchr(fcp,'/')) {
- X strncpy(bcp,lastsl+1,NBUFN);
- X bcp[NBUFN-1] = '\0';
- X } else { /* no slashes, use the filename as is */
- X strncpy(bcp,fcp,NBUFN);
- X bcp[NBUFN-1] = '\0';
- X }
- X return;
- X
- #else
- X cp2 = &bname[0];
- X while (cp2!=&bname[NBUFN-1] && *cp1!=0 && *cp1!=';')
- X *cp2++ = *cp1++;
- X *cp2 = 0;
- #endif
- }
- X
- unqname(name,ok_to_ask) /* make sure a buffer name is unique */
- char *name; /* name to check on */
- {
- X register char *sp;
- X
- X /* check to see if it is in the buffer list */
- X while (bfind(name, 0, NO_CREAT) != NULL) {
- X
- X sp = &name[strlen(name)-1]; /* last char */
- X if (sp - name >= 2 && sp[-1] == '-') {
- X if (sp[0] == '9')
- X sp[0] = 'A';
- X else if (sp[0] == 'Z')
- X goto choosename;
- X else if (isdigit(sp[0]) || isupper(sp[0]))
- X sp[0] += 1;
- X } else if (sp + 2 < &name[NBUFN-1]) {
- X strcat(sp, "-1");
- X } else {
- X choosename:
- X if (ok_to_ask) {
- X do {
- X mlreply("Choose a unique buffer name: ",
- X name, NBUFN);
- X } while (name[0] == '\0');
- X } else { /* can't ask, just overwrite end of name */
- X sp[-1] = '-';
- X sp[0] = '1';
- X }
- X }
- X }
- }
- X
- /*
- X * Ask for a file name, and write the
- X * contents of the current buffer to that file.
- X */
- filewrite(f, n)
- {
- X register int s;
- X static char fname[NFILEN];
- X
- X strncpy(fname, curbp->b_fname, NFILEN);
- X
- X /* HACK -- this implies knowledge of how kbd_engl works! */
- X if (isnamedcmd && lastkey != '\r') {
- X if ((s=mlreply("Write to file: ", fname, NFILEN)) != TRUE)
- X return s;
- X if ((s = glob(fname)) != TRUE)
- X return FALSE;
- X if (strcmp(fname,curbp->b_fname) &&
- X fname[0] != '!' && flook(fname,FL_HERE)) {
- X if (mlyesno("File exists, okay to overwrite") != TRUE) {
- X mlwrite("File not written");
- X return FALSE;
- X }
- X }
- X }
- X if ((s=writeout(fname,curbp,TRUE)) == TRUE) {
- X curbp->b_flag &= ~BFCHG;
- X markWFMODE(curbp);
- X }
- X return s;
- }
- X
- /*
- X * Save the contents of the current
- X * buffer in its associatd file. Do nothing
- X * if nothing has changed (this may be a bug, not a
- X * feature). Error if there is no remembered file
- X * name for the buffer.
- X */
- filesave(f, n)
- {
- X register int s;
- X
- #if its_a_bug
- X if ((curbp->b_flag&BFCHG) == 0) /* Return, no changes. */
- X return TRUE;
- #endif
- X if (curbp->b_fname[0] == 0) { /* Must have a name. */
- X mlwrite("No file name");
- X return FALSE;
- X }
- X if ((s=writeout(curbp->b_fname,curbp,TRUE)) == TRUE) {
- X curbp->b_flag &= ~BFCHG;
- X markWFMODE(curbp);
- X }
- X return s;
- }
- X
- /*
- X * This function performs the details of file
- X * writing. Uses the file management routines in the
- X * "fileio.c" package. The number of lines written is
- X * displayed. Sadly, it looks inside a LINE; provide
- X * a macro for this. Most of the grief is error
- X * checking of some sort.
- X */
- writeout(fn,bp,msgf)
- char *fn;
- BUFFER *bp;
- {
- X register LINE *lp; /* current line */
- X register long numchars; /* # of chars in file */
- X REGION region;
- X
- X /* starting at the beginning of the buffer */
- X lp = lforw(bp->b_linep);
- X region.r_linep = lp;
- X region.r_offset = 0;
- X
- X /* start counting chars */
- X numchars = 0;
- X while (lp != bp->b_linep) {
- X numchars += llength(lp) + 1;
- X lp = lforw(lp);
- X }
- X region.r_size = numchars;
- X
- #if DOSFILES
- X dosfile = bp->b_mode & MDDOS;
- #endif
- X
- X return writereg(®ion,fn,msgf);
- }
- X
- writeregion(f,n)
- {
- X REGION region;
- X int s;
- X static char fname[NFILEN];
- SHAR_EOF
- true || echo 'restore of file.c failed'
- echo 'End of Vile part 6'
- echo 'File file.c is continued in part 7'
- echo 7 > _shar_seq_.tmp
- exit 0
- --
- paul fox, pgf@cayman.com, (617)494-1999
- Cayman Systems, 26 Landsdowne St., Cambridge, MA 02139
-