bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

coreutils int cleanups for uniq, wc, who, whoami


From: Paul Eggert
Subject: coreutils int cleanups for uniq, wc, who, whoami
Date: Tue, 03 Aug 2004 16:43:36 -0700
User-agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3 (gnu/linux)

This upgrades uniq -c to support line counts up to 2**64 on modern
hosts (instead of the old 2**31).  It also reports any line number
overflows now.  Also, a "whoami" diagnostic for invalid uids can now
print uids up to ULONG_MAX, not merely UINT_MAX.

2004-08-03  Paul Eggert  <address@hidden>

        * src/uniq.c (hard_LC_COLLATE, ignore_case, different, check_file,
        main): Use bool for booleans.
        (writeline, check_file): Use uintmax_t for line counts.
        (check_file): Check for and report line number overflow,
        when that matters.
        * src/wc.c (iswspace, wc): Use to_uchar rather than a cast.
        (print_lines, print_words, print_chars, print_bytes, print_linelength,
        have_read_stdin, wc, wc_file, main):
        Use bool for booleans.
        (exit_status): Remove.
        (wc, wc_file): Return bool status.  All callers changed.
        * src/who.c (scan_entries): 0 -> STDIN_FILENO.
        * src/whoami.c (main): Print uids using unsigned long int, not
        unsigned int.

Index: src/uniq.c
===================================================================
RCS file: /home/eggert/coreutils/cu/src/uniq.c,v
retrieving revision 1.111
diff -p -u -r1.111 uniq.c
--- src/uniq.c  21 Jun 2004 15:03:35 -0000      1.111
+++ src/uniq.c  20 Jul 2004 05:15:24 -0000
@@ -52,8 +52,8 @@
 /* The name this program was run with. */
 char *program_name;
 
-/* Nonzero if the LC_COLLATE locale is hard.  */
-static int hard_LC_COLLATE;
+/* True if the LC_COLLATE locale is hard.  */
+static bool hard_LC_COLLATE;
 
 /* Number of fields to skip on each line when doing comparisons. */
 static size_t skip_fields;
@@ -81,8 +81,8 @@ static bool output_unique;
 static bool output_first_repeated;
 static bool output_later_repeated;
 
-/* If nonzero, ignore case when comparing.  */
-static int ignore_case;
+/* If true, ignore case when comparing.  */
+static bool ignore_case;
 
 enum delimit_method
 {
@@ -210,12 +210,12 @@ find_field (const struct linebuffer *lin
   return lp + i;
 }
 
-/* Return zero if two strings OLD and NEW match, nonzero if not.
+/* Return false if two strings OLD and NEW match, true if not.
    OLD and NEW point not to the beginnings of the lines
    but rather to the beginnings of the fields to compare.
    OLDLEN and NEWLEN are their lengths. */
 
-static int
+static bool
 different (char *old, char *new, size_t oldlen, size_t newlen)
 {
   if (check_chars < oldlen)
@@ -229,7 +229,7 @@ different (char *old, char *new, size_t 
       return oldlen != newlen || memcasecmp (old, new, oldlen);
     }
   else if (HAVE_SETLOCALE && hard_LC_COLLATE)
-    return xmemcoll (old, oldlen, new, newlen);
+    return xmemcoll (old, oldlen, new, newlen) != 0;
   else
     return oldlen != newlen || memcmp (old, new, oldlen);
 }
@@ -242,7 +242,7 @@ different (char *old, char *new, size_t 
 
 static void
 writeline (struct linebuffer const *line, FILE *stream,
-          bool match, int linecount)
+          bool match, uintmax_t linecount)
 {
   if (! (linecount == 0 ? output_unique
         : !match ? output_first_repeated
@@ -250,7 +250,7 @@ writeline (struct linebuffer const *line
     return;
 
   if (countmode == count_occurrences)
-    fprintf (stream, "%7d ", linecount + 1);
+    fprintf (stream, "%7" PRIuMAX " ", linecount + 1);
 
   fwrite (line->buffer, sizeof (char), line->length, stream);
 }
@@ -322,8 +322,8 @@ check_file (const char *infile, const ch
     {
       char *prevfield;
       size_t prevlen;
-      int match_count = 0;
-      int first_delimiter = 1;
+      uintmax_t match_count = 0;
+      bool first_delimiter = true;
 
       if (readlinebuffer (prevline, istream) == 0)
        goto closefiles;
@@ -344,16 +344,21 @@ check_file (const char *infile, const ch
          thisfield = find_field (thisline);
          thislen = thisline->length - 1 - (thisfield - thisline->buffer);
          match = !different (thisfield, prevfield, thislen, prevlen);
+         match_count += match;
 
-         if (match)
-           ++match_count;
+         if (match_count == UINTMAX_MAX)
+           {
+             if (count_occurrences)
+               error (EXIT_FAILURE, 0, _("too many repeated lines"));
+             match_count--;
+           }
 
           if (delimit_groups != DM_NONE)
            {
              if (!match)
                {
                  if (match_count) /* a previous match */
-                   first_delimiter = 0; /* Only used when DM_SEPARATE */
+                   first_delimiter = false; /* Only used when DM_SEPARATE */
                }
              else if (match_count == 1)
                {
@@ -506,7 +511,7 @@ main (int argc, char **argv)
          break;
 
        case 'i':
-         ignore_case = 1;
+         ignore_case = true;
          break;
 
        case 's':               /* Like '+#'. */
@@ -535,7 +540,7 @@ main (int argc, char **argv)
   if (obsolete_skip_fields && 200112 <= posix2_version ())
     {
       error (0, 0, _("`-%lu' option is obsolete; use `-f %lu'"),
-            (unsigned long) skip_fields, (unsigned long) skip_fields);
+            (unsigned long int) skip_fields, (unsigned long int) skip_fields);
       usage (EXIT_FAILURE);
     }
 
Index: src/wc.c
===================================================================
RCS file: /home/eggert/coreutils/cu/src/wc.c,v
retrieving revision 1.99
diff -p -u -r1.99 wc.c
--- src/wc.c    6 May 2004 14:23:08 -0000       1.99
+++ src/wc.c    20 Jul 2004 03:39:17 -0000
@@ -38,7 +38,7 @@
 #endif
 #if !defined iswspace && !HAVE_ISWSPACE
 # define iswspace(wc) \
-    ((wc) == (unsigned char) (wc) && ISSPACE ((unsigned char) (wc)))
+    ((wc) == to_uchar (wc) && ISSPACE (to_uchar (wc)))
 #endif
 
 /* Include this after wctype.h so that we `#undef' ISPRINT
@@ -88,17 +88,14 @@ static uintmax_t total_bytes;
 static uintmax_t max_line_length;
 
 /* Which counts to print. */
-static int print_lines, print_words, print_chars, print_bytes;
-static int print_linelength;
+static bool print_lines, print_words, print_chars, print_bytes;
+static bool print_linelength;
 
 /* The print width of each count.  */
 static int number_width;
 
-/* Nonzero if we have ever read the standard input. */
-static int have_read_stdin;
-
-/* The error code to return to the system. */
-static int exit_status;
+/* True if we have ever read the standard input. */
+static bool have_read_stdin;
 
 /* The result of calling fstat or stat on a file descriptor or file.  */
 struct fstatus
@@ -198,15 +195,17 @@ write_counts (uintmax_t lines,
   putchar ('\n');
 }
 
-/* FILE_X is the name of the file (or NULL for standard input) that is
-   open on descriptor FD.  */
-static void
+/* Count words.  FILE_X is the name of the file (or NULL for standard
+   input) that is open on descriptor FD.  *FSTATUS is its status.
+   Return true if successful.  */
+static bool
 wc (int fd, char const *file_x, struct fstatus *fstatus)
 {
+  bool ok = true;
   char buf[BUFFER_SIZE + 1];
   size_t bytes_read;
   uintmax_t lines, words, chars, bytes, linelength;
-  int count_bytes, count_chars, count_complicated;
+  bool count_bytes, count_chars, count_complicated;
   char const *file = file_x ? file_x : _("standard input");
 
   lines = words = chars = bytes = linelength = 0;
@@ -222,10 +221,10 @@ wc (int fd, char const *file_x, struct f
   else
 #endif
     {
-      count_bytes = print_bytes + print_chars;
-      count_chars = 0;
+      count_bytes = print_bytes | print_chars;
+      count_chars = false;
     }
-  count_complicated = print_words + print_linelength;
+  count_complicated = print_words | print_linelength;
 
   /* We need binary input, since `wc' relies on `lseek' and byte counts.  */
   SET_BINARY (fd);
@@ -240,7 +239,7 @@ wc (int fd, char const *file_x, struct f
      `(dd ibs=99k skip=1 count=0; ./wc -c) < /etc/group'
      should make wc report `0' bytes.  */
 
-  if (count_bytes && !count_chars && !print_lines && !count_complicated)
+  if (count_bytes & !count_chars & !print_lines & !count_complicated)
     {
       off_t current_pos, end_pos;
 
@@ -262,14 +261,14 @@ wc (int fd, char const *file_x, struct f
              if (bytes_read == SAFE_READ_ERROR)
                {
                  error (0, errno, "%s", file);
-                 exit_status = 1;
+                 ok = false;
                  break;
                }
              bytes += bytes_read;
            }
        }
     }
-  else if (!count_chars && !count_complicated)
+  else if (!count_chars & !count_complicated)
     {
       /* Use a separate loop when counting only lines or lines and bytes --
         but not chars or words.  */
@@ -280,7 +279,7 @@ wc (int fd, char const *file_x, struct f
          if (bytes_read == SAFE_READ_ERROR)
            {
              error (0, errno, "%s", file);
-             exit_status = 1;
+             ok = false;
              break;
            }
 
@@ -296,7 +295,7 @@ wc (int fd, char const *file_x, struct f
 # define SUPPORT_OLD_MBRTOWC 1
   else if (MB_CUR_MAX > 1)
     {
-      int in_word = 0;
+      bool in_word = false;
       uintmax_t linepos = 0;
       mbstate_t state;
       uintmax_t last_error_line = 0;
@@ -324,7 +323,7 @@ wc (int fd, char const *file_x, struct f
          if (bytes_read == SAFE_READ_ERROR)
            {
              error (0, errno, "%s", file);
-             exit_status = 1;
+             ok = false;
              break;
            }
 
@@ -358,6 +357,7 @@ wc (int fd, char const *file_x, struct f
                      last_error_errno = errno;
                      error (0, errno, "%s:%s", file,
                             umaxtostr (last_error_line, line_number_buf));
+                     ok = false;
                    }
                  p++;
                  bytes_read--;
@@ -391,11 +391,8 @@ wc (int fd, char const *file_x, struct f
                      /* Fall through. */
                    case '\v':
                    mb_word_separator:
-                     if (in_word)
-                       {
-                         in_word = 0;
-                         words++;
-                       }
+                     words += in_word;
+                     in_word = false;
                      break;
                    default:
                      if (iswprint (wide_char))
@@ -405,7 +402,7 @@ wc (int fd, char const *file_x, struct f
                            linepos += width;
                          if (iswspace (wide_char))
                            goto mb_word_separator;
-                         in_word = 1;
+                         in_word = true;
                        }
                      break;
                    }
@@ -429,13 +426,12 @@ wc (int fd, char const *file_x, struct f
        }
       if (linepos > linelength)
        linelength = linepos;
-      if (in_word)
-       words++;
+      words += in_word;
     }
 #endif
   else
     {
-      int in_word = 0;
+      bool in_word = false;
       uintmax_t linepos = 0;
 
       while ((bytes_read = safe_read (fd, buf, BUFFER_SIZE)) > 0)
@@ -444,7 +440,7 @@ wc (int fd, char const *file_x, struct f
          if (bytes_read == SAFE_READ_ERROR)
            {
              error (0, errno, "%s", file);
-             exit_status = 1;
+             ok = false;
              break;
            }
 
@@ -470,19 +466,16 @@ wc (int fd, char const *file_x, struct f
                  /* Fall through. */
                case '\v':
                word_separator:
-                 if (in_word)
-                   {
-                     in_word = 0;
-                     words++;
-                   }
+                 words += in_word;
+                 in_word = false;
                  break;
                default:
-                 if (ISPRINT ((unsigned char) p[-1]))
+                 if (ISPRINT (to_uchar (p[-1])))
                    {
                      linepos++;
-                     if (ISSPACE ((unsigned char) p[-1]))
+                     if (ISSPACE (to_uchar (p[-1])))
                        goto word_separator;
-                     in_word = 1;
+                     in_word = true;
                    }
                  break;
                }
@@ -491,8 +484,7 @@ wc (int fd, char const *file_x, struct f
        }
       if (linepos > linelength)
        linelength = linepos;
-      if (in_word)
-       words++;
+      words += in_word;
     }
 
   if (count_chars < print_chars)
@@ -505,15 +497,17 @@ wc (int fd, char const *file_x, struct f
   total_bytes += bytes;
   if (linelength > max_line_length)
     max_line_length = linelength;
+
+  return ok;
 }
 
-static void
+static bool
 wc_file (char const *file, struct fstatus *fstatus)
 {
   if (STREQ (file, "-"))
     {
-      have_read_stdin = 1;
-      wc (STDIN_FILENO, file, fstatus);
+      have_read_stdin = true;
+      return wc (STDIN_FILENO, file, fstatus);
     }
   else
     {
@@ -521,14 +515,17 @@ wc_file (char const *file, struct fstatu
       if (fd == -1)
        {
          error (0, errno, "%s", file);
-         exit_status = 1;
-         return;
+         return false;
        }
-      wc (fd, file, fstatus);
-      if (close (fd))
+      else
        {
-         error (0, errno, "%s", file);
-         exit_status = 1;
+         bool ok = wc (fd, file, fstatus);
+         if (close (fd) != 0)
+           {
+             error (0, errno, "%s", file);
+             return false;
+           }
+         return ok;
        }
     }
 }
@@ -598,6 +595,7 @@ compute_number_width (int nfiles, struct
 int
 main (int argc, char **argv)
 {
+  bool ok;
   int optc;
   int nfiles;
   struct fstatus *fstatus;
@@ -610,8 +608,8 @@ main (int argc, char **argv)
 
   atexit (close_stdout);
 
-  exit_status = 0;
-  print_lines = print_words = print_chars = print_bytes = print_linelength = 0;
+  print_lines = print_words = print_chars = print_bytes = false;
+  print_linelength = false;
   total_lines = total_words = total_chars = total_bytes = max_line_length = 0;
 
   while ((optc = getopt_long (argc, argv, "clLmw", longopts, NULL)) != -1)
@@ -621,23 +619,23 @@ main (int argc, char **argv)
        break;
 
       case 'c':
-       print_bytes = 1;
+       print_bytes = true;
        break;
 
       case 'm':
-       print_chars = 1;
+       print_chars = true;
        break;
 
       case 'l':
-       print_lines = 1;
+       print_lines = true;
        break;
 
       case 'w':
-       print_words = 1;
+       print_words = true;
        break;
 
       case 'L':
-       print_linelength = 1;
+       print_linelength = true;
        break;
 
       case_GETOPT_HELP_CHAR;
@@ -648,9 +646,9 @@ main (int argc, char **argv)
        usage (EXIT_FAILURE);
       }
 
-  if (print_lines + print_words + print_chars + print_bytes + print_linelength
-      == 0)
-    print_lines = print_words = print_bytes = 1;
+  if (! (print_lines | print_words | print_chars | print_bytes
+        | print_linelength))
+    print_lines = print_words = print_bytes = true;
 
   nfiles = argc - optind;
   nfiles += (nfiles == 0);
@@ -660,14 +658,16 @@ main (int argc, char **argv)
 
   if (! argv[optind])
     {
-      have_read_stdin = 1;
-      wc (STDIN_FILENO, NULL, &fstatus[0]);
+      have_read_stdin = true;
+      ok = wc (STDIN_FILENO, NULL, &fstatus[0]);
     }
   else
     {
       int i;
+
+      ok = true;
       for (i = 0; i < nfiles; i++)
-       wc_file (argv[optind + i], &fstatus[i]);
+       ok &= wc_file (argv[optind + i], &fstatus[i]);
 
       if (nfiles > 1)
        write_counts (total_lines, total_words, total_chars, total_bytes,
@@ -679,5 +679,5 @@ main (int argc, char **argv)
   if (have_read_stdin && close (STDIN_FILENO) != 0)
     error (EXIT_FAILURE, errno, "-");
 
-  exit (exit_status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
+  exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
 }
Index: src/who.c
===================================================================
RCS file: /home/eggert/coreutils/cu/src/who.c,v
retrieving revision 1.101
diff -p -u -r1.101 who.c
--- src/who.c   2 Aug 2004 20:56:46 -0000       1.101
+++ src/who.c   3 Aug 2004 23:11:03 -0000
@@ -577,7 +577,7 @@ scan_entries (size_t n, const STRUCT_UTM
 
   if (my_line_only)
     {
-      ttyname_b = ttyname (0);
+      ttyname_b = ttyname (STDIN_FILENO);
       if (!ttyname_b)
        return;
       if (strncmp (ttyname_b, DEV_DIR_WITH_TRAILING_SLASH, DEV_DIR_LEN) == 0)
Index: src/whoami.c
===================================================================
RCS file: /home/eggert/coreutils/cu/src/whoami.c,v
retrieving revision 1.42
diff -p -u -r1.42 whoami.c
--- src/whoami.c        21 Jun 2004 15:03:35 -0000      1.42
+++ src/whoami.c        20 Jul 2004 04:32:16 -0000
@@ -108,7 +108,7 @@ main (int argc, char **argv)
       puts (pw->pw_name);
       exit (EXIT_SUCCESS);
     }
-  fprintf (stderr, _("%s: cannot find username for UID %u\n"),
-          program_name, (unsigned) uid);
+  fprintf (stderr, _("%s: cannot find username for UID %lu\n"),
+          program_name, (unsigned long int) uid);
   exit (EXIT_FAILURE);
 }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]