From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1KJrEy-0002ns-AR for mharc-grub-devel@gnu.org; Fri, 18 Jul 2008 10:47:24 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KJrEw-0002mY-R7 for grub-devel@gnu.org; Fri, 18 Jul 2008 10:47:22 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KJrEs-0002jW-Tb for grub-devel@gnu.org; Fri, 18 Jul 2008 10:47:21 -0400 Received: from [199.232.76.173] (port=51264 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KJrEs-0002jM-NZ for grub-devel@gnu.org; Fri, 18 Jul 2008 10:47:18 -0400 Received: from gateway08.websitewelcome.com ([69.41.248.18]:33533) by monty-python.gnu.org with smtp (Exim 4.60) (envelope-from ) id 1KJrEs-0002Vj-0F for grub-devel@gnu.org; Fri, 18 Jul 2008 10:47:18 -0400 Received: (qmail 6168 invoked from network); 18 Jul 2008 14:57:23 -0000 Received: from gator297.hostgator.com (74.53.228.114) by gateway08.websitewelcome.com with SMTP; 18 Jul 2008 14:57:23 -0000 Received: from c-67-185-142-228.hsd1.wa.comcast.net ([67.185.142.228]:39556 helo=localhost) by gator297.hostgator.com with esmtpsa (TLSv1:AES128-SHA:128) (Exim 4.68) (envelope-from ) id 1KJrEm-0003wO-Va for grub-devel@gnu.org; Fri, 18 Jul 2008 09:47:13 -0500 Date: Fri, 18 Jul 2008 07:46:45 -0700 From: Colin D Bennett To: grub-devel@gnu.org Message-ID: <20080718074645.309d364a@gibibit.com> In-Reply-To: References: X-Mailer: Claws Mail 3.5.0 (GTK+ 2.12.10; i686-pc-linux-gnu) Mime-Version: 1.0 Content-Type: multipart/signed; boundary="Sig_/X/Uh4H8J/Q2U+6WyNXsTjnG"; protocol="application/pgp-signature"; micalg=PGP-SHA1 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - gator297.hostgator.com X-AntiAbuse: Original Domain - gnu.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - gibibit.com X-detected-kernel: by monty-python.gnu.org: Linux 2.6 (newer, 3) Subject: Re: Idea: elimination of the normal mode (revised version) X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: The development of GRUB 2 List-Id: The development of GRUB 2 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 18 Jul 2008 14:47:23 -0000 --Sig_/X/Uh4H8J/Q2U+6WyNXsTjnG Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable On Thu, 17 Jul 2008 11:24:23 +0800 Bean wrote: > On Mon, Jul 7, 2008 at 8:29 AM, Bean wrote: > > Hi, > > > > First of all, we can still keep rescue and normal command. But > > instead of depending on normal.mod, normal command depends on > > module arg, which is an option parser. Also, these two type of > > commands are of the same command set. In fact, module arg is > > implemented as a pre parser, which goes through the list of > > arguments and extract the options. In the case of rescue command, > > the pre parser field is null, which means it wants to parse options > > itself. > > > > Then, I think of a new structure to represent all configurable > > handlers of grub. Different types of handler have different fields, > > but they all share a command header: > > > > struct grub_handler > > { > > .next, > > .name, > > .init, > > .fini > > }; > > > > Same type of handlers are linked together. We first define an enum > > to list all types. For example: > > > > enum { > > GRUB_HANDLER_INPUT, > > GRUB_HANDLER_OUTPUT, > > GRUB_HANDLER_CONSOLE, > > GRUB_HANDLER_MENU, > > GRUB_HANDLER_SCRIPT, > > GRUB_HANDLER_NUM > > }; > > > > Then, we define an array to point to the head of handler linked > > list: grub_handler[GRUB_HANDLER_NUM]; > > > > Head is the default selection. When we insert a new handler module, > > it would automatically become the new default, although we can > > switch back to old handler using a command. > > > > Here are more details about different handlers: > > > > input: > > This is the input component of terminal: > > > > struct grub_handler_input > > { > > .next, > > .name, > > .init, > > .fini, > > .checkkey, > > .getkey > > .flags, > > }; > > > > output: > > This is the output component of terminal: > > > > struct grub_handler_output > > { > > .next, > > .name, > > .init, > > .fini, > > .putchar, > > .getcharwidth, > > .getxy, > > .gotoxy, > > .cls, > > .setcolorstate, > > .setcursor, > > .flags, > > }; > > > > console interface: > > It represent the grub console, users type commands and execute them > > line by line. > > > > struct grub_handler_console > > { > > .next, > > .name, > > .init, > > .fini, > > .run > > }; > > > > menu interface: > > It represent the menu, users select a menu item and execute it. > > > > struct grub_handler_menu > > { > > .next, > > .name, > > .init, > > .fini, > > .run > > }; > > > > script engine: > > It's responsible for parsing config file to get the menu list, and > > execution of commands. > > > > struct grub_handler_script > > { > > .next, > > .name, > > .init, > > .fini, > > .readconfig > > .getmenu > > .execute > > }; > > > > The handlers are independent of each other. When they need > > something, they called specific function of the default handler. > > For example, to read a key from the console, we can use > > grub_handler[GRUB_HANDLER_INPUT]->getkey. Also, to get the list of > > items to be displayed on screen, the menu handler can call > > grub_handler[GRUB_HANDLER_SCRIPT]->getmenu. >=20 > Any comment for this idea ? I like the idea, especially the idea of separating the script engine and menu loading code from the character-terminal-based menu system. I wonder whether it would be better just to have separate variables for the different handler types like struct grub_handler_input grub_handler_input; struct grub_handler_output grub_handler_output; struct grub_handler_console grub_handler_console; instead of an array indexed by a constant representing the type, for the following reasons: 1. You would have to use casting to be able to call the functions in the handler other than the common 4 (next, name, init, fini). For instance, you couldn't do=20 grub_handler[GRUB_HANDLER_INPUT]->getkey() since the type of grub_handler is struct grub_handler[]. 2. If we did use casting for each call to a handler, it is more error prone since we would not get compiler type checking and could accidentally write GRUB_HANDLER_INPUT when we meant GRUB_HANDLER_OUTPUT with obvious consequences. 3. It is more code to write to do grub_handler[GRUB_HANDLER_INPUT]->getkey() instead of grub_handler_input->getkey() Now, suppose we did define grub_handler_input, grub_handler_output, etc. Then if there were a reason to iterate over all types of handlers, or treat handlers generically for some other reason, we could certainly also create and array of pointers to the handlers for that purpose: extern struct grub_handler *grub_handlers[GRUB_HANDLER_NUM]; extern const char *grub_handler_types[GRUB_HANDLER_NUM]; void print_current_handlers (void) { int i; for (i =3D 0; i < GRUB_HANDLER_NUM; i++) grub_printf ("handler for %s: %s\n", grub_handler_types[i], grub_handlers[i]); } We would then have to make sure the list of all handlers was kept in sync with the separate variables. This would mean a little more code for each handler type (a global "set current handler" function for each) but we would probably rarely add a new handler type so it would not be a great burden. I don't see a need for this iteration over all handlers, anyway. Regards, Colin --Sig_/X/Uh4H8J/Q2U+6WyNXsTjnG Content-Type: application/pgp-signature; name=signature.asc Content-Disposition: attachment; filename=signature.asc -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.9 (GNU/Linux) iEYEARECAAYFAkiArNkACgkQokx8fzcGbYfI7QCfbu0CZFp2mrE73JGaEFOc0oNL 48MAnArwX27ej7n6O8tYJDpO7NJFvcbc =3lEl -----END PGP SIGNATURE----- --Sig_/X/Uh4H8J/Q2U+6WyNXsTjnG--