home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 329_01 / wc.c < prev    next >
C/C++ Source or Header  |  1988-12-16  |  4KB  |  208 lines

  1. /*-
  2.  * wc - word count
  3.  *
  4.  * Usage: wc [-lwc] [file...]
  5.  *
  6.  * Count lines, words, and characters in the named files or stdin.
  7.  * Words are delimited by spaces, tabs, or newlines.  Default action is
  8.  * -lwc. 
  9.  *
  10.  * Flags:
  11.  * -l   display number of lines
  12.  * -w   display number of words
  13.  * -c   display number of characters
  14.  *
  15.  * This program is in the public domain.
  16.  * David MacKenzie
  17.  * 6522 Elgin Lane
  18.  * Bethesda, MD 20817
  19.  *
  20.  * Latest revision: 04/23/88
  21. **
  22. **    Roberto Artigas Jr
  23. **    P.O. Box 281415
  24. **    Memphis, TN 38168-1415
  25. **    work: 901-762-6092
  26. **    home: 901-373-4738
  27. **
  28. **    1988.12.14 - Get to run under OS/2.
  29. **        Used C/2 version 1.10 under OS/2 E 1.1
  30. **        cl -c -AL wc.c
  31. **        link wc,/noi,wc,llibce+os2, ;
  32. **+
  33. */
  34. #define    CPM    0
  35. #define    DOS    0
  36. #define    OS2    1
  37.  
  38. #include    <stdio.h>
  39.  
  40. #if    CPM
  41. extern int errno;
  42. #endif
  43.  
  44. #if    DOS || OS2
  45. #define    agetc    getc
  46. #include    <ctype.h>
  47. #include    <stdlib.h>
  48. #include    <string.h>
  49. #endif
  50.  
  51.  
  52. /* Totals in case multiple files are specified. */
  53. long totnlines = 0L;
  54. long totnwords = 0L;
  55. long totnchars = 0L;
  56.  
  57. int nfiles = 0;                   /* Number of files specified. */
  58.  
  59. main(argc, argv)
  60. int argc;
  61. char **argv;
  62. {
  63.     void wc();
  64.     int lines = 0;               /* Count lines? */
  65.     int words = 0;               /* Count words? */
  66.     int chars = 0;               /* Count chars? */
  67.     int optind;                   /* Loop index. */
  68.  
  69.     for (optind = 1; optind < argc && *argv[optind] == '-'; ++optind)
  70.     while (*++argv[optind])
  71.         switch (*argv[optind])
  72.         {
  73.         case 'l':
  74.         lines = 1;
  75.         break;
  76.         case 'w':
  77.         words = 1;
  78.         break;
  79.         case 'c':
  80.         chars = 1;
  81.         break;
  82.         default:
  83.         fprintf(stderr, "Usage: wc [-lwc] [file...]\n");
  84.         exit(1);
  85.         }
  86.  
  87.     if (lines + words + chars == 0)
  88.     lines = words = chars = 1;
  89.  
  90.     if (optind == argc)
  91.     {
  92.     wc("-", lines, words, chars);
  93.     exit(0);
  94.     }
  95.     for (; optind < argc; ++optind)
  96.     wc(argv[optind], lines, words, chars);
  97.  
  98.     if (nfiles > 1)
  99.     {
  100.     if (lines)
  101.         printf("%8ld", totnlines);
  102.     if (words)
  103.         printf("%8ld", totnwords);
  104.     if (chars)
  105.         printf("%8ld", totnchars);
  106.     printf(" total\n");
  107.     }
  108.     return (0);
  109.     exit(0);
  110. }
  111. /*
  112.  * Calculate and output the specified counts. 
  113.  */
  114.  
  115. void
  116. wc(file, lines, words, chars)
  117. char *file;
  118. char lines,
  119.  words,
  120.  chars;
  121. {
  122.     char *normalize();
  123.     FILE *fp;                   /* Input file pointer. */
  124.     int c;                   /* One byte of input. */
  125.     long nlines = 0L;               /* Number of lines in current file. */
  126.     long nwords = 0L;               /* Ditto for words. */
  127.     long nchars = 0L;               /* Ditto for characters. */
  128.     char inword = 0;               /* Were we in a word before this
  129.                         * char? */
  130.  
  131.     ++nfiles;
  132.     if (!strcmp(file, "-"))
  133.     fp = stdin;
  134. #if    DOS || OS2
  135.     else
  136.     if (!(fp = fopen(file, "rb")))
  137.     {
  138. #else
  139.     else
  140.     if (!(fp = fopen(file, "r")))
  141.     {
  142. #endif
  143.     perror(file);
  144.     return;
  145.     }
  146.     while ((c = agetc(fp)) != EOF)
  147.     {
  148.     ++nchars;
  149.     switch (c)
  150.     {
  151.     case '\n':
  152.         ++nlines;
  153.         /* Fall through. */
  154.     case '\t':
  155.     case ' ':
  156.         if (inword)
  157.         ++nwords;
  158.         inword = 0;
  159.         break;
  160.     default:
  161.         inword = 1;
  162.         break;
  163.     }
  164.     }
  165.  
  166.     if (inword)
  167.     {
  168.     ++nlines;
  169.     ++nwords;
  170.     }
  171.     totnlines += nlines;
  172.     totnwords += nwords;
  173.     totnchars += nchars;
  174.  
  175.     if (lines)
  176.     printf("%8ld", nlines);
  177.     if (words)
  178.     printf("%8ld", nwords);
  179.     if (chars)
  180.     printf("%8ld", nchars);
  181.     if (fp != stdin)
  182.     printf(" %s", normalize(file));
  183.     printf("\n");
  184.  
  185.     if (fp != stdin)
  186.     (void) fclose(fp);
  187. }
  188. /*
  189.  * Convert uppercase letters to lowercase, and non-graphic characters to
  190.  * '?'. 
  191.  */
  192.  
  193. char *
  194. normalize(s)
  195. char *s;
  196. {
  197.     char *t;
  198.  
  199.     for (t = s; *t; ++t)
  200.     if (!isascii(*t) || !isgraph(*t))
  201.         *t = '?';
  202.     else
  203.     if (isupper(*t) && *t != '_')
  204.         /* Aztec C's ctype thinks that isupper('_') is true . . . */
  205.         *t = tolower(*t);
  206.     return s;
  207. }
  208.