Hi Jim, hello everybody, genparse version 0.6.8 has support for command line parameters with optional arguments now. This was the most important missing feature for generating the command line parsing code for the tail command. I focused on the tail command because in a previous email you suggested tail as a candidate for genparse.
The attached patch contains the genparse extensions for both the wc command (as previously posted) and the tail command. I verified that it successfully passes make check. I also added tail to the examples on the genparse homepage (http://genparse.sourceforge.net/examples.html) so that you can have a look at the generated code without downloading and building the latest version of genparse. As usual: Any comments welcome! Michael
diff -u -N -r coreutils-6.9.orig/doc/Makefile.am coreutils-6.9/doc/Makefile.am --- coreutils-6.9.orig/doc/Makefile.am 2007-03-18 22:36:43.000000000 +0100 +++ coreutils-6.9/doc/Makefile.am 2007-08-19 13:45:25.000000000 +0200 @@ -32,10 +32,10 @@ # old systems. AM_MAKEINFOFLAGS = --no-split -constants.texi: $(top_srcdir)/src/tail.c +constants.texi: $(top_srcdir)/src/tail.h LC_ALL=C \ sed -n -e 's/^#define \(DEFAULT_MAX[_A-Z]*\) \(.*\)/@set \1 \2/p' \ - $(top_srcdir)/src/tail.c > t-$@ + $(top_srcdir)/src/tail.h > t-$@ mv t-$@ $@ MAINTAINERCLEANFILES = constants.texi diff -u -N -r coreutils-6.9.orig/doc/Makefile.in coreutils-6.9/doc/Makefile.in --- coreutils-6.9.orig/doc/Makefile.in 2007-03-22 22:20:21.000000000 +0100 +++ coreutils-6.9/doc/Makefile.in 2007-08-19 13:46:04.000000000 +0200 @@ -937,10 +937,10 @@ uninstall-ps-am -constants.texi: $(top_srcdir)/src/tail.c +constants.texi: $(top_srcdir)/src/tail.h LC_ALL=C \ sed -n -e 's/^#define \(DEFAULT_MAX[_A-Z]*\) \(.*\)/@set \1 \2/p' \ - $(top_srcdir)/src/tail.c > t-$@ + $(top_srcdir)/src/tail.h > t-$@ mv t-$@ $@ $(DVIS): $(EXTRA_DIST) diff -u -N -r coreutils-6.9.orig/src/Makefile.am coreutils-6.9/src/Makefile.am --- coreutils-6.9.orig/src/Makefile.am 2007-03-20 08:24:27.000000000 +0100 +++ coreutils-6.9/src/Makefile.am 2007-08-19 13:46:56.000000000 +0200 @@ -363,3 +363,12 @@ | grep -Ev -f $$t && \ { echo 'the above variables should have static scope' 1>&2; \ exit 1; } || : + +wc_SOURCES = wc_clp.c wc.c +wc_clp.c: wc.gp + genparse --longmembers --internationalize -o wc_clp wc.gp + + +tail_SOURCES = tail_clp.c tail.c +tail_clp.c: tail.gp + genparse --longmembers --internationalize -o tail_clp tail.gp diff -u -N -r coreutils-6.9.orig/src/Makefile.in coreutils-6.9/src/Makefile.in --- coreutils-6.9.orig/src/Makefile.in 2007-03-22 22:23:20.000000000 +0100 +++ coreutils-6.9/src/Makefile.in 2007-08-19 13:47:14.000000000 +0200 @@ -569,8 +569,8 @@ tac_LDADD = $(LDADD) tac_DEPENDENCIES = ../lib/libcoreutils.a $(am__DEPENDENCIES_1) \ ../lib/libcoreutils.a -tail_SOURCES = tail.c -tail_OBJECTS = tail.$(OBJEXT) +am_tail_OBJECTS = tail_clp.$(OBJEXT) tail.$(OBJEXT) +tail_OBJECTS = $(am_tail_OBJECTS) tail_DEPENDENCIES = $(am__DEPENDENCIES_3) tee_SOURCES = tee.c tee_OBJECTS = tee.$(OBJEXT) @@ -636,8 +636,8 @@ vdir_OBJECTS = $(am_vdir_OBJECTS) vdir_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -wc_SOURCES = wc.c -wc_OBJECTS = wc.$(OBJEXT) +am_wc_OBJECTS = wc_clp.$(OBJEXT) wc.$(OBJEXT) +wc_OBJECTS = $(am_wc_OBJECTS) wc_LDADD = $(LDADD) wc_DEPENDENCIES = ../lib/libcoreutils.a $(am__DEPENDENCIES_1) \ ../lib/libcoreutils.a @@ -677,10 +677,10 @@ rmdir.c seq.c setuidgid.c $(sha1sum_SOURCES) \ $(sha224sum_SOURCES) $(sha256sum_SOURCES) $(sha384sum_SOURCES) \ $(sha512sum_SOURCES) shred.c shuf.c sleep.c sort.c split.c \ - stat.c stty.c su.c sum.c sync.c tac.c tail.c tee.c test.c \ - touch.c tr.c true.c tsort.c tty.c uname.c unexpand.c uniq.c \ - unlink.c uptime.c users.c $(vdir_SOURCES) wc.c who.c whoami.c \ - yes.c + stat.c stty.c su.c sum.c sync.c tac.c $(tail_SOURCES) tee.c \ + test.c touch.c tr.c true.c tsort.c tty.c uname.c unexpand.c \ + uniq.c unlink.c uptime.c users.c $(vdir_SOURCES) $(wc_SOURCES) \ + who.c whoami.c yes.c DIST_SOURCES = $(__SOURCES) base64.c basename.c cat.c $(chgrp_SOURCES) \ chmod.c $(chown_SOURCES) chroot.c cksum.c comm.c $(cp_SOURCES) \ csplit.c cut.c date.c dd.c df.c $(dir_SOURCES) dircolors.c \ @@ -693,10 +693,10 @@ rmdir.c seq.c setuidgid.c $(sha1sum_SOURCES) \ $(sha224sum_SOURCES) $(sha256sum_SOURCES) $(sha384sum_SOURCES) \ $(sha512sum_SOURCES) shred.c shuf.c sleep.c sort.c split.c \ - stat.c stty.c su.c sum.c sync.c tac.c tail.c tee.c test.c \ - touch.c tr.c true.c tsort.c tty.c uname.c unexpand.c uniq.c \ - unlink.c uptime.c users.c $(vdir_SOURCES) wc.c who.c whoami.c \ - yes.c + stat.c stty.c su.c sum.c sync.c tac.c $(tail_SOURCES) tee.c \ + test.c touch.c tr.c true.c tsort.c tty.c uname.c unexpand.c \ + uniq.c unlink.c uptime.c users.c $(vdir_SOURCES) $(wc_SOURCES) \ + who.c whoami.c yes.c HEADERS = $(noinst_HEADERS) ETAGS = etags CTAGS = ctags @@ -1144,6 +1144,8 @@ s1 = '/^\#define AUTHORS \([^\\]\)/{;s//\1/;$(sed_filter);p;q;}' # Sometimes the string is on the backslash-continued line after the #define. s2 = '/^\#define AUTHORS \\\\/{;n;$(sed_filter);p;q;}' +wc_SOURCES = wc_clp.c wc.c +tail_SOURCES = tail_clp.c tail.c all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am @@ -1200,7 +1202,7 @@ done clean-binPROGRAMS: - -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) > /dev/null 2>&1 || /bin/rm -f $(bin_PROGRAMS) + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) clean-noinstPROGRAMS: -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) @@ -1602,6 +1604,7 @@ @AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@ @AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@ @AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@ [EMAIL PROTECTED]@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@ @AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@ @AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@ @AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@ @@ -1616,6 +1619,7 @@ @AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@ @AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@ @AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@ [EMAIL PROTECTED]@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@ @AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@ @AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@ @AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@ @@ -2060,6 +2064,10 @@ | grep -Ev -f $$t && \ { echo 'the above variables should have static scope' 1>&2; \ exit 1; } || : +wc_clp.c: wc.gp + genparse --longmembers --internationalize -o wc_clp wc.gp +tail_clp.c: tail.gp + genparse --longmembers --internationalize -o tail_clp tail.gp # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff -u -N -r coreutils-6.9.orig/src/tail.c coreutils-6.9/src/tail.c --- coreutils-6.9.orig/src/tail.c 2007-03-18 22:36:43.000000000 +0100 +++ coreutils-6.9/src/tail.c 2007-08-19 14:10:03.000000000 +0200 @@ -31,7 +31,6 @@ #include <sys/types.h> #include <signal.h> -#include "system.h" #include "argmatch.h" #include "c-strtod.h" #include "error.h" @@ -45,6 +44,7 @@ #include "xnanosleep.h" #include "xstrtol.h" #include "xstrtod.h" +#include "tail_clp.h" /* The official name of this program (e.g., no `g' prefix). */ #define PROGRAM_NAME "tail" @@ -52,9 +52,6 @@ #define AUTHORS \ "Paul Rubin", "David MacKenzie, Ian Lance Taylor", "Jim Meyering" -/* Number of items to tail. */ -#define DEFAULT_N_LINES 10 - /* Special values for dump_remainder's N_BYTES parameter. */ #define COPY_TO_EOF UINTMAX_MAX #define COPY_A_BUFFER (UINTMAX_MAX - 1) @@ -151,12 +148,6 @@ multiple_files, always, never }; -/* When tailing a file by name, if there have been this many consecutive - iterations for which the file has not changed, then open/fstat - the file to determine if that file name is still associated with the - same device/inode-number pair as before. This option is meaningful only - when following by name. --max-unchanged-stats=N */ -#define DEFAULT_MAX_N_UNCHANGED_STATS_BETWEEN_OPENS 5 static uintmax_t max_n_unchanged_stats_between_opens = DEFAULT_MAX_N_UNCHANGED_STATS_BETWEEN_OPENS; @@ -175,118 +166,6 @@ more expensive) code unconditionally. Intended solely for testing. */ static bool presume_input_pipe; -/* For long options that have no equivalent short option, use a - non-character as a pseudo short option, starting with CHAR_MAX + 1. */ -enum -{ - RETRY_OPTION = CHAR_MAX + 1, - MAX_UNCHANGED_STATS_OPTION, - PID_OPTION, - PRESUME_INPUT_PIPE_OPTION, - LONG_FOLLOW_OPTION -}; - -static struct option const long_options[] = -{ - {"bytes", required_argument, NULL, 'c'}, - {"follow", optional_argument, NULL, LONG_FOLLOW_OPTION}, - {"lines", required_argument, NULL, 'n'}, - {"max-unchanged-stats", required_argument, NULL, MAX_UNCHANGED_STATS_OPTION}, - {"pid", required_argument, NULL, PID_OPTION}, - {"-presume-input-pipe", no_argument, NULL, - PRESUME_INPUT_PIPE_OPTION}, /* do not document */ - {"quiet", no_argument, NULL, 'q'}, - {"retry", no_argument, NULL, RETRY_OPTION}, - {"silent", no_argument, NULL, 'q'}, - {"sleep-interval", required_argument, NULL, 's'}, - {"verbose", no_argument, NULL, 'v'}, - {GETOPT_HELP_OPTION_DECL}, - {GETOPT_VERSION_OPTION_DECL}, - {NULL, 0, NULL, 0} -}; - -void -usage (int status) -{ - if (status != EXIT_SUCCESS) - fprintf (stderr, _("Try `%s --help' for more information.\n"), - program_name); - else - { - printf (_("\ -Usage: %s [OPTION]... [FILE]...\n\ -"), - program_name); - printf (_("\ -Print the last %d lines of each FILE to standard output.\n\ -With more than one FILE, precede each with a header giving the file name.\n\ -With no FILE, or when FILE is -, read standard input.\n\ -\n\ -"), DEFAULT_N_LINES); - fputs (_("\ -Mandatory arguments to long options are mandatory for short options too.\n\ -"), stdout); - fputs (_("\ - --retry keep trying to open a file even if it is\n\ - inaccessible when tail starts or if it becomes\n\ - inaccessible later; useful when following by name,\n\ - i.e., with --follow=name\n\ - -c, --bytes=N output the last N bytes; alternatively, use +N to\n\ - output bytes starting with the Nth of each file\n\ -"), stdout); - fputs (_("\ - -f, --follow[={name|descriptor}]\n\ - output appended data as the file grows;\n\ - -f, --follow, and --follow=descriptor are\n\ - equivalent\n\ - -F same as --follow=name --retry\n\ -"), stdout); - printf (_("\ - -n, --lines=N output the last N lines, instead of the last %d;\n\ - or use +N to output lines starting with the Nth\n\ - --max-unchanged-stats=N\n\ - with --follow=name, reopen a FILE which has not\n\ - changed size after N (default %d) iterations\n\ - to see if it has been unlinked or renamed\n\ - (this is the usual case of rotated log files)\n\ -"), - DEFAULT_N_LINES, - DEFAULT_MAX_N_UNCHANGED_STATS_BETWEEN_OPENS - ); - fputs (_("\ - --pid=PID with -f, terminate after process ID, PID dies\n\ - -q, --quiet, --silent never output headers giving file names\n\ - -s, --sleep-interval=S with -f, sleep for approximately S seconds\n\ - (default 1.0) between iterations.\n\ - -v, --verbose always output headers giving file names\n\ -"), stdout); - fputs (HELP_OPTION_DESCRIPTION, stdout); - fputs (VERSION_OPTION_DESCRIPTION, stdout); - fputs (_("\ -\n\ -If the first character of N (the number of bytes or lines) is a `+',\n\ -print beginning with the Nth item from the start of each file, otherwise,\n\ -print the last N items in the file. N may have a multiplier suffix:\n\ -b 512, k 1024, m 1024*1024.\n\ -\n\ -"), stdout); - fputs (_("\ -With --follow (-f), tail defaults to following the file descriptor, which\n\ -means that even if a tail'ed file is renamed, tail will continue to track\n\ -its end. \ -"), stdout); - fputs (_("\ -This default behavior is not desirable when you really want to\n\ -track the actual name of the file, not the file descriptor (e.g., log\n\ -rotation). Use --follow=name in that case. That causes tail to track the\n\ -named file by reopening it periodically to see if it has been removed and\n\ -recreated by some other program.\n\ -"), stdout); - printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT); - } - exit (status); -} - static bool valid_file_spec (struct File_spec const *f) { @@ -1446,122 +1325,129 @@ return true; } +void param_lines_or_bytes(bool lines, char *arg_str, uintmax_t *n_units) +{ + count_lines = lines; + if (*arg_str == '+') + from_start = true; + else if (*arg_str == '-') + ++arg_str; + + { + strtol_error s_err; + s_err = xstrtoumax (arg_str, NULL, 10, n_units, "bkm"); + if (s_err != LONGINT_OK) + { + error (EXIT_FAILURE, 0, "%s: %s", arg_str, + (lines + ? _("invalid number of lines") + : _("invalid number of bytes"))); + } + } +} + static void parse_options (int argc, char **argv, uintmax_t *n_units, enum header_mode *header_mode, double *sleep_interval) { int c; + struct arg_t cmdline; - while ((c = getopt_long (argc, argv, "c:n:fFqs:v0123456789", - long_options, NULL)) - != -1) - { - switch (c) - { - case 'F': - forever = true; - follow_mode = Follow_name; - reopen_inaccessible_files = true; - break; + Cmdline(&cmdline, argc, argv); - case 'c': - case 'n': - count_lines = (c == 'n'); - if (*optarg == '+') - from_start = true; - else if (*optarg == '-') - ++optarg; + if (cmdline.lines != NULL) + param_lines_or_bytes(true, cmdline.lines, n_units); - { - strtol_error s_err; - s_err = xstrtoumax (optarg, NULL, 10, n_units, "bkm"); - if (s_err != LONGINT_OK) - { - error (EXIT_FAILURE, 0, "%s: %s", optarg, - (c == 'n' - ? _("invalid number of lines") - : _("invalid number of bytes"))); - } - } - break; - - case 'f': - case LONG_FOLLOW_OPTION: - forever = true; - if (optarg == NULL) - follow_mode = DEFAULT_FOLLOW_MODE; - else - follow_mode = XARGMATCH ("--follow", optarg, - follow_mode_string, follow_mode_map); - break; + if (cmdline.bytes != NULL) + param_lines_or_bytes(false, cmdline.bytes, n_units); - case RETRY_OPTION: - reopen_inaccessible_files = true; - break; + if (cmdline.follow_flag) + { + forever = true; + if (cmdline.follow == NULL) + follow_mode = DEFAULT_FOLLOW_MODE; + else + follow_mode = XARGMATCH ("--follow", cmdline.follow, + follow_mode_string, follow_mode_map); + } - case MAX_UNCHANGED_STATS_OPTION: - /* --max-unchanged-stats=N */ - if (xstrtoumax (optarg, NULL, 10, - &max_n_unchanged_stats_between_opens, - "") - != LONGINT_OK) - { - error (EXIT_FAILURE, 0, - _("%s: invalid maximum number of unchanged stats between opens"), - optarg); - } - break; + if (cmdline.F) + { + forever = true; + follow_mode = Follow_name; + reopen_inaccessible_files = true; + } - case PID_OPTION: - { - strtol_error s_err; - unsigned long int tmp_ulong; - s_err = xstrtoul (optarg, NULL, 10, &tmp_ulong, ""); - if (s_err != LONGINT_OK || tmp_ulong > PID_T_MAX) - { - error (EXIT_FAILURE, 0, _("%s: invalid PID"), optarg); - } - pid = tmp_ulong; - } - break; + reopen_inaccessible_files = cmdline.retry; - case PRESUME_INPUT_PIPE_OPTION: - presume_input_pipe = true; - break; + if (cmdline.max_unchanged_stats != NULL) + { + /* --max-unchanged-stats=N */ + if (xstrtoumax (cmdline.max_unchanged_stats, NULL, 10, + &max_n_unchanged_stats_between_opens, + "") + != LONGINT_OK) + { + error (EXIT_FAILURE, 0, + _("%s: invalid maximum number of unchanged stats between opens"), + cmdline.max_unchanged_stats); + } + } - case 'q': - *header_mode = never; - break; + if (cmdline.pid != NULL) + { + strtol_error s_err; + unsigned long int tmp_ulong; + s_err = xstrtoul (cmdline.pid, NULL, 10, &tmp_ulong, ""); + if (s_err != LONGINT_OK || tmp_ulong > PID_T_MAX) + { + error (EXIT_FAILURE, 0, _("%s: invalid PID"), cmdline.pid); + } + pid = tmp_ulong; + } - case 's': - { - double s; - if (! (xstrtod (optarg, NULL, &s, c_strtod) && 0 <= s)) - error (EXIT_FAILURE, 0, - _("%s: invalid number of seconds"), optarg); - *sleep_interval = s; - } - break; + presume_input_pipe = cmdline._presume_input_pipe; - case 'v': - *header_mode = always; - break; + if (cmdline.quiet) + *header_mode = never; - case_GETOPT_HELP_CHAR; + if (cmdline.sleep_interval != NULL) + { + double s; + if (! (xstrtod (cmdline.sleep_interval, NULL, &s, c_strtod) && 0 <= s)) + error (EXIT_FAILURE, 0, + _("%s: invalid number of seconds"), cmdline.sleep_interval); + *sleep_interval = s; + } - case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); + if (cmdline.verbose) + *header_mode = always; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - error (EXIT_FAILURE, 0, - _("option used in invalid context -- %c"), c); + if (cmdline.help) + usage (EXIT_SUCCESS, program_name); - default: - usage (EXIT_FAILURE); - } + if (cmdline.version) + { + version_etc (stdout, PROGRAM_NAME, GNU_PACKAGE, VERSION, AUTHORS, + (char *) NULL); + exit (EXIT_SUCCESS); } + c = 0; + if (cmdline._0) c = '0'; + if (cmdline._1) c = '1'; + if (cmdline._2) c = '2'; + if (cmdline._3) c = '3'; + if (cmdline._4) c = '4'; + if (cmdline._5) c = '5'; + if (cmdline._6) c = '6'; + if (cmdline._7) c = '7'; + if (cmdline._8) c = '8'; + if (cmdline._9) c = '9'; + if (c) + error (EXIT_FAILURE, 0, _("option used in invalid context -- %c"), c); + if (reopen_inaccessible_files && follow_mode != Follow_name) error (0, 0, _("warning: --retry is useful mainly when following by name")); diff -u -N -r coreutils-6.9.orig/src/tail.gp coreutils-6.9/src/tail.gp --- coreutils-6.9.orig/src/tail.gp 1970-01-01 01:00:00.000000000 +0100 +++ coreutils-6.9/src/tail.gp 2007-08-19 13:47:40.000000000 +0200 @@ -0,0 +1,68 @@ +#include <config.h> +#include "system.h" +#include "tail.h" + +NONE / retry flag "keep trying to open a file even if it is" + "inaccessible when tail starts or if it becomes" + "inaccessible later; useful when following by name," + "i.e., with --follow=name" +c / bytes=N string "output the last N bytes; alternatively, use +N to" + "output bytes starting with the Nth of each file" +f! / follow*[={name|descriptor}] string "" + "output appended data as the file grows;" + "-f, --follow, and --follow=descriptor are" + "equivalent" +F flag "same as --follow=name --retry" +n / lines=N string "output the last N lines, instead of the last __INT__(DEFAULT_N_LINES);" + "or use +N to output lines starting with the Nth" +NONE / max-unchanged-stats=N string "" + "with --follow=name, reopen a FILE which has not" + "changed size after N (default __INT__(DEFAULT_MAX_N_UNCHANGED_STATS_BETWEEN_OPENS)) iterations" + "to see if it has been unlinked or renamed" + "(this is the usual case of rotated log files)" +NONE / pid=PID string "with -f, terminate after process ID, PID dies" +q / quiet flag "never output headers giving file names" +NONE / silent flag "same as --quiet" +s / sleep-interval=S string "with -f, sleep for approximately S seconds" + "(default 1.0) between iterations." +v / verbose flag "always output headers giving file names" +NONE / help flag "display this help and exit" +NONE / version flag "output version information and exit" +NONE / -presume-input-pipe flag "__DO_NOT_DOCUMENT__" +0 flag "__DO_NOT_DOCUMENT__" +1 flag "__DO_NOT_DOCUMENT__" +2 flag "__DO_NOT_DOCUMENT__" +3 flag "__DO_NOT_DOCUMENT__" +4 flag "__DO_NOT_DOCUMENT__" +5 flag "__DO_NOT_DOCUMENT__" +6 flag "__DO_NOT_DOCUMENT__" +7 flag "__DO_NOT_DOCUMENT__" +8 flag "__DO_NOT_DOCUMENT__" +9 flag "__DO_NOT_DOCUMENT__" + +#usage_begin +Usage: __PROGRAM_NAME__ [OPTION]... [FILE]... +Print the last __INT__(DEFAULT_N_LINES) lines of each FILE to standard output. +With more than one FILE, precede each with a header giving the file name. +With no FILE, or when FILE is -, read standard input. +Mandatory arguments to long options are mandatory for short options too. + +__GLOSSARY_GNU__(25) + +If the first character of N (the number of bytes or lines) is a `+', +print beginning with the Nth item from the start of each file, otherwise, +print the last N items in the file. N may have a multiplier suffix: +b 512, k 1024, m 1024*1024. + +With --follow (-f), tail defaults to following the file descriptor, which +means that even if a tail'ed file is renamed, tail will continue to track +its end. + +This default behavior is not desirable when you really want to +track the actual name of the file, not the file descriptor (e.g., log +rotation). Use --follow=name in that case. That causes tail to track the +named file by reopening it periodically to see if it has been removed and +recreated by some other program. + +Report bugs to <__STRING__(PACKAGE_BUGREPORT)>. +#usage_end diff -u -N -r coreutils-6.9.orig/src/tail.h coreutils-6.9/src/tail.h --- coreutils-6.9.orig/src/tail.h 1970-01-01 01:00:00.000000000 +0100 +++ coreutils-6.9/src/tail.h 2007-08-19 13:47:42.000000000 +0200 @@ -0,0 +1,9 @@ +/* Number of items to tail. */ +#define DEFAULT_N_LINES 10 + +/* When tailing a file by name, if there have been this many consecutive + iterations for which the file has not changed, then open/fstat + the file to determine if that file name is still associated with the + same device/inode-number pair as before. This option is meaningful only + when following by name. --max-unchanged-stats=N */ +#define DEFAULT_MAX_N_UNCHANGED_STATS_BETWEEN_OPENS 5 diff -u -N -r coreutils-6.9.orig/src/wc.c coreutils-6.9/src/wc.c --- coreutils-6.9.orig/src/wc.c 2007-03-18 22:36:43.000000000 +0100 +++ coreutils-6.9/src/wc.c 2007-07-16 19:40:21.000000000 +0200 @@ -24,13 +24,13 @@ #include <getopt.h> #include <sys/types.h> -#include "system.h" #include "error.h" #include "inttostr.h" #include "quote.h" #include "readtokens0.h" #include "safe-read.h" #include "wcwidth.h" +#include "wc_clp.h" #if !defined iswspace && !HAVE_ISWSPACE # define iswspace(wc) \ @@ -77,60 +77,6 @@ struct stat st; }; -/* For long options that have no equivalent short option, use a - non-character as a pseudo short option, starting with CHAR_MAX + 1. */ -enum -{ - FILES0_FROM_OPTION = CHAR_MAX + 1 -}; - -static struct option const longopts[] = -{ - {"bytes", no_argument, NULL, 'c'}, - {"chars", no_argument, NULL, 'm'}, - {"lines", no_argument, NULL, 'l'}, - {"words", no_argument, NULL, 'w'}, - {"files0-from", required_argument, NULL, FILES0_FROM_OPTION}, - {"max-line-length", no_argument, NULL, 'L'}, - {GETOPT_HELP_OPTION_DECL}, - {GETOPT_VERSION_OPTION_DECL}, - {NULL, 0, NULL, 0} -}; - -void -usage (int status) -{ - if (status != EXIT_SUCCESS) - fprintf (stderr, _("Try `%s --help' for more information.\n"), - program_name); - else - { - printf (_("\ -Usage: %s [OPTION]... [FILE]...\n\ - or: %s [OPTION]... --files0-from=F\n\ -"), - program_name, program_name); - fputs (_("\ -Print newline, word, and byte counts for each FILE, and a total line if\n\ -more than one FILE is specified. With no FILE, or when FILE is -,\n\ -read standard input.\n\ - -c, --bytes print the byte counts\n\ - -m, --chars print the character counts\n\ - -l, --lines print the newline counts\n\ -"), stdout); - fputs (_("\ - --files0-from=F read input from the files specified by\n\ - NUL-terminated names in file F\n\ - -L, --max-line-length print the length of the longest line\n\ - -w, --words print the word counts\n\ -"), stdout); - fputs (HELP_OPTION_DESCRIPTION, stdout); - fputs (VERSION_OPTION_DESCRIPTION, stdout); - printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT); - } - exit (status); -} - /* FILE is the name of the file (or NULL for standard input) associated with the specified counters. */ static void @@ -580,6 +526,7 @@ char *files_from = NULL; struct fstatus *fstatus; struct Tokens tok; + struct arg_t cmdline; initialize_main (&argc, &argv); program_name = argv[0]; @@ -589,44 +536,25 @@ atexit (close_stdout); - 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) - switch (optc) - { - case 'c': - print_bytes = true; - break; - - case 'm': - print_chars = true; - break; - - case 'l': - print_lines = true; - break; - - case 'w': - print_words = true; - break; - - case 'L': - print_linelength = true; - break; - - case FILES0_FROM_OPTION: - files_from = optarg; - break; - - case_GETOPT_HELP_CHAR; - - case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); - - default: - usage (EXIT_FAILURE); - } + Cmdline(&cmdline, argc, argv); + print_bytes = cmdline.bytes; + print_chars = cmdline.chars; + print_lines = cmdline.lines; + print_words = cmdline.words; + print_linelength = cmdline.max_line_length; + files_from = cmdline.files0_from; + + if (cmdline.help) + usage (EXIT_SUCCESS, program_name); + + if (cmdline.version) + { + version_etc (stdout, PROGRAM_NAME, GNU_PACKAGE, VERSION, AUTHORS, + (char *) NULL); + exit (EXIT_SUCCESS); + } if (! (print_lines | print_words | print_chars | print_bytes | print_linelength)) @@ -643,7 +571,7 @@ error (0, 0, _("extra operand %s"), quote (argv[optind])); fprintf (stderr, "%s\n", _("File operands cannot be combined with --files0-from.")); - usage (EXIT_FAILURE); + usage (EXIT_FAILURE, program_name); } if (STREQ (files_from, "-")) diff -u -N -r coreutils-6.9.orig/src/wc.gp coreutils-6.9/src/wc.gp --- coreutils-6.9.orig/src/wc.gp 1970-01-01 01:00:00.000000000 +0100 +++ coreutils-6.9/src/wc.gp 2007-07-22 08:43:52.000000000 +0200 @@ -0,0 +1,24 @@ +#include <config.h> +#include "system.h" + +c / bytes flag "print the byte counts" +m / chars flag "print the character counts" +l / lines flag "print the newline counts" +NONE / files0-from=F string "read input from the files specified by" + " NUL-terminated names in file F" +L / max-line-length flag "print the length of the longest line" +w / words flag "print the word counts" +NONE / help flag "display this help and exit" +NONE / version flag "output version information and exit" + +#usage_begin +Usage: __PROGRAM_NAME__ [OPTION]... [FILE]... + or: __PROGRAM_NAME__ [OPTION]... --files0-from=F +Print newline, word, and byte counts for each FILE, and a total line if +more than one FILE is specified. With no FILE, or when FILE is -, +read standard input. + +__GLOSSARY_GNU__(25) + +Report bugs to <__STRING__(PACKAGE_BUGREPORT)>. +#usage_end
_______________________________________________ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils