home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 300-399 / ff314.lha / zc / zc.lzh / Examples / Stdio / Wc / Wc.c < prev    next >
C/C++ Source or Header  |  1988-06-09  |  6KB  |  388 lines

  1. /*
  2.  *  wc [ -lwcp ] [ -spagesize ] [ -v ] [ files... ]
  3.  *
  4.  *  Count lines, words, characters, and pages.
  5.  *
  6.  *  Runs faster by doing less work if it doesn't have to count
  7.  *  all quantities.
  8.  *
  9.  *  Use this program as you wish, but please leave this header intact.
  10.  *
  11.  *  Steve Summit 12/4/84
  12.  */
  13.  
  14. #include <stdio.h>
  15.  
  16. #ifdef unix
  17. extern char *rindex();
  18. #else
  19. #define rindex strrchr
  20. extern char *strrchr();
  21. #endif
  22. extern char *strcat();
  23. extern char *strcpy();
  24.  
  25. #define TRUE 1
  26. #define FALSE 0
  27.  
  28. long int totchars = 0;
  29. long int totwords = 0;
  30. long int totlines = 0;
  31. long int totpages = 0;
  32.  
  33. #define LINES    04
  34. #define WORDS    02
  35. #define CHARS    01
  36.  
  37. int count = LINES | WORDS | CHARS;
  38. char want[10] = "lwc";
  39.  
  40. int verbose = FALSE;
  41.  
  42. int pagelen = 66;
  43.  
  44. int errs = 0;
  45.  
  46. int deflt = TRUE;
  47.  
  48. #define Isdigit(c) ((c) >= '0' && (c) <= '9')
  49. #define Ctod(c) ((c) - '0')
  50.  
  51. #ifdef unix
  52.  
  53. #define Append(mask, letter)    if(deflt)                \
  54.                     {                \
  55.                     count = mask;            \
  56.                     (void)strcpy(want, letter);    \
  57.                     deflt = FALSE;            \
  58.                     }                \
  59.                 else    {                \
  60.                     count |= mask;            \
  61.                     (void)strcat(want, letter);    \
  62.                     }
  63.  
  64. #define Append2(letter)        if(deflt)                \
  65.                     {                \
  66.                     (void)strcpy(want, letter);    \
  67.                     deflt = FALSE;            \
  68.                     }                \
  69.                 else    (void)strcat(want, letter)
  70.  
  71. #else
  72.  
  73. Append(mask, letter)
  74. {
  75.     if(deflt)
  76.     {
  77.         count = mask;
  78.         (void)strcpy(want, letter);
  79.         deflt = FALSE;
  80.     }
  81.     else
  82.     {
  83.         count |= mask;
  84.         (void)strcat(want, letter);
  85.     }
  86. }
  87.  
  88. Append2(letter)
  89. {
  90.     if(deflt)
  91.     {
  92.         (void)strcpy(want, letter);
  93.         deflt = FALSE;
  94.     }
  95.     else
  96.     {
  97.         (void)strcat(want, letter);
  98.     }
  99. }
  100.  
  101. #endif
  102.  
  103. char *progname = "wc";
  104.  
  105. main(argc, argv)
  106. int argc;
  107. char *argv[];
  108. {
  109. int fd;
  110. int argi;
  111. char *p;
  112. int totals;
  113.  
  114. if(argc > 0)
  115.     {
  116.     p = rindex(argv[0], '/');
  117.     if(p != NULL)
  118.         progname = p + 1;
  119.     else    progname = argv[0];
  120.     }
  121.  
  122. for(argi = 1; argi < argc && argv[argi][0] == '-'; argi++)
  123.     {
  124.     for(p = &argv[argi][1]; *p != '\0'; p++)
  125.         {
  126.         switch(*p)
  127.             {
  128.             case 'l':
  129.                 Append(LINES, "l");
  130.                 break;
  131.  
  132.             case 'w':
  133.                 Append(WORDS, "w");
  134.                 break;
  135.  
  136.             case 'c':
  137.                 Append(CHARS, "c");
  138.                 break;
  139.  
  140.             case 'p':
  141.                 Append2("p");
  142.                 break;
  143.  
  144.             case 'v':
  145.                 verbose = TRUE;
  146.                 if(deflt)
  147.                     (void)strcpy(want, "lwcp");
  148.                 break;
  149.  
  150.             case 's':
  151.                 pagelen = 0;
  152.                 while(Isdigit(*(p + 1)))
  153.                     pagelen = 10 * pagelen + Ctod(*++p);
  154.                 break;
  155.  
  156.             default:
  157.                 fprintf(stderr, "%s: unknown option -%c\n",
  158.                                 progname, *p);
  159.             }
  160.         }
  161.     }
  162.  
  163. if(verbose)
  164.     {
  165.     for(p = want; *p != '\0'; p++)
  166.         {
  167.         switch(*p)
  168.             {
  169.             case 'l':
  170.                 printf("   lines");
  171.                 break;
  172.  
  173.             case 'w':
  174.                 printf("   words");
  175.                 break;
  176.  
  177.             case 'c':
  178.                 printf("   chars");
  179.                 break;
  180.  
  181.             case 'p':
  182.                 printf("   pages");
  183.                 break;
  184.             }
  185.         }
  186.  
  187.     putchar('\n');
  188.     }
  189.  
  190. if(argi >= argc)
  191.     wc("", 0);
  192. else    {
  193.     totals = (argi + 1) < argc;
  194.  
  195.     for(; argi < argc; argi++)
  196.         {
  197.         if((fd = open(argv[argi], 0)) < 0)
  198.             {
  199.             fprintf(stderr, "%s: can't open %s\n", progname,
  200.                                 argv[argi]);
  201.             errs++;
  202.             continue;
  203.             }
  204.         wc(argv[argi], fd);
  205.         (void)close(fd);
  206.         }
  207.  
  208.     if(totals)
  209.         {
  210.         printit(totlines, totwords, totchars, totpages);
  211.         printf(" total\n");
  212.         }
  213.     }
  214.  
  215. exit(errs);
  216. }
  217.  
  218. #define Set(flag)    flag++
  219. #define Clear(flag)    flag = FALSE
  220.  
  221. #define Checkline()    if(*p == '\n')                    \
  222.                 lines++
  223.  
  224. #define Checkword()    if(' ' < *p && *p < '\177')            \
  225.                 {                    \
  226.                 if(!inword)                \
  227.                     {                \
  228.                     words++;            \
  229.                     Set(inword);            \
  230.                     }                \
  231.                 continue;                \
  232.                 }
  233.  
  234. #define Checkword2()    else if(*p != ' ' && *p != '\t')         \
  235.                 continue;                \
  236.             Clear(inword)
  237.  
  238. #define Checkword3()    if(*p == ' ' || *p == '\n' || *p == '\t')    \
  239.                 Clear(inword)
  240.  
  241. #define Dochars()    chars += r
  242.  
  243. wc(name, fd)
  244. char *name;
  245. int fd;
  246. {
  247. char buf[BUFSIZ];
  248. register char *bufend;
  249. int r;
  250. long int lines, words, chars, pages;
  251. register char *p;
  252. register int inword;
  253.  
  254. lines = words = chars = pages = 0;
  255.  
  256. Clear(inword);
  257.  
  258. switch(count)
  259.     {
  260.     case LINES:
  261.         while((r = read(fd, buf, BUFSIZ)) > 0)
  262.             {
  263.             bufend = buf + r;
  264.             for(p = buf; p < bufend; p++)
  265.                 Checkline();
  266.             }
  267.         break;
  268.  
  269.     case WORDS:
  270.         while((r = read(fd, buf, BUFSIZ)) > 0)
  271.             {
  272.             bufend = buf + r;
  273.             for(p = buf; p < bufend; p++)
  274.                 {
  275.                 Checkword();
  276.                 Checkword3();
  277.                 }
  278.             }
  279.         break;
  280.  
  281.     case CHARS:
  282.         while((r = read(fd, buf, BUFSIZ)) > 0)
  283.             Dochars();
  284.         break;
  285.  
  286.     case LINES|CHARS:
  287.         while((r = read(fd, buf, BUFSIZ)) > 0)
  288.             {
  289.             Dochars();
  290.  
  291.             bufend = buf + r;
  292.             for(p = buf; p < bufend; p++)
  293.                 Checkline();
  294.             }
  295.         break;
  296.  
  297.     case LINES|WORDS:
  298.         while((r = read(fd, buf, BUFSIZ)) > 0)
  299.             {
  300.             bufend = buf + r;
  301.             for(p = buf; p < bufend; p++)
  302.                 {
  303.                 Checkword();
  304.                 Checkline();
  305.                 Checkword2();
  306.                 }
  307.             }
  308.         break;
  309.  
  310.     case WORDS|CHARS:
  311.         while((r = read(fd, buf, BUFSIZ)) > 0)
  312.             {
  313.             Dochars();
  314.  
  315.             bufend = buf + r;
  316.             for(p = buf; p < bufend; p++)
  317.                 {
  318.                 Checkword();
  319.                 Checkword3();
  320.                 }
  321.             }
  322.         break;
  323.  
  324.     case LINES|WORDS|CHARS:
  325.         while((r = read(fd, buf, BUFSIZ)) > 0)
  326.             {
  327.             Dochars();
  328.  
  329.             bufend = buf + r;
  330.             for(p = buf; p < bufend; p++)
  331.                 {
  332.                 Checkword();
  333.                 Checkline();
  334.                 Checkword2();
  335.                 }
  336.             }
  337.         break;
  338.     }
  339.  
  340. if(r < 0)
  341.     {
  342.     fprintf(stderr, "%s: %s: read error\n", progname,
  343.                 *name != '\0' ? name : "standard input");
  344.     errs++;
  345.     }
  346.  
  347. pages = lines / pagelen + (lines % pagelen != 0 ? 1 : 0);
  348.  
  349. printit(lines, words, chars, pages);
  350.  
  351. if(*name != '\0')
  352.     printf(" %s", name);
  353. putchar('\n');
  354.  
  355. totlines += lines;
  356. totwords += words;
  357. totchars += chars;
  358. totpages += pages;
  359. }
  360.  
  361. printit(lines, words, chars, pages)
  362. long int lines, words, chars, pages;
  363. {
  364. char *p;
  365.  
  366. for(p = want; *p != '\0'; p++)
  367.     {
  368.     switch(*p)
  369.         {
  370.         case 'l':
  371.             printf(" %7ld", lines);
  372.             break;
  373.  
  374.         case 'w':
  375.             printf(" %7ld", words);
  376.             break;
  377.  
  378.         case 'c':
  379.             printf(" %7ld", chars);
  380.             break;
  381.  
  382.         case 'p':
  383.             printf(" %7ld", pages);
  384.             break;
  385.         }
  386.     }
  387. }
  388.