]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
(main): Revamp option processing, again.
authorJim Meyering <jim@meyering.net>
Sat, 19 Sep 1998 17:30:17 +0000 (17:30 +0000)
committerJim Meyering <jim@meyering.net>
Sat, 19 Sep 1998 17:30:17 +0000 (17:30 +0000)
stty couldn't parse some of its options.

src/stty.c

index 65fe183fa130512bb57fec4e33043a3b8ede8524..2237e5fdd4ba1728ee7d4faa4615650d7ae594ae 100644 (file)
@@ -697,6 +697,7 @@ main (int argc, char **argv)
   int fd;
   const char *device_name;
   const char *posixly_correct = getenv ("POSIXLY_CORRECT");
+  int invalid_long_option = 0;
 
   program_name = argv[0];
   setlocale (LC_ALL, "");
@@ -709,10 +710,12 @@ main (int argc, char **argv)
   verbose_output = 0;
   recoverable_output = 0;
 
-  /* Recognize the long options only.  */
+  /* Don't print error messages for unrecognized options.  */
   opterr = 0;
-  while ((optc = getopt_long_only (argc, argv, "agF:", longopts, NULL)) != -1)
+
+  while ((optc = getopt_long (argc, argv, "agF:", longopts, NULL)) != -1)
     {
+      int unrecognized_option = 0;
       switch (optc)
        {
        case 'a':
@@ -732,11 +735,19 @@ main (int argc, char **argv)
          break;
 
        default:
+         unrecognized_option = 1;
          break;
        }
+
+      if (unrecognized_option)
+       break;
     }
 
-  /* Clear out the options that have been parsed.  This is kind of
+  /* FIXME: what is this?!? */
+  if (invalid_long_option)
+    usage (1);
+
+  /* Clear out the options that have been parsed.  This is really
      gross, but it's needed because stty SETTINGS look like options to
      getopt(), so we need to work around things in a really horrible
      way.  If any new options are ever added to stty, the short option
@@ -746,33 +757,61 @@ main (int argc, char **argv)
      short and long options, --, POSIXLY_CORRECT, etc.  */
   for (k = 1; k < argc; k++)
     {
-      if (!argv[k])
+      size_t len;
+      char *eq;
+
+      if (argv[k] == NULL)
        continue;
+
       /* Handle --, and reset noargs if there are arguments following it.  */
       if (STREQ (argv[k], "--"))
        {
-         argv[k] = 0;
+         argv[k] = NULL;
          if (k < argc - 1)
            noargs = 0;
          break;
        }
+
       /* Handle "--file device" */
-      if (STREQ (argv[k], "--file"))
+      len = strlen (argv[k]);
+      if (len >= 3 && strstr ("--file", argv[k]))
        {
-         argv[k + 1] = 0;
-         argv[k] = 0;
+         argv[k] = NULL;
+         argv[k + 1] = NULL;
+         continue;
        }
-      /* Handle "--all", "--save", and "--file=device".  */
-      else if (STREQ (argv[k], "--all") ||
-              STREQ (argv[k], "--save") ||
-              !strncmp (argv[k], "--file=", 7))
-       argv[k] = 0;
+
+      /* Handle "--all" and "--save".  */
+      if (len >= 3
+         && (strstr ("--all", argv[k])
+             || strstr ("--save", argv[k])))
+       {
+         argv[k] = NULL;
+         continue;
+       }
+
+      /* Handle "--file=device".  */
+      eq = strchr (argv[k], '=');
+      if (eq && eq - argv[k] >= 3)
+       {
+         *eq = '\0';
+         if (strstr ("--file", argv[k]))
+           {
+             argv[k] = NULL;
+             continue;
+           }
+         /* Put the equals sign back for the error message.  */
+         *eq = '=';
+       }
+
       /* Handle "-a", "-ag", "-aF/dev/foo", "-aF /dev/foo", etc.  */
-      else if (valid_options (argv[k], "ag", "F"))
+      if (valid_options (argv[k], "ag", "F"))
        {
-         if (STREQ (argv[k], "-file") || argv[k][strlen (argv[k]) - 1] == 'F')
-           argv[k + 1] = 0;
-         argv[k] = 0;
+         /* FIXME: this loses when the device name ends in `F'.
+            e.g. `stty -F/dev/BARF nl' would clobber the `nl' argument.  */
+         if (argv[k][strlen (argv[k]) - 1] == 'F')
+           argv[k + 1] = NULL;
+         argv[k] = NULL;
         }
       /* Everything else must be a normal, non-option argument.  */
       else
@@ -793,6 +832,11 @@ mutually exclusive"));
   if (!noargs && (verbose_output || recoverable_output))
     error (2, 0, _("when specifying an output style, modes may not be set"));
 
+  /* FIXME: it'd be better not to open the file until we've verified
+     that all arguments are valid.  Otherwise, we could end up doing
+     only some of the requested operations and then failing, probably
+     leaving things in an undesirable state.  */
+
   if (file_name)
     {
       int fdflags;