changed list fn's to accept lists instead of list pointers

partial-rewrite
Ben Blazak 2013-05-24 15:03:45 -07:00
parent 1197f4d682
commit e560e476f7
6 changed files with 104 additions and 108 deletions

View File

@ -4,9 +4,6 @@
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
// TODO: change from using pointers to everything, to just using the things
// (since they're structs anyway)
/** description
* An interface to a simple linked-list that can be used to implement lists,
* queues, stacks, and things
@ -37,7 +34,7 @@
*
* - If you want to iterate through a list, use something like
*
* for (node_t * node = list->head; node; node = node->_private.next) {
* for (node_t * node = list.head; node; node = node->_private.next) {
* // do stuff
* }
*
@ -69,25 +66,23 @@
// ----------------------------------------------------------------------------
typedef struct list__node_t {
void * next; // will be cast to `list__node_t` before use
void * next; // will be cast to `list__node_t *` before use
} list__node_t;
typedef struct list__list_t {
void * head; // will be cast to `list__node_t` before use
void * tail; // will be cast to `list__node_t` before use
void * head; // will be cast to `list__node_t *` before use
void * tail; // will be cast to `list__node_t *` before use
uint8_t length;
} list__list_t;
// ----------------------------------------------------------------------------
void * list__insert ( list__list_t * list,
int8_t index,
void * node );
void * list__peek (list__list_t * list, int8_t index);
void * list__pop_index (list__list_t * list, int8_t index);
void * list__pop_node (list__list_t * list, void * node);
void * list__pop_node_next (list__list_t * list, void * node);
void list__free (list__list_t * list);
void * list__insert (list__list_t list, int8_t index, void * node);
void * list__peek (list__list_t list, int8_t index);
void * list__pop_index (list__list_t list, int8_t index);
void * list__pop_node (list__list_t list, void * node);
void * list__pop_node_next (list__list_t list, void * node);
void list__free_all (list__list_t list);
// ----------------------------------------------------------------------------
@ -125,12 +120,12 @@ void list__free (list__list_t * list);
* Insert `node` at position `index % list->length`
*
* Arguments:
* - `list`: A pointer to the list to be operated on
* - `list`: The list to be operated on
* - `index`: An `int8_t` indicating the position the new node will occupy
* - `node`: A pointer to the node to insert
* - `node`: A `void *` pointer to the node to insert
*
* Returns:
* - success: A `void *` pointer to the new node
* - success: A `void *` pointer to the inserted node
* - failure: `NULL`
*/
@ -139,8 +134,8 @@ void list__free (list__list_t * list);
* Return a pointer to the node at position `index % list->length`
*
* Arguments:
* - `list`: A pointer to the list to be operated on
* - `index`: An `int8_t` indicating the position of the node to peek at
* - `list`: The list to be operated on
* - `index`: An `int8_t` indicating the position the new node will occupy
*
* Returns:
* - success: A `void *` pointer to the node at position `index % list->length`
@ -153,12 +148,12 @@ void list__free (list__list_t * list);
* the node from the list
*
* Warnings:
* - Does not free the node's memory - this is the calling function's
* - Does not free the node's memory; this is the calling function's
* responsibility.
*
* Arguments:
* - `list`: A pointer to the list to be operated on
* - `index`: An `int8_t` indicating the position of the node to pop
* - `list`: The list to be operated on
* - `index`: An `int8_t` indicating the position the new node will occupy
*
* Returns:
* - success: A `void *` pointer to the node at position `index % list->length`
@ -170,12 +165,12 @@ void list__free (list__list_t * list);
* Remove `node` from the list, and return a pointer to it
*
* Warnings:
* - Does not free the node's memory - this is the calling function's
* - Does not free the node's memory; this is the calling function's
* responsibility.
*
* Arguments:
* - `list`: A pointer to the list to be operated on
* - `node`: A pointer to the node to pop (and free)
* - `list`: The list to be operated on
* - `node`: A `void *` pointer to the node to pop
*
* Returns:
* - success: A `void *` pointer to `node`
@ -185,11 +180,11 @@ void list__free (list__list_t * list);
// === list__pop_node_next() ===
/** functions/list__pop_node_next/description
* Remove `node` from the list, free its memory, and return a pointer to the
* next element, if the node exists
* next element, if such an element exists
*
* Arguments:
* - `list`: A pointer to the list to be operated on
* - `node`: A pointer to the node to pop (and free)
* - `list`: The list to be operated on
* - `node`: A `void *` pointer to the node to pop (and free)
*
* Returns:
* - success: A `void *` pointer to the next node in the list
@ -199,14 +194,14 @@ void list__free (list__list_t * list);
* - This is helpful, sometimes, when iterating through a list, some of who's
* members need to be removed. If performance is critical, keep in mind that
* it does have the O(n) time penalty of having to re-search the list for the
* given node's predecesor before removing the node.
* given node's predecessor before removing the node.
*/
// === list__free() ===
/** functions/list__free/description
// === list__free_all() ===
/** functions/list__free_all/description
* Free all node pointers in `list`
*
* Arguments:
* - `list`: A pointer to the list to be operated on
* - `list`: The list to be operated on
*/

View File

@ -15,151 +15,154 @@
// ----------------------------------------------------------------------------
// since we'll be casting to type `list__node_t *` a lot
#define N(name) ((list__node_t *)name)
#define list_t list__list_t
#define node_t list__node_t
// since we'll be casting to `node_t *` a lot
#define N(name) ((node_t *) name)
// ----------------------------------------------------------------------------
void * list__insert(list__list_t * list, int8_t index, void * node) {
if (!node) return NULL;
void * list__insert(list_t list, int8_t index, void * node) {
// if `node` does not exist
if (!node)
return NULL;
list->length++;
list.length++;
if (list->length == 1) {
if (list.length == 1) {
// insert as only node (no others exist yet)
list->head = node;
list->tail = node;
list.head = node;
list.tail = node;
N(node)->next = NULL;
} else {
index %= list->length;
index %= list.length;
if (index == 0) {
// insert as first node
N(node)->next = list->head;
list->head = node;
N(node)->next = list.head;
list.head = node;
} else if (index == list->length-1) {
} else if (index == list.length-1) {
// insert as last node
N(list->tail)->next = node;
list->tail = node;
N(list.tail)->next = node;
list.tail = node;
N(node)->next = NULL;
} else {
// insert as other node
void * previous = list->head;
node_t * previous = list.head;
for (uint8_t i=1; i<index; i++)
previous = N(previous)->next;
N(node)->next = N(previous)->next;
N(previous)->next = node;
previous = previous->next;
N(node)->next = previous->next;
previous->next = node;
}
}
return node;
}
void * list__peek(list__list_t * list, int8_t index) {
void * list__peek(list_t list, int8_t index) {
// if no nodes exist
if (list->length == 0)
if (list.length == 0)
return NULL;
index %= list->length;
index %= list.length;
// if last node
if (index == list->length-1)
return list->tail;
if (index == list.length-1)
return list.tail;
// else
void * node = list->head;
node_t * node = list.head;
for (uint8_t i=0; i<index; i++)
node = N(node)->next;
return node;
}
void * list__pop_index(list__list_t * list, int8_t index) {
void * list__pop_index(list_t list, int8_t index) {
// if no nodes exist
if (list->length == 0)
if (list.length == 0)
return NULL;
index %= list->length;
index %= list.length;
void * node;
node_t * node;
if (index == 0) {
// pop first node
node = list->head;
list->head = N(node)->next;
node = list.head;
list.head = N(node)->next;
} else {
// find the `index-1`th node
void * previous = list->head;
node_t * previous = list.head;
for (uint8_t i=1; i<index; i++)
previous = N(previous)->next;
previous = previous->next;
// if last node
if (index == list->length-1)
list->tail = previous;
if (index == list.length-1)
list.tail = previous;
// pop the node at `index`
node = N(previous)->next;
N(previous)->next = N(node)->next;
node = previous->next;
previous->next = N(node)->next;
}
list->length--;
list.length--;
return node;
}
void * list__pop_node(list__list_t * list, void * node) {
// if `node` is `NULL` or no nodes exist
if (!node || !list->head)
void * list__pop_node(list_t list, void * node) {
// if `node` does not exist, or no nodes exist
if (!node || list.length == 0)
return NULL;
void * previous = list->head;
node_t * previous = list.head;
if (node == list->head) {
if (node == list.head) {
// pop first node
list->head = N(node)->next;
list.head = N(node)->next;
} else {
// find the previous node (if `node` is in `list`)
while (N(previous)->next != node) {
previous = N(previous)->next;
while (previous->next != node) {
previous = previous->next;
if (!previous)
return NULL; // `node` not found
}
// if last node
if (node == list->tail)
list->tail = previous;
if (node == list.tail)
list.tail = previous;
// pop the node
N(previous)->next = N(node)->next;
previous->next = N(node)->next;
}
list->length--;
list.length--;
return node;
}
void * list__pop_node_next(list__list_t * list, void * node) {
void * list__pop_node_next(list_t list, void * node ) {
if (!list__pop_node(list, node))
return NULL;
return NULL; // `node` was not in `list`
void * next = N(node)->next;
node_t * next = N(node)->next;
free(node);
return next;
}
void list__free(list__list_t * list) {
if (list) {
void * node;
while (list->head) {
node = list->head;
list->head = N(list->head)->next;
free(node);
}
void list__free_all(list_t list) {
node_t * node;
while (list.head) {
node = list.head;
list.head = node->next;
free(node);
}
}

View File

@ -27,7 +27,7 @@
// ----------------------------------------------------------------------------
static volatile uint16_t _milliseconds__counter;
static list__list_t * _milliseconds__scheduled_events = &(list__list_t){};
static list__list_t _milliseconds__scheduled_events;
// ----------------------------------------------------------------------------

View File

@ -45,10 +45,10 @@
// ----------------------------------------------------------------------------
uint8_t event_list__append ( list__list_t * list,
uint16_t ticks,
uint8_t event_list__append ( list__list_t list,
uint16_t ticks,
void(*function)(void) );
void event_list__tick (list__list_t * list);
void event_list__tick (list__list_t list);
// ----------------------------------------------------------------------------

View File

@ -29,10 +29,10 @@ typedef struct {
// ----------------------------------------------------------------------------
uint8_t event_list__append( list__list_t * list,
uint16_t ticks,
uint8_t event_list__append( list__list_t list,
uint16_t ticks,
void(*function)(void) ) {
if (!function || !list) return 0; // success: nothing to do
if (!function) return 0; // success: nothing to do
event_t * event = malloc(sizeof(event_t));
if (!event) return 1; // error
@ -47,9 +47,7 @@ uint8_t event_list__append( list__list_t * list,
return 0; // success
}
void event_list__tick(list__list_t * list) {
if (!list) return;
void event_list__tick(list__list_t list) {
event_t * next;
event_t * run = NULL; // for keeping track of events to run
@ -57,7 +55,7 @@ void event_list__tick(list__list_t * list) {
// - keep track of the events that need to be run this "tick"
// - note that every other event is one "tick" closer to being run
ATOMIC_BLOCK( ATOMIC_RESTORESTATE ) {
for (event_t * event = list->head; event;) {
for (event_t * event = list.head; event;) {
if (event->ticks == 0) {
next = event->_private.next;
list__pop_node(list, event);

View File

@ -17,15 +17,15 @@
// ----------------------------------------------------------------------------
#define DEFINE_TIMER(name) \
static uint16_t _##name##__counter; \
static list__list_t * _##name##__scheduled_events = &(list__list_t){}; \
static uint16_t _##name##__counter; \
static list__list_t _##name##__scheduled_events; \
\
uint16_t timer__get_##name(void) { \
return _##name##__counter; \
} \
uint8_t timer__schedule_##name(uint16_t name, void(*function)(void)) { \
uint8_t timer__schedule_##name(uint16_t ticks, void(*function)(void)) { \
return event_list__append( \
_##name##__scheduled_events, name, function ); \
_##name##__scheduled_events, ticks, function ); \
} \
void timer___tick_##name(void) { \
_##name##__counter++; \