Blame src/lib/libcmd/wclib.c

Packit Service a8c26c
/***********************************************************************
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
*               This software is part of the ast package               *
Packit Service a8c26c
*          Copyright (c) 1992-2011 AT&T Intellectual Property          *
Packit Service a8c26c
*                      and is licensed under the                       *
Packit Service a8c26c
*                 Eclipse Public License, Version 1.0                  *
Packit Service a8c26c
*                    by AT&T Intellectual Property                     *
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
*                A copy of the License is available at                 *
Packit Service a8c26c
*          http://www.eclipse.org/org/documents/epl-v10.html           *
Packit Service a8c26c
*         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
*              Information and Software Systems Research               *
Packit Service a8c26c
*                            AT&T Research                             *
Packit Service a8c26c
*                           Florham Park NJ                            *
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
*                 Glenn Fowler <gsf@research.att.com>                  *
Packit Service a8c26c
*                  David Korn <dgk@research.att.com>                   *
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
***********************************************************************/
Packit Service a8c26c
#pragma prototyped
Packit Service a8c26c
/*
Packit Service a8c26c
 * David Korn
Packit Service a8c26c
 * AT&T Bell Laboratories
Packit Service a8c26c
 *
Packit Service a8c26c
 * library interface for word count
Packit Service a8c26c
 */
Packit Service a8c26c
Packit Service a8c26c
#include <cmd.h>
Packit Service a8c26c
#include <wc.h>
Packit Service a8c26c
#include <ctype.h>
Packit Service a8c26c
Packit Service a8c26c
#if _hdr_wchar && _hdr_wctype && _lib_iswctype
Packit Service a8c26c
Packit Service a8c26c
#include <wchar.h>
Packit Service a8c26c
#include <wctype.h>
Packit Service a8c26c
#include <lc.h>
Packit Service a8c26c
Packit Service a8c26c
#else
Packit Service a8c26c
Packit Service a8c26c
#ifndef iswspace
Packit Service a8c26c
#define iswspace(x)	isspace(x)
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#define	WC_SP		0x08
Packit Service a8c26c
#define	WC_NL		0x10
Packit Service a8c26c
#define	WC_MB		0x20
Packit Service a8c26c
#define	WC_ERR		0x40
Packit Service a8c26c
Packit Service a8c26c
#define eol(c)		((c)&WC_NL)
Packit Service a8c26c
#define mbc(c)		((c)&WC_MB)
Packit Service a8c26c
#define spc(c)		((c)&WC_SP)
Packit Service a8c26c
#define mb2wc(w,p,n)	(*ast.mb_towc)(&w,(char*)p,n)
Packit Service a8c26c
Packit Service a8c26c
Wc_t* wc_init(int mode)
Packit Service a8c26c
{
Packit Service a8c26c
	register int	n;
Packit Service a8c26c
	register int	w;
Packit Service a8c26c
	Wc_t*		wp;
Packit Service a8c26c
Packit Service a8c26c
	if (!(wp = (Wc_t*)stakalloc(sizeof(Wc_t))))
Packit Service a8c26c
		return 0;
Packit Service a8c26c
	if (!mbwide())
Packit Service a8c26c
		wp->mb = 0;
Packit Service a8c26c
#if _hdr_wchar && _hdr_wctype && _lib_iswctype
Packit Service a8c26c
	else if (!(mode & WC_NOUTF8) && (lcinfo(LC_CTYPE)->lc->flags & LC_utf8))
Packit Service a8c26c
		wp->mb = 1;
Packit Service a8c26c
#endif
Packit Service a8c26c
	else
Packit Service a8c26c
		wp->mb = -1;
Packit Service a8c26c
	w = mode & WC_WORDS;
Packit Service a8c26c
	for (n = (1<<CHAR_BIT); --n >= 0;)
Packit Service a8c26c
		wp->type[n] = (w && isspace(n)) ? WC_SP : 0;
Packit Service a8c26c
	wp->type['\n'] = WC_SP|WC_NL;
Packit Service a8c26c
	if ((mode & (WC_MBYTE|WC_WORDS)) && wp->mb > 0)
Packit Service a8c26c
	{
Packit Service a8c26c
		for (n = 0; n < 64; n++)
Packit Service a8c26c
		{
Packit Service a8c26c
			wp->type[0x80+n] |= WC_MB;
Packit Service a8c26c
			if (n<32)
Packit Service a8c26c
				wp->type[0xc0+n] |= WC_MB+1;
Packit Service a8c26c
			else if (n<48)
Packit Service a8c26c
				wp->type[0xc0+n] |= WC_MB+2;
Packit Service a8c26c
			else if (n<56)
Packit Service a8c26c
				wp->type[0xc0+n] |= WC_MB+3;
Packit Service a8c26c
			else if (n<60)
Packit Service a8c26c
				wp->type[0xc0+n] |= WC_MB+4;
Packit Service a8c26c
			else if (n<62)
Packit Service a8c26c
				wp->type[0xc0+n] |= WC_MB+5;
Packit Service a8c26c
		}
Packit Service a8c26c
		wp->type[0xc0] = WC_MB|WC_ERR;
Packit Service a8c26c
		wp->type[0xc1] = WC_MB|WC_ERR;
Packit Service a8c26c
		wp->type[0xfe] = WC_MB|WC_ERR;
Packit Service a8c26c
		wp->type[0xff] = WC_MB|WC_ERR;
Packit Service a8c26c
	}
Packit Service a8c26c
	wp->mode = mode;
Packit Service a8c26c
	return wp;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
static int invalid(const char *file, int nlines)
Packit Service a8c26c
{
Packit Service a8c26c
	error_info.file = (char*)file;
Packit Service a8c26c
	error_info.line = nlines;
Packit Service a8c26c
	error(ERROR_SYSTEM|1, "invalid multibyte character");
Packit Service a8c26c
	error_info.file = 0;
Packit Service a8c26c
	error_info.line = 0;
Packit Service a8c26c
	return nlines;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
/*
Packit Service a8c26c
 * handle utf space characters
Packit Service a8c26c
 */
Packit Service a8c26c
Packit Service a8c26c
static int chkstate(int state, register unsigned int c)
Packit Service a8c26c
{
Packit Service a8c26c
	switch(state)
Packit Service a8c26c
	{
Packit Service a8c26c
	case 1:
Packit Service a8c26c
		state = (c==0x9a?4:0);
Packit Service a8c26c
		break;
Packit Service a8c26c
	case 2:
Packit Service a8c26c
		state = ((c==0x80||c==0x81)?6+(c&1):0);
Packit Service a8c26c
		break;
Packit Service a8c26c
	case 3:
Packit Service a8c26c
		state = (c==0x80?5:0);
Packit Service a8c26c
		break;
Packit Service a8c26c
	case 4:
Packit Service a8c26c
		state = (c==0x80?10:0);
Packit Service a8c26c
		break;
Packit Service a8c26c
	case 5:
Packit Service a8c26c
		state = (c==0x80?10:0);
Packit Service a8c26c
		break;
Packit Service a8c26c
	case 6:
Packit Service a8c26c
		state = 0;
Packit Service a8c26c
		if(c==0xa0 || c==0xa1)
Packit Service a8c26c
			return(10);
Packit Service a8c26c
		else if((c&0xf0)== 0x80)
Packit Service a8c26c
		{
Packit Service a8c26c
			if((c&=0xf)==7)
Packit Service a8c26c
				return(iswspace(0x2007)?10:0);
Packit Service a8c26c
			if(c<=0xb)
Packit Service a8c26c
				return(10);
Packit Service a8c26c
		}
Packit Service a8c26c
		else if(c==0xaf && iswspace(0x202f))
Packit Service a8c26c
			return(10);
Packit Service a8c26c
		break;
Packit Service a8c26c
	case 7:
Packit Service a8c26c
		state = (c==0x9f?10:0);
Packit Service a8c26c
		break;
Packit Service a8c26c
	case 8:
Packit Service a8c26c
		return (iswspace(c)?10:0);
Packit Service a8c26c
	}
Packit Service a8c26c
	return state;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
/*
Packit Service a8c26c
 * compute the line, word, and character count for file <fd>
Packit Service a8c26c
 */
Packit Service a8c26c
Packit Service a8c26c
int wc_count(Wc_t *wp, Sfio_t *fd, const char* file)
Packit Service a8c26c
{
Packit Service a8c26c
	register char*		type = wp->type;
Packit Service a8c26c
	register unsigned char*	cp;
Packit Service a8c26c
	register Sfoff_t	nbytes;
Packit Service a8c26c
	register Sfoff_t	nchars;
Packit Service a8c26c
	register Sfoff_t	nwords;
Packit Service a8c26c
	register Sfoff_t	nlines;
Packit Service a8c26c
	register Sfoff_t	eline = -1;
Packit Service a8c26c
	register Sfoff_t	longest = 0;
Packit Service a8c26c
	register ssize_t	c;
Packit Service a8c26c
	register unsigned char*	endbuff;
Packit Service a8c26c
	register int		lasttype = WC_SP;
Packit Service a8c26c
	unsigned int		lastchar;
Packit Service a8c26c
	ssize_t			n;
Packit Service a8c26c
	ssize_t			o;
Packit Service a8c26c
	unsigned char*		buff;
Packit Service a8c26c
	wchar_t			x;
Packit Service a8c26c
	unsigned char		side[32];
Packit Service a8c26c
Packit Service a8c26c
	sfset(fd,SF_WRITE,1);
Packit Service a8c26c
	nlines = nwords = nchars = nbytes = 0;
Packit Service a8c26c
	wp->longest = 0;
Packit Service a8c26c
	if (wp->mb < 0 && (wp->mode & (WC_MBYTE|WC_WORDS)))
Packit Service a8c26c
	{
Packit Service a8c26c
		cp = buff = endbuff = 0;
Packit Service a8c26c
		for (;;)
Packit Service a8c26c
		{
Packit Service a8c26c
			if (cp >= endbuff || (n = mb2wc(x, cp, endbuff-cp)) < 0)
Packit Service a8c26c
			{
Packit Service a8c26c
				if ((o = endbuff-cp) < sizeof(side))
Packit Service a8c26c
				{
Packit Service a8c26c
					if (buff)
Packit Service a8c26c
					{
Packit Service a8c26c
						if (o)
Packit Service a8c26c
							memcpy(side, cp, o);
Packit Service a8c26c
						mbinit();
Packit Service a8c26c
					}
Packit Service a8c26c
					else
Packit Service a8c26c
						o = 0;
Packit Service a8c26c
					cp = side + o;
Packit Service a8c26c
					if (!(buff = (unsigned char*)sfreserve(fd, SF_UNBOUND, 0)) || (n = sfvalue(fd)) <= 0)
Packit Service a8c26c
					{
Packit Service a8c26c
						if ((nchars - longest) > wp->longest)
Packit Service a8c26c
							wp->longest = nchars - longest;
Packit Service a8c26c
						break;
Packit Service a8c26c
					}
Packit Service a8c26c
					nbytes += n;
Packit Service a8c26c
					if ((c = sizeof(side) - o) > n)
Packit Service a8c26c
						c = n;
Packit Service a8c26c
					if (c)
Packit Service a8c26c
						memcpy(cp, buff, c);
Packit Service a8c26c
					endbuff = buff + n;
Packit Service a8c26c
					cp = side;
Packit Service a8c26c
					x = mbchar(cp);
Packit Service a8c26c
					if ((cp-side) < o)
Packit Service a8c26c
					{
Packit Service a8c26c
						cp = buff;
Packit Service a8c26c
						nchars += (cp-side) - 1;
Packit Service a8c26c
					}
Packit Service a8c26c
					else
Packit Service a8c26c
						cp = buff + (cp-side) - o;
Packit Service a8c26c
				}
Packit Service a8c26c
				else
Packit Service a8c26c
				{
Packit Service a8c26c
					cp++;
Packit Service a8c26c
					x = -1;
Packit Service a8c26c
				}
Packit Service a8c26c
				if (x == -1 && eline != nlines && !(wp->mode & WC_QUIET))
Packit Service a8c26c
					eline = invalid(file, nlines);
Packit Service a8c26c
			}
Packit Service a8c26c
			else
Packit Service a8c26c
				cp += n ? n : 1;
Packit Service a8c26c
			if (x == '\n')
Packit Service a8c26c
			{
Packit Service a8c26c
				if ((nchars - longest) > wp->longest)
Packit Service a8c26c
					wp->longest = nchars - longest;
Packit Service a8c26c
				longest = nchars + 1;
Packit Service a8c26c
				nlines++;
Packit Service a8c26c
				lasttype = 1;
Packit Service a8c26c
			}
Packit Service a8c26c
			else if (iswspace(x))
Packit Service a8c26c
				lasttype = 1;
Packit Service a8c26c
			else if (lasttype)
Packit Service a8c26c
			{
Packit Service a8c26c
				lasttype = 0;
Packit Service a8c26c
				nwords++;
Packit Service a8c26c
			}
Packit Service a8c26c
			nchars++;
Packit Service a8c26c
		}
Packit Service a8c26c
		if (!(wp->mode & WC_MBYTE))
Packit Service a8c26c
			nchars = nbytes;
Packit Service a8c26c
	}
Packit Service a8c26c
	else if (!wp->mb && !(wp->mode & WC_LONGEST) || wp->mb > 0 && !(wp->mode & (WC_MBYTE|WC_WORDS|WC_LONGEST)))
Packit Service a8c26c
	{
Packit Service a8c26c
		if (!(wp->mode & (WC_MBYTE|WC_WORDS|WC_LONGEST)))
Packit Service a8c26c
		{
Packit Service a8c26c
			while ((cp = (unsigned char*)sfreserve(fd, SF_UNBOUND, 0)) && (c = sfvalue(fd)) > 0)
Packit Service a8c26c
			{
Packit Service a8c26c
				nchars += c;
Packit Service a8c26c
				endbuff = cp + c;
Packit Service a8c26c
				if (*--endbuff == '\n')
Packit Service a8c26c
					nlines++;
Packit Service a8c26c
				else
Packit Service a8c26c
					*endbuff = '\n';
Packit Service a8c26c
				for (;;)
Packit Service a8c26c
					if (*cp++ == '\n')
Packit Service a8c26c
					{
Packit Service a8c26c
						if (cp > endbuff)
Packit Service a8c26c
							break;
Packit Service a8c26c
						nlines++;
Packit Service a8c26c
					}
Packit Service a8c26c
			}
Packit Service a8c26c
		}
Packit Service a8c26c
		else
Packit Service a8c26c
		{
Packit Service a8c26c
			while ((cp = buff = (unsigned char*)sfreserve(fd, SF_UNBOUND, 0)) && (c = sfvalue(fd)) > 0)
Packit Service a8c26c
			{
Packit Service a8c26c
				nchars += c;
Packit Service a8c26c
				/* check to see whether first character terminates word */
Packit Service a8c26c
				if (c==1)
Packit Service a8c26c
				{
Packit Service a8c26c
					if (eol(lasttype))
Packit Service a8c26c
						nlines++;
Packit Service a8c26c
					if ((c = type[*cp]) && !lasttype)
Packit Service a8c26c
						nwords++;
Packit Service a8c26c
					lasttype = c;
Packit Service a8c26c
					continue;
Packit Service a8c26c
				}
Packit Service a8c26c
				if (!lasttype && type[*cp])
Packit Service a8c26c
					nwords++;
Packit Service a8c26c
				lastchar = cp[--c];
Packit Service a8c26c
				*(endbuff = cp+c) = '\n';
Packit Service a8c26c
				c = lasttype;
Packit Service a8c26c
				/* process each buffer */
Packit Service a8c26c
				for (;;)
Packit Service a8c26c
				{
Packit Service a8c26c
					/* process spaces and new-lines */
Packit Service a8c26c
					do
Packit Service a8c26c
					{
Packit Service a8c26c
						if (eol(c))
Packit Service a8c26c
							for (;;)
Packit Service a8c26c
							{
Packit Service a8c26c
								/* check for end of buffer */
Packit Service a8c26c
								if (cp > endbuff)
Packit Service a8c26c
									goto beob;
Packit Service a8c26c
								nlines++;
Packit Service a8c26c
								if (*cp != '\n')
Packit Service a8c26c
									break;
Packit Service a8c26c
								cp++;
Packit Service a8c26c
							}
Packit Service a8c26c
					} while (c = type[*cp++]);
Packit Service a8c26c
					/* skip over word characters */
Packit Service a8c26c
					while (!(c = type[*cp++]));
Packit Service a8c26c
					nwords++;
Packit Service a8c26c
				}
Packit Service a8c26c
			beob:
Packit Service a8c26c
				if ((cp -= 2) >= buff)
Packit Service a8c26c
					c = type[*cp];
Packit Service a8c26c
				else
Packit Service a8c26c
					c = lasttype;
Packit Service a8c26c
				lasttype = type[lastchar];
Packit Service a8c26c
				/* see if was in word */
Packit Service a8c26c
				if (!c && !lasttype)
Packit Service a8c26c
					nwords--;
Packit Service a8c26c
			}
Packit Service a8c26c
			if (eol(lasttype))
Packit Service a8c26c
				nlines++;
Packit Service a8c26c
			else if (!lasttype)
Packit Service a8c26c
				nwords++;
Packit Service a8c26c
		}
Packit Service a8c26c
	}
Packit Service a8c26c
	else
Packit Service a8c26c
	{
Packit Service a8c26c
		int		lineoff=0;
Packit Service a8c26c
		int		skip=0;
Packit Service a8c26c
		int		adjust=0;
Packit Service a8c26c
		int		state=0;
Packit Service a8c26c
		int		oldc;
Packit Service a8c26c
		int		xspace;
Packit Service a8c26c
		int		wasspace = 1;
Packit Service a8c26c
		unsigned char*	start;
Packit Service a8c26c
Packit Service a8c26c
		lastchar = 0;
Packit Service a8c26c
		start = (endbuff = side) + 1;
Packit Service a8c26c
		xspace = iswspace(0xa0) || iswspace(0x85);
Packit Service a8c26c
		while ((cp = buff = (unsigned char*)sfreserve(fd, SF_UNBOUND, 0)) && (c = sfvalue(fd)) > 0)
Packit Service a8c26c
		{
Packit Service a8c26c
			nbytes += c;
Packit Service a8c26c
			nchars += c;
Packit Service a8c26c
			start = cp-lineoff;
Packit Service a8c26c
			/* check to see whether first character terminates word */
Packit Service a8c26c
			if(c==1)
Packit Service a8c26c
			{
Packit Service a8c26c
				if(eol(lasttype))
Packit Service a8c26c
					nlines++;
Packit Service a8c26c
				if((c = type[*cp]) && !lasttype)
Packit Service a8c26c
					nwords++;
Packit Service a8c26c
				lasttype = c;
Packit Service a8c26c
				endbuff = start;
Packit Service a8c26c
				continue;
Packit Service a8c26c
			}
Packit Service a8c26c
			lastchar = cp[--c];
Packit Service a8c26c
			endbuff = cp+c;
Packit Service a8c26c
			cp[c] = '\n';
Packit Service a8c26c
			if(mbc(lasttype))
Packit Service a8c26c
			{
Packit Service a8c26c
				c = lasttype;
Packit Service a8c26c
				goto mbyte;
Packit Service a8c26c
			}
Packit Service a8c26c
			if(!lasttype && spc(type[*cp]))
Packit Service a8c26c
				nwords++;
Packit Service a8c26c
			c = lasttype;
Packit Service a8c26c
			/* process each buffer */
Packit Service a8c26c
			for (;;)
Packit Service a8c26c
			{
Packit Service a8c26c
				/* process spaces and new-lines */
Packit Service a8c26c
			spaces:
Packit Service a8c26c
				do
Packit Service a8c26c
				{
Packit Service a8c26c
					if (eol(c))
Packit Service a8c26c
					{
Packit Service a8c26c
						/* check for end of buffer */
Packit Service a8c26c
						if (cp > endbuff)
Packit Service a8c26c
							goto eob;
Packit Service a8c26c
						if(wp->mode&WC_LONGEST)
Packit Service a8c26c
						{
Packit Service a8c26c
							if((cp-start)-adjust > longest)
Packit Service a8c26c
								longest = (cp-start)-adjust-1;
Packit Service a8c26c
							start = cp;
Packit Service a8c26c
						}
Packit Service a8c26c
						nlines++;
Packit Service a8c26c
						nchars -= adjust;
Packit Service a8c26c
						adjust = 0;
Packit Service a8c26c
					}
Packit Service a8c26c
				} while (spc(c = type[*cp++]));
Packit Service a8c26c
				wasspace=1;
Packit Service a8c26c
				if(mbc(c))
Packit Service a8c26c
				{
Packit Service a8c26c
				mbyte:
Packit Service a8c26c
					do
Packit Service a8c26c
					{
Packit Service a8c26c
						if(c&WC_ERR)
Packit Service a8c26c
							goto err;
Packit Service a8c26c
						if(skip && (c&7))
Packit Service a8c26c
							break;
Packit Service a8c26c
						if(!skip)
Packit Service a8c26c
						{
Packit Service a8c26c
							if(!(c&7))
Packit Service a8c26c
							{
Packit Service a8c26c
								skip=1;
Packit Service a8c26c
								break;
Packit Service a8c26c
							}
Packit Service a8c26c
							skip = (c&7;;
Packit Service a8c26c
							adjust += skip;
Packit Service a8c26c
							state = 0;
Packit Service a8c26c
							if(skip==2 && (cp[-1]&0xc)==0 && (state=(cp[-1]&0x3)))
Packit Service a8c26c
								oldc = *cp;
Packit Service a8c26c
							else if(xspace && cp[-1]==0xc2)
Packit Service a8c26c
							{
Packit Service a8c26c
								state = 8;
Packit Service a8c26c
								oldc = *cp;
Packit Service a8c26c
							}
Packit Service a8c26c
						}
Packit Service a8c26c
						else
Packit Service a8c26c
						{
Packit Service a8c26c
							skip--;
Packit Service a8c26c
							if(state && (state=chkstate(state,oldc)))
Packit Service a8c26c
							{
Packit Service a8c26c
								if(state==10)
Packit Service a8c26c
								{
Packit Service a8c26c
									if(!wasspace)
Packit Service a8c26c
										nwords++;
Packit Service a8c26c
									wasspace = 1;
Packit Service a8c26c
									state=0;
Packit Service a8c26c
									goto spaces;
Packit Service a8c26c
								}
Packit Service a8c26c
								oldc = *cp;
Packit Service a8c26c
							}
Packit Service a8c26c
						}
Packit Service a8c26c
					} while (mbc(c = type[*cp++]));
Packit Service a8c26c
					wasspace = 0;
Packit Service a8c26c
					if(skip)
Packit Service a8c26c
					{
Packit Service a8c26c
						if(eol(c) && (cp > endbuff))
Packit Service a8c26c
							goto eob;
Packit Service a8c26c
				err:
Packit Service a8c26c
						skip = 0;
Packit Service a8c26c
						state = 0;
Packit Service a8c26c
						if(eline!=nlines && !(wp->mode & WC_QUIET))
Packit Service a8c26c
							eline = invalid(file, nlines);
Packit Service a8c26c
						while(mbc(c) && ((c|WC_ERR) || (c&7)==0)) 
Packit Service a8c26c
							c=type[*cp++];
Packit Service a8c26c
						if(eol(c) && (cp > endbuff))
Packit Service a8c26c
						{
Packit Service a8c26c
							c = WC_MB|WC_ERR;
Packit Service a8c26c
							goto eob;
Packit Service a8c26c
						}
Packit Service a8c26c
						if(mbc(c))
Packit Service a8c26c
							goto mbyte;
Packit Service a8c26c
						else if(c&WC_SP)
Packit Service a8c26c
							goto spaces;
Packit Service a8c26c
					}
Packit Service a8c26c
					if(spc(c))
Packit Service a8c26c
					{
Packit Service a8c26c
						nwords++;
Packit Service a8c26c
						continue;
Packit Service a8c26c
					}
Packit Service a8c26c
				}
Packit Service a8c26c
				/* skip over word characters */
Packit Service a8c26c
				while(!(c = type[*cp++]));
Packit Service a8c26c
				if(mbc(c))
Packit Service a8c26c
					goto mbyte;
Packit Service a8c26c
				nwords++;
Packit Service a8c26c
			}
Packit Service a8c26c
		eob:
Packit Service a8c26c
			lineoff = cp-start;
Packit Service a8c26c
			if((cp -= 2) >= buff)
Packit Service a8c26c
				c = type[*cp];
Packit Service a8c26c
			else
Packit Service a8c26c
				c = lasttype;
Packit Service a8c26c
			lasttype = type[lastchar];
Packit Service a8c26c
			/* see if was in word */
Packit Service a8c26c
			if(!c && !lasttype)
Packit Service a8c26c
				nwords--;
Packit Service a8c26c
		}
Packit Service a8c26c
		if ((wp->mode&WC_LONGEST) && ((endbuff + 1 - start) - adjust - (lastchar == '\n')) > longest)
Packit Service a8c26c
			longest = (endbuff + 1 - start) - adjust - (lastchar == '\n');
Packit Service a8c26c
		wp->longest = longest;
Packit Service a8c26c
		if (eol(lasttype))
Packit Service a8c26c
			nlines++;
Packit Service a8c26c
		else if (!lasttype)
Packit Service a8c26c
			nwords++;
Packit Service a8c26c
		if (wp->mode & WC_MBYTE)
Packit Service a8c26c
			nchars -= adjust;
Packit Service a8c26c
		else
Packit Service a8c26c
			nchars = nbytes;
Packit Service a8c26c
	}
Packit Service a8c26c
	wp->chars = nchars;
Packit Service a8c26c
	wp->words = nwords;
Packit Service a8c26c
	wp->lines = nlines;
Packit Service a8c26c
	return 0;
Packit Service a8c26c
}
Packit Service a8c26c