grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE : a simple list


From: Eric Salomé
Subject: RE : a simple list
Date: Tue, 9 May 2006 22:31:30 +0200

Hi Vincent,

I picked up your email from the archive as I didn't received it yet.

As you see, it's very easy with a simple #define to create simple code
for simple cases and yet be powerful for more complex cases :
#define grub_iterate_list_brk(list, func, context, it) \
  {typeof(list) el = list; it = 0; \
    while (el) {if (func(context, el)) {it = el; break;} el=el->next; }}

that you can call with 

grub_iterate_list_brk(grub_devices, compare, dev, it);

with the simpliest compare function between two devices, and you get
in-line functions nearly as simpler as the one you wrote.

But let's try this :

item * grub_iterate_list_brk (item * start, 
                void * (*fct) (void * a, void * b), void * search) {
        while (start && fct(search, (void *) start)) start =
start->next;
        return start ? start : (item *) fct(search, NULL);
}

that you can call with :

it = (dev *) grub_iterate_list_brk((item *) grub_devices, 
                                devcompare, device);

You are not in-lining functions (that makes the code smaller) and this
is a simple devcompare function to see how it works :

void * devcompare (dev * a, dev * b) {
        if (b == NULL) return NULL;
        if (a == NULL) return NULL;
        return (void *) strcmp (a->name, b->name);
}

Which is 3 line long but still is readable ... and yet powerful :

If (b == NULL) return NULL;
You have ended the list and didn't find a match ? grub_iterate_list_brk
let the compare function choose what it likes to return as a result :
Can be NULL (not found)
Can be a default value
Can be the "best" item picked out of the iteration process that matches
best the criteria; as you like :-)

If (a == NULL) return NULL;
What happens then ? if you call grub_iterate_list_brk with no criteria
(device == NULL), than it assumes you want any item and returns the
first item in the list. That's good behaviour and only a small overhead
in devcompare.

Return (void *) strcmp (a->name, b->name); 
Grub_iterate_list_brk return the item for which the compare function
returns 0 (or NULL), so that you can easily write :
Return (void *) (
        a->id - b->id
   || a->magic - b-> magic
   || strcmp(a->name, b->name) );

  
Is that what you were looking for ?

PS: Sorry folks for my previous emails sent in html : it sent lots of
useless blank lines for nothing.
________________________________________
Eric Salomé – Paris, France

From: 
vincent guffens
Subject: 
Re: RE : a simple list
Date: 
Tue, 09 May 2006 10:08:24 +0100
User-agent: 
Debian Thunderbird 1.0.7 (X11/20051017)

Thank you for this information. Adding the concept of context is indeed
the right idea. I was doing it as follows

void function (grub_device_t dev)
{
 grub_device_t it;
 auto int look_for_dev (grub_device_t);

  int look_for_dev (grub_device_t grub_device_t other_dev)
  {
     return compare (dev, other_dev)
  }

grub_iterate_list_brk (grub_devices, look_for_dev, it);
}

but it has to be compared with something like

void function (grub_device_t dev)
{
  grub_device_t it = grub_devices;

  while (it)
  {
     if ( compare (dev, it) )
       break;
  }
}


which is obviously simpler. Maybe the only two functions that are really
needed are add and del ?






reply via email to

[Prev in Thread] Current Thread [Next in Thread]