Let's not go trespassing in reserved namespace

This commit is contained in:
Juhani Krekelä 2018-08-11 20:45:28 +03:00
parent 034ee8c3ef
commit a13a5a75b2

View file

@ -1,69 +1,69 @@
#ifndef __CMAYBE_H__
#define __CMAYBE_H__
#ifndef CMAYBE_H
#define CMAYBE_H
#define MAYBE_TYPE(name, type) struct maybe_##name {type value; char is_value;}
#define MAYBE(name) struct maybe_##name
#define ENABLE_RETURN(name) MAYBE(name) __return_value
#define ENABLE_RETURN(name) MAYBE(name) _return_value
#define RETURN_VALUE(x) {\
__return_value.is_value = 1;\
__return_value.value = x;\
return __return_value;\
_return_value.is_value = 1;\
_return_value.value = x;\
return _return_value;\
}
#define RETURN_NOTHING() {\
__return_value.is_value = 0;\
return __return_value;\
_return_value.is_value = 0;\
return _return_value;\
}
#define IS_VALUE(x) if ((x).is_value)
#define IS_NOT_VALUE(x) if (!(x).is_value)
#define VALUE(x) (x).value
struct __free_list {
struct __free_list *next;
struct _free_list {
struct _free_list *next;
void *ptr;
void (*freer)(void*);
};
#define ENABLE_TRY() \
struct __free_list *__allocations = NULL, *__free_list_node;\
void *__allocation;\
jmp_buf __try_fail_jmp_buf;\
if (setjmp(__try_fail_jmp_buf)) {\
struct _free_list *_allocations = NULL, *_free_list_node;\
void *_allocation;\
jmp_buf _try_fail_jmp_buf;\
if (setjmp(_try_fail_jmp_buf)) {\
TRY_FAIL_HANDLE();\
RETURN_NOTHING();\
}
#define TRY_TYPE(name) MAYBE(name) __try_tmp_##name
#define TRY_TYPE(name) MAYBE(name) _try_tmp_##name
#define TRY(name, maybe_value) (\
__try_tmp_##name = maybe_value,\
(__try_tmp_##name.is_value ? 0 :\
longjmp(__try_fail_jmp_buf, 1)\
_try_tmp_##name = maybe_value,\
(_try_tmp_##name.is_value ? 0 :\
longjmp(_try_fail_jmp_buf, 1)\
),\
__try_tmp_##name.value\
_try_tmp_##name.value\
)
#define TRY_HOF_HANDLE(freer_func, pointer) (\
__allocation = pointer,\
__free_list_node = malloc(sizeof(struct __free_list)),\
(__free_list_node == NULL ? (\
free(__allocation),\
longjmp(__try_fail_jmp_buf, 1)\
_allocation = pointer,\
_free_list_node = malloc(sizeof(struct _free_list)),\
(_free_list_node == NULL ? (\
free(_allocation),\
longjmp(_try_fail_jmp_buf, 1)\
) : (\
__free_list_node->next = __allocations,\
__free_list_node->ptr = __allocation,\
__free_list_node->freer = freer_func,\
__allocations = __free_list_node\
_free_list_node->next = _allocations,\
_free_list_node->ptr = _allocation,\
_free_list_node->freer = freer_func,\
_allocations = _free_list_node\
)),\
__allocation\
_allocation\
)
#define FREE_ON_TRY_FAIL(pointer) TRY_HOF_HANDLE(free, pointer)
// free() is passed as an argument to avoid errors in case the program uses
// no TRY functionality and doesn't include stdlib.h
static void __remove_free_list(struct __free_list **head, void *ptr, void (*free)(void*)) {
struct __free_list **current = head;
static void _remove_free_list(struct _free_list **head, void *ptr, void (*free)(void*)) {
struct _free_list **current = head;
while (*current != NULL) {
if (current[0]->ptr == ptr) {
struct __free_list *deleted = *current;
struct _free_list *deleted = *current;
*current = deleted->next;
free(deleted);
break;
@ -72,18 +72,18 @@ static void __remove_free_list(struct __free_list **head, void *ptr, void (*free
}
}
#define TRY_HOF_REMOVE(allocation) __remove_free_list(&__allocations, allocation, free)
#define TRY_HOF_REMOVE(allocation) _remove_free_list(&_allocations, allocation, free)
#define TRY_FAIL_HANDLE() \
while (__allocations != NULL) {\
struct __free_list *current = __allocations;\
while (_allocations != NULL) {\
struct _free_list *current = _allocations;\
void (*freer)(void*) = current->freer;\
freer(current->ptr);\
__allocations = current->next;\
_allocations = current->next;\
free(current);\
}
static void __replace_free_list(struct __free_list **head, void *from, void *to) {
struct __free_list **current = head;
static void _replace_free_list(struct _free_list **head, void *from, void *to) {
struct _free_list **current = head;
while (*current != NULL) {
if (current[0]->ptr == from) {
current[0]->ptr = to;
@ -92,6 +92,6 @@ static void __replace_free_list(struct __free_list **head, void *from, void *to)
current = &current[0]->next;
}
}
#define TRY_HOF_REPLACE(old_ptr, new_ptr) __replace_free_list(&__allocations, old_ptr, new_ptr)
#define TRY_HOF_REPLACE(old_ptr, new_ptr) _replace_free_list(&_allocations, old_ptr, new_ptr)
#endif