Path: utzoo!utgpu!cs.utexas.edu!sdd.hp.com!zaphod.mps.ohio-state.edu!think.com!cayman!pgf 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 Organization: Cayman Systems Inc., Cambridge Ma Lines: 1953 Submitted-by: pgf@cayman.com Archive-name: Vile/part05 #!/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 #include #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 #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 #include #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 #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 #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