"C++fan" <jw****@excite.com> wrote in message
news:15**************************@posting.google.c om...
The following code is for list operation. But I can not understand.
Could anyone explain the code for me?
/*
* List definitions.
*/
#define LIST_HEAD(name, type)
struct name {
type *lh_first; /* first element */
}
#define LIST_ENTRY(type)
struct {
type *le_next; /* next element */
type **le_prev; /* address of previous next element */
}
Questions:
Why the struct does not have a name?
Is the list a two-way list?
/*
* List functions.
*/
#define LIST_INIT(head) {
(head)->lh_first = NULL;
}
#define LIST_INSERT_AFTER(listelm, elm, field) {
if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)
(listelm)->field.le_next->field.le_prev =
&(elm)->field.le_next;
(listelm)->field.le_next = (elm);
(elm)->field.le_prev = &(listelm)->field.le_next;
}
Question:
What is listelm, elm, field?
#define LIST_INSERT_HEAD(head, elm, field) {
if (((elm)->field.le_next = (head)->lh_first) != NULL)
(head)->lh_first->field.le_prev =
&(elm)->field.le_next;
(head)->lh_first = (elm);
(elm)->field.le_prev = &(head)->lh_first;
}
Question:
If elm becomes head, what's the purpose of the last sentence:
(elm)->field.le_prev = &(head)->lh_first;
Thanks in advance.
Jack
Jack, that's quite a puzzle. As a true "C++fan" I hope you won't actually
use crap like this unless you have to! (Hint: std::list)
Anyway, I'm far from sure of this but maybe it is used as follows:
struct fred_node
{
LIST_ENTRY(struct fred_node) node;
Fred fred; // Fred is some arbitrary type -- this is a list of Freds
};
which translates to:
struct fred_node
{
struct {
struct fred_node *le_next; /* next element */
struct fred_node **le_prev; /* address of previous next element */
} node;
Fred fred; // Fred is some arbitrary type -- this is a list of Freds
};
This defines the node type. Then make the list head:
LIST_HEAD(fred_head, struct fred_node) fredlist;
LIST_INIT(fredlist);
which is equivalent to:
struct fred_head {
struct fred_node *lh_first; /* first element */
} fredlist;
fredlist->lh_first = NULL;
Now add a node:
struct fred_node *new_node = (struct fred_node *) malloc(sizeof(struct
fred_node));
new_node.fred = Fred(21); // whatever that means
LIST_INSERT_HEAD(mylist, new_node, node);
which expands to
struct fred_node *new_node = (struct fred_node *) malloc(sizeof(struct
fred_node));
new_node.fred = Fred(21); // whatever that means
if ((new_node->node.le_next = (fredlist)->lh_first) != NULL)
fredlist->lh_first->node.le_prev = &new_node->node.le_next;
fredlist->lh_first = new_node;
new_node->node.le_prev = &new_node;
Now add another node:
struct fred_node *newer_node = (struct fred_node *) malloc(sizeof(struct
fred_node));
newer_node.fred = Fred(-33); // whatever that means
LIST_INSERT_AFTER(newer_node, new_node, node);
which expands to:
struct fred_node *newer_node = (struct fred_node *) malloc(sizeof(struct
fred_node));
newer_node.fred = Fred(-33); // whatever that means
if ((new_node->node.le_next = newer_node->node.le_next) != NULL)
newer_node->node.le_next->node.le_prev = &new_node->node.le_next;
newer_node->node.le_next = new_node;
new_node->node.le_prev = &new_node;
Well, that's what I came up with. I didn't test anything. Good luck.
--
Cy
http://home.rochester.rr.com/cyhome/