home *** CD-ROM | disk | FTP | other *** search
- Subject: v08i015: 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 15
- Archive-name: micrognu/Part08
-
-
- #! /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:
- # sys/eunice/Makefile
- # sys/eunice/fileio.c
- # sys/eunice/readme
- # sys/eunice/spawn.c
- # sys/eunice/sysdef.h
- # sys/eunice/ttyio.c
- # sys/vms/aaareadme.1st
- # sys/vms/bcopy.mar
- # sys/vms/ccom.com
- # sys/vms/make.com
- # sys/vms/mg.com
- # sys/vms/mglink.com
- # sys/vms/mgmailedit.com
- # sys/vms/emacs.opt
- # sys/vms/fileio.c
- # sys/vms/spawn.c
- # sys/vms/trnlnm.c
- # sys/vms/ttyio.c
- # sys/vms/sysdef.h
- # This archive created: Sat Nov 15 15:40:17 1986
- export PATH; PATH=/bin:$PATH
- if test ! -d sys/eunice
- then
- mkdir sys/eunice
- fi
- if test ! -d sys/vms
- then
- mkdir sys/vms
- fi
- if test ! -d sys/vms/termcap
- then
- mkdir sys/vms/termcap
- fi
- if test -f 'sys/eunice/Makefile'
- then
- echo shar: will not over-write existing file "'sys/eunice/Makefile'"
- else
- cat << \SHAR_EOF > 'sys/eunice/Makefile'
- # Makefile for MicroEMACS, under Eunice
-
- SYS =eunice
- TTY =termcap
-
- LIBS = -ltermcap
- # CDEFS gets defines, and gets passed to lint. CFLAGS gets flags, and doesn't
- # get passed to lint.
- CDEFS = -Isys/$(SYS)/ -Itty/$(TTY)/ -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
- INCS = def.h
-
- mg: $(OBJ) $(XOBJ)
- cc $(CFLAGS) -o mg $(OBJ) $(LIBS)
- rm -f $(OSRCS)
-
- # 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)
-
- clean: rm -f *.o $(OSRCS)
-
- $(OBJ): def.h sys/$(SYS)/sysdef.h tty/$(TTY)/ttydef.h
-
- fileio.c: sys/$(SYS)/fileio.c
- cp sys/$(SYS)/fileio.c .
-
- spawn.c: sys/$(SYS)/spawn.c
- cp sys/$(SYS)/spawn.c .
-
- tty.c: tty/$(TTY)/tty.c
- cp tty/$(TTY)/tty.c .
-
- ttyio.c: sys/$(SYS)/ttyio.c
- cp sys/$(SYS)/ttyio.c .
-
- ttykbd.c: tty/$(TTY)/ttykbd.c
- cp tty/$(TTY)/ttykbd.c .
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/eunice/fileio.c'
- then
- echo shar: will not over-write existing file "'sys/eunice/fileio.c'"
- else
- cat << \SHAR_EOF > 'sys/eunice/fileio.c'
- /*
- * Eunice BSD 4.2 file I/O
- */
- #include "def.h"
-
- #ifndef F_OK
- #define F_OK FRDONLY
- #endif
-
- 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(fname) + 1);
- return (ABORT);
- }
- (void) strcpy(nname, fn);
- (void) strcat(nname, "~");
- (void) unlink(nname); /* Ignore errors. */
- if (rename(fname, 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/eunice/readme'
- then
- echo shar: will not over-write existing file "'sys/eunice/readme'"
- else
- cat << \SHAR_EOF > 'sys/eunice/readme'
- This directory contains sources that allow MicroEmacs to be compiled
- and linked using Eunice cc. Although I am the de facto Eunice hacker
- at the site I work for, I don't have enough experience with it to
- understand why it crashes for me when I attempt to run it under the
- C shell. If I give the command
-
- $ MG :== $dev:[dir]MG. MG
-
- and invoke it from DCL, it works fine. If you find out what's wrong
- (probably something simple), let me know.
-
- If you have the VAX C compiler, you might be better off using the native
- VMS terminal/system modules, to avoid the overhead involved in running Eunice.
-
- Mic Kaczmarczik
- ...!ihnp4!seismo!ut-sally!ut-ngp!mic
- ccep001@utadnx.bitnet
- mic@ngp.utexas.edu
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/eunice/spawn.c'
- then
- echo shar: will not over-write existing file "'sys/eunice/spawn.c'"
- else
- cat << \SHAR_EOF > 'sys/eunice/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 */
- #ifdef BSD43
- omask = sigsetmask(0);
- #endif
- (void) kill(0, SIGTSTP);
- setttysize() ;
- #ifdef BSD43
- (void) sigsetmask(omask);
- #endif
- } 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/eunice/sysdef.h'
- then
- echo shar: will not over-write existing file "'sys/eunice/sysdef.h'"
- else
- cat << \SHAR_EOF > 'sys/eunice/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/eunice/ttyio.c'
- then
- echo shar: will not over-write existing file "'sys/eunice/ttyio.c'"
- else
- cat << \SHAR_EOF > 'sys/eunice/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
- #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/vms/aaareadme.1st'
- then
- echo shar: will not over-write existing file "'sys/vms/aaareadme.1st'"
- else
- cat << \SHAR_EOF > 'sys/vms/aaareadme.1st'
- This directory ([.SYS.VMS]) contains the VMS-specific files for MicroGnuEmacs.
-
- +-----------------------+
- | Construction |
- +-----------------------+
-
- By this point you should have put the ``system-independent'' files into
- a directory of your choice, then put the VMS files into the subdirectory
- [.SYS.VMS]. You should also put the termcap terminal driver into the
- subdirectory [.TTY.TERMCAP].
-
- The command file MAKE.COM is designed to compile and link the entire
- program, using the VMS system functions and the termcap terminal driver.
-
- To invoke MAKE.COM, enter
-
- SET DEF dev:[emacs-dir] ! location of system-independent files
- @[.SYS.VMS]MAKE ! go have some coffee...
-
- This will create the termcap library, compile each of the necessary
- modules, and link the entire program into dev:[emacs-dir]MG.EXE.
-
- NOTE: To keep the size of the executable program down,
- [.SYS.VMS]MGLINK.COM attempts to link in the VAX C shareable run-time
- library. If the command procedure finds the file SYS$SHARE:VAXCRTL.EXE,
- it attempts to link to it, else it defaults to SYS$LIBRARY:VAXCRTL.OLB
- for the runtime library.
-
- +-------------------------------------------------------+
- | Specifying Your Terminal With Termcap |
- +-------------------------------------------------------+
-
- (CAVEAT AND CREDITS: The termcap library in [.SYS.VMS.TERMCAP] was
- written by Fred Fish (of Amiga Public Domain Library fame) and placed in
- the public domain. It is not guaranteed to be a complete implementation
- of the Unix termcap(5) library; the usual disclaimers (like "it works
- for me":-) apply here. I have modified it to support the tc=
- capability, which lets you define terminals in terms (pardon the pun) of
- other terminals, so it should work reasonably well with the termcap
- provided in [.SYS.VMS.TERMCAP]TERMCAP.)
-
- To use the termcap library, you need to tell it where to find a terminal
- definition (termcap) file. On Unix systems, this is found in a file
- called /etc/termcap. To emulate the same behavior on VMS, DEFINE/JOB the
- logical name ETC to point to a directory that contains a termcap file,
- with the name TERMCAP. (no extension). (The /JOB qualifier is needed
- when you run MicroGnuEmacs as a spawned supprocess.)
-
- If your system has Eunice, there is a large termcap file already
- available via this exact mechanism, so you shouldn't need to define ETC
- at all. If you don't have Eunice, never fear; a termcap resides in the
- file [.SYS.VMS.TERMCAP]TERMCAP., so all you have to do is
-
- DEFINE ETC [emacs-directory.SYS.VMS.TERMCAP]
-
- to get started. You get the idea. Lastly, if your site uses the logical
- name ETC for another purpose, you can define the logical name TERMCAP
- to point to the MG termcap file. You must specify the path in Unix format,
- with the root being the disk drive the file resides on. For example,
- if the termcap file is in DUA0:[USER]TERMCAP., the command would be
-
- DEFINE TERMCAP "/dua0/user/termcap"
-
- The VAX C run-time library can translate this into the appropriate
- VMS file specification for you (a rather nice feature...).
-
- Once you've indicated where the termcap file is,
- DEFINE/JOB TERM "termtype"
-
- where "termtype" is in lower case and matches an entry in the termcap
- file. This tells MicroEmacs (even when it runs in another process) what
- your terminal type is.
-
- NOTE: One performance aspect of termcap files is that they are searched
- sequentially, so you may want to move the most frequently used terminals
- at your site to the beginning of the file to minimize startup overhead.
-
- +---------------------------------------+
- | INVOKING MG |
- +---------------------------------------+
-
- First of all, remember to set up the logical names for the terminal
- type and termcap file:
- $ DEFINE/JOB ETC dev:[dir] ! location of TERMCAP. file
- (or)$ DEFINE/JOB TERMCAP "/disk/dir1/dir2/termcapfile"
-
- $ DEFINE/JOB TERM "termtype" ! termtype is lower case
-
- (Obviously, this can be done just once, in your LOGIN.COM file.)
-
- Then, to just run MicroGnuEmacs in your current process,
- $ RUN [emacs-directory]MG
-
- Or you can define a symbol to run it with command line arguments:
- $ MG :== $dev:[emacs-directory]MG
- $ MG [file]
-
- +---------------------------------------+
- | MG As a Kept Fork |
- +---------------------------------------+
-
- You can use [.SYS.VMS]MG.COM to spawn a MicroEmacs subjob, which you
- can then attach to and pop out of as you please. Edit the line at the
- top of MG.COM that defines the path to the image MG.EXE, then define a
- global symbol called MG:
-
- $ MG :== @dev:[emacs-directory.SYS.VMS]MG
-
- You can then use MG to edit files:
-
- $ MG [file]
-
- When inside MicroGnuEmacs, use the command M-x suspend-emacs (bound to
- C-z by default) to suspend the MicroGnuEmacs process and attach your
- terminal to the process that spawned it. To re-attach to
- MicroGnuEmacs, just issue the MG command again:
-
- $ MG [file]
-
- The command file will reattach you to your MicroGnuEmacs process,
- where you can continue editing where you left off. If you specify a
- new file to edit, the command file sets a logical name which
- MicroGnuEmacs then looks at when you reattach.
-
- Note that this functionality may not be identical to what happens in
- real GNU Emacs for VMS. However, it does provide a facility that you
- don't really want to do without.
-
- +---------------------------------------+
- | MicroGnuEmacs As a Mail Editor |
- +---------------------------------------+
-
- As an added bonus, the file MGMAILEDIT.COM makes MicroGnuEmacs your
- mail editor when you use the SEND/EDIT command. Just issue the
- command
-
- DEFINE/JOB MAIL$EDIT dev:[dir]MGMAILEDIT.COM
-
- to inform the mail system you want to use MGMAILEDIT.COM, then whenever
- you issue SEND/EDIT inside mail, MG will be used as your mail editor.
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/vms/bcopy.mar'
- then
- echo shar: will not over-write existing file "'sys/vms/bcopy.mar'"
- else
- cat << \SHAR_EOF > 'sys/vms/bcopy.mar'
- .title bcopy MicroEmacs access to movc3
- ;
- ; Mic Kaczmarczik
- ; July 11, 1986
- ;
- ; This code implements the bcopy() function for quick
- ; memory copies in VAX C.
- ;
- .entry bcopy,^m<r2,r3,r4,r5> ; MOVC3 side-effects r0-r5
- subl2 #4,sp ; Step over call frame
- movc3 12(ap),@4(ap),@8(ap) ; Copy them bytes
- ret ; Bye!
- .end
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/vms/ccom.com'
- then
- echo shar: will not over-write existing file "'sys/vms/ccom.com'"
- else
- cat << \SHAR_EOF > 'sys/vms/ccom.com'
- $ Verify = F$Verify(0)
- $!
- $! CCOM.COM
- $!
- $! Run the C compiler on P1, but only if the .c file
- $! is newer than the corresponding .obj file.
- $!
- $! Usage:
- $! @CCOM [file [qualifiers]]
- $!
- $ If P1 .Eqs. "" Then -
- Inquire P1 "C Source File"
- $ Name = P1 - ".C"
- $ Source = Name + ".C"
- $ Object = Name + ".OBJ"
- $!
- $! See if both files exist. If both exist, only compile the
- $! source if the revision date is greater than or equal to
- $! that of the object file.
- $!
- $ If F$Search(Source) .Eqs. "" Then -
- Goto NoSource
- $ If F$Search(Object) .Eqs. "" Then -
- $ Goto Compile
- $ SDate = F$File_Attributes(Source, "RDT")
- $ ODate = F$File_Attributes(Object, "RDT")
- $ If SDate .Lts. ODate Then -
- Goto Bye
- $!
- $! Compile the program
- $!
- $Compile:
- $ On Error Then Goto Fail
- $ Write Sys$Output "Compiling " + Source
- $ CC 'P2' 'Source
- $ If F$Search(Object) .Eqs. "" Then -
- Goto Fail
- $!
- $! Done.
- $!
- $Bye:
- $ If Verify Then -
- Set Verify
- $ Exit
- $!
- $NoSource:
- $ Write Sys$Output "%CCOM-F-NOTFOUND, file not found"
- $ Goto Bye
- $!
- $Fail:
- $ Write Sys$Output "%CCOM-F-FAIL, compile failed"
- $ Goto Bye
-
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/vms/make.com'
- then
- echo shar: will not over-write existing file "'sys/vms/make.com'"
- else
- cat << \SHAR_EOF > 'sys/vms/make.com'
- $ on error then goto trouble
- $ on severe_error then goto trouble
- $ default = f$trnlnm("SYS$DISK") + f$directory()
- $!
- $! Command procedure to build MicroGnuEmacs on VMS systems.
- $!
- $! Compile-time options you can set by appropriate assignments to
- $! "ccomflags" and "linkflags". Defining these flags asks for
- $! a particular feature.
- $!
- $! /DEFINE:"STARTUP" -- look for SYS$LOGIN:.MG startup file
- $! /DEFINE:"FLOWCONTROL" -- use ^S, ^Q for flow control
- $!
- $! Set compilation and linking options. The first commented-out-line is
- $! the set I use...
- $ ccomflags := "/define:""STARTUP"" "
- $! ccomflags := "/define:(""STARTUP"",""XKEYS"",""PREFIXREGION"") "
- $! ccomflags := "/debug" ! if you want to debug the program
- $!
- $ linkflags := ""
- $! linkflags := "/debug" ! to debug the program
- $!
- $! To make MG,
- $!
- $! Set def to the top level MicroGnuEmacs directory and type
- $!
- $! @[.SYS.VMS]MAKE
- $!
- $! to get things rolling.
- $!
- $!* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- $! Create the termcap library
- $!
- $ set def [.sys.vms.termcap]
- $ @createlib.com
- $ set def [---]
- $!* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- $! Define a search path for source files. This is important
- $! because
- $! 1) The search path lets us to keep these files in
- $! separate directories
- $! 2) When searching for quoted #include files (e.g.
- $! #include "def.h"), VAX C uses the default file
- $! specification set up by the source file name.
- $!
- $! If we use mgsrc:foo.c, the search list becomes
- $! part of the default file spec, and the compiler
- $! can find the system- and terminal-specific
- $! header files. This acts as a substitute for the
- $! -I flag found on most Unix C compilers.
- $!
- $! A side effect of the search list is that the object files get
- $! created in the top level directory, which I prefer.
- $!
- $ define mgsrc [],[.sys.vms],[.tty.termcap]
- $!
- $! Define alias for the compilation command. By default, use a
- $! command file that checks revision dates and only compiles when
- $! it has to. If you want to force a total recompile, switch the
- $! comments around.
- $!
- $ ccom := @mgsrc:ccom
- $! ccom := cc
- $!
- $! Compile all the basic files
- $!
- $ ccom mgsrc:basic 'ccomflags
- $ ccom mgsrc:buffer 'ccomflags
- $ ccom mgsrc:cinfo 'ccomflags
- $ ccom mgsrc:display 'ccomflags
- $ ccom mgsrc:echo 'ccomflags
- $ ccom mgsrc:extend 'ccomflags
- $ ccom mgsrc:file 'ccomflags
- $ ccom mgsrc:kbd 'ccomflags
- $ ccom mgsrc:line 'ccomflags
- $ ccom mgsrc:main 'ccomflags
- $ ccom mgsrc:match 'ccomflags
- $ ccom mgsrc:paragraph 'ccomflags
- $ ccom mgsrc:prefix 'ccomflags
- $ ccom mgsrc:random 'ccomflags
- $ ccom mgsrc:region 'ccomflags
- $ ccom mgsrc:search 'ccomflags
- $ ccom mgsrc:symbol 'ccomflags
- $ ccom mgsrc:version 'ccomflags
- $ ccom mgsrc:window 'ccomflags
- $ ccom mgsrc:word 'ccomflags
- $!
- $! Compile the terminal interface
- $!
- $ ccom mgsrc:tty 'ccomflags
- $ ccom mgsrc:ttykbd 'ccomflags
- $!
- $! Compile the VMS-specific files
- $!
- $ ccom mgsrc:fileio 'ccomflags
- $ ccom mgsrc:spawn 'ccomflags
- $ ccom mgsrc:trnlnm 'ccomflags
- $ ccom mgsrc:ttyio 'ccomflags/define:"FLOWCONTROL=0"
- $ macro mgsrc:bcopy
- $!
- $! Link the program
- $!
- $ @[.sys.vms]mglink "''linkflags'"
- $!
- $! We're done!
- $!
- $ write sys$output "MicroEmacs build completed."
- $ set default 'default
- $ exit
- $!
- $! Trouble somewhere -- go 'way
- $!
- $trouble:
- $ write sys$output "Problem building MicroEmacs!!!!!"
- $ set default 'default
- $ exit
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/vms/mg.com'
- then
- echo shar: will not over-write existing file "'sys/vms/mg.com'"
- else
- cat << \SHAR_EOF > 'sys/vms/mg.com'
- $ Verify = 'F$Verify(0)
- $!
- $! MG.COM
- $!
- $! Usage:
- $! @MG [file1 [file2 [...]]] ! To start up MG
- $! @MG [file] ! To reattach to MG after ^Z
- $!
- $! MG.COM implements a "kept-fork" capability for MG, allowing you to pop
- $! in and out of the editor without reloading it all the time. If a
- $! process called user_MG (where user is your username) exists, this
- $! command file attempts to attach to it. If not, it silently spawns a
- $! subjob to run Emacs for you.
- $!
- $! To `keep' MG around once you get into it, use "suspend-emacs" (bound
- $! to C-z by default) to suspend MG and attach back to the process
- $! pointed to by MG$AttachTo.
- $!
- $! To get back into MG from DCL enter @MG again. You may optionally
- $! specify *one* new file name, in which case MG will attempt to
- $! visit that file when you re-attach.
- $!
- $!----------------------------------------------------------------
- $!
- $! Set things up. Change the definition of MG_Name to whatever you like.
- $! You'll *have* to redefine MG_PROG, of course...
- $!
- $ MG_Name = F$Edit(F$Getjpi("","USERNAME"),"TRIM") + "_MG"
- $ MG_Prog = "Disk$Staff:[Ccep001.Proj.Mg3]MG.Exe"
- $ MG_Base = MG_Name ! Used for additions
- $ If F$Length(MG_Base) .GT. 13 Then - ! Truncate base for _1,_2...
- $ MG_Base = F$Extract(0,13,MG_Base)
- $ Proc = F$GetJpi("","PRCNAM")
- $ Master_Pid = F$Getjpi("","MASTER_PID")
- $!
- $! Define logical names used for communicating with MG
- $!
- $ Define/Nolog/Job MG$AttachTo "''Proc'"
- $ Define/Nolog/Job MG$File " " ! No file by default
- $ If P1 .Nes. "" Then -
- Define/Nolog/Job MG$File "''P1'"
- $!
- $! Attempt to find MG subprocess in current tree. If found, attach
- $! to it, else spawn a new MG process
- $!
- $ Save_Priv = F$SetPrv("NOWORLD,NOGROUP") ! Only look in job tree
- $ Try_Count = 1
- $Search:
- $ Context = "" ! Set up process search context
- $ProcLoop:
- $ Pid = F$Pid(Context) ! Get next PID
- $ If Pid .Eqs. "" Then -
- Goto Spawn ! No MG_Name found; spawn a process
- $ If F$GetJpi(Pid,"PRCNAM") .Nes. MG_Name Then -
- Goto Procloop ! Try next process
- $! Process name matches; see if it's in our job
- $ If F$GetJpi(Pid,"MASTER_PID") .Eqs. Master_Pid Then -
- Goto Attach ! Found process in our job!
- $! Process name matches, but isn't in our job. Re-start search
- $ MG_Name = MG_Base + "_" + F$String(Try_Count)
- $ Try_Count = Try_Count + 1
- $ Goto Search
- $!
- $! Here to attach to a process in our tree. Set message to
- $! turn off the "Attaching to..." message
- $!
- $Attach:
- $ Message = F$Environment("MESSAGE")
- $ Set Proc/Priv=('Save_Priv') ! Restore privileges
- $ Set Message/NoFacility/NoIdentification/NoSeverity/NoText
- $ Attach "''MG_Name'"
- $ Set Message/Facility/Identification/Severity/Text
- $ Goto Done
- $!
- $! Here if can't attach. Spawn a new MG process
- $!
- $Spawn:
- $ Set Process/Priv=('Save_Priv') ! Restore privileges
- $ MG$MG :== $'MG_Prog' ! Avoid recursion
- $ Spawn/NoLog/Proc="''MG_Name'" MG$MG 'P1' 'P2' 'P3' 'P4' 'P5' 'P6' 'P7' 'P8'
- $ Delete/Symbol/Global MG$MG ! Get rid of it
- $Done:
- $!
- $! Here once we reconnect from MG, whether we detached or exited.
- $!
- $ Deassign/Job MG$File
- $ Deassign/Job MG$AttachTo
- $ If Verify Then -
- Set Verify
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/vms/mglink.com'
- then
- echo shar: will not over-write existing file "'sys/vms/mglink.com'"
- else
- cat << \SHAR_EOF > 'sys/vms/mglink.com'
- $!
- $! Link MicroGnuEmacs object files into MG.EXE
- $!
- $! Note: This command procedure is designed to be executed
- $! in the main microEmacs directory.
- $!
- $! Further note: If the VAX C shareable run-time library is
- $! found in SYS$SHARE, the command procedure uses it.
- $! If not found, it uses SYS$LIBRARY:VAXCRTL.
- $
- $ runtime_library := sys$library:vaxcrtl.olb/lib
- $ if f$search("SYS$SHARE:VAXCRTL.EXE") .nes. "" then -
- runtime_library := [.sys.vms]emacs.opt/opt
- $ link'p1'/exec=sys$disk:[]mg.exe basic.obj, buffer.obj, cinfo.obj, -
- display.obj, echo.obj, extend.obj, file.obj, kbd.obj, line.obj, -
- main.obj, match.obj, paragraph.obj, prefix.obj, random.obj, -
- region.obj, search.obj, symbol.obj, version.obj, window.obj, word.obj, -
- tty.obj, ttykbd.obj, -
- fileio.obj, spawn.obj, trnlnm.obj, ttyio.obj, bcopy.obj, -
- [.sys.vms.termcap]termcap.olb/lib,-
- 'runtime_library'
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/vms/mgmailedit.com'
- then
- echo shar: will not over-write existing file "'sys/vms/mgmailedit.com'"
- else
- cat << \SHAR_EOF > 'sys/vms/mgmailedit.com'
- $ Verify = 'F$Verify(0)
- $ ! Command procedure to invoke MG from MAIL. You should
- $ ! have the symbol MG globally defined, either as
- $ !
- $ ! MG :== $dev:[dir]MG
- $ !
- $ ! Then
- $ ! DEFINE MAIL$EDIT dev:[dir]MGMAILEDIT.COM
- $ !
- $ ! to make MAIL look for this file.
- $ !
- $ ! or, if using the kept-fork capability,
- $ !
- $ ! MG :== @dev:[dir]MG.COM
- $ !
- $ ! Inputs:
- $ !
- $ ! P1 = Input file name.
- $ ! P2 = Output file name.
- $ !
- $ ! The default directory is the same as the parent process.
- $ !
- $ ! Copy the input file to the output file, then invoke MG on it.
- $ !
- $ Set Noon
- $ Define/Job MG$AttachTo "''F$Process()'"
- $ If P2 .Nes. "" .AND. P1 .Nes. "" Then Copy 'P1' 'P2'
- $ Define/User Sys$Input Sys$Command
- $ MG 'P2'
- $ If F$Trnlnm("MG$AttachTo") .Nes. "" Then - ! MG.COM might have done it already
- Deassign/Job MG$AttachTo
- $ If Verify Then -
- Set Verify
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/vms/emacs.opt'
- then
- echo shar: will not over-write existing file "'sys/vms/emacs.opt'"
- else
- cat << \SHAR_EOF > 'sys/vms/emacs.opt'
- SYS$SHARE:VAXCRTL.EXE/SHARE
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/vms/fileio.c'
- then
- echo shar: will not over-write existing file "'sys/vms/fileio.c'"
- else
- cat << \SHAR_EOF > 'sys/vms/fileio.c'
- /*
- * Name: MicroEMACS
- * Version: 30
- * VAX/VMS file I/O.
- * Last edit: 05-Feb-86
- * By: rex::conroy
- * decvax!decwrl!dec-rhea!dec-rex!conroy
- *
- * Read and write ASCII files. All
- * of the low level file I/O knowledge is here.
- * VAX/VMS.
- * Pretty much vanilla standard I/O, using
- * the (traditional) funny open.
- */
- #include "def.h"
-
- 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;
- {
- register int fd;
-
- if ((fd=creat(fn, 0, "rfm=var", "rat=cr")) < 0
- || (ffp=fdopen(fd, "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). 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).
- * (17-Jul-1986 MPK) strip NULs too.
- */
- 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 (c == '\0') /* strip NULs */
- continue;
- 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);
- }
-
- /*
- * VMS has version numbers, so there is
- * no need for MicroEMACS to bother making its own
- * flavour of backup copy. Return TRUE so the
- * caller doesn't quit.
- */
- fbackupfile(fname)
- char *fname;
- {
- return (TRUE);
- }
-
- /*
- * 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.
- */
- adjustcase(fn)
- register char *fn;
- {
- register int c;
-
- while ((c = *fn) != 0) {
- if (c>='A' && c<='Z')
- *fn = c + 'a' - 'A';
- ++fn;
- }
- }
-
- #ifndef MICRO
- #include <file.h>
- /*
- * Find the user's startup file, and return its name.
- * Use the VAX C getenv() function, which returns the VMS
- * directory spec for the user's home directory.
- * Check for ${HOME}.emacs, then for ${HOME}.mg, 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)]);
-
- (VOID) strcpy(file, ".mg");
- if (access(home, O_RDONLY ) == 0) return home;
-
- (VOID) strcpy(file, ".emacs");
- if (access(home, O_RDONLY) == 0) return home;
-
- return NULL;
- }
- #endif
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/vms/spawn.c'
- then
- echo shar: will not over-write existing file "'sys/vms/spawn.c'"
- else
- cat << \SHAR_EOF > 'sys/vms/spawn.c'
- /*
- * Name: MicroEMACS
- * VAX/VMS spawn and attach to a DCL subprocess.
- * Created: rex::conroy
- * decvax!decwrl!dec-rhea!dec-rex!conroy
- * Modified:
- * 19-May-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
- * Add att-to-parent command to attach to the parent
- * process. If we can't attach to parent somehow,
- * spawn a DCL subjob. This gives us the same
- * suspend capability as Unix Emacses.
- *
- * As an added hook, you can DEFINE/JOB
- * MG$ATTACHTO to a process name, and
- * the code will try to attach to that name.
- *
- * Also, if the logical name MG$FILE is
- * defined, attachtoparent() will visit that file
- * when you re-attach to Emacs. This is useful
- * for a lot of applications, especially MAIL/EDIT...
- * 26-Jun-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
- * Specify process we're attaching to when we attempt
- * to attach to it.
- * 03-Sep-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
- * Call savebuffers() before leaving the editor.
- * Unlike csh, DCL has no problem with people
- * logging out without completing subjobs...
- * #define NOSAVEONZ if you don't want this behavior.
- * 13-Oct-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
- * Change MICROEMACS$... to MG$... for consistency.
- */
- #include "def.h"
-
- #include <ssdef.h>
- #include <stsdef.h>
- #include <descrip.h>
- #include <iodef.h>
- #include <jpidef.h>
-
- #define EFN 0 /* Event flag. */
-
- extern int oldmode[3]; /* In "ttyio.c". */
- extern int newmode[3];
- extern short iochan;
- extern int ckttysize(); /* Checks for new term size */
- #ifndef NOSAVEONZ
- extern int savebuffers(); /* Save all buffers before */
- #endif
-
- /*
- * Create a subjob with a copy
- * of the command intrepreter in it. When the
- * command interpreter exits, mark the screen as
- * garbage so that you do a full repaint. Bound
- * to "C-C" and called from "C-Z". The message at
- * the start in VMS puts out a newline. Under
- * some (unknown) condition, you don't get one
- * free when DCL starts up.
- */
-
- spawncli(f, n, k)
- {
- register int s;
-
- #ifndef NOSAVEONZ
- if (savebuffers() == ABORT) /* TRUE means all saved,*/
- return (ABORT); /* FALSE means not. */
- #endif
- eerase(); /* Get rid of echo line */
- ttcolor(CTEXT); /* Normal color. */
- ttnowindow(); /* Full screen scroll. */
- ttmove(nrow-1, 0); /* Last line. */
- eputs("Starting DCL");
- ttputc('\r');
- ttputc('\n');
- ttflush();
- sgarbf = TRUE;
- s = sys(NULL); /* NULL => DCL. */
- return (s);
- }
-
- /*
- * Run a command. The "cmd" is a pointer
- * to a command string, or NULL if you want to run
- * a copy of DCL in the subjob (this is how the standard
- * routine LIB$SPAWN works. You have to do wierd stuff
- * with the terminal on the way in and the way out,
- * because DCL does not want the channel to be
- * in raw mode.
- */
- sys(cmd)
- register char *cmd;
- {
- struct dsc$descriptor cdsc;
- struct dsc$descriptor *cdscp;
- long status;
- long substatus;
- long iosb[2];
-
- status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
- oldmode, sizeof(oldmode), 0, 0, 0, 0);
- if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
- return (FALSE);
- cdscp = NULL; /* Assume DCL. */
- if (cmd != NULL) { /* Build descriptor. */
- cdsc.dsc$a_pointer = cmd;
- cdsc.dsc$w_length = strlen(cmd);
- cdsc.dsc$b_dtype = DSC$K_DTYPE_T;
- cdsc.dsc$b_class = DSC$K_CLASS_S;
- cdscp = &cdsc;
- }
- status = LIB$SPAWN(cdscp, 0, 0, 0, 0, 0, &substatus, 0, 0, 0);
- if (status != SS$_NORMAL)
- substatus = status;
- ckttysize(); /* check for new terminal size */
- status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
- newmode, sizeof(newmode), 0, 0, 0, 0);
- if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
- return (FALSE);
- if ((substatus&STS$M_SUCCESS) == 0) /* Command failed. */
- return (FALSE);
- return (TRUE);
- }
-
- /*
- * Front end for combined attach-to-parent and spawn-cli action
- */
-
- attachtoparent(f, n, k)
- {
- register int s;
- s = attparent();
- if (s == ABORT)
- return (ABORT);
- else if (s == FALSE)
- return spawncli(f, n, k); /* better than nothing */
- else
- return (TRUE);
- }
-
- /*
- * Attach to parent. If the logical name MG$ATTACHTO
- * is present, attempt to attach to it. If not, attempt to
- * attach to parent process.
- *
- * On return, see if the logical name MG$FILE contains
- * anything, and try to visit that file.
- */
-
- static $DESCRIPTOR(nmdsc,"MG$ATTACHTO");
-
- attparent()
- {
- long pid, jpi_code;
- char equiv[18], msgbuf[60];
- struct dsc$descriptor_s eqdsc;
- short eqlen;
- int status, pos;
- register BUFFER *bp;
- BUFFER *findbuffer();
- int s;
-
-
- /* Set up string descriptor */
- eqdsc.dsc$a_pointer = equiv;
- eqdsc.dsc$w_length = sizeof(equiv);
- eqdsc.dsc$b_dtype = DSC$K_DTYPE_T;
- eqdsc.dsc$b_class = DSC$K_CLASS_S;
-
- /* Try to translate MG$ATTACH */
- status = lib$sys_trnlog(&nmdsc, &eqdsc.dsc$w_length, &eqdsc);
- if (status!=SS$_NORMAL && status!=SS$_NOTRAN) {
- ewprintf("Error translating %s",nmdsc.dsc$a_pointer);/* DEBUG */
- return (FALSE);
- }
-
- if (status == SS$_NORMAL) {
- /* Found a translation -- attempt to attach to it */
- jpi_code = JPI$_PID;
-
- status = lib$getjpi(&jpi_code,0,&eqdsc,&pid,0);
- equiv[eqdsc.dsc$w_length] = '\0';
- if (status != SS$_NORMAL) {
- ewprintf("Error getting JPI for \"%s\"",equiv);
- return (FALSE);
- }
-
- #ifndef NOSAVEONZ
- /* Attempt to attach to named process. Save all buffers, */
- /* set sgarbf because attach() always trashes the display */
- if (savebuffers() == ABORT)
- return (ABORT);
- #endif
- /* indicate process we're attaching to */
- strcpy(msgbuf,"Attaching to process \"");
- for (pos = strlen(equiv) - 1; pos >= 0; --pos)
- if (equiv[pos] != ' ') {
- equiv[pos+1] = '\0';
- break;
- }
- strcat(msgbuf,equiv);
- strcat(msgbuf,"\"");
-
- sgarbf = TRUE;
- if (attach(pid,msgbuf) == FALSE) /* whups -- try spawn */
- return (FALSE);
- }
- else { /* No translation -- attempt to find parent process */
- jpi_code = JPI$_OWNER;
- status = lib$getjpi(&jpi_code,0,0,&pid,0,0);
-
- if ((status != SS$_NORMAL) || (pid == 0)) /* not found! */
- return (FALSE);
-
- #ifndef NOSAVEONZ
- if (savebuffers() == ABORT)
- return (ABORT);
- #endif
- sgarbf = TRUE;
- if (attach(pid,"Attaching to parent process") == FALSE)
- return (FALSE);
- }
-
- newfile(); /* attempt to find a new file, but don't care */
- /* if we don't find one... */
- refresh(FALSE, 0, KRANDOM);
- return (TRUE);
- }
-
- /*
- * If we find after re-attaching that there is
- * a new file to be edited, attempt to read it in,
- * using essentially the same code as findfile().
- */
-
- static newfile()
- {
- register BUFFER *bp;
- register int s;
- char filename[NFILEN];
- BUFFER *findbuffer();
-
- if ((s = cknewfile(filename, sizeof filename)) != TRUE)
- return (s);
- if ((bp = findbuffer(filename, &s)) == NULL)
- return (s);
- curbp = bp;
- if (showbuffer(bp, curwp, WFHARD) != TRUE)
- return (FALSE);
- if (bp->b_fname[0] == 0)
- return (readin(filename)); /* Read it in. */
- return (TRUE);
- }
-
- /*
- * Attach to a process by process number. Restore the
- * terminal channel to the way it was when we started.
- * Also put out an optional message to the user.
- */
-
- static attach(pid, msg)
- long pid;
- char *msg;
- {
- long status, attstatus;
- long iosb[2];
-
- ttcolor(CTEXT); /* Normal color. */
- ttnowindow(); /* Full screen scroll. */
- ttmove(nrow-1, 0); /* Last line. */
- if (msg) { /* Display a message */
- eputs(msg);
- ttputc('\r');
- ttputc('\n');
- }
- ttflush();
-
- /* Set terminal to old modes */
- status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
- oldmode, sizeof(oldmode), 0, 0, 0, 0);
- if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
- return (FALSE);
-
- /* Attach to the process */
- attstatus = LIB$ATTACH(&pid);
-
- /* Return terminal to the modes MG needs */
- ckttysize(); /* check for new terminal size first */
- status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
- newmode, sizeof(newmode), 0, 0, 0, 0);
- if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
- return (FALSE);
-
- return (attstatus == SS$_NORMAL ? TRUE : FALSE);
- }
-
-
- /*
- * Attempt to translate MG$FILE into fname.
- * If it's there and non-empty, return TRUE.
- */
-
- static $DESCRIPTOR(filedsc,"MG$FILE");
-
- static cknewfile(fname,fnsiz)
- char *fname;
- int fnsiz;
- {
- char equiv[NFILEN];
- struct dsc$descriptor_s eqdsc;
- short len;
- register int status;
-
- eqdsc.dsc$a_pointer = equiv;
- eqdsc.dsc$w_length = sizeof(equiv);
- eqdsc.dsc$b_dtype = DSC$K_DTYPE_T;
- eqdsc.dsc$b_class = DSC$K_CLASS_S;
-
- status = lib$sys_trnlog(&filedsc, &len, &eqdsc);
- if (status!=SS$_NORMAL && status!=SS$_NOTRAN) {
- ewprintf("Error translating MG$FILE");
- return (FALSE);
- }
-
- if (status == SS$_NOTRAN) /* No new file found */
- return (FALSE);
-
- if (equiv[0] == ' ')
- return (FALSE);
-
- equiv[len] = '\0';
- strcpy(fname, equiv);
- return (TRUE);
- }
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/vms/trnlnm.c'
- then
- echo shar: will not over-write existing file "'sys/vms/trnlnm.c'"
- else
- cat << \SHAR_EOF > 'sys/vms/trnlnm.c'
- /*
- * Name: MicroEmacs
- * VAX/VMS translate logical name routine
- * Version: Gnu30
- * Last Edit: 10-Jul-86
- * By: ...!ihnp4!seismo!ut-sally!ut-ngp!mic
- *
- */
-
- /*
- *
- * Trnlnm()
- *
- * Description:
- * Attempt to translate the logical name logname into an equivalence
- * string, using the standard VMS routine LIB$SYS_TRNLOG().
- * If a translation exists, return a pointer to the static area
- * that contains the null-terminated translation string. If not,
- * return 0.
- *
- * Bugs:
- * Returns a pointer to static data that is modified each time
- * the routine successfully translates a logical name.
- */
-
- #include <ssdef.h>
- #include <descrip.h>
- #include <stdio.h>
-
- static char _equiv_buf[256];
- static struct dsc$descriptor_s
- _equiv = {
- sizeof(_equiv_buf), DSC$K_DTYPE_T, DSC$K_CLASS_S, _equiv_buf
- },
- _name = {
- 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL
- };
-
- char *trnlnm(logname)
- char *logname;
- {
- short eqlen;
- int status;
-
- if (logname == NULL)
- return (NULL);
-
- _name.dsc$a_pointer = logname;
- _name.dsc$w_length = strlen(logname);
-
- status = lib$sys_trnlog(&_name, &eqlen, &_equiv);
- if (status != SS$_NORMAL)
- return (NULL);
-
- _equiv_buf[eqlen] = '\0';
- return (_equiv_buf);
- }
-
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/vms/ttyio.c'
- then
- echo shar: will not over-write existing file "'sys/vms/ttyio.c'"
- else
- cat << \SHAR_EOF > 'sys/vms/ttyio.c'
- /*
- * Name: MicroGnuEmacs
- * VAX/VMS terminal I/O.
- * o 16-Apr-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
- * Turn off TTSYNC so ^S and ^Q are sent to program.
- * To get this back, compile with -DFLOWCONTROL
- * o 10-Jul-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
- * Add setttysize(), typeahead() and panic() for Gnu v30
- */
- #include "def.h"
-
- #include <stsdef.h>
- #include <ssdef.h>
- #include <descrip.h>
- #include <iodef.h>
- #include <ttdef.h>
- #include <tt2def.h>
-
- #define NIBUF 128 /* Probably excessive. */
- #define NOBUF 512 /* Not too big for 750/730. */
- #define EFN 0 /* Event flag */
-
- char obuf[NOBUF]; /* Output buffer */
- int nobuf; /* # of bytes in above */
- char ibuf[NIBUF]; /* Input buffer */
- int nibuf; /* # of bytes in above */
- int ibufi; /* Read index */
- int oldmode[3]; /* Old TTY mode bits */
- int newmode[3]; /* New TTY mode bits */
- short iochan; /* TTY I/O channel */
- int nrow; /* Terminal size, rows. */
- int ncol; /* Terminal size, columns. */
- short ospeed; /* Terminal output speed */
- /* for termcap library */
-
- /*
- * This routines gets called once, to set up the
- * terminal channel.
- * On VMS we find the translation of the SYS$COMMAND:
- * logical name, assign a channel to it, and set it raw.
- */
-
- ttopen()
- {
- struct dsc$descriptor idsc;
- struct dsc$descriptor odsc;
- char oname[40];
- int iosb[2];
- int status;
-
- odsc.dsc$a_pointer = "SYS$COMMAND";
- odsc.dsc$w_length = strlen(odsc.dsc$a_pointer);
- odsc.dsc$b_dtype = DSC$K_DTYPE_T;
- odsc.dsc$b_class = DSC$K_CLASS_S;
- idsc.dsc$b_dtype = DSC$K_DTYPE_T;
- idsc.dsc$b_class = DSC$K_CLASS_S;
- do {
- idsc.dsc$a_pointer = odsc.dsc$a_pointer;
- idsc.dsc$w_length = odsc.dsc$w_length;
- odsc.dsc$a_pointer = &oname[0];
- odsc.dsc$w_length = sizeof(oname);
- status = LIB$SYS_TRNLOG(&idsc, &odsc.dsc$w_length, &odsc);
- if (status!=SS$_NORMAL && status!=SS$_NOTRAN)
- exit(status);
- if (oname[0] == 0x1B) {
- odsc.dsc$a_pointer += 4;
- odsc.dsc$w_length -= 4;
- }
- } while (status == SS$_NORMAL);
- status = SYS$ASSIGN(&odsc, &iochan, 0, 0);
- if (status != SS$_NORMAL)
- exit(status);
- status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE, iosb, 0, 0,
- oldmode, sizeof(oldmode), 0, 0, 0, 0);
- if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
- exit(status);
-
- nrow = (oldmode[1]>>24) & 0xFF; /* Terminal length. */
- if (nrow > NROW)
- nrow = NROW;
- ncol = (oldmode[0]>>16) & 0xFFFF; /* Width. */
- if (ncol > NCOL)
- ncol = NCOL;
- ospeed = (iosb[0]>>24) & 0xFF; /* Speed (for termcap) */
- newmode[0] = oldmode[0]; /* Only in version 4. */
- #ifdef FLOWCONTROL
- newmode[1] = oldmode[1] | TT$M_NOECHO | TT$M_TTSYNC;
- #else
- newmode[1] = (oldmode[1] | TT$M_NOECHO) & ~TT$M_TTSYNC;
- #endif
- newmode[2] = oldmode[2] | TT2$M_PASTHRU;
- status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
- newmode, sizeof(newmode), 0, 0, 0, 0);
-
- if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
- exit(status);
- }
-
- /*
- * This function gets called just
- * before we go back home to the command interpreter.
- * On VMS it puts the terminal back in a reasonable state.
- */
- ttclose()
- {
- int status;
- int iosb[2];
-
- ttflush();
- status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
- oldmode, sizeof(oldmode), 0, 0, 0, 0);
- if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
- exit(status);
- status = SYS$DASSGN(iochan);
- if (status != SS$_NORMAL)
- exit(status);
- }
-
- /*
- * Write a character to the display.
- * On VMS, terminal output is buffered, and
- * we just put the characters in the big array,
- * after checking for overflow.
- */
- ttputc(c)
- {
- if (nobuf >= NOBUF)
- ttflush();
- obuf[nobuf++] = c;
- }
-
- /*
- * This function does the real work of
- * flushing out buffered I/O on VMS. All
- * we do is blast out the block with a write call. No status
- * checking is done on the write, because there isn't anything
- * clever that can be done, and because you will see the
- * error as a messed up screen.
- */
- ttflush()
- {
- int iosb[2];
-
- if (nobuf != 0) {
- SYS$QIOW(EFN, iochan, IO$_WRITELBLK|IO$M_NOFORMAT,
- iosb, 0, 0, obuf, nobuf, 0, 0, 0, 0);
- nobuf = 0;
- }
- }
-
- /*
- * Read a character from the terminal,
- * performing no editing and doing no echo at all.
- * More complex in VMS that almost anyplace else,
- * which figures.
- */
- ttgetc()
- {
- int status;
- int iosb[2];
- int term[2];
-
- term[0] = 0;
- term[1] = 0;
- while (ibufi >= nibuf) {
- ibufi = 0;
- status = SYS$QIOW(EFN, iochan, IO$_READLBLK|IO$M_TIMED,
- iosb, 0, 0, ibuf, NIBUF, 0, term, 0, 0);
- if (status != SS$_NORMAL)
- continue;
- status = iosb[0] & 0xFFFF;
- if (status!=SS$_NORMAL && status!=SS$_TIMEOUT)
- continue;
- nibuf = (iosb[0]>>16) + (iosb[1]>>16);
- if (nibuf == 0) {
- status = SYS$QIOW(EFN, iochan, IO$_READLBLK,
- iosb, 0, 0, ibuf, 1, 0, term, 0, 0);
- if (status != SS$_NORMAL)
- continue;
- if ((iosb[0]&0xFFFF) != SS$_NORMAL)
- continue;
- nibuf = (iosb[0]>>16) + (iosb[1]>>16);
- }
- }
- return (ibuf[ibufi++] & 0xFF);
- }
-
- /*
- * Internal check for new terminal size.
- * Do this *before* setting terminal modes, so
- * the size changes are kept when.
- */
- ckttysize()
- {
- int status, mode[3], iosb[2], wid, len;
-
- status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE, iosb, 0, 0,
- mode, sizeof(mode), 0, 0, 0, 0);
- if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
- panic("ckttsize: can't sense terminal modes!");
-
- /* save new page length */
- len = (mode[1] >> 24) & 0xFF;
- oldmode[1] = (oldmode[1] & 0x00FFFFFF) | (len << 24);
- newmode[1] = (newmode[1] & 0x00FFFFFF) | (len << 24);
-
- /* save new page width */
- wid = (mode[0] >> 16) & 0xFF;
- oldmode[0] = (oldmode[0] & 0x0000FFFF) | (wid << 16);
- newmode[0] = (newmode[0] & 0x0000FFFF) | (wid << 16);
- }
-
- /*
- * Tell Emacs how big the terminal is now,
- * making sure the page size is in the range
- * 1..NROW.
- */
-
- setttysize()
- {
- nrow = (newmode[1]>>24) & 0xFF; /* Length. */
- if (nrow > NROW)
- nrow = NROW;
-
- ncol = (newmode[0]>>16) & 0xFFFF; /* Width. */
- if (ncol > NCOL)
- ncol = NCOL;
- }
-
- /*
- * Return the number of characters in the
- * typeahead buffer.
- */
-
- typeahead()
- {
- int status, SYS$QIOW(), iosb[2], mode[2];
-
- status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE|IO$M_TYPEAHDCNT,
- iosb, 0, 0, mode, sizeof(mode), 0, 0, 0, 0);
- if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
- exit(status);
- return (mode[0] & 0xFFFF); /* # characters in typeahead buf */
- }
-
- #ifdef DPROMPT
- /*
- * Attempt to read for one character. Return TRUE if the
- * read times out after 2 seconds, return immediately with
- * FALSE if the user enters something.
- */
- ttwait()
- {
- int status;
- int iosb[2];
- int term[2];
-
- term[0] = 0; /* no termination characters for read */
- term[1] = 0;
- while (ibufi >= nibuf) { /* anything in the buffer? */
- ibufi = 0; /* nope, read 1 char w/timeout */
- status = SYS$QIOW(EFN, iochan, IO$_READLBLK|IO$M_TIMED,
- iosb, 0, 0, ibuf, 1, 2, term, 0, 0);
- if (status != SS$_NORMAL)
- continue; /* did read succeed ? */
- status = iosb[0] & 0xFFFF; /* yes, get secondary status */
- if (status!=SS$_NORMAL && status!=SS$_TIMEOUT)
- continue; /* try again if bad */
- nibuf = (iosb[0]>>16) + (iosb[1]>>16);/* store # chars read */
- if (status == SS$_TIMEOUT)
- return (TRUE); /* the read timed out */
- }
- return (FALSE); /* read did not time out */
- }
- #endif DPROMPT
-
- /*
- * Just exit, as quickly as we can.
- */
-
- panic(s)
- char *s;
- {
- fprintf(stderr,"panic: %s\n", s);
- ttclose(); /* set the terminal back to sane state... */
- abort();
- }
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'sys/vms/sysdef.h'
- then
- echo shar: will not over-write existing file "'sys/vms/sysdef.h'"
- else
- cat << \SHAR_EOF > 'sys/vms/sysdef.h'
- /*
- * Name: MicroEMACS
- * VAX/VMS system header file.
- * Version: 29
- * Last edit: 05-Feb-86
- * By: rex::conroy
- * decvax!decwrl!dec-rhea!dec-rex!conroy
- */
- #include <ssdef.h>
-
- #define PCC 0 /* "[]" works. */
- #define KBLOCK 8192 /* Kill grow. */
- #define GOOD (SS$_NORMAL) /* 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. */
- #define BDC2 ']'
- #define BDC3 ';'
-
- #define DPROMPT /* use delayed prompts */
- SHAR_EOF
- fi # end of overwriting check
- # End of shell archive
- exit 0
-
-