home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Source Code 1992 March
/
Source_Code_CD-ROM_Walnut_Creek_March_1992.iso
/
usenet
/
altsrcs
/
3
/
3501
< prev
next >
Wrap
Internet Message Format
|
1991-06-19
|
56KB
From: pgf@cayman.COM (Paul Fox)
Newsgroups: alt.sources
Subject: Vile 05/17 - vi feel-alike (multi-window)
Message-ID: <4524@cayman.COM>
Date: 7 Jun 91 22:09:27 GMT
#!/bin/sh
# this is vileshar.05 (part 5 of Vile)
# do not concatenate these parts, unpack them in order with /bin/sh
# file efunc.h continued
#
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck
if test "$Scheck" != 5; then
echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
echo 'x - continuing file efunc.h'
sed 's/^X//' << 'SHAR_EOF' >> 'efunc.h' &&
#if ! SMALLER
X {"save-window", savewnd, NONE },
#endif
X {"scroll-next-up", scrnextup, NONE },
X {"scroll-next-down", scrnextdw, NONE },
X {"search-forward", forwsearch, ABS|MOTION },
X {"search-reverse", backsearch, ABS|MOTION },
X {"select-buffer", usebuffer, NONE },
X {"set", setmode, NONE },
X {"setall", showmodes, NONE },
X {"setg", setgmode, NONE },
X {"setgall", showgmodes, NONE },
X {"setgno", delgmode, NONE },
X {"setno", delmode, NONE },
#if ! SMALLER
X {"setv", setvar, NONE },
#endif
#if CRYPT
X {"set-encryption-key", setkey, NONE },
#endif
X {"set-fill-column", setfillcol, NONE },
X {"set-named-mark", setnmmark, NONE },
X {"set-mark", setmark, NONE },
X {"sh", spawncli, NONE },
X {"shell-command", spawn, NONE },
X {"shift-left-til", operlshift, REDO|UNDO },
X {"shift-right-til", operrshift, REDO|UNDO },
X {"show-modes", showmodes, NONE },
X {"show-global-modes", showgmodes, NONE },
X {"shrink-window", shrinkwind, NONE },
X {"split-current-window", splitwind, NONE },
X {"store-macro", storemac, NONE },
#if PROC
X {"store-procedure", storeproc, NONE },
#endif
#if BSD
X {"suspend-emacs", bktoshell, NONE },
#endif
#if TAGS
X {"ta", gototag, NONE },
X {"tag", gototag, NONE },
#endif
X {"toggle-buffer-list", togglelistbuffers, NONE },
#if ! SMALLER
X {"transpose-characters", twiddle, REDO|UNDO },
#endif
#if AEDIT
X {"trim-line", trim, REDO|UNDO },
#endif
X {"unbind-key", unbindkey, NONE },
X {"undo-change", undo, NONE },
X {"undo-line-changes", lineundo, NONE },
X {"universal-argument", unarg, NONE },
X {"unmark-buffer", unmark, NONE },
X {"unsetg", delgmode, NONE },
X {"unset", delmode, NONE },
X {"update-screen", upscreen, NONE },
X {"upper-til", operupper, REDO|UNDO },
X {"use-named-kill-register", usekreg, REDO },
X {"view-file", viewfile, NONE },
X {"w", filesave, NONE },
#if WORDPRO
X {"wc", wordcount, NONE },
#endif
X {"wq", writequit, NONE },
X {"wrap-word", wrapword, REDO|UNDO },
X {"write-file", filewrite, NONE },
X {"write-file-and-quit", writequit, NONE },
#if ! SMALLER
X {"write-message", writemsg, NONE },
#endif
X {"write-til", operwrite, NONE },
X {"x", quickexit, NONE },
X {"yank-line", yankline, NONE },
X {"yank-lines-til", operlineyank, NONE },
X {"yank-til", operyank, NONE },
X
X {"", NULL}
};
SHAR_EOF
echo 'File efunc.h is complete' &&
chmod 0444 efunc.h ||
echo 'restore of efunc.h failed'
Wc_c="`wc -c < 'efunc.h'`"
test 27465 -eq "$Wc_c" ||
echo 'efunc.h: original size 27465, current size' "$Wc_c"
# ============= epath.h ==============
echo 'x - extracting epath.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'epath.h' &&
/* EPATH: This file contains certain info needed to locate the
X MicroEMACS files on a system dependant basis.
X
X */
X
/* possible names and paths of help files under different OSs */
X
/* first two entries are default startup and help files, the rest are
X possible places to look for them */
X
char *pathname[] =
X
#if AMIGA
{
X ".vilerc",
X "vile.hlp",
X "",
X "sys:c/",
X "sys:t/",
X "sys:s/",
X ":c/",
X ":t/",
X ":s/"
};
#endif
X
#if ST520
{
X "vile.rc",
X "vile.hlp",
X "\\",
X "\\bin\\",
X "\\util\\",
X ""
};
#endif
X
#if FINDER
{
X "vile.rc",
X "vile.hlp",
X "/bin",
X "/sys/public",
X ""
};
#endif
X
#if MSDOS
{
X "vile.rc",
X "vile.hlp",
X "\\sys\\public\\",
X "\\usr\\bin\\",
X "\\bin\\",
X "\\",
X ""
};
#endif
X
#if V7 | BSD | USG
{
X ".vilerc",
X "vile.hlp",
X "/usr/local/",
X "/usr/lib/",
X "/usr/local/bin",
X "/usr/local/lib",
X ""
};
#endif
X
#if VMS
{
X "vile.rc",
X "vile.hlp",
X "",
X "sys$sysdevice:[vmstools]"
};
#endif
X
#define NPNAMES (sizeof(pathname)/sizeof(char *))
SHAR_EOF
chmod 0444 epath.h ||
echo 'restore of epath.h failed'
Wc_c="`wc -c < 'epath.h'`"
test 956 -eq "$Wc_c" ||
echo 'epath.h: original size 956, current size' "$Wc_c"
# ============= estruct.h ==============
echo 'x - extracting estruct.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'estruct.h' &&
/* ESTRUCT: Structure and preprocesser defines for
X vile. Reshaped from the original, which
X was for MicroEMACS 3.9
X
X vile is by Paul Fox
X MicroEmacs was written by Dave G. Conroy
X modified by Steve Wilhite, George Jones
X substantially modified by Daniel Lawrence
*/
X
#ifdef LATTICE
#undef LATTICE /* don't use their definitions...use ours */
#endif
#ifdef MSDOS
#undef MSDOS
#endif
#ifdef CPM
#undef CPM
#endif
#ifdef AMIGA
#undef AMIGA
#endif
#ifdef EGA
#undef EGA
#endif
X
/* Machine/OS definitions */
/* sun, mips, generic 386, ODT, and Ultrix, see below... */
/* unix flavors */
#define BSD 1 /* UNIX BSD 4.2 and ULTRIX */
#define USG 0 /* UNIX system V */
#define V7 0 /* V7 UNIX or Coherent or BSD4.2*/
X /* presumably also Minix? */
/* unix sub-flavors */
#define ODT 0 /* UNIX OPEN DESK TOP */
#define ULTRIX 0 /* UNIX ULTRIX */
#define POSIX 0
X
/* non-unix flavors */
#define AMIGA 0 /* AmigaDOS */
#define ST520 0 /* ST520, TOS */
#define MSDOS 0 /* MS-DOS */
#define CPM 0 /* CP/M-86 */
#define VMS 0 /* VAX/VMS */
X
/* the following overrides for sun, i386, and mips are for convenience only */
#if sun
# undef BSD
# undef USG
# define BSD 1 /* UNIX BSD 4.2 and ULTRIX */
# define USG 0 /* UNIX system V */
#endif
X
#if i386 || mips
# undef BSD
# undef USG
# define BSD 0 /* UNIX BSD 4.2 and ULTRIX */
# define USG 1 /* UNIX system V */
#endif
X
#if ODT
# undef POSIX
# undef BSD
# undef USG
# define POSIX 1
# define BSD 0 /* UNIX BSD 4.2 and ULTRIX */
# define USG 1 /* UNIX system V */
#endif
X
#if ULTRIX
# undef POSIX
# undef BSD
# undef USG
# define POSIX 1
# define BSD 1
# define USG 0 /* UNIX system V */
#endif
X
#define UNIX (V7 | BSD | USG) /* any unix */
X
#define OS (UNIX | AMIGA | ST520 | MSDOS | CPM | VMS)
#if ! OS
X you need to choose a system #define...
#endif
X
/* Porting constraints */
#define HAVE_MKDIR 1 /* if your system has the mkdir() system call */
#define SHORTNAMES 0 /* if your compiler insists on 7 char names */
X
/* Compiler definitions */
#define MWC86 0 /* marc williams compiler */
#define LATTICE 0 /* Lattice 2.14 thruough 3.0 compilers */
#define AZTEC 0 /* Aztec C 3.20e */
#define MSC 0 /* MicroSoft C compile version 3 & 4 */
#define TURBO 0 /* Turbo C/MSDOS */
X
/* Terminal Output definitions */
/* choose one of the following */
#define TERMCAP 1 /* Use TERMCAP */
#define ANSI 0 /* ANSI escape sequences */
#define AT386 0 /* AT style 386 unix console */
#define HP150 0 /* HP150 screen driver */
#define HP110 0 /* HP110 screen driver */
#define VMSVT 0 /* various VMS terminal entries */
#define VT52 0 /* VT52 terminal (Zenith). */
#define RAINBOW 0 /* Use Rainbow fast video. */
#define IBMPC 0 /* IBM-PC CGA/MONO/EGA driver */
#define DG10 0 /* Data General system/10 */
#define TIPC 0 /* TI Profesional PC driver */
#define Z309 0 /* Zenith 100 PC family driver */
#define MAC 0 /* Macintosh */
#define ATARI 0 /* Atari 520/1040ST screen */
#define NeWS 0 /* distributed */
X
/* Special keyboard definitions */
#define WANGPC 0 /* WangPC - mostly escape sequences */
/* the WANGPC stuff isn't in the cmdtbl keyboard definitions: sorry -- pgf */
X
/* Configuration options... pick and choose as you wish */
X
/* Appearance */
#define TYPEAH 1 /* type ahead causes screen refresh to be delayed */
#define REVSTA 1 /* Status line appears in reverse video */
#define COLOR 0 /* color commands and windows */
#define CLRMSG 0 /* space clears the message line with no insert */
X
/* Feature turnon/turnoff */
#define CTRLZ 0 /* add a ^Z at end of files under MSDOS only */
#define DOSFILES 1 /* turn on code for DOS mode (lines that end in crlf) */
X /* use DOSFILES, for instance, if you edit DOS- */
X /* created files under UNIX */
#define CFENCE 1 /* do fench matching in CMODE */
#define REBIND 1 /* permit rebinding of keys at run-time */
#define APROP 1 /* Add code for Apropos command (needs REBIND) */
#define FILOCK 0 /* file locking under unix BSD 4.2 (uses scanf) */
#define ISRCH 1 /* Incremental searches like ITS EMACS */
#define FLABEL 0 /* function key label code [HP150] */
#define CRYPT 0 /* file encryption? (not crypt(1) compatible!) */
#define MAGIC 1 /* include regular expression matching? */
#define TAGS 1 /* tags support. requires MAGIC */
#define WORDPRO 1 /* "Advanced" word processing features */
#define AEDIT 1 /* advanced editing options: e.g. en/detabbing */
#define PROC 1 /* named procedures */
#define FINDERR 1 /* finderr support. uses scanf() */
#define GLOBALS 1 /* "global" command support. */
#define PATHLOOK 1 /* look along $PATH for startup and help files */
#define SCROLLCODE 1 /* code in display.c for scrolling the screen.
X Only useful if your display can scroll
X regions, or at least insert/delete lines.
X ANSI, TERMCAP, and AT386 can do this */
X
#define CVMVAS 1 /* arguments to forward/back page and half page */
X /* are in pages instead of rows */
#define PRETTIER_SCROLL 1 /* can improve the appearance of a scrolling screen */
#define STUTTER_SEC_CMD 0 /* must the next/prev section commands (i.e.
X ']]' and '[[' be stuttered? they must be
X stuttered in real vi, I prefer them not
X to be */
X
/* Code size options */
#define FEWNAMES 0 /* strip some names - will no longer be bindable */
#define SMALLER 0 /* strip out a bunch of uemacs fluff */
X /* (to each their own... :-) pgf) */
X
/* Debugging options */
#define RAMSIZE 0 /* dynamic RAM memory usage tracking */
#define RAMSHOW 0 /* auto dynamic RAM reporting */
#define VMALLOC 0 /* verify malloc operation (slow!) */
#define DEBUG 1 /* allows core dump from keyboard under UNIX */
#define TIMING 0 /* shows user time spent on each user command */
X /* TIMING doesn't work yet... sorry -pgf */
#define DEBUGM 0 /* $debug triggers macro debugging */
#define VISMAC 0 /* update display during keyboard macros */
X
X
/* That's the end of the user selections -- the rest is static definition */
/* (i.e. you shouldn't need to touch anything below here */
/* ====================================================================== */
X
#if SHORTNAMES
#include "shorten/remap.h"
#endif
X
/* System dependant library redefinitions, structures and includes */
X
#if TURBO
#include <dos.h>
#include <mem.h>
#undef peek
#undef poke
#define peek(a,b,c,d) movedata(a,b,FP_SEG(c),FP_OFF(c),d)
#define poke(a,b,c,d) movedata(FP_SEG(c),FP_OFF(c),a,b,d)
#endif
X
#if VMS
#define atoi xatoi
#define abs xabs
#define getname xgetname
#endif
X
#if LATTICE
#define unsigned
#endif
X
#if AZTEC
#undef fputc
#undef fgetc
#if MSDOS
#define fgetc a1getc
#else
#define fgetc agetc
#endif
#define fputc aputc
#define int86 sysint
#define intdos(a, b) sysint(33, a, b)
#define inp inportb
#define outp outportb
X
struct XREG {
X int ax,bx,cx,dx,si,di;
};
X
struct HREG {
X char al,ah,bl,bh,cl,ch,dl,dh;
};
X
union REGS {
X struct XREG x;
X struct HREG h;
};
#endif
X
#if MSDOS & MWC86
#include <dos.h>
#define int86(a, b, c) intcall(b, c, a)
#define inp in
X
struct XREG {
X int ax,bx,cx,dx,si,di,ds,es,flags;
};
X
struct HREG {
X char al,ah,bl,bh,cl,ch,dl,dh;
X int ds,es,flags;
};
X
union REGS {
X struct XREG x;
X struct HREG h;
};
#endif
X
#if MSDOS & MSC
#include <dos.h>
#include <memory.h>
#define peek(a,b,c,d) movedata(a,b,FP_SEG(c),FP_OFF(c),d)
#define poke(a,b,c,d) movedata(FP_SEG(c),FP_OFF(c),a,b,d)
#define movmem(a, b, c) memcpy(b, a, c)
#endif
X
#if MSDOS & LATTICE
#undef CPM
#undef LATTICE
#include <dos.h>
#undef CPM
#endif
X
#if VMS
#define unlink(a) delete(a)
#endif
X
/* define some ability flags */
X
#if IBMPC | Z309
#define MEMMAP 1
#else
#define MEMMAP 0
#endif
X
#if ((MSDOS) & (LATTICE | AZTEC | MSC | TURBO)) | UNIX
#define ENVFUNC 1
#else
#define ENVFUNC 0
#endif
X
#if BSD
#define strchr index
#define strrchr rindex
#endif
X
#define TABVAL tabval
#define TABMASK tabmask
X
/* internal constants */
X
#define NBINDS 100 /* max # of bound prefixed keys */
#define NFILEN 80 /* # of bytes, file name */
#define NBUFN 20 /* # of bytes, buffer name */
#define NLINE 256 /* # of bytes, input line */
#define NSTRING 128 /* # of bytes, string buffers */
#define NKBDM 256 /* # of strokes, keyboard macro */
#define NPAT 128 /* # of bytes, pattern */
#define HUGE 60000 /* Huge number */
#define NLOCKS 100 /* max # of file locks active */
#define NCOLORS 8 /* number of supported colors */
#define KBLOCK 256 /* sizeof kill buffer chunks */
#define NKREGS 36 /* number of kill buffers */
#define NBLOCK 16 /* line block chunk size */
#define NVSIZE 10 /* max #chars in a var name */
X
/* SPEC is just 8th bit set, for convenience in some systems (like NeWS?) */
#define SPEC 0x0080 /* special key (function keys) */
#define CTLA 0x0100 /* ^A flag, or'ed in */
#define CTLX 0x0200 /* ^X flag, or'ed in */
X
#define kcod2key(c) (c & 0x7f) /* strip off the above prefixes */
X
#ifdef FALSE
#undef FALSE
#endif
#ifdef TRUE
#undef TRUE
#endif
X
#define FALSE 0 /* False, no, bad, etc. */
#define TRUE 1 /* True, yes, good, etc. */
#define ABORT 2 /* Death, ESC, abort, etc. */
#define FAILED 3 /* not-quite fatal false return */
#define SORTOFTRUE 4 /* really! */
X
#define STOP 0 /* keyboard macro not in use */
#define PLAY 1 /* " " playing */
#define RECORD 2 /* " " recording */
#define TMPSTOP 3 /* temporary stop, record can resume */
X
/* flook options */
#define FL_HERE 1
#define FL_HERE_HOME 2
#define FL_ANYWHERE 3
X
/* bfind options */
#define OK_CREAT TRUE
#define NO_CREAT FALSE
X
/* kbd_string options */
#define EXPAND TRUE
#define NO_EXPAND FALSE
X
/* Directive definitions */
X
#if ! SMALLER
X
#define DIF 0
#define DELSE 1
#define DENDIF 2
#define DGOTO 3
#define DRETURN 4
#define DENDM 5
#define DWHILE 6
#define DENDWHILE 7
#define DBREAK 8
#define DFORCE 9
X
#define NUMDIRS 10
X
#else
X
#define DENDM 0
#define NUMDIRS 1
X
#endif
X
/*
X * PTBEG, PTEND, FORWARD, and REVERSE are all toggle-able values for
X * the scan routines.
X */
#define PTBEG 0 /* Leave the point at the beginning on search */
#define PTEND 1 /* Leave the point at the end on search */
#define FORWARD 0 /* forward direction */
#define REVERSE 1 /* backwards direction */
X
#define FIOSUC 0 /* File I/O, success. */
#define FIOFNF 1 /* File I/O, file not found. */
#define FIOEOF 2 /* File I/O, end of file. */
#define FIOERR 3 /* File I/O, error. */
#define FIOMEM 4 /* File I/O, out of memory */
#define FIOFUN 5 /* File I/O, eod of file/bad line*/
X
/* two flavors of insert mode */
#define INSERT 1
#define OVERWRITE 2
X
/* kill register control */
#define KNEEDCLEAN 0x01 /* Kill register needs cleaning */
#define KYANK 0x02 /* Kill register resulted from yank */
#define KLINES 0x04 /* Kill register contains full lines */
#define KAPPEND 0x04 /* Kill register should be appended */
X
/* operator types. Needed mainly because word movement changes depending on
X whether operator is "delete" or not. Aargh. */
#define OPDEL 1
#define OPOTHER 2
X
/* define these so C-fence matching doesn't get confused when we're editing
X the cfence code itself */
#define LBRACE '{'
#define RBRACE '}'
X
X
#if UNIX
#define PATHCHR ':'
#else
#define PATHCHR ';'
#endif
X
/* how big is the ascii rep. of an int? */
#define INTWIDTH sizeof(int) * 3
X
/* Macro argument token types */
X
#define TKNUL 0 /* end-of-string */
#define TKARG 1 /* interactive argument */
#define TKBUF 2 /* buffer argument */
#define TKVAR 3 /* user variables */
#define TKENV 4 /* environment variables */
#define TKFUN 5 /* function.... */
#define TKDIR 6 /* directive */
#define TKLBL 7 /* line label */
#define TKLIT 8 /* numeric literal */
#define TKSTR 9 /* quoted string literal */
#define TKCMD 10 /* command name */
X
/* Internal defined functions */
X
#define nextab(a) ((a & ~TABMASK) + TABVAL)
X
#ifdef abs
#undef abs
#endif
X
/* these are the bits that go into the _chartypes_ array */
/* the macros below test for them */
#define N_chars 128
#define _upper 1 /* upper case */
#define _lower 2 /* lower case */
#define _digit 4 /* digits */
#define _space 8 /* whitespace */
#define _bspace 16 /* backspace character (^H, DEL, and user's) */
#define _cntrl 32 /* control characterts, including DEL */
#define _print 64 /* printable */
#define _punct 128 /* punctuation */
#define _ident 256 /* is typically legal in "normal" identifier */
#define _path 512 /* is typically legal in a file's pathname */
#define _wild 2048 /* is typically a shell wildcard char */
#define _linespec 4096 /* ex-style line range: 1,$ or 13,15 or % etc.*/
X
/* these intentionally match the ctypes.h definitions, except that
X they force the char to 7-bit ascii first */
#define istype(sometype,c) (_chartypes_[(c)&(N_chars-1)] & (sometype))
#define islower(c) istype(_lower, c)
#define isupper(c) istype(_upper, c)
#define isdigit(c) istype(_digit, c)
#define isspace(c) istype(_space, c)
#define iscntrl(c) istype(_cntrl, c)
#define isprint(c) istype(_print, c)
#define ispunct(c) istype(_punct, c)
#define iswild(c) istype(_wild, c)
#define isalpha(c) istype(_lower|_upper, c)
#define isalnum(c) istype(_lower|_upper|_digit, c)
#define isident(c) istype(_ident, c)
#define ispath(c) istype(_path, c)
#define isbackspace(c) istype(_bspace, c)
#define islinespecchar(c) istype(_linespec, c)
X
/* DIFCASE represents the difference between upper
X and lower case letters, DIFCNTRL the difference between upper case and
X control characters. They are xor-able values. */
#define DIFCASE 0x20
#define DIFCNTRL 0x40
#define toupper(c) ((c)^DIFCASE)
#define tolower(c) ((c)^DIFCASE)
#define tocntrl(c) ((c)^DIFCNTRL)
#define toalpha(c) ((c)^DIFCNTRL)
X
/* Dynamic RAM tracking and reporting redefinitions */
X
#if RAMSIZE
#define malloc allocate
#define free release
#endif
X
#if VMALLOC
char *vmalloc();
void vfree();
void rvverify();
char *vrealloc();
char *vcalloc();
void vdump();
# define malloc(x) vmalloc(x,__FILE__,__LINE__)
# define free(x) vfree(x,__FILE__,__LINE__)
# define realloc(x,y) vrealloc(x,y,__FILE__,__LINE__)
# define calloc(x,y) vcalloc(x,y,__FILE__,__LINE__)
# define vverify(s) rvverify(s,__FILE__,__LINE__)
#else
# define vverify(s) ;
#endif
X
/*
X * There is a window structure allocated for every active display window. The
X * windows are kept in a big list, in top to bottom screen order, with the
X * listhead at "wheadp". Each window contains its own values of dot and mark.
X * The flag field contains some bits that are set by commands to guide
X * redisplay. Although this is a bit of a compromise in terms of decoupling,
X * the full blown redisplay is just too expensive to run for every input
X * character.
X */
typedef struct WINDOW {
X struct WINDOW *w_wndp; /* Next window */
X struct BUFFER *w_bufp; /* Buffer displayed in window */
X struct LINE *w_linep; /* Top line in the window */
X struct LINE *w_dotp; /* Line containing "." */
X struct LINE *w_mkp; /* Line containing "mark" */
X struct LINE *w_ldmkp; /* Line containing "lastdotmark"*/
X int w_doto; /* Byte offset for "." */
X int w_mko; /* Byte offset for "mark" */
X int w_ldmko; /* Byte offset for "lastdotmark"*/
X int w_toprow; /* Origin 0 top row of window */
X int w_ntrows; /* # of rows of text in window */
X int w_force; /* If non-zero, forcing row. */
X int w_flag; /* Flags. */
X int w_sideways; /* sideways offset */
#if COLOR
X int w_fcolor; /* current forground color */
X int w_bcolor; /* current background color */
#endif
} WINDOW;
X
#define WFFORCE 0x01 /* Window needs forced reframe */
#define WFMOVE 0x02 /* Movement from line to line */
#define WFEDIT 0x04 /* Editing within a line */
#define WFHARD 0x08 /* Better do a full display */
#define WFMODE 0x10 /* Update mode line. */
#define WFCOLR 0x20 /* Needs a color change */
#define WFKILLS 0x40 /* something was deleted */
#define WFINS 0x80 /* something was inserted */
X
struct MARK {
X struct LINE *markp;
X int marko;
};
X
/*
X * Text is kept in buffers. A buffer header, described below, exists for every
X * buffer in the system. The buffers are kept in a big list, so that commands
X * that search for a buffer by name can find the buffer header. There is a
X * safe store for the dot and mark in the header, but this is only valid if
X * the buffer is not being displayed (that is, if "b_nwnd" is 0). The text for
X * the buffer is kept in a circularly linked list of lines, with a pointer to
X * the header line in "b_linep" Buffers may be "Inactive" which means the files associated with them
X * have not been read in yet. These get read in at "use buffer" time.
X */
typedef struct BUFFER {
X struct BUFFER *b_bufp; /* Link to next BUFFER */
X struct MARK *b_nmmarks; /* named marks a-z */
X struct LINE *b_linep; /* Link to the header LINE */
X struct LINE *b_dotp; /* Link to "." LINE structure */
X struct LINE *b_markp; /* The same as the above two, */
X struct LINE *b_ldmkp; /* The same as the above two, */
X int b_doto; /* Offset of "." in above LINE */
X int b_marko; /* same but for the "mark" */
X int b_ldmko; /* same but for the "last dot mark" */
X int b_sideways; /* sideways offset */
X int b_mode; /* editor mode of this buffer */
X struct LINE *b_udstks[2]; /* undo stack pointers */
X short b_udstkindx; /* which of above to use */
X struct LINE *b_uddotps[2]; /* Link to "." before undoable op*/
X int b_uddotos[2]; /* offset of "." before undoable op*/
X struct LINE *b_ulinep; /* pointer at 'Undo' line */
X int b_active; /* window activated flag */
X int b_nwnd; /* Count of windows on buffer */
X int b_flag; /* Flags */
X char b_fname[NFILEN]; /* File name */
X char b_bname[NBUFN]; /* Buffer name */
#if CRYPT
X char b_key[NPAT]; /* current encrypted key */
#endif
} BUFFER;
X
#define BFINVS 0x01 /* Internal invisable buffer */
#define BFCHG 0x02 /* Changed since last write */
#define BFSCRTCH 0x04 /* scratch -- gone on last close */
X
/* mode flags */
/* the first set are bitmapped, and are inherited from global to per-buffer */
#define NUMMODES 11 /* # of defined modes */
#define MDWRAP 0x0001 /* word wrap */
#define MDCMOD 0x0002 /* C indentation and fence match*/
#define MDSWRAP 0x0004 /* wrap-around search mode */
#define MDEXACT 0x0008 /* Exact matching for searches */
#define MDVIEW 0x0010 /* read-only buffer */
#define MDMAGIC 0x0020 /* regular expresions in search */
#define MDCRYPT 0x0040 /* encrytion mode active */
#define MDASAVE 0x0080 /* auto-save mode */
#define MDLIST 0x0100 /* "list" mode -- show tabs and EOL */
#define MDDOS 0x0200 /* "dos" mode -- lines end in crlf */
#define MDAIND 0x0400 /* auto-indent */
X
/* the next set are global, bit-mapped, but are meaningless per-buffer */
#define NUMOTHERMODES 2 /* # of defined modes */
#define OTH_LAZY 0x01
#define OTH_VERS 0x02
X
/* the last set are global, and have values */
#define NUMVALUEMODES 2 /* # of defined modes */
#define VAL_TAB 0
#define VAL_FILL 1
X
/*
X * The starting position of a region, and the size of the region in
X * characters, is kept in a region structure. Used by the region commands.
X */
typedef struct {
X struct LINE *r_linep; /* Origin LINE address. */
X int r_offset; /* Origin LINE offset. */
X struct LINE *r_endlinep; /* Ending LINE address. */
X int r_endoffset; /* Ending LINE offset. */
X long r_size; /* Length in characters. */
} REGION;
X
/*
X * All text is kept in circularly linked lists of "LINE" structures. These
X * begin at the header line. This line is pointed to by the "BUFFER".
X * Each line contains:
X * number of bytes in the line (the "used" size),
X * the size of the text array,
X * the text.
X * The end of line is not stored as a byte; it's implied. Future
X * additions may include update hints, and a list of marks into the line.
X *
X * Lines are additionally sometimes stacked in undo lists.
X */
typedef struct LINE {
X struct LINE *l_fp; /* Link to the next line */
X struct LINE *l_bp; /* Link to the previous line */
X int l_size; /* Allocated size */
X int l_used; /* Used size */
X char *l_text;
X union {
X struct LINE *l_stklnk; /* Link for undo stack */
X long l_flag; /* flags for undo ops */
X } l;
} LINE;
X
/* flag values */
#define LCOPIED 1 /* original line is already on an undo stack */
#define LGMARK 2 /* line matched a global scan */
X
/* macros to ease the use of lines */
#define lforw(lp) ((lp)->l_fp)
#define lback(lp) ((lp)->l_bp)
#define lgetc(lp, n) ((lp)->l_text[(n)]&0xFF)
#define lputc(lp, n, c) ((lp)->l_text[(n)]=(c))
#define llength(lp) ((lp)->l_used)
#define l_nxtundo l.l_stklnk
#define liscopied(lp) (lp->l.l_flag & LCOPIED)
#define lismarked(lp) (lp->l.l_flag & LGMARK)
#define lsetcopied(lp) (lp->l.l_flag |= LCOPIED)
#define lsetnotcopied(lp) (lp->l.l_flag &= ~LCOPIED)
#define lsetmarked(lp) (lp->l.l_flag |= LGMARK)
#define lsetnotmarked(lp) (lp->l.l_flag &= ~LGMARK)
#define lsetclear(lp) (lp->l.l_flag = 0)
#define LINENOTREAL ((int)(-1))
#define LINEUNDOPATCH ((int)(-2))
#define MARKPATCH ((int)(-3))
#define lisreal(lp) ((lp)->l_used >= 0)
#define lisnotreal(lp) ((lp)->l_used == LINENOTREAL)
#define lislinepatch(lp) ((lp)->l_used == LINEUNDOPATCH)
#define lismarkpatch(lp) ((lp)->l_used == MARKPATCH)
#define lispatch(lp) (lislinepatch(lp) || lismarkpatch(lp))
#define lneedscopying(lp) ((lp)->l_copied != TRUE)
X
/*
X * The editor communicates with the display using a high level interface. A
X * "TERM" structure holds useful variables, and indirect pointers to routines
X * that do useful operations. The low level get and put routines are here too.
X * This lets a terminal, in addition to having non standard commands, have
X * funny get and put character code too. The calls might get changed to
X * "termp->t_field" style in the future, to make it possible to run more than
X * one terminal type.
X */
typedef struct {
X int t_mrow; /* max number of rows allowable */
X int t_nrow; /* current number of rows used */
X int t_mcol; /* max Number of columns. */
X int t_ncol; /* current Number of columns. */
X int t_margin; /* min margin for extended lines*/
X int t_scrsiz; /* size of scroll region " */
X int t_pause; /* # times thru update to pause */
X int (*t_open)(); /* Open terminal at the start. */
X int (*t_close)(); /* Close terminal at end. */
X int (*t_kopen)(); /* Open keyboard */
X int (*t_kclose)(); /* close keyboard */
X int (*t_getchar)(); /* Get character from keyboard. */
X int (*t_putchar)(); /* Put character to display. */
X int (*t_flush)(); /* Flush output buffers. */
X int (*t_move)(); /* Move the cursor, origin 0. */
X int (*t_eeol)(); /* Erase to end of line. */
X int (*t_eeop)(); /* Erase to end of page. */
X int (*t_beep)(); /* Beep. */
X int (*t_rev)(); /* set reverse video state */
X int (*t_rez)(); /* change screen resolution */
#if COLOR
X int (*t_setfor)(); /* set forground color */
X int (*t_setback)(); /* set background color */
#endif
#if SCROLLCODE
X int (*t_scroll)(); /* scroll a region of the screen */
#endif
} TERM;
X
/* TEMPORARY macros for terminal I/O (to be placed in a machine
X dependant place later) */
X
#define TTopen (*term.t_open)
#define TTclose (*term.t_close)
#define TTkopen (*term.t_kopen)
#define TTkclose (*term.t_kclose)
#define TTgetc (*term.t_getchar)
#define TTputc (*term.t_putchar)
#define TTflush (*term.t_flush)
#define TTmove (*term.t_move)
#define TTeeol (*term.t_eeol)
#define TTeeop (*term.t_eeop)
#define TTbeep (*term.t_beep)
#define TTrev (*term.t_rev)
#define TTrez (*term.t_rez)
#if COLOR
#define TTforg (*term.t_setfor)
#define TTbacg (*term.t_setback)
#endif
X
X
/* Commands are represented as CMDFUNC structures, which contain a
X * pointer to the actual function, and flags which help to classify it.
X * (things like is it a MOTION, can it be UNDOne)
X *
X * These structures are generated automatically from the cmdtbl file,
X * and can be found in the file nefunc.h
*/
typedef struct {
X int (*c_func)(); /* function name is bound to */
X unsigned long c_flags; /* what sort of command is it? */
} CMDFUNC;
X
/* when referencing a command by name (e.g ":e file") it is looked up in
X * the nametbl, which is an array of NTAB structures, containing the
X * name, and a pointer to the CMDFUNC structure. There can be several
X * entries pointing at a single CMDFUNC, since a command might have
X * several synonymous names.
X *
X * The nametbl array is generated automatically from the cmdtbl file,
X * and can be found in the file nename.h
X */
typedef struct {
X char *n_name;
X CMDFUNC *n_cmd;
} NTAB;
X
/* when a command is referenced by bound key (like h,j,k,l, or "dd"), it
X * is looked up one of two ways: single character 7-bit ascii commands
X * (by far the majority) are simply indexed into a 128 element array of
X * CMDFUNC pointers. Other commands (those with ^A, ^X, or SPEC
X * prefixes) are searched for in a binding table, made up of KBIND
X * structures. This structure contains the command code, and again, a
X * pointer to the CMDFUNC structure for the command
X *
X * The asciitbl array, and the kbindtbl array are generated automatically
X * from the cmdtbl file, and can be found in the file nebind.h
X */
typedef struct {
X short k_code; /* Key code */
X CMDFUNC *k_cmd;
} KBIND;
X
X
/* these are the flags which can appear in the CMDFUNC structure, describing
X a command */
#define NONE 0
#define UNDO 0x01 /* command is undo-able, so clean up undo lists */
#define REDO 0x02 /* command is redo-able, record it for dotcmd */
#define MOTION 0x04 /* command causes motion, okay after operator cmds */
#define FL 0x08 /* if command causes motion, opers act on full lines */
#define ABS 0x10 /* command causes absolute (i.e. non-relative) motion */
#define GOAL 0x20 /* column goal should be retained */
#define GLOBOK 0x40 /* permitted after global command */
#define OPER 0x80 /* function is an operator, affects a region */
#define LISTED 0x100 /* internal use only -- used in describing bindings
X to only describe each once */
X
/* these flags are ex argument descriptors. I simply moved them over
X from elvis. Not all are used or honored or implemented */
#define FROM (1<<16) /* allow a linespec */
#define TO (2<<16) /* allow a second linespec */
#define BANG (4<<16) /* allow a ! after the command name */
#define EXTRA (8<<16) /* allow extra args after command name */
#define XFILE (16<<16) /* expand wildcards in extra part */
#define NOSPC (32<<16) /* no spaces allowed in the extra part */
#define DFLALL (64<<16) /* default file range is 1,$ */
#define DFLNONE (128<<16) /* no default file range */
#define NODFL (256<<16) /* do not default to the current file name */
#define EXRCOK (512<<16) /* can be in a .exrc file */
#define NL (1024<<16) /* if !exmode, then write a newline first */
#define PLUS (2048<<16) /* allow a line number, as in ":e +32 foo" */
#define ZERO (4096<<16) /* allow 0 to be given as a line number */
#define FILES (XFILE + EXTRA) /* multiple extra files allowed */
#define WORD1 (EXTRA + NOSPC) /* one extra word allowed */
#define FILE1 (FILES + NOSPC) /* 1 file allowed, defaults to current file */
#define NAMEDF (FILE1 + NODFL) /* 1 file allowed, defaults to "" */
#define NAMEDFS (FILES + NODFL) /* multiple files allowed, default is "" */
#define RANGE (FROM + TO) /* range of linespecs allowed */
X
/* The editor holds deleted text chunks in the KILL registers. The
X kill registers are logically a stream of ascii characters, however
X due to unpredicatable size, get implemented as a linked
X list of chunks. (The d_ prefix is for "deleted" text, as k_
X was taken up by the keycode structure)
*/
X
typedef struct KILL {
X struct KILL *d_next; /* link to next chunk, NULL if last */
X char d_chunk[KBLOCK]; /* deleted text */
} KILL;
X
typedef struct KILLREG {
X struct KILL *kbufp; /* current kill register chunk pointer */
X struct KILL *kbufh; /* kill register header pointer */
X int kused; /* # of bytes used in kill last chunk */
X short kbflag; /* flags describing kill register */
} KILLREG;
X
/* When the command interpretor needs to get a variable's name,
X rather than its value, it is passed back as a VDESC variable
X description structure. The v_num field is an index into the
X appropriate variable table.
*/
X
typedef struct VDESC {
X int v_type; /* type of variable */
X int v_num; /* ordinal pointer to variable in list */
} VDESC;
X
/* The !WHILE directive in the execution language needs to
X stack references to pending whiles. These are stored linked
X to each currently open procedure via a linked list of
X the following structure
*/
X
typedef struct WHBLOCK {
X LINE *w_begin; /* ptr to !while statement */
X LINE *w_end; /* ptr to the !endwhile statement*/
X int w_type; /* block type */
X struct WHBLOCK *w_next; /* next while */
} WHBLOCK;
X
#define BTWHILE 1
#define BTBREAK 2
X
/*
X * Incremental search defines.
X */
#if ISRCH
X
#define CMDBUFLEN 256 /* Length of our command buffer */
X
#define IS_REVERSE tocntrl('R') /* Search backward */
#define IS_FORWARD tocntrl('F') /* Search forward */
X
#endif
X
#if MAGIC
X
/*
X * Defines for the metacharacters in the regular expressions in search
X * routines.
X */
X
#define MCNIL 0 /* Like the '\0' for strings.*/
#define LITCHAR 1
#define ANY 2
#define CCL 3
#define NCCL 4
#define BOL 5
#define EOL 6
#define CLOSURE 256 /* An or-able value.*/
#define MASKCL CLOSURE - 1
X
#define MC_ANY '.' /* 'Any' character (except newline).*/
#define MC_CCL '[' /* Character class.*/
#define MC_NCCL '^' /* Negate character class.*/
#define MC_RCCL '-' /* Range in character class.*/
#define MC_ECCL ']' /* End of character class.*/
#define MC_BOL '^' /* Beginning of line.*/
#define MC_EOL '$' /* End of line.*/
#define MC_CLOSURE '*' /* Closure - does not extend past newline.*/
X
#define MC_ESC '\\' /* Escape - suppress meta-meaning.*/
X
#define BIT(n) (1 << (n)) /* An integer with one bit set.*/
#define CHCASE(c) ((c) ^ DIFCASE) /* Toggle the case of a letter.*/
X
/* HICHAR - 1 is the largest character we will deal with.
X * HIBYTE represents the number of bytes in the bitmap.
X */
X
#define HICHAR 256
#define HIBYTE HICHAR >> 3
X
typedef char *BITMAP;
X
typedef struct {
X short int mc_type;
X union {
X int lchar;
X BITMAP cclmap;
X } u;
} MC;
#endif
X
SHAR_EOF
chmod 0444 estruct.h ||
echo 'restore of estruct.h failed'
Wc_c="`wc -c < 'estruct.h'`"
test 30449 -eq "$Wc_c" ||
echo 'estruct.h: original size 30449, current size' "$Wc_c"
# ============= eval.c ==============
echo 'x - extracting eval.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'eval.c' &&
/* EVAL.C: Expresion evaluation functions for
X MicroEMACS
X
X written 1986 by Daniel Lawrence */
X
#include <stdio.h>
#include "estruct.h"
#include "edef.h"
#include "evar.h"
X
varinit() /* initialize the user variable list */
X
{
#if ! SMALLER
X register int i;
X
X for (i=0; i < MAXVARS; i++)
X uv[i].u_name[0] = 0;
#endif
}
X
#if ! SMALLER
char *gtfun(fname) /* evaluate a function */
char *fname; /* name of function to evaluate */
{
X register int fnum; /* index to function to eval */
X register int status; /* return status */
X char arg1[NSTRING]; /* value of first argument */
X char arg2[NSTRING]; /* value of second argument */
X char arg3[NSTRING]; /* value of third argument */
X static char result[2 * NSTRING]; /* string result */
#if ENVFUNC
X char *getenv();
#endif
X
X /* look the function up in the function table */
X fname[3] = 0; /* only first 3 chars significant */
X mklower(fname); /* and let it be upper or lower case */
X for (fnum = 0; fnum < NFUNCS; fnum++)
X if (strcmp(fname, funcs[fnum].f_name) == 0)
X break;
X
X /* return errorm on a bad reference */
X if (fnum == NFUNCS)
X return(errorm);
X
X /* if needed, retrieve the first argument */
X if (funcs[fnum].f_type >= MONAMIC) {
X if ((status = macarg(arg1)) != TRUE)
X return(errorm);
X
X /* if needed, retrieve the second argument */
X if (funcs[fnum].f_type >= DYNAMIC) {
X if ((status = macarg(arg2)) != TRUE)
X return(errorm);
X
X /* if needed, retrieve the third argument */
X if (funcs[fnum].f_type >= TRINAMIC)
X if ((status = macarg(arg3)) != TRUE)
X return(errorm);
X }
X }
X
X
X /* and now evaluate it! */
X switch (fnum) {
X case UFADD: return(itoa(atoi(arg1) + atoi(arg2)));
X case UFSUB: return(itoa(atoi(arg1) - atoi(arg2)));
X case UFTIMES: return(itoa(atoi(arg1) * atoi(arg2)));
X case UFDIV: return(itoa(atoi(arg1) / atoi(arg2)));
X case UFMOD: return(itoa(atoi(arg1) % atoi(arg2)));
X case UFNEG: return(itoa(-atoi(arg1)));
X case UFCAT: strcpy(result, arg1);
X return(strcat(result, arg2));
X case UFLEFT: return(strncpy(result, arg1, atoi(arg2)));
X case UFRIGHT: return(strcpy(result, &arg1[atoi(arg2)-1]));
X case UFMID: return(strncpy(result, &arg1[atoi(arg2)-1],
X atoi(arg3)));
X case UFNOT: return(ltos(stol(arg1) == FALSE));
X case UFEQUAL: return(ltos(atoi(arg1) == atoi(arg2)));
X case UFLESS: return(ltos(atoi(arg1) < atoi(arg2)));
X case UFGREATER: return(ltos(atoi(arg1) > atoi(arg2)));
X case UFSEQUAL: return(ltos(strcmp(arg1, arg2) == 0));
X case UFSLESS: return(ltos(strcmp(arg1, arg2) < 0));
X case UFSGREAT: return(ltos(strcmp(arg1, arg2) > 0));
X case UFIND: return(tokval(arg1));
X case UFAND: return(ltos(stol(arg1) && stol(arg2)));
X case UFOR: return(ltos(stol(arg1) || stol(arg2)));
X case UFLENGTH: return(itoa(strlen(arg1)));
X case UFUPPER: return(mkupper(arg1));
X case UFLOWER: return(mklower(arg1));
X case UFTRUTH: return(ltos(atoi(arg1) == 42));
X case UFASCII: return(itoa((int)arg1[0]));
X case UFCHR: result[0] = atoi(arg1);
X result[1] = 0;
X return(result);
X case UFGTKEY: result[0] = tgetc();
X result[1] = 0;
X return(result);
X case UFRND: return(itoa((ernd() % abs(atoi(arg1))) + 1));
X case UFABS: return(itoa(abs(atoi(arg1))));
X case UFSINDEX: return(itoa(sindex(arg1, arg2)));
X case UFENV:
#if ENVFUNC
X return(getenv(arg1) == NULL ? "" : getenv(arg1));
#else
X return("");
#endif
X case UFBIND: return(prc2engl(arg1));
X }
X
X exit(-11); /* never should get here */
}
X
char *gtusr(vname) /* look up a user var's value */
char *vname; /* name of user variable to fetch */
{
X
X register int vnum; /* ordinal number of user var */
X
X /* scan the list looking for the user var name */
X for (vnum = 0; vnum < MAXVARS; vnum++)
X if (strcmp(vname, uv[vnum].u_name) == 0)
X break;
X
X /* return errorm on a bad reference */
X if (vnum == MAXVARS)
X return(errorm);
X
X return(uv[vnum].u_value);
}
X
char *gtenv(vname)
char *vname; /* name of environment variable to retrieve */
{
X register int vnum; /* ordinal number of var refrenced */
X char *getkill();
X
X /* scan the list, looking for the referenced name */
X for (vnum = 0; vnum < NEVARS; vnum++)
X if (strcmp(vname, envars[vnum]) == 0)
X break;
X
X /* return errorm on a bad reference */
X if (vnum == NEVARS)
X return(errorm);
X
X /* otherwise, fetch the appropriate value */
X switch (vnum) {
X case EVFILLCOL: return(itoa(fillcol));
X case EVPAGELEN: return(itoa(term.t_nrow + 1));
X case EVCURCOL: return(itoa(getccol(FALSE)));
X case EVCURLINE: return(itoa(getcline()));
X case EVRAM: return(itoa((int)(envram / 1024l)));
X case EVFLICKER: return(ltos(flickcode));
X case EVCURWIDTH:return(itoa(term.t_nrow));
X case EVCBUFNAME:return(curbp->b_bname);
X case EVCFNAME: return(curbp->b_fname);
X case EVSRES: return(sres);
X case EVDEBUG: return(ltos(macbug));
X case EVSTATUS: return(ltos(cmdstatus));
X case EVPALETTE: return(palstr);
X case EVASAVE: return(itoa(gasave));
X case EVACOUNT: return(itoa(gacount));
X case EVLASTKEY: return(itoa(lastkey));
X case EVCURCHAR:
X return(curwp->w_dotp->l_used ==
X curwp->w_doto ? itoa('\n') :
X itoa(lgetc(curwp->w_dotp, curwp->w_doto)));
X case EVDISCMD: return(ltos(discmd));
X case EVVERSION: return(version);
X case EVPROGNAME:return(prognam);
X case EVSEED: return(itoa(seed));
X case EVDISINP: return(ltos(disinp));
X case EVWLINE: return(itoa(curwp->w_ntrows));
X case EVCWLINE: return(itoa(getwpos()));
X case EVSEARCH: return(pat);
X case EVREPLACE: return(rpat);
X case EVMATCH: return((patmatch == NULL)? "": patmatch);
X case EVKILL: return(getkill());
X case EVCMODE: return(itoa(curbp->b_mode));
X case EVGMODE: return(itoa(gmode));
X case EVTPAUSE: return(itoa(term.t_pause));
X case EVPENDING:
#if TYPEAH
X return(ltos(typahead()));
#else
X return(falsem);
#endif
X case EVLWIDTH: return(itoa(llength(curwp->w_dotp)));
X case EVLINE: return(getctext());
X }
X exit(-12); /* again, we should never get here */
}
X
char *getkill() /* return some of the contents of the kill buffer */
X
{
X register int size; /* max number of chars to return */
X char value[NSTRING]; /* temp buffer for value */
X
X if (kbs[0].kbufh == NULL)
X /* no kill buffer....just a null string */
X value[0] = 0;
X else {
X /* copy in the contents... */
X if (kbs[0].kused < NSTRING)
X size = kbs[0].kused;
X else
X size = NSTRING - 1;
X strncpy(value, kbs[0].kbufh->d_chunk, size);
X }
X
X /* and return the constructed value */
X return(value);
}
X
int setvar(f, n) /* set a variable */
X
int f; /* default flag */
int n; /* numeric arg (can overide prompted value) */
X
{
X register int status; /* status return */
#if DEBUGM
X register char *sp; /* temp string pointer */
X register char *ep; /* ptr to end of outline */
#endif
X VDESC vd; /* variable num/type */
X static char var[NVSIZE+1]; /* name of variable to fetch */
X char value[NSTRING]; /* value to set variable to */
X
X /* first get the variable to set.. */
X if (clexec == FALSE) {
X status = mlreply("Variable to set: ", &var[0], NVSIZE);
X if (status != TRUE)
X return(status);
X } else { /* macro line argument */
X /* grab token and skip it */
X execstr = token(execstr, var);
X }
X
X /* check the legality and find the var */
X findvar(var, &vd);
X
X /* if its not legal....bitch */
X if (vd.v_type == -1) {
X mlwrite("%%No such variable as '%s'", var);
X return(FALSE);
X }
X
X /* get the value for that variable */
X if (f == TRUE)
X strcpy(value, itoa(n));
X else {
X value[0] = 0;
X status = mlreply("Value: ", &value[0], NSTRING);
X if (status != TRUE)
X return(status);
X }
X
X /* and set the appropriate value */
X status = svar(&vd, value);
X
#if DEBUGM
X /* if $debug == TRUE, every assignment will echo a statment to
X that effect here. */
X
X if (macbug) {
X strcpy(outline, "(((");
X
X /* assignment status */
X strcat(outline, ltos(status));
X strcat(outline, ":");
X
X /* variable name */
X strcat(outline, var);
X strcat(outline, ":");
X
X /* and lastly the value we tried to assign */
X strcat(outline, value);
X strcat(outline, ")))");
X
X /* expand '%' to "%%" so mlwrite wont bitch */
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 to hold the output */
X if (kbd_key() == abortc) {
X mlforce("[Macro aborted]");
X status = FALSE;
X }
X }
#endif
X
X /* and return it */
X return(status);
}
X
findvar(var, vd) /* find a variables type and name */
X
char *var; /* name of var to get */
VDESC *vd; /* structure to hold type and ptr */
X
{
X register int vnum; /* subscript in varable arrays */
X register int vtype; /* type to return */
X
fvar: vtype = -1;
X switch (var[0]) {
X
X case '$': /* check for legal enviromnent var */
X for (vnum = 0; vnum < NEVARS; vnum++)
X if (strcmp(&var[1], envars[vnum]) == 0) {
X vtype = TKENV;
X break;
X }
X break;
X
X case '%': /* check for existing legal user variable */
X for (vnum = 0; vnum < MAXVARS; vnum++)
X if (strcmp(&var[1], uv[vnum].u_name) == 0) {
X vtype = TKVAR;
X break;
X }
X if (vnum < MAXVARS)
X break;
X
X /* create a new one??? */
X for (vnum = 0; vnum < MAXVARS; vnum++)
X if (uv[vnum].u_name[0] == 0) {
X vtype = TKVAR;
X strcpy(uv[vnum].u_name, &var[1]);
X break;
X }
X break;
X
X case '&': /* indirect operator? */
X var[4] = 0;
X if (strcmp(&var[1], "ind") == 0) {
X /* grab token, and eval it */
X execstr = token(execstr, var);
X strcpy(var, tokval(var));
X goto fvar;
X }
X }
X
X /* return the results */
X vd->v_num = vnum;
X vd->v_type = vtype;
X return;
}
X
int svar(var, value) /* set a variable */
X
VDESC *var; /* variable to set */
char *value; /* value to set to */
X
{
X register int vnum; /* ordinal number of var refrenced */
X register int vtype; /* type of variable to set */
X register int status; /* status return */
X register int c; /* translated character */
X register char * sp; /* scratch string pointer */
X
X /* simplify the vd structure (we are gonna look at it a lot) */
X vnum = var->v_num;
X vtype = var->v_type;
X
X /* and set the appropriate value */
X status = TRUE;
X switch (vtype) {
X case TKVAR: /* set a user variable */
X if (uv[vnum].u_value != NULL)
X free(uv[vnum].u_value);
X sp = malloc(strlen(value) + 1);
X if (sp == NULL)
X return(FALSE);
X strcpy(sp, value);
X uv[vnum].u_value = sp;
X break;
X
X case TKENV: /* set an environment variable */
X status = TRUE; /* by default */
X switch (vnum) {
X case EVFILLCOL: fillcol = atoi(value);
X break;
X case EVCURCOL: status = gotocol(TRUE,atoi(value));
X break;
X case EVCURLINE: status = gotoline(TRUE, atoi(value));
X break;
X case EVRAM: break;
X case EVFLICKER: flickcode = stol(value);
X break;
X case EVCURWIDTH:status = newwidth(TRUE, atoi(value));
X break;
X case EVPAGELEN: status = newlength(TRUE,atoi(value));
X break;
X case EVCBUFNAME:strcpy(curbp->b_bname, value);
X curwp->w_flag |= WFMODE;
X break;
X case EVCFNAME: strcpy(curbp->b_fname, value);
X curwp->w_flag |= WFMODE;
X break;
X case EVSRES: status = TTrez(value);
X break;
X case EVDEBUG: macbug = stol(value);
X break;
X case EVSTATUS: cmdstatus = stol(value);
X break;
X case EVPALETTE: strncpy(palstr, value, 48);
X spal(palstr);
X break;
X case EVASAVE: gasave = atoi(value);
X break;
X case EVACOUNT: gacount = atoi(value);
X break;
X case EVLASTKEY: lastkey = atoi(value);
X break;
X case EVCURCHAR: ldelete(1, FALSE); /* delete 1 char */
X c = atoi(value);
X if (c == '\n')
X lnewline(FALSE, 1);
X else
X linsert(1, c);
X backchar(FALSE, 1);
X break;
X case EVDISCMD: discmd = stol(value);
X break;
X case EVVERSION: break;
X case EVPROGNAME:break;
X case EVSEED: seed = atoi(value);
X break;
X case EVDISINP: disinp = stol(value);
X break;
X case EVWLINE: status = resize(TRUE, atoi(value));
X break;
X case EVCWLINE: status = forwline(TRUE,
X atoi(value) - getwpos());
X break;
X case EVSEARCH: strcpy(pat, value);
X rvstrcpy(tap, pat);
X mcclear();
X break;
X case EVREPLACE: strcpy(rpat, value);
X break;
X case EVMATCH: break;
X case EVKILL: break;
X case EVCMODE: curbp->b_mode = atoi(value);
X curwp->w_flag |= WFMODE;
X break;
X case EVGMODE: gmode = atoi(value);
X break;
X case EVTPAUSE: term.t_pause = atoi(value);
X break;
X case EVPENDING: break;
X case EVLWIDTH: break;
X case EVLINE: putctext(value);
X }
X break;
X }
X return(status);
}
#endif
X
/* atoi: ascii string to integer......This is too
X inconsistant to use the system's */
X
atoi(st)
char *st;
{
X int result; /* resulting number */
X int sign; /* sign of resulting number */
X char c; /* current char being examined */
X
X result = 0;
X sign = 1;
X
X /* skip preceding whitespace */
X while (isspace(*st))
X ++st;
X
X /* check for sign */
X if (*st == '-') {
X sign = -1;
X ++st;
X }
X if (*st == '+')
X ++st;
X
X /* scan digits, build value */
X while ((c = *st++))
X if (isdigit(c))
X result = result * 10 + c - '0';
X else
X return(0);
X
X return(result * sign);
}
X
#if ! SMALLER
X
/* itoa: integer to ascii string.......... This is too
X inconsistant to use the system's */
X
char *itoa(i)
int i; /* integer to translate to a string */
{
X register int digit; /* current digit being used */
X register char *sp; /* pointer into result */
X register int sign; /* sign of resulting number */
X static char result[INTWIDTH+1]; /* resulting string */
X
X /* record the sign...*/
X sign = 1;
X if (i < 0) {
X sign = -1;
X i = -i;
X }
X
X /* and build the string (backwards!) */
X sp = result + INTWIDTH;
X *sp = 0;
X do {
X digit = i % 10;
X *(--sp) = '0' + digit; /* and install the new digit */
X i = i / 10;
X } while (i);
X
X /* and fix the sign */
X if (sign == -1) {
X *(--sp) = '-'; /* and install the minus sign */
X }
X
X return(sp);
}
#endif
X
int toktyp(tokn) /* find the type of a passed token */
char *tokn; /* token to analyze */
{
X register char c; /* first char in token */
X
X /* grab the first char (this is all we need) */
X c = *tokn;
X
X /* no blanks!!! */
X if (c == 0)
X return(TKNUL);
X
X /* a numeric literal? */
X if (isdigit(c))
X return(TKLIT);
X
#if ! SMALLER
X switch (c) {
X case '"': return(TKSTR);
X
X case '~': return(TKDIR);
X case '@': return(TKARG);
X case '#': return(TKBUF);
X case '$': return(TKENV);
X case '%': return(TKVAR);
X case '&': return(TKFUN);
X case '*': return(TKLBL);
X
X default: return(TKCMD);
X }
#else
X return(TKCMD);
#endif
}
X
char *
tokval(tokn) /* find the value of a token */
char *tokn; /* token to evaluate */
{
#if ! SMALLER
X register int status; /* error return */
X register BUFFER *bp; /* temp buffer pointer */
X register int blen; /* length of buffer argument */
X register int distmp; /* temporary discmd flag */
X char pad[20]; /* pad 20 bytes on stack for safety */
X char buf[NSTRING]; /* string buffer for some returns */
X
X switch (toktyp(tokn)) {
X case TKNUL: return("");
X
X case TKARG: /* interactive argument */
X strcpy(tokn, tokval(&tokn[1]));
X distmp = discmd; /* echo it always! */
X discmd = TRUE;
X status = kbd_string(tokn,
X buf, NSTRING, '\n',EXPAND);
X discmd = distmp;
X if (status == ABORT)
X return(errorm);
X return(buf);
X
X case TKBUF: /* buffer contents fetch */
X
X /* grab the right buffer */
X strcpy(tokn, tokval(&tokn[1]));
X bp = bfind(tokn, NO_CREAT, 0);
X if (bp == NULL)
X return(errorm);
X
X /* if the buffer is displayed, get the window
X vars instead of the buffer vars */
X if (bp->b_nwnd > 0) {
X curbp->b_dotp = curwp->w_dotp;
X curbp->b_doto = curwp->w_doto;
X }
X
X /* make sure we are not at the end */
X if (bp->b_linep == bp->b_dotp)
X return(errorm);
X
X /* grab the line as an argument */
X blen = bp->b_dotp->l_used - bp->b_doto;
X if (blen > NSTRING)
X blen = NSTRING;
X strncpy(buf, bp->b_dotp->l_text + bp->b_doto,
X blen);
X buf[blen] = 0;
X
X /* and step the buffer's line ptr ahead a line */
X bp->b_dotp = bp->b_dotp->l_fp;
X bp->b_doto = 0;
X
X /* if displayed buffer, reset window ptr vars*/
X if (bp->b_nwnd > 0) {
X curwp->w_dotp = curbp->b_dotp;
X curwp->w_doto = 0;
X curwp->w_flag |= WFMOVE;
X }
X
X /* and return the spoils */
X return(buf);
X
X case TKVAR: return(gtusr(tokn+1));
X case TKENV: return(gtenv(tokn+1));
X case TKFUN: return(gtfun(tokn+1));
X case TKDIR: return(errorm);
X case TKLBL: return(itoa(gtlbl(tokn)));
X case TKLIT: return(tokn);
X case TKSTR: return(tokn+1);
X case TKCMD: return(tokn);
X }
#else
X return tokn;
#endif
}
X
#if ! SMALLER
X
gtlbl(tokn) /* find the line number of the given label */
char *tokn; /* label name to find */
{
X return(1);
}
X
int stol(val) /* convert a string to a numeric logical */
char *val; /* value to check for stol */
{
X /* check for logical values */
X if (val[0] == 'F')
X return(FALSE);
X if (val[0] == 'T')
X return(TRUE);
X
X /* check for numeric truth (!= 0) */
X return((atoi(val) != 0));
}
X
char *ltos(val) /* numeric logical to string logical */
int val; /* value to translate */
{
X if (val)
X return(truem);
X else
X return(falsem);
}
X
char *mkupper(str) /* make a string upper case */
char *str; /* string to upper case */
{
X char *sp;
X
X sp = str;
X while (*sp) {
X if (islower(*sp))
X *sp += 'A' - 'a';
X ++sp;
X }
X return(str);
}
#endif
X
#if ! SMALLER || MSDOS
X
char *mklower(str) /* make a string lower case */
char *str; /* string to lower case */
{
X char *sp;
X
X sp = str;
X while (*sp) {
X if (isupper(*sp))
X *sp += 'a' - 'A';
X ++sp;
X }
X return(str);
}
#endif
X
#if ! SMALLER
X
int abs(x) /* take the absolute value of an integer */
int x;
{
X return(x < 0 ? -x : x);
}
X
int ernd() /* returns a random integer */
{
X seed = abs(seed * 1721 + 10007);
X return(seed);
}
X
int sindex(source, pattern) /* find pattern within source */
char *source; /* source string to search */
char *pattern; /* string to look for */
{
X char *sp; /* ptr to current position to scan */
X char *csp; /* ptr to source string during comparison */
X char *cp; /* ptr to place to check for equality */
X
X /* scanning through the source string */
X sp = source;
X while (*sp) {
X /* scan through the pattern */
X cp = pattern;
X csp = sp;
X while (*cp) {
X if (!eq(*cp, *csp))
X break;
X ++cp;
X ++csp;
X }
X
X /* was it a match? */
X if (*cp == 0)
X return((int)(sp - source) + 1);
X ++sp;
X }
X
X /* no match at all.. */
X return(0);
}
X
#endif
SHAR_EOF
chmod 0444 eval.c ||
echo 'restore of eval.c failed'
Wc_c="`wc -c < 'eval.c'`"
test 18430 -eq "$Wc_c" ||
echo 'eval.c: original size 18430, current size' "$Wc_c"
# ============= evar.h ==============
echo 'x - extracting evar.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'evar.h' &&
/* EVAR.H: Environment and user variable definitions
X for MicroEMACS (and now vile)
X
X written 1986 by Daniel Lawrence
*/
X
#if !SMALLER
X
/* structure to hold user variables and their definitions */
X
typedef struct UVAR {
X char u_name[NVSIZE + 1]; /* name of user variable */
X char *u_value; /* value (string) */
} UVAR;
X
/* current user variables (This structure will probably change) */
X
#define MAXVARS 255
X
UVAR uv[MAXVARS]; /* user variables */
SHAR_EOF
true || echo 'restore of evar.h failed'
echo 'End of Vile part 5'
echo 'File evar.h is continued in part 6'
echo 6 > _shar_seq_.tmp
exit 0
--
paul fox, pgf@cayman.com, (617)494-1999
Cayman Systems, 26 Landsdowne St., Cambridge, MA 02139