[BACK]Return to wc.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / wc

Diff for /src/usr.bin/wc/wc.c between version 1.2 and 1.3

version 1.2, 1996/06/26 05:42:50 version 1.3, 1999/02/02 03:44:07
Line 1 
Line 1 
 /*      $OpenBSD$       */  /*      $OpenBSD$       */
   
 /*  /*
  * Copyright (c) 1980, 1987 Regents of the University of California.   * Copyright (c) 1980, 1987, 1991, 1993
  * All rights reserved.   *      The Regents of the University of California.  All rights reserved.
  *   *
  * Redistribution and use in source and binary forms, with or without   * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions   * modification, are permitted provided that the following conditions
Line 34 
Line 34 
  */   */
   
 #ifndef lint  #ifndef lint
 char copyright[] =  static char copyright[] =
 "@(#) Copyright (c) 1980, 1987 Regents of the University of California.\n\  "@(#) Copyright (c) 1980, 1987, 1991, 1993\n\
  All rights reserved.\n";          The Regents of the University of California.  All rights reserved.\n";
 #endif /* not lint */  #endif /* not lint */
   
 #ifndef lint  #ifndef lint
 /*static char sccsid[] = "from: @(#)wc.c        5.7 (Berkeley) 3/2/91";*/  #if 0
   static char sccsid[] = "@(#)wc.c        8.2 (Berkeley) 5/2/95";
   #else
 static char rcsid[] = "$OpenBSD$";  static char rcsid[] = "$OpenBSD$";
   #endif
 #endif /* not lint */  #endif /* not lint */
   
 /* wc line, word and char count */  
   
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
 #include <locale.h>  #include <locale.h>
 #include <ctype.h>  #include <ctype.h>
 #include <errno.h>  #include <err.h>
 #include <sys/param.h>  #include <sys/param.h>
 #include <sys/stat.h>  #include <sys/stat.h>
 #include <sys/file.h>  #include <sys/file.h>
 #include <unistd.h>  #include <unistd.h>
 #include <err.h>  
   
 static void     print_counts();  int64_t tlinect, twordct, tcharct;
 static void     cnt();  int     doline, doword, dochar;
 static long     tlinect, twordct, tcharct;  int     rval;
 static int      doline, doword, dochar;  extern char *__progname;
 static int      rval = 0;  
   
   void    print_counts __P((int64_t, int64_t, int64_t, char *));
   void    cnt __P((char *));
   
 int  int
 main(argc, argv)  main(argc, argv)
         int argc;          int argc;
         char **argv;          char *argv[];
 {  {
         extern int optind;  
         register int ch;          register int ch;
   
         setlocale(LC_ALL, "");          setlocale(LC_ALL, "");
Line 88 
Line 89 
                         break;                          break;
                 case '?':                  case '?':
                 default:                  default:
                         fprintf(stderr, "usage: wc [-c | -m] [-lw] [file ...]\n");                          (void)fprintf(stderr,
                               "usage: %s [-c | -m] [-lw] [file ...]\n",
                               __progname);
                         exit(1);                          exit(1);
                 }                  }
         argv += optind;          argv += optind;
Line 99 
Line 102 
          * if you don't get any arguments, you have to turn them           * if you don't get any arguments, you have to turn them
          * all on.           * all on.
          */           */
         if (!doline && !doword && !dochar) {          if (!doline && !doword && !dochar)
                 doline = doword = dochar = 1;                  doline = doword = dochar = 1;
         }  
   
         if (!*argv) {          if (!*argv) {
                 cnt((char *)NULL);                  cnt((char *)NULL);
Line 112 
Line 114 
                         cnt(*argv);                          cnt(*argv);
                 } while(*++argv);                  } while(*++argv);
   
                 if (dototal) {                  if (dototal)
                         print_counts (tlinect, twordct, tcharct, "total");                          print_counts(tlinect, twordct, tcharct, "total");
                 }  
         }          }
   
         exit(rval);          exit(rval);
 }  }
   
   void
 static void  
 cnt(file)  cnt(file)
         char *file;          char *file;
 {  {
         register u_char *C;          register u_char *C;
         register short gotsp;          register short gotsp;
         register int len;          register int len;
         register long linect, wordct, charct;          register int64_t linect, wordct, charct;
         struct stat sbuf;          struct stat sbuf;
         int fd;          int fd;
         u_char buf[MAXBSIZE];          u_char buf[MAXBSIZE];
Line 136 
Line 136 
         linect = wordct = charct = 0;          linect = wordct = charct = 0;
         if (file) {          if (file) {
                 if ((fd = open(file, O_RDONLY, 0)) < 0) {                  if ((fd = open(file, O_RDONLY, 0)) < 0) {
                         warn ("%s", file);                          warn("%s", file);
                         rval = 1;                          rval = 1;
                         return;                          return;
                 }                  }
Line 146 
Line 146 
   
         if (!doword) {          if (!doword) {
                 /*                  /*
                  * line counting is split out because it's a lot                   * Line counting is split out because it's a lot
                  * faster to get lines than to get words, since                   * faster to get lines than to get words, since
                  * the word count requires some logic.                   * the word count requires some logic.
                  */                   */
                 if (doline) {                  if (doline) {
                         while((len = read(fd, buf, MAXBSIZE)) > 0) {                          while ((len = read(fd, buf, MAXBSIZE)) > 0) {
                                 charct += len;                                  charct += len;
                                 for (C = buf; len--; ++C)                                  for (C = buf; len--; ++C)
                                         if (*C == '\n')                                          if (*C == '\n')
                                                 ++linect;                                                  ++linect;
                         }                          }
                         if (len == -1) {                          if (len == -1) {
                                 warn ("%s", file);                                  warn("%s", file);
                                 rval = 1;                                  rval = 1;
                         }                          }
                 }                  }
   
                 /*                  /*
                  * if all we need is the number of characters and                   * If all we need is the number of characters and
                  * it's a directory or a regular or linked file, just                   * it's a directory or a regular or linked file, just
                  * stat the puppy.  We avoid testing for it not being                   * stat the puppy.  We avoid testing for it not being
                  * a special device in case someone adds a new type                   * a special device in case someone adds a new type
                  * of inode.                   * of inode.
                  */                   */
                 else if (dochar) {                  else if (dochar) {
                         int ifmt;                          mode_t ifmt;
   
                         if (fstat(fd, &sbuf)) {                          if (fstat(fd, &sbuf)) {
                                 warn ("%s", file);                                  warn("%s", file);
                                 rval = 1;                                  rval = 1;
                         } else {                          } else {
                                 ifmt = sbuf.st_mode & S_IFMT;                                  ifmt = sbuf.st_mode & S_IFMT;
                                 if (ifmt == S_IFREG || ifmt == S_IFLNK                                  if (ifmt == S_IFREG || ifmt == S_IFLNK
                                         || ifmt == S_IFDIR) {                                      || ifmt == S_IFDIR) {
                                         charct = sbuf.st_size;                                          charct = sbuf.st_size;
                                 } else {                                  } else {
                                         while((len = read(fd, buf, MAXBSIZE)) > 0)                                          while ((len = read(fd, buf, MAXBSIZE)) > 0)
                                                 charct += len;                                                  charct += len;
                                         if (len == -1) {                                          if (len == -1) {
                                                 warn ("%s", file);                                                  warn("%s", file);
                                                 rval = 1;                                                  rval = 1;
                                         }                                          }
                                 }                                  }
                         }                          }
                 }                  }
         }          } else {
         else                  /* Do it the hard way... */
         {  
                 /* do it the hard way... */  
                 gotsp = 1;                  gotsp = 1;
                 while ((len = read(fd, buf, MAXBSIZE)) > 0) {                  while ((len = read(fd, buf, MAXBSIZE)) > 0) {
                           /*
                            * This loses in the presence of multi-byte characters.
                            * To do it right would require a function to return a
                            * character while knowing how many bytes it consumed.
                            */
                         charct += len;                          charct += len;
                         for (C = buf; len--; ++C) {                          for (C = buf; len--; ++C) {
                                 if (isspace (*C)) {                                  if (isspace (*C)) {
                                         gotsp = 1;                                          gotsp = 1;
                                         if (*C == '\n') {                                          if (*C == '\n')
                                                 ++linect;                                                  ++linect;
                                         }  
                                 } else {                                  } else {
                                         /*                                          /*
                                          * This line implements the POSIX                                           * This line implements the POSIX
Line 221 
Line 222 
                         }                          }
                 }                  }
                 if (len == -1) {                  if (len == -1) {
                         warn ("%s", file);                          warn("%s", file);
                         rval = 1;                          rval = 1;
                 }                  }
         }          }
   
         print_counts (linect, wordct, charct, file ? file : "");          print_counts(linect, wordct, charct, file ? file : "");
   
         /* don't bother checkint doline, doword, or dochar --- speeds          /*
            up the common case */           * Don't bother checking doline, doword, or dochar -- speeds
            * up the common case
            */
         tlinect += linect;          tlinect += linect;
         twordct += wordct;          twordct += wordct;
         tcharct += charct;          tcharct += charct;
   
         if (close(fd)) {          if (close(fd) != 0) {
                 warn ("%s", file);                  warn("%s", file);
                 rval = 1;                  rval = 1;
         }          }
 }  }
   
   
 void  void
 print_counts (lines, words, chars, name)  print_counts(lines, words, chars, name)
         long lines;          int64_t lines;
         long words;          int64_t words;
         long chars;          int64_t chars;
         char *name;          char *name;
 {  {
   
         if (doline)          if (doline)
                 printf(" %7ld", lines);                  (void)printf(" %7qd", (quad_t) lines);
         if (doword)          if (doword)
                 printf(" %7ld", words);                  (void)printf(" %7qd", (quad_t) words);
         if (dochar)          if (dochar)
                 printf(" %7ld", chars);                  (void)printf(" %7qd", (quad_t) chars);
   
         printf (" %s\n", name);          (void)printf(" %s\n", name);
 }  }

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3