[mod.sources] v09i038: MicroEMACS 3.8b, Part06/14

sources-request@mirror.UUCP (03/14/87)

Submitted by: ihnp4!itivax!duncan!lawrence (Daniel Lawrence)
Mod.sources: Volume 9, Issue 38
Archive-name: uemacs3.8b/Part06

#! /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 6 (of 14)."
# Contents:  bind.c buffer.c word.c
# Wrapped by rs@mirror on Fri Mar 13 13:24:12 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo shar: Extracting \"bind.c\" \(14963 characters\)
if test -f bind.c ; then 
  echo shar: Will not over-write existing file \"bind.c\"
else
sed "s/^X//" >bind.c <<'END_OF_bind.c'
X/*	This file is for functions having to do with key bindings,
X	descriptions, help commands and startup file.
X
X	written 11-feb-86 by Daniel Lawrence
X								*/
X
X#include	<stdio.h>
X#include	"estruct.h"
X#include	"edef.h"
X#include	"epath.h"
X
X#if	MEGAMAX & ST520
Xoverlay	"bind"
X#endif
X
Xextern int meta(), cex(), unarg(), ctrlg(); /* dummy prefix binding functions */
X
Xdeskey(f, n)	/* describe the command for a certain key */
X
X{
X	register int c;		/* command character to describe */
X	register char *ptr;	/* string pointer to scan output strings */
X	register KEYTAB *ktp;	/* pointer into the command table */
X	register int found;	/* matched command flag */
X	register NBIND *nptr;	/* pointer into the name binding table */
X	char outseq[80];	/* output buffer for command sequence */
X
X	/* prompt the user to type us a key to describe */
X	mlwrite(": describe-key ");
X
X	/* get the command sequence to describe */
X	c = getckey(FALSE);			/* get a command sequence */
X
X	/* change it to something we can print as well */
X	cmdstr(c, &outseq[0]);
X
X	/* and dump it out */
X	ptr = &outseq[0];
X	while (*ptr)
X		TTputc(*ptr++);
X	TTputc(' ');		/* space it out */
X
X	/* find the right ->function */
X	ktp = &keytab[0];
X	found = FALSE;
X	while (ktp->k_fp != NULL) {
X		if (ktp->k_code == c) {
X			found = TRUE;
X			break;
X		}
X		++ktp;
X	}
X
X	if (!found)
X		strcpy(outseq,"Not Bound");
X	else {
X		/* match it against the name binding table */
X		nptr = &names[0];
X		strcpy(outseq,"[Bad binding]");
X		while (nptr->n_func != NULL) {
X			if (nptr->n_func == ktp->k_fp) {
X				strcpy(outseq, nptr->n_name);
X				break;
X			}
X			++nptr;
X		}
X	}
X
X	/* output the command sequence */
X	ptr = &outseq[0];
X	while (*ptr)
X		TTputc(*ptr++);
X}
X
Xcmdstr(c, seq)	/* change a key command to a string we can print out */
X
Xint c;		/* sequence to translate */
Xchar *seq;	/* destination string for sequence */
X
X{
X	char *ptr;	/* pointer into current position in sequence */
X
X	ptr = seq;
X
X	/* apply meta sequence if needed */
X	if (c & META) {
X		*ptr++ = 'M';
X		*ptr++ = '-';
X	}
X
X	/* apply ^X sequence if needed */
X	if (c & CTLX) {
X		*ptr++ = '^';
X		*ptr++ = 'X';
X	}
X
X	/* apply SPEC sequence if needed */
X	if (c & SPEC) {
X		*ptr++ = 'F';
X		*ptr++ = 'N';
X	}
X
X	/* apply control sequence if needed */
X	if (c & CTRL) {
X		*ptr++ = '^';
X	}
X
X	c = c & 255;	/* strip the prefixes */
X
X	/* and output the final sequence */
X
X	*ptr++ = c;
X	*ptr = 0;	/* terminate the string */
X}
X
Xhelp(f, n)	/* give me some help!!!!
X		   bring up a fake buffer and read the help file
X		   into it with view mode			*/
X{
X	register WINDOW *wp;	/* scaning pointer to windows */
X	register BUFFER *bp;	/* buffer pointer to help */
X	char *fname;		/* ptr to file returned by flook() */
X
X	/* first check if we are already here */
X	bp = bfind("emacs.hlp", FALSE, BFINVS);
X
X	if (bp == NULL) {
X		fname = flook(pathname[1], FALSE);
X		if (fname == NULL) {
X			mlwrite("[Help file is not online]");
X			return(FALSE);
X		}
X	}
X
X	/* split the current window to make room for the help stuff */
X	if (splitwind(FALSE, 1) == FALSE)
X			return(FALSE);
X
X	if (bp == NULL) {
X		/* and read the stuff in */
X		if (getfile(fname, FALSE) == FALSE)
X			return(FALSE);
X	} else
X		swbuffer(bp);
X
X	/* make this window in VIEW mode, update all mode lines */
X	curwp->w_bufp->b_mode |= MDVIEW;
X	curwp->w_bufp->b_flag |= BFINVS;
X	wp = wheadp;
X	while (wp != NULL) {
X		wp->w_flag |= WFMODE;
X		wp = wp->w_wndp;
X	}
X	return(TRUE);
X}
X
Xint (*fncmatch(fname))() /* match fname to a function in the names table
X			    and return any match or NULL if none		*/
X
Xchar *fname;	/* name to attempt to match */
X
X{
X	register NBIND *ffp;	/* pointer to entry in name binding table */
X
X	/* scan through the table, returning any match */
X	ffp = &names[0];
X	while (ffp->n_func != NULL) {
X		if (strcmp(fname, ffp->n_name) == 0)
X			return(ffp->n_func);
X		++ffp;
X	}
X	return(NULL);
X}
X
X/* bindtokey:	add a new key to the key binding table		*/
X
Xbindtokey(f, n)
X
Xint f, n;	/* command arguments [IGNORED] */
X
X{
X	register int c;		/* command key to bind */
X	register (*kfunc)();	/* ptr to the requexted function to bind to */
X	register char *ptr;	/* ptr to dump out input key string */
X	register KEYTAB *ktp;	/* pointer into the command table */
X	register int found;	/* matched command flag */
X	char outseq[80];	/* output buffer for keystroke sequence */
X	int (*getname())();
X
X	/* prompt the user to type in a key to bind */
X	mlwrite(": bind-to-key ");
X
X	/* get the function name to bind it to */
X	kfunc = getname();
X	if (kfunc == NULL) {
X		mlwrite("[No such function]");
X		return(FALSE);
X	}
X	TTputc(' ');		/* space it out */
X	TTflush();
X
X	/* get the command sequence to bind */
X	c = getckey((kfunc == meta) || (kfunc == cex) ||
X	            (kfunc == unarg) || (kfunc == ctrlg));
X
X	/* change it to something we can print as well */
X	cmdstr(c, &outseq[0]);
X
X	/* and dump it out */
X	ptr = &outseq[0];
X	while (*ptr)
X		TTputc(*ptr++);
X
X	/* if the function is a prefix key */
X	if (kfunc == meta || kfunc == cex ||
X	    kfunc == unarg || kfunc == ctrlg) {
X
X		/* search for an existing binding for the prefix key */
X		ktp = &keytab[0];
X		found = FALSE;
X		while (ktp->k_fp != NULL) {
X			if (ktp->k_fp == kfunc)
X				unbindchar(ktp->k_code);
X			++ktp;
X		}
X
X		/* reset the appropriate global prefix variable */
X		if (kfunc == meta)
X			metac = c;
X		if (kfunc == cex)
X			ctlxc = c;
X		if (kfunc == unarg)
X			reptc = c;
X		if (kfunc == ctrlg)
X			abortc = c;
X	}
X
X	/* search the table to see if it exists */
X	ktp = &keytab[0];
X	found = FALSE;
X	while (ktp->k_fp != NULL) {
X		if (ktp->k_code == c) {
X			found = TRUE;
X			break;
X		}
X		++ktp;
X	}
X
X	if (found) {	/* it exists, just change it then */
X		ktp->k_fp = kfunc;
X	} else {	/* otherwise we need to add it to the end */
X		/* if we run out of binding room, bitch */
X		if (ktp >= &keytab[NBINDS]) {
X			mlwrite("Binding table FULL!");
X			return(FALSE);
X		}
X
X		ktp->k_code = c;	/* add keycode */
X		ktp->k_fp = kfunc;	/* and the function pointer */
X		++ktp;			/* and make sure the next is null */
X		ktp->k_code = 0;
X		ktp->k_fp = NULL;
X	}
X	return(TRUE);
X}
X
X/* unbindkey:	delete a key from the key binding table	*/
X
Xunbindkey(f, n)
X
Xint f, n;	/* command arguments [IGNORED] */
X
X{
X	register int c;		/* command key to unbind */
X	register char *ptr;	/* ptr to dump out input key string */
X	char outseq[80];	/* output buffer for keystroke sequence */
X
X	/* prompt the user to type in a key to unbind */
X	mlwrite(": unbind-key ");
X
X	/* get the command sequence to unbind */
X	c = getckey(FALSE);		/* get a command sequence */
X
X	/* change it to something we can print as well */
X	cmdstr(c, &outseq[0]);
X
X	/* and dump it out */
X	ptr = &outseq[0];
X	while (*ptr)
X		TTputc(*ptr++);
X
X	/* if it isn't bound, bitch */
X	if (unbindchar(c) == FALSE) {
X		mlwrite("[Key not bound]");
X		return(FALSE);
X	}
X	return(TRUE);
X}
X
Xunbindchar(c)
X
Xint c;		/* command key to unbind */
X
X{
X	register KEYTAB *ktp;	/* pointer into the command table */
X	register KEYTAB *sktp;	/* saved pointer into the command table */
X	register int found;	/* matched command flag */
X
X	/* search the table to see if the key exists */
X	ktp = &keytab[0];
X	found = FALSE;
X	while (ktp->k_fp != NULL) {
X		if (ktp->k_code == c) {
X			found = TRUE;
X			break;
X		}
X		++ktp;
X	}
X
X	/* if it isn't bound, bitch */
X	if (!found)
X		return(FALSE);
X
X	/* save the pointer and scan to the end of the table */
X	sktp = ktp;
X	while (ktp->k_fp != NULL)
X		++ktp;
X	--ktp;		/* backup to the last legit entry */
X
X	/* copy the last entry to the current one */
X	sktp->k_code = ktp->k_code;
X	sktp->k_fp   = ktp->k_fp;
X
X	/* null out the last one */
X	ktp->k_code = 0;
X	ktp->k_fp = NULL;
X	return(TRUE);
X}
X
Xdesbind(f, n)	/* describe bindings
X		   bring up a fake buffer and list the key bindings
X		   into it with view mode			*/
X
X#if	APROP
X{
X	buildlist(TRUE, "");
X}
X
Xapro(f, n)	/* Apropos (List functions that match a substring) */
X
X{
X	char mstring[NSTRING];	/* string to match cmd names to */
X	int status;		/* status return */
X
X	status = mlreply("Apropos string: ", mstring, NSTRING - 1);
X	if (status != TRUE)
X		return(status);
X
X	return(buildlist(FALSE, mstring));
X}
X
Xbuildlist(type, mstring)  /* build a binding list (limited or full) */
X
Xint type;	/* true = full list,   false = partial list */
Xchar *mstring;	/* match string if a partial list */
X
X#endif
X{
X	register WINDOW *wp;	/* scnaning pointer to windows */
X	register KEYTAB *ktp;	/* pointer into the command table */
X	register NBIND *nptr;	/* pointer into the name binding table */
X	register BUFFER *bp;	/* buffer to put binding list into */
X	char *strp;		/* pointer int string to send */
X	int cpos;		/* current position to use in outseq */
X	char outseq[80];	/* output buffer for keystroke sequence */
X
X	/* split the current window to make room for the binding list */
X	if (splitwind(FALSE, 1) == FALSE)
X			return(FALSE);
X
X	/* and get a buffer for it */
X	bp = bfind("Binding list", TRUE, 0);
X	if (bp == NULL || bclear(bp) == FALSE) {
X		mlwrite("Can not display binding list");
X		return(FALSE);
X	}
X
X	/* let us know this is in progress */
X	mlwrite("[Building binding list]");
X
X	/* disconect the current buffer */
X        if (--curbp->b_nwnd == 0) {             /* Last use.            */
X                curbp->b_dotp  = curwp->w_dotp;
X                curbp->b_doto  = curwp->w_doto;
X                curbp->b_markp = curwp->w_markp;
X                curbp->b_marko = curwp->w_marko;
X        }
X
X	/* connect the current window to this buffer */
X	curbp = bp;	/* make this buffer current in current window */
X	bp->b_mode = 0;		/* no modes active in binding list */
X	bp->b_nwnd++;		/* mark us as more in use */
X	wp = curwp;
X	wp->w_bufp = bp;
X	wp->w_linep = bp->b_linep;
X	wp->w_flag = WFHARD|WFFORCE;
X	wp->w_dotp = bp->b_dotp;
X	wp->w_doto = bp->b_doto;
X	wp->w_markp = NULL;
X	wp->w_marko = 0;
X
X	/* build the contents of this window, inserting it line by line */
X	nptr = &names[0];
X	while (nptr->n_func != NULL) {
X
X		/* add in the command name */
X		strcpy(outseq, nptr->n_name);
X		cpos = strlen(outseq);
X		
X#if	APROP
X		/* if we are executing an apropos command..... */
X		if (type == FALSE &&
X		    /* and current string doesn't include the search string */
X		    strinc(outseq, mstring) == FALSE)
X			goto fail;
X#endif
X		/* search down any keys bound to this */
X		ktp = &keytab[0];
X		while (ktp->k_fp != NULL) {
X			if (ktp->k_fp == nptr->n_func) {
X				/* padd out some spaces */
X				while (cpos < 25)
X					outseq[cpos++] = ' ';
X
X				/* add in the command sequence */
X				cmdstr(ktp->k_code, &outseq[cpos]);
X				while (outseq[cpos] != 0)
X					++cpos;
X
X				/* and add it as a line into the buffer */
X				strp = &outseq[0];
X				while (*strp != 0)
X					linsert(1, *strp++);
X				lnewline();
X
X				cpos = 0;	/* and clear the line */
X			}
X			++ktp;
X		}
X
X		/* if no key was bound, we need to dump it anyway */
X		if (cpos > 0) {
X			outseq[cpos] = 0;
X			strp = &outseq[0];
X			while (*strp != 0)
X				linsert(1, *strp++);
X			lnewline();
X		}
X
Xfail:		/* and on to the next name */
X		++nptr;
X	}
X
X	curwp->w_bufp->b_mode |= MDVIEW;/* put this buffer view mode */
X	curbp->b_flag &= ~BFCHG;	/* don't flag this as a change */
X	wp->w_dotp = lforw(bp->b_linep);/* back to the beginning */
X	wp->w_doto = 0;
X	wp = wheadp;			/* and update ALL mode lines */
X	while (wp != NULL) {
X		wp->w_flag |= WFMODE;
X		wp = wp->w_wndp;
X	}
X	mlwrite("");	/* clear the mode line */
X	return(TRUE);
X}
X
X#if	APROP
Xstrinc(source, sub)	/* does source include sub? */
X
Xchar *source;	/* string to search in */
Xchar *sub;	/* substring to look for */
X
X{
X	char *sp;	/* ptr into source */
X	char *nxtsp;	/* next ptr into source */
X	char *tp;	/* ptr into substring */
X
X	/* for each character in the source string */
X	sp = source;
X	while (*sp) {
X		tp = sub;
X		nxtsp = sp;
X
X		/* is the substring here? */
X		while (*tp) {
X			if (*nxtsp++ != *tp)
X				break;
X			else
X				tp++;
X		}
X
X		/* yes, return a success */
X		if (*tp == 0)
X			return(TRUE);
X
X		/* no, onward */
X		sp++;
X	}
X	return(FALSE);
X}
X#endif
X
Xgetckey(mflag)	/* get a command key sequence from the keyboard	*/
X
Xint mflag;	/* going for a meta sequence? */
X
X{
X	register int c;		/* character fetched */
X	register char *tp;	/* pointer into the token */
X	char tok[NSTRING];	/* command incoming */
X
X	/* check to see if we are executing a command line */
X	if (clexec) {
X		macarg(tok);	/* get the next token */
X
X		/* parse it up */
X		tp = &tok[0];
X		c = 0;
X
X		/* first, the META prefix */
X		if (*tp == 'M' && *(tp+1) == '-') {
X			c = META;
X			tp += 2;
X		}
X
X		/* next the function prefix */
X		if (*tp == 'F' && *(tp+1) == 'N') {
X			c |= SPEC;
X			tp += 2;
X		}
X
X		/* control-x as well... */
X		if (*tp == '^' && *(tp+1) == 'X') {
X			c |= CTLX;
X			tp += 2;
X		}
X
X		/* a control char? */
X		if (*tp == '^' && *(tp+1) != 0) {
X			c |= CTRL;
X			++tp;
X		}
X
X		/* make sure we are not lower case */
X		if (c >= 'a' && c <= 'z')
X			c -= 32;
X
X		/* the final sequence... */
X		c |= *tp;
X
X		return(c);
X	}
X
X	/* or the normal way */
X	if (mflag)
X		c = get1key();
X	else
X		c = getcmd();
X	return(c);
X}
X
X/* execute the startup file */
X
Xstartup(sfname)
X
Xchar *sfname;	/* name of startup file (null if default) */
X
X{
X	char *fname;	/* resulting file name to execute */
X
X	/* look up the startup file */
X	if (*sfname != 0)
X		fname = flook(sfname, TRUE);
X	else
X		fname = flook(pathname[0], TRUE);
X
X	/* if it isn't around, don't sweat it */
X	if (fname == NULL)
X		return(TRUE);
X
X	/* otherwise, execute the sucker */
X	return(dofile(fname));
X}
X
X/*	Look up the existance of a file along the normal or PATH
X	environment variable. Look first in the HOME directory if
X	asked and possible
X*/
X
Xchar *flook(fname, hflag)
X
Xchar *fname;	/* base file name to search for */
Xint hflag;	/* Look in the HOME environment variable first? */
X
X{
X	register char *home;	/* path to home directory */
X	register char *path;	/* environmental PATH variable */
X	register char *sp;	/* pointer into path spec */
X	register int i;		/* index */
X	register int status;	/* return status */
X	static char fspec[NSTRING];	/* full path spec to search */
X	char *getenv();
X
X#if	((MSDOS | AMIGA) & (LATTICE | AZTEC | MSC)) | V7 | USG | BSD
X
X	if (hflag) {
X		home = getenv("HOME");
X		if (home != NULL) {
X			/* build home dir file spec */
X			strcpy(fspec, home);
X			strcat(fspec, "/");
X			strcat(fspec, fname);
X
X			/* and try it out */
X			status = ffropen(fspec);
X			if (status == FIOSUC) {
X				ffclose();
X				return(fspec);
X			}
X		}
X	}
X
X	/* get the PATH variable */
X	path = getenv("PATH");
X	if (path != NULL)
X		while (*path) {
X
X			/* build next possible file spec */
X			sp = fspec;
X			while (*path && (*path != PATHCHR))
X				*sp++ = *path++;
X			*sp++ = '/';
X			*sp = 0;
X			strcat(fspec, fname);
X
X			/* and try it out */
X			status = ffropen(fspec);
X			if (status == FIOSUC) {
X				ffclose();
X				return(fspec);
X			}
X
X			if (*path == PATHCHR)
X				++path;
X		}
X#endif
X
X	/* look it up via the old table method */
X	for (i=2; i < NPNAMES; i++) {
X		strcpy(fspec, pathname[i]);
X		strcat(fspec, fname);
X
X		/* and try it out */
X		status = ffropen(fspec);
X		if (status == FIOSUC) {
X			ffclose();
X			return(fspec);
X		}
X	}
X
X	return(NULL);	/* no such luck */
X}
X
END_OF_bind.c
if test 14963 -ne `wc -c <bind.c`; then
    echo shar: \"bind.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: Extracting \"buffer.c\" \(15529 characters\)
if test -f buffer.c ; then 
  echo shar: Will not over-write existing file \"buffer.c\"
else
sed "s/^X//" >buffer.c <<'END_OF_buffer.c'
X/*
X * Buffer management.
X * Some of the functions are internal,
X * and some are actually attached to user
X * keys. Like everyone else, they set hints
X * for the display system.
X */
X#include        <stdio.h>
X#include	"estruct.h"
X#include        "edef.h"
X
X#if	MEGAMAX & ST520
Xoverlay	"buffer"
X#endif
X
X/*
X * Attach a buffer to a window. The
X * values of dot and mark come from the buffer
X * if the use count is 0. Otherwise, they come
X * from some other window.
X */
Xusebuffer(f, n)
X{
X        register BUFFER *bp;
X        register int    s;
X        char            bufn[NBUFN];
X
X        if ((s=mlreply("Use buffer: ", bufn, NBUFN)) != TRUE)
X                return (s);
X        if ((bp=bfind(bufn, TRUE, 0)) == NULL)
X                return (FALSE);
X	return(swbuffer(bp));
X}
X
Xnextbuffer(f, n)	/* switch to the next buffer in the buffer list */
X
X{
X        register BUFFER *bp;
X
X	bp = curbp->b_bufp;
X	/* cycle through the buffers to find an eligable one */
X	while (bp == NULL || bp->b_flag & BFINVS) {
X		if (bp == NULL)
X			bp = bheadp;
X		else
X			bp = bp->b_bufp;
X	}
X	return(swbuffer(bp));
X}
X
Xswbuffer(bp)	/* make buffer BP current */
X
XBUFFER *bp;
X
X{
X        register WINDOW *wp;
X
X        if (--curbp->b_nwnd == 0) {             /* Last use.            */
X                curbp->b_dotp  = curwp->w_dotp;
X                curbp->b_doto  = curwp->w_doto;
X                curbp->b_markp = curwp->w_markp;
X                curbp->b_marko = curwp->w_marko;
X        }
X        curbp = bp;                             /* Switch.              */
X	if (curbp->b_active != TRUE) {		/* buffer not active yet*/
X		/* read it in and activate it */
X		readin(curbp->b_fname, TRUE);
X		curbp->b_dotp = lforw(curbp->b_linep);
X		curbp->b_doto = 0;
X		curbp->b_active = TRUE;
X	}
X        curwp->w_bufp  = bp;
X        curwp->w_linep = bp->b_linep;           /* For macros, ignored. */
X        curwp->w_flag |= WFMODE|WFFORCE|WFHARD; /* Quite nasty.         */
X        if (bp->b_nwnd++ == 0) {                /* First use.           */
X                curwp->w_dotp  = bp->b_dotp;
X                curwp->w_doto  = bp->b_doto;
X                curwp->w_markp = bp->b_markp;
X                curwp->w_marko = bp->b_marko;
X                return (TRUE);
X        }
X        wp = wheadp;                            /* Look for old.        */
X        while (wp != NULL) {
X                if (wp!=curwp && wp->w_bufp==bp) {
X                        curwp->w_dotp  = wp->w_dotp;
X                        curwp->w_doto  = wp->w_doto;
X                        curwp->w_markp = wp->w_markp;
X                        curwp->w_marko = wp->w_marko;
X                        break;
X                }
X                wp = wp->w_wndp;
X        }
X        return (TRUE);
X}
X
X/*
X * Dispose of a buffer, by name.
X * Ask for the name. Look it up (don't get too
X * upset if it isn't there at all!). Get quite upset
X * if the buffer is being displayed. Clear the buffer (ask
X * if the buffer has been changed). Then free the header
X * line and the buffer header. Bound to "C-X K".
X */
Xkillbuffer(f, n)
X
X{
X	register BUFFER *bp;
X        register int    s;
X        char bufn[NBUFN];
X
X        if ((s=mlreply("Kill buffer: ", bufn, NBUFN)) != TRUE)
X                return(s);
X        if ((bp=bfind(bufn, FALSE, 0)) == NULL) /* Easy if unknown.     */
X                return (TRUE);
X	if(bp->b_flag & BFINVS)		/* Deal with special buffers	*/
X			return (TRUE);		/* by doing nothing.	*/
X	return(zotbuf(bp));
X}
X
Xzotbuf(bp)	/* kill the buffer pointed to by bp */
X
Xregister BUFFER *bp;
X
X{
X        register BUFFER *bp1;
X        register BUFFER *bp2;
X        register int    s;
X
X        if (bp->b_nwnd != 0) {                  /* Error if on screen.  */
X                mlwrite("Buffer is being displayed");
X                return (FALSE);
X        }
X        if ((s=bclear(bp)) != TRUE)             /* Blow text away.      */
X                return (s);
X        free((char *) bp->b_linep);             /* Release header line. */
X        bp1 = NULL;                             /* Find the header.     */
X        bp2 = bheadp;
X        while (bp2 != bp) {
X                bp1 = bp2;
X                bp2 = bp2->b_bufp;
X        }
X        bp2 = bp2->b_bufp;                      /* Next one in chain.   */
X        if (bp1 == NULL)                        /* Unlink it.           */
X                bheadp = bp2;
X        else
X                bp1->b_bufp = bp2;
X        free((char *) bp);                      /* Release buffer block */
X        return (TRUE);
X}
X
Xnamebuffer(f,n)		/*	Rename the current buffer	*/
X
Xint f, n;		/* default Flag & Numeric arg */
X
X{
X	register BUFFER *bp;	/* pointer to scan through all buffers */
X	char bufn[NBUFN];	/* buffer to hold buffer name */
X
X	/* prompt for and get the new buffer name */
Xask:	if (mlreply("Change buffer name to: ", bufn, NBUFN) != TRUE)
X		return(FALSE);
X
X	/* and check for duplicates */
X	bp = bheadp;
X	while (bp != NULL) {
X		if (bp != curbp) {
X			/* if the names the same */
X			if (strcmp(bufn, bp->b_bname) == 0)
X				goto ask;  /* try again */
X		}
X		bp = bp->b_bufp;	/* onward */
X	}
X
X	strcpy(curbp->b_bname, bufn);	/* copy buffer name to structure */
X	curwp->w_flag |= WFMODE;	/* make mode line replot */
X	mlerase();
X	return(TRUE);
X}
X
X/*
X * List all of the active
X * buffers. First update the special
X * buffer that holds the list. Next make
X * sure at least 1 window is displaying the
X * buffer list, splitting the screen if this
X * is what it takes. Lastly, repaint all of
X * the windows that are displaying the
X * list. Bound to "C-X C-B".
X */
Xlistbuffers(f, n)
X{
X        register WINDOW *wp;
X        register BUFFER *bp;
X        register int    s;
X
X        if ((s=makelist()) != TRUE)
X                return (s);
X        if (blistp->b_nwnd == 0) {              /* Not on screen yet.   */
X                if ((wp=wpopup()) == NULL)
X                        return (FALSE);
X                bp = wp->w_bufp;
X                if (--bp->b_nwnd == 0) {
X                        bp->b_dotp  = wp->w_dotp;
X                        bp->b_doto  = wp->w_doto;
X                        bp->b_markp = wp->w_markp;
X                        bp->b_marko = wp->w_marko;
X                }
X                wp->w_bufp  = blistp;
X                ++blistp->b_nwnd;
X        }
X        wp = wheadp;
X        while (wp != NULL) {
X                if (wp->w_bufp == blistp) {
X                        wp->w_linep = lforw(blistp->b_linep);
X                        wp->w_dotp  = lforw(blistp->b_linep);
X                        wp->w_doto  = 0;
X                        wp->w_markp = NULL;
X                        wp->w_marko = 0;
X                        wp->w_flag |= WFMODE|WFHARD;
X                }
X                wp = wp->w_wndp;
X        }
X        return (TRUE);
X}
X
X/*
X * This routine rebuilds the
X * text in the special secret buffer
X * that holds the buffer list. It is called
X * by the list buffers command. Return TRUE
X * if everything works. Return FALSE if there
X * is an error (if there is no memory).
X */
Xmakelist()
X{
X        register char   *cp1;
X        register char   *cp2;
X        register int    c;
X        register BUFFER *bp;
X        register LINE   *lp;
X        register int    s;
X	register int	i;
X        long	nbytes;		/* # of bytes in current buffer */
X        char            b[7+1];
X        char            line[128];
X
X        blistp->b_flag &= ~BFCHG;               /* Don't complain!      */
X        if ((s=bclear(blistp)) != TRUE)         /* Blow old text away   */
X                return (s);
X        strcpy(blistp->b_fname, "");
X        if (addline("AC MODES       Size Buffer        File") == FALSE
X        ||  addline("-- -----       ---- ------        ----") == FALSE)
X                return (FALSE);
X        bp = bheadp;                            /* For all buffers      */
X
X	/* build line to report global mode settings */
X	cp1 = &line[0];
X	*cp1++ = ' ';
X	*cp1++ = ' ';
X	*cp1++ = ' ';
X
X	/* output the mode codes */
X	for (i = 0; i < NUMMODES; i++)
X		if (gmode & (1 << i))
X			*cp1++ = modecode[i];
X		else
X			*cp1++ = '.';
X	strcpy(cp1, "         Global Modes");
X	if (addline(line) == FALSE)
X		return(FALSE);
X
X	/* output the list of buffers */
X        while (bp != NULL) {
X                if ((bp->b_flag&BFINVS) != 0) { /* Skip magic ones.     */
X                        bp = bp->b_bufp;
X                        continue;
X                }
X                cp1 = &line[0];                 /* Start at left edge   */
X
X		/* output status of ACTIVE flag (has the file been read in? */
X                if (bp->b_active == TRUE)    /* "@" if activated       */
X                        *cp1++ = '@';
X                else
X                        *cp1++ = ' ';
X
X		/* output status of changed flag */
X                if ((bp->b_flag&BFCHG) != 0)    /* "*" if changed       */
X                        *cp1++ = '*';
X                else
X                        *cp1++ = ' ';
X                *cp1++ = ' ';                   /* Gap.                 */
X
X		/* output the mode codes */
X		for (i = 0; i < NUMMODES; i++) {
X			if (bp->b_mode & (1 << i))
X				*cp1++ = modecode[i];
X			else
X				*cp1++ = '.';
X		}
X                *cp1++ = ' ';                   /* Gap.                 */
X                nbytes = 0L;                    /* Count bytes in buf.  */
X                lp = lforw(bp->b_linep);
X                while (lp != bp->b_linep) {
X                        nbytes += (long)llength(lp)+1L;
X                        lp = lforw(lp);
X                }
X                ltoa(b, 7, nbytes);             /* 6 digit buffer size. */
X                cp2 = &b[0];
X                while ((c = *cp2++) != 0)
X                        *cp1++ = c;
X                *cp1++ = ' ';                   /* Gap.                 */
X                cp2 = &bp->b_bname[0];          /* Buffer name          */
X                while ((c = *cp2++) != 0)
X                        *cp1++ = c;
X                cp2 = &bp->b_fname[0];          /* File name            */
X                if (*cp2 != 0) {
X                        while (cp1 < &line[2+1+5+1+6+1+NBUFN])
X                                *cp1++ = ' ';
X                        while ((c = *cp2++) != 0) {
X                                if (cp1 < &line[128-1])
X                                        *cp1++ = c;
X                        }
X                }
X                *cp1 = 0;                       /* Add to the buffer.   */
X                if (addline(line) == FALSE)
X                        return (FALSE);
X                bp = bp->b_bufp;
X        }
X        return (TRUE);                          /* All done             */
X}
X
Xltoa(buf, width, num)
X
Xchar   buf[];
Xint    width;
Xlong   num;
X
X{
X        buf[width] = 0;                         /* End of string.       */
X        while (num >= 10) {                     /* Conditional digits.  */
X                buf[--width] = (int)(num%10L) + '0';
X                num /= 10L;
X        }
X        buf[--width] = (int)num + '0';          /* Always 1 digit.      */
X        while (width != 0)                      /* Pad with blanks.     */
X                buf[--width] = ' ';
X}
X
X/*
X * The argument "text" points to
X * a string. Append this line to the
X * buffer list buffer. Handcraft the EOL
X * on the end. Return TRUE if it worked and
X * FALSE if you ran out of room.
X */
Xaddline(text)
Xchar    *text;
X{
X        register LINE   *lp;
X        register int    i;
X        register int    ntext;
X
X        ntext = strlen(text);
X        if ((lp=lalloc(ntext)) == NULL)
X                return (FALSE);
X        for (i=0; i<ntext; ++i)
X                lputc(lp, i, text[i]);
X        blistp->b_linep->l_bp->l_fp = lp;       /* Hook onto the end    */
X        lp->l_bp = blistp->b_linep->l_bp;
X        blistp->b_linep->l_bp = lp;
X        lp->l_fp = blistp->b_linep;
X        if (blistp->b_dotp == blistp->b_linep)  /* If "." is at the end */
X                blistp->b_dotp = lp;            /* move it to new line  */
X        return (TRUE);
X}
X
X/*
X * Look through the list of
X * buffers. Return TRUE if there
X * are any changed buffers. Buffers
X * that hold magic internal stuff are
X * not considered; who cares if the
X * list of buffer names is hacked.
X * Return FALSE if no buffers
X * have been changed.
X */
Xanycb()
X{
X        register BUFFER *bp;
X
X        bp = bheadp;
X        while (bp != NULL) {
X                if ((bp->b_flag&BFINVS)==0 && (bp->b_flag&BFCHG)!=0)
X                        return (TRUE);
X                bp = bp->b_bufp;
X        }
X        return (FALSE);
X}
X
X/*
X * Find a buffer, by name. Return a pointer
X * to the BUFFER structure associated with it.
X * If the buffer is not found
X * and the "cflag" is TRUE, create it. The "bflag" is
X * the settings for the flags in in buffer.
X */
XBUFFER  *
Xbfind(bname, cflag, bflag)
Xregister char   *bname;
X{
X        register BUFFER *bp;
X	register BUFFER *sb;	/* buffer to insert after */
X        register LINE   *lp;
X	char *malloc();
X
X        bp = bheadp;
X        while (bp != NULL) {
X                if (strcmp(bname, bp->b_bname) == 0)
X                        return (bp);
X                bp = bp->b_bufp;
X        }
X        if (cflag != FALSE) {
X                if ((bp=(BUFFER *)malloc(sizeof(BUFFER))) == NULL)
X                        return (NULL);
X                if ((lp=lalloc(0)) == NULL) {
X                        free((char *) bp);
X                        return (NULL);
X                }
X		/* find the place in the list to insert this buffer */
X		if (bheadp == NULL || strcmp(bheadp->b_bname, bname) > 0) {
X			/* insert at the beginning */
X	                bp->b_bufp = bheadp;
X        	        bheadp = bp;
X        	} else {
X			sb = bheadp;
X			while (sb->b_bufp != NULL) {
X				if (strcmp(sb->b_bufp->b_bname, bname) > 0)
X					break;
X				sb = sb->b_bufp;
X			}
X
X			/* and insert it */
X       			bp->b_bufp = sb->b_bufp;
X        		sb->b_bufp = bp;
X       		}
X
X		/* and set up the other buffer fields */
X		bp->b_active = TRUE;
X                bp->b_dotp  = lp;
X                bp->b_doto  = 0;
X                bp->b_markp = NULL;
X                bp->b_marko = 0;
X                bp->b_flag  = bflag;
X		bp->b_mode  = gmode;
X                bp->b_nwnd  = 0;
X                bp->b_linep = lp;
X                strcpy(bp->b_fname, "");
X                strcpy(bp->b_bname, bname);
X#if	CRYPT
X		bp->b_key[0] = 0;
X#endif
X                lp->l_fp = lp;
X                lp->l_bp = lp;
X        }
X        return (bp);
X}
X
X/*
X * This routine blows away all of the text
X * in a buffer. If the buffer is marked as changed
X * then we ask if it is ok to blow it away; this is
X * to save the user the grief of losing text. The
X * window chain is nearly always wrong if this gets
X * called; the caller must arrange for the updates
X * that are required. Return TRUE if everything
X * looks good.
X */
Xbclear(bp)
Xregister BUFFER *bp;
X{
X        register LINE   *lp;
X        register int    s;
X
X        if ((bp->b_flag&BFINVS) == 0            /* Not scratch buffer.  */
X        && (bp->b_flag&BFCHG) != 0              /* Something changed    */
X        && (s=mlyesno("Discard changes")) != TRUE)
X                return (s);
X        bp->b_flag  &= ~BFCHG;                  /* Not changed          */
X        while ((lp=lforw(bp->b_linep)) != bp->b_linep)
X                lfree(lp);
X        bp->b_dotp  = bp->b_linep;              /* Fix "."              */
X        bp->b_doto  = 0;
X        bp->b_markp = NULL;                     /* Invalidate "mark"    */
X        bp->b_marko = 0;
X        return (TRUE);
X}
X
Xunmark(f, n)	/* unmark the current buffers change flag */
X
Xint f, n;	/* unused command arguments */
X
X{
X	curbp->b_flag &= ~BFCHG;
X	curwp->w_flag |= WFMODE;
X	return(TRUE);
X}
END_OF_buffer.c
if test 15529 -ne `wc -c <buffer.c`; then
    echo shar: \"buffer.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: Extracting \"word.c\" \(15895 characters\)
if test -f word.c ; then 
  echo shar: Will not over-write existing file \"word.c\"
else
sed "s/^X//" >word.c <<'END_OF_word.c'
X/*
X * The routines in this file implement commands that work word or a
X * paragraph at a time.  There are all sorts of word mode commands.  If I
X * do any sentence mode commands, they are likely to be put in this file. 
X */
X
X#if	MEGAMAX & ST520
Xoverlay	"word"
X#endif
X
X#include        <stdio.h>
X#include        "estruct.h"
X#include	"edef.h"
X
X/* Word wrap on n-spaces. Back-over whatever precedes the point on the current
X * line and stop on the first word-break or the beginning of the line. If we
X * reach the beginning of the line, jump back to the end of the word and start
X * a new line.  Otherwise, break the line at the word-break, eat it, and jump
X * back to the end of the word.
X * Returns TRUE on success, FALSE on errors.
X */
Xwrapword(f, n)
X
Xint f;		/* default flag */
Xint n;		/* numeric argument */
X
X{
X        register int cnt;	/* size of word wrapped to next line */
X	register int c;		/* charector temporary */
X
X	/* backup from the <NL> 1 char */
X        if (!backchar(0, 1))
X	        return(FALSE);
X
X	/* back up until we aren't in a word,
X	   make sure there is a break in the line */
X        cnt = 0;
X	while (((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' ')
X				&& (c != '\t')) {
X                cnt++;
X                if (!backchar(0, 1))
X                        return(FALSE);
X		/* if we make it to the beginning, start a new line */
X		if (curwp->w_doto == 0) {
X			gotoeol(FALSE, 0);
X			return(lnewline());
X		}
X        }
X
X	/* delete the forward white space */
X        if (!forwdel(0, 1))
X                return(FALSE);
X
X	/* put in a end of line */
X        if (!lnewline())
X                return(FALSE);
X
X	/* and past the first word */
X	while (cnt-- > 0) {
X		if (forwchar(FALSE, 1) == FALSE)
X			return(FALSE);
X	}
X        return(TRUE);
X}
X
X/*
X * Move the cursor backward by "n" words. All of the details of motion are
X * performed by the "backchar" and "forwchar" routines. Error if you try to
X * move beyond the buffers.
X */
Xbackword(f, n)
X{
X        if (n < 0)
X                return (forwword(f, -n));
X        if (backchar(FALSE, 1) == FALSE)
X                return (FALSE);
X        while (n--) {
X                while (inword() == FALSE) {
X                        if (backchar(FALSE, 1) == FALSE)
X                                return (FALSE);
X                }
X                while (inword() != FALSE) {
X                        if (backchar(FALSE, 1) == FALSE)
X                                return (FALSE);
X                }
X        }
X        return (forwchar(FALSE, 1));
X}
X
X/*
X * Move the cursor forward by the specified number of words. All of the motion
X * is done by "forwchar". Error if you try and move beyond the buffer's end.
X */
Xforwword(f, n)
X{
X        if (n < 0)
X                return (backword(f, -n));
X        while (n--) {
X#if	NFWORD
X                while (inword() != FALSE) {
X                        if (forwchar(FALSE, 1) == FALSE)
X                                return (FALSE);
X                }
X#endif
X                while (inword() == FALSE) {
X                        if (forwchar(FALSE, 1) == FALSE)
X                                return (FALSE);
X                }
X#if	NFWORD == 0
X                while (inword() != FALSE) {
X                        if (forwchar(FALSE, 1) == FALSE)
X                                return (FALSE);
X                }
X#endif
X        }
X	return(TRUE);
X}
X
X/*
X * Move the cursor forward by the specified number of words. As you move,
X * convert any characters to upper case. Error if you try and move beyond the
X * end of the buffer. Bound to "M-U".
X */
Xupperword(f, n)
X{
X        register int    c;
X
X	if (curbp->b_mode&MDVIEW)	/* don't allow this command if	*/
X		return(rdonly());	/* we are in read only mode	*/
X        if (n < 0)
X                return (FALSE);
X        while (n--) {
X                while (inword() == FALSE) {
X                        if (forwchar(FALSE, 1) == FALSE)
X                                return (FALSE);
X                }
X                while (inword() != FALSE) {
X                        c = lgetc(curwp->w_dotp, curwp->w_doto);
X                        if (c>='a' && c<='z') {
X                                c -= 'a'-'A';
X                                lputc(curwp->w_dotp, curwp->w_doto, c);
X                                lchange(WFHARD);
X                        }
X                        if (forwchar(FALSE, 1) == FALSE)
X                                return (FALSE);
X                }
X        }
X        return (TRUE);
X}
X
X/*
X * Move the cursor forward by the specified number of words. As you move
X * convert characters to lower case. Error if you try and move over the end of
X * the buffer. Bound to "M-L".
X */
Xlowerword(f, n)
X{
X        register int    c;
X
X	if (curbp->b_mode&MDVIEW)	/* don't allow this command if	*/
X		return(rdonly());	/* we are in read only mode	*/
X        if (n < 0)
X                return (FALSE);
X        while (n--) {
X                while (inword() == FALSE) {
X                        if (forwchar(FALSE, 1) == FALSE)
X                                return (FALSE);
X                }
X                while (inword() != FALSE) {
X                        c = lgetc(curwp->w_dotp, curwp->w_doto);
X                        if (c>='A' && c<='Z') {
X                                c += 'a'-'A';
X                                lputc(curwp->w_dotp, curwp->w_doto, c);
X                                lchange(WFHARD);
X                        }
X                        if (forwchar(FALSE, 1) == FALSE)
X                                return (FALSE);
X                }
X        }
X        return (TRUE);
X}
X
X/*
X * Move the cursor forward by the specified number of words. As you move
X * convert the first character of the word to upper case, and subsequent
X * characters to lower case. Error if you try and move past the end of the
X * buffer. Bound to "M-C".
X */
Xcapword(f, n)
X{
X        register int    c;
X
X	if (curbp->b_mode&MDVIEW)	/* don't allow this command if	*/
X		return(rdonly());	/* we are in read only mode	*/
X        if (n < 0)
X                return (FALSE);
X        while (n--) {
X                while (inword() == FALSE) {
X                        if (forwchar(FALSE, 1) == FALSE)
X                                return (FALSE);
X                }
X                if (inword() != FALSE) {
X                        c = lgetc(curwp->w_dotp, curwp->w_doto);
X                        if (c>='a' && c<='z') {
X                                c -= 'a'-'A';
X                                lputc(curwp->w_dotp, curwp->w_doto, c);
X                                lchange(WFHARD);
X                        }
X                        if (forwchar(FALSE, 1) == FALSE)
X                                return (FALSE);
X                        while (inword() != FALSE) {
X                                c = lgetc(curwp->w_dotp, curwp->w_doto);
X                                if (c>='A' && c<='Z') {
X                                        c += 'a'-'A';
X                                        lputc(curwp->w_dotp, curwp->w_doto, c);
X                                        lchange(WFHARD);
X                                }
X                                if (forwchar(FALSE, 1) == FALSE)
X                                        return (FALSE);
X                        }
X                }
X        }
X        return (TRUE);
X}
X
X/*
X * Kill forward by "n" words. Remember the location of dot. Move forward by
X * the right number of words. Put dot back where it was and issue the kill
X * command for the right number of characters. Bound to "M-D".
X */
Xdelfword(f, n)
X{
X        register LINE   *dotp;
X        register int    doto;
X        long size;
X
X	if (curbp->b_mode&MDVIEW)	/* don't allow this command if	*/
X		return(rdonly());	/* we are in read only mode	*/
X        if (n < 0)
X                return (FALSE);
X        if ((lastflag&CFKILL) == 0)     /* Clear kill buffer if */
X                kdelete();              /* last wasn't a kill.  */
X        thisflag |= CFKILL;
X        dotp = curwp->w_dotp;
X        doto = curwp->w_doto;
X        size = 0;
X        while (n--) {
X#if	NFWORD
X		if (curwp->w_doto == llength(curwp->w_dotp)) {
X			if (forwchar(FALSE,1) == FALSE)
X				return(FALSE);
X			++size;
X		}
X
X		while (inword() != FALSE) {
X			if (forwchar(FALSE,1) == FALSE)
X				return(FALSE);
X			++size;
X		}
X
X                while ((inword() == FALSE) &&
X				(curwp->w_doto != llength(curwp->w_dotp))) {
X                        if (forwchar(FALSE, 1) == FALSE)
X                                return (FALSE);
X                        ++size;
X                }
X#else
X                while (inword() == FALSE) {
X                        if (forwchar(FALSE, 1) == FALSE)
X                                return (FALSE);
X                        ++size;
X                }
X
X                while (inword() != FALSE) {
X                        if (forwchar(FALSE, 1) == FALSE)
X                                return (FALSE);
X                        ++size;
X                }
X#endif
X        }
X        curwp->w_dotp = dotp;
X        curwp->w_doto = doto;
X        return (ldelete(size, TRUE));
X}
X
X/*
X * Kill backwards by "n" words. Move backwards by the desired number of words,
X * counting the characters. When dot is finally moved to its resting place,
X * fire off the kill command. Bound to "M-Rubout" and to "M-Backspace".
X */
Xdelbword(f, n)
X{
X        long size;
X
X	if (curbp->b_mode&MDVIEW)	/* don't allow this command if	*/
X		return(rdonly());	/* we are in read only mode	*/
X        if (n < 0)
X                return (FALSE);
X        if ((lastflag&CFKILL) == 0)     /* Clear kill buffer if */
X                kdelete();              /* last wasn't a kill.  */
X        thisflag |= CFKILL;
X        if (backchar(FALSE, 1) == FALSE)
X                return (FALSE);
X        size = 0;
X        while (n--) {
X                while (inword() == FALSE) {
X                        if (backchar(FALSE, 1) == FALSE)
X                                return (FALSE);
X                        ++size;
X                }
X                while (inword() != FALSE) {
X                        if (backchar(FALSE, 1) == FALSE)
X                                return (FALSE);
X                        ++size;
X                }
X        }
X        if (forwchar(FALSE, 1) == FALSE)
X                return (FALSE);
X        return (ldelete(size, TRUE));
X}
X
X/*
X * Return TRUE if the character at dot is a character that is considered to be
X * part of a word. The word character list is hard coded. Should be setable.
X */
Xinword()
X{
X        register int    c;
X
X        if (curwp->w_doto == llength(curwp->w_dotp))
X                return (FALSE);
X        c = lgetc(curwp->w_dotp, curwp->w_doto);
X        if (c>='a' && c<='z')
X                return (TRUE);
X        if (c>='A' && c<='Z')
X                return (TRUE);
X        if (c>='0' && c<='9')
X                return (TRUE);
X        if (c=='$' || c=='_')                   /* For identifiers      */
X                return (TRUE);
X        return (FALSE);
X}
X
X#if	WORDPRO
Xfillpara(f, n)	/* Fill the current paragraph according to the current
X		   fill column						*/
X
Xint f, n;	/* deFault flag and Numeric argument */
X
X{
X	register int c;			/* current char durring scan	*/
X	register int wordlen;		/* length of current word	*/
X	register int clength;		/* position on line during fill	*/
X	register int i;			/* index during word copy	*/
X	register int newlength;		/* tentative new line length	*/
X	register int eopflag;		/* Are we at the End-Of-Paragraph? */
X	register int firstflag;		/* first word? (needs no space)	*/
X	register LINE *eopline;		/* pointer to line just past EOP */
X	register int dotflag;		/* was the last char a period?	*/
X	char wbuf[NSTRING];		/* buffer for current word	*/
X
X	if (curbp->b_mode&MDVIEW)	/* don't allow this command if	*/
X		return(rdonly());	/* we are in read only mode	*/
X	if (fillcol == 0) {	/* no fill column set */
X		mlwrite("No fill column set");
X		return(FALSE);
X	}
X
X	/* record the pointer to the line just past the EOP */
X	gotoeop(FALSE, 1);
X	eopline = lforw(curwp->w_dotp);
X
X	/* and back top the beginning of the paragraph */
X	gotobop(FALSE, 1);
X
X	/* initialize various info */
X	clength = curwp->w_doto;
X	if (clength && curwp->w_dotp->l_text[0] == TAB)
X		clength = 8;
X	wordlen = 0;
X	dotflag = FALSE;
X
X	/* scan through lines, filling words */
X	firstflag = TRUE;
X	eopflag = FALSE;
X	while (!eopflag) {
X		/* get the next character in the paragraph */
X		if (curwp->w_doto == llength(curwp->w_dotp)) {
X			c = ' ';
X			if (lforw(curwp->w_dotp) == eopline)
X				eopflag = TRUE;
X		} else
X			c = lgetc(curwp->w_dotp, curwp->w_doto);
X
X		/* and then delete it */
X		ldelete(1L, FALSE);
X
X		/* if not a separator, just add it in */
X		if (c != ' ' && c != '\t') {
X			dotflag = (c == '.');		/* was it a dot */
X			if (wordlen < NSTRING - 1)
X				wbuf[wordlen++] = c;
X		} else if (wordlen) {
X			/* at a word break with a word waiting */
X			/* calculate tantitive new length with word added */
X			newlength = clength + 1 + wordlen;
X			if (newlength <= fillcol) {
X				/* add word to current line */
X				if (!firstflag) {
X					linsert(1, ' '); /* the space */
X					++clength;
X				}
X				firstflag = FALSE;
X			} else {
X				/* start a new line */
X				lnewline();
X				clength = 0;
X			}
X
X			/* and add the word in in either case */
X			for (i=0; i<wordlen; i++) {
X				linsert(1, wbuf[i]);
X				++clength;
X			}
X			if (dotflag) {
X				linsert(1, ' ');
X				++clength;
X			}
X			wordlen = 0;
X		}
X	}
X	/* and add a last newline for the end of our new paragraph */
X	lnewline();
X	return(TRUE);
X}
X
Xkillpara(f, n)	/* delete n paragraphs starting with the current one */
X
Xint f;	/* default flag */
Xint n;	/* # of paras to delete */
X
X{
X	register int status;	/* returned status of functions */
X
X	while (n--) {		/* for each paragraph to delete */
X
X		/* mark out the end and beginning of the para to delete */
X		gotoeop(FALSE, 1);
X
X		/* set the mark here */
X	        curwp->w_markp = curwp->w_dotp;
X	        curwp->w_marko = curwp->w_doto;
X
X		/* go to the beginning of the paragraph */
X		gotobop(FALSE, 1);
X		curwp->w_doto = 0;	/* force us to the beginning of line */
X	
X		/* and delete it */
X		if ((status = killregion(FALSE, 1)) != TRUE)
X			return(status);
X
X		/* and clean up the 2 extra lines */
X		ldelete(2L, TRUE);
X	}
X	return(TRUE);
X}
X
X
X/*	wordcount:	count the # of words in the marked region,
X			along with average word sizes, # of chars, etc,
X			and report on them.			*/
X
Xwordcount(f, n)
X
Xint f, n;	/* ignored numeric arguments */
X
X{
X	register LINE *lp;	/* current line to scan */
X	register int offset;	/* current char to scan */
X	long size;		/* size of region left to count */
X	register int ch;	/* current character to scan */
X	register int wordflag;	/* are we in a word now? */
X	register int lastword;	/* were we just in a word? */
X	long nwords;		/* total # of words */
X	long nchars;		/* total number of chars */
X	int nlines;		/* total number of lines in region */
X	int avgch;		/* average number of chars/word */
X	int status;		/* status return code */
X	REGION region;		/* region to look at */
X
X	/* make sure we have a region to count */
X        if ((status = getregion(&region)) != TRUE)
X                return(status);
X	lp = region.r_linep;
X	offset = region.r_offset;
X	size = region.r_size;
X
X	/* count up things */
X	lastword = FALSE;
X	nchars = 0L;
X	nwords = 0L;
X	nlines = 0;
X	while (size--) {
X
X		/* get the current character */
X		if (offset == llength(lp)) {	/* end of line */
X			ch = '\n';
X			lp = lforw(lp);
X			offset = 0;
X			++nlines;
X		} else {
X			ch = lgetc(lp, offset);
X			++offset;
X		}
X
X		/* and tabulate it */
X		wordflag = ((ch >= 'a' && ch <= 'z') ||
X			    (ch >= 'A' && ch <= 'Z') ||
X			    (ch >= '0' && ch <= '9') ||
X			    (ch == '$' || ch == '_'));
X		if (wordflag == TRUE && lastword == FALSE)
X			++nwords;
X		lastword = wordflag;
X		++nchars;
X	}
X
X	/* and report on the info */
X	if (nwords > 0L)
X		avgch = (int)((100L * nchars) / nwords);
X	else
X		avgch = 0;
X
X	mlwrite("Words %D Chars %D Lines %d Avg chars/word %f",
X		nwords, nchars, nlines + 1, avgch);
X	return(TRUE);
X}
X#endif
END_OF_word.c
if test 15895 -ne `wc -c <word.c`; then
    echo shar: \"word.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 6 \(of 14\).
cp /dev/null ark6isdone
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