Hi, What about the feature environment variable to allow dynamic detection of this enhancement?
--S On May 11, 2013, at 9:35 AM, Andrey Borzenkov <arvidj...@gmail.com> wrote: > В Sat, 04 May 2013 23:08:03 +0200 > Vladimir 'φ-coder/phcoder' Serbinenko <phco...@gmail.com> пишет: > >>> - it adds "eval" command (same as known from UNIX shells) which >>> executes its argument >> >> eval is generally good >> >> >>> +static grub_err_t >>> +grub_cmd_eval (grub_extcmd_context_t ctxt __attribute__((__unused__)), >>> + int argc, char *argv[]) >>> +{ >> >> You don't use any argument parsing. It's better to use command and not >> extcmd in this case. Also "eval" in bash concatenates its arguments. >> >>> + cmd = grub_register_extcmd ("eval", grub_cmd_eval, 0, >>> + N_("[STRING]"), N_("Evaluate commands"), >> >> This description seems a bit vague for either human-reading or translation. > > Is patch below OK? I decided to split off pure execute_sourcecode so > that eval context would not clobber positional arguments. > > diff --git a/ChangeLog b/ChangeLog > index cd8213a..8ca9874 100644 > --- a/ChangeLog > +++ b/ChangeLog > @@ -1,3 +1,11 @@ > +2013-05-11 Andrey Borzenkov <arvidj...@gmail.com> > + > + * grub-core/script/execute.c (grub_script_execute_sourcecode): Split > + off new function grub_script_execute_new_scope. Change callers to use > + either of them as appropriate. > + * grub-core/commands/eval.c: New command eval. > + * docs/grub.texi (Commands): Document it. > + > 2013-05-11 Vladimir Serbinenko <phco...@gmail.com> > > * util/grub-install.in: Gettextize "Not found" message. > diff --git a/docs/grub.texi b/docs/grub.texi > index 75a5ea4..9dcfa2d 100644 > --- a/docs/grub.texi > +++ b/docs/grub.texi > @@ -3435,6 +3435,7 @@ you forget a command, you can run the command > @command{help} > * date:: Display or set current date and time > * drivemap:: Map a drive to another > * echo:: Display a line of text > +* eval:: Evaluate agruments as GRUB commands > * export:: Export an environment variable > * false:: Do nothing, unsuccessfully > * gettext:: Translate a string > @@ -3812,6 +3813,15 @@ character will print that character. > @end deffn > > > +@node eval > +@subsection eval > + > +@deffn Command eval string ... > +Concatenate arguments together using single space as separator and evaluate > +result as sequence of GRUB commands. > +@end deffn > + > + > @node export > @subsection export > > diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def > index 602b497..0fcc4e7 100644 > --- a/grub-core/Makefile.core.def > +++ b/grub-core/Makefile.core.def > @@ -699,6 +699,11 @@ module = { > }; > > module = { > + name = eval; > + common = commands/eval.c; > +}; > + > +module = { > name = extcmd; > common = commands/extcmd.c; > common = lib/arg.c; > diff --git a/grub-core/commands/eval.c b/grub-core/commands/eval.c > new file mode 100644 > index 0000000..e514a1a > --- /dev/null > +++ b/grub-core/commands/eval.c > @@ -0,0 +1,72 @@ > +/* > + * GRUB -- GRand Unified Bootloader > + * Copyright (C) 2009 Free Software Foundation, Inc. > + * > + * GRUB is free software: you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation, either version 3 of the License, or > + * (at your option) any later version. > + * > + * GRUB is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with GRUB. If not, see <http://www.gnu.org/licenses/>. > + */ > + > +#include <grub/dl.h> > +#include <grub/misc.h> > +#include <grub/script_sh.h> > +#include <grub/command.h> > +#include <grub/i18n.h> > +#include <grub/term.h> > + > +GRUB_MOD_LICENSE ("GPLv3+"); > + > +static grub_err_t > +grub_cmd_eval (grub_command_t cmd __attribute__((__unused__)), > + int argc, char *argv[]) > +{ > + int i; > + grub_size_t size = argc; /* +1 for final zero */ > + char *str, *p; > + grub_err_t ret; > + > + if (argc == 0) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing arguments")); > + > + for (i = 0; i < argc; i++) > + size += grub_strlen (argv[i]); > + > + str = p = grub_malloc (size); > + if (!str) > + return grub_errno; > + > + for (i = 0; i < argc; i++) > + { > + grub_strcpy (p, argv[i]); > + p += grub_strlen (argv[i]); > + *p++ = ' '; > + } > + *--p = '\0'; > + > + ret = grub_script_execute_sourcecode (str); > + grub_free (str); > + return ret; > +} > + > +static grub_command_t cmd; > + > +GRUB_MOD_INIT(eval) > +{ > + cmd = grub_register_command ("eval", grub_cmd_eval, N_("STRING ..."), > + N_("Evaluate arguments as GRUB commands")); > +} > + > +GRUB_MOD_FINI(eval) > +{ > + grub_unregister_command (cmd); > +} > + > diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c > index fba19db..9b88290 100644 > --- a/grub-core/normal/menu.c > +++ b/grub-core/normal/menu.c > @@ -245,7 +245,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int > auto_boot) > else > grub_env_unset ("default"); > > - grub_script_execute_sourcecode (entry->sourcecode, entry->argc, > entry->args); > + grub_script_execute_new_scope (entry->sourcecode, entry->argc, > entry->args); > > if (errs_before != grub_err_printed_errors) > grub_wait_after_message (); > diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c > index fae258a..0f15a7e 100644 > --- a/grub-core/normal/menu_entry.c > +++ b/grub-core/normal/menu_entry.c > @@ -1120,7 +1120,6 @@ run (struct screen *screen) > char *script; > int errs_before; > grub_menu_t menu = NULL; > - char *dummy[1] = { NULL }; > > grub_cls (); > grub_printf (" "); > @@ -1160,7 +1159,7 @@ run (struct screen *screen) > } > script[size] = '\0'; > } > - grub_script_execute_sourcecode (script, 0, dummy); > + grub_script_execute_sourcecode (script); > grub_free (script); > > if (errs_before != grub_err_printed_errors) > diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c > index 9babbee..afd5513 100644 > --- a/grub-core/script/execute.c > +++ b/grub-core/script/execute.c > @@ -856,19 +856,10 @@ grub_script_execute_sourcecode_getline (char **line, > > /* Execute a source script. */ > grub_err_t > -grub_script_execute_sourcecode (const char *source, int argc, char **args) > +grub_script_execute_sourcecode (const char *source) > { > grub_err_t ret = 0; > struct grub_script *parsed_script; > - struct grub_script_scope new_scope; > - struct grub_script_scope *old_scope; > - > - new_scope.argv.argc = argc; > - new_scope.argv.args = args; > - new_scope.flags = 0; > - > - old_scope = scope; > - scope = &new_scope; > > while (source) > { > @@ -880,13 +871,35 @@ grub_script_execute_sourcecode (const char *source, int > argc, char **args) > if (! parsed_script) > { > ret = grub_errno; > + grub_free (line); > break; > } > > ret = grub_script_execute (parsed_script); > + grub_script_free (parsed_script); > grub_free (line); > } > > + return ret; > +} > + > +/* Execute a source script in new scope. */ > +grub_err_t > +grub_script_execute_new_scope (const char *source, int argc, char **args) > +{ > + grub_err_t ret = 0; > + struct grub_script_scope new_scope; > + struct grub_script_scope *old_scope; > + > + new_scope.argv.argc = argc; > + new_scope.argv.args = args; > + new_scope.flags = 0; > + > + old_scope = scope; > + scope = &new_scope; > + > + ret = grub_script_execute_sourcecode (source); > + > scope = old_scope; > return ret; > } > diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h > index 78602e4..57bdd4d 100644 > --- a/include/grub/script_sh.h > +++ b/include/grub/script_sh.h > @@ -329,7 +329,8 @@ grub_err_t grub_script_execute_cmdwhile (struct > grub_script_cmd *cmd); > > /* Execute any GRUB pre-parsed command or script. */ > grub_err_t grub_script_execute (struct grub_script *script); > -grub_err_t grub_script_execute_sourcecode (const char *source, int argc, > char **args); > +grub_err_t grub_script_execute_sourcecode (const char *source); > +grub_err_t grub_script_execute_new_scope (const char *source, int argc, char > **args); > > /* Break command for loops. */ > grub_err_t grub_script_break (grub_command_t cmd, int argc, char *argv[]); > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > https://lists.gnu.org/mailman/listinfo/grub-devel _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel