[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] wc: add -v option to print total counts every second.
From: |
Sina Siadat |
Subject: |
[PATCH] wc: add -v option to print total counts every second. |
Date: |
Fri, 11 Mar 2016 12:49:13 +0330 |
* src/wc.c: add -v option and write live counts to stderr.
---
src/wc.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 114 insertions(+), 19 deletions(-)
diff --git a/src/wc.c b/src/wc.c
index 94cbaff..52ca437 100644
--- a/src/wc.c
+++ b/src/wc.c
@@ -60,9 +60,16 @@ static uintmax_t total_chars;
static uintmax_t total_bytes;
static uintmax_t max_line_length;
+static uintmax_t live_total_lines;
+static uintmax_t live_total_words;
+static uintmax_t live_total_chars;
+static uintmax_t live_total_bytes;
+static uintmax_t live_max_line_length;
+
/* Which counts to print. */
static bool print_lines, print_words, print_chars, print_bytes;
static bool print_linelength;
+static bool print_verbose;
/* The print width of each count. */
static int number_width;
@@ -96,6 +103,7 @@ static struct option const longopts[] =
{"words", no_argument, NULL, 'w'},
{"files0-from", required_argument, NULL, FILES0_FROM_OPTION},
{"max-line-length", no_argument, NULL, 'L'},
+ {"verbose", no_argument, NULL, 'v'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
@@ -135,6 +143,7 @@ the following order: newline, word, character, byte,
maximum line length.\n\
If F is - then read names from standard input\n\
-L, --max-line-length print the maximum display width\n\
-w, --words print the word counts\n\
+ -v, --verbose print the counts every second\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
@@ -143,10 +152,11 @@ the following order: newline, word, character, byte,
maximum line length.\n\
exit (status);
}
-/* FILE is the name of the file (or NULL for standard input)
+/* file is the name of the file (or NULL for standard input)
associated with the specified counters. */
static void
-write_counts (uintmax_t lines,
+write_counts (FILE * restrict stream,
+ uintmax_t lines,
uintmax_t words,
uintmax_t chars,
uintmax_t bytes,
@@ -159,31 +169,70 @@ write_counts (uintmax_t lines,
if (print_lines)
{
- printf (format_int, number_width, umaxtostr (lines, buf));
+ fprintf (stream, format_int, number_width, umaxtostr (lines, buf));
format_int = format_sp_int;
}
if (print_words)
{
- printf (format_int, number_width, umaxtostr (words, buf));
+ fprintf (stream, format_int, number_width, umaxtostr (words, buf));
format_int = format_sp_int;
}
if (print_chars)
{
- printf (format_int, number_width, umaxtostr (chars, buf));
+ fprintf (stream, format_int, number_width, umaxtostr (chars, buf));
format_int = format_sp_int;
}
if (print_bytes)
{
- printf (format_int, number_width, umaxtostr (bytes, buf));
+ fprintf (stream, format_int, number_width, umaxtostr (bytes, buf));
format_int = format_sp_int;
}
if (print_linelength)
{
- printf (format_int, number_width, umaxtostr (linelength, buf));
+ fprintf (stream, format_int, number_width, umaxtostr (linelength, buf));
}
if (file)
- printf (" %s", strchr (file, '\n') ? quotef (file) : file);
- putchar ('\n');
+ fprintf (stream, " %s", strchr (file, '\n') ? quotef (file) : file);
+}
+
+static void
+write_live_counts (int signum)
+{
+ if (isatty (STDERR_FILENO))
+ fprintf (stderr, "\r");
+
+ write_counts (stderr, live_total_lines, live_total_words,
+ live_total_chars, live_total_bytes, live_max_line_length,
NULL);
+
+ if (isatty (STDERR_FILENO))
+ fflush (stderr);
+ else
+ fprintf (stderr, "\n");
+
+ alarm (1);
+}
+
+static void
+write_counts_final (uintmax_t lines,
+ uintmax_t words,
+ uintmax_t chars,
+ uintmax_t bytes,
+ uintmax_t linelength,
+ const char *file)
+{
+ if (print_verbose) {
+ if (isatty (STDERR_FILENO))
+ fprintf (stderr, "\r");
+
+ /* Update the counts for the final time, if stdout is not a tty. */
+ if (!isatty (STDOUT_FILENO)) {
+ write_live_counts (0);
+ fprintf (stderr, "\n");
+ }
+ }
+
+ write_counts (stdout, lines, words, chars, bytes, linelength, file);
+ fprintf (stdout, "\n");
}
/* Count words. FILE_X is the name of the file (or NULL for standard
@@ -249,7 +298,10 @@ wc (int fd, char const *file_x, struct fstatus *fstatus,
off_t current_pos)
current_pos = lseek (fd, 0, SEEK_CUR);
if (0 <= current_pos && current_pos < hi_pos
&& 0 <= lseek (fd, hi_pos, SEEK_CUR))
- bytes = hi_pos - current_pos;
+ {
+ bytes = hi_pos - current_pos;
+ live_total_bytes = bytes;
+ }
}
fdadvise (fd, 0, 0, FADVISE_SEQUENTIAL);
@@ -262,6 +314,7 @@ wc (int fd, char const *file_x, struct fstatus *fstatus,
off_t current_pos)
break;
}
bytes += bytes_read;
+ live_total_bytes += bytes_read;
}
}
else if (!count_chars && !count_complicated)
@@ -279,6 +332,7 @@ wc (int fd, char const *file_x, struct fstatus *fstatus,
off_t current_pos)
}
bytes += bytes_read;
+ live_total_bytes += bytes_read;
char *p = buf;
char *end = p + bytes_read;
@@ -288,7 +342,12 @@ wc (int fd, char const *file_x, struct fstatus *fstatus,
off_t current_pos)
{
/* Avoid function call overhead for shorter lines. */
while (p != end)
- lines += *p++ == '\n';
+ {
+ if (*p++ == '\n') {
+ lines ++;
+ live_total_lines ++;
+ }
+ }
}
else
{
@@ -297,6 +356,7 @@ wc (int fd, char const *file_x, struct fstatus *fstatus,
off_t current_pos)
{
++p;
++lines;
+ ++live_total_lines;
}
}
@@ -347,6 +407,7 @@ wc (int fd, char const *file_x, struct fstatus *fstatus,
off_t current_pos)
}
bytes += bytes_read;
+ live_total_bytes += bytes_read;
p = buf;
bytes_read += prev;
do
@@ -396,15 +457,20 @@ wc (int fd, char const *file_x, struct fstatus *fstatus,
off_t current_pos)
p += n;
bytes_read -= n;
chars++;
+ live_total_chars++;
switch (wide_char)
{
case '\n':
lines++;
+ live_total_lines++;
/* Fall through. */
case '\r':
case '\f':
if (linepos > linelength)
- linelength = linepos;
+ {
+ linelength = linepos;
+ live_max_line_length = linepos;
+ }
linepos = 0;
goto mb_word_separator;
case '\t':
@@ -416,6 +482,7 @@ wc (int fd, char const *file_x, struct fstatus *fstatus,
off_t current_pos)
case '\v':
mb_word_separator:
words += in_word;
+ live_total_words += in_word;
in_word = false;
break;
default:
@@ -448,8 +515,12 @@ wc (int fd, char const *file_x, struct fstatus *fstatus,
off_t current_pos)
# endif
}
if (linepos > linelength)
- linelength = linepos;
+ {
+ linelength = linepos;
+ live_max_line_length = linepos;
+ }
words += in_word;
+ live_total_words += in_word;
}
#endif
else
@@ -468,17 +539,22 @@ wc (int fd, char const *file_x, struct fstatus *fstatus,
off_t current_pos)
}
bytes += bytes_read;
+ live_total_bytes += bytes_read;
do
{
switch (*p++)
{
case '\n':
lines++;
+ live_total_lines++;
/* Fall through. */
case '\r':
case '\f':
if (linepos > linelength)
- linelength = linepos;
+ {
+ linelength = linepos;
+ live_max_line_length = linepos;
+ }
linepos = 0;
goto word_separator;
case '\t':
@@ -490,6 +566,7 @@ wc (int fd, char const *file_x, struct fstatus *fstatus,
off_t current_pos)
case '\v':
word_separator:
words += in_word;
+ live_total_words += in_word;
in_word = false;
break;
default:
@@ -506,14 +583,20 @@ wc (int fd, char const *file_x, struct fstatus *fstatus,
off_t current_pos)
while (--bytes_read);
}
if (linepos > linelength)
- linelength = linepos;
+ {
+ linelength = linepos;
+ live_max_line_length = linepos;
+ }
words += in_word;
+ live_total_words += in_word;
}
if (count_chars < print_chars)
chars = bytes;
- write_counts (lines, words, chars, bytes, linelength, file_x);
+ live_total_chars += chars;
+
+ write_counts_final (lines, words, chars, bytes, linelength, file_x);
total_lines += lines;
total_words += words;
total_chars += chars;
@@ -646,7 +729,7 @@ main (int argc, char **argv)
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)
+ while ((optc = getopt_long (argc, argv, "clLmwv", longopts, NULL)) != -1)
switch (optc)
{
case 'c':
@@ -665,6 +748,10 @@ main (int argc, char **argv)
print_words = true;
break;
+ case 'v':
+ print_verbose = true;
+ break;
+
case 'L':
print_linelength = true;
break;
@@ -742,6 +829,14 @@ main (int argc, char **argv)
ai = argv_iter_init_argv (files);
}
+ if (print_verbose)
+ {
+ struct sigaction action;
+ action.sa_handler = write_live_counts;
+ sigaction (SIGALRM, &action, NULL);
+ alarm (1);
+ }
+
if (!ai)
xalloc_die ();
@@ -819,8 +914,8 @@ main (int argc, char **argv)
readtokens0_free (&tok);
if (1 < argv_iter_n_args (ai))
- write_counts (total_lines, total_words, total_chars, total_bytes,
- max_line_length, _("total"));
+ write_counts_final (total_lines, total_words, total_chars, total_bytes,
+ max_line_length, _("total"));
argv_iter_free (ai);
--
2.7.1
- [PATCH] wc: add -v option to print total counts every second.,
Sina Siadat <=