]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
(main): Fix some more incompatibilities with POSIX.2,
authorJim Meyering <jim@meyering.net>
Sat, 25 Aug 2001 15:07:17 +0000 (15:07 +0000)
committerJim Meyering <jim@meyering.net>
Sat, 25 Aug 2001 15:07:17 +0000 (15:07 +0000)
(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.

src/uniq.c

index 21f4ab07aeda9f50c73a7cf82606e71ce0269be8..36119cff82d252fefe1093e6070035fb09fb81ed 100644 (file)
@@ -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);
 }