diff options
author | Campbell Barton <ideasman42@gmail.com> | 2014-06-28 23:06:22 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2014-06-28 23:57:48 +0400 |
commit | f32079d4b9f0ee565dc4bb63a4ef25286f183d0e (patch) | |
tree | 10d24971269b58ebb42a35e3006bde9f5e21db5b /source/blender/blenlib/BLI_stackdefines.h | |
parent | 00c8a691e921e5e838b96e92290bd9901e1bf3c4 (diff) |
BLI_stackdefines
Bounds check the stack while debugging, also add STACK_PEEK
Diffstat (limited to 'source/blender/blenlib/BLI_stackdefines.h')
-rw-r--r-- | source/blender/blenlib/BLI_stackdefines.h | 39 |
1 files changed, 31 insertions, 8 deletions
diff --git a/source/blender/blenlib/BLI_stackdefines.h b/source/blender/blenlib/BLI_stackdefines.h index 3a4957599d6..24cb043cd43 100644 --- a/source/blender/blenlib/BLI_stackdefines.h +++ b/source/blender/blenlib/BLI_stackdefines.h @@ -23,20 +23,41 @@ /** \file BLI_stackdefines.h * \ingroup bli + * + * Macro's for a simple array based stack + * \note Caller handles alloc & free). */ -/* simple stack */ -#define STACK_DECLARE(stack) unsigned int _##stack##_index -#define STACK_INIT(stack) ((void)stack, (void)((_##stack##_index) = 0)) -#define STACK_SIZE(stack) ((void)stack, (_##stack##_index)) -#define STACK_PUSH(stack, val) (void)((stack)[(_##stack##_index)++] = val) -#define STACK_PUSH_RET(stack) ((void)stack, ((stack)[(_##stack##_index)++])) -#define STACK_PUSH_RET_PTR(stack) ((void)stack, &((stack)[(_##stack##_index)++])) +/* only validate array-bounds in debug mode */ +#ifdef DEBUG +# define STACK_DECLARE(stack) unsigned int _##stack##_index, _##stack##_totalloc +# define STACK_INIT(stack, tot) ((void)stack, (void)((_##stack##_index) = 0), (void)((_##stack##_totalloc) = tot)) +# define _STACK_SIZETEST(stack, off) (BLI_assert((_##stack##_index) + off <= _##stack##_totalloc)) +# define _STACK_SWAP_TOTALLOC(stack_a, stack_b) SWAP(unsigned int, _##stack_a##_totalloc, _##stack_b##_totalloc) +#else +# define STACK_DECLARE(stack) unsigned int _##stack##_index +# define STACK_INIT(stack, tot) ((void)stack, (void)((_##stack##_index) = 0), (void)(tot)) +# define _STACK_SIZETEST(stack, off) (void)(stack), (void)(off) +# define _STACK_SWAP_TOTALLOC(stack_a, stack_b) (void)(stack_a), (void)(stack_b) +#endif +#define _STACK_BOUNDSTEST(stack, index) ((void)stack, BLI_assert(index >= 0 && index < _##stack##_index)) + + +#define STACK_SIZE(stack) ((void)stack, (_##stack##_index)) +/** add item to stack */ +#define STACK_PUSH(stack, val) ((void)stack, _STACK_SIZETEST(stack, 1), ((stack)[(_##stack##_index)++] = val)) +#define STACK_PUSH_RET(stack) ((void)stack, _STACK_SIZETEST(stack, 1), ((stack)[(_##stack##_index)++])) +#define STACK_PUSH_RET_PTR(stack) ((void)stack, _STACK_SIZETEST(stack, 1), &((stack)[(_##stack##_index)++])) +/** take last item from stack */ #define STACK_POP(stack) ((_##stack##_index) ? ((stack)[--(_##stack##_index)]) : NULL) #define STACK_POP_PTR(stack) ((_##stack##_index) ? &((stack)[--(_##stack##_index)]) : NULL) #define STACK_POP_DEFAULT(stack, r) ((_##stack##_index) ? ((stack)[--(_##stack##_index)]) : r) -/* take care, re-orders */ +/** look at last item (assumes non-empty stack) */ +#define STACK_PEEK(stack) (BLI_assert(_##stack##_index), ((stack)[_##stack##_index - 1])) +#define STACK_PEEK_PTR(stack) (BLI_assert(_##stack##_index), &((stack)[_##stack##_index - 1])) +/** remove any item from the stack, take care, re-orders */ #define STACK_REMOVE(stack, i) \ + _STACK_BOUNDSTEST(stack, i); \ if (--_##stack##_index != i) { \ stack[i] = stack[_##stack##_index]; \ } (void)0 @@ -44,11 +65,13 @@ #define STACK_SWAP(stack_a, stack_b) { \ SWAP(typeof(stack_a), stack_a, stack_b); \ SWAP(unsigned int, _##stack_a##_index, _##stack_b##_index); \ + _STACK_SWAP_TOTALLOC(stack_a, stack_b); \ } (void)0 #else #define STACK_SWAP(stack_a, stack_b) { \ SWAP(void *, stack_a, stack_b); \ SWAP(unsigned int, _##stack_a##_index, _##stack_b##_index); \ + _STACK_SWAP_TOTALLOC(stack_a, stack_b); \ } (void)0 #endif |