Re: Improved <linux/lists.h>

From: Bill Wendling (wendling@ganymede.isdn.uiuc.edu)
Date: Tue Feb 22 2000 - 18:59:08 EST


Also sprach Borislav Deianov:
} On Tue, Feb 22, 2000 at 04:00:11PM -0600, Bill Wendling wrote:
} > Our design team has something similar to what this looks like. One thing
} > we had which was nice, it was a FOREACH() macro. Does the above code:
} >
} > tmp = queue.next;
} > while (tmp != &queue) {
} > /* blah */
} > tmp = tmp->next;
} > }
} >
} > occur frequently enough to warrent such a beast?
}
} I've thought about this since I have the above (more or less) all over
} my code. The problem is, I could find no good way to do that macro. I
} ended up with something like:
}
} #define for_each_entry(p,tmp,head,type,member) \
} for (tmp = (head)->next; \
} p = list_entry(tmp,type,member), tmp != (head); \
} tmp = tmp->next)
}
} struct node {
} int data;
} struct list_head list;
} };
}
} struct list_head *queue, *tmp;
} struct node *n;
}
} ...
}
} for_each_entry(n,tmp,queue,struct node,list)
} printf("%d\n", n->data);
}
} ...but I could never remember what order the fields come in. Or you
} can leave the list_entry call outside, but then the macro doesn't help
} much, just reduces the readability of the code. So no macro for me.
}
I was thinking something slightly simpler..Like this:

#define FOR_EACH(pos, head) \
        for (pos = (head)->next; pos != (head); pos = pos->next)

So a sample program would be:

#include <stdio.h>
#include "list.h"

struct node {
        int data;
        struct list_head list;
};

int main(void)
{
        struct list_head queue, *pos;
        struct node n1, n2, n3;
        n1.data = 1;
        n2.data = 2;
        n3.data = 3;

        INIT_LIST_HEAD(&queue);
        list_add(&n1.list, &queue);
        list_add(&n2.list, &queue);
        list_add(&n3.list, &queue);
        FOR_EACH(pos, &queue) {
                struct node *n = list_entry(pos, struct node, list);
                printf("%d\n", n->data);
        }
/* Instead of:

        pos = queue.next;
        while(pos != &queue) {
                struct node *n = list_entry(pos, struct node, list);
                printf("%d\n", n->data);
                pos = pos->next;
        }
*/
        list_del(&n2.list);
        list_del(&n1.list);
        list_del(&n3.list);
}

-- 
|| Bill Wendling			wendling@ganymede.isdn.uiuc.edu

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed Feb 23 2000 - 21:00:32 EST