[mod.sources] v06i082: MicroEmacs, Version 3.7

sources-request@mirror.UUCP (07/31/86)

Submitted by: ihnp4!pur-ee!pur-phy!duncan!lawrence
Mod.sources: Volume 6, Issue 82
Archive-name: uEmacs/Part12

[  This is the last version of emacs that will be posted here for quite
   some time.  Anyone for a mod.sources.emacs?  --r$ ]

echo extracting - word.c
sed 's/^X//' > word.c << 'FRIDAY_NIGHT'
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#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(n)
X
Xint n;
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 begining, start a new line */
X		if (curwp->w_doto == 0) {
X			gotoeol(FALSE, 0);
X			return(newline(0,1));
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 (!newline(0, 1))
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 begining 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 != '	') {
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 begining 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 begining of the paragraph */
X		gotobop(FALSE, 1);
X		curwp->w_doto = 0;	/* force us to the begining 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 lastflag;	/* 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	lastflag = 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 && lastflag == FALSE)
X			++nwords;
X		lastflag = 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
FRIDAY_NIGHT