sources-request@mirror.UUCP (03/14/87)
Submitted by: ihnp4!itivax!duncan!lawrence (Daniel Lawrence) Mod.sources: Volume 9, Issue 39 Archive-name: uemacs3.8b/Part07 #! /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