From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1Uc8iC-000113-JK for mharc-grub-devel@gnu.org; Tue, 14 May 2013 02:27:48 -0400 Received: from eggs.gnu.org ([208.118.235.92]:50960) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uc8i9-0000x7-7w for grub-devel@gnu.org; Tue, 14 May 2013 02:27:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Uc8i7-0006Ms-Da for grub-devel@gnu.org; Tue, 14 May 2013 02:27:45 -0400 Received: from mail-ea0-x229.google.com ([2a00:1450:4013:c01::229]:48526) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uc8i7-0006Mk-4F for grub-devel@gnu.org; Tue, 14 May 2013 02:27:43 -0400 Received: by mail-ea0-f169.google.com with SMTP id m14so83920eaj.28 for ; Mon, 13 May 2013 23:27:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:message-id:date:from:user-agent:mime-version:to:subject :references:in-reply-to:x-enigmail-version:content-type; bh=/iPxV+XRwsafyJwy5k71SAkxD+4CfpVvp6ZF1xy8/a0=; b=NdG/S48+156SBU9ID0Ai3bnFI/yZycmzVbZmhdTJm68GRgtdPDQjIL87OAnAnTCgYn tFAsuffr+Id128DpHpkWH9duWQKiZQD783b9KPTemHCCVqal+1Ic0RCcSD+005DcpRJr 4FIifVxrvWbJnOx84UraUEr5xz9mE+muZTFwNIViodkAJrVxxXGVQYijaUPRISiOWDdv Q3Yzz7505kU0nS+9iFQvLvUFBWKO5DBwvbFkeiJKfb9/M89TnY9uANMqJAcF04YZ0vvg 6Vc1+jsbGs2LefCXaCLM60RwPqwJ7DCAEdD0q8TGSxup/FPVlF7aFwF/gcC4ALkZSlN2 WecA== X-Received: by 10.14.69.138 with SMTP id n10mr87272912eed.32.1368512862451; Mon, 13 May 2013 23:27:42 -0700 (PDT) Received: from debian.x201.phnet (vpn-global-dhcp2-86.ethz.ch. [129.132.209.86]) by mx.google.com with ESMTPSA id e50sm27290535eev.13.2013.05.13.23.27.41 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 13 May 2013 23:27:41 -0700 (PDT) Message-ID: <5191D923.6020306@gmail.com> Date: Tue, 14 May 2013 08:26:43 +0200 From: =?UTF-8?B?VmxhZGltaXIgJ8+GLWNvZGVyL3BoY29kZXInIFNlcmJpbmVua28=?= User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:10.0.12) Gecko/20130116 Icedove/10.0.12 MIME-Version: 1.0 To: grub-devel@gnu.org Subject: Re: New command eval. References: <1367240132.58582.YahooMailNeo@web120204.mail.ne1.yahoo.com> <20130501185934.3f2b9c28@opensuse.site> <518578B3.5040003@gmail.com> <20130511203534.52499628@opensuse.site> <518E79C2.701@gmail.com> <20130511213005.0827778e@opensuse.site> In-Reply-To: <20130511213005.0827778e@opensuse.site> X-Enigmail-Version: 1.4.1 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="------------enig4ED027CDB30D9808049FBFD3" X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:4013:c01::229 X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list Reply-To: The development of GNU GRUB List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 14 May 2013 06:27:47 -0000 This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --------------enig4ED027CDB30D9808049FBFD3 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Patch is good. Could you add corresponding testcase to testsuite and comm= it? On 11.05.2013 19:30, Andrey Borzenkov wrote: > =D0=92 Sat, 11 May 2013 19:02:58 +0200 > Vladimir '=CF=86-coder/phcoder' Serbinenko =D0=BF=D0= =B8=D1=88=D0=B5=D1=82: >=20 >> On 11.05.2013 18:35, Andrey Borzenkov wrote: >> >>> + grub_size_t size =3D argc; /* +1 for final zero */ >>> + char *str, *p; >>> + grub_err_t ret; >>> + >>> + if (argc =3D=3D 0) >>> + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing arguments"= )); >>> + >> >> eval with no arguments returns success in bash, to match this behaviou= r, >> it should be GRUB_ERR_NONE and no use of grub_error >> >>> + for (i =3D 0; i < argc; i++) >>> + size +=3D grub_strlen (argv[i]); >>> + >>> + str =3D p =3D grub_malloc (size); >>> + if (!str) >>> + return grub_errno; >>> + >>> + for (i =3D 0; i < argc; i++) >>> + { >>> + grub_strcpy (p, argv[i]); >>> + p +=3D grub_strlen (argv[i]); >> >> These 2 operations should be condensed by using grub_stpcpy >> >>> + *p++ =3D ' '; >> >> >>> - grub_script_execute_sourcecode (script, 0, dummy); >>> + grub_script_execute_sourcecode (script); >> (in menu_entry.c) here you need a new scope for consistency. >> >=20 > diff --git a/ChangeLog b/ChangeLog > index cd8213a..60c64ee 100644 > --- a/ChangeLog > +++ b/ChangeLog > @@ -1,3 +1,11 @@ > +2013-05-11 Andrey Borzenkov > + > + * 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 > =20 > * 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 @co= mmand{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 > =20 > =20 > +@node eval > +@subsection eval > + > +@deffn Command eval string ... > +Concatenate arguments together using single space as separator and eva= luate > +result as sequence of GRUB commands. > +@end deffn > + > + > @node export > @subsection export > =20 > 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 =3D { > }; > =20 > module =3D { > + name =3D eval; > + common =3D commands/eval.c; > +}; > + > +module =3D { > name =3D extcmd; > common =3D commands/extcmd.c; > common =3D lib/arg.c; > diff --git a/grub-core/commands/eval.c b/grub-core/commands/eval.c > new file mode 100644 > index 0000000..f826a4f > --- /dev/null > +++ b/grub-core/commands/eval.c > @@ -0,0 +1,71 @@ > +/* > + * 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 . > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +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 =3D argc; /* +1 for final zero */ > + char *str, *p; > + grub_err_t ret; > + > + if (argc =3D=3D 0) > + return GRUB_ERR_NONE; > + > + for (i =3D 0; i < argc; i++) > + size +=3D grub_strlen (argv[i]); > + > + str =3D p =3D grub_malloc (size); > + if (!str) > + return grub_errno; > + > + for (i =3D 0; i < argc; i++) > + { > + p =3D grub_stpcpy (p, argv[i]); > + *p++ =3D ' '; > + } > + *--p =3D '\0'; > + > + ret =3D grub_script_execute_sourcecode (str); > + grub_free (str); > + return ret; > +} > + > +static grub_command_t cmd; > + > +GRUB_MOD_INIT(eval) > +{ > + cmd =3D 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, in= t auto_boot) > else > grub_env_unset ("default"); > =20 > - grub_script_execute_sourcecode (entry->sourcecode, entry->argc, entr= y->args); > + grub_script_execute_new_scope (entry->sourcecode, entry->argc, entry= ->args); > =20 > if (errs_before !=3D grub_err_printed_errors) > grub_wait_after_message (); > diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entr= y.c > index fae258a..506715c 100644 > --- a/grub-core/normal/menu_entry.c > +++ b/grub-core/normal/menu_entry.c > @@ -1160,7 +1160,7 @@ run (struct screen *screen) > } > script[size] =3D '\0'; > } > - grub_script_execute_sourcecode (script, 0, dummy); > + grub_script_execute_new_scope (script, 0, dummy); > grub_free (script); > =20 > if (errs_before !=3D 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 **li= ne, > =20 > /* Execute a source script. */ > grub_err_t > -grub_script_execute_sourcecode (const char *source, int argc, char **a= rgs) > +grub_script_execute_sourcecode (const char *source) > { > grub_err_t ret =3D 0; > struct grub_script *parsed_script; > - struct grub_script_scope new_scope; > - struct grub_script_scope *old_scope; > - > - new_scope.argv.argc =3D argc; > - new_scope.argv.args =3D args; > - new_scope.flags =3D 0; > - > - old_scope =3D scope; > - scope =3D &new_scope; > =20 > while (source) > { > @@ -880,13 +871,35 @@ grub_script_execute_sourcecode (const char *sourc= e, int argc, char **args) > if (! parsed_script) > { > ret =3D grub_errno; > + grub_free (line); > break; > } > =20 > ret =3D grub_script_execute (parsed_script); > + grub_script_free (parsed_script); > grub_free (line); > } > =20 > + return ret; > +} > + > +/* Execute a source script in new scope. */ > +grub_err_t > +grub_script_execute_new_scope (const char *source, int argc, char **ar= gs) > +{ > + grub_err_t ret =3D 0; > + struct grub_script_scope new_scope; > + struct grub_script_scope *old_scope; > + > + new_scope.argv.argc =3D argc; > + new_scope.argv.args =3D args; > + new_scope.flags =3D 0; > + > + old_scope =3D scope; > + scope =3D &new_scope; > + > + ret =3D grub_script_execute_sourcecode (source); > + > scope =3D 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 gru= b_script_cmd *cmd); > =20 > /* 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 arg= c, 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); > =20 > /* Break command for loops. */ > grub_err_t grub_script_break (grub_command_t cmd, int argc, char *argv= []); >=20 >=20 >=20 > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > https://lists.gnu.org/mailman/listinfo/grub-devel --------------enig4ED027CDB30D9808049FBFD3 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iF4EAREKAAYFAlGR2SMACgkQNak7dOguQgkXSAD7BC3egSCM49m/FS3jak08vCTR qVBGaIGf0/nn6FvpxzEA/1TDDJtWQNLzcZ9tgh+x7RU6k8P6m6U/i4ZoxIouusui =KI7s -----END PGP SIGNATURE----- --------------enig4ED027CDB30D9808049FBFD3--