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.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-05-01 13:20:07 +02:00
parent a8ebb84111
commit 6f8aaf68be
2 changed files with 146 additions and 259 deletions

View file

@ -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> 2010-05-01 BVK Chaitanya <bvk.groups@gmail.com>
Fix comment handling. Fix comment handling.

View file

@ -26,37 +26,48 @@
struct grub_term_autoload *grub_term_input_autoload = NULL; struct grub_term_autoload *grub_term_input_autoload = NULL;
struct grub_term_autoload *grub_term_output_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 static grub_err_t
grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)), handle_command (int argc, char **args, struct abstract_terminal **enabled,
int argc, char **args) struct abstract_terminal **disabled,
struct grub_term_autoload *autoloads,
const char *active_str,
const char *available_str)
{ {
int i; int i;
grub_term_input_t term; struct abstract_terminal *term;
struct grub_term_autoload *aut; struct grub_term_autoload *aut;
if (argc == 0) if (argc == 0)
{ {
grub_puts_ (N_ ("Active input terminals:")); grub_puts_ (active_str);
FOR_ACTIVE_TERM_INPUTS(term) for (term = *enabled; term; term = term->next)
grub_printf ("%s ", term->name); grub_printf ("%s ", term->name);
grub_printf ("\n"); grub_printf ("\n");
grub_puts_ (N_ ("Available input terminals:")); grub_puts_ (available_str);
FOR_DISABLED_TERM_INPUTS(term) for (term = *disabled; term; term = term->next)
grub_printf ("%s ", term->name); grub_printf ("%s ", term->name);
/* This is quadratic but we don't expect mode than 30 terminal /* This is quadratic but we don't expect mode than 30 terminal
modules ever. */ modules ever. */
for (aut = grub_term_input_autoload; aut; aut = aut->next) for (aut = autoloads; aut; aut = aut->next)
{ {
FOR_DISABLED_TERM_INPUTS(term) for (term = *disabled; term; term = term->next)
if (grub_strcmp (term->name, aut->name) == 0) if (grub_strcmp (term->name, aut->name) == 0)
break; break;
if (!term) if (!term)
FOR_ACTIVE_TERM_INPUTS(term) for (term = *enabled; term; term = term->next)
if (grub_strcmp (term->name, aut->name) == 0) if (grub_strcmp (term->name, aut->name) == 0)
break; break;
if (!term) if (!term)
grub_printf ("%s ", aut->name); grub_printf ("%s ", aut->name);
} }
grub_printf ("\n"); grub_printf ("\n");
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
@ -73,112 +84,108 @@ grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)),
{ {
int again = 0; int again = 0;
while (1) while (1)
{ {
FOR_DISABLED_TERM_INPUTS(term) for (term = *disabled; term; term = term->next)
if (grub_strcmp (args[i], term->name) == 0) if (grub_strcmp (args[i], term->name) == 0)
break; break;
if (term == 0) if (term == 0)
FOR_ACTIVE_TERM_INPUTS(term) for (term = *enabled; term; term = term->next)
if (grub_strcmp (args[i], term->name) == 0) if (grub_strcmp (args[i], term->name) == 0)
break; break;
if (term) if (term)
break; break;
if (again) if (again)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n", return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
args[i]); args[i]);
for (aut = grub_term_input_autoload; aut; aut = aut->next) for (aut = autoloads; aut; aut = aut->next)
if (grub_strcmp (args[i], aut->name) == 0) if (grub_strcmp (args[i], aut->name) == 0)
{ {
grub_dl_t mod; grub_dl_t mod;
mod = grub_dl_load (aut->modname); mod = grub_dl_load (aut->modname);
if (mod) if (mod)
grub_dl_ref (mod); grub_dl_ref (mod);
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;
break; break;
} }
if (!aut) if (!aut)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n", return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
args[i]); args[i]);
again = 1; again = 1;
} }
} }
if (grub_strcmp (args[0], "--append") == 0) if (grub_strcmp (args[0], "--append") == 0)
{ {
for (i = 1; i < argc; i++) for (i = 1; i < argc; i++)
{ {
FOR_DISABLED_TERM_INPUTS(term) for (term = *disabled; term; term = term->next)
if (grub_strcmp (args[i], term->name) == 0) if (grub_strcmp (args[i], term->name) == 0)
break; break;
if (term) if (term)
{ {
if (term->init && term->init () != GRUB_ERR_NONE) if (term->init && term->init () != GRUB_ERR_NONE)
return grub_errno; return grub_errno;
grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs_disabled)), grub_list_remove (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
GRUB_AS_LIST (term)); grub_list_push (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), }
GRUB_AS_LIST (term)); }
}
}
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
if (grub_strcmp (args[0], "--remove") == 0) if (grub_strcmp (args[0], "--remove") == 0)
{ {
for (i = 1; i < argc; i++) for (i = 1; i < argc; i++)
{ {
FOR_ACTIVE_TERM_INPUTS(term) for (term = *enabled; term; term = term->next)
if (grub_strcmp (args[i], term->name) == 0) if (grub_strcmp (args[i], term->name) == 0)
break; break;
if (term) if (term)
{ {
if (!term->next && term == grub_term_inputs) if (!term->next && term == *enabled)
return grub_error (GRUB_ERR_BAD_ARGUMENT, return grub_error (GRUB_ERR_BAD_ARGUMENT,
"can't remove the last terminal"); "can't remove the last terminal");
grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs)), grub_list_remove (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
GRUB_AS_LIST (term)); if (term->fini)
if (term->fini) term->fini ();
term->fini (); grub_list_push (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled), }
GRUB_AS_LIST (term)); }
}
}
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
for (i = 0; i < argc; i++) for (i = 0; i < argc; i++)
{ {
FOR_DISABLED_TERM_INPUTS(term) for (term = *disabled; term; term = term->next)
if (grub_strcmp (args[i], term->name) == 0) if (grub_strcmp (args[i], term->name) == 0)
break; break;
if (term) if (term)
{ {
if (term->init && term->init () != GRUB_ERR_NONE) if (term->init && term->init () != GRUB_ERR_NONE)
return grub_errno; return grub_errno;
grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs_disabled)), grub_list_remove (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
GRUB_AS_LIST (term)); grub_list_push (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), }
GRUB_AS_LIST (term));
}
} }
FOR_ACTIVE_TERM_INPUTS(term)
{ {
for (i = 0; i < argc; i++) struct abstract_terminal *next;
if (grub_strcmp (args[i], term->name) == 0) for (term = *enabled; term; term = next)
break;
if (i == argc)
{ {
if (!term->next && term == grub_term_inputs) next = term->next;
return grub_error (GRUB_ERR_BAD_ARGUMENT, for (i = 0; i < argc; i++)
"can't remove the last terminal"); if (grub_strcmp (args[i], term->name) == 0)
grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs)), break;
GRUB_AS_LIST (term)); if (i == argc)
if (term->fini) {
term->fini (); if (!term->next && term == *enabled)
grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled), return grub_error (GRUB_ERR_BAD_ARGUMENT,
GRUB_AS_LIST (term)); "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 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 argc, char **args)
{ {
int i; (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, next);
grub_term_output_t term; (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, name);
struct grub_term_autoload *aut; (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:"));
}
if (argc == 0) static grub_err_t
{ grub_cmd_terminal_output (grub_command_t cmd __attribute__ ((unused)),
grub_puts_ (N_ ("Active output terminals:")); int argc, char **args)
FOR_ACTIVE_TERM_OUTPUTS(term) {
grub_printf ("%s ", term->name); (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, next);
grub_printf ("\n"); (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, name);
grub_puts_ (N_ ("Available output terminals:")); (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, init);
FOR_DISABLED_TERM_OUTPUTS(term) (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, fini);
grub_printf ("%s ", term->name); return handle_command (argc, args, (struct abstract_terminal **) &grub_term_outputs,
/* This is quadratic but we don't expect mode than 30 terminal (struct abstract_terminal **) &grub_term_outputs_disabled,
modules ever. */ grub_term_output_autoload,
for (aut = grub_term_output_autoload; aut; aut = aut->next) N_ ("Active output terminals:"),
{ N_ ("Available output terminals:"));
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));
}
}
return GRUB_ERR_NONE;
} }
static grub_command_t cmd_terminal_input, cmd_terminal_output; static grub_command_t cmd_terminal_input, cmd_terminal_output;