2008-02-10 Robert Millan * commands/read.c (options): New struct. (grub_getline): Receive a hook as argument, that will be invoked for each character read instead of directly printing it. This lets the caller choose which action is appropiate. Echo the final newline. (grub_cmd_read): Parse --echo parameter to determine echoing behaviour. Pass a hook to grub_getline() that implements behaviour determined by --echo. (grub_read_init): Pass `options' parameter to grub_register_command(). diff -x configure -x config.h.in -x CVS -x '*~' -x '*.mk' -urp ../grub2/commands/read.c ./commands/read.c --- ../grub2/commands/read.c 2008-02-02 21:35:08.000000000 +0100 +++ ./commands/read.c 2008-02-09 22:46:56.000000000 +0100 @@ -24,8 +24,14 @@ #include #include +static const struct grub_arg_option options[] = + { + {"echo", 'e', 0, "whether to echo user input", "[yes|no|wildcard]", ARG_TYPE_STRING}, + {0, 0, 0, 0, 0, 0} + }; + static char * -grub_getline (void) +grub_getline (void (*hook) (char c)) { int i; char *line; @@ -39,8 +45,7 @@ grub_getline (void) while ((line[i - 1] != '\n') && (line[i - 1] != '\r')) { line[i] = grub_getkey (); - if (grub_isprint (line[i])) - grub_putchar (line[i]); + hook (line[i]); i++; tmp = grub_realloc (line, 1 + i + sizeof('\0')); if (! tmp) @@ -51,14 +56,53 @@ grub_getline (void) line = tmp; } line[i] = '\0'; + grub_putchar ('\n'); return line; } +enum +{ + ECHO_YES, + ECHO_NO, + ECHO_WILDCARD, +}; + static grub_err_t -grub_cmd_read (struct grub_arg_list *state UNUSED, int argc, char **args) +grub_cmd_read (struct grub_arg_list *state, int argc, char **args) { - char *line = grub_getline (); + char *line; + int echo = ECHO_YES; + + if (state[0].set) + { + grub_printf ("%s\n", state[0].arg); + if (! grub_strcmp (state[0].arg, "no")) + echo = ECHO_NO; + else if (! grub_strcmp (state[0].arg, "wildcard")) + echo = ECHO_WILDCARD; + else if (grub_strcmp (state[0].arg, "yes")) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument"); + } + + auto void hook (char); + void hook (char c) + { + if (! grub_isprint (c)) + return; + + switch (echo) + { + case ECHO_YES: + grub_putchar (c); + break; + case ECHO_WILDCARD: + grub_putchar ('*'); + break; + } + } + + line = grub_getline (hook); if (! line) return grub_errno; if (argc > 0) @@ -72,7 +116,7 @@ grub_cmd_read (struct grub_arg_list *sta GRUB_MOD_INIT(read) { grub_register_command ("read", grub_cmd_read, GRUB_COMMAND_FLAG_CMDLINE, - "read [ENVVAR]", "Set variable with user input", 0); + "read [ENVVAR]", "Set variable with user input", options); } GRUB_MOD_FINI(read)