[Top][All Lists]
[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);
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- coreutils int cleanups for uniq, wc, who, whoami,
Paul Eggert <=