home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************/
- /* Count the characters, words and lines in a file. */
- /* */
- /* By David Megginson, 1991 */
- /* Released into the public domain. */
- /* */
- /* Command line options: */
- /* -c Count characters */
- /* -w Count words */
- /* -l Count lines */
- /* (count everything by default) */
- /* */
- /* Makefile options: */
- /* -DBUFFER_SIZE=n Read n bytes at a time */
- /* -DSKIP_CR Ignore carriage returns */
- /****************************************************************/
-
-
- /* $Id: wc.c,v 1.2 1991/03/05 09:02:30 david Exp david $ */
-
- /*
- * $Log: wc.c,v $
- * Revision 1.2 1991/03/05 09:02:30 david
- * Changed `static version' to `static char * version' (duh!)
- *
- * Revision 1.1 1991/03/05 08:59:46 david
- * Initial revision
- *
- */
-
- static char * version = "$Id: wc.c,v 1.2 1991/03/05 09:02:30 david Exp david $";
-
-
- #include <stdio.h>
- #include <stddef.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <errno.h>
-
- /* The string of legal options for getopt */
-
- #define OPTSTRING "clw"
-
- /* The size of the read() buffer. Allow the user to define */
- /* this in the Makefile if desired. */
-
- #ifndef BUFFER_SIZE
- #define BUFFER_SIZE 50000L
- #endif
-
- /* Use this buffer to read in the file */
-
- static char buffer[BUFFER_SIZE];
-
- /* Number of files read so far, and running totals */
-
- static int total_files = 0;
- static long total_characters = 0;
- static long total_words = 0;
- static long total_lines = 0;
-
- /* Flags controlled by command-line options */
-
- static int all_flag = 1; /* count everything (default) */
- static int c_flag = 0; /* count characters */
- static int w_flag = 0; /* count words */
- static int l_flag = 0; /* count lines */
- static int whitespace_flag = 1; /* whitespace seen */
- static int nl_flag = 0; /* newline seen */
-
- /* getopt() stuff */
-
- extern int optind;
-
- /* Local functions */
-
- static void do_file( const char * filename,int fd );
- static void count_buffer( long * c,long * w,long * l,fpos_t length );
- static void show_results( long c,long w,long l,const char * filename );
- static void show_totals( void );
-
-
- main( int ac,const char ** av )
- {
- int opt,current,fd;
-
- opt = getopt(ac,av,OPTSTRING);
- while( opt != EOF ) {
- switch( opt ) {
-
- case 'c':
- all_flag = 0;
- c_flag = 1;
- break;
- case 'l':
- all_flag = 0;
- l_flag = 1;
- break;
- case 'w':
- all_flag = 0;
- w_flag = 1;
- break;
- }
- opt = getopt(ac,av,OPTSTRING);
- }
-
- if( optind == ac ) {
- do_file(NULL,0);
- } else for( current = optind; current < ac; current++ ) {
- if( !strcmp(av[current],"-") )
- do_file(av[current],0);
- else {
- fd = open(av[current],O_RDONLY);
- if( fd < 0 ) {
- perror(av[current]);
- exit(1);
- }
- do_file(av[current],fd);
- close(fd);
- }
- }
-
- if( total_files > 1 )
- show_totals();
- return 0;
- }
-
-
- /*******
- Count the words in a single file.
-
- Arguments: const char * filename the file name
- int fd the file descriptor
- Return value: none
- *******/
-
- static void
- do_file( const char * filename,int fd )
- {
- fpos_t total_read;
- long c=0, w=0, l=0;
-
- whitespace_flag = 1;
- total_files++;
-
- do {
- total_read = read(fd,buffer,BUFFER_SIZE);
- #if DEBUG
- printf("Read %ld characters from %s\n",total_read,filename?filename:"stdin");
- #endif
- if( total_read > 0 )
- count_buffer(&c,&w,&l,total_read);
- } while( total_read == BUFFER_SIZE );
-
- /* if the file ended on a word, count that word too */
-
- if( !whitespace_flag )
- w++;
-
- /* if the last character was not NL, count the last */
- /* line */
-
- if( !nl_flag )
- l++;
-
- show_results(c,w,l,filename);
-
- total_characters += c;
- total_words += w;
- total_lines += l;
- }
-
-
- /*******
- Count the buffer itself.
-
- Arguments: long * c characters
- long * w words
- long * l lines
- fpos_t length characters in buffer
- Return value: none
- *******/
-
- void
- count_buffer( long * c,long * w,long * l,fpos_t length )
- {
- fpos_t pos;
-
- for( pos = 0; pos < length; pos++ ) {
-
- switch( buffer[pos] ) {
- #ifdef SKIP_CR
- case '\r':
- break;
- #endif
- case '\n':
- (*l)++;
- if( !whitespace_flag )
- (*w)++;
- whitespace_flag = 1;
- nl_flag = 1;
- break;
- case ' ':
- case '\t':
- if( !whitespace_flag )
- (*w)++;
- whitespace_flag = 1;
- break;
- default:
- whitespace_flag = 0;
- break;
- }
-
- /* Always count a character */
-
- (*c)++;
- }
- }
-
-
- /*******
- Show the results for a file.
-
- Arguments: long c characters
- long w words
- long l lines
- const char * filename
- Return value: none
- *******/
-
- void
- show_results( long c,long w,long l,const char * filename )
- {
- if( all_flag || l_flag )
- printf("%10ld",l);
- if( all_flag || w_flag )
- printf("%10ld",w);
- if( all_flag || c_flag )
- printf("%10ld",c);
- if( filename )
- printf(" %s",filename);
- printf("\n");
- }
-
- /*******
- Show the final total for more than one file.
-
- Arguments: none
- Return value: none
- *******/
-
- void
- show_totals()
- {
- if( all_flag || l_flag )
- printf("%10ld",total_lines);
- if( all_flag || w_flag )
- printf("%10ld",total_words);
- if( all_flag || c_flag )
- printf("%10ld",total_characters);
- printf(" TOTAL\n");
- }
-
-
-