grub-devel
[Top][All Lists]
Advanced

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

Re: Handlers


From: Vesa Jääskeläinen
Subject: Re: Handlers
Date: Fri, 29 Aug 2008 22:43:13 +0300
User-agent: Thunderbird 2.0.0.16 (Windows/20080708)

Marco Gerards wrote:
> If I knew a better way, I would have used it.  I think the
> alternatives will all end up in either code duplication or a loss of
> type safety that now is at least present through warnings.  But please
> understand that you only have to use the macros, not change them :-)
> 
> Suggestions are welcome.

Hi,

Well... How about something like this?

It only requires one cast and no macros at all.

Thanks,
Vesa Jääskeläinen
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct grub_list 
{
        struct grub_list *next;
} grub_list_t;

typedef struct
{
        /* Has to be first */
        grub_list_t entry;

        /* Just some data */
        char name[32];
} grub_fs_t;

void grub_list_add(grub_list_t **list, grub_list_t *item)
{
        item->next = *list;
        *list = item;
}

void grub_list_remove(grub_list_t **list, grub_list_t *item)
{
        grub_list_t *prev = 0;
        grub_list_t *tmp = *list;
        
        while (tmp)
        {
                if (tmp == item)
                {
                        if (! prev)
                        {
                                *list = tmp->next;
                                tmp->next = 0;
                                return;
                        }
                        else
                        {
                                prev->next = tmp->next;
                                tmp->next = 0;
                                return;
                        }
                }
                
                prev = tmp;
                tmp = tmp->next;
        }
}

int grub_list_iterate(grub_list_t *list, int (*hook) (const grub_list_t *item))
{
        while (list)
        {
                if (hook(list))
                        return 1;

                list = list->next;
        }

        return 0;
}

int grub_fs_print (const grub_list_t *list_item)
{
        grub_fs_t *item = (grub_fs_t *)list_item;

        printf("'%s'\n", item->name);

        return 0;
}

int main()
{
        grub_fs_t item1;
        grub_fs_t item2;
        grub_fs_t item3;

        grub_list_t *fs_list = 0;

        memset(&item1, 0, sizeof(item1));
        memset(&item2, 0, sizeof(item2));
        memset(&item3, 0, sizeof(item3));

        strcpy(item1.name, "item 1");
        strcpy(item2.name, "item 2");
        strcpy(item3.name, "item 3");

        grub_list_add(&fs_list, &item1.entry);
        grub_list_add(&fs_list, &item2.entry);
        grub_list_add(&fs_list, &item3.entry);

        printf("---\n");
        grub_list_iterate(fs_list, grub_fs_print);
        
        printf("---\n");
        grub_list_remove(&fs_list, &item2.entry);
        grub_list_iterate(fs_list, grub_fs_print);

        printf("---\n");
        grub_list_remove(&fs_list, &item2.entry);
        grub_list_iterate(fs_list, grub_fs_print);

        printf("---\n");
        grub_list_remove(&fs_list, &item1.entry);
        grub_list_iterate(fs_list, grub_fs_print);

        printf("---\n");
        grub_list_remove(&fs_list, &item3.entry);
        grub_list_iterate(fs_list, grub_fs_print);

        printf("---\n");
        grub_list_remove(&fs_list, &item3.entry);
        grub_list_iterate(fs_list, grub_fs_print);
        printf("---\n");

        return 0;
}

reply via email to

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