]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Merge handling of input and output terminals. Fix a hang.
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sat, 1 May 2010 11:20:07 +0000 (13:20 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sat, 1 May 2010 11:20:07 +0000 (13:20 +0200)
* commands/terminal.c (abstract_terminal): New struct.
(handle_command): New function. Based on grub_cmd_terminal_input.
(grub_cmd_terminal_input): Use handle_command.
(grub_cmd_terminal_output): Use handle_command.

ChangeLog
commands/terminal.c

index 572fade3544df2e66e46b1053b115b665a7b0ed1..530ecf32aa3c18cdfc823a46900156c759fba580 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2010-05-01  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       MErge handling of input and output terminals. Fix a hang.
+
+       * commands/terminal.c (abstract_terminal): New struct.
+       (handle_command): New function. Based on grub_cmd_terminal_input.
+       (grub_cmd_terminal_input): Use handle_command.
+       (grub_cmd_terminal_output): Use handle_command.
+
 2010-05-01  BVK Chaitanya  <bvk.groups@gmail.com>
 
        Fix comment handling.
index e725123b804db59e43f67c14aba2fdfac47ddea9..c8c1ffe097da138f5783c14374ae288c21501d2c 100644 (file)
 struct grub_term_autoload *grub_term_input_autoload = NULL;
 struct grub_term_autoload *grub_term_output_autoload = NULL;
 
+struct abstract_terminal
+{
+  struct abstract_terminal *next;
+  const char *name;
+  grub_err_t (*init) (void);
+  grub_err_t (*fini) (void);
+};
+
 static grub_err_t
-grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)),
-                        int argc, char **args)
+handle_command (int argc, char **args, struct abstract_terminal **enabled,
+               struct abstract_terminal **disabled,
+               struct grub_term_autoload *autoloads,
+               const char *active_str,
+               const char *available_str)
 {
   int i;
-  grub_term_input_t term;
+  struct abstract_terminal *term;
   struct grub_term_autoload *aut;
 
   if (argc == 0)
     {
-      grub_puts_ (N_ ("Active input terminals:"));
-      FOR_ACTIVE_TERM_INPUTS(term)
-       grub_printf ("%s ", term->name);
+      grub_puts_ (active_str);
+      for (term = *enabled; term; term = term->next)
+       grub_printf ("%s ", term->name);
       grub_printf ("\n");
-      grub_puts_ (N_ ("Available input terminals:"));
-      FOR_DISABLED_TERM_INPUTS(term)
-       grub_printf ("%s ", term->name);
+      grub_puts_ (available_str);
+      for (term = *disabled; term; term = term->next)
+       grub_printf ("%s ", term->name);
       /* This is quadratic but we don't expect mode than 30 terminal
-        modules ever.  */
-      for (aut = grub_term_input_autoload; aut; aut = aut->next)
-       {
-         FOR_DISABLED_TERM_INPUTS(term)
-           if (grub_strcmp (term->name, aut->name) == 0)
-             break;
-         if (!term)
-           FOR_ACTIVE_TERM_INPUTS(term)
-             if (grub_strcmp (term->name, aut->name) == 0)
-               break;
-         if (!term)
-           grub_printf ("%s ", aut->name);
-       }
+        modules ever.  */
+      for (aut = autoloads; aut; aut = aut->next)
+       {
+         for (term = *disabled; term; term = term->next)
+           if (grub_strcmp (term->name, aut->name) == 0)
+             break;
+         if (!term)
+           for (term = *enabled; term; term = term->next)
+             if (grub_strcmp (term->name, aut->name) == 0)
+               break;
+         if (!term)
+           grub_printf ("%s ", aut->name);
+       }
       grub_printf ("\n");
       return GRUB_ERR_NONE;
     }
@@ -73,112 +84,108 @@ grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)),
     {
       int again = 0;
       while (1)
-       {
-         FOR_DISABLED_TERM_INPUTS(term)
-           if (grub_strcmp (args[i], term->name) == 0)
-             break;
-         if (term == 0)
-           FOR_ACTIVE_TERM_INPUTS(term)
-             if (grub_strcmp (args[i], term->name) == 0)
-               break;
-         if (term)
-           break;
-         if (again)
-           return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
-                              args[i]);
-         for (aut = grub_term_input_autoload; aut; aut = aut->next)
-           if (grub_strcmp (args[i], aut->name) == 0)
-             {
-               grub_dl_t mod;
-               mod = grub_dl_load (aut->modname);
-               if (mod)
-                 grub_dl_ref (mod);
-               grub_errno = GRUB_ERR_NONE;
-               break;
-             }
-         if (!aut)
-           return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
-                              args[i]);
-         again = 1;
-       }
+       {
+         for (term = *disabled; term; term = term->next)
+           if (grub_strcmp (args[i], term->name) == 0)
+             break;
+         if (term == 0)
+           for (term = *enabled; term; term = term->next)
+             if (grub_strcmp (args[i], term->name) == 0)
+               break;
+         if (term)
+           break;
+         if (again)
+           return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
+                              args[i]);
+         for (aut = autoloads; aut; aut = aut->next)
+           if (grub_strcmp (args[i], aut->name) == 0)
+             {
+               grub_dl_t mod;
+               mod = grub_dl_load (aut->modname);
+               if (mod)
+                 grub_dl_ref (mod);
+               grub_errno = GRUB_ERR_NONE;
+               break;
+             }
+         if (!aut)
+           return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
+                              args[i]);
+         again = 1;
+       }
     }
 
   if (grub_strcmp (args[0], "--append") == 0)
     {
       for (i = 1; i < argc; i++)
-       {
-         FOR_DISABLED_TERM_INPUTS(term)
-           if (grub_strcmp (args[i], term->name) == 0)
-             break;
-         if (term)
-           {
+       {
+         for (term = *disabled; term; term = term->next)
+           if (grub_strcmp (args[i], term->name) == 0)
+             break;
+         if (term)
+           {
               if (term->init && term->init () != GRUB_ERR_NONE)
                 return grub_errno;
 
-             grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs_disabled)),
-                               GRUB_AS_LIST (term));
-             grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs),
-                             GRUB_AS_LIST (term));
-           }
-       }
+             grub_list_remove (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
+             grub_list_push (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
+           }
+       }
       return GRUB_ERR_NONE;
     }
 
   if (grub_strcmp (args[0], "--remove") == 0)
     {
       for (i = 1; i < argc; i++)
-       {
-         FOR_ACTIVE_TERM_INPUTS(term)
-           if (grub_strcmp (args[i], term->name) == 0)
-             break;
-         if (term)
-           {
-             if (!term->next && term == grub_term_inputs)
-               return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                                  "can't remove the last terminal");
-             grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs)),
-                               GRUB_AS_LIST (term));
-             if (term->fini)
-               term->fini ();
-             grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled),
-                             GRUB_AS_LIST (term));
-           }
-       }
+       {
+         for (term = *enabled; term; term = term->next)
+           if (grub_strcmp (args[i], term->name) == 0)
+             break;
+         if (term)
+           {
+             if (!term->next && term == *enabled)
+               return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                                  "can't remove the last terminal");
+             grub_list_remove (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
+             if (term->fini)
+               term->fini ();
+             grub_list_push (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
+           }
+       }
       return GRUB_ERR_NONE;
     }
   for (i = 0; i < argc; i++)
     {
-      FOR_DISABLED_TERM_INPUTS(term)
-       if (grub_strcmp (args[i], term->name) == 0)
-         break;
+      for (term = *disabled; term; term = term->next)
+       if (grub_strcmp (args[i], term->name) == 0)
+         break;
       if (term)
-       {
-         if (term->init && term->init () != GRUB_ERR_NONE)
-           return grub_errno;
+       {
+         if (term->init && term->init () != GRUB_ERR_NONE)
+           return grub_errno;
 
-         grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs_disabled)),
-                           GRUB_AS_LIST (term));
-         grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs),
-                         GRUB_AS_LIST (term));
-       }       
+         grub_list_remove (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
+         grub_list_push (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
+       }       
     }
-
-  FOR_ACTIVE_TERM_INPUTS(term)
+  
   {
-    for (i = 0; i < argc; i++)
-      if (grub_strcmp (args[i], term->name) == 0)
-       break;
-    if (i == argc)
+    struct abstract_terminal *next;
+    for (term = *enabled; term; term = next)
       {
-       if (!term->next && term == grub_term_inputs)
-         return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                            "can't remove the last terminal");
-       grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs)),
-                         GRUB_AS_LIST (term));
-       if (term->fini)
-         term->fini ();
-       grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled),
-                       GRUB_AS_LIST (term));
+       next = term->next;
+       for (i = 0; i < argc; i++)
+         if (grub_strcmp (args[i], term->name) == 0)
+           break;
+       if (i == argc)
+         {
+           if (!term->next && term == *enabled)
+             return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                                "can't remove the last terminal");
+           grub_list_remove (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
+           if (term->fini)
+             term->fini ();
+           grub_list_push (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
+         }
       }
   }
 
@@ -186,163 +193,34 @@ grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)),
 }
 
 static grub_err_t
-grub_cmd_terminal_output (grub_command_t cmd __attribute__ ((unused)),
+grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)),
                         int argc, char **args)
 {
-  int i;
-  grub_term_output_t term;
-  struct grub_term_autoload *aut;
-
-  if (argc == 0)
-    {
-      grub_puts_ (N_ ("Active output terminals:"));
-      FOR_ACTIVE_TERM_OUTPUTS(term)
-       grub_printf ("%s ", term->name);
-      grub_printf ("\n");
-      grub_puts_ (N_ ("Available output terminals:"));
-      FOR_DISABLED_TERM_OUTPUTS(term)
-       grub_printf ("%s ", term->name);
-      /* This is quadratic but we don't expect mode than 30 terminal
-        modules ever.  */
-      for (aut = grub_term_output_autoload; aut; aut = aut->next)
-       {
-         FOR_DISABLED_TERM_OUTPUTS(term)
-           if (grub_strcmp (term->name, aut->name) == 0)
-             break;
-         if (!term)
-           FOR_ACTIVE_TERM_OUTPUTS(term)
-             if (grub_strcmp (term->name, aut->name) == 0)
-               break;
-         if (!term)
-           grub_printf ("%s ", aut->name);
-       }
-      grub_printf ("\n");
-      return GRUB_ERR_NONE;
-    }
-  i = 0;
-
-  if (grub_strcmp (args[0], "--append") == 0
-      || grub_strcmp (args[0], "--remove") == 0)
-    i++;
-
-  if (i == argc)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("no terminal specified"));
-
-  for (; i < argc; i++)
-    {
-      int again = 0;
-      while (1)
-       {
-         FOR_DISABLED_TERM_OUTPUTS(term)
-           if (grub_strcmp (args[i], term->name) == 0)
-             break;
-         if (term == 0)
-           FOR_ACTIVE_TERM_OUTPUTS(term)
-             if (grub_strcmp (args[i], term->name) == 0)
-               break;
-         if (term)
-           break;
-         if (again)
-           return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
-                              args[i]);
-         for (aut = grub_term_output_autoload; aut; aut = aut->next)
-           if (grub_strcmp (args[i], aut->name) == 0)
-             {
-               grub_dl_t mod;
-               mod = grub_dl_load (aut->modname);
-               if (mod)
-                 grub_dl_ref (mod);
-               grub_errno = GRUB_ERR_NONE;
-               break;
-             }
-         if (!aut)
-           return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
-                              args[i]);
-         again = 1;
-       }
-    }
-
-  if (grub_strcmp (args[0], "--append") == 0)
-    {
-      for (i = 1; i < argc; i++)
-       {
-         FOR_DISABLED_TERM_OUTPUTS(term)
-           if (grub_strcmp (args[i], term->name) == 0)
-             break;
-         if (term)
-           {
-              if (term->init && term->init () != GRUB_ERR_NONE)
-                return grub_errno;
-
-             grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs_disabled)),
-                               GRUB_AS_LIST (term));
-             grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs),
-                             GRUB_AS_LIST (term));
-           }
-       }
-      return GRUB_ERR_NONE;
-    }
-
-  if (grub_strcmp (args[0], "--remove") == 0)
-    {
-      for (i = 1; i < argc; i++)
-       {
-         FOR_ACTIVE_TERM_OUTPUTS(term)
-           if (grub_strcmp (args[i], term->name) == 0)
-             break;
-         if (term)
-           {
-             if (!term->next && term == grub_term_outputs)
-               return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                                  "can't remove the last terminal");
-             grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs)),
-                               GRUB_AS_LIST (term));
-             if (term->fini)
-               term->fini ();
-             grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled),
-                             GRUB_AS_LIST (term));
-           }
-       }
-      return GRUB_ERR_NONE;
-    }
-
-  for (i = 0; i < argc; i++)
-    {
-      FOR_DISABLED_TERM_OUTPUTS(term)
-       if (grub_strcmp (args[i], term->name) == 0)
-         break;
-      if (term)
-       {
-         if (term->init && term->init () != GRUB_ERR_NONE)
-           return grub_errno;
-
-         grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs_disabled)),
-                           GRUB_AS_LIST (term));
-         grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs),
-                         GRUB_AS_LIST (term));
-       }       
-    }
-
-  FOR_ACTIVE_TERM_OUTPUTS(term)
-  {
-    for (i = 0; i < argc; i++)
-      if (grub_strcmp (args[i], term->name) == 0)
-       break;
-    if (i == argc)
-      {
-       if (!term->next && term == grub_term_outputs)
-         return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                            "can't remove the last terminal");
-       grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs)),
-                         GRUB_AS_LIST (term));
-       if (term->fini)
-         term->fini ();
-       grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled),
-                       GRUB_AS_LIST (term));
-      }
-  }
+  (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, next);
+  (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, name);
+  (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, init);
+  (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, fini);
+  return handle_command (argc, args,
+                        (struct abstract_terminal **) &grub_term_inputs,
+                        (struct abstract_terminal **) &grub_term_inputs_disabled,
+                        grub_term_input_autoload,
+                        N_ ("Active input terminals:"),
+                        N_ ("Available input terminals:"));
+}
 
-  return GRUB_ERR_NONE;
+static grub_err_t
+grub_cmd_terminal_output (grub_command_t cmd __attribute__ ((unused)),
+                         int argc, char **args)
+{
+  (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, next);
+  (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, name);
+  (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, init);
+  (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, fini);
+  return handle_command (argc, args, (struct abstract_terminal **) &grub_term_outputs,
+                        (struct abstract_terminal **) &grub_term_outputs_disabled,
+                        grub_term_output_autoload,
+                        N_ ("Active output terminals:"),
+                        N_ ("Available output terminals:"));
 }
 
 static grub_command_t cmd_terminal_input, cmd_terminal_output;