home *** CD-ROM | disk | FTP | other *** search
- Subject: v08i012: A Micro-Emacs variant that resembles GNU Emacs
- Newsgroups: mod.sources
- Approved: mirror!rs
-
- Submitted by: Bob Larson <seismo!usc-oberon!blarson>
- Mod.sources: Volume 8, Issue 12
- Archive-name: micrognu/Part05
-
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # tty/termcap/ttykbd.c
- # sys/bsd/Makefile
- # sys/bsd/fileio.c
- # sys/bsd/spawn.c
- # sys/bsd/sysdef.h
- # sys/bsd/ttyio.c
- # sys/sysv/Makefile
- # sys/sysv/fileio.c
- # sys/sysv/spawn.c
- # sys/sysv/ttyio.c
- # sys/sysv/sysdef.h
- # sys/osk/readme.osk
- # sys/osk/sysdef.h
- # sys/osk/varargs.h
- # sys/osk/fileio.c
- # sys/osk/spawn.c
- # sys/osk/ttyio.c
- # sys/osk/makefile
- # This archive created: Sat Nov 15 15:16:30 1986
- export PATH; PATH=/bin:$PATH
- if test ! -d sys/bsd
- then
- mkdir sys/bsd
- fi
- if test ! -d sys/sysv
- then
- mkdir sys/sysv
- fi
- if test ! -d sys/osk
- then
- mkdir sys/osk
- fi
- if test -f 'tty/termcap/ttykbd.c'
- then
- echo shar: will not over-write existing file "'tty/termcap/ttykbd.c'"
- else
- cat << \SHAR_EOF > 'tty/termcap/ttykbd.c'
- /*
- * Name: MicroEmacs
- * Version: 30
- * Termcap keyboard driver
- * Created: 21-Aug-1986
- * Mic Kaczmarczik ...!ihnp4!seismo!ut-sally!ut-ngp!mic
- * Last edit: 03-Sep-86
- *
- * [ Several of the nasty comments about the XKEYS code are
- * by me. [Bob Larson (usc-oberon!blarson)] It is my opinion
- * that function keys cannot be made to work with standard
- * emacs keybindings except on a very limited set of terminals.
- * I just work with to many that do not fit the assumptions Mic's
- * XKEYS code makes to consider it useful to me, and think that
- * others considering using this code should look and see what
- * it realy does first.
- * ]
- *
- * If XKEYS is defined this routine looks for the following
- * termcap sequences, which are obtained by "tty.c":
- *
- * ks -- start using the function keypad
- * ke -- finish using the function keypad
- * kh -- home key
- * ku -- up arrow
- * kd -- down arrow
- * kl -- left arrow
- * kr -- right arrow
- * k0-k9 -- standard termcap function keys
- * l0-l9 -- labels for termcap function keys
- * (nonstandard)
- * K0-K9 -- extra keys that we look for -- the get mapped
- * internally to F10-F19
- * L0-L9 -- labels for same.
- *
- * Bugs/features/problems:
- *
- * XKEYS and DPROMPT do not work together well.
- *
- * If the META introducer is used as the initial character of
- * a function key sequence, what should the key parser do when the
- * user wants to type a META-ed key, or just the META introducer
- * alone? This is of practical importance on DEC terminals, where
- * the META introducer is the Escape key. Even worse things happen
- * on terminals that have something (or more than one thing) other
- * than the META introducer as the inital character of a function
- * sequence.
- *
- * The approach I took was that if the META introducer is the first
- * character in a function sequence, and the second character c
- * isn't part of a function key sequence, the parser returns
- * (KMETA | c). If it sees two META introducers in a row, it
- * returns one instance of METACH. This approach is subject to
- * discussion and debate, but it works. [In at lease some cases.]
- *
- * If the META introducer is NOT the first character in a function
- * sequence (including arrow keys) this code has a very nasty
- * side effect of eating that key. For example, on an Adds viewpoint
- * 60, six normal control characters are eaten if you have defined
- * XKEYS and put the keys in the termcap. More than a little
- * creativity is needed because ^U is one of the arrow keys, and
- * prefixes aren't bindable.
- *
- * [ From a quick look at the code, it seems that a single character
- * funciton key won't work, but it is still put in the table.
- * ]
- */
- #include "def.h"
-
- /*
- * Default key name table. Can be overridden by
- * definitions of l0-l9 in the termcap entry. You
- * can't redefine the names for the arrow keys
- * and the home key.
- */
-
- #ifdef XKEYS
- /* key sequences (from tty.c) */
- extern char *K[], *L[], *KS, *KE, *KH, *KU, *KD, *KL, *KR;
- extern int putpad(); /* also from tty.c */
- char *keystrings[] = {
- NULL, "Home", "Down-Arrow", "Up-Arrow",
- "Left-Arrow", "Right-Arrow", "F0", "F1",
- "F2", "F3", "F4", "F5",
- "F6", "F7", "F8", "F9",
- "F10", "F11", "F12", "F13",
- "F14", "F15", "F16", "F17",
- "F18", "F19", NULL, NULL,
- NULL, NULL, NULL, NULL
- };
- #else
- char *keystrings[] = {
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL
- };
- #endif
-
- #ifdef XKEYS
- /*
- * Type declarations for data structure we
- * use to parse for function key sequences
- */
- #define NODE 0 /* internal node */
- #define VALUE 1 /* internal key code value */
- #define SENTINEL 2 /* sentinel value */
-
- typedef struct trienode {
- int type; /* one of NODE, LEAF */
- struct trienode *sibling, *child;
- KEY value;
- } TRIENODE, *TRIE;
-
- TRIE keywords, sentinel, talloc(), tinsert();
- #endif
-
- /*
- * Get keyboard character, and interpret
- * any special keys on the keyboard. If XKEYS is
- * #defined, use a dictionary organized as a
- * trie to keep the parsing overhead down.
- *
- * To keep the function call overhead down, do the
- * first level of parse() inside getkbd().
- *
- * Also, since ESC (the usual value of METACH) is
- * the first character in many function key sequences,
- * we return (KMETA | ch) if METACH-<ch> is not
- * the start of an escape sequence. Blecch. Furthermore,
- * if we see METACH-METACH, we return the value METACH.
- * Phhhht.
- */
- getkbd() {
- #ifndef XKEYS
- return (ttgetc());
- #else
- register TRIE t;
- register int c;
- KEY code;
-
- c = ttgetc();
- for (t = keywords; t->type == NODE; t = t->sibling)
- if (t->value == c) { /* possible function key sequence */
- if (c != METACH)
- return (parse(t->child));
- else { /* maybe sequence, maybe META char */
- c = ttgetc();
- for (t = t->child; t->type == NODE; t = t->sibling)
- if (t->value == c)
- return (parse(t->child));
- /* METACH-METACH -> METACH */
- if (c == METACH)
- return (METACH);
- /* Else make c into a META character */
- if (ISLOWER(c) != FALSE)
- c = TOUPPER(c);
- if (c>=0x00 && c<=0x1F)
- c = KCTRL | (c+'@');
- return (KMETA | c);
- }
- }
- return (c);
- #endif
- }
-
- #ifdef XKEYS
- static parse(first)
- TRIE first;
- {
- register TRIE t;
- register int c;
-
- if (first->type == VALUE) /* found a match! */
- return (first->value);
-
- c = ttgetc();
- for (t = first; t->type == NODE; t = t->sibling)/* look thru list */
- if (t->value == c)
- return (parse(t->child)); /* try next level */
- return (c); /* nothing matched */
- }
- #endif
-
- /*
- * If XKEYS is defined, get key definitions from the termcap
- * entry and put them in the parse table.
- */
- ttykeymapinit()
- {
- #ifdef XKEYS
- register int i;
- register int s;
- register char *cp;
- register SYMBOL *sp;
-
- if (KS && *KS) /* turn on keypad */
- putpad(KS);
-
- tinit(); /* set up initial trie */
-
- for (i = 0; i < NFKEYS; i++) {
- if (K[i] && *K[i])
- adddict(K[i], (KEY) (KF0 + i));
- if (L[i] && *L[i]) /* record new name */
- keystrings[(KF0-KFIRST)+i] = L[i];
- }
-
- /*
- * Add the home and arrow keys
- */
- if (KH && *KH)
- adddict(KH, (KEY) KHOME);
- if (KU && *KU)
- adddict(KU, (KEY) KUP);
- if (KD && *KD)
- adddict(KD, (KEY) KDOWN);
- if (KL && *KL)
- adddict(KL, (KEY) KLEFT);
- if (KR && *KR)
- adddict(KR, (KEY) KRIGHT);
-
- /*
- * Bind things to the movement keys
- */
- keydup(KHOME, "beginning-of-buffer"); /* for now */
- keydup(KUP, "previous-line");
- keydup(KDOWN, "next-line");
- keydup(KLEFT, "backward-char");
- keydup(KRIGHT, "forward-char");
-
- /*
- * These bindings sort of go with the termcap I use for my vt220
- * clone, which is why they're #ifdef'd. I don't really use
- * them, but it gives you an example of what to do...
- */
- #ifdef MPK
- keydup((KEY)KF0, "describe-key-briefly"); /* Help */
- keydup((KEY)KF1, "execute-extended-command"); /* Do */
- keydup((KEY)KF2, "search-forward"); /* Find */
- keydup((KEY)KF3, "yank"); /* Insert here */
- keydup((KEY)KF4, "kill-region"); /* Remove */
- keydup((KEY)KF5, "set-mark-command"); /* Select */
- keydup((KEY)KF6, "scroll-down"); /* Prev Screen */
- keydup((KEY)KF7, "scroll-up"); /* Next Screen */
-
- /* Don't expect these to make much sense, I'm just filling in */
- /* the keymap B-] */
- keydup((KEY)KF10, "suspend-emacs"); /* PF1 */
- keydup((KEY)KF11, "query-replace"); /* PF2 */
- keydup((KEY)KF12, "call-last-kbd-macro"); /* PF3 */
- keydup((KEY)KF13, "save-buffers-kill-emacs"); /* PF4 */
- #endif MPK
- #endif XKEYS
- }
-
- #ifdef XKEYS
- /*
- * Clean up the keyboard -- called by tttidy()
- */
- ttykeymaptidy()
- {
- tdelete(keywords); /* get rid of parse tree */
- free(sentinel); /* remove sentinel value */
- if (KE && *KE)
- putpad(KE); /* turn off keypad */
- }
-
- /*
- * * * * * * * * Dictionary management * * * * * * * * *
- */
-
- /*
- * Add a key string to the dictionary.
- */
-
- static adddict(kstr, kcode)
- char *kstr;
- KEY kcode;
- {
- keywords = tinsert(kstr, kcode, keywords);
- }
-
- /*
- * Initialize the parse tree by creating the sentinel value
- */
-
- static tinit()
- {
- keywords = sentinel = talloc();
- sentinel->type = SENTINEL;
- sentinel->value = (KEY) -1;
- sentinel->sibling = sentinel->child = sentinel; /* set up a loop */
- }
-
- /*
- * Deallocate all the space used by the trie --
- * Tell all the siblings to deallocate space, then
- * all the children.
- */
-
- static tdelete(t)
- register TRIE t;
- {
- if (t->type != SENTINEL) {
- tdelete(t->sibling);
- tdelete(t->child);
- free(t);
- }
- }
-
- /*
- * Insert a dictionary key string and a value into the dictionary,
- * returning as the value the first sibling in the current sublevel,
- * which may have been changed by an insertion into the list of siblings.
- */
-
- static TRIE tinsert(kstring, kcode, first)
- register char *kstring;
- register KEY kcode;
- TRIE first;
- {
- register TRIE match;
- register TRIE p;
-
- if (!*kstring) { /* base case -- return a value node */
- p = talloc();
- p->type = VALUE;
- p->value = kcode;
- p->sibling = p->child = sentinel;
- return (p);
- }
- /* recursive case -- insert rest of string in trie */
-
- /* search for sibling that matches the current character */
- match = NULL;
- for (p = first; p->type == NODE; p = p->sibling)
- if (p->value == *kstring) {
- match = p;
- break;
- }
-
- if (match == NULL) { /* if not, add it to beginning of the list */
- match = talloc();
- match->type = NODE;
- match->value = *kstring;
- match->sibling = first;
- match->child = sentinel;
- first = match;
- }
- /* add rest of string to this child's subtrie */
- match->child = tinsert(kstring+1, kcode, match->child);
- return (first);
- }
-
- /*
- * Allocate a trie node
- */
- static TRIE talloc()
- {
- char *malloc();
- TRIE t;
-
- if ((t = (TRIE) malloc(sizeof(TRIENODE))) == NULL)
- panic("talloc: can't allocate trie node!");
- return (t);
- }
- #endif
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/bsd/Makefile'
- then
- echo shar: will not over-write existing file "'sys/bsd/Makefile'"
- else
- cat << \SHAR_EOF > 'sys/bsd/Makefile'
- # Makefile for MicroEMACS.
- # Is there a better way to do the rebuilds, other than using
- # the links?
-
- SYS = bsd
- TTY = termcap
- LIBS = -ltermcap
- # CDEFS gets defines, and gets passed to lint. CFLAGS gets flags, and doesn't
- # get passed to lint.
- CDEFS = -DDO_METAKEY -DSTARTUP
- CFLAGS = -g $(CDEFS)
-
- OBJ = basic.o buffer.o cinfo.o display.o echo.o extend.o file.o kbd.o \
- line.o main.o match.o random.o region.o search.o symbol.o version.o \
- window.o paragraph.o prefix.o \
- word.o fileio.o spawn.o ttyio.o tty.o ttykbd.o
- OSRCS = fileio.c spawn.c ttyio.c tty.c ttykbd.c
- SRCS = basic.c buffer.c cinfo.c display.c echo.c extend.c file.c kbd.c \
- line.c main.c match.c random.c region.c search.c symbol.c version.c \
- window.c word.c paragraph.c prefix.c
- OINCS = ttydef.h sysdef.h
- INCS = def.h
-
- mg: $(OBJ)
- cc $(CFLAGS) -o mg $(OBJ) $(LIBS)
-
- # the v arg to lint turns off all the complaints about args f, n & k.
- # It's a good idea to take that out and rerun make lint after getting
- # a clean lint, just to verify that f, n & k are the ONLY unused args.
- lint: $(SRCS) $(OSRCS)
- lint -ahb $(CDEFS) $(SRCS) $(OSRCS)
-
- $(OBJ): def.h sysdef.h ttydef.h
-
- sysdef.h: sys/$(SYS)/sysdef.h # Update links, if needed.
- rm -f sysdef.h
- ln sys/$(SYS)/sysdef.h .
-
- ttydef.h: tty/$(TTY)/ttydef.h
- rm -f ttydef.h
- ln tty/$(TTY)/ttydef.h .
-
- fileio.c: sys/$(SYS)/fileio.c
- rm -f fileio.c
- ln sys/$(SYS)/fileio.c .
-
- spawn.c: sys/$(SYS)/spawn.c
- rm -f spawn.c
- ln sys/$(SYS)/spawn.c .
-
- tty.c: tty/$(TTY)/tty.c
- rm -f tty.c
- ln tty/$(TTY)/tty.c .
-
- ttyio.c: sys/$(SYS)/ttyio.c
- rm -f ttyio.c
- ln sys/$(SYS)/ttyio.c .
-
- ttykbd.c: tty/$(TTY)/ttykbd.c
- rm -f ttykbd.c
- ln tty/$(TTY)/ttykbd.c .
-
- port: $(SRCS) $(INCS)
- rm -f port
- tar cfb port 1 $?
-
- clean:; rm -f $(OBJ) $(OSRCS) $(OINCS)
-
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/bsd/fileio.c'
- then
- echo shar: will not over-write existing file "'sys/bsd/fileio.c'"
- else
- cat << \SHAR_EOF > 'sys/bsd/fileio.c'
- /*
- * bsd (4.2, others?) and Ultrix-32 file I/O.
- */
- #include "def.h"
-
- static FILE *ffp;
- extern char *getenv();
-
- /*
- * handle C-shell style names
- */
- static char *bsd(fn, buf, bufsiz) char *fn, *buf; int bufsiz;
- {
- if (*fn != '~')
- return (fn);
- else { /* C-shell $HOME-relative names */
- strncpy(buf, getenv("HOME"), bufsiz);
- strncat(buf, fn + 1, bufsiz);
- return (buf);
- }
- }
-
- /*
- * Open a file for reading.
- */
- ffropen(fn) char *fn; {
- char buf[NFILEN];
- fn = bsd(fn, buf, sizeof(buf));
- if ((ffp=fopen(fn, "r")) == NULL)
- return (FIOFNF);
- return (FIOSUC);
- }
-
- /*
- * Open a file for writing.
- * Return TRUE if all is well, and
- * FALSE on error (cannot create).
- */
- ffwopen(fn) char *fn; {
- char buf[NFILEN];
- fn = bsd(fn, buf, sizeof(buf));
- if ((ffp=fopen(fn, "w")) == NULL) {
- ewprintf("Cannot open file for writing");
- return (FIOERR);
- }
- return (FIOSUC);
- }
-
- /*
- * Close a file.
- * Should look at the status.
- */
- ffclose() {
- (VOID) fclose(ffp);
- return (FIOSUC);
- }
-
- /*
- * Write a line to the already
- * opened file. The "buf" points to the
- * buffer, and the "nbuf" is its length, less
- * the free newline. Return the status.
- * Check only at the newline.
- */
- ffputline(buf, nbuf) register char buf[]; {
- register int i;
-
- /* What's with putc? */
- for (i=0; i<nbuf; ++i)
- putc(buf[i]&0xFF, ffp);
- putc('\n', ffp);
- if (ferror(ffp) != FALSE) {
- ewprintf("Write I/O error");
- return (FIOERR);
- }
- return (FIOSUC);
- }
-
- /*
- * Read a line from a file, and store the bytes
- * in the supplied buffer. Stop on end of file or end of
- * line. Don't get upset by files that don't have an end of
- * line on the last line; this seem to be common on CP/M-86 and
- * MS-DOS (the suspected culprit is VAX/VMS kermit, but this
- * has not been confirmed. If this is sufficiently researched
- * it may be possible to pull this kludge). Delete any CR
- * followed by an LF. This is mainly for runoff documents,
- * both on VMS and on Ultrix (they get copied over from
- * VMS systems with DECnet).
- */
- ffgetline(buf, nbuf) register char buf[]; {
- register int c;
- register int i;
-
- i = 0;
- for (;;) {
- c = getc(ffp);
- if (c == '\r') { /* Delete any non-stray */
- c = getc(ffp); /* carriage returns. */
- if (c != '\n') {
- if (i >= nbuf-1) {
- ewprintf("File has long line");
- return (FIOERR);
- }
- buf[i++] = '\r';
- }
- }
- if (c==EOF || c=='\n') /* End of line. */
- break;
- if (i >= nbuf-1) {
- ewprintf("File has long line");
- return (FIOERR);
- }
- buf[i++] = c;
- }
- if (c == EOF) { /* End of file. */
- if (ferror(ffp) != FALSE) {
- ewprintf("File read error");
- return (FIOERR);
- }
- if (i == 0) /* Don't get upset if */
- return (FIOEOF); /* no newline at EOF. */
- }
- buf[i] = 0;
- return (FIOSUC);
- }
-
- #if BACKUP
- /*
- * Rename the file "fname" into a backup
- * copy. On Unix the backup has the same name as the
- * original file, with a "~" on the end; this seems to
- * be newest of the new-speak. The error handling is
- * all in "file.c". The "unlink" is perhaps not the
- * right thing here; I don't care that much as
- * I don't enable backups myself.
- */
- fbackupfile(fn) char *fn; {
- register char *nname;
- char *malloc();
- char buf[NFILEN];
-
- fn = bsd(fn, buf, sizeof(buf));
- if ((nname=malloc(strlen(fn)+1+1)) == NULL) {
- ewprintf("Can't get %d bytes", strlen(fn) + 1);
- return (ABORT);
- }
- (void) strcpy(nname, fn);
- (void) strcat(nname, "~");
- (void) unlink(nname); /* Ignore errors. */
- if (rename(fn, nname) < 0) {
- free(nname);
- return (FALSE);
- }
- free(nname);
- return (TRUE);
- }
- #endif
- /*
- * The string "fn" is a file name.
- * Perform any required case adjustments. All sustems
- * we deal with so far have case insensitive file systems.
- * We zap everything to lower case. The problem we are trying
- * to solve is getting 2 buffers holding the same file if
- * you visit one of them with the "caps lock" key down.
- * On UNIX file names are dual case, so we leave
- * everything alone.
- */
- /*ARGSUSED*/
- adjustcase(fn) register char *fn; {
- #if 0
- register int c;
-
- while ((c = *fn) != 0) {
- if (c>='A' && c<='Z')
- *fn = c + 'a' - 'A';
- ++fn;
- }
- #endif
- }
-
- #ifdef STARTUP
- #include <sys/file.h>
- /*
- * find the users startup file, and return it's name. Check for
- * $HOME/.mg then for $HOME/.emacs, then give up.
- */
- char *
- startupfile() {
- register char *file;
- static char home[NFILEN];
- char *getenv();
-
- if ((file = getenv("HOME")) == NULL) return NULL;
- if (strlen(file)+7 >= NFILEN - 1) return NULL;
- (VOID) strcpy(home, file);
- file = &(home[strlen(home)]);
- *file++ = '/';
-
- (VOID) strcpy(file, ".mg");
- if (access(home, F_OK ) == 0) return home;
-
- (VOID) strcpy(file, ".emacs");
- if (access(home, F_OK) == 0) return home;
-
- return NULL;
- }
- #endif
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/bsd/spawn.c'
- then
- echo shar: will not over-write existing file "'sys/bsd/spawn.c'"
- else
- cat << \SHAR_EOF > 'sys/bsd/spawn.c'
- /*
- * Spawn. New version, which
- * interracts with the job control stuff
- * in the 4.X BSD C shell.
- * Last edit: Wed Aug 27 11:16:07 PDT 1986
- * By: rtech!daveb, to use stop for ksh.
- */
- #include "def.h"
-
- #include <sgtty.h>
- #include <signal.h>
-
- char *shellp = NULL; /* Saved "SHELL" name. */
-
- extern struct sgttyb oldtty; /* There really should be a */
- extern struct sgttyb newtty; /* nicer way of doing this, so */
- extern struct sgttyb oldtchars; /* spawn does not need to know */
- extern struct sgttyb newtchars; /* about the insides of the */
- extern struct sgttyb oldltchars; /* terminal I/O code. */
- extern struct sgttyb newltchars;
-
- extern char *getenv();
-
- /*
- * This code does a one of 2 different
- * things, depending on what version of the shell
- * you are using. If you are using the C shell, which
- * implies that you are using job control, then MicroEMACS
- * moves the cursor to a nice place and sends itself a
- * stop signal. If you are using the Bourne shell it runs
- * a subshell using fork/exec. Bound to "C-C", and used
- * as a subcommand by "C-Z".
- *
- * Daveb -- changed sense of test so that we only spawn if you
- * are explicitly using /bin/sh. This makes it stop
- * work with the ksh.
- */
- /*ARGSUSED*/
- spawncli(f, n, k) {
- register int pid, wpid, (*oqsig)(), (*oisig)(), omask;
- int status;
-
- if (shellp == NULL) {
- shellp = getenv("SHELL");
- if (shellp == NULL)
- shellp = getenv("shell");
- if (shellp == NULL)
- shellp = "/bin/sh"; /* Safer. */
- }
- ttcolor(CTEXT);
- ttnowindow();
- if (strcmp(shellp, "/bin/csh") == 0) {
- if (epresf != FALSE) {
- ttmove(nrow-1, 0);
- tteeol();
- epresf = FALSE;
- } /* Csh types a "\n" */
- ttmove(nrow-2, 0); /* before "Stopped". */
- } else {
- ttmove(nrow-1, 0);
- if (epresf != FALSE) {
- tteeol();
- epresf = FALSE;
- }
- }
- ttflush();
- if (ioctl(0, TIOCSLTC, (char *) &oldltchars) < 0
- || ioctl(0, TIOCSETC, (char *) &oldtchars) < 0
- || ioctl(0, TIOCSETP, (char *) &oldtty) < 0) {
- ewprintf("IOCTL #1 to terminal failed");
- return (FALSE);
- }
- if (strcmp(shellp, "/bin/sh") != 0) { /* C shell, ksh */
- omask = sigsetmask(0);
- (void) kill(0, SIGTSTP);
- setttysize() ;
- (void) sigsetmask(omask);
- } else { /* Bourne shell. */
- oqsig = signal(SIGQUIT, SIG_IGN);
- oisig = signal(SIGINT, SIG_IGN);
- if ((pid=fork()) < 0) {
- (void) signal(SIGQUIT, oqsig);
- (void) signal(SIGINT, oisig);
- ewprintf("Failed to create process");
- return (FALSE);
- }
- if (pid == 0) {
- execl(shellp, "sh", "-i", NULL);
- _exit(0); /* Should do better! */
- }
- while ((wpid=wait(&status))>=0 && wpid!=pid)
- ;
- (void) signal(SIGQUIT, oqsig);
- (void) signal(SIGINT, oisig);
- }
- sgarbf = TRUE; /* Force repaint. */
- if (ioctl(0, TIOCSETP, (char *) &newtty) < 0
- || ioctl(0, TIOCSETC, (char *) &newtchars) < 0
- || ioctl(0, TIOCSLTC, (char *) &newltchars) < 0) {
- ewprintf("IOCTL #2 to terminal failed");
- return (FALSE);
- }
- return (TRUE);
- }
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/bsd/sysdef.h'
- then
- echo shar: will not over-write existing file "'sys/bsd/sysdef.h'"
- else
- cat << \SHAR_EOF > 'sys/bsd/sysdef.h'
- /*
- * Ultrix-32 system header file.
- */
- #define PCC 1 /* "[]" gets an error. */
- #define KBLOCK 8192 /* Kill grow. */
- #define GOOD 0 /* Good exit status. */
-
- typedef int RSIZE; /* Type for file/region sizes */
- typedef short KEY; /* Type for internal keystrokes */
-
- /*
- * Macros used by the buffer name making code.
- * Start at the end of the file name, scan to the left
- * until BDC1 (or BDC2, if defined) is reached. The buffer
- * name starts just to the right of that location, and
- * stops at end of string (or at the next BDC3 character,
- * if defined). BDC2 and BDC3 are mainly for VMS.
- */
- #define BDC1 '/' /* Buffer names. */
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/bsd/ttyio.c'
- then
- echo shar: will not over-write existing file "'sys/bsd/ttyio.c'"
- else
- cat << \SHAR_EOF > 'sys/bsd/ttyio.c'
- /*
- * Ultrix-32 and Unix terminal I/O.
- * The functions in this file
- * negotiate with the operating system for
- * keyboard characters, and write characters to
- * the display in a barely buffered fashion.
- */
- #include "def.h"
-
- #include <sgtty.h>
-
- #define NOBUF 512 /* Output buffer size. */
-
- char obuf[NOBUF]; /* Output buffer. */
- int nobuf;
- struct sgttyb oldtty; /* V6/V7 stty data. */
- struct sgttyb newtty;
- struct tchars oldtchars; /* V7 editing. */
- struct tchars newtchars;
- struct ltchars oldltchars; /* 4.2 BSD editing. */
- struct ltchars newltchars;
- #ifdef TIOCGWINSZ
- struct winsize winsize; /* 4.3 BSD window sizing */
- #endif
- int nrow; /* Terminal size, rows. */
- int ncol; /* Terminal size, columns. */
-
- /*
- * This function gets called once, to set up
- * the terminal channel. On Ultrix is's tricky, since
- * we want flow control, but we don't want any characters
- * stolen to send signals. Use CBREAK mode, and set all
- * characters but start and stop to 0xFF.
- */
- ttopen() {
- register char *tv_stype;
- char *getenv(), *tgetstr(), tcbuf[1024], err_str[72];
-
- if (ioctl(0, TIOCGETP, (char *) &oldtty) < 0)
- panic("ttopen can't get sgtty");
- newtty.sg_ospeed = oldtty.sg_ospeed;
- newtty.sg_ispeed = oldtty.sg_ispeed;
- newtty.sg_erase = oldtty.sg_erase;
- newtty.sg_kill = oldtty.sg_kill;
- newtty.sg_flags = oldtty.sg_flags;
- newtty.sg_flags &= ~(ECHO|CRMOD); /* Kill echo, CR=>NL. */
- #ifdef FLOWCONTROL
- newtty.sg_flags |= CBREAK; /* Half-cooked mode. */
- #else
- newtty.sg_flags |= RAW|ANYP; /* raw mode for 8 bit path.*/
- #endif
- if (ioctl(0, TIOCSETP, (char *) &newtty) < 0)
- panic("ttopen can't set sgtty");
- if (ioctl(0, TIOCGETC, (char *) &oldtchars) < 0)
- panic("ttopen can't get chars");
- newtchars.t_intrc = 0xFF; /* Interrupt. */
- newtchars.t_quitc = 0xFF; /* Quit. */
- #if FLOWCONTROL
- newtchars.t_startc = 0x11; /* ^Q, for terminal. */
- newtchars.t_stopc = 0x13; /* ^S, for terminal. */
- #else
- newtchars.t_startc = 0xFF; /* ^Q, for terminal. */
- newtchars.t_stopc = 0xFF; /* ^S, for terminal. */
- #endif
- newtchars.t_eofc = 0xFF;
- newtchars.t_brkc = 0xFF;
- if (ioctl(0, TIOCSETC, (char *) &newtchars) < 0)
- panic("ttopen can't set chars");
- if (ioctl(0, TIOCGLTC, (char *) &oldltchars) < 0)
- panic("ttopen can't get ltchars");
- newltchars.t_suspc = 0xFF; /* Suspend #1. */
- newltchars.t_dsuspc = 0xFF; /* Suspend #2. */
- newltchars.t_rprntc = 0xFF;
- newltchars.t_flushc = 0xFF; /* Output flush. */
- newltchars.t_werasc = 0xFF;
- newltchars.t_lnextc = 0xFF; /* Literal next. */
- if (ioctl(0, TIOCSLTC, (char *) &newltchars) < 0)
- panic("ttopen can't set ltchars");
-
- /* do this the REAL way */
- if ((tv_stype = getenv("TERM")) == NULL)
- {
- puts("Environment variable TERM not defined!");
- exit(1);
- }
-
- if((tgetent(tcbuf, tv_stype)) != 1)
- {
- (void) sprintf(err_str, "Unknown terminal type %s!", tv_stype);
- puts(err_str);
- exit(1);
- }
-
- setttysize() ;
- }
-
- /*
- * This function gets called just
- * before we go back home to the shell. Put all of
- * the terminal parameters back.
- */
- ttclose() {
- ttflush();
- if (ioctl(0, TIOCSLTC, (char *) &oldltchars) < 0)
- panic("ttclose can't set ltchars");
- if (ioctl(0, TIOCSETC, (char *) &oldtchars) < 0)
- panic("ttclose can't set chars");
- if (ioctl(0, TIOCSETP, (char *) &oldtty) < 0)
- panic("ttclose can't set sgtty");
- }
-
- /*
- * Write character to the display.
- * Characters are buffered up, to make things
- * a little bit more efficient.
- */
- ttputc(c) {
- if (nobuf >= NOBUF)
- ttflush();
- obuf[nobuf++] = c;
- }
-
- /*
- * Flush output.
- */
- ttflush() {
- if (nobuf != 0) {
- if (write(1, obuf, nobuf) != nobuf)
- panic("ttflush write failed");
- nobuf = 0;
- }
- }
-
- /*
- * Read character from terminal.
- * All 8 bits are returned, so that you can use
- * a multi-national terminal.
- */
- ttgetc() {
- char buf[1];
-
- while (read(0, &buf[0], 1) != 1)
- ;
- return (buf[0] & 0xFF);
- }
- /*
- * set the tty size. Functionized for 43BSD.
- */
- setttysize() {
-
- #ifdef TIOCGWINSZ
- if (ioctl(0, TIOCGWINSZ, (char *) &winsize) == 0) {
- nrow = winsize . ws_row;
- ncol = winsize . ws_col;
- } else nrow = 0;
- if(nrow<=0 || ncol<=0)
- #endif
- if ((nrow=tgetnum ("li")) <= 0
- || (ncol=tgetnum ("co")) <= 0) {
- nrow = 24;
- ncol = 80;
- }
- if (nrow > NROW) /* Don't crash if the */
- nrow = NROW; /* termcap entry is */
- if (ncol > NCOL) /* too big. */
- ncol = NCOL;
- }
-
- /*
- * typeahead returns TRUE if there are characters available to be read
- * in.
- */
- typeahead() {
- int x;
-
- return((ioctl(0, FIONREAD, (char *) &x) < 0) ? 0 : x);
- }
-
- /*
- * panic - just exit, as quickly as we can.
- */
- panic(s) char *s; {
- printf(stderr, "panic: %s\n", s);
- abort(); /* To leave a core image. */
- }
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/sysv/Makefile'
- then
- echo shar: will not over-write existing file "'sys/sysv/Makefile'"
- else
- cat << \SHAR_EOF > 'sys/sysv/Makefile'
- # Makefile for MicroEMACS.
- # Is there a better way to do the rebuilds, other than using
- # the links?
-
- SYS = sysv
- TTY = termcap
- # you may not need (or have) termlib...
- LIBS = -lcurses -ltermlib
- # CDEFS gets defines, and gets passed to lint. CFLAGS gets flags, and doesn't
- # get passed to lint.
- CDEFS = -DDO_METAKEY
- CFLAGS = -g $(CDEFS)
-
- OBJ = basic.o buffer.o cinfo.o display.o echo.o extend.o file.o kbd.o \
- line.o main.o match.o random.o region.o search.o symbol.o version.o \
- window.o paragraph.o prefix.o \
- word.o fileio.o spawn.o ttyio.o tty.o ttykbd.o
- OSRCS = fileio.c spawn.c ttyio.c tty.c ttykbd.c
- SRCS = basic.c buffer.c cinfo.c display.c echo.c extend.c file.c kbd.c \
- line.c main.c match.o random.c region.c search.c symbol.c version.c \
- window.c word.c paragraph.c prefix.c
- OINCS = ttydef.h sysdef.h
- INCS = def.h
-
- mg: $(OBJ)
- cc $(CFLAGS) -o mg $(OBJ) $(LIBS)
-
- # for AT&T UNIX-PC
- mg.7300: $(OBJ)
- ld /lib/crt0s.o /lib/shlib.ifile $(OBJ) -o mg.7300
-
- lint: $(SRCS) $(OSRCS)
- lint $(CDEFS) $(SRCS) $(OSRCS)
-
- $(OBJ): def.h sysdef.h ttydef.h
-
- sysdef.h: sys/$(SYS)/sysdef.h # Update links, if needed.
- rm -f sysdef.h
- ln sys/$(SYS)/sysdef.h .
-
- ttydef.h: tty/$(TTY)/ttydef.h
- rm -f ttydef.h
- ln tty/$(TTY)/ttydef.h .
-
- fileio.c: sys/$(SYS)/fileio.c
- rm -f fileio.c
- ln sys/$(SYS)/fileio.c .
-
- spawn.c: sys/$(SYS)/spawn.c
- rm -f spawn.c
- ln sys/$(SYS)/spawn.c .
-
- tty.c: tty/$(TTY)/tty.c
- rm -f tty.c
- ln tty/$(TTY)/tty.c .
-
- ttyio.c: sys/$(SYS)/ttyio.c
- rm -f ttyio.c
- ln sys/$(SYS)/ttyio.c .
-
- ttykbd.c: tty/$(TTY)/ttykbd.c
- rm -f ttykbd.c
- ln tty/$(TTY)/ttykbd.c .
-
- clean:; rm -f $(OBJ) $(OSRCS) $(OINCS)
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/sysv/fileio.c'
- then
- echo shar: will not over-write existing file "'sys/sysv/fileio.c'"
- else
- cat << \SHAR_EOF > 'sys/sysv/fileio.c'
- /*
- * Name: MicroEMACS
- * System V file I/O
- */
- #include "def.h"
-
- # ifndef F_OK
- # define F_OK 0
- # define X_OK 1
- # define W_OK 2
- # define R_OK 4
- # endif
-
- /*
- * Move bytes, overlaps OK (daveb).
- *
- * Doesn't really belong here, but it's system specific since it
- * is in assembler in some C libraries.
- */
- bcopy( from, to, cnt )
- char *from;
- char *to;
- int cnt;
- {
- if ( from == to )
- return;
-
- if( from > to )
- {
- while( cnt-- )
- *to++ = *from++;
- }
- else
- {
- to += cnt;
- from += cnt;
- while( cnt-- )
- *--to = *--from;
- }
- }
-
-
- static FILE *ffp;
-
- /*
- * Open a file for reading.
- */
- ffropen(fn)
- char *fn;
- {
- if ((ffp=fopen(fn, "r")) == NULL)
- return (FIOFNF);
- return (FIOSUC);
- }
-
- /*
- * Open a file for writing.
- * Return TRUE if all is well, and
- * FALSE on error (cannot create).
- */
- ffwopen(fn)
- char *fn;
- {
- if ((ffp=fopen(fn, "w")) == NULL) {
- ewprintf("Cannot open file for writing");
- return (FIOERR);
- }
- return (FIOSUC);
- }
-
- /*
- * Close a file.
- * Should look at the status.
- */
- ffclose()
- {
- (VOID) fclose(ffp);
- return (FIOSUC);
- }
-
- /*
- * Write a line to the already
- * opened file. The "buf" points to the
- * buffer, and the "nbuf" is its length, less
- * the free newline. Return the status.
- * Check only at the newline.
- */
- ffputline(buf, nbuf)
- register char buf[];
- {
- register int i;
-
- for (i=0; i<nbuf; ++i)
- putc(buf[i]&0xFF, ffp);
- putc('\n', ffp);
- if (ferror(ffp) != FALSE) {
- ewprintf("Write I/O error");
- return (FIOERR);
- }
- return (FIOSUC);
- }
-
- /*
- * Read a line from a file, and store the bytes
- * in the supplied buffer. Stop on end of file or end of
- * line. Don't get upset by files that don't have an end of
- * line on the last line; this seem to be common on CP/M-86 and
- * MS-DOS (the suspected culprit is VAX/VMS kermit, but this
- * has not been confirmed. If this is sufficiently researched
- * it may be possible to pull this kludge). Delete any CR
- * followed by an LF. This is mainly for runoff documents,
- * both on VMS and on Ultrix (they get copied over from
- * VMS systems with DECnet).
- */
- ffgetline(buf, nbuf)
- register char buf[];
- {
- register int c;
- register int i;
-
- i = 0;
- for (;;) {
- c = getc(ffp);
- if (c == '\r') { /* Delete any non-stray */
- c = getc(ffp); /* carriage returns. */
- if (c != '\n') {
- if (i >= nbuf-1) {
- ewprintf("File has long line");
- return (FIOERR);
- }
- buf[i++] = '\r';
- }
- }
- if (c==EOF || c=='\n') /* End of line. */
- break;
- if (i >= nbuf-1) {
- ewprintf("File has long line");
- return (FIOERR);
- }
- buf[i++] = c;
- }
- if (c == EOF) { /* End of file. */
- if (ferror(ffp) != FALSE) {
- ewprintf("File read error");
- return (FIOERR);
- }
- if (i == 0) /* Don't get upset if */
- return (FIOEOF); /* no newline at EOF. */
- }
- buf[i] = 0;
- return (FIOSUC);
- }
-
- #if BACKUP
- /*
- * Rename the file "fname" into a backup
- * copy. On Unix the backup has the same name as the
- * original file, with a "~" on the end; this seems to
- * be newest of the new-speak. The error handling is
- * all in "file.c". The "unlink" is perhaps not the
- * right thing here; I don't care that much as
- * I don't enable backups myself.
- */
- fbackupfile(fname)
- char *fname;
- {
- register char *nname;
-
- if ((nname=malloc(strlen(fname)+1+1)) == NULL)
- return (ABORT);
- (void) strcpy(nname, fname);
- (void) strcat(nname, "~");
- (void) unlink(nname); /* Ignore errors. */
-
- /* no rename on System V, so do it dangerous way. */
- if ( link(fname, nname) < 0 || unlink(fname) < 0 ) {
- free(nname);
- return (FALSE);
- }
- free(nname);
- return (TRUE);
- }
- #endif
-
- /*
- * The string "fn" is a file name.
- * Perform any required case adjustments. All sustems
- * we deal with so far have case insensitive file systems.
- * We zap everything to lower case. The problem we are trying
- * to solve is getting 2 buffers holding the same file if
- * you visit one of them with the "caps lock" key down.
- * On UNIX file names are dual case, so we leave
- * everything alone.
- */
- /*ARGSUSED*/
- adjustcase(fn)
- register char *fn;
- {
- #if 0
- register int c;
-
- while ((c = *fn) != 0) {
- if (c>='A' && c<='Z')
- *fn = c + 'a' - 'A';
- ++fn;
- }
- #endif
- }
-
-
-
- #ifdef STARTUP
- #include <sys/types.h>
- #include <sys/file.h>
- /*
- * find the users startup file, and return it's name. Check for
- * $HOME/.mg then for $HOME/.emacs, then give up.
- */
- char *
- startupfile()
- {
- register char *file;
- static char home[NFILEN];
- char *getenv();
-
- if ( (file = getenv("HOME")) == NULL
- || strlen(file)+7 >= NFILEN - 1 )
- return NULL;
- (VOID) strcpy(home, file);
- file = &(home[strlen(home)]);
- *file++ = '/';
-
- (VOID) strcpy(file, ".mg");
- if (access(home, F_OK ) == 0) return home;
-
- (VOID) strcpy(file, ".emacs");
- if (access(home, F_OK) == 0) return home;
-
- return NULL;
- }
- #endif
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/sysv/spawn.c'
- then
- echo shar: will not over-write existing file "'sys/sysv/spawn.c'"
- else
- cat << \SHAR_EOF > 'sys/sysv/spawn.c'
- /*
- * Name: MicroEMACS
- * Spawn CLI for System V.
- * Version: 0
- * Last edit: 17-Apr-86
- * By: gonzo!daveb
- * {sun, amdahl, mtxinu}!rtech!daveb
- *
- * Spawn for System V.
- */
- #include "def.h"
-
- #include <signal.h>
-
- char *shellp = NULL; /* Saved "SHELL" program. */
- char *shname = NULL; /* Saved shell name */
-
- extern char *getenv();
-
- /*
- * On System V, we no gots job control, so always run
- * a subshell using fork/exec. Bound to "C-C", and used
- * as a subcommand by "C-Z". (daveb)
- *
- * Returns 0 if the shell executed OK, something else if
- * we couldn't start shell or it exited badly.
- */
- spawncli(f, n, k)
- {
- extern char *strrchr();
- register int pid;
- register int wpid;
- register int (*oqsig)();
- register int (*oisig)();
- int status;
- int errp = FALSE;
-
- if (shellp == NULL) {
- shellp = getenv("SHELL");
- if (shellp == NULL)
- shellp = getenv("shell");
- if (shellp == NULL)
- shellp = "/bin/sh"; /* Safer. */
- shname = strrchr( shellp, '/' );
- shname = shname ? shname++ : shellp;
-
- }
- ttcolor(CTEXT);
- ttnowindow();
- ttmove(nrow-1, 0);
- if (epresf != FALSE) {
- tteeol();
- epresf = FALSE;
- }
- ttclose();
- sgarbf = TRUE; /* Force repaint. */
- oqsig = signal(SIGQUIT, SIG_IGN);
- oisig = signal(SIGINT, SIG_IGN);
- if ((pid=fork()) == 0) {
- execlp(shellp, shname, "-i", NULL);
- _exit(1); /* Should do better! */
- }
- else if (pid > 0) {
- while ((wpid=wait(&status))>=0 && wpid!=pid)
- ;
- }
- else errp = TRUE;
-
- signal(SIGINT, oisig);
- ttopen();
- if(errp)
- ewprintf("Failed to create process");
-
- return ( errp | status );
- }
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/sysv/ttyio.c'
- then
- echo shar: will not over-write existing file "'sys/sysv/ttyio.c'"
- else
- cat << \SHAR_EOF > 'sys/sysv/ttyio.c'
- /*
- * Name: MicroEMACS
- * System V terminal I/O.
- * Version: 0
- * Last edit: Tue Aug 26 23:57:57 PDT 1986
- * By: gonzo!daveb
- * {sun, amdahl, mtxinu}!rtech!gonzo!daveb
- *
- * The functions in this file
- * negotiate with the operating system for
- * keyboard characters, and write characters to
- * the display in a barely buffered fashion.
- *
- * This version goes along with tty/termcap/tty.c.
- * Terminal size is determined there, rather than here, and
- * this does not open the termcap file
- */
- #include "def.h"
-
- #include <sys/types.h>
- #include <fcntl.h>
- #include <termio.h>
-
- #define NOBUF 512 /* Output buffer size. */
-
- char obuf[NOBUF]; /* Output buffer. */
- int nobuf; /* buffer count */
-
- static struct termio ot; /* entry state of the terminal */
- static struct termio nt; /* editor's terminal state */
-
- static int ttyactivep = FALSE; /* terminal in editor mode? */
- static int ttysavedp = FALSE; /* terminal state saved? */
-
- int nrow; /* Terminal size, rows. */
- int ncol; /* Terminal size, columns. */
-
- /* These are used to implement typeahead on System V */
-
- int kbdflgs; /* saved keyboard fd flags */
- int kbdpoll; /* in O_NDELAY mode */
- int kbdqp; /* there is a char in kbdq */
- char kbdq; /* char we've already read */
-
- /*
- * This function gets called once, to set up
- * the terminal channel. This version turns off flow
- * control. This may be wrong for your system, but no
- * good solution has really been found (daveb).
- */
- ttopen()
- {
- register char *cp;
- extern char *getenv();
-
- if (ttyactivep)
- return;
-
- if( !ttysavedp )
- {
- if (ioctl(0, TCGETA, &ot) < 0)
- abort();
- nt = ot; /* save entry state */
- nt.c_cc[VMIN] = 1; /* one character read is OK */
- nt.c_cc[VTIME] = 0; /* Never time out. */
- nt.c_iflag |= IGNBRK;
- nt.c_iflag &= ~( ICRNL | INLCR | ISTRIP | IXON | IXOFF );
- nt.c_oflag &= ~OPOST;
- nt.c_cflag |= CS8; /* allow 8th bit on input */
- nt.c_cflag &= ~PARENB; /* Don't check parity */
- nt.c_lflag &= ~( ECHO | ICANON | ISIG );
-
- kbdflgs = fcntl( 0, F_GETFL, 0 );
- kbdpoll = FALSE;
-
- ttysavedp = TRUE;
- }
-
- if (ioctl(0, TCSETAF, &nt) < 0)
- abort();
-
- /* This really belongs in tty/termcap... */
-
- if ((cp=getenv("TERMCAP")) == NULL
- || (nrow=getvalue(cp, "li")) <= 0
- || (ncol=getvalue(cp, "co")) <= 0) {
- nrow = 24;
- ncol = 80;
- }
- if (nrow > NROW) /* Don't crash if the */
- nrow = NROW; /* termcap entry is */
- if (ncol > NCOL) /* too big. */
- ncol = NCOL;
-
- ttyactivep = TRUE;
- }
-
- /*
- * This routine scans a string, which is
- * actually the return value of a getenv call for the TERMCAP
- * variable, looking for numeric parameter "name". Return the value
- * if found. Return -1 if not there. Assume that "name" is 2
- * characters long. This limited use of the TERMCAP lets us find
- * out the size of a window on the X display.
- */
- getvalue(cp, name)
- register char *cp;
- register char *name;
- {
- for (;;) {
- while (*cp!=0 && *cp!=':')
- ++cp;
- if (*cp++ == 0) /* Not found. */
- return (-1);
- if (cp[0]==name[0] && cp[1]==name[1] && cp[2]=='#')
- return (atoi(cp+3)); /* Stops on ":". */
- }
- }
-
- /*
- * This function gets called just
- * before we go back home to the shell. Put all of
- * the terminal parameters back.
- */
- ttclose()
- {
- if(!ttysavedp || !ttyactivep)
- return;
- ttflush();
- if (ioctl(0, TCSETAF, &ot) < 0 || fcntl( 0, F_SETFL, kbdflgs ) < 0)
- abort();
- ttyactivep = FALSE;
- }
-
- /*
- * Write character to the display.
- * Characters are buffered up, to make things
- * a little bit more efficient.
- */
- ttputc(c)
- {
- if (nobuf >= NOBUF)
- ttflush();
- obuf[nobuf++] = c;
- }
-
- /*
- * Flush output.
- */
- ttflush()
- {
- if (nobuf != 0) {
- write(1, obuf, nobuf);
- nobuf = 0;
- }
- }
-
- /*
- * Read character from terminal.
- * All 8 bits are returned, so that you can use
- * a multi-national terminal.
- *
- * If keyboard 'queue' already has typeahead from a typeahead() call,
- * just return it. Otherwise, make sure we are in blocking i/o mode
- * and read a character.
- */
- ttgetc()
- {
- if( kbdqp )
- kbdqp = FALSE;
- else
- {
- if( kbdpoll && fcntl( 0, F_SETFL, kbdflgs ) < 0 )
- abort();
- kbdpoll = FALSE;
- while (read(0, &kbdq, 1) != 1)
- ;
- }
- return ( kbdq & 0xff );
- }
-
- /*
- * Return non-FALSE if typeahead is pending.
- *
- * If already got unread typeahead, do nothing.
- * Otherwise, set keyboard to O_NDELAY if not already, and try
- * a one character read.
- */
- typeahead()
- {
- if( !kbdqp )
- {
- if( !kbdpoll && fcntl( 0, F_SETFL, kbdflgs | O_NDELAY ) < 0 )
- abort();
- kbdqp = (1 == read( 0, &kbdq, 1 ));
- }
- return ( kbdqp );
- }
-
-
- /*
- * panic: print error and die, leaving core file.
- * Don't know why this is needed (daveb).
- */
- panic(s)
- char *s;
- {
- fprintf(stderr, "%s\r\n", s);
- abort();
- }
-
-
- /*
- ** This should check the size of the window, and reset if needed.
- */
-
- setttysize()
- {
- #ifdef TIOCGWINSZ
- if (ioctl(0, TIOCGWINSZ, (char *) &winsize) == 0) {
- nrow = winsize . ws_row;
- ncol = winsize . ws_col;
- } else
- #endif
- if ((nrow=tgetnum ("li")) <= 0
- || (ncol=tgetnum ("co")) <= 0) {
- nrow = 24;
- ncol = 80;
- }
- if (nrow > NROW) /* Don't crash if the */
- nrow = NROW; /* termcap entry is */
- if (ncol > NCOL) /* too big. */
- ncol = NCOL;
- }
-
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/sysv/sysdef.h'
- then
- echo shar: will not over-write existing file "'sys/sysv/sysdef.h'"
- else
- cat << \SHAR_EOF > 'sys/sysv/sysdef.h'
- /*
- * Name: MicroEMACS
- * Ultrix-32 system header file same for System V.
- * Version: 29
- * Last edit: 05-Feb-86
- * By: rex::conroy
- * decvax!decwrl!dec-rhea!dec-rex!conroy
- */
- #define PCC 1 /* "[]" gets an error. */
- #define KBLOCK 8192 /* Kill grow. */
- #define GOOD 0 /* Good exit status. */
-
- typedef int RSIZE; /* Type for file/region sizes */
- typedef short KEY; /* Type for internal keystrokes */
-
- /*
- * Macros used by the buffer name making code.
- * Start at the end of the file name, scan to the left
- * until BDC1 (or BDC2, if defined) is reached. The buffer
- * name starts just to the right of that location, and
- * stops at end of string (or at the next BDC3 character,
- * if defined). BDC2 and BDC3 are mainly for VMS.
- */
- #define BDC1 '/' /* Buffer names. */
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/osk/readme.osk'
- then
- echo shar: will not over-write existing file "'sys/osk/readme.osk'"
- else
- cat << \SHAR_EOF > 'sys/osk/readme.osk'
- readme.osk for MicroGnuEmacs 1a Nov 10, 1986
-
- Copy sys/osk/makefile to .
-
- copy sys/osk/varargs.h to /dd/defs/varargs.h if you don't have one.
- (I think version 2.1 of the C compiler will include mine.)
-
- Look at makefile for personal preference options and terminal selection.
-
- Use make to compile.
-
- Currently defined for termcap, assuming a termlib library exists.
- (I've heard there will be one with version 2.1 of the C compiler. I
- can't distribute the one I have.)
-
- Baud should be set correctly in tmode/xmode even if it is set in
- hardware as it is on a QT+. This is used for display optimization
- and padding.
-
- All files are indented assuming tabs every eight columns, and mg
- itself uses tabs there. I have no idea why Microware decided not to
- follow this defacto industry standard, but at least they allow you to
- change your system to whatever you want.
-
- The enviornment variable TERM is used to determine your terminal type,
- and HOME is used to find the .mg startup file.
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/osk/sysdef.h'
- then
- echo shar: will not over-write existing file "'sys/osk/sysdef.h'"
- else
- cat << \SHAR_EOF > 'sys/osk/sysdef.h'
- /*
- * Os9/68K specific definitions for micrognuemacs
- */
- #define PCC /* "[]" gets an error. */
- #define KBLOCK 1024 /* Kill grow. */
- #define GOOD 0 /* Good exit status. */
- #define VARARGS /* use my varargs.h rather than */
- /* the non-portable code supplied */
- #define NO_VOID_TYPE /* void not supported yet */
- #define SEOL '\l' /* used in search (because \r==\n) */
- #define PC PC_ /* compiler can't handle variable called PC */
- #define SR SR_ /* or SR */
- #define NO_RESIZE /* terminal doesn't change size */
-
- /* typedefs for gnu version */
- typedef int RSIZE; /* Type for file/region sizes */
- typedef short KEY; /* Type for internal keystrokes */
-
- /*
- * Macros used by the buffer name making code.
- * Start at the end of the file name, scan to the left
- * until BDC1 (or BDC2, if defined) is reached. The buffer
- * name starts just to the right of that location, and
- * stops at end of string (or at the next BDC3 character,
- * if defined). BDC2 and BDC3 are mainly for VMS.
- */
- #define BDC1 '/' /* Buffer names. */
-
- /*
- * Needed for lots of small mallocs on os9/68k. _memmins should be
- * (maximum malloced memory)/16. (defalt _memmins is 4096)
- * Note that malloc may now fail if there isn't _memmins bytes
- * contiguous free memory. _memins could be reduced and the malloc
- * tried again. (Not currently implemented.)
- */
- #ifdef MAXMEM
- # define SYSINIT {extern int _memmins; _memmins=MAXMEM*64; }
- #else
- # define SYSINIT {extern int _memmins; _memmins=32768; }
- #endif
-
- /* see "caveates" in the osk C manual on _strass */
- #define bcopy(from,to,len) _strass(to,from,len)
-
- /* see comments on these in display.c. OSK can't stand the wasted memory
- * without making the score array "remote", which generates lousy code.
- * Besides, I don't have an extra 100kb of memory for the score array.
- */
- #define XCHAR char
- #define XSHORT short
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/osk/varargs.h'
- then
- echo shar: will not over-write existing file "'sys/osk/varargs.h'"
- else
- cat << \SHAR_EOF > 'sys/osk/varargs.h'
- /* varargs.h for os9/68k by Robert A. Larson */
- /* version 0 for os9/68k C 2.0 04/20/86 */
- /* varargs is a "portable" way to write a routine that takes a variable */
- /* number of arguements. This implemination agrees with both the 4.2bsd*/
- /* and Sys V documentation of varargs. Note that just because varargs.h*/
- /* is used does not mean that it is used properly. */
- /* Ignore the "expression with little effect" warnings. (Seems to be a */
- /* compiler bug.) */
-
- #define va_alist _va_arg1, _va_arg2, _va_arg3
-
- #define va_dcl unsigned _va_arg1, _va_arg2, _va_arg3;
-
- typedef struct {
- unsigned _va_at; /* number of arguments used, 0, 1, or more */
- /* (double as first arg counts as 2) */
- union {
- struct {
- unsigned _va_uns1, _va_uns2;
- } _va_uuns;
- double _va_udouble;
- } _va_union;
- char *_va_pointer;
- } va_list;
-
- #define va_start(pvar) ( (pvar)._va_at = 0, \
- (pvar)._va_union._va_uuns._va_uns1 = _va_arg1,\
- (pvar)._va_union._va_uuns._va_uns2 = _va_arg2,\
- (pvar)._va_pointer = (char *) &_va_arg3 \
- )
-
- #define va_arg(pvar, type) ( \
- ((pvar)._va_at++) ? ( \
- ((pvar)._va_at == 2) ? ( \
- (sizeof(type) == 8) ? ( \
- *(((type *)((pvar)._va_pointer))++) \
- ) : (type)( \
- (pvar)._va_union._va_uuns._va_uns2 \
- ) \
- ) : ( \
-
- *(((type *)((pvar)._va_pointer))++) \
- ) \
- ) : ( \
- (sizeof(type) == 8) ? (type)( \
- (pvar)._va_at++, \
- (pvar)._va_union._va_udouble \
- ) : (type)( \
- (pvar)._va_union._va_uuns._va_uns1 \
- ) \
- ) \
- )
-
- #define va_end(pvar) /* va_end is simple */
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/osk/fileio.c'
- then
- echo shar: will not over-write existing file "'sys/osk/fileio.c'"
- else
- cat << \SHAR_EOF > 'sys/osk/fileio.c'
- /*
- * Os9/68k fileio.c for MicroGnuEmacs by Robert A. Larson
- * system dependent file io routines
- */
- #include "def.h"
-
- char *getenv();
-
- static FILE *ffp;
-
- /*
- * Open a file for reading.
- */
- ffropen(fn)
- char *fn;
- {
- if ((ffp=fopen(fn, "r")) == NULL)
- return (FIOFNF);
- return (FIOSUC);
- }
-
- /*
- * Open a file for writing.
- * Return TRUE if all is well, and
- * FALSE on error (cannot create).
- */
- ffwopen(fn)
- char *fn;
- {
- if ((ffp=fopen(fn, "w")) == NULL) {
- ewprintf("Cannot open file for writing");
- return (FIOERR);
- }
- return (FIOSUC);
- }
-
- /*
- * Close a file.
- * Should look at the status.
- */
- ffclose()
- {
- fclose(ffp);
- return (FIOSUC);
- }
-
- /*
- * Write a line to the already
- * opened file. The "buf" points to the
- * buffer, and the "nbuf" is its length, less
- * the free newline. Return the status.
- * Check only at the newline.
- */
- ffputline(buf, nbuf)
- register char buf[];
- {
- register int i;
-
- for (i=0; i<nbuf; ++i)
- putc(buf[i]&0xFF, ffp);
- putc('\n', ffp);
- if (ferror(ffp) != FALSE) {
- ewprintf("Write I/O error");
- return (FIOERR);
- }
- return (FIOSUC);
- }
-
- /*
- * Read a line from a file, and store the bytes
- * in the supplied buffer. Stop on end of file or end of
- * line. Don't get upset by files that don't have an end of
- * line on the last line; this seem to be common on CP/M-86 and
- * MS-DOS (the suspected culprit is VAX/VMS kermit, but this
- * has not been confirmed. If this is sufficiently researched
- * it may be possible to pull this kludge).
- */
- ffgetline(buf, nbuf)
- register char *buf;
- {
- register int c;
- register int i;
-
- i = 0;
- for (;;) {
- c = getc(ffp);
- if (c==EOF || c=='\n') /* End of line. */
- break;
- if (i >= nbuf-1) {
- ewprintf("File has long line");
- return (FIOERR);
- }
- buf[i++] = c;
- }
- if (c == EOF) { /* End of file. */
- if (ferror(ffp) != FALSE) {
- ewprintf("File read error");
- return (FIOERR);
- }
- if (i == 0) /* Don't get upset if */
- return (FIOEOF); /* no newline at EOF. */
- }
- buf[i] = 0;
- return (FIOSUC);
- }
-
- #ifdef BACKUP
- /*
- * Rename the file "fname" into a backup copy.
- * The backup copy is the same name with ".BAK" appended unless the file
- * name is to long. If your file name is 28 characters long ending in ".BAK"
- * you lose. The error handling is all in "file.c".
- */
- fbackupfile(fname)
- char *fname;
- {
- register char *params;
- int status;
- register char *fn;
- register int fnamel;
- register int fnl;
- char *rindex();
-
- if((fn = rindex(fname, '/')) == NULL) fn = fname; else fn++;
- fnamel = strlen(fname);
- fnl = strlen(fn);
- if((params = malloc(strlen(fname)+strlen(fn)+6)) == NULL)
- return(ABORT);
- /* delete the old backup */
- strcpy(params, fname);
- if(fnl < 25) strcat(params, ".BAK");
- else strcpy(params+(fnamel-fnl+24), ".BAK");
- unlink(params); /* ignore errors */
- /* now do the rename (This is rather akward) */
- strcpy(params, fname);
- strcat(params, " ");
- strcat(params, fn);
- if(fnl < 25) strcat(params, ".BAK");
- else strcpy(params+fnamel+1+24, ".BAK");
- if(os9fork("rename", strlen(params)+1, params, 0, 0, 0, 0)==-1) {
- free(params);
- return (FALSE);
- }
- wait(&status);
- free(params);
- return ((status & 0xffff)==0);
- }
- #endif
-
- /*
- * The string "fn" is a file name.
- * Perform any required case adjustments. All sustems
- * we deal with so far have case insensitive file systems.
- * We zap everything to lower case. The problem we are trying
- * to solve is getting 2 buffers holding the same file if
- * you visit one of them with the "caps lock" key down.
- * On UNIX file names are dual case, so we leave
- * everything alone. Os9's dual case storage but non-case sensitivity
- * does not seem to be accounted for here. I'm treating it as a
- * mono-case system, but it would be better to beleive the file (if found)
- * or the user (if not).
- */
- adjustcase(fn)
- register char *fn;
- {
- register int c;
-
- while ((c = *fn) != 0) {
- if (c>='A' && c<='Z')
- *fn = c + 'a' - 'A';
- ++fn;
- }
- }
-
- #ifndef MICRO
- char *startupfile()
- {
- static char startname[64];
- char *cp;
-
- if ((cp = getenv("HOME")) == NULL) return ".mg";
- strncpy(startname, cp, 64 - 4);
- strcat(startname, "/.mg");
- return startname;
- }
- #endif
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/osk/spawn.c'
- then
- echo shar: will not over-write existing file "'sys/osk/spawn.c'"
- else
- cat << \SHAR_EOF > 'sys/osk/spawn.c'
- /*
- * Name: MicroEMACS
- * OS9/68k Spawn Shell
- * Version: 29ral
- * Last edit: 04/20/86
- * By: Blarson@Usc-Ecl.Arpa
- *
- */
- #include "def.h"
-
- #include <sgstat.h>
-
- extern struct sgbuf oldtty; /* There really should be a */
- extern struct sgbuf newtty; /* nicer way of doing this, so */
-
- spawncli(f, n, k)
- /* what are f, n, and k? They */
- /* arn't used by ultrix, so I */
- /* ignore them too. */
- {
- register int pid;
- register int wpid;
- int status;
-
- ttcolor(CTEXT);
- ttnowindow();
- ttmove(nrow-1, 0);
- if (epresf != FALSE) {
- tteeol();
- epresf = FALSE;
- }
- ttflush();
- if(_ss_opt(0, &oldtty) == -1) {
- ewprintf("_ss_opt #1 to terminal failed");
- return (FALSE);
- }
- if((pid=os9fork("shell", 0, "", 0, 0, 0, 0)) == -1) {
- ewprintf("Failed to create process");
- return (FALSE);
- }
- while ((wpid=wait(&status))>=0 && wpid!=pid)
- ;
- sgarbf = TRUE; /* Force repaint. */
- if(_ss_opt(0, &newtty) == -1) {
- ewprintf("_ss_opt #2 to terminal failed");
- return (FALSE);
- }
- return (TRUE);
- }
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/osk/ttyio.c'
- then
- echo shar: will not over-write existing file "'sys/osk/ttyio.c'"
- else
- cat << \SHAR_EOF > 'sys/osk/ttyio.c'
- /*
- * sys/osk/ttyio.c by Robert A. Larson
- *
- * The functions in this file
- * negotiate with the operating system for
- * keyboard characters, and write characters to
- * the display in a barely buffered fashion.
- */
- #include "def.h"
-
- #include <sgstat.h>
- #ifdef DPROMPT
- # include <varargs.h>
- # define S_RDY 2437 /* arbitrary user signal */
- #endif
-
- #define NOBUF 512 /* Output buffer size. */
-
- char obuf[NOBUF]; /* Output buffer. */
- int nobuf;
- struct sgbuf oldtty, newtty;
- int nrow; /* Terminal size, rows. */
- int ncol; /* Terminal size, columns. */
- short ospeed; /* Terminal speed, for termlib.l */
-
- #ifdef DPROMPT
- wakeup(signum)
- int signum;
- {
- /* ignore the signal */
- }
- #endif
-
- /*
- * This function gets called once, to set up
- * the terminal channel.
- */
-
- ttopen()
- {
- if(_gs_opt(0, &oldtty) == -1) panic("can't get options");
- ospeed = oldtty.sg_baud;
- _strass(&newtty, &oldtty, sizeof(newtty)); /* newtty=oldtty; */
- if(oldtty.sg_class == 0) { /* scf */
- newtty.sg_backsp=
- newtty.sg_delete=
- newtty.sg_echo =
- newtty.sg_alf =
- newtty.sg_pause =
- newtty.sg_bspch =
- newtty.sg_dlnch =
- newtty.sg_eorch =
- newtty.sg_eofch =
- newtty.sg_rlnch =
- newtty.sg_dulnch=
- newtty.sg_psch =
- newtty.sg_kbich =
- newtty.sg_kbach = 0;
- #ifndef xon_xoff
- newtty.sg_xon =
- newtty.sg_xoff = 0;
- #endif
- if(_ss_opt(0, &newtty) == -1) panic("can't set options");
- nrow = oldtty.sg_page == 0 ? NROW : oldtty.sg_page;
- } else { /* not scf, fake it */
- nrow = NROW;
- }
- ncol = NCOL;
- #ifdef DPROMPT
- intercept(wakeup); /* ignore signals */
- #endif
- }
-
- /*
- * This function gets called just
- * before we go back home to the shell. Put all of
- * the terminal parameters back.
- */
- ttclose()
- {
- ttflush();
- if(_ss_opt(0, &oldtty) == -1) panic("can't reset options");
- }
-
- /*
- * Write character to the display.
- * Characters are buffered up, to make things
- * a little bit more efficient.
- */
- ttputc(c)
- {
- if (nobuf >= NOBUF)
- ttflush();
- obuf[nobuf++] = c;
- }
-
- /*
- * Flush output.
- */
- ttflush()
- {
- if (nobuf != 0) {
- write(1, obuf, nobuf);
- nobuf = 0;
- }
- }
-
- /*
- * Read character from terminal.
- * All 8 bits are returned, so that you can use
- * a multi-national terminal.
- */
- ttgetc()
- {
- char buf[1];
-
- while (read(0, &buf[0], 1) != 1)
- ;
- return (buf[0] & 0xFF);
- }
-
- int typeahead()
- {
- return _gs_rdy(0) > 0;
- }
-
- panic(s) char *s; {
- _ss_opt(0, &oldtty); /* ignore errors */
- fputs("Panic: ", stdout); /* avoid printf, don't load all that */
- puts(s);
- exit(1);
- }
-
- #ifdef DPROMPT
- ttwait() {
- if(_gs_rdy(0) > 0) return FALSE; /* already something waiting */
- _ss_ssig(0, S_RDY); /* wake me when you have something */
- if(sleep(2)!=0) return FALSE; /* sleep interupted */
- _ss_rel(0);
- return TRUE;
- }
- #endif
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/osk/makefile'
- then
- echo shar: will not over-write existing file "'sys/osk/makefile'"
- else
- cat << \SHAR_EOF > 'sys/osk/makefile'
- # Makefile for OSK MicroGnuEMACS by Robert A. Larson
- # 07/12/86 MicroGnuEMACS version
- # Copy ./sys/osk/makefile to . before making. Check
- # OPTS and LIBS.
- #
- # mg is short for micrognuemacs. Call it what you want.
- NAME = mg
- # terminal type or termcap
- TERM = TERMCAP
- # opts is for user definable options, such as:
- # BACKUP define for automatic backups
- # CVMVAS define for ^V and M-V to work in pages
- # MAXMEM memory available to malloc in kbytes. Default 512 (OSK only)
- # NLINE maximum line length, default 256. If big, use -m in LFLAGS.
- # DPROMPT print delayed prompt strings for ESC, ^X, etc.
- # STARTUP startup file handling
- # PREFIXREGION functions for prefixing a region
- OPTS = -dBACKUP -dMAXMEM=320 -dNLINE=2048 -dDPROMPT -dSTARTUP
- # termlib is needed for termcap.
- LFLAGS = -l=/dd/lib/termlib.l -m=4
- OBJ = basic.r \
- buffer.r \
- cinfo.r \
- display.r \
- echo.r \
- extend.r \
- file.r \
- kbd.r \
- line.r \
- main.r \
- match.r \
- paragraph.r \
- prefix.r \
- random.r \
- region.r \
- search.r \
- symbol.r \
- version.r \
- window.r \
- word.r
- # these files are listed individually below
- SYSOBJ = SYS/OSK/fileio.r \
- SYS/OSK/spawn.r \
- SYS/OSK/ttyio.r
- # ditto
- TERMOBJ = TTY/$(TERM)/tty.r \
- TTY/$(TERM)/ttykbd.r
- #
- $(NAME): $(OBJ) $(SYSOBJ) $(TERMOBJ) makefile
- cc -i -t=/r0 -f=$(NAME) $(LFLAGS) $(OBJ) $(SYSOBJ) $(TERMOBJ)
- $(OBJ): def.h sysdef.h ttydef.h makefile
- cc -r -t=/r0 $(OPTS) $*.c
- SYS/OSK/fileio.r: SYS/OSK/fileio.c def.h sysdef.h ttydef.h makefile
- cc -r=SYS/OSK -t=/r0 $(OPTS) SYS/OSK/fileio.c
- SYS/OSK/spawn.r: SYS/OSK/spawn.c def.h sysdef.h ttydef.h makefile
- cc -r=SYS/OSK -t=/r0 $(OPTS) SYS/OSK/spawn.c
- SYS/OSK/ttyio.r: SYS/OSK/ttyio.c def.h sysdef.h ttydef.h makefile
- cc -r=SYS/OSK -t=/r0 $(OPTS) SYS/OSK/ttyio.c
- TTY/$(TERM)/tty.r: TTY/$(TERM)/tty.c def.h sysdef.h ttydef.h makefile
- cc -r=TTY/$(TERM) -t=/r0 $(OPTS) TTY/$(TERM)/tty.c
- TTY/$(TERM)/ttykbd.r: TTY/$(TERM)/ttykbd.c def.h sysdef.h ttydef.h makefile
- cc -r=TTY/$(TERM) -t=/r0 $(OPTS) TTY/$(TERM)/ttykbd.c
- # The touch commands are needed to update the modified time.
- sysdef.h: SYS/OSK/sysdef.h
- copy -r -b=16 -w=. SYS/OSK/sysdef.h
- touch sysdef.h
- ttydef.h: TTY/$(TERM)/ttydef.h makefile
- copy -r -b=16 -w=. TTY/$(TERM)/ttydef.h
- touch ttydef.h
- SHAR_EOF
- fi # end of overwriting check
- # End of shell archive
- exit 0
-
-