-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added a stack implementation to be used for each module become/unbeco…
…me functions, that are finally useful. Stack is public too.
- Loading branch information
Showing
17 changed files
with
357 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
#pragma once | ||
|
||
#include "module_cmn.h" | ||
|
||
/** Stack interface **/ | ||
|
||
typedef enum { | ||
STACK_WRONG_PARAM = -4, | ||
STACK_MISSING, | ||
STACK_ERR, | ||
STACK_OMEM, | ||
STACK_OK | ||
} stack_ret_code; | ||
|
||
/* Callback for stack_iterate */ | ||
typedef stack_ret_code (*stack_cb)(void *, void *); | ||
|
||
/* Incomplete struct declaration for stack */ | ||
typedef struct _stack stack_t; | ||
|
||
#ifdef __cplusplus | ||
extern "C"{ | ||
#endif | ||
|
||
_public_ stack_t *stack_new(void); | ||
_public_ stack_ret_code stack_iterate(const stack_t *s, const stack_cb fn, void *userptr); | ||
_public_ stack_ret_code stack_push(stack_t *s, void *data, bool autofree); | ||
_public_ void *stack_pop(stack_t *s); | ||
_public_ void *stack_peek(const stack_t *s); | ||
_public_ stack_ret_code stack_free(stack_t *s); | ||
_public_ int stack_length(const stack_t *s); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
#include "poll_priv.h" | ||
|
||
typedef struct _elem { | ||
void *userptr; | ||
bool autofree; | ||
struct _elem *prev; | ||
} stack_elem; | ||
|
||
struct _stack { | ||
int len; | ||
stack_elem *data; | ||
}; | ||
|
||
stack_t *stack_new(void) { | ||
stack_t *s = memhook._malloc(sizeof(stack_t)); | ||
if (s) { | ||
s->len = 0; | ||
s->data = NULL; | ||
} | ||
return s; | ||
} | ||
|
||
stack_ret_code stack_iterate(const stack_t *s, const stack_cb fn, void *userptr) { | ||
MOD_ASSERT(s, "NULL stack.", STACK_WRONG_PARAM); | ||
MOD_ASSERT(fn, "NULL cb.", STACK_WRONG_PARAM); | ||
MOD_ASSERT(stack_length(s) > 0, "Empty stack.", STACK_MISSING); | ||
|
||
stack_ret_code status = STACK_OK; | ||
stack_elem *elem = s->data; | ||
while (elem && status == STACK_OK) { | ||
status = fn(userptr, elem->userptr); | ||
elem = elem->prev; | ||
} | ||
return status; | ||
} | ||
|
||
stack_ret_code stack_push(stack_t *s, void *data, bool autofree) { | ||
MOD_ASSERT(s, "NULL stack.", STACK_WRONG_PARAM); | ||
MOD_ASSERT(data, "NULL data.", STACK_WRONG_PARAM); | ||
|
||
stack_elem *elem = memhook._malloc(sizeof(stack_elem)); | ||
if (elem) { | ||
s->len++; | ||
elem->userptr = data; | ||
elem->prev = s->data; | ||
elem->autofree = autofree; | ||
s->data = elem; | ||
return STACK_OK; | ||
} | ||
return STACK_OMEM; | ||
} | ||
|
||
void *stack_pop(stack_t *s) { | ||
MOD_ASSERT(s, "NULL stack.", NULL); | ||
MOD_ASSERT(stack_length(s) > 0, "Empty stack.", NULL); | ||
|
||
stack_elem *elem = s->data; | ||
s->data = s->data->prev; | ||
void *data = elem->userptr; | ||
memhook._free(elem); | ||
s->len--; | ||
return data; | ||
} | ||
|
||
void *stack_peek(const stack_t *s) { | ||
MOD_ASSERT(s, "NULL stack.", NULL); | ||
MOD_ASSERT(stack_length(s) > 0, "Empty stack.", NULL); | ||
|
||
return s->data->userptr; // return most recent element data | ||
} | ||
|
||
stack_ret_code stack_free(stack_t *s) { | ||
MOD_ASSERT(s, "NULL stack.", STACK_WRONG_PARAM); | ||
|
||
stack_elem *elem = NULL; | ||
while ((elem = s->data) && s->len > 0) { | ||
const bool autofree = elem->autofree; | ||
void *data = stack_pop(s); | ||
if (autofree) { | ||
memhook._free(data); | ||
} | ||
} | ||
free(s); | ||
return STACK_OK; | ||
} | ||
|
||
int stack_length(const stack_t *s) { | ||
MOD_ASSERT(s, "NULL stack.", STACK_WRONG_PARAM); | ||
|
||
return s->len; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
.. |br| raw:: html | ||
|
||
<br /> | ||
|
||
Libmodule Stack API | ||
=================== | ||
|
||
Libmodule offers an easy to use stack implementation, provided by <module/stack.h> header. |br| | ||
It is used internally to store module's stack for become/unbecome methods. |br| | ||
|
||
Stack structures | ||
---------------- | ||
|
||
.. code:: | ||
typedef enum { | ||
STACK_WRONG_PARAM = -4, | ||
STACK_MISSING, | ||
STACK_ERR, | ||
STACK_OMEM, | ||
STACK_OK | ||
} stack_ret_code; | ||
/* Callback for stack_iterate */ | ||
typedef stack_ret_code (*stack_cb)(void *, void *); | ||
/* Incomplete struct declaration for stack */ | ||
typedef struct _stack stack_t; | ||
Stack API | ||
--------- | ||
|
||
Where not specified, these functions return a stack_ret_code. | ||
|
||
.. c:function:: stack_new() | ||
Create a new stack_t object. | ||
|
||
:returns: pointer to newly allocated stack_t. | ||
|
||
.. c:function:: stack_iterate(s, fn, userptr) | ||
Iterate a stack calling cb on each element until STACK_OK is returned (or end of stack is reached). Returns STACK_MISSING if stack is NULL. | ||
|
||
:param s: pointer to stack_t | ||
:param fn: callback to be called | ||
:param userptr: userdata to be passed to callback as first parameter | ||
:type s: :c:type:`stack_t *` | ||
:type fn: :c:type:`const stack_cb` | ||
:type userptr: :c:type:`void *` | ||
|
||
.. c:function:: stack_push(s, val, autofree) | ||
Push a value on top of stack. Note that if autofree is true, data willbe automatically freed when calling stack_free() on the stack. | ||
|
||
:param s: pointer to stack_t | ||
:param val: value to be put inside stack | ||
:param autofree: whether to autofree val on stack_free | ||
:type s: :c:type:`stack_t *` | ||
:type val: :c:type:`void *` | ||
:type autofree: :c:type:`const bool` | ||
|
||
.. c:function:: stack_pop(s) | ||
Pop a value from top of stack, removing it from stack. | ||
|
||
:param s: pointer to stack_t | ||
:type s: :c:type:`stack_t *` | ||
:returns: void pointer to value, on NULL on error. | ||
|
||
.. c:function:: stack_peek(s) | ||
Return top-of-stack element, without removing it. | ||
|
||
:param s: pointer to stack_t | ||
:type s: :c:type:`stack_t *` | ||
:returns: void pointer to value, on NULL on error. | ||
|
||
.. c:function:: stack_free(s) | ||
Free a stack object. | ||
|
||
:param s: pointer to stack_t | ||
:type s: :c:type:`stack_t *` | ||
|
||
.. c:function:: stack_length(s) | ||
Get stack length. | ||
|
||
:param s: pointer to stack_t | ||
:type s: :c:type:`stack_t *` | ||
:returns: stack length or a stack_ret_code if any error happens (stack_t is null). | ||
|
Oops, something went wrong.