[alsa-devel] Replace include/list.h with non-GPL implementation
Takashi Iwai
tiwai at suse.de
Fri Jul 24 18:32:30 CEST 2015
On Fri, 24 Jul 2015 10:13:16 +0200,
Takashi Iwai wrote:
>
> On Fri, 24 Jul 2015 09:34:19 +0200,
> Clemens Lang wrote:
> >
> > On Thu, Jul 23, 2015 at 09:03:31PM +0200, Takashi Iwai wrote:
> > > Well, the linked-list macro is a trivial thing each beginner
> > > programmer starts writing at school. And, the API itself can't be an
> > > issue.
> >
> > I agree, but that does not necessarily mean that the license wouldn't
> > apply. Consider this thought experiment. You write a two-page prose
> > article on how a linked list works. Obviously, the concept of a linked
> > list is trivial -- but does that mean copyright doesn't apply to your
> > article? I think we have a similar situation here; the concept of a list
> > may be trivial, but that doesn't mean the implementation is.
>
> Sure, it can be written differently. But my point is that it is (or
> must be) trivial to write a linked list code for C programmer. We can
> easily drop the existing code and replace with our own.
>
> > > That is, it'd be enough just rewriting the existing list.h (e.g.
> > > renaming variables, shuffles the call order, rephrase the comments) by
> > > ourselves without introducing a big piece of codes of even a different
> > > license, IMO.
> >
> > Unless you re-implement a list from scratch that provides the same API
> > that wouldn't really help you.
>
> So why not writing from scratch? We just need only a few things:
>
> struct list_head
> list_entry()
> list_for_each()
> list_for_each_safe()
> list_add()
> list_add_tail()
FYI, below is an example replacement of list.h I wrote quickly from
scratch. It turned out that LIST_HEAD(), INIT_LIST_HEAD(), list_del()
and list_empty() are needed in addition.
Takashi
===
/* Doubly linked list macros compatible with Linux kernel */
#ifndef _LIST_H
#define _LIST_H
#include <stddef.h>
struct list_head {
struct list_head *next;
struct list_head *prev;
};
/* one-shot definition of a list head */
#define LIST_HEAD(x) \
struct list_head x = { &x, &x }
/* initialize a list head explicitly */
static inline void INIT_LIST_HEAD(struct list_head *p)
{
p->next = p->prev = p;
}
#define list_entry_offset(p, type, offset) \
((type *)((char *)(p) - (offset)))
/* list_entry - retrieve the original struct from list_head
* @p: list_head pointer
* @type: struct type
* @member: struct field member containing the list_head
*/
#define list_entry(p, type, member) \
list_entry_offset(p, type, offsetof(type, member))
/* list_for_each - iterate over the linked list
* @p: iterator, a list_head pointer variable
* @list: list_head pointer containing the list
*/
#define list_for_each(p, list) \
for (p = (list)->next; p != (list); p = p->next)
/* list_for_each_safe - iterate over the linked list, safe to delete
* @p: iterator, a list_head pointer variable
* @s: a temporary variable to keep the next, a list_head pointer, too
* @list: list_head pointer containing the list
*/
#define list_for_each_safe(p, s, list) \
for (p = (list)->next; s = p->next, p != (list); p = s)
/* list_add - prepend a list entry at the head
* @p: the new list entry to add
* @list: the list head
*/
static inline void list_add(struct list_head *p, struct list_head *list)
{
struct list_head *first = list->next;
p->next = first;
first->prev = p;
list->next = p;
p->prev = list;
}
/* list_add_tail - append a list entry at the tail
* @p: the new list entry to add
* @list: the list head
*/
static inline void list_add_tail(struct list_head *p, struct list_head *list)
{
struct list_head *last = list->prev;
last->next = p;
p->prev = last;
p->next = list;
list->prev = p;
}
/* list_del - delete the given list entry */
static inline void list_del(struct list_head *p)
{
p->prev->next = p->next;
p->next->prev = p->prev;
}
/* list_empty - returns 1 if the given list is empty */
static inline int list_empty(const struct list_head *p)
{
return p->next == p;
}
#endif /* _LIST_H */
More information about the Alsa-devel
mailing list