#! /bin/sh
# This is a shell archive. Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
# If this archive is complete, you will see the message:
# "End of archive 7 (of 14)."
# Contents: exec.c spawn.c window.c
# Wrapped by rs@mirror on Fri Mar 13 13:24:22 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo shar: Extracting \"exec.c\" \(16413 characters\)
if test -f exec.c ; then
echo shar: Will not over-write existing file \"exec.c\"
else
sed "s/^X//" >exec.c <<'END_OF_exec.c'
X/* This file is for functions dealing with execution of
X commands, command lines, buffers, files and startup files
X
X written 1986 by Daniel Lawrence */
X
X#include <stdio.h>
X#include "estruct.h"
X#include "edef.h"
X
X#if MEGAMAX & ST520
Xoverlay "exec"
X#endif
X
X#if DEBUGM
Xchar outline[NSTRING]; /* global string to hold debug line text */
X#endif
X
X/* namedcmd: execute a named command even if it is not bound */
X
Xnamedcmd(f, n)
X
Xint f, n; /* command arguments [passed through to command executed] */
X
X{
X register (*kfunc)(); /* ptr to the requexted function to bind to */
X int (*getname())();
X
X /* prompt the user to type a named command */
X mlwrite(": ");
X
X /* and now get the function name to execute */
X kfunc = getname();
X if (kfunc == NULL) {
X mlwrite("[No such function]");
X return(FALSE);
X }
X
X /* and then execute the command */
X return((*kfunc)(f, n));
X}
X
X/* execcmd: Execute a command line command to be typed in
X by the user */
X
Xexeccmd(f, n)
X
Xint f, n; /* default Flag and Numeric argument */
X
X{
X register int status; /* status return */
X char cmdstr[NSTRING]; /* string holding command to execute */
X
X /* get the line wanted */
X if ((status = mlreply(": ", cmdstr, NSTRING)) != TRUE)
X return(status);
X
X execlevel = 0;
X return(docmd(cmdstr));
X}
X
X/* docmd: take a passed string as a command line and translate
X it to be executed as a command. This function will be
X used by execute-command-line and by all source and
X startup files. Lastflag/thisflag is also updated.
X
X format of the command line is:
X
X {# arg} <command-name> {<argument string(s)>}
X
X Directives start with a "!" and include:
X
X !endm End a macro
X !if (cond) conditional execution
X !else
X !endif
X !return Return (terminating current macro)
X !goto <label> Jump to a label in the current macro
X
X Line Labels begin with a "*" in column 1, like:
X
X *LBL01
X*/
X
Xdocmd(cline)
X
Xchar *cline; /* command line to execute */
X
X{
X register int f; /* default argument flag */
X register int n; /* numeric repeat value */
X register int i;
X int (*fnc)(); /* function to execute */
X int status; /* return status of function */
X int oldcle; /* old contents of clexec flag */
X int llen; /* length of cline */
X int force; /* force TRUE result? */
X char *tmp; /* tmp pointer into cline */
X struct LINE *lp; /* a line pointer */
X char *oldestr; /* original exec string */
X char token[NSTRING]; /* next token off of command line */
X int (*fncmatch())();
X#if DEBUGM
X /* if $debug == TRUE, every line to execute
X gets echoed and a key needs to be pressed to continue
X ^G will abort the command */
X register char *sp; /* pointer into buf to expand %s */
X
X if (macbug) {
X strcpy(outline, "<<<");
X#if 1 /* debug if levels */
X strcat(outline, itoa(execlevel));
X strcat(outline, ":");
X#endif
X strcat(outline, cline);
X strcat(outline, ">>>");
X
X /* change all '%' to ':' so mlwrite won't expect arguments */
X sp = outline;
X while (*sp) {
X if (*sp++ == '%')
X *(sp-1) = ':';
X }
X
X /* write out the debug line */
X mlwrite(outline);
X update(TRUE);
X
X /* and get the keystroke */
X if (tgetc() == 7) {
X mlwrite("[Macro aborted]");
X return(FALSE);
X }
X }
X#endif
X
X /* dump comments and labels here */
X if (*cline == ';' || *cline == '*')
X return(TRUE);
X
X /* eat leading spaces */
X while (*cline == ' ' || *cline == '\t')
X ++cline;
X
X /* check to see if this line turns macro storage off */
X if (cline[0] == '!' && strncmp(&cline[1], "endm", 4) == 0) {
X mstore = FALSE;
X bstore = NULL;
X return(TRUE);
X }
X
X /* if macro store is on, just salt this away */
X if (mstore) {
X /* allocate the space for the line */
X llen = strlen(cline);
X if ((lp=lalloc(llen)) == NULL) {
X mlwrite("Out of memory while storing macro");
X return (FALSE);
X }
X
X /* copy the text into the new line */
X for (i=0; i<llen; ++i)
X lputc(lp, i, cline[i]);
X
X /* attach the line to the end of the buffer */
X bstore->b_linep->l_bp->l_fp = lp;
X lp->l_bp = bstore->b_linep->l_bp;
X bstore->b_linep->l_bp = lp;
X lp->l_fp = bstore->b_linep;
X return (TRUE);
X }
X
X force = FALSE;
X oldestr = execstr; /* save last ptr to string to execute */
X execstr = cline; /* and set this one as current */
X
X /* process directives */
X if (*cline == '!') {
X /* save directive location and skip it */
X tmp = cline;
X while (*execstr && *execstr != ' ' && *execstr != '\t')
X ++execstr;
X
X if (tmp[1] == 'f' && tmp[2] == 'o') {
X force = TRUE;
X goto do001;
X
X } else if (tmp[1] == 'i' && tmp[2] == 'f') {
X
X /* IF directive */
X /* grab the value of the logical exp */
X if (execlevel == 0) {
X if ((status = macarg(token)) != TRUE) {
X execstr = oldestr;
X return(status);
X }
X status = stol(token);
X } else
X status = TRUE;
X
X if (status) {
X
X /* IF (TRUE) */
X if (execlevel != 0)
X ++execlevel;
X } else {
X
X /* IF (FALSE) */
X ++execlevel;
X }
X
X } else if (tmp[1] == 'e' && tmp[2] == 'l') {
X
X /* ELSE directive */
X if (execlevel == 1)
X --execlevel;
X else if (execlevel == 0 )
X ++execlevel;
X
X } else if (tmp[1] == 'e' && tmp[2] == 'n') {
X
X /* ENDIF directive */
X if (execlevel)
X --execlevel;
X
X } else if (tmp[1] == 'r' && tmp[2] == 'e') {
X
X /* RETURN directive */
X execstr = oldestr;
X return(RET);
X
X } else if (tmp[1] == 'g' && tmp[2] == 'o') {
X
X /* GOTO directive */
X /* .....only if we are currently executing */
X if (execlevel) {
X execstr = oldestr;
X return(TRUE);
X }
X
X while (*execstr == ' ' || *execstr == '\t')
X ++execstr;
X strncpy(golabel, execstr, NPAT - 1);
X return(GOLINE);
X
X } else {
X mlwrite("%%Unknown Directive");
X return(FALSE);
X }
X
X /* restore execstr and exit */
X execstr = oldestr;
X return(TRUE);
X }
X
Xdo001: /* if we are scanning and not executing..go back here */
X if (execlevel) {
X execstr = oldestr;
X return(TRUE);
X }
X
X /* first set up the default command values */
X f = FALSE;
X n = 1;
X lastflag = thisflag;
X thisflag = 0;
X
X if ((status = macarg(token)) != TRUE) { /* and grab the first token */
X execstr = oldestr;
X return(status);
X }
X
X /* process leadin argument */
X if (gettyp(token) != TKCMD) {
X f = TRUE;
X n = atoi(getval(token));
X
X /* and now get the command to execute */
X if ((status = macarg(token)) != TRUE) {
X execstr = oldestr;
X return(status);
X }
X }
X
X /* and match the token to see if it exists */
X if ((fnc = fncmatch(token)) == NULL) {
X mlwrite("[No such Function]");
X execstr = oldestr;
X return(FALSE);
X }
X
X /* save the arguments and go execute the command */
X oldcle = clexec; /* save old clexec flag */
X clexec = TRUE; /* in cline execution */
X status = (*fnc)(f, n); /* call the function */
X cmdstatus = status; /* save the status */
X if (force) /* force the status */
X status = TRUE;
X clexec = oldcle; /* restore clexec flag */
X execstr = oldestr;
X return(status);
X}
X
X/* token: chop a token off a string
X return a pointer past the token
X*/
X
Xchar *token(src, tok)
X
Xchar *src, *tok; /* source string, destination token string */
X
X{
X register int quotef; /* is the current string quoted? */
X
X /* first scan past any whitespace in the source string */
X while (*src == ' ' || *src == '\t')
X ++src;
X
X /* scan through the source string */
X quotef = FALSE;
X while (*src) {
X /* process special characters */
X if (*src == '~') {
X ++src;
X if (*src == 0)
X break;
X switch (*src++) {
X case 'r': *tok++ = 13; break;
X case 'n': *tok++ = 10; break;
X case 't': *tok++ = 9; break;
X case 'b': *tok++ = 8; break;
X case 'f': *tok++ = 12; break;
X default: *tok++ = *(src-1);
X }
X } else {
X /* check for the end of the token */
X if (quotef) {
X if (*src == '"')
X break;
X } else {
X if (*src == ' ' || *src == '\t')
X break;
X }
X
X /* set quote mode if qoute found */
X if (*src == '"')
X quotef = TRUE;
X
X /* record the character */
X *tok++ = *src++;
X }
X }
X
X /* terminate the token and exit */
X if (*src)
X ++src;
X *tok = 0;
X return(src);
X}
X
Xmacarg(tok) /* get a macro line argument */
X
Xchar *tok; /* buffer to place argument */
X
X{
X int savcle; /* buffer to store original clexec */
X int status;
X
X savcle = clexec; /* save execution mode */
X clexec = TRUE; /* get the argument */
X status = nextarg("", tok, NSTRING, ctoec('\n'));
X clexec = savcle; /* restore execution mode */
X return(status);
X}
X
X/* nextarg: get the next argument */
X
Xnextarg(prompt, buffer, size, terminator)
X
Xchar *prompt; /* prompt to use if we must be interactive */
Xchar *buffer; /* buffer to put token into */
Xchar *size; /* size of the buffer */
Xint terminator; /* terminating char to be used on interactive fetch */
X
X{
X /* if we are interactive, go get it! */
X if (clexec == FALSE)
X return(getstring(prompt, buffer, size, terminator));
X
X /* grab token and advance past */
X execstr = token(execstr, buffer);
X
X /* evaluate it */
X strcpy(buffer, getval(buffer));
X return(TRUE);
X}
X
X/* storemac: Set up a macro buffer and flag to store all
X executed command lines there */
X
Xstoremac(f, n)
X
Xint f; /* default flag */
Xint n; /* macro number to use */
X
X{
X register struct BUFFER *bp; /* pointer to macro buffer */
X char bname[NBUFN]; /* name of buffer to use */
X
X /* must have a numeric argument to this function */
X if (f == FALSE) {
X mlwrite("No macro specified");
X return(FALSE);
X }
X
X /* range check the macro number */
X if (n < 1 || n > 40) {
X mlwrite("Macro number out of range");
X return(FALSE);
X }
X
X /* construct the macro buffer name */
X strcpy(bname, "[Macro xx]");
X bname[7] = '0' + (n / 10);
X bname[8] = '0' + (n % 10);
X
X /* set up the new macro buffer */
X if ((bp = bfind(bname, TRUE, BFINVS)) == NULL) {
X mlwrite("Can not create macro");
X return(FALSE);
X }
X
X /* and make sure it is empty */
X bclear(bp);
X
X /* and set the macro store pointers to it */
X mstore = TRUE;
X bstore = bp;
X return(TRUE);
X}
X
X/* execbuf: Execute the contents of a buffer of commands */
X
Xexecbuf(f, n)
X
Xint f, n; /* default flag and numeric arg */
X
X{
X register BUFFER *bp; /* ptr to buffer to execute */
X register int status; /* status return */
X char bufn[NBUFN]; /* name of buffer to execute */
X
X /* find out what buffer the user wants to execute */
X if ((status = mlreply("Execute buffer: ", bufn, NBUFN)) != TRUE)
X return(status);
X
X /* find the pointer to that buffer */
X if ((bp=bfind(bufn, FALSE, 0)) == NULL) {
X mlwrite("No such buffer");
X return(FALSE);
X }
X
X /* and now execute it as asked */
X while (n-- > 0)
X if ((status = dobuf(bp)) != TRUE)
X return(status);
X return(TRUE);
X}
X
X/* dobuf: execute the contents of the buffer pointed to
X by the passed BP */
X
Xdobuf(bp)
X
XBUFFER *bp; /* buffer to execute */
X
X{
X register int status; /* status return */
X register LINE *lp; /* pointer to line to execute */
X register LINE *hlp; /* pointer to line header */
X register LINE *glp; /* line to goto */
X register int linlen; /* length of line to execute */
X register WINDOW *wp; /* ptr to windows to scan */
X char *eline; /* text of line to execute */
X
X /* clear IF level flags */
X execlevel = 0;
X
X /* starting at the beginning of the buffer */
X hlp = bp->b_linep;
X lp = hlp->l_fp;
X while (lp != hlp) {
X /* allocate eline and copy macro line to it */
X linlen = lp->l_used;
X if ((eline = malloc(linlen+1)) == NULL) {
X mlwrite("%%Out of Memory during macro execution");
X return(FALSE);
X }
X strncpy(eline, lp->l_text, linlen);
X eline[linlen] = 0; /* make sure it ends */
X
X /* trim leading whitespace */
X while (eline[0] == ' ' || eline[0] == '\t')
X strcpy(eline, &eline[1]);
X
X /* if it is not a comment, execute it */
X if (eline[0] != 0 && eline[0] != ';') {
X status = docmd(eline);
X
X /* if it is a !GOTO directive, deal with it */
X if (status == GOLINE) {
X linlen = strlen(golabel);
X glp = hlp->l_fp;
X while (glp != hlp) {
X if (*glp->l_text == '*' &&
X (strncmp(&glp->l_text[1], golabel,
X linlen) == 0)) {
X lp = glp;
X status = TRUE;
X }
X glp = glp->l_fp;
X }
X }
X
X if (status == GOLINE) {
X mlwrite("%%No such label");
X return(FALSE);
X }
X
X /* if it is a !RETURN directive...do so */
X if (status == RET) {
X free(eline);
X break;
X }
X
X /* check for a command error */
X if (status != TRUE) {
X /* look if buffer is showing */
X wp = wheadp;
X while (wp != NULL) {
X if (wp->w_bufp == bp) {
X /* and point it */
X wp->w_dotp = lp;
X wp->w_doto = 0;
X wp->w_flag |= WFHARD;
X }
X wp = wp->w_wndp;
X }
X /* in any case set the buffer . */
X bp->b_dotp = lp;
X bp->b_doto = 0;
X free(eline);
X execlevel = 0;
X return(status);
X }
X }
X
X /* on to the next line */
X free(eline);
X lp = lp->l_fp;
X }
X
X /* exit the current function */
X execlevel = 0;
X return(TRUE);
X}
X
Xexecfile(f, n) /* execute a series of commands in a file
X*/
X
Xint f, n; /* default flag and numeric arg to pass on to file */
X
X{
X register int status; /* return status of name query */
X char *fname[NSTRING]; /* name of file to execute */
X
X if ((status = mlreply("File to execute: ", fname, NSTRING -1)) != TRUE)
X return(status);
X
X /* otherwise, execute it */
X while (n-- > 0)
X if ((status=dofile(fname)) != TRUE)
X return(status);
X
X return(TRUE);
X}
X
X/* dofile: yank a file into a buffer and execute it
X if there are no errors, delete the buffer on exit */
X
Xdofile(fname)
X
Xchar *fname; /* file name to execute */
X
X{
X register BUFFER *bp; /* buffer to place file to exeute */
X register BUFFER *cb; /* temp to hold current buf while we read */
X register int status; /* results of various calls */
X char bname[NBUFN]; /* name of buffer */
X
X makename(bname, fname); /* derive the name of the buffer */
X if ((bp = bfind(bname, TRUE, 0)) == NULL) /* get the needed buffer */
X return(FALSE);
X
X bp->b_mode = MDVIEW; /* mark the buffer as read only */
X cb = curbp; /* save the old buffer */
X curbp = bp; /* make this one current */
X /* and try to read in the file to execute */
X if ((status = readin(fname, FALSE)) != TRUE) {
X curbp = cb; /* restore the current buffer */
X return(status);
X }
X
X /* go execute it! */
X curbp = cb; /* restore the current buffer */
X if ((status = dobuf(bp)) != TRUE)
X return(status);
X
X /* if not displayed, remove the now unneeded buffer and exit */
X if (bp->b_nwnd == 0)
X zotbuf(bp);
X return(TRUE);
X}
X
X/* cbuf: Execute the contents of a numbered buffer */
X
Xcbuf(f, n, bufnum)
X
Xint f, n; /* default flag and numeric arg */
Xint bufnum; /* number of buffer to execute */
X
X{
X register BUFFER *bp; /* ptr to buffer to execute */
X register int status; /* status return */
X static char bufname[] = "[Macro xx]";
X
X /* make the buffer name */
X bufname[7] = '0' + (bufnum / 10);
X bufname[8] = '0' + (bufnum % 10);
X
X /* find the pointer to that buffer */
X if ((bp=bfind(bufname, FALSE, 0)) == NULL) {
X mlwrite("Macro not defined");
X return(FALSE);
X }
X
X /* and now execute it as asked */
X while (n-- > 0)
X if ((status = dobuf(bp)) != TRUE)
X return(status);
X return(TRUE);
X}
X
Xcbuf1(f, n)
X
X{
X cbuf(f, n, 1);
X}
X
Xcbuf2(f, n)
X
X{
X cbuf(f, n, 2);
X}
X
Xcbuf3(f, n)
X
X{
X cbuf(f, n, 3);
X}
X
Xcbuf4(f, n)
X
X{
X cbuf(f, n, 4);
X}
X
Xcbuf5(f, n)
X
X{
X cbuf(f, n, 5);
X}
X
Xcbuf6(f, n)
X
X{
X cbuf(f, n, 6);
X}
X
Xcbuf7(f, n)
X
X{
X cbuf(f, n, 7);
X}
X
Xcbuf8(f, n)
X
X{
X cbuf(f, n, 8);
X}
X
Xcbuf9(f, n)
X
X{
X cbuf(f, n, 9);
X}
X
Xcbuf10(f, n)
X
X{
X cbuf(f, n, 10);
X}
X
Xcbuf11(f, n)
X
X{
X cbuf(f, n, 11);
X}
X
Xcbuf12(f, n)
X
X{
X cbuf(f, n, 12);
X}
X
Xcbuf13(f, n)
X
X{
X cbuf(f, n, 13);
X}
X
Xcbuf14(f, n)
X
X{
X cbuf(f, n, 14);
X}
X
Xcbuf15(f, n)
X
X{
X cbuf(f, n, 15);
X}
X
Xcbuf16(f, n)
X
X{
X cbuf(f, n, 16);
X}
X
Xcbuf17(f, n)
X
X{
X cbuf(f, n, 17);
X}
X
Xcbuf18(f, n)
X
X{
X cbuf(f, n, 18);
X}
X
Xcbuf19(f, n)
X
X{
X cbuf(f, n, 19);
X}
X
Xcbuf20(f, n)
X
X{
X cbuf(f, n, 20);
X}
X
Xcbuf21(f, n)
X
X{
X cbuf(f, n, 21);
X}
X
Xcbuf22(f, n)
X
X{
X cbuf(f, n, 22);
X}
X
Xcbuf23(f, n)
X
X{
X cbuf(f, n, 23);
X}
X
Xcbuf24(f, n)
X
X{
X cbuf(f, n, 24);
X}
X
Xcbuf25(f, n)
X
X{
X cbuf(f, n, 25);
X}
X
Xcbuf26(f, n)
X
X{
X cbuf(f, n, 26);
X}
X
Xcbuf27(f, n)
X
X{
X cbuf(f, n, 27);
X}
X
Xcbuf28(f, n)
X
X{
X cbuf(f, n, 28);
X}
X
Xcbuf29(f, n)
X
X{
X cbuf(f, n, 29);
X}
X
Xcbuf30(f, n)
X
X{
X cbuf(f, n, 30);
X}
X
Xcbuf31(f, n)
X
X{
X cbuf(f, n, 31);
X}
X
Xcbuf32(f, n)
X
X{
X cbuf(f, n, 32);
X}
X
Xcbuf33(f, n)
X
X{
X cbuf(f, n, 33);
X}
X
Xcbuf34(f, n)
X
X{
X cbuf(f, n, 34);
X}
X
Xcbuf35(f, n)
X
X{
X cbuf(f, n, 35);
X}
X
Xcbuf36(f, n)
X
X{
X cbuf(f, n, 36);
X}
X
Xcbuf37(f, n)
X
X{
X cbuf(f, n, 37);
X}
X
Xcbuf38(f, n)
X
X{
X cbuf(f, n, 38);
X}
X
Xcbuf39(f, n)
X
X{
X cbuf(f, n, 39);
X}
X
Xcbuf40(f, n)
X
X{
X cbuf(f, n, 40);
X}
X
X
END_OF_exec.c
if test 16413 -ne `wc -c <exec.c`; then
echo shar: \"exec.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: Extracting \"spawn.c\" \(16459 characters\)
if test -f spawn.c ; then
echo shar: Will not over-write existing file \"spawn.c\"
else
sed "s/^X//" >spawn.c <<'END_OF_spawn.c'
X/* Spawn: various DOS access commands
X for MicroEMACS
X*/
X
X#include <stdio.h>
X#include "estruct.h"
X#include "edef.h"
X
X#if AMIGA
X#define NEW 1006
X#endif
X
X#if ST520
X#include <osbind.h>
X#include <string.h>
X#define LOAD_EXEC 0 /* load and execute the program */
Xchar *STcmd, /* the command filename & path */
X *STargs, /* command args (if any) */
X *STenv, /* environment */
X *STwork; /* work area */
X#endif
X
X#if VMS
X#define EFN 0 /* Event flag. */
X
X#include <ssdef.h> /* Random headers. */
X#include <stsdef.h>
X#include <descrip.h>
X#include <iodef.h>
X
Xextern int oldmode[3]; /* In "termio.c" */
Xextern int newmode[3]; /* In "termio.c" */
Xextern short iochan; /* In "termio.c" */
X#endif
X
X#if V7 | USG | BSD
X#include <signal.h>
Xextern int vttidy();
X#endif
X
X#if MSDOS & MSC
X#include <process.h>
X#define system(a) spawnlp(P_WAIT, a, NULL)
X#endif
X
X/*
X * Create a subjob with a copy of the command intrepreter in it. When the
X * command interpreter exits, mark the screen as garbage so that you do a full
X * repaint. Bound to "^X C". The message at the start in VMS puts out a newline.
X * Under some (unknown) condition, you don't get one free when DCL starts up.
X */
Xspawncli(f, n)
X{
X#if AMIGA
X long newcli;
X#endif
X
X#if V7 | USG | BSD
X register char *cp;
X char *getenv();
X#endif
X
X /* don't allow this command if restricted */
X if (restflag)
X return(resterr());
X
X#if AMIGA
X newcli = Open("CON:1/1/639/199/MicroEmacs Subprocess", NEW);
X mlwrite("[Starting new CLI]");
X sgarbf = TRUE;
X Execute("", newcli, 0);
X Close(newcli);
X return(TRUE);
X#endif
X
X#if VMS
X movecursor(term.t_nrow, 0); /* In last line. */
X mlputs("[Starting DCL]\r\n");
X TTflush(); /* Ignore "ttcol". */
X sgarbf = TRUE;
X return (sys(NULL)); /* NULL => DCL. */
X#endif
X#if CPM
X mlwrite("Not in CP/M-86");
X#endif
X#if ST520
X mlwrite("Not in TOS");
X#endif
X#if MSDOS & AZTEC
X movecursor(term.t_nrow, 0); /* Seek to last line. */
X TTflush();
X TTkclose();
X system("command.com");
X TTkopen();
X sgarbf = TRUE;
X return(TRUE);
X#endif
X#if MSDOS & LATTICE
X movecursor(term.t_nrow, 0); /* Seek to last line. */
X TTflush();
X TTkclose();
X sys("\\command.com", ""); /* Run CLI. */
X TTkopen();
X sgarbf = TRUE;
X return(TRUE);
X#endif
X#if V7 | USG | BSD
X movecursor(term.t_nrow, 0); /* Seek to last line. */
X TTflush();
X TTclose(); /* stty to old settings */
X if ((cp = getenv("SHELL")) != NULL && *cp != '\0')
X system(cp);
X else
X#if BSD
X system("exec /bin/csh");
X#else
X system("exec /bin/sh");
X#endif
X sgarbf = TRUE;
X sleep(2);
X TTopen();
X return(TRUE);
X#endif
X}
X
X#if BSD
X
Xbktoshell() /* suspend MicroEMACS and wait to wake up */
X{
X int pid;
X
X vttidy();
X pid = getpid();
X kill(pid,SIGTSTP);
X}
X
Xrtfrmshell()
X{
X TTopen();
X curwp->w_flag = WFHARD;
X sgarbf = TRUE;
X}
X#endif
X
X/*
X * Run a one-liner in a subjob. When the command returns, wait for a single
X * character to be typed, then mark the screen as garbage so a full repaint is
X * done. Bound to "C-X !".
X */
Xspawn(f, n)
X{
X register int s;
X char line[NLINE];
X
X#if ST520
X int i,j,k;
X char *sptr,*tptr;
X#endif
X
X#if AMIGA
X long newcli;
X#endif
X
X /* don't allow this command if restricted */
X if (restflag)
X return(resterr());
X
X#if AMIGA
X if ((s=mlreply("!", line, NLINE)) != TRUE)
X return (s);
X newcli = Open("CON:1/1/639/199/MicroEmacs Subprocess", NEW);
X Execute(line,0,newcli);
X Close(newcli);
X tgetc(); /* Pause. */
X sgarbf = TRUE;
X return(TRUE);
X#endif
X#if ST520
X if ((s=mlreply("!", line, NLINE)) != TRUE)
X return(s);
X movecursor(term.t_nrow - 1, 0);
X TTclose();
X/*
X * break the line into the command and its args
X * be cute about it, if there is no '.' in the filename, try
X * to find .prg, .tos or .ttp in that order
X * in any case check to see that the file exists before we run
X * amok
X */
X STenv = NULL;
X if((tptr = index(&line[0],' ')) == NULL) { /* no args */
X STcmd = (char *)malloc(strlen(line) + 1);
X strcpy(STcmd,line);
X STargs = NULL;
X }
X else { /* seperate out the args from the command */
X /* resist the temptation to do ptr arithmetic */
X STcmd = (char *)malloc(strlen(line) + 1);
X for(i = 0,sptr = &line[0]; sptr != tptr; sptr++,i++)
X STcmd[i] = *sptr;
X STcmd[i] = '\0';
X for(; *tptr == ' ' || *tptr == '\t'; tptr++);
X if(*tptr == '\0')
X STargs = NULL;
X else {
X STargs = (char *)malloc(strlen(tptr) + 2);
X/* first byte of STargs is the length of the string */
X STargs[0] = strlen(tptr);
X STargs[1] = NULL; /* fake it for strcat */
X strcat(STargs,tptr);
X }
X }
X/*
X * before we issue the command look for the '.', if it's not there
X * try adding .prg, .tos and .ttp to see if they exist, if not
X * issue the command as is
X */
X if((tptr = index(STcmd,'.')) == NULL) {
X STwork = (char *)malloc(strlen(STcmd) + 4);
X strcpy(STwork,STcmd);
X strcat(STwork,".prg");
X tptr = index(STwork,'.');
X if(Fsfirst(1,STwork) != 0) { /* try .tos */
X strcpy(tptr,".tos");
X if(Fsfirst(1,STwork) != 0) { /* try .ttp */
X strcpy(tptr,".ttp");
X if(Fsfirst(1,STwork) != 0) /* never mind */
X *STwork = NULL;
X }
X }
X }
X if(*STwork != NULL)
X Pexec(LOAD_EXEC,STwork,STargs,STenv);
X else
X Pexec(LOAD_EXEC,STcmd,STargs,STenv);
X TTopen();
X mlputs("\r\n\n[End]"); /* Pause. */
X TTgetc(); /* Pause. */
X sgarbf = TRUE;
X return (TRUE);
X#endif
X#if VMS
X if ((s=mlreply("!", line, NLINE)) != TRUE)
X return (s);
X TTputc('\n'); /* Already have '\r' */
X TTflush();
X s = sys(line); /* Run the command. */
X mlputs("\r\n\n[End]"); /* Pause. */
X TTflush();
X tgetc();
X sgarbf = TRUE;
X return (s);
X#endif
X#if CPM
X mlwrite("Not in CP/M-86");
X return (FALSE);
X#endif
X#if MSDOS
X if ((s=mlreply("!", line, NLINE)) != TRUE)
X return(s);
X movecursor(term.t_nrow - 1, 0);
X TTkclose();
X system(line);
X TTkopen();
X /* if we are interactive, pause here */
X if (clexec == FALSE) {
X mlputs("\r\n\n[End]");
X tgetc();
X }
X sgarbf = TRUE;
X return (TRUE);
X#endif
X#if V7 | USG | BSD
X if ((s=mlreply("!", line, NLINE)) != TRUE)
X return (s);
X TTputc('\n'); /* Already have '\r' */
X TTflush();
X TTclose(); /* stty to old modes */
X system(line);
X TTopen();
X mlputs("[End]"); /* Pause. */
X TTflush();
X while ((s = tgetc()) != '\r' && s != ' ')
X ;
X sgarbf = TRUE;
X return (TRUE);
X#endif
X}
X
X/*
X * Pipe a one line command into a window
X * Bound to ^X @
X */
Xpipe(f, n)
X{
X register int s; /* return status from CLI */
X register WINDOW *wp; /* pointer to new window */
X register BUFFER *bp; /* pointer to buffer to zot */
X char line[NLINE]; /* command line send to shell */
X static char bname[] = "command";
X
X#if AMIGA
X static char filnam[] = "ram:command";
X long newcli;
X#else
X static char filnam[] = "command";
X#endif
X
X#if MSDOS
X char *tmp;
X char *getenv();
X FILE *fp;
X FILE *fopen();
X#endif
X
X /* don't allow this command if restricted */
X if (restflag)
X return(resterr());
X
X#if MSDOS
X if ((tmp = getenv("TMP")) == NULL)
X strcpy(filnam, "command");
X else
X strcpy(filnam, tmp);
X#endif
X
X#if VMS
X mlwrite("Not availible under VMS");
X return(FALSE);
X#endif
X#if CPM
X mlwrite("Not availible under CP/M-86");
X return(FALSE);
X#endif
X
X /* get the command to pipe in */
X if ((s=mlreply("@", line, NLINE)) != TRUE)
X return(s);
X
X /* get rid of the command output buffer if it exists */
X if ((bp=bfind(bname, FALSE, 0)) != FALSE) {
X /* try to make sure we are off screen */
X wp = wheadp;
X while (wp != NULL) {
X if (wp->w_bufp == bp) {
X onlywind(FALSE, 1);
X break;
X }
X wp = wp->w_wndp;
X }
X if (zotbuf(bp) != TRUE)
X return(FALSE);
X }
X
X#if AMIGA
X newcli = Open("CON:1/1/639/199/MicroEmacs Subprocess", NEW);
X strcat(line, " >");
X strcat(line, filnam);
X Execute(line,0,newcli);
X s = TRUE;
X Close(newcli);
X sgarbf = TRUE;
X#endif
X#if MSDOS
X strcat(line," >>");
X strcat(line,filnam);
X movecursor(term.t_nrow - 1, 0);
X TTkclose();
X system(line);
X TTkopen();
X sgarbf = TRUE;
X if ((fp = fopen(filnam, "r")) == NULL) {
X s = FALSE;
X } else {
X fclose(fp);
X s = TRUE;
X }
X#endif
X#if V7 | USG | BSD
X TTputc('\n'); /* Already have '\r' */
X TTflush();
X TTclose(); /* stty to old modes */
X strcat(line,">");
X strcat(line,filnam);
X system(line);
X TTopen();
X TTflush();
X sgarbf = TRUE;
X s = TRUE;
X#endif
X
X if (s != TRUE)
X return(s);
X
X /* split the current window to make room for the command output */
X if (splitwind(FALSE, 1) == FALSE)
X return(FALSE);
X
X /* and read the stuff in */
X if (getfile(filnam, FALSE) == FALSE)
X return(FALSE);
X
X /* make this window in VIEW mode, update all mode lines */
X curwp->w_bufp->b_mode |= MDVIEW;
X wp = wheadp;
X while (wp != NULL) {
X wp->w_flag |= WFMODE;
X wp = wp->w_wndp;
X }
X
X /* and get rid of the temporary file */
X unlink(filnam);
X return(TRUE);
X}
X
X/*
X * filter a buffer through an external DOS program
X * Bound to ^X #
X */
Xfilter(f, n)
X
X{
X register int s; /* return status from CLI */
X register BUFFER *bp; /* pointer to buffer to zot */
X char line[NLINE]; /* command line send to shell */
X char tmpnam[NFILEN]; /* place to store real file name */
X static char bname1[] = "fltinp";
X
X#if AMIGA
X static char filnam1[] = "ram:fltinp";
X static char filnam2[] = "ram:fltout";
X long newcli;
X#else
X static char filnam1[] = "fltinp";
X static char filnam2[] = "fltout";
X#endif
X
X /* don't allow this command if restricted */
X if (restflag)
X return(resterr());
X
X if (curbp->b_mode&MDVIEW) /* don't allow this command if */
X return(rdonly()); /* we are in read only mode */
X
X#if VMS
X mlwrite("Not availible under VMS");
X return(FALSE);
X#endif
X#if CPM
X mlwrite("Not availible under CP/M-86");
X return(FALSE);
X#endif
X
X /* get the filter name and its args */
X if ((s=mlreply("#", line, NLINE)) != TRUE)
X return(s);
X
X /* setup the proper file names */
X bp = curbp;
X strcpy(tmpnam, bp->b_fname); /* save the original name */
X strcpy(bp->b_fname, bname1); /* set it to our new one */
X
X /* write it out, checking for errors */
X if (writeout(filnam1) != TRUE) {
X mlwrite("[Cannot write filter file]");
X strcpy(bp->b_fname, tmpnam);
X return(FALSE);
X }
X
X#if AMIGA
X newcli = Open("CON:1/1/639/199/MicroEmacs Subprocess", NEW);
X strcat(line, " <ram:fltinp >ram:fltout");
X Execute(line,0,newcli);
X s = TRUE;
X Close(newcli);
X sgarbf = TRUE;
X#endif
X#if MSDOS
X strcat(line," <fltinp >fltout");
X movecursor(term.t_nrow - 1, 0);
X TTkclose();
X system(line);
X TTkopen();
X sgarbf = TRUE;
X s = TRUE;
X#endif
X#if V7 | USG | BSD
X TTputc('\n'); /* Already have '\r' */
X TTflush();
X TTclose(); /* stty to old modes */
X strcat(line," <fltinp >fltout");
X system(line);
X TTopen();
X TTflush();
X sgarbf = TRUE;
X s = TRUE;
X#endif
X
X /* on failure, escape gracefully */
X if (s != TRUE || (readin(filnam2,FALSE) == FALSE)) {
X mlwrite("[Execution failed]");
X strcpy(bp->b_fname, tmpnam);
X unlink(filnam1);
X unlink(filnam2);
X return(s);
X }
X
X /* reset file name */
X strcpy(bp->b_fname, tmpnam); /* restore name */
X bp->b_flag |= BFCHG; /* flag it as changed */
X
X /* and get rid of the temporary file */
X unlink(filnam1);
X unlink(filnam2);
X return(TRUE);
X}
X
X#if VMS
X/*
X * Run a command. The "cmd" is a pointer to a command string, or NULL if you
X * want to run a copy of DCL in the subjob (this is how the standard routine
X * LIB$SPAWN works. You have to do wierd stuff with the terminal on the way in
X * and the way out, because DCL does not want the channel to be in raw mode.
X */
Xsys(cmd)
Xregister char *cmd;
X{
X struct dsc$descriptor cdsc;
X struct dsc$descriptor *cdscp;
X long status;
X long substatus;
X long iosb[2];
X
X status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
X oldmode, sizeof(oldmode), 0, 0, 0, 0);
X if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
X return (FALSE);
X cdscp = NULL; /* Assume DCL. */
X if (cmd != NULL) { /* Build descriptor. */
X cdsc.dsc$a_pointer = cmd;
X cdsc.dsc$w_length = strlen(cmd);
X cdsc.dsc$b_dtype = DSC$K_DTYPE_T;
X cdsc.dsc$b_class = DSC$K_CLASS_S;
X cdscp = &cdsc;
X }
X status = LIB$SPAWN(cdscp, 0, 0, 0, 0, 0, &substatus, 0, 0, 0);
X if (status != SS$_NORMAL)
X substatus = status;
X status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
X newmode, sizeof(newmode), 0, 0, 0, 0);
X if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
X return (FALSE);
X if ((substatus&STS$M_SUCCESS) == 0) /* Command failed. */
X return (FALSE);
X return (TRUE);
X}
X#endif
X
X#if ~AZTEC & MSDOS
X
X/*
X * This routine, once again by Bob McNamara, is a C translation of the "system"
X * routine in the MWC-86 run time library. It differs from the "system" routine
X * in that it does not unconditionally append the string ".exe" to the end of
X * the command name. We needed to do this because we want to be able to spawn
X * off "command.com". We really do not understand what it does, but if you don't
X * do it exactly "malloc" starts doing very very strange things.
X */
Xsys(cmd, tail)
Xchar *cmd;
Xchar *tail;
X{
X#if MWC_86
X register unsigned n;
X extern char *__end;
X
X n = __end + 15;
X n >>= 4;
X n = ((n + dsreg() + 16) & 0xFFF0) + 16;
X return(execall(cmd, tail, n));
X#endif
X
X#if LATTICE
X return(forklp(cmd, tail, (char *)NULL));
X#endif
X
X#if MSC
X return(spawnlp(P_WAIT, cmd, tail, NULL));
X#endif
X}
X#endif
X
X#if MSDOS & LATTICE
X/* System: a modified version of lattice's system() function
X that detects the proper switchar and uses it
X written by Dana Hogget */
X
Xsystem(cmd)
X
Xchar *cmd; /* Incoming command line to execute */
X
X{
X char *getenv();
X static char *swchar = "/C"; /* Execution switch */
X union REGS inregs; /* parameters for dos call */
X union REGS outregs; /* Return results from dos call */
X char *shell; /* Name of system command processor */
X char *p; /* Temporary pointer */
X int ferr; /* Error condition if any */
X
X /* get name of system shell */
X if ((shell = getenv("COMSPEC")) == NULL) {
X return (-1); /* No shell located */
X }
X
X p = cmd;
X while (isspace(*p)) { /* find out if null command */
X p++;
X }
X
X /** If the command line is not empty, bring up the shell **/
X /** and execute the command. Otherwise, bring up the **/
X /** shell in interactive mode. **/
X
X if (p && *p) {
X /** detect current switch character and us it **/
X inregs.h.ah = 0x37; /* get setting data */
X inregs.h.al = 0x00; /* get switch character */
X intdos(&inregs, &outregs);
X *swchar = outregs.h.dl;
X ferr = forkl(shell, "command", swchar, cmd, (char *)NULL);
X } else {
X ferr = forkl(shell, "command", (char *)NULL);
X }
X
X return (ferr ? ferr : wait());
X}
X#endif
X
END_OF_spawn.c
if test 16459 -ne `wc -c <spawn.c`; then
echo shar: \"spawn.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: Extracting \"window.c\" \(18023 characters\)
if test -f window.c ; then
echo shar: Will not over-write existing file \"window.c\"
else
sed "s/^X//" >window.c <<'END_OF_window.c'
X/*
X * Window management. Some of the functions are internal, and some are
X * attached to keys that the user actually types.
X */
X
X#include <stdio.h>
X#include "estruct.h"
X#include "edef.h"
X
X#if MEGAMAX & ST520
Xoverlay "window"
X#endif
X
X/*
X * Reposition dot in the current window to line "n". If the argument is
X * positive, it is that line. If it is negative it is that line from the
X * bottom. If it is 0 the window is centered (this is what the standard
X * redisplay code does). With no argument it defaults to 0. Bound to M-!.
X */
Xreposition(f, n)
X {
X if (f == FALSE) /* default to 0 to center screen */
X n = 0;
X curwp->w_force = n;
X curwp->w_flag |= WFFORCE;
X return (TRUE);
X }
X
X/*
X * Refresh the screen. With no argument, it just does the refresh. With an
X * argument it recenters "." in the current window. Bound to "C-L".
X */
Xrefresh(f, n)
X {
X if (f == FALSE)
X sgarbf = TRUE;
X else
X {
X curwp->w_force = 0; /* Center dot. */
X curwp->w_flag |= WFFORCE;
X }
X
X return (TRUE);
X }
X
X/*
X * The command make the next window (next => down the screen) the current
X * window. There are no real errors, although the command does nothing if
X * there is only 1 window on the screen. Bound to "C-X C-N".
X *
X * with an argument this command finds the <n>th window from the top
X *
X */
Xnextwind(f, n)
X
Xint f, n; /* default flag and numeric argument */
X
X{
X register WINDOW *wp;
X register int nwindows; /* total number of windows */
X
X if (f) {
X
X /* first count the # of windows */
X wp = wheadp;
X nwindows = 1;
X while (wp->w_wndp != NULL) {
X nwindows++;
X wp = wp->w_wndp;
X }
X
X /* if the argument is negative, it is the nth window
X from the bottom of the screen */
X if (n < 0)
X n = nwindows + n + 1;
X
X /* if an argument, give them that window from the top */
X if (n > 0 && n <= nwindows) {
X wp = wheadp;
X while (--n)
X wp = wp->w_wndp;
X } else {
X mlwrite("Window number out of range");
X return(FALSE);
X }
X } else
X if ((wp = curwp->w_wndp) == NULL)
X wp = wheadp;
X curwp = wp;
X curbp = wp->w_bufp;
X upmode();
X return (TRUE);
X}
X
X/*
X * This command makes the previous window (previous => up the screen) the
X * current window. There arn't any errors, although the command does not do a
X * lot if there is 1 window.
X */
Xprevwind(f, n)
X{
X register WINDOW *wp1;
X register WINDOW *wp2;
X
X /* if we have an argument, we mean the nth window from the bottom */
X if (f)
X return(nextwind(f, -n));
X
X wp1 = wheadp;
X wp2 = curwp;
X
X if (wp1 == wp2)
X wp2 = NULL;
X
X while (wp1->w_wndp != wp2)
X wp1 = wp1->w_wndp;
X
X curwp = wp1;
X curbp = wp1->w_bufp;
X upmode();
X return (TRUE);
X}
X
X/*
X * This command moves the current window down by "arg" lines. Recompute the
X * top line in the window. The move up and move down code is almost completely
X * the same; most of the work has to do with reframing the window, and picking
X * a new dot. We share the code by having "move down" just be an interface to
X * "move up". Magic. Bound to "C-X C-N".
X */
Xmvdnwind(f, n)
X
Xint n;
X
X{
X return (mvupwind(f, -n));
X}
X
X/*
X * Move the current window up by "arg" lines. Recompute the new top line of
X * the window. Look to see if "." is still on the screen. If it is, you win.
X * If it isn't, then move "." to center it in the new framing of the window
X * (this command does not really move "."; it moves the frame). Bound to
X * "C-X C-P".
X */
Xmvupwind(f, n)
X int n;
X {
X register LINE *lp;
X register int i;
X
X lp = curwp->w_linep;
X
X if (n < 0)
X {
X while (n++ && lp!=curbp->b_linep)
X lp = lforw(lp);
X }
X else
X {
X while (n-- && lback(lp)!=curbp->b_linep)
X lp = lback(lp);
X }
X
X curwp->w_linep = lp;
X curwp->w_flag |= WFHARD; /* Mode line is OK. */
X
X for (i = 0; i < curwp->w_ntrows; ++i)
X {
X if (lp == curwp->w_dotp)
X return (TRUE);
X if (lp == curbp->b_linep)
X break;
X lp = lforw(lp);
X }
X
X lp = curwp->w_linep;
X i = curwp->w_ntrows/2;
X
X while (i-- && lp != curbp->b_linep)
X lp = lforw(lp);
X
X curwp->w_dotp = lp;
X curwp->w_doto = 0;
X return (TRUE);
X }
X
X/*
X * This command makes the current window the only window on the screen. Bound
X * to "C-X 1". Try to set the framing so that "." does not have to move on the
X * display. Some care has to be taken to keep the values of dot and mark in
X * the buffer structures right if the distruction of a window makes a buffer
X * become undisplayed.
X */
Xonlywind(f, n)
X{
X register WINDOW *wp;
X register LINE *lp;
X register int i;
X
X while (wheadp != curwp) {
X wp = wheadp;
X wheadp = wp->w_wndp;
X if (--wp->w_bufp->b_nwnd == 0) {
X wp->w_bufp->b_dotp = wp->w_dotp;
X wp->w_bufp->b_doto = wp->w_doto;
X wp->w_bufp->b_markp = wp->w_markp;
X wp->w_bufp->b_marko = wp->w_marko;
X }
X free((char *) wp);
X }
X while (curwp->w_wndp != NULL) {
X wp = curwp->w_wndp;
X curwp->w_wndp = wp->w_wndp;
X if (--wp->w_bufp->b_nwnd == 0) {
X wp->w_bufp->b_dotp = wp->w_dotp;
X wp->w_bufp->b_doto = wp->w_doto;
X wp->w_bufp->b_markp = wp->w_markp;
X wp->w_bufp->b_marko = wp->w_marko;
X }
X free((char *) wp);
X }
X lp = curwp->w_linep;
X i = curwp->w_toprow;
X while (i!=0 && lback(lp)!=curbp->b_linep) {
X --i;
X lp = lback(lp);
X }
X curwp->w_toprow = 0;
X curwp->w_ntrows = term.t_nrow-1;
X curwp->w_linep = lp;
X curwp->w_flag |= WFMODE|WFHARD;
X return (TRUE);
X}
X
X/*
X * Delete the current window, placing its space in the window above,
X * or, if it is the top window, the window below. Bound to C-X 0.
X */
X
Xdelwind(f,n)
X
Xint f, n; /* arguments are ignored for this command */
X
X{
X register WINDOW *wp; /* window to recieve deleted space */
X register WINDOW *lwp; /* ptr window before curwp */
X register int target; /* target line to search for */
X
X /* if there is only one window, don't delete it */
X if (wheadp->w_wndp == NULL) {
X mlwrite("Can not delete this window");
X return(FALSE);
X }
X
X /* find window before curwp in linked list */
X wp = wheadp;
X lwp = NULL;
X while (wp != NULL) {
X if (wp == curwp)
X break;
X lwp = wp;
X wp = wp->w_wndp;
X }
X
X /* find recieving window and give up our space */
X wp = wheadp;
X if (curwp->w_toprow == 0) {
X /* find the next window down */
X target = curwp->w_ntrows + 1;
X while (wp != NULL) {
X if (wp->w_toprow == target)
X break;
X wp = wp->w_wndp;
X }
X if (wp == NULL)
X return(FALSE);
X wp->w_toprow = 0;
X wp->w_ntrows += target;
X } else {
X /* find the next window up */
X target = curwp->w_toprow - 1;
X while (wp != NULL) {
X if ((wp->w_toprow + wp->w_ntrows) == target)
X break;
X wp = wp->w_wndp;
X }
X if (wp == NULL)
X return(FALSE);
X wp->w_ntrows += 1 + curwp->w_ntrows;
X }
X
X /* get rid of the current window */
X if (--curwp->w_bufp->b_nwnd == 0) {
X curwp->w_bufp->b_dotp = curwp->w_dotp;
X curwp->w_bufp->b_doto = curwp->w_doto;
X curwp->w_bufp->b_markp = curwp->w_markp;
X curwp->w_bufp->b_marko = curwp->w_marko;
X }
X if (lwp == NULL)
X wheadp = curwp->w_wndp;
X else
X lwp->w_wndp = curwp->w_wndp;
X free((char *)curwp);
X curwp = wp;
X wp->w_flag |= WFHARD;
X curbp = wp->w_bufp;
X upmode();
X return(TRUE);
X}
X
X/*
X
XSplit the current window. A window smaller than 3 lines cannot be
Xsplit. An argument of 1 forces the cursor into the upper window, an
Xargument of two forces the cursor to the lower window. The only other
Xerror that is possible is a "malloc" failure allocating the structure
Xfor the new window. Bound to "C-X 2".
X
X */
Xsplitwind(f, n)
X
Xint f, n; /* default flag and numeric argument */
X
X{
X register WINDOW *wp;
X register LINE *lp;
X register int ntru;
X register int ntrl;
X register int ntrd;
X register WINDOW *wp1;
X register WINDOW *wp2;
X char *malloc();
X
X if (curwp->w_ntrows < 3) {
X mlwrite("Cannot split a %d line window", curwp->w_ntrows);
X return (FALSE);
X }
X if ((wp = (WINDOW *) malloc(sizeof(WINDOW))) == NULL) {
X mlwrite("Cannot allocate WINDOW block");
X return (FALSE);
X }
X ++curbp->b_nwnd; /* Displayed twice. */
X wp->w_bufp = curbp;
X wp->w_dotp = curwp->w_dotp;
X wp->w_doto = curwp->w_doto;
X wp->w_markp = curwp->w_markp;
X wp->w_marko = curwp->w_marko;
X wp->w_flag = 0;
X wp->w_force = 0;
X#if COLOR
X /* set the colors of the new window */
X wp->w_fcolor = gfcolor;
X wp->w_bcolor = gbcolor;
X#endif
X ntru = (curwp->w_ntrows-1) / 2; /* Upper size */
X ntrl = (curwp->w_ntrows-1) - ntru; /* Lower size */
X lp = curwp->w_linep;
X ntrd = 0;
X while (lp != curwp->w_dotp) {
X ++ntrd;
X lp = lforw(lp);
X }
X lp = curwp->w_linep;
X if (((f == FALSE) && (ntrd <= ntru)) || ((f == TRUE) && (n == 1))) {
X /* Old is upper window. */
X if (ntrd == ntru) /* Hit mode line. */
X lp = lforw(lp);
X curwp->w_ntrows = ntru;
X wp->w_wndp = curwp->w_wndp;
X curwp->w_wndp = wp;
X wp->w_toprow = curwp->w_toprow+ntru+1;
X wp->w_ntrows = ntrl;
X } else { /* Old is lower window */
X wp1 = NULL;
X wp2 = wheadp;
X while (wp2 != curwp) {
X wp1 = wp2;
X wp2 = wp2->w_wndp;
X }
X if (wp1 == NULL)
X wheadp = wp;
X else
X wp1->w_wndp = wp;
X wp->w_wndp = curwp;
X wp->w_toprow = curwp->w_toprow;
X wp->w_ntrows = ntru;
X ++ntru; /* Mode line. */
X curwp->w_toprow += ntru;
X curwp->w_ntrows = ntrl;
X while (ntru--)
X lp = lforw(lp);
X }
X curwp->w_linep = lp; /* Adjust the top lines */
X wp->w_linep = lp; /* if necessary. */
X curwp->w_flag |= WFMODE|WFHARD;
X wp->w_flag |= WFMODE|WFHARD;
X return (TRUE);
X}
X
X/*
X * Enlarge the current window. Find the window that loses space. Make sure it
X * is big enough. If so, hack the window descriptions, and ask redisplay to do
X * all the hard work. You don't just set "force reframe" because dot would
X * move. Bound to "C-X Z".
X */
Xenlargewind(f, n)
X{
X register WINDOW *adjwp;
X register LINE *lp;
X register int i;
X
X if (n < 0)
X return (shrinkwind(f, -n));
X if (wheadp->w_wndp == NULL) {
X mlwrite("Only one window");
X return (FALSE);
X }
X if ((adjwp=curwp->w_wndp) == NULL) {
X adjwp = wheadp;
X while (adjwp->w_wndp != curwp)
X adjwp = adjwp->w_wndp;
X }
X if (adjwp->w_ntrows <= n) {
X mlwrite("Impossible change");
X return (FALSE);
X }
X if (curwp->w_wndp == adjwp) { /* Shrink below. */
X lp = adjwp->w_linep;
X for (i=0; i<n && lp!=adjwp->w_bufp->b_linep; ++i)
X lp = lforw(lp);
X adjwp->w_linep = lp;
X adjwp->w_toprow += n;
X } else { /* Shrink above. */
X lp = curwp->w_linep;
X for (i=0; i<n && lback(lp)!=curbp->b_linep; ++i)
X lp = lback(lp);
X curwp->w_linep = lp;
X curwp->w_toprow -= n;
X }
X curwp->w_ntrows += n;
X adjwp->w_ntrows -= n;
X curwp->w_flag |= WFMODE|WFHARD;
X adjwp->w_flag |= WFMODE|WFHARD;
X return (TRUE);
X}
X
X/*
X * Shrink the current window. Find the window that gains space. Hack at the
X * window descriptions. Ask the redisplay to do all the hard work. Bound to
X * "C-X C-Z".
X */
Xshrinkwind(f, n)
X{
X register WINDOW *adjwp;
X register LINE *lp;
X register int i;
X
X if (n < 0)
X return (enlargewind(f, -n));
X if (wheadp->w_wndp == NULL) {
X mlwrite("Only one window");
X return (FALSE);
X }
X if ((adjwp=curwp->w_wndp) == NULL) {
X adjwp = wheadp;
X while (adjwp->w_wndp != curwp)
X adjwp = adjwp->w_wndp;
X }
X if (curwp->w_ntrows <= n) {
X mlwrite("Impossible change");
X return (FALSE);
X }
X if (curwp->w_wndp == adjwp) { /* Grow below. */
X lp = adjwp->w_linep;
X for (i=0; i<n && lback(lp)!=adjwp->w_bufp->b_linep; ++i)
X lp = lback(lp);
X adjwp->w_linep = lp;
X adjwp->w_toprow -= n;
X } else { /* Grow above. */
X lp = curwp->w_linep;
X for (i=0; i<n && lp!=curbp->b_linep; ++i)
X lp = lforw(lp);
X curwp->w_linep = lp;
X curwp->w_toprow += n;
X }
X curwp->w_ntrows -= n;
X adjwp->w_ntrows += n;
X curwp->w_flag |= WFMODE|WFHARD;
X adjwp->w_flag |= WFMODE|WFHARD;
X return (TRUE);
X}
X
X/* Resize the current window to the requested size */
X
Xresize(f, n)
X
Xint f, n; /* default flag and numeric argument */
X
X{
X int clines; /* current # of lines in window */
X
X /* must have a non-default argument, else ignore call */
X if (f == FALSE)
X return(TRUE);
X
X /* find out what to do */
X clines = curwp->w_ntrows;
X
X /* already the right size? */
X if (clines == n)
X return(TRUE);
X
X return(enlargewind(TRUE, n - clines));
X}
X
X/*
X * Pick a window for a pop-up. Split the screen if there is only one window.
X * Pick the uppermost window that isn't the current window. An LRU algorithm
X * might be better. Return a pointer, or NULL on error.
X */
XWINDOW *
Xwpopup()
X{
X register WINDOW *wp;
X
X if (wheadp->w_wndp == NULL /* Only 1 window */
X && splitwind(FALSE, 0) == FALSE) /* and it won't split */
X return (NULL);
X wp = wheadp; /* Find window to use */
X while (wp!=NULL && wp==curwp)
X wp = wp->w_wndp;
X return (wp);
X}
X
Xscrnextup(f, n) /* scroll the next window up (back) a page */
X
X{
X nextwind(FALSE, 1);
X backpage(f, n);
X prevwind(FALSE, 1);
X}
X
Xscrnextdw(f, n) /* scroll the next window down (forward) a page */
X
X{
X nextwind(FALSE, 1);
X forwpage(f, n);
X prevwind(FALSE, 1);
X}
X
Xsavewnd(f, n) /* save ptr to current window */
X
X{
X swindow = curwp;
X return(TRUE);
X}
X
Xrestwnd(f, n) /* restore the saved screen */
X
X{
X register WINDOW *wp;
X
X /* find the window */
X wp = wheadp;
X while (wp != NULL) {
X if (wp == swindow) {
X curwp = wp;
X curbp = wp->w_bufp;
X upmode();
X return (TRUE);
X }
X wp = wp->w_wndp;
X }
X
X mlwrite("[No such window exists]");
X return(FALSE);
X}
X
Xnewsize(f, n) /* resize the screen, re-writing the screen */
X
Xint f; /* default flag */
Xint n; /* numeric argument */
X
X{
X WINDOW *wp; /* current window being examined */
X WINDOW *nextwp; /* next window to scan */
X WINDOW *lastwp; /* last window scanned */
X int lastline; /* screen line of last line of current window */
X
X /* if the command defaults, assume the largest */
X if (f == FALSE)
X n = term.t_mrow + 1;
X
X /* make sure it's in range */
X if (n < 3 || n > term.t_mrow + 1) {
X mlwrite("%%Screen size out of range");
X return(FALSE);
X }
X
X if (term.t_nrow == n - 1)
X return(TRUE);
X else if (term.t_nrow < n - 1) {
X
X /* go to the last window */
X wp = wheadp;
X while (wp->w_wndp != NULL)
X wp = wp->w_wndp;
X
X /* and enlarge it as needed */
X wp->w_ntrows = n - wp->w_toprow - 2;
X wp->w_flag |= WFHARD|WFMODE;
X
X } else {
X
X /* rebuild the window structure */
X nextwp = wheadp;
X wp = NULL;
X lastwp = NULL;
X while (nextwp != NULL) {
X wp = nextwp;
X nextwp = wp->w_wndp;
X
X /* get rid of it if it is too low */
X if (wp->w_toprow > n - 2) {
X
X /* save the point/mark if needed */
X if (--wp->w_bufp->b_nwnd == 0) {
X wp->w_bufp->b_dotp = wp->w_dotp;
X wp->w_bufp->b_doto = wp->w_doto;
X wp->w_bufp->b_markp = wp->w_markp;
X wp->w_bufp->b_marko = wp->w_marko;
X }
X
X /* update curwp and lastwp if needed */
X if (wp == curwp)
X curwp = wheadp;
X curbp = curwp->w_bufp;
X if (lastwp != NULL)
X lastwp->w_wndp = NULL;
X
X /* free the structure */
X free((char *)wp);
X wp = NULL;
X
X } else {
X /* need to change this window size? */
X lastline = wp->w_toprow + wp->w_ntrows - 1;
X if (lastline >= n - 2) {
X wp->w_ntrows = n - wp->w_toprow - 2;
X wp->w_flag |= WFHARD|WFMODE;
X }
X }
X
X lastwp = wp;
X }
X }
X
X /* screen is garbage */
X term.t_nrow = n - 1;
X sgarbf = TRUE;
X return(TRUE);
X}
X
Xnewwidth(f, n) /* resize the screen, re-writing the screen */
X
Xint f; /* default flag */
Xint n; /* numeric argument */
X
X{
X /* if the command defaults, assume the largest */
X if (f == FALSE)
X n = term.t_mcol;
X
X /* make sure it's in range */
X if (n < 10 || n > term.t_mcol) {
X mlwrite("%%Screen width out of range");
X return(FALSE);
X }
X
X /* otherwise, just re-width it (no big deal) */
X term.t_ncol = n;
X term.t_margin = n / 10;
X term.t_scrsiz = n - (term.t_margin * 2);
X curwp->w_flag |= WFHARD | WFMOVE;
X sgarbf = TRUE;
X return(TRUE);
X}
END_OF_window.c
if test 18023 -ne `wc -c <window.c`; then
echo shar: \"window.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 7 \(of 14\).
cp /dev/null ark7isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 14 archives.
echo "See the readme file"
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0