/* Copyright 1985 by Lattice, Inc. */

#include "stdio.h"
#include "ctype.h"

#define VERSION	"1.00"
#define WHITE(x)	(x == ' ' || x == '\t' || x == '\n')

/*
 * Delete the _bufsiz definition when not using Lattice on MS-DOS, or
 * when compiling for non-MS-DOS operating system
 */

int _bufsiz = 4096;
static char *filename;
static char *ascii1 = "!@#$%^&*()_+1234567890-=qwertyuiop[]asdfghjkl;'`\\",
            *ascii2 = "zxcvbnm,./QWERTYUIOP{}ASDFGHJKL:\"~|ZXCVBNM<>?";
static int sflag = 0, pflag = 0;

main(argc,argv)
int argc;
char *argv[];
{	
   long c_count = 0L, w_count = 0L, l_count = 0L, sum = 0L, asnum = 0L;
   int c, oc;
   FILE *fp;

   parms(argc,argv);	/* parse command line and determine options */

   if ( (fp = fopen(filename,"r")) == NULL ) {
	fprintf(stderr,"Can't open %s\n",filename);
	exit(1);
   }

   oc = '\n';  /* initialize old character to end of line */
   while ( (c = pgetc(fp)) != EOF ) { /* get the next character */
	c_count++;
	if ( WHITE(c) ) { /* If it's white space */
		if ( ! WHITE(oc) ) /* and the previous one was non-white */
			w_count++; /* then you've seen another word */
		if ( c == '\n' )   /* If it's a newline */
			l_count++; /* then you've seen another line */
		else if (sflag) {
			asnum++;
			sum += asc(c);
		}
		while ( (c = pgetc(fp)) && WHITE(c) ) { /* scan to non-white */
			c_count++;
			if ( c == '\n' )
				l_count++;
			else if (sflag) {
				asnum++;
				sum += asc(c);
			}
		}
		if ( c != EOF )
			c_count++;
	}

	oc = c;  /* store old character */
   }

   fprintf(stderr,"Characters: %ld\n",c_count);
   fprintf(stderr,"     Words: %ld\n",w_count);
   fprintf(stderr,"     Lines: %ld\n",l_count);
   if ( sflag )
	fprintf(stderr,"\nSum: %ld %ld\n",asnum,sum);
   

}

/*
 * NAME:	parms -- parse command line and determine parameters
 *
 * SYNOPSIS:
 *		parms(argc, argv)
 *		
 * DESCRIPTION:
 *		Examine the command line for option flags and file names.
 *		Handle options and determine files to work on.
 *
 */

parms(argc, argv)
int argc;
char *argv[];
{  
   int i;

   if ( argc < 2 ) {
	usage();
	exit(1);
   }

   for ( i = 1; i < argc; i++ ) {

	 if ( argv[i][0] == '-' ) { /* option */

		switch ( argv[i][1] ) {
			case 'p': /* filter out non-printables */
				pflag = 1;
				break;
			case 's': /* compute sum */
				sflag = 1;
				break;

			default:
				fprintf(stderr,"Unrecognized option: %s\n",argv[i]);
				usage();
				exit(1);
		}
	 }
	 else
		break;
   }	 
   filename = argv[i];
}

 
/*
 * NAME:	usage -- print usage message
 *
 * SYNOPSIS:	usage()
 *
 * DESCRIPTION:
 *		Print a message describing usage of diff utility
 *
 */

usage()
{
	fprintf(stderr,"Lattice wc: Version %s Copyright (C) 1984\n",VERSION);
	fprintf(stderr,"usage: wc [-p] [-s] file\n");
}


/*
 * NAME:	asc -- assign number to ascii character
 *
 * SYNOPSIS:
 *		n = asc(c)
 *		int n;		representative number
 *		int c;		character to be mapped to number
 *
 * DESCRIPTION:
 *		This function maps the ASCII alphabet onto into a set of
 * 		integers beginning with 1 in a rather arbitrary way.  The
 *		only point is to be able to provide a machine independent
 *		checksum of a file.
 *
 */

asc(c)
int c;
{
   int i;
   char *a;

   a = ascii1;
   for ( i = 1; *a != NULL; i++ )
	 if ( *a++ == c )
		return(i);

   a = ascii2;
   while ( *a != NULL )
	 if ( *a++ == c )
		return(i);
	 else
		i++;

   return(0);
}

/*
 * name:	pgetc -- get a character from a file
 *
 * synopsis:	c = pgetc(fp)
 *		int c;		character returned
 *		FILE *fp;	file pointer to file being read
 *
 * description:
 *		Gets the next character from the designated file.
 *		If pflag is reset, that character is returned.  If
 *		pflag is set, the character is examined for
 *		"printability".  If it passes this test, the high
 *		bit is masked off and the result returned.
 *
 */

pgetc(fp)
FILE *fp;
{
   int c;

   while(1) {
	c = getc(fp);
	if ( !pflag )
	     return(c);
	if ( c == EOF )
	     return(c);
	if ( !isprint(c) && !isspace(c) )
	     continue;	/* skip over non-printables if pflag is set */
	else
	     return(c & 0x7F);
   }
}
