From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1KpQPa-0003sP-Dh for mharc-grub-devel@gnu.org; Mon, 13 Oct 2008 12:36:50 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KpQPY-0003s8-Ed for grub-devel@gnu.org; Mon, 13 Oct 2008 12:36:48 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KpQPX-0003rw-UJ for grub-devel@gnu.org; Mon, 13 Oct 2008 12:36:48 -0400 Received: from [199.232.76.173] (port=36849 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KpQPX-0003rt-MR for grub-devel@gnu.org; Mon, 13 Oct 2008 12:36:47 -0400 Received: from gateway14.websitewelcome.com ([69.56.150.9]:37506) by monty-python.gnu.org with smtp (Exim 4.60) (envelope-from ) id 1KpQPX-0001gb-5X for grub-devel@gnu.org; Mon, 13 Oct 2008 12:36:47 -0400 Received: (qmail 19480 invoked from network); 13 Oct 2008 16:52:39 -0000 Received: from gator297.hostgator.com (74.53.228.114) by gateway14.websitewelcome.com with SMTP; 13 Oct 2008 16:52:39 -0000 Received: from c-67-185-142-228.hsd1.wa.comcast.net ([67.185.142.228]:45503 helo=localhost) by gator297.hostgator.com with esmtpsa (TLSv1:AES128-SHA:128) (Exim 4.68) (envelope-from ) id 1KpQPR-0004Db-ET; Mon, 13 Oct 2008 11:36:41 -0500 Date: Mon, 13 Oct 2008 09:35:53 -0700 From: Colin D Bennett To: The development of GRUB 2 Message-ID: <20081013093553.4f3e978e@gibibit.com> In-Reply-To: <48E891E4.1000507@nic.fi> References: <20080830235254.7cc5ad80@gamma.lan> <48E891E4.1000507@nic.fi> X-Mailer: Claws Mail 3.5.0 (GTK+ 2.14.3; i686-pc-linux-gnu) Mime-Version: 1.0 Content-Type: multipart/signed; boundary="Sig_/Udqh2x.PRdFvK2yYrrUpI+H"; 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-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 3) Cc: Subject: Re: [PATCH] GSoC #05 Menu entry class attribute (v2) 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: Mon, 13 Oct 2008 16:36:48 -0000 --Sig_/Udqh2x.PRdFvK2yYrrUpI+H Content-Type: multipart/mixed; boundary="MP_/5wr3jd20pGxjaaIX0ulxjKC" --MP_/5wr3jd20pGxjaaIX0ulxjKC Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline On Sun, 05 Oct 2008 13:07:32 +0300 Vesa J=C3=A4=C3=A4skel=C3=A4inen wrote: > Colin D Bennett wrote: > > This patch adds support for a 'class' attribute on menu entries. > > It is somewhat of a kludge, however since currently you just append > > "|class=3Dthis,that" to the menu entry title to specify the classes. > >=20 > > Classes are used to provide a simple and flexible way for the best > > available icon to be used in a graphical menu, but there are other > > possible uses for them as well. The idea originates from the CSS > > (cascading style sheets) and HTML 'class' concept. >=20 > Here is the patch snipped for using menuentry --class foo "title" { }. >=20 > Please try it out and see if it fits. Hi Vesa, Thanks for the argument parsing improvement. I'm glad to rip out the '|class=3D' title kludge. Here is the result of merging your patch into the menu entry class code. Regards, Colin --MP_/5wr3jd20pGxjaaIX0ulxjKC Content-Type: text/x-patch; name=05_menu-entry-class_v2.patch Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename=05_menu-entry-class_v2.patch 2008-10-13 Colin D Bennett Support classes for menu entries via the '--class CLASSNAME' argument to the menuentry command. Argument list parsing functionality by Vesa J=C3=A4=C3=A4skel=C3=A4inen . * include/grub/menu.h (grub_menu_entry_class): New struct type. (grub_menu_entry): Added 'classes' field. * include/grub/normal.h (grub_normal_menu_addentry): Changed signature to take a list of arguments instead of just a title. * include/grub/script.h (grub_script_cmd_menuentry): Replaced title with arglist. (grub_script_create_cmdmenu): Changed signature to take an arglist instead of just a single arg (title). * normal/execute.c (grub_script_execute_menuentry): Parse arguments to the 'menuentry' script command. * normal/main.c (free_menu_entry_classes): New function. (grub_normal_menu_addentry): Take and process a list of arguments; handle '--class CLASSNAME' arguments and store the list of class names in the menu entry. * normal/parser.y (menuentry): Take a list of arguments. * normal/script.c (grub_script_create_cmdmenu): Take an argument list, store it in the command. =3D=3D=3D modified file 'include/grub/menu.h' --- include/grub/menu.h 2008-08-30 19:20:13 +0000 +++ include/grub/menu.h 2008-10-13 16:15:06 +0000 @@ -20,12 +20,24 @@ #ifndef GRUB_MENU_HEADER #define GRUB_MENU_HEADER 1 =20 +struct grub_menu_entry_class +{ + char *name; + struct grub_menu_entry_class *next; +}; + /* The menu entry. */ struct grub_menu_entry { /* The title name. */ const char *title; =20 + /* The classes associated with the menu entry: + used to choose an icon or other style attributes. + This is a dummy head node for the linked list, so for an entry E, + E.classes->next is the first class if it is not NULL. */ + struct grub_menu_entry_class *classes; + /* The commands associated with this menu entry. */ struct grub_script *commands; =20 =3D=3D=3D modified file 'include/grub/normal.h' --- include/grub/normal.h 2008-10-03 14:26:41 +0000 +++ include/grub/normal.h 2008-10-13 16:15:06 +0000 @@ -141,7 +141,7 @@ char *grub_normal_do_completion (char *buf, int *restore, void (*hook) (const char *item, grub_completion_type_t type, int coun= t)); grub_err_t grub_normal_print_device_info (const char *name); -grub_err_t grub_normal_menu_addentry (const char *title, +grub_err_t grub_normal_menu_addentry (int argc, const char **args, struct grub_script *script, const char *sourcecode); char *grub_env_write_color_normal (struct grub_env_var *var, const char *v= al); =3D=3D=3D modified file 'include/grub/script.h' --- include/grub/script.h 2008-05-30 02:26:56 +0000 +++ include/grub/script.h 2008-10-13 16:15:06 +0000 @@ -113,8 +113,8 @@ { struct grub_script_cmd cmd; =20 - /* The title of the menu entry. */ - struct grub_script_arg *title; + /* The arguments for this menu entry. */ + struct grub_script_arglist *arglist; =20 /* The sourcecode the entry will be generated from. */ const char *sourcecode; @@ -204,7 +204,7 @@ =20 struct grub_script_cmd * grub_script_create_cmdmenu (struct grub_parser_param *state, - struct grub_script_arg *title, + struct grub_script_arglist *arglist, char *sourcecode, int options); =20 =3D=3D=3D modified file 'normal/execute.c' --- normal/execute.c 2008-01-15 15:32:17 +0000 +++ normal/execute.c 2008-10-13 16:15:06 +0000 @@ -216,29 +216,50 @@ grub_script_execute_menuentry (struct grub_script_cmd *cmd) { struct grub_script_cmd_menuentry *cmd_menuentry; - char *title; + struct grub_script_arglist *arglist; struct grub_script *script; + char **args =3D 0; + int argcount =3D 0; + int i =3D 0; =20 cmd_menuentry =3D (struct grub_script_cmd_menuentry *) cmd; =20 - /* The title can contain variables, parse them and generate a string - from it. */ - title =3D grub_script_execute_argument_to_string (cmd_menuentry->title); - if (! title) - return grub_errno; + if (cmd_menuentry->arglist) + { + argcount =3D cmd_menuentry->arglist->argcount; + + /* Create argv from the arguments. */ + args =3D grub_malloc (sizeof (char *) * argcount); + + if (! args) + { + return grub_errno; + } + + for (arglist =3D cmd_menuentry->arglist; arglist; arglist =3D arglis= t->next) + { + char *str; + str =3D grub_script_execute_argument_to_string (arglist->arg); + args[i++] =3D str; + } + } =20 /* Parse the menu entry *again*. */ script =3D grub_script_parse ((char *) cmd_menuentry->sourcecode, 0); =20 - if (! script) + /* Add new menu entry. */ + if (script) { - grub_free (title); - return grub_errno; + grub_normal_menu_addentry (argcount, args, + script, cmd_menuentry->sourcecode); } =20 - /* XXX: When this fails, the memory should be freed? */ - return grub_normal_menu_addentry (title, script, - cmd_menuentry->sourcecode); + /* Free arguments. */ + for (i =3D 0; i < argcount; i++) + grub_free (args[i]); + grub_free (args); + + return grub_errno; } =20 =0C =3D=3D=3D modified file 'normal/main.c' --- normal/main.c 2008-08-30 19:20:13 +0000 +++ normal/main.c 2008-10-13 16:15:06 +0000 @@ -148,14 +148,41 @@ grub_env_unset_data_slot ("menu"); } =20 +static void +free_menu_entry_classes (struct grub_menu_entry_class *head) +{ + /* Free all the classes. */ + while (head) + { + struct grub_menu_entry_class *next; + + grub_free (head->name); + next =3D head->next; + grub_free (head); + head =3D next; + } +} + grub_err_t -grub_normal_menu_addentry (const char *title, struct grub_script *script, +grub_normal_menu_addentry (int argc, const char **args, struct grub_script= *script, const char *sourcecode) { - const char *menutitle; + const char *menutitle =3D 0; const char *menusourcecode; grub_menu_t menu; grub_menu_entry_t *last; + int failed =3D 0; + int i; + struct grub_menu_entry_class *classes_head; /* Dummy head node for list= . */ + struct grub_menu_entry_class *classes_tail; + + /* Allocate dummy head node for class list. */ + classes_head =3D grub_malloc (sizeof (struct grub_menu_entry_class)); + if (! classes_head) + return grub_errno; + classes_head->name =3D 0; + classes_head->next =3D 0; + classes_tail =3D classes_head; =20 menu =3D grub_env_get_data_slot("menu"); if (! menu) @@ -167,10 +194,81 @@ if (! menusourcecode) return grub_errno; =20 - menutitle =3D grub_strdup (title); - if (! menutitle) - { + /* Parse menu arguments. */ + for (i =3D 0; i < argc; i++) + { + /* Capture arguments. */ + if (grub_strncmp ("--", args[i], 2) =3D=3D 0) + { + const char *arg =3D &args[i][2]; + + /* Handle menu class. */ + if (grub_strcmp(arg, "class") =3D=3D 0) + { + char *class_name; + struct grub_menu_entry_class *new_class; + + i++; + class_name =3D grub_strdup (args[i]); + if (! class_name) + { + failed =3D 1; + break; + } + + /* Create a new class and add it at the tail of the list. */ + new_class =3D grub_malloc (sizeof (struct grub_menu_entry_class)); + if (! new_class) + { + grub_free (class_name); + failed =3D 1; + break; + } + /* Fill in the new class node. */ + new_class->name =3D class_name; + new_class->next =3D 0; + /* Link the tail to it, and make it the new tail. */ + classes_tail->next =3D new_class; + classes_tail =3D new_class; + continue; + } + else + { + /* Handle invalid argument. */ + failed =3D 1; + grub_error (GRUB_ERR_MENU, "invalid argument for menuentry: %s", ar= gs[i]); + break; + } + } + + /* Capture title. */ + if (! menutitle) + { + menutitle =3D grub_strdup (args[i]); + } + else + { + failed =3D 1; + grub_error (GRUB_ERR_MENU, "too many titles for menuentry: %s", args[i]= ); + break; + } + } + + /* Validate arguments. */ + if ((! failed) && (! menutitle)) + { + grub_error (GRUB_ERR_MENU, "menuentry is missing title"); + failed =3D 1; + } + + /* If argument parsing failed, free any allocated resources. */ + if (failed) + { + free_menu_entry_classes (classes_head); + grub_free ((void *) menutitle); grub_free ((void *) menusourcecode); + + /* Here we assume that grub_error has been used to specify failure d= etails. */ return grub_errno; } =20 @@ -181,6 +279,7 @@ *last =3D grub_malloc (sizeof (**last)); if (! *last) { + free_menu_entry_classes (classes_head); grub_free ((void *) menutitle); grub_free ((void *) menusourcecode); return grub_errno; @@ -188,6 +287,7 @@ =20 (*last)->commands =3D script; (*last)->title =3D menutitle; + (*last)->classes =3D classes_head; (*last)->next =3D 0; (*last)->sourcecode =3D menusourcecode; =20 =3D=3D=3D modified file 'normal/parser.y' --- normal/parser.y 2008-07-02 00:00:37 +0000 +++ normal/parser.y 2008-10-13 16:15:06 +0000 @@ -204,7 +204,7 @@ ; =20 /* A menu entry. Carefully save the memory that is allocated. */ -menuentry: "menuentry" argument +menuentry: "menuentry" arguments { grub_script_lexer_ref (state->lexerstate); } newlines '{' =3D=3D=3D modified file 'normal/script.c' --- normal/script.c 2007-12-30 08:52:06 +0000 +++ normal/script.c 2008-10-13 16:15:06 +0000 @@ -206,7 +206,7 @@ The options for this entry are passed in OPTIONS. */ struct grub_script_cmd * grub_script_create_cmdmenu (struct grub_parser_param *state, - struct grub_script_arg *title, + struct grub_script_arglist *arglist, char *sourcecode, int options) { @@ -232,9 +232,9 @@ cmd->cmd.next =3D 0; /* XXX: Check if this memory is properly freed. */ cmd->sourcecode =3D sourcecode; - cmd->title =3D title; + cmd->arglist =3D arglist; cmd->options =3D options; -=20 + return (struct grub_script_cmd *) cmd; } =20 --MP_/5wr3jd20pGxjaaIX0ulxjKC-- --Sig_/Udqh2x.PRdFvK2yYrrUpI+H Content-Type: application/pgp-signature; name=signature.asc Content-Disposition: attachment; filename=signature.asc -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.9 (GNU/Linux) iEYEARECAAYFAkjzeOwACgkQokx8fzcGbYdGdQCfRgwZl7EerJCtFYIYIVra9DtP G9YAn1f5w9jQqAr4fU0JH1M4xwrRNTDT =s7lP -----END PGP SIGNATURE----- --Sig_/Udqh2x.PRdFvK2yYrrUpI+H--