From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1FdFW5-000753-6f for mharc-grub-devel@gnu.org; Mon, 08 May 2006 19:51:53 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1FdFW3-000742-27 for grub-devel@gnu.org; Mon, 08 May 2006 19:51:51 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1FdFVy-00071q-7z for grub-devel@gnu.org; Mon, 08 May 2006 19:51:48 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1FdFVy-00071g-15 for grub-devel@gnu.org; Mon, 08 May 2006 19:51:46 -0400 Received: from [212.27.42.35] (helo=smtp5-g19.free.fr) by monty-python.gnu.org with esmtp (Exim 4.52) id 1FdFWt-0004jh-10 for grub-devel@gnu.org; Mon, 08 May 2006 19:52:44 -0400 Received: from yoda (std93-4-82-229-216-106.fbx.proxad.net [82.229.216.106]) by smtp5-g19.free.fr (Postfix) with ESMTP id BC05024C57 for ; Tue, 9 May 2006 01:51:41 +0200 (CEST) From: =?iso-8859-1?Q?Eric_Salom=E9?= To: "'The development of GRUB 2'" Date: Tue, 9 May 2006 01:51:41 +0200 Message-ID: <003001c672fa$5adab170$0b00a8c0@yoda> MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_NextPart_000_0031_01C6730B.1E668EB0" X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook, Build 10.0.2627 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869 In-Reply-To: <3C2082E50F32E1459503A8E675E24EE4B0462A@icex3.ic.ac.uk> Importance: Normal Subject: RE : a simple list 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, 08 May 2006 23:51:51 -0000 This is a multi-part message in MIME format. ------=_NextPart_000_0031_01C6730B.1E668EB0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Hi, I didn=92t take a good look at current iterate functions in Grub 2, yet. =20 Most iterations needs a =93init=94 (before treatment of first item) and = a =93fini=94 (after treatment of last item). Further more, one might want to make iteration functions = =93re-entrant=94 (or recursive), or call-back other functions in a generic way. =20 One way to get to such behavior easily cost a bit more than the example you provided :=20 you may just add an argument (let=92s call it the context object) to the call of the iterate function : =20 #define grub_iterate_list(list, func, context) \ {typeof(list) el =3D list; while (el) {func(context, el); = el=3Del->next;} func(context, NULL)} or #define grub_iterate_list(list, func) \ {void * context =3D NULL; typeof(list) el =3D list; while (el) {func(&context, el); el=3Del->next;} func(&context, NULL)} but I prefer the first define as it allows transmission of a full context to the iteration function. =20 my_struct * my_ctxt; =20 my_ctxt =3D NULL; grub_iterate_list(list, my_func, &my_ctxt); =20 void my_func (my_struct ** ctxt, my_item * item) { if (item =3D=3D NULL) { /* End of iteration : Do any cleanup */ if (*ctxt =3D=3D NULL) return; free (*ctxt) =85=85 =85.. return; } if (*ctxt =3D=3D NULL) { /* First iteration : Do any initialization */ *ctxt =3D malloc (sizeof (my_struct)); =85. =85.. } /* Do the iteration stuff */ =85.. return; } =20 In grub_iterate_list_brk, you can use context to send a patern or model object to compare each item of the list with. =20 The draw back is it makes iteration function a bit less readable, but a lot more powerful. =20 _________________________________________ Eric Salom=E9 =96 Paris, France =20 -----Message d'origine----- De : grub-devel-bounces+esalome=3Dctx.net@gnu.org [mailto:grub-devel-bounces+esalome=3Dctx.net@gnu.org] De la part de Guffens, Vincent Envoy=E9 : lundi 8 mai 2006 01:14 =C0 : grub-devel@gnu.org Objet : a simple list =20 Hi, I need to use a simple list to register the pci devices, drivers and so on. I notice that there are lists like that already in the code so what would you think about having a list.h file like that ? /* A very simple list. * * If you want a list of struct myitem * you do * * struct myitem *item_list; * * where myitem MUST have its next pointer as the FIRST field * * and you can then add, delete the EL item, * grub_add_list (&item_list, el); * grub_del_list (&item_list, el); * * or call HOOK(item) for each element of the list * grub_iterate_list (item_list, hook); * * This brk version will point el to the list item for which * HOOK(EL) returns a non-null value * grub_iterate_list_brk (item_list, hook, el); * */ struct obj { struct obj *next; /* MUST BE FIRST */ }; #define grub_del_list(list, el) _grub_del_list((struct obj**) list, (struct obj*) el) #define grub_add_list(list, el) _grub_add_list((struct obj**) list, (struct obj*) el) #define grub_find_list(list, el) \ (typeof(list)) _grub_find_list((struct obj*) list, (struct obj*) el) #define grub_iterate_list(list, func) \ {typeof(list) el =3D list; while (el) {func(el); el=3Del->next;}} #define grub_iterate_list_brk(list, func, it) \ {typeof(list) el =3D list; it =3D 0; \ while (el) {if (func(el)) {it =3D el; break;} el=3Del->next; }} static inline struct obj* _grub_find_list (struct obj *list, struct obj *el) { struct obj *it =3D list; for (it =3D list; it; it=3Dit->next) { if (it =3D=3D el) return el; } return 0; }; static inline void _grub_add_list (struct obj **list, struct obj *el) { if ( (!el) || (_grub_find_list (*list, el)) ) return; =20 el->next =3D *list; *list =3D el; }; static inline void _grub_del_list (struct obj **list, struct obj *el) { struct obj **p; struct obj *q; for (p =3D list, q =3D *p; q; p =3D &(q->next), q =3D q->next) if (q =3D=3D el) { *p =3D q->next; break; } }; ------=_NextPart_000_0031_01C6730B.1E668EB0 Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable a simple list

Hi,

I didn’t take = a good look at current iterate functions in Grub 2, yet.

 

Most iterations = needs a “init” (before treatment of first item) and a “fini” (after = treatment of last item).

Further more, one = might want to make iteration functions “re-entrant” (or recursive), or = call-back other functions in a generic way.

 

One way to get to = such behavior easily cost a bit more than the example you provided : =

you may just add an = argument (let’s call it the context object) to the call of the iterate = function :

 

#define grub_iterate_list(list, func, = context) \
  {typeof(list) el =3D list; while (el) {func(context, el); = el=3Del->next;} func(context, NULL)}
or

#define grub_iterate_list(list, func) \
  {void * context =3D NULL; typeof(list) el =3D list; while (el) = {func(&context, el); el=3Del->next;} func(&context, NULL)}
but I prefer the first define as it allows transmission of a full = context to the iteration function.

 

my_struct * my_ctxt;

 

my_ctxt =3D NULL; grub_iterate_list(list, my_func, = &my_ctxt);

 

void my_func (my_struct ** ctxt, my_item * item) {

=A0=A0=A0=A0=A0 if (item =3D=3D NULL) {

=A0=A0=A0=A0=A0 =A0=A0=A0 /* End of iteration : Do any cleanup */

=A0=A0=A0=A0=A0 =A0=A0=A0 if (*ctxt =3D=3D NULL) return;

=A0=A0=A0=A0=A0 =A0=A0=A0 free (*ctxt) ……

=A0=A0=A0=A0=A0 =A0=A0=A0 …..

=A0=A0=A0=A0=A0 =A0=A0=A0 return;

=A0=A0=A0=A0=A0 }

=A0=A0=A0=A0=A0 if (*ctxt =3D=3D NULL) {

=A0=A0=A0=A0=A0 =A0=A0=A0=A0 /* First iteration : Do any initialization */

=A0=A0=A0=A0=A0 =A0=A0=A0=A0 *ctxt =3D malloc (sizeof (my_struct)); ….

=A0=A0=A0=A0=A0 =A0=A0=A0=A0 …..

}

/* Do the iteration stuff */

…..

return;

}

 

In = grub_iterate_list_brk, you can use context to send a patern or model object to compare each item of = the list with.

 

The draw back is it = makes iteration function a bit less readable, but a lot more = powerful.

=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0

_________________= ________________________

Eric Salom=E9 = Paris, France

 

-----Message d'origine-----
De : grub-devel-bounces+esalome=3Dctx.net@gnu.org [mailto:grub-devel-bounces+esalome=3Dctx.net@gnu.org] De la part de Guffens, Vincent
Envoy=E9 : lundi 8 = mai 2006 01:14
=C0 : = grub-devel@gnu.org
Objet : a simple = list

 

Hi,

I need to use a simple list to register the pci devices, drivers and so = on. I notice that there are lists like that already in the code so what would = you think about having a list.h file like that ?

/* A very simple list.
 *
 * If you want a list of struct myitem
 * you do
 *
 * struct myitem *item_list;
 *
 * where myitem MUST have its next pointer as the FIRST field
 *
 * and you can then add, delete the EL item,
 * grub_add_list (&item_list, el);
 * grub_del_list (&item_list, el);
 *
 * or call HOOK(item) for each element of the list
 * grub_iterate_list (item_list, hook);
 *
 * This brk version will point el to the list item for which
 * HOOK(EL) returns a non-null value
 * grub_iterate_list_brk (item_list, hook, el);
 *
 */

struct obj {
  struct obj *next; /* MUST BE FIRST */
};

#define grub_del_list(list, el) _grub_del_list((struct obj**) list, = (struct obj*) el)
#define grub_add_list(list, el) _grub_add_list((struct obj**) list, = (struct obj*) el)
#define grub_find_list(list, el) \
  (typeof(list)) _grub_find_list((struct obj*) list, (struct obj*) = el)
#define grub_iterate_list(list, func) \
  {typeof(list) el =3D list; while (el) {func(el); = el=3Del->next;}}
#define grub_iterate_list_brk(list, func, it) \
  {typeof(list) el =3D list; it =3D 0; \
    while (el) {if (func(el)) {it =3D el; break;} = el=3Del->next; }}

static inline struct obj*  _grub_find_list (struct obj *list, = struct obj *el)
{
  struct obj *it =3D list;
  for (it =3D list; it; it=3Dit->next)
  {
    if (it =3D=3D el) return el;
  }
  return 0;
};

static inline void _grub_add_list (struct obj **list, struct obj = *el)
{
  if ( (!el) || (_grub_find_list (*list, el)) )
    return;
 
  el->next =3D *list;
  *list =3D el;
};

static inline void _grub_del_list (struct obj **list, struct obj = *el)
{
  struct obj **p;
  struct obj *q;

  for (p =3D list, q =3D *p; q; p =3D &(q->next), q =3D = q->next)
    if (q =3D=3D el)
      {
        *p =3D q->next;
        break;
      }
};

------=_NextPart_000_0031_01C6730B.1E668EB0--