Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,7 @@ ifneq (,$(findstring sixlowpan,$(USEMODULE)))
ifeq (,$(findstring transceiver, $(USEMODULE)))
USEMODULE += transceiver
endif
ifeq (,$(findstring list, $(USEMODULE)))
USEMODULE += list
endif
endif
3 changes: 3 additions & 0 deletions sys/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ endif
ifneq (,$(findstring ccn_lite_client,$(USEMODULE)))
DIRS += net/ccn_lite/util
endif
ifneq (,$(findstring list,$(USEMODULE)))
DIRS += list
endif

all: $(BINDIR)$(MODULE).a
@for i in $(DIRS) ; do "$(MAKE)" -C $$i ; done ;
Expand Down
47 changes: 47 additions & 0 deletions sys/include/list.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#ifndef SIMPLE_LIST_H_
#define SIMPLE_LIST_H_
#include <stddef.h>
#include <stdlib.h>

struct simple_list_elem;

#define simple_list_add_head(head) _simple_list_add_head((struct simple_list_elem**) head, calloc(1, sizeof **head))
#define simple_list_set_head(head, node) _simple_list_add_head((struct simple_list_elem**) head, node)
#define simple_list_add_tail(head) _simple_list_add_tail((struct simple_list_elem**) head, calloc(1, sizeof **head))
#define simple_list_set_tail(head, node) _simple_list_add_tail((struct simple_list_elem**) head, node)
#define simple_list_add_before(head, value) *head == 0 ? simple_list_add_head(head) : \
_simple_list_add_before((struct simple_list_elem**) head, calloc(1, sizeof **head), value, (void*) &(*(head))->value - (void*) *head)
#define simple_list_set_before(head, node, value) *head == 0 ? simple_list_set_head(head, node) : \
_simple_list_add_before((struct simple_list_elem**) head, node, value, (void*) &(*(head))->value - (void*) *head)
#define simple_list_find(head, value) head == 0 ? NULL : \
_simple_list_find((struct simple_list_elem*) head, value, (void*) &((head)->value) - (void*) head, 0)
#define simple_list_find_memcmp(head, value) head == 0 ? NULL : \
_simple_list_find((struct simple_list_elem*) head, value, (void*) &((head)->value) - (void*) head, sizeof(*value))
#define simple_list_find_cmp(head, value, comperator) head == 0 ? NULL : \
_simple_list_find_cmp((struct simple_list_elem*) head, value, (void*) &((head)->value) - (void*) head, comperator)
#define simple_list_remove(head, node) _simple_list_remove((struct simple_list_elem**) head, (struct simple_list_elem*) node, 0)
#define simple_list_extract(head, node) _simple_list_remove((struct simple_list_elem**) head, (struct simple_list_elem*) node, 1)
#define simple_list_clear(head) _simple_list_clear((struct simple_list_elem**) head)

#define simple_list_for_each(head, node) for (node = head; node; node = node->next)
#define simple_list_for_each_safe(head, node, prev, skipped) \
for (skipped = 0, prev = 0, node = head; node; prev = (skipped ? prev : node), node = (skipped ? node : node->next), skipped = 0)
#define simple_list_for_each_remove(head, node, prev) { \
if (!prev) { \
skipped = 1; \
*head = (*head)->next; \
} else \
prev->next = node->next; \
free(node); \
node = prev ? prev : *head; \
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we don't want multi line defines, so all of these functions should go as normal c functions.

The rule of thumb:use define for function aliases, but if you have more than one command use a normal function

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but they operate directly on the variables inside the loop, the defines are there to make the functions easier to use and write.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my opinion, complex Macros make code really hard to debug. That was the intention behind the last point in:
https://github.com/RIOT-OS/RIOT/wiki/Coding-conventions#wiki-functions

So, I'm with @mehlis here.


void* _simple_list_add_head(struct simple_list_elem** head, void* mem);
void* _simple_list_add_tail(struct simple_list_elem** head, void* mem);
void* _simple_list_add_before(struct simple_list_elem** head, void* mem, int needle, int offset);
void* _simple_list_find(struct simple_list_elem* head, void* needle, int offset, size_t size);
void* _simple_list_find_cmp(struct simple_list_elem* head, void* needle, int offset, int compare(void*, void*));
void* _simple_list_remove(struct simple_list_elem** head, struct simple_list_elem* node, int keep);
void _simple_list_clear(struct simple_list_elem** head);

#endif /* SIMPLE_LIST_H_ */
5 changes: 5 additions & 0 deletions sys/list/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
INCLUDES = -I../include -I$(RIOTBASE)/core/include
MODULE = list

include $(RIOTBASE)/Makefile.base

141 changes: 141 additions & 0 deletions sys/list/list.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
#include <stdlib.h>
#include <string.h>

#include "list.h"

struct simple_list_elem {
struct simple_list_elem* next;
};

void* _simple_list_add_tail(struct simple_list_elem** head, void* mem) {
struct simple_list_elem* _head = *head;

/* check out-of-memory condition */
if (mem == NULL)
return NULL;

if (!_head) {
*head = mem;
return *head;
}

while (_head->next) {
_head = _head->next;
}

_head = _head->next = mem;
return _head;
}

void* _simple_list_add_head(struct simple_list_elem** head, void* mem) {
struct simple_list_elem* _head = *head;

/* check out-of-memory condition */
if (mem == NULL)
return NULL;

*head = mem;
(*head)->next = _head;

return *head;
}

void* _simple_list_add_before(struct simple_list_elem** head, void* mem, int needle, int offset) {
struct simple_list_elem* _head = *head;
struct simple_list_elem* prev = 0;

/* check out-of-memory condition */
if (mem == NULL)
return NULL;

if (!_head) {
*head = mem;
return *head;
}

while(_head) {
int* buff = (void*) _head + offset;
if (*buff > needle) {
if (prev) {
prev->next = mem;
prev->next->next = _head;
return prev->next;
}

prev = mem;
prev->next = _head;
*head = prev;
return prev;
}
prev = _head;
_head = _head->next;
}

_head = prev->next = mem;
return _head;
}

void* _simple_list_find(struct simple_list_elem* head, void* needle, int offset, size_t size) {
while (head) {
void** buff = (void*) head + offset;

if (size == 0 && *buff == needle)
return head;
if (size > 0 && memcmp(*buff, needle, size) == 0)
return head;
head = head->next;
}

return 0;
}

void* _simple_list_find_cmp(struct simple_list_elem* head, void* needle, int offset, int compare(void*, void*)) {
while (head) {
void** buff = (void*) head + offset;

if (compare(*buff, needle) == 0)
return head;

head = head->next;
}

return 0;
}

void* _simple_list_remove(struct simple_list_elem** head, struct simple_list_elem* node, int keep) {
struct simple_list_elem* _head = *head;
struct simple_list_elem* prev = 0;

while (_head && _head != node) {
prev = _head;
_head = _head->next;
}

/* not found */
if (_head != node)
return NULL;

/* remove head */
if (!prev)
*head = _head->next;
else
prev->next = node->next;

if (keep)
return node;

free(node);
return (void*) 1;
}

void _simple_list_clear(struct simple_list_elem** head) {
struct simple_list_elem *tmp, *_head = *head;

while (_head != NULL) {
tmp = _head;
_head = _head->next;
free(tmp);
}

*head = NULL;
}
Loading