bug-coreutils
[Top][All Lists]
Advanced

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

Support for `tail -10', etc. even when conforming to POSIX.1-2001


From: Paul Eggert
Subject: Support for `tail -10', etc. even when conforming to POSIX.1-2001
Date: Tue, 26 Apr 2005 09:52:26 -0700

I installed this patch to coreutils to bring back support for commonly
used commands like "tail -10" even when conforming to POSIX.1-2001, as
a compatible extension to POSIX.  There are still a few remaining
trouble spots (see the NEWS patch below) but most of the problems
should be resolved to everyone's satisfaction.  Thanks to everyone who
pushed the POSIX committee (and me :-) to get this matter clarified
and resolved.

2005-04-26  Paul Eggert  <address@hidden>

        Restore support for usages like "head -1" and "tail -1",
        even when conforming to POSIX 1003.1-2001.
        Fix bug with "POSIXLY_CORRECT=1 fold file -3".
        join now supports a NUL field separator, e.g., "join -t '\0'".
        join now detects and reports incompatible options, e.g.,
        "join -t x -t y",
        * NEWS: Document this.
        * doc/coreutils.texi (Standards conformance): Do not mention head -10,
        since it now works the same regardless of POSIX version.
        (od invocation): -w N -> -w[N].
        (pr invocation): -S STRING -> -SSTRING.
        (fold invocation): -WIDTH works even when conforming to POSIX
        1003.1-2001.
        (head invocation, tail invocation): Likewise for -NUM.
        (split invocation): Likewise for -LINES.
        (uniq invocation): Likewise for -N.
        (expand invocation, unexpand invocation): Likewise for -TAB.
        (nice invocation): Likewise for -ADJUSTMENT.
        (sort invocation): Clarify explanation of +N option.
        (uniq invocation): Likewise.
        (join invocation): Remove special case for --help, --version.
        (touch invocation): Clarify explanation of date options.
        (Options for date): -I timespec -> -I[timespec].
        * src/date.c: Remove posixver.h and its uses.
        (COMMON_SHORT_OPTIONS): Remove.
        (short_options): New constant.
        (short_options, usage): -I now always takes an optional arg.
        * src/expand.c: Remove posixver.h and its uses.
        (shortopts): New constant.  -DIGIT now always takes an optional arg.
        (main): Revamp parsing of -DIGIT to let parse_tab_stops handle it.
        Don't complain about -DIGIT.
        * src/fold.c: Remove posixver.h and its uses.
        (shortopts): New constant.  -DIGIT now always takes an optional arg.
        (main): Don't preprocess arg list; that was buggy.  Use method
        similar to expand.
        * src/head.c: Remove posixver.h and its uses.
        (header_mode_option): Remove.
        (main): Don't complain about obsolete -NUM args.
        * src/join.c: Remove posixver.h and its uses.
        (obsolete_usage): Remove.
        (join_field_1, join_field_2): Initialize to SIZE_MAX to indicate
        they haven't been set yet.
        (tab): Now int, not char.  Initialize to -1 to indicate white space
        separates columns, so that we can use NUL as a separator.
        All uses changed.
        (OBSOLETE_LONG_OPTIONS, get_option): Remove.
        (string_to_join_field): Remove ERR_MSG_FMT arg; a single format
        suffices.  Use xstrtoul for sizes; it suffices.
        (decode_field_spec): Report an error and exit on failure.  Return void,
        not bool.
        (add_field_list): Likewise.
        (set_join_field): New function.
        (enum operand_status): New enum.
        (add_file_name): New args OPERAND_STATUS, JOPTION_COUNT,
        PREV_OPTC_STATUS, OPTC_STATUS to handle the bewildering array of
        possibilities with obsolete option parsing.
        (main): Use it.  Do not depend on POSIX version.
        Check for conflicting options.  Parse obsolete options -j1 and -j2
        so that it is a pure extension to POSIX 1003.1-2001.
        Allow '-t\0' to specify a NUL tab, stealing the code from 'sort'.
        * src/nice.c: Remove posixver.h and its uses.
        (main): Always support -NUM option.
        * src/od.c: Remove posixver.h and its uses.
        (short_options): New constant, which always supports -w[num].
        (COMMON_SHORT_OPTIONS): Remove.
        * src/pr.c: Remove posixver.h and its uses.
        (short_options): New constant, which always supports -S[string].
        (COMMON_SHORT_OPTIONS): Remove.
        * src/sort.c: Remove posixver.h and its uses.
        (short_options): New constant, which always supports -y arg.
        (COMMON_SHORT_OPTIONS): Remove.
        (main): Redo workaround for Solaris compatibility with -y.
        This change isn't visible to the user; it just cleans up the
        code so that we don't need posixver.h.
        * src/split.c: Remove posixver.h and its uses.
        (main): Don't complain about -NUM option.
        * src/tail.c (parse_obsolete_option): Don't complain about -NUM.
        * src/unexpand.c: Remove posixver.h and its uses.
        (main): Don't complain about -TAB.
        * src/uniq.c (main): Don't complain about -NUM.

Index: NEWS
===================================================================
RCS file: /fetish/cu/NEWS,v
retrieving revision 1.278
diff -p -u -r1.278 NEWS
--- NEWS        23 Apr 2005 06:01:50 -0000      1.278
+++ NEWS        26 Apr 2005 16:39:24 -0000
@@ -2,7 +2,53 @@ GNU coreutils NEWS                      
 
 * Major changes in release 5.3.1 (2005-??-??) [unstable]
 
-** Changes for better compliance with POSIX
+** Bring back support for `head -NUM', `tail -NUM', etc. even when
+  conforming to POSIX 1003.1-2001.  The following changes apply only
+  when conforming to POSIX 1003.1-2001; there is no effect when
+  conforming to older POSIX versions.
+
+  The following usages now behave just as when conforming to older POSIX:
+
+    date -I
+    expand -TAB1[,TAB2,...]
+    fold -WIDTH
+    head -NUM
+    join -j FIELD
+    join -j1 FIELD
+    join -j2 FIELD
+    join -o FIELD_NAME1 FIELD_NAME2...
+    nice -NUM
+    od -w
+    pr -S
+    split -NUM
+    tail -[NUM][bcl][f] [FILE]
+
+  The following usages no longer work, due to the above changes:
+
+    date -I TIMESPEC  (use `date -ITIMESPEC' instead)
+    od -w WIDTH       (use `od -wWIDTH' instead)
+    pr -S STRING      (use `pr -SSTRING' instead)
+
+  A few usages still have behavior that depends on which POSIX standard is
+  being conformed to, and portable applications should beware these
+  problematic usages.  These include:
+
+    Problematic       Standard-conforming replacement, depending on
+       usage            whether you prefer the behavior of:
+                      POSIX 1003.2-1992    POSIX 1003.1-2001
+    sort +4           sort -k 5            sort ./+4
+    tail +4           tail -n +4           tail ./+4
+    tail - main.c     tail main.c          tail -- - main.c
+    tail -c 4         tail -c 10 ./4       tail -c4
+    touch 12312359 f  touch -t 12312359 f  touch ./12312359 f
+    uniq +4           uniq -s 4            uniq ./+4
+
+  These changes are in response to decisions taken in the January 2005
+  Austin Group standardization meeting.  For more details, please see
+  "Utility Syntax Guidelines" in the Minutes of the January 2005
+  Meeting <http://www.opengroup.org/austin/docs/austin_239.html>.
+
+** Changes for better conformance to POSIX
 
   dd changes:
 
@@ -11,6 +57,11 @@ GNU coreutils NEWS                      
     On hosts lacking the INFO signal, dd no longer treats the USR1
     signal as if it were INFO when POSIXLY_CORRECT is set.
 
+  fold changes:
+
+    When POSIXLY_CORRECT is set, "fold file -3" is now equivalent to
+    "fold file ./-3", not the obviously-erroneous "fold file ./-w3".
+
   nohup changes:
 
     nohup now ignores the umask when creating nohup.out.
@@ -63,6 +114,9 @@ GNU coreutils NEWS                      
 
 ** New features
 
+  join now supports a NUL field separator, e.g., "join -t '\0'".
+  join now detects and reports incompatible options, e.g., "join -t x -t y",
+
   stat -f -c %S outputs the fundamental block size (used for block counts).
   stat -f's default output format has been changed to output this size as well.
   stat -f recognizes file systems of type XFS and JFS
@@ -473,6 +527,7 @@ GNU coreutils NEWS                      
   "-o LIST1,LIST2..." respectively.  If join was compiled on a
   POSIX 1003.1-2001 system, you may enable the old behavior
   by setting _POSIX2_VERSION=199209 in your environment.
+  [This change was reverted in coreutils 5.3.1.]
 
 
 * Major changes in release 5.1.0 (2003-12-21):
@@ -1021,10 +1076,10 @@ point at which the packages merged to fo
    --process (-p), --runlevel (-r), --short (-s), --time (-t), --users (-u).
    The -u option now produces POSIX-specified results and is the same as
    the long option `--users'.  --idle is no longer the same as -u.
-* The following changes apply on systems conforming to POSIX 1003.1-2001,
-  and are required by the new POSIX standard:
+* The following changes apply on systems conforming to POSIX 1003.1-2001:
    - `date -I' is no longer supported.  Instead, use `date --iso-8601'.
    - `nice -NUM' is no longer supported.  Instead, use `nice -n NUM'.
+  [This change was reverted in coreutils 5.3.1.]
 * New 'uname' options -i or --hardware-platform, and -o or --operating-system.
    'uname -a' now outputs -i and -o information at the end.
    New uname option --kernel-version is an alias for -v.
Index: doc/coreutils.texi
===================================================================
RCS file: /fetish/cu/doc/coreutils.texi,v
retrieving revision 1.251
diff -p -u -r1.251 coreutils.texi
--- doc/coreutils.texi  24 Apr 2005 04:46:33 -0000      1.251
+++ doc/coreutils.texi  26 Apr 2005 16:39:26 -0000
@@ -1182,10 +1182,9 @@ environment variable to a value of the f
 the year and month the standard was adopted.  Two values are currently
 supported for @env{_POSIX2_VERSION}: @samp{199209} stands for
 @acronym{POSIX} 1003.2-1992, and @samp{200112} stands for @acronym{POSIX}
-1003.1-2001.  For example, if you are running older software that
-assumes an older version of @acronym{POSIX} and uses @samp{sort +1},
address@hidden -10}, or @samp{tail +10}, you
-can work around the compatibility problems by setting
+1003.1-2001.  For example, if you have a newer system but are running software
+that assumes an older version of @acronym{POSIX} and uses @samp{sort +1}
+or @samp{tail +10}, you can work around any compatibility problems by setting
 @samp{_POSIX2_VERSION=199209} in your environment.
 
 @node Output of entire files
@@ -1702,7 +1701,7 @@ more consecutive output lines would be i
 the first line, and puts just an asterisk on the following line to
 indicate the elision.
 
address@hidden -w @var{n}
address@hidden address@hidden
 @itemx address@hidden
 @opindex -w
 @opindex --width
@@ -1711,11 +1710,7 @@ the least common multiple of the sizes a
 output types.
 
 If this option is not given at all, the default is 16.  If @var{n} is
-omitted with @option{--width}, the default is 32.  On older systems,
address@hidden @command{od} instead supports an obsolete option
address@hidden@var{n}]}, where @var{n} also defaults to 32.  @acronym{POSIX}
-1003.1-2001 (@pxref{Standards conformance}) does not allow @option{-w}
-without an argument; use @option{--width} instead.
+omitted, the default is 32.
 
 @end table
 
@@ -2203,7 +2198,7 @@ three column options (@option{-COLUMN}|@
 @option{-w} is set.  This is a @acronym{POSIX}-compliant formulation.
 
 
address@hidden -S @var{string}
address@hidden address@hidden
 @itemx address@hidden
 @opindex -S
 @opindex --sep-string
@@ -2213,15 +2208,8 @@ does not affect line truncation or colum
 Without @option{-S}, and with @option{-J}, @command{pr} uses the default output
 separator, address@hidden
 Without @option{-S} or @option{-J}, @command{pr} uses a @samp{space}
-(same as @option{-S"@w{ }"}).  With @address@hidden,
address@hidden must be nonempty; @option{--sep-string} with no
address@hidden is equivalent to @option{--sep-string=""}.
-
-On older systems, @command{pr} instead supports an obsolete option
address@hidden@var{string}]}, where @var{string} is optional.  @acronym{POSIX}
-1003.1-2001 (@pxref{Standards conformance}) does not allow this older
-usage.  To specify an empty @var{string} portably, use
address@hidden
+(same as @option{-S"@w{ }"}).  @option{--sep-string} with no
address@hidden@var{string}} is equivalent to @option{--sep-string=""}.
 
 @item -t
 @itemx --omit-header
@@ -2328,9 +2316,8 @@ is broken at the maximum line length as 
 @opindex --width
 Use a maximum line length of @var{width} columns instead of 80.
 
-On older systems, @command{fold} supports an obsolete option
address@hidden@var{width}}.  @acronym{POSIX} 1003.1-2001 (@pxref{Standards
-conformance}) does not allow this; use @option{-w @var{width}}
+For compatibility @command{fold} supports an obsolete option syntax
address@hidden@var{width}}.  New scripts should use @option{-w @var{width}}
 instead.
 
 @end table
@@ -2416,13 +2403,13 @@ Always print file name headers.
 
 @end table
 
-On older systems, @command{head} supports an obsolete option
+For compatibility @command{head} also supports an obsolete option syntax
 @address@hidden@var{options}}, which is recognized only if it is
 specified first.  @var{count} is a decimal number optionally followed
 by a size letter (@samp{b}, @samp{k}, @samp{m}) as in @option{-c}, or
 @samp{l} to mean count by lines, or other option letters (@samp{cqv}).
address@hidden 1003.1-2001 (@pxref{Standards conformance}) does not allow
-this; use @option{-c @var{count}} or @option{-n @var{count}} instead.
+New scripts should use @option{-c @var{count}} or @option{-n
address@hidden instead.
 
 @exitstatus
 
@@ -2597,21 +2584,28 @@ Always print file name headers.
 
 @end table
 
-On older systems, @command{tail} supports an obsolete option
address@hidden@var{count}[bcl][f]}, which is recognized only if it is
-specified first.  @var{count} is an optional decimal number optionally
+For compatibility @command{tail} also supports an obsolete option
+syntax @address@hidden, which is recognized only if it
+is specified first and does not conflict with the usage described
+above.  @var{count} is an optional decimal number optionally
 followed by a size letter (@samp{b}, @samp{c}, @samp{l}) to mean count
 by 512-byte blocks, bytes, or lines, optionally followed by @samp{f}
-which has the same meaning as @option{-f}.  Also, the leading @samp{-}
-can be replaced by @samp{+} with the same meaning as in counts.
address@hidden 1003.1-2001 (@pxref{Standards conformance}) does not
-allow most of these obsolete usages; use @option{-c @var{count}[b]},
+which has the same meaning as @option{-f}.
+New scripts should use @option{-c @var{count}[b]},
 @option{-n @var{count}}, and/or @option{-f} instead.
 
-On older systems, obsolete usage overrides normal usage, so portable
-shell scripts should avoid commands that can be interpreted either
-way.  For example, use @samp{tail -- - file} rather than @samp{tail -
-file}, and use @samp{tail -c4} rather than @samp{tail -c 4}.
address@hidden _POSIX2_VERSION
+On older systems, the leading @samp{-} can be replaced by @samp{+} in
+the obsolete option syntax with the same meaning as in counts, and
+obsolete usage overrides normal usage when the two conflict.
+This obsolete behavior can be enabled or disabled with the
address@hidden environment variable (@pxref{Standards
+conformance}), but portable scripts should avoid commands whose
+behavior depends on this variable.
+For example, use @samp{tail -- - main.c} or @samp{tail main.c} rather than
+the ambiguous @samp{tail - main.c}, @samp{tail -c4} or @samp{tail -c 10
+4} rather than the ambiguous @samp{tail -c 4}, and @samp{tail ./+4}
+or @samp{tail -n +4} rather than the ambiguous @samp{tail +4}.
 
 @exitstatus
 
@@ -2659,10 +2653,9 @@ Use suffixes of length @var{length}.  Th
 @opindex --lines
 Put @var{lines} lines of @var{input} into each output file.
 
-On older systems, @command{split} supports an obsolete option
address@hidden@var{lines}}.  @acronym{POSIX} 1003.1-2001 (@pxref{Standards
-conformance}) does not allow this; use @option{-l @var{lines}}
-instead.
+For compatibility @command{split} also supports an obsolete
+option syntax @address@hidden  New scripts should use @option{-l
address@hidden instead.
 
 @item -b @var{bytes}
 @itemx address@hidden
@@ -3526,10 +3519,15 @@ numbers of leading blanks in fields can 
 
 Keys can span multiple fields.
 
address@hidden _POSIX2_VERSION
 On older systems, @command{sort} supports an obsolete origin-zero
 syntax @address@hidden address@hidden for specifying sort keys.
address@hidden 1003.1-2001 (@pxref{Standards conformance}) does not allow
-this; use @option{-k} instead.
+This obsolete behavior can be enabled or disabled with the
address@hidden environment variable (@pxref{Standards
+conformance}), but portable scripts should avoid commands whose
+behavior depends on this variable.
+For example, use @samp{sort ./+2} or @samp{sort -k 3} rather than
+the ambiguous @samp{sort +2}.
 
 Here are some examples to illustrate various combinations of options.
 
@@ -3699,9 +3697,8 @@ a null string for comparison if a line h
 are sequences of non-space non-tab characters that are separated from
 each other by at least one space or tab.
 
-On older systems, @command{uniq} supports an obsolete option
address@hidden@var{n}}.  @acronym{POSIX} 1003.1-2001 (@pxref{Standards 
conformance})
-does not allow this; use @option{-f @var{n}} instead.
+For compatibility @command{uniq} supports an obsolete option syntax
address@hidden@var{n}}.  New scripts should use @option{-f @var{n}} instead.
 
 @item -s @var{n}
 @itemx address@hidden
@@ -3711,9 +3708,15 @@ Skip @var{n} characters before checking 
 for comparison if a line has fewer than @var{n} characters.  If you use both
 the field and character skipping options, fields are skipped over first.
 
-On older systems, @command{uniq} supports an obsolete option
address@hidden@var{n}}.  @acronym{POSIX} 1003.1-2001 (@pxref{Standards 
conformance})
-does not allow this; use @option{-s @var{n}} instead.
address@hidden _POSIX2_VERSION
+On older systems, @command{uniq} supports an obsolete option syntax
address@hidden@var{n}}.
+This obsolete behavior can be enabled or disabled with the
address@hidden environment variable (@pxref{Standards
+conformance}), but portable scripts should avoid commands whose
+behavior depends on this variable.
+For example, use @samp{uniq ./+10} or @samp{uniq -s 10} rather than
+the ambiguous @samp{uniq +10}.
 
 @item -c
 @itemx --count
@@ -4753,10 +4756,6 @@ Print a line for each unpairable line in
 
 @end table
 
-In addition, when @sc{gnu} @command{join} is invoked with exactly one argument,
-the @option{--help} and @option{--version} options are recognized.
address@hidden options}.
-
 @exitstatus
 
 
@@ -5183,11 +5182,9 @@ If only one tab stop is given, set the t
 last tab stop given with single spaces.  Tab stops can be separated by
 blanks as well as by commas.
 
-On older systems, @command{expand} supports an obsolete option
address@hidden@var{tab1}[,@address@hidden, where tab stops must be
-separated by commas.  @acronym{POSIX} 1003.1-2001 (@pxref{Standards
-conformance}) does not allow this; use @option{-t
address@hidden,@address@hidden instead.
+For compatibility @command{expand} also supports an obsolete
+option syntax @address@hidden,@address@hidden  New scripts
+should use @option{-t @var{tab1}[,@address@hidden instead.
 
 @item -i
 @itemx --initial
@@ -5238,11 +5235,10 @@ instead of the default 8.  Otherwise, se
 beyond the tab stops given unchanged.  Tab stops can be separated by
 blanks as well as by commas.  This option implies the @option{-a} option.
 
-On older systems, @command{unexpand} supports an obsolete option
+For compatibility @command{unexpand} supports an obsolete option syntax
 @address@hidden,@address@hidden, where tab stops must be
 separated by commas.  (Unlike @option{-t}, this obsolete option does
-not imply @option{-a}.)  @acronym{POSIX} 1003.1-2001 (@pxref{Standards
-conformance}) does not allow this; use @option{--first-only -t
+not imply @option{-a}.)  New scripts should use @option{--first-only -t
 @var{tab1}[,@address@hidden instead.
 
 @item -a
@@ -8523,14 +8519,6 @@ specified files.  Synopsis:
 touch address@hidden@dots{} @address@hidden
 @end example
 
-On older systems, @command{touch} supports an obsolete syntax, as follows.
-If the first @var{file} would be a valid argument to the @option{-t}
-option and no timestamp is given with any of the @option{-d}, @option{-r},
-or @option{-t} options and the @samp{--} argument is not given, that
-argument is interpreted as the time for the other files instead of
-as a file name.  @acronym{POSIX} 1003.1-2001 (@pxref{Standards conformance})
-does not allow this; use @option{-t} instead.
-
 @cindex empty files, creating
 Any @var{file} that does not exist is created empty.
 
@@ -8623,7 +8611,7 @@ the origin for any relative @var{time}s 
 For example, @samp{-r foo -d '-5 seconds'} specifies a time stamp
 equal to five seconds before the corresponding time stamp for @file{foo}.
 
address@hidden -t [[CC]YY]MMDDhhmm[.ss]
address@hidden -t address@hidden@address@hidden@var{ss}]
 Use the argument (optional four-digit or two-digit years, months,
 days, hours, minutes, optional seconds) instead of the current time.
 If the year is specified with only two digits, then @var{CC}
@@ -8633,6 +8621,21 @@ the argument is interpreted as a date in
 
 @end table
 
address@hidden _POSIX2_VERSION
+On older systems, @command{touch} supports an obsolete syntax, as follows.
+If no timestamp is given with any of the @option{-d}, @option{-r}, or
address@hidden options, and if there are two or more @var{file}s and the
+first @var{file} is of the form @address@hidden@var{YY}]} and this
+would be a valid argument to the @option{-t} option (if the @var{YY}, if
+any, were moved to the front), that argument is interpreted as the time
+for the other files instead of as a file name.
+This obsolete behavior can be enabled or disabled with the
address@hidden environment variable (@pxref{Standards
+conformance}), but portable scripts should avoid commands whose
+behavior depends on this variable.
+For example, use @samp{touch ./12312359 main.c} or @samp{touch -t
+12312359 main.c} rather than the ambiguous @samp{touch 12312359 main.c}.
+
 @exitstatus
 
 
@@ -11835,9 +11838,9 @@ input.  This is useful when you have man
 system overhead of starting up the @command{date} executable many times can
 be considerable.
 
address@hidden -I @var{timespec}
address@hidden address@hidden
 @itemx address@hidden
address@hidden -I @var{timespec}
address@hidden address@hidden
 @opindex address@hidden
 Display the date using the @acronym{ISO} 8601 format, @samp{%Y-%m-%d}.
 
@@ -11845,7 +11848,7 @@ The argument @var{timespec} specifies th
 terms of the time to include.  It can be one of the following:
 @table @samp
 @item auto
-The default behavior: print just the date.
+Print just the date.  This is the default if @var{timespec} is omitted.
 
 @item hours
 Append the hour of the day to the date.
@@ -11863,13 +11866,6 @@ Append the hours, minutes, seconds, and 
 If showing any time terms, then include the time zone using the format
 @samp{%z}.
 
-If @var{timespec} is omitted with @option{--iso-8601}, the default is
address@hidden  On older systems, @sc{gnu} @command{date} instead
-supports an obsolete option @address@hidden, where
address@hidden defaults to @samp{auto}.  @acronym{POSIX} 1003.1-2001
-(@pxref{Standards conformance}) does not allow @option{-I} without an
-argument; use @option{--iso-8601} instead.
-
 @item -R
 @itemx --rfc-822
 @itemx --rfc-2822
@@ -12453,10 +12449,9 @@ Add @var{adjustment} instead of 10 to th
 @command{nice} issues a warning but otherwise acts as if you specified
 a zero adjustment.
 
-On older systems, @command{nice} supports an obsolete option
address@hidden@var{adjustment}}.  @acronym{POSIX} 1003.1-2001 (@pxref{Standards
-conformance}) does not allow this; use @option{-n @var{adjustment}}
-instead.
+For compatibility @command{nice} also supports an obsolete
+option syntax @address@hidden  New scripts should use
address@hidden @var{adjustment}} instead.
 
 @end table
 
Index: src/date.c
===================================================================
RCS file: /fetish/cu/src/date.c,v
retrieving revision 1.142
diff -p -u -r1.142 date.c
--- src/date.c  28 Mar 2005 18:00:16 -0000      1.142
+++ src/date.c  26 Apr 2005 16:39:27 -0000
@@ -32,7 +32,6 @@
 #include "getline.h"
 #include "inttostr.h"
 #include "posixtm.h"
-#include "posixver.h"
 #include "quote.h"
 #include "strftime.h"
 
@@ -79,7 +78,7 @@ static int iso_8601_format = 0;
 /* If true, display time in RFC-(2)822 format for mail or news. */
 static bool rfc_format = false;
 
-#define COMMON_SHORT_OPTIONS "Rd:f:r:s:u"
+static char const short_options[] = "d:f:I::r:Rs:u";
 
 static struct option const long_options[] =
 {
@@ -128,7 +127,7 @@ Display the current time in the given FO
 \n\
   -d, --date=STRING         display time described by STRING, not `now'\n\
   -f, --file=DATEFILE       like --date once for each line of DATEFILE\n\
-      --iso-8601[=TIMESPEC] output date/time in ISO 8601 format.\n\
+  -I[TIMESPEC], --iso-8601[=TIMESPEC]  output date/time in ISO 8601 format.\n\
                             TIMESPEC=`date' for date only (the default),\n\
                             `hours', `minutes', `seconds', or `ns' for date 
and\n\
                             time to the indicated precision.\n\
@@ -307,9 +306,6 @@ main (int argc, char **argv)
   int n_args;
   bool ok;
   int option_specified_date;
-  char const *short_options = (posix2_version () < 200112
-                              ? COMMON_SHORT_OPTIONS "I::"
-                              : COMMON_SHORT_OPTIONS "I:");
 
   initialize_main (&argc, &argv);
   program_name = argv[0];
Index: src/expand.c
===================================================================
RCS file: /fetish/cu/src/expand.c,v
retrieving revision 1.82
diff -p -u -r1.82 expand.c
--- src/expand.c        25 Mar 2005 20:59:26 -0000      1.82
+++ src/expand.c        26 Apr 2005 16:39:27 -0000
@@ -40,7 +40,6 @@
 #include <sys/types.h>
 #include "system.h"
 #include "error.h"
-#include "posixver.h"
 #include "quote.h"
 #include "xstrndup.h"
 
@@ -90,6 +89,8 @@ static bool have_read_stdin;
 /* The desired exit status.  */
 static int exit_status;
 
+static char const shortopts[] = "it:0::1::2::3::4::5::6::7::8::9::";
+
 static struct option const longopts[] =
 {
   {"tabs", required_argument, NULL, 't'},
@@ -170,18 +171,16 @@ parse_tab_stops (char const *stops)
              have_tabval = true;
              num_start = stops;
            }
-         {
-           /* Detect overflow.  */
-           if (!DECIMAL_DIGIT_ACCUMULATE (tabval, *stops - '0', UINTMAX_MAX))
-             {
-               size_t len = strspn (num_start, "0123456789");
-               char *bad_num = xstrndup (num_start, len);
-               error (0, 0, _("tab stop is too large %s"), quote (bad_num));
-               free (bad_num);
-               ok = false;
-               stops = num_start + len - 1;
-             }
-         }
+
+         if (!DECIMAL_DIGIT_ACCUMULATE (tabval, *stops - '0', UINTMAX_MAX))
+           {
+             size_t len = strspn (num_start, "0123456789");
+             char *bad_num = xstrndup (num_start, len);
+             error (0, 0, _("tab stop is too large %s"), quote (bad_num));
+             free (bad_num);
+             ok = false;
+             stops = num_start + len - 1;
+           }
        }
       else
        {
@@ -371,12 +370,8 @@ expand (void)
 int
 main (int argc, char **argv)
 {
-  bool have_tabval = false;
-  uintmax_t tabval IF_LINT (= 0);
   int c;
 
-  bool obsolete_tablist = false;
-
   initialize_main (&argc, &argv);
   program_name = argv[0];
   setlocale (LC_ALL, "");
@@ -391,51 +386,40 @@ main (int argc, char **argv)
   tab_list = NULL;
   first_free_tab = 0;
 
-  while ((c = getopt_long (argc, argv, "it:,0123456789", longopts, NULL))
-        != -1)
+  while ((c = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1)
     {
       switch (c)
        {
-       case '?':
-         usage (EXIT_FAILURE);
        case 'i':
          convert_entire_line = false;
          break;
+
        case 't':
          parse_tab_stops (optarg);
          break;
-       case ',':
-         if (have_tabval)
-           add_tab_stop (tabval);
-         have_tabval = false;
-         obsolete_tablist = true;
+
+       case '0': case '1': case '2': case '3': case '4':
+       case '5': case '6': case '7': case '8': case '9':
+         if (optarg)
+           parse_tab_stops (optarg - 1);
+         else
+           {
+             char tab_stop[2];
+             tab_stop[0] = c;
+             tab_stop[1] = '\0';
+             parse_tab_stops (tab_stop);
+           }
          break;
+
        case_GETOPT_HELP_CHAR;
+
        case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
+
        default:
-         if (!have_tabval)
-           {
-             tabval = 0;
-             have_tabval = true;
-           }
-         {
-           if (!DECIMAL_DIGIT_ACCUMULATE (tabval, c - '0', UINTMAX_MAX))
-             error (EXIT_FAILURE, 0, _("tab stop value is too large"));
-         }
-         obsolete_tablist = true;
-         break;
+         usage (EXIT_FAILURE);
        }
     }
 
-  if (obsolete_tablist && 200112 <= posix2_version ())
-    {
-      error (0, 0, _("`-LIST' option is obsolete; use `-t LIST'"));
-      usage (EXIT_FAILURE);
-    }
-
-  if (have_tabval)
-    add_tab_stop (tabval);
-
   validate_tab_stops (tab_list, first_free_tab);
 
   if (first_free_tab == 0)
Index: src/fold.c
===================================================================
RCS file: /fetish/cu/src/fold.c,v
retrieving revision 1.81
diff -p -u -r1.81 fold.c
--- src/fold.c  6 Mar 2005 16:31:31 -0000       1.81
+++ src/fold.c  26 Apr 2005 16:39:27 -0000
@@ -25,7 +25,6 @@
 
 #include "system.h"
 #include "error.h"
-#include "posixver.h"
 #include "xstrtol.h"
 
 #define TAB_WIDTH 8
@@ -47,6 +46,8 @@ static bool count_bytes;
 /* If nonzero, at least one of the files we read was standard input. */
 static bool have_read_stdin;
 
+static char const shortopts[] = "bsw:0::1::2::3::4::5::6::7::8::9::";
+
 static struct option const longopts[] =
 {
   {"bytes", no_argument, NULL, 'b'},
@@ -255,33 +256,10 @@ main (int argc, char **argv)
 
   break_spaces = count_bytes = have_read_stdin = false;
 
-  /* Turn any numeric options into -w options.  */
-  for (i = 1; i < argc; i++)
+  while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1)
     {
-      char const *a = argv[i];
-      if (a[0] == '-')
-       {
-         if (a[1] == '-' && ! a[2])
-           break;
-         if (ISDIGIT (a[1]))
-           {
-             size_t len_a = strlen (a);
-             char *s = xmalloc (len_a + 2);
-             s[0] = '-';
-             s[1] = 'w';
-             memcpy (s + 2, a + 1, len_a);
-             argv[i] = s;
-             if (200112 <= posix2_version ())
-               {
-                 error (0, 0, _("`%s' option is obsolete; use `%s'"), a, s);
-                 usage (EXIT_FAILURE);
-               }
-           }
-       }
-    }
+      char optargbuf[2];
 
-  while ((optc = getopt_long (argc, argv, "bsw:", longopts, NULL)) != -1)
-    {
       switch (optc)
        {
        case 'b':               /* Count bytes rather than columns. */
@@ -292,6 +270,17 @@ main (int argc, char **argv)
          break_spaces = true;
          break;
 
+       case '0': case '1': case '2': case '3': case '4':
+       case '5': case '6': case '7': case '8': case '9':
+         if (optarg)
+           optarg--;
+         else
+           {
+             optargbuf[0] = optc;
+             optargbuf[1] = '\0';
+             optarg = optargbuf;
+           }
+         /* Fall through.  */
        case 'w':               /* Line width. */
          {
            unsigned long int tmp_ulong;
Index: src/head.c
===================================================================
RCS file: /fetish/cu/src/head.c,v
retrieving revision 1.98
diff -p -u -r1.98 head.c
--- src/head.c  11 Apr 2005 20:07:37 -0000      1.98
+++ src/head.c  26 Apr 2005 16:39:27 -0000
@@ -36,7 +36,6 @@
 #include "full-write.h"
 #include "full-read.h"
 #include "inttostr.h"
-#include "posixver.h"
 #include "quote.h"
 #include "safe-read.h"
 #include "xstrtol.h"
@@ -64,9 +63,6 @@ enum header_mode
   multiple_files, always, never
 };
 
-/* Options corresponding to header_mode values.  */
-static char const header_mode_option[][4] = { "", " -v", " -q" };
-
 /* The name this program was run with. */
 char *program_name;
 
@@ -996,17 +992,6 @@ main (int argc, char **argv)
            }
        }
 
-      if (200112 <= posix2_version ())
-       {
-         int n_string_prefix_len = end_n_string - n_string;
-         error (0, 0, _("`-%s' option is obsolete; use `-%c %.*s%.*s%s'"),
-                n_string, count_lines ? 'n' : 'c',
-                n_string_prefix_len, n_string,
-                multiplier_char != 0, &multiplier_char,
-                header_mode_option[header_mode]);
-         usage (EXIT_FAILURE);
-       }
-
       /* Append the multiplier character (if any) onto the end of
         the digit string.  Then add NUL byte if necessary.  */
       *end_n_string = multiplier_char;
@@ -1019,9 +1004,6 @@ main (int argc, char **argv)
       argv[1] = argv[0];
       argv++;
       argc--;
-
-      /* FIXME: allow POSIX options if there were obsolescent ones?  */
-
     }
 
   while ((c = getopt_long (argc, argv, "c:n:qv", long_options, NULL)) != -1)
Index: src/join.c
===================================================================
RCS file: /fetish/cu/src/join.c,v
retrieving revision 1.135
diff -p -u -r1.135 join.c
--- src/join.c  11 Apr 2005 20:07:54 -0000      1.135
+++ src/join.c  26 Apr 2005 16:39:27 -0000
@@ -29,7 +29,6 @@
 #include "hard-locale.h"
 #include "linebuffer.h"
 #include "memcasecmp.h"
-#include "posixver.h"
 #include "quote.h"
 #include "stdio-safer.h"
 #include "xmemcoll.h"
@@ -87,9 +86,6 @@ char *program_name;
 /* True if the LC_COLLATE locale is hard.  */
 static bool hard_LC_COLLATE;
 
-/* True if obsolete option usage should be supported.  */
-static bool obsolete_usage;
-
 /* If nonzero, print unpairable lines in file 1 or 2.  */
 static bool print_unpairables_1, print_unpairables_2;
 
@@ -99,8 +95,9 @@ static bool print_pairables;
 /* Empty output field filler.  */
 static char const *empty_filler;
 
-/* Field to join on.  */
-static size_t join_field_1, join_field_2;
+/* Field to join on; SIZE_MAX means they haven't been determined yet.  */
+static size_t join_field_1 = SIZE_MAX;
+static size_t join_field_2 = SIZE_MAX;
 
 /* List of fields to print.  */
 static struct outlist outlist_head;
@@ -108,46 +105,25 @@ static struct outlist outlist_head;
 /* Last element in `outlist', where a new element can be added.  */
 static struct outlist *outlist_end = &outlist_head;
 
-/* Tab character separating fields; if this is NUL fields are separated
-   by any nonempty string of white space, otherwise by exactly one
-   tab character.  */
-static char tab;
+/* Tab character separating fields.  If negative, fields are separated
+   by any nonempty string of blanks, otherwise by exactly one
+   tab character whose value (when cast to unsigned char) equals TAB.  */
+static int tab = -1;
 
-/* When using getopt_long_only, no long option can start with
-   a character that is a short option.  */
 static struct option const longopts[] =
 {
-  /* These three options are obsolete; see OBSOLETE_LONG_OPTIONS below.  */
-  {"j", required_argument, NULL, 'j'},
-  {"j1", required_argument, NULL, '1'},
-  {"j2", required_argument, NULL, '2'},
-
   {"ignore-case", no_argument, NULL, 'i'},
   {GETOPT_HELP_OPTION_DECL},
   {GETOPT_VERSION_OPTION_DECL},
   {NULL, 0, NULL, 0}
 };
 
-/* Number of options at the start of longopts that are obsolete.  */
-enum { OBSOLETE_LONG_OPTIONS = 3 };
-
 /* Used to print non-joining lines */
 static struct line uni_blank;
 
 /* If nonzero, ignore case when comparing join fields.  */
 static bool ignore_case;
 
-/* Get the next option from the argument vector.  */
-
-static int
-get_option (int argc, char **argv)
-{
-  return (obsolete_usage
-         ? getopt_long_only (argc, argv, "-a:e:i1:2:o:t:v:", longopts, NULL)
-         : getopt_long (argc, argv, "a:e:ij:1:2:o:t:v:",
-                        longopts + OBSOLETE_LONG_OPTIONS, NULL));
-}
-
 void
 usage (int status)
 {
@@ -232,11 +208,10 @@ xfields (struct line *line)
   if (ptr == lim)
     return;
 
-  if (tab)
+  if (0 <= tab)
     {
-      unsigned char t = tab;
       char *sep;
-      for (; (sep = memchr (ptr, t, lim - ptr)) != NULL; ptr = sep + 1)
+      for (; (sep = memchr (ptr, tab, lim - ptr)) != NULL; ptr = sep + 1)
        extract_field (line, ptr, sep - ptr);
     }
   else
@@ -415,7 +390,7 @@ static void
 prjoin (struct line const *line1, struct line const *line2)
 {
   const struct outlist *outlist;
-  char output_separator = tab ? tab : ' ';
+  char output_separator = tab < 0 ? ' ' : tab;
 
   outlist = outlist_head.next;
   if (outlist)
@@ -637,12 +612,12 @@ add_field (int file, size_t field)
    diagnostic and exit.  */
 
 static size_t
-string_to_join_field (char const *str, char const *err_msg_fmt)
+string_to_join_field (char const *str)
 {
   size_t result;
-  uintmax_t val;
+  unsigned long int val;
 
-  strtol_error s_err = xstrtoumax (str, NULL, 10, &val, "");
+  strtol_error s_err = xstrtoul (str, NULL, 10, &val, "");
   if (s_err == LONGINT_OVERFLOW || (s_err == LONGINT_OK && SIZE_MAX < val))
     {
       error (EXIT_FAILURE, 0,
@@ -651,7 +626,7 @@ string_to_join_field (char const *str, c
     }
 
   if (s_err != LONGINT_OK || val == 0)
-    error (EXIT_FAILURE, 0, err_msg_fmt, quote (str));
+    error (EXIT_FAILURE, 0, _("invalid field number: %s"), quote (str));
 
   result = val - 1;
 
@@ -660,53 +635,42 @@ string_to_join_field (char const *str, c
 
 /* Convert a single field specifier string, S, to a *FILE_INDEX, *FIELD_INDEX
    pair.  In S, the field index string is 1-based; *FIELD_INDEX is zero-based.
-   If S is valid, return true.  Otherwise, give a diagnostic, don't update
-   *FILE_INDEX or *FIELD_INDEX, and return false.  */
+   If S is valid, return true.  Otherwise, give a diagnostic and exit.  */
 
-static bool
+static void
 decode_field_spec (const char *s, int *file_index, size_t *field_index)
 {
-  bool valid = false;
-
   /* The first character must be 0, 1, or 2.  */
   switch (s[0])
     {
     case '0':
-      if (s[1] == '\0')
-       {
-         *file_index = 0;
-         *field_index = 0;
-         valid = true;
-       }
-      else
+      if (s[1])
         {
          /* `0' must be all alone -- no `.FIELD'.  */
-         error (0, 0, _("invalid field specifier: `%s'"), s);
+         error (EXIT_FAILURE, 0, _("invalid field specifier: %s"), quote (s));
        }
+      *file_index = 0;
+      *field_index = 0;
       break;
 
     case '1':
     case '2':
-      if (s[1] == '.' && s[2] != '\0')
-        {
-         *field_index
-           = string_to_join_field (s + 2, _("invalid field number: %s"));
-         *file_index = s[0] - '0';
-         valid = true;
-       }
+      if (s[1] != '.')
+       error (EXIT_FAILURE, 0, _("invalid field specifier: %s"), quote (s));
+      *file_index = s[0] - '0';
+      *field_index = string_to_join_field (s + 2);
       break;
 
     default:
-      error (0, 0, _("invalid file number in field spec: `%s'"), s);
+      error (EXIT_FAILURE, 0,
+            _("invalid file number in field spec: %s"), quote (s));
       break;
     }
-  return valid;
 }
 
-/* Add the comma or blank separated field spec(s) in STR to `outlist'.
-   Return true if successful.  */
+/* Add the comma or blank separated field spec(s) in STR to `outlist'.  */
 
-static bool
+static void
 add_field_list (char *str)
 {
   char *p = str;
@@ -719,36 +683,108 @@ add_field_list (char *str)
 
       p = strpbrk (p, ", \t");
       if (p)
-        *p++ = 0;
-      if (! decode_field_spec (spec_item, &file_index, &field_index))
-       return false;
+        *p++ = '\0';
+      decode_field_spec (spec_item, &file_index, &field_index);
       add_field (file_index, field_index);
     }
   while (p);
+}
 
-  return true;
+/* Set the join field *VAR to VAL, but report an error if *VAR is set
+   more than once to incompatible values.  */
+
+static void
+set_join_field (size_t *var, size_t val)
+{
+  if (*var != SIZE_MAX && *var != val)
+    {
+      unsigned long int var1 = *var + 1;
+      unsigned long int val1 = val + 1;
+      error (EXIT_FAILURE, 0, _("incompatible join fields %lu, %lu"),
+            var1, val1);
+    }
+  *var = val;
 }
 
-/* Add NAME to the array of input file NAMES; currently there are
-   *NFILES names in the list.  */
+/* Status of command-line arguments.  */
+
+enum operand_status
+  {
+    /* This argument must be an operand, i.e., one of the files to be
+       joined.  */
+    MUST_BE_OPERAND,
+
+    /* This might be the argument of the preceding -j1 or -j2 option,
+       or it might be an operand.  */
+    MIGHT_BE_J1_ARG,
+    MIGHT_BE_J2_ARG,
+
+    /* This might be the argument of the preceding -o option, or it might be
+       an operand.  */
+    MIGHT_BE_O_ARG
+  };
+
+/* Add NAME to the array of input file NAMES with operand statuses
+   OPERAND_STATUS; currently there are NFILES names in the list.  */
 
 static void
-add_file_name (char const *name, char const *names[2], int *nfiles)
+add_file_name (char *name, char *names[2],
+              int operand_status[2], int joption_count[2], int *nfiles,
+              int *prev_optc_status, int *optc_status)
 {
-  if (*nfiles == 2)
+  int n = *nfiles;
+
+  if (n == 2)
     {
-      error (0, 0, _("extra operand %s"), quote (name));
-      usage (EXIT_FAILURE);
+      bool op0 = (operand_status[0] == MUST_BE_OPERAND);
+      char *arg = names[op0];
+      switch (operand_status[op0])
+       {
+       case MUST_BE_OPERAND:
+         error (0, 0, _("extra operand %s"), quote (name));
+         usage (EXIT_FAILURE);
+
+       case MIGHT_BE_J1_ARG:
+         joption_count[0]--;
+         set_join_field (&join_field_1, string_to_join_field (arg));
+         break;
+
+       case MIGHT_BE_J2_ARG:
+         joption_count[1]--;
+         set_join_field (&join_field_2, string_to_join_field (arg));
+         break;
+
+       case MIGHT_BE_O_ARG:
+         add_field_list (arg);
+         break;
+       }
+      if (!op0)
+       {
+         operand_status[0] = operand_status[1];
+         names[0] = names[1];
+       }
+      n = 1;
     }
-  names[(*nfiles)++] = name;
+
+  operand_status[n] = *prev_optc_status;
+  names[n] = name;
+  *nfiles = n + 1;
+  if (*prev_optc_status == MIGHT_BE_O_ARG)
+    *optc_status = MIGHT_BE_O_ARG;
 }
 
 int
 main (int argc, char **argv)
 {
-  char const *names[2];
+  int optc_status;
+  int prev_optc_status = MUST_BE_OPERAND;
+  int operand_status[2];
+  int joption_count[2] = { 0, 0 };
+  char *names[2];
   FILE *fp1, *fp2;
-  int optc, prev_optc = 0, nfiles;
+  int optc;
+  int nfiles = 0;
+  int i;
 
   initialize_main (&argc, &argv);
   program_name = argv[0];
@@ -756,16 +792,16 @@ main (int argc, char **argv)
   bindtextdomain (PACKAGE, LOCALEDIR);
   textdomain (PACKAGE);
   hard_LC_COLLATE = hard_locale (LC_COLLATE);
-  obsolete_usage = (posix2_version () < 200112);
 
   atexit (close_stdout);
 
-  nfiles = 0;
   print_pairables = true;
 
-  while ((optc = get_option (argc, argv)) != -1)
+  while ((optc = getopt_long (argc, argv, "-a:e:i1:2:j:o:t:v:",
+                             longopts, NULL))
+        != -1)
     {
-      long int val;
+      optc_status = MUST_BE_OPERAND;
 
       switch (optc)
        {
@@ -774,16 +810,23 @@ main (int argc, char **argv)
            /* Fall through.  */
 
        case 'a':
-         if (xstrtol (optarg, NULL, 10, &val, "") != LONGINT_OK
-             || (val != 1 && val != 2))
-           error (EXIT_FAILURE, 0, _("invalid field number: `%s'"), optarg);
-         if (val == 1)
-           print_unpairables_1 = true;
-         else
-           print_unpairables_2 = true;
+         {
+           unsigned long int val;
+           if (xstrtoul (optarg, NULL, 10, &val, "") != LONGINT_OK
+               || (val != 1 && val != 2))
+             error (EXIT_FAILURE, 0,
+                    _("invalid field number: %s"), quote (optarg));
+           if (val == 1)
+             print_unpairables_1 = true;
+           else
+             print_unpairables_2 = true;
+         }
          break;
 
        case 'e':
+         if (empty_filler && ! STREQ (empty_filler, optarg))
+           error (EXIT_FAILURE, 0,
+                  _("conflicting empty-field replacement strings"));
          empty_filler = optarg;
          break;
 
@@ -792,42 +835,56 @@ main (int argc, char **argv)
          break;
 
        case '1':
-         join_field_1 =
-           string_to_join_field (optarg,
-                                 _("invalid field number for file 1: `%s'"));
+         set_join_field (&join_field_1, string_to_join_field (optarg));
          break;
 
        case '2':
-         join_field_2 =
-           string_to_join_field (optarg,
-                                 _("invalid field number for file 2: `%s'"));
+         set_join_field (&join_field_2, string_to_join_field (optarg));
          break;
 
        case 'j':
-         join_field_1 = join_field_2 =
-           string_to_join_field (optarg,
-                                 _("invalid field number: `%s'"));
+         if ((optarg[0] == '1' || optarg[0] == '2') && !optarg[1]
+             && optarg == argv[optind - 1] + 2)
+           {
+             /* The argument was either "-j1" or "-j2".  */
+             bool is_j2 = (optarg[0] == '2');
+             joption_count[is_j2]++;
+             optc_status = MIGHT_BE_J1_ARG + is_j2;
+           }
+         else
+           {
+             set_join_field (&join_field_1, string_to_join_field (optarg));
+             set_join_field (&join_field_2, join_field_1);
+           }
          break;
 
        case 'o':
-         if (! add_field_list (optarg))
-           exit (EXIT_FAILURE);
+         add_field_list (optarg);
+         optc_status = MIGHT_BE_O_ARG;
          break;
 
        case 't':
-         tab = *optarg;
+         {
+           unsigned char newtab = optarg[0];
+           if (! newtab)
+             error (EXIT_FAILURE, 0, _("empty tab"));
+           if (optarg[1])
+             {
+               if (STREQ (optarg, "\\0"))
+                 newtab = '\0';
+               else
+                 error (EXIT_FAILURE, 0, _("multi-character tab `%s'"),
+                        optarg);
+             }
+           if (0 <= tab && tab != newtab)
+             error (EXIT_FAILURE, 0, _("incompatible tabs"));
+           tab = newtab;
+         }
          break;
 
        case 1:         /* Non-option argument.  */
-         if (prev_optc == 'o' && optind <= argc - 2)
-           {
-             if (! add_field_list (optarg))
-               exit (EXIT_FAILURE);
-
-             /* Might be continuation of args to -o.  */
-             continue;         /* Don't change `prev_optc'.  */
-           }
-         add_file_name (optarg, names, &nfiles);
+         add_file_name (optarg, names, operand_status, joption_count,
+                        &nfiles, &prev_optc_status, &optc_status);
          break;
 
        case_GETOPT_HELP_CHAR;
@@ -837,12 +894,15 @@ main (int argc, char **argv)
        default:
          usage (EXIT_FAILURE);
        }
-      prev_optc = optc;
+
+      prev_optc_status = optc_status;
     }
 
-  if (! obsolete_usage)
-    while (optind < argc)
-      add_file_name (argv[optind++], names, &nfiles);
+  /* Process any operands after "--".  */
+  prev_optc_status = MUST_BE_OPERAND;
+  while (optind < argc)
+    add_file_name (argv[optind++], names, operand_status, joption_count,
+                  &nfiles, &prev_optc_status, &optc_status);
 
   if (nfiles != 2)
     {
@@ -853,6 +913,20 @@ main (int argc, char **argv)
       usage (EXIT_FAILURE);
     }
 
+  /* If "-j1" was specified and it turns out not to have had an argument,
+     treat it as "-j 1".  Likewise for -j2.  */
+  for (i = 0; i < 2; i++)
+    if (joption_count[i] != 0)
+      {
+       set_join_field (&join_field_1, i);
+       set_join_field (&join_field_2, i);
+      }
+
+  if (join_field_1 == SIZE_MAX)
+    join_field_1 = 0;
+  if (join_field_2 == SIZE_MAX)
+    join_field_2 = 0;
+
   fp1 = STREQ (names[0], "-") ? stdin : fopen_safer (names[0], "r");
   if (!fp1)
     error (EXIT_FAILURE, errno, "%s", names[0]);
Index: src/nice.c
===================================================================
RCS file: /fetish/cu/src/nice.c,v
retrieving revision 1.79
diff -p -u -r1.79 nice.c
--- src/nice.c  23 Apr 2005 05:39:55 -0000      1.79
+++ src/nice.c  26 Apr 2005 16:39:27 -0000
@@ -35,7 +35,6 @@
 
 #include "error.h"
 #include "long-options.h"
-#include "posixver.h"
 #include "xstrtol.h"
 
 /* The official name of this program (e.g., no `g' prefix).  */
@@ -118,8 +117,7 @@ main (int argc, char **argv)
     {
       char const *s = argv[i];
 
-      if (s[0] == '-' && ISDIGIT (s[1 + (s[1] == '-' || s[1] == '+')])
-         && posix2_version () < 200112)
+      if (s[0] == '-' && ISDIGIT (s[1 + (s[1] == '-' || s[1] == '+')]))
        {
          adjustment_given = s + 1;
          ++i;
Index: src/od.c
===================================================================
RCS file: /fetish/cu/src/od.c,v
retrieving revision 1.154
diff -p -u -r1.154 od.c
--- src/od.c    11 Apr 2005 20:09:01 -0000      1.154
+++ src/od.c    26 Apr 2005 16:39:27 -0000
@@ -25,7 +25,6 @@
 #include <sys/types.h>
 #include "system.h"
 #include "error.h"
-#include "posixver.h"
 #include "quote.h"
 #include "xstrtol.h"
 
@@ -262,7 +261,7 @@ static enum size_spec integral_type_size
 #define MAX_FP_TYPE_SIZE sizeof (LONG_DOUBLE)
 static enum size_spec fp_type_size[MAX_FP_TYPE_SIZE + 1];
 
-#define COMMON_SHORT_OPTIONS "A:aBbcDdeFfHhIij:LlN:OoS:st:vXx"
+static char const short_options[] = "A:aBbcDdeFfHhIij:LlN:OoS:st:vw::Xx";
 
 /* For long options that have no equivalent short option, use a
    non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
@@ -1550,9 +1549,6 @@ main (int argc, char **argv)
   bool modern = false;
   bool width_specified = false;
   bool ok = true;
-  char const *short_options = (posix2_version () < 200112
-                              ? COMMON_SHORT_OPTIONS "w::"
-                              : COMMON_SHORT_OPTIONS "w:");
 
   /* The old-style `pseudo starting address' to be printed in parentheses
      after any true address.  */
Index: src/pr.c
===================================================================
RCS file: /fetish/cu/src/pr.c,v
retrieving revision 1.143
diff -p -u -r1.143 pr.c
--- src/pr.c    11 Apr 2005 20:09:42 -0000      1.143
+++ src/pr.c    26 Apr 2005 16:39:28 -0000
@@ -319,7 +319,6 @@
 #include "hard-locale.h"
 #include "inttostr.h"
 #include "mbswidth.h"
-#include "posixver.h"
 #include "stdio-safer.h"
 #include "strftime.h"
 #include "xstrtol.h"
@@ -740,8 +739,8 @@ enum
   PAGES_OPTION
 };
 
-#define COMMON_SHORT_OPTIONS \
-       "-0123456789D:FJN:TW:abcde::fh:i::l:mn::o:rs::tvw:"
+static char const short_options[] =
+  "-0123456789D:FJN:S::TW:abcde::fh:i::l:mn::o:rs::tvw:";
 
 static struct option const long_options[] =
 {
@@ -869,10 +868,6 @@ main (int argc, char **argv)
   size_t n_digits = 0;
   size_t n_alloc = 0;
 
-  char const *short_options = (posix2_version () < 200112
-                              ? COMMON_SHORT_OPTIONS "S::"
-                              : COMMON_SHORT_OPTIONS "S:");
-
   initialize_main (&argc, &argv);
   program_name = argv[0];
   setlocale (LC_ALL, "");
Index: src/sort.c
===================================================================
RCS file: /fetish/cu/src/sort.c,v
retrieving revision 1.307
diff -p -u -r1.307 sort.c
--- src/sort.c  11 Apr 2005 20:10:52 -0000      1.307
+++ src/sort.c  26 Apr 2005 16:39:28 -0000
@@ -354,7 +354,7 @@ native byte values.\n\
   exit (status);
 }
 
-#define COMMON_SHORT_OPTIONS "-bcdfgik:mMno:rsS:t:T:uz"
+static char const short_options[] = "-bcdfgik:mMno:rsS:t:T:uy:z";
 
 static struct option const long_options[] =
 {
@@ -2300,9 +2300,6 @@ main (int argc, char **argv)
   size_t nfiles = 0;
   bool posixly_correct = (getenv ("POSIXLY_CORRECT") != NULL);
   bool obsolete_usage = (posix2_version () < 200112);
-  char const *short_options = (obsolete_usage
-                              ? COMMON_SHORT_OPTIONS "y::"
-                              : COMMON_SHORT_OPTIONS "y:");
   char *minus = "-", **files;
   char const *outfile = NULL;
 
@@ -2582,12 +2579,12 @@ main (int argc, char **argv)
             emulate Solaris 8 and 9 "sort -y 100" which ignores the "100",
             and which in general ignores the argument after "-y" if it
             consists entirely of digits (it can even be empty).  */
-         if (!optarg && optind != argc)
+         if (optarg == argv[optind - 1])
            {
              char const *p;
-             for (p = argv[optind]; ISDIGIT (*p); p++)
+             for (p = optarg; ISDIGIT (*p); p++)
                continue;
-             optind += !*p;
+             optind -= (*p != '\0');
            }
          break;
 
Index: src/split.c
===================================================================
RCS file: /fetish/cu/src/split.c,v
retrieving revision 1.105
diff -p -u -r1.105 split.c
--- src/split.c 11 Apr 2005 20:11:08 -0000      1.105
+++ src/split.c 26 Apr 2005 16:39:28 -0000
@@ -34,7 +34,6 @@
 #include "full-read.h"
 #include "full-write.h"
 #include "inttostr.h"
-#include "posixver.h"
 #include "quote.h"
 #include "safe-read.h"
 #include "unistd-safer.h"
@@ -510,14 +509,6 @@ main (int argc, char **argv)
        }
     }
 
-  if (digits_optind && 200112 <= posix2_version ())
-    {
-      char buffer[INT_BUFSIZE_BOUND (uintmax_t)];
-      char const *a = umaxtostr (n_units, buffer);
-      error (0, 0, _("`-%s' option is obsolete; use `-l %s'"), a, a);
-      usage (EXIT_FAILURE);
-    }
-
   /* Handle default case.  */
   if (split_type == type_undef)
     {
@@ -527,8 +518,6 @@ main (int argc, char **argv)
 
   if (n_units == 0)
     {
-      /* FIXME: be sure to remove this block when removing
-        support for obsolete options like `-10'.  */
       error (0, 0, _("invalid number of lines: 0"));
       usage (EXIT_FAILURE);
     }
Index: src/tail.c
===================================================================
RCS file: /fetish/cu/src/tail.c,v
retrieving revision 1.234
diff -p -u -r1.234 tail.c
--- src/tail.c  11 Apr 2005 20:12:01 -0000      1.234
+++ src/tail.c  26 Apr 2005 16:39:28 -0000
@@ -1411,8 +1411,8 @@ parse_obsolete_option (int argc, char * 
     case '-':
       /* In the non-obsolete form, "-" is standard input and "-c"
         requires an option-argument.  The obsolete multidigit options
-        are diagnosed more nicely below than they would be if we
-        simply returned false here.  */
+        are supported as a GNU extension even when conforming to
+        POSIX 1003.1-2001, so don't complain about them.  */
       if (!obsolete_usage && !p[p[0] == 'c'])
        return false;
 
@@ -1443,21 +1443,10 @@ parse_obsolete_option (int argc, char * 
 
   if (n_string == n_string_end)
     *n_units = default_count;
-  else
-    {
-      if ((xstrtoumax (n_string, NULL, 10, n_units, "b")
-          & ~LONGINT_INVALID_SUFFIX_CHAR)
-         != LONGINT_OK)
-       error (EXIT_FAILURE, 0, _("number in `%s' is too large"), argv[1]);
-
-      if (!obsolete_usage)
-       {
-         error (0, 0, _("`%s' option is obsolete; use `%s-%c %"PRIuMAX"'"),
-                argv[1], t_forever ? "-f " : "", t_count_lines ? 'n' : 'c',
-                *n_units);
-         usage (EXIT_FAILURE);
-       }
-    }
+  else if ((xstrtoumax (n_string, NULL, 10, n_units, "b")
+           & ~LONGINT_INVALID_SUFFIX_CHAR)
+          != LONGINT_OK)
+    error (EXIT_FAILURE, 0, _("number in `%s' is too large"), argv[1]);
 
   /* Set globals.  */
   from_start = t_from_start;
Index: src/unexpand.c
===================================================================
RCS file: /fetish/cu/src/unexpand.c,v
retrieving revision 1.89
diff -p -u -r1.89 unexpand.c
--- src/unexpand.c      11 Apr 2005 20:13:10 -0000      1.89
+++ src/unexpand.c      26 Apr 2005 16:39:29 -0000
@@ -41,7 +41,6 @@
 #include <sys/types.h>
 #include "system.h"
 #include "error.h"
-#include "posixver.h"
 #include "quote.h"
 #include "xstrndup.h"
 
@@ -469,8 +468,6 @@ main (int argc, char **argv)
      so that only leading blanks will be considered.  */
   bool convert_first_only = false;
 
-  bool obsolete_tablist = false;
-
   initialize_main (&argc, &argv);
   program_name = argv[0];
   setlocale (LC_ALL, "");
@@ -506,7 +503,6 @@ main (int argc, char **argv)
          if (have_tabval)
            add_tab_stop (tabval);
          have_tabval = false;
-         obsolete_tablist = true;
          break;
        case_GETOPT_HELP_CHAR;
        case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
@@ -516,22 +512,12 @@ main (int argc, char **argv)
              tabval = 0;
              have_tabval = true;
            }
-         {
-           if (!DECIMAL_DIGIT_ACCUMULATE (tabval, c - '0', UINTMAX_MAX))
-             error (EXIT_FAILURE, 0, _("tab stop value is too large"));
-         }
-         obsolete_tablist = true;
+         if (!DECIMAL_DIGIT_ACCUMULATE (tabval, c - '0', UINTMAX_MAX))
+           error (EXIT_FAILURE, 0, _("tab stop value is too large"));
          break;
        }
     }
 
-  if (obsolete_tablist && 200112 <= posix2_version ())
-    {
-      error (0, 0,
-            _("`-LIST' option is obsolete; use `--first-only -t LIST'"));
-      usage (EXIT_FAILURE);
-    }
-
   if (convert_first_only)
     convert_entire_line = false;
 
Index: src/uniq.c
===================================================================
RCS file: /fetish/cu/src/uniq.c,v
retrieving revision 1.121
diff -p -u -r1.121 uniq.c
--- src/uniq.c  11 Apr 2005 20:13:26 -0000      1.121
+++ src/uniq.c  26 Apr 2005 16:39:29 -0000
@@ -510,7 +510,7 @@ main (int argc, char **argv)
                                        delimit_method_map);
          break;
 
-       case 'f':               /* Like '-#'. */
+       case 'f':
          skip_field_option_type = SFO_NEW;
          skip_fields = size_opt (optarg,
                                  N_("invalid number of fields to skip"));
@@ -520,7 +520,7 @@ main (int argc, char **argv)
          ignore_case = true;
          break;
 
-       case 's':               /* Like '+#'. */
+       case 's':
          skip_chars = size_opt (optarg,
                                 N_("invalid number of bytes to skip"));
          break;
@@ -543,13 +543,6 @@ main (int argc, char **argv)
        }
     }
 
-  if (skip_field_option_type == SFO_OBSOLETE && 200112 <= posix2_version ())
-    {
-      error (0, 0, _("`-%lu' option is obsolete; use `-f %lu'"),
-            (unsigned long int) skip_fields, (unsigned long int) skip_fields);
-      usage (EXIT_FAILURE);
-    }
-
   if (countmode == count_occurrences && output_later_repeated)
     {
       error (0, 0,




reply via email to

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