summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2001-08-25 15:07:17 +0000
committerJim Meyering <jim@meyering.net>2001-08-25 15:07:17 +0000
commitba2900b4aabaf468ba28a06812d2ea9c46743b25 (patch)
tree6afabf072805ba1d09e80408279c7fba18eba419 /src
parent1774bc1d786be3711607d381af58505eb1caf224 (diff)
downloadcoreutils-ba2900b4aabaf468ba28a06812d2ea9c46743b25.tar.xz
(main): Fix some more incompatibilities with POSIX.2,
(e.g. `uniq +3 --' did not work) by invoking getopt_long with leading '-', resembling what was done to 'sort' on 2001-03-20. Recognize an +N option only if it is an integer in range, and (if POSIXLY_CORRECT) only if a file name argument has not been seen; otherwise silently treat it as a file name. If the user specifies too many operands, output the first one in the error message, as a diagnostic aid.
Diffstat (limited to 'src')
-rw-r--r--src/uniq.c66
1 files changed, 38 insertions, 28 deletions
diff --git a/src/uniq.c b/src/uniq.c
index 21f4ab07a..36119cff8 100644
--- a/src/uniq.c
+++ b/src/uniq.c
@@ -378,9 +378,12 @@ check_file (const char *infile, const char *outfile)
int
main (int argc, char **argv)
{
- int optc;
- char *infile = "-", *outfile = "-";
+ int optc = 0;
+ int posixly_correct = (getenv ("POSIXLY_CORRECT") != NULL);
+ int nfiles = 0;
+ char const *file[2];
+ file[0] = file[1] = "-";
program_name = argv[0];
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
@@ -395,12 +398,40 @@ main (int argc, char **argv)
countmode = count_none;
delimit_groups = DM_NONE;
- while ((optc = getopt_long (argc, argv, "0123456789cdDf:is:uw:", longopts,
- NULL)) != -1)
+ for (;;)
{
- switch (optc)
+ /* Parse an operand with leading "+" as a file after "--" was
+ seen; or if pedantic and a file was seen. POSIX 1003.1-200x
+ d7 removes support for such operands, so when it becomes
+ official the code will need to be changed. */
+
+ if (optc == -1
+ || (posixly_correct && nfiles != 0)
+ || ((optc = getopt_long (argc, argv,
+ "-0123456789cdDf:is:uw:", longopts, NULL))
+ == -1))
{
- case 0:
+ if (optind == argc)
+ break;
+ file[nfiles++] = argv[optind++];
+ }
+ else switch (optc)
+ {
+ case 1:
+ {
+ unsigned long int size;
+ if (optarg[0] == '+'
+ && xstrtoul (optarg, NULL, 10, &size, "") == LONGINT_OK
+ && size <= SIZE_MAX)
+ skip_chars = size;
+ else if (nfiles == 2)
+ {
+ error (0, 0, _("extra operand `%s'"), optarg);
+ usage (1);
+ }
+ else
+ file[nfiles++] = optarg;
+ }
break;
case '0':
@@ -472,27 +503,6 @@ main (int argc, char **argv)
}
}
- if (optind < argc && !STREQ (argv[optind - 1], "--"))
- {
- /* Interpret non-option arguments with leading `+' only
- if we haven't seen `--'. */
- while (optind < argc && argv[optind][0] == '+')
- skip_chars = size_opt (argv[optind++],
- N_("invalid number of bytes to skip"));
- }
-
- if (optind < argc)
- infile = argv[optind++];
-
- if (optind < argc)
- outfile = argv[optind++];
-
- if (optind < argc)
- {
- error (0, 0, _("too many arguments"));
- usage (1);
- }
-
if (countmode == count_occurrences && mode == output_all_repeated)
{
error (0, 0,
@@ -500,7 +510,7 @@ main (int argc, char **argv)
usage (1);
}
- check_file (infile, outfile);
+ check_file (file[0], file[1]);
exit (EXIT_SUCCESS);
}