NAME
genericStack - generic stack interface
DESCRIPTION
genericStack is a set of macros to manage a stack. It is is generic in the sense that it is not restricted to one type of variable. It is recommended to always use valid C identifiers in these macros.
SYNOPSIS
#include <genericStack.h>
genericStack_t myStack, *myStackp;
/* The generic stack can be on the stack */
myStackp = &myStack;
GENERICSTACK_INIT(myStackp);
/* ... */
GENERICSTACK_RESET(myStackp);
/* ... or on the heap */
GENERICSTACK_NEW(myStackp);
/* ... */
GENERICSTACK_FREE(myStackp);
MACROS
GENERICSTACK_INIT(stackName)
Initialize a stack pointer that is on the stack. Memory will be released with GENERICSTACK_RESET(stackName).
GENERICSTACK_INIT_SIZED(stackName, wantedSize)
Create an empty stack referenced with the name stackName
itself on the stack, though pre-allocating room for wantedSize
elements>. The stack will also automatically grow if user if putting an element beyond wantedSize
.
GENERICSTACK_NEW(stackName)
Create an empty stack referenced with the name stackName
. The stack will automatically grow if needed.
GENERICSTACK_NEW_SIZED(stackName, wantedSize)
Create an empty stack referenced with the name stackName
, though pre-allocating room for wantedSize
elements>. The stack will also automatically grow if user if putting an element beyond wantedSize
.
GENERICSTACK_SET_XXX(stackName, var, index)
Set an entry in stack stackName
, at index index
(numbering start 0), using the result of the expression var
. XXX is meant to be a C datatype or an array (the later being nothing else but a PTR associated to a length), i.e. the exact list of macros is:
- GENERICSTACK_SET_CHAR
-
Set
var
expression result, explicitely typecasted into achar
. - GENERICSTACK_SET_SHORT
-
Set
var
expression result, explicitely typecasted into ashort
. - GENERICSTACK_SET_INT
-
Set
var
expression result, explicitely typecasted into anint
. - GENERICSTACK_SET_LONG
-
Set
var
expression result, explicitely typecasted into along
. - GENERICSTACK_SET_LONG_DOUBLE
-
Set
var
expression result, explicitely typecasted into along double
. - GENERICSTACK_SET_FLOAT
-
Set
var
expression result, explicitely typecasted into afloat
. - GENERICSTACK_SET_DOUBLE
-
Set
var
expression result, explicitely typecasted into adouble
. - GENERICSTACK_SET_PTR
-
Set
var
expression result, explicitely typecasted into avoid *
. - GENERICSTACK_SET_ARRAY
-
Set
var
, that is an internal structure containing both a pointer and a length to fully describe an array. - GENERICSTACK_SET_ARRAYP
-
Set
*var
, that is an internal structure containing both a pointer and a length to fully describe an array.
C99 datatypes (see NOTES) may be available via:
- GENERICSTACK_SET_LONG_LONG
-
Set
var
expression result, explicitely typecasted into along long
. - GENERICSTACK_SET__BOOL
-
Set
var
expression result, explicitely typecasted into a_Bool
. - GENERICSTACK_SET_FLOAT__COMPLEX
-
Set
var
expression result, explicitely typecasted into afloat _Complex
. - GENERICSTACK_SET_DOUBLE__COMPLEX
-
Set
var
expression result, explicitely typecasted into adouble _Complex
. - GENERICSTACK_SET_LONG_DOUBLE__COMPLEX
-
Set
var
expression result, explicitely typecasted into along double _Complex
.
Custom datatype (see NOTES) is available via:
- GENERICSTACK_SET_CUSTOM
-
Set
var
expression result, explicitely typecasted into aGENERICSTACK_CUSTOM
. - GENERICSTACK_SET_CUSTOMP
-
Set
*var
expression result, explicitely typecasted into aGENERICSTACK_CUSTOM
.
GENERICSTACK_SET_NA(stackName, index)
Specific macro that removes any association at position index
.
GENERICSTACK_GET_XXX(stackName, index)
Get an entry in stack stackName
, at index index
(numbering start 0). The data type of the entry is left as-is, letting the compiler do type promotion, and eventually warn. XXX is meant to be a C datatype, an array, or an array pointer, i.e. the exact list of macros is:
- GENERICSTACK_GET_CHAR
- GENERICSTACK_GET_SHORT
- GENERICSTACK_GET_INT
- GENERICSTACK_GET_LONG
- GENERICSTACK_GET_LONG_DOUBLE
- GENERICSTACK_GET_FLOAT
- GENERICSTACK_GET_DOUBLE
- GENERICSTACK_GET_PTR
- GENERICSTACK_GET_ARRAY
- GENERICSTACK_GET_ARRAYP
-
Returns a pointer to the array element.
C99 datatypes (see NOTES) may be available via:
- GENERICSTACK_GET_LONG_LONG
- GENERICSTACK_GET__BOOL
- GENERICSTACK_GET_FLOAT__COMPLEX
- GENERICSTACK_GET_DOUBLE__COMPLEX
- GENERICSTACK_GET_LONG_DOUBLE__COMPLEX
Custom datatype (see NOTES) may be available via:
- GENERICSTACK_GET_CUSTOM
- GENERICSTACK_GET_CUSTOMP
GENERICSTACK_PUSH_XXX(stackName, var)
This is an interface on top of <GENERICSTACK_SET_XXX>, that it automatically pushing data on the stack, the later will increase if needed.
GENERICSTACK_POP_XXX(stackName)
This is an interface on top of <GENERICSTACK_GET_XXX>, that it automatically popping data from the stack (i.e. retreive the last argument, and (artificially) reduce the generic stack size.
GENERICSTACK_IS_XXX(stackName, index)
Check if item at indice index
is of type <XXX>, and returns a true or false value.
GENERICSTACK_FREE(stackName)
Releases a stack that is on the heap.
GENERICSTACK_RESET(stackName)
Releases a stack that is on the stack. It can be reused.
GENERICSTACK_RELAX(stackName)
Fast dispose of a stack for immediate reuse. This does not prevent the user to call GENERICSTACK_RESET()
or GENERICSTACK_FREE()
, though.
GENERICSTACK_ERROR(stackName)
Return a true value if there is an error. Should be called after every call to:
GENERICSTACK_INITIAL_LENGTH(stackName)
Return the number of available items always available.
GENERICSTACK_HEAP_LENGTH(stackName)
Return the number of available items allocated on the heap.
GENERICSTACK_LENGTH(stackName)
Return the total number of available items.
GENERICSTACK_USED(stackName)
Return the total used items. This can be used as l-value, the effect is to pretend that the stack is empty without releasing internal memory, the later will be reused if necessary. If you believe that the internal size of the stack (in particular the memory allocated on the heap) fit the whole lifetime of the stack, this is by far more effcient than doing sequences of FREE (or RESET) followed by NEW (or INIT, respectively).
GENERICSTACK_DUMP(stackName)
Handy macro that dump the stack on stderr.
GENERICSTACK_ERROR_RESET(stackName)
Reset error to a false value.
GENERICSTACK_SWITCH(stackName, i1, i2)
Switches items at positions i1
and i2
.
GENERICSTACKITEMTYPE(stackName, index)
Returns the type of the item at position index
within stack stackName
.
GENERICSTACKITEMTYPE_XXX
Convenient enum associating a value to the item type XXX
, for example:
- GENERICSTACKITEMTYPE_NA
-
is the value
0
- GENERICSTACKITEMTYPE_CHAR
-
is the value
1
and so on.
GENERICSTACKITEMTYPE2TYPE_XXX
Generates a basic C type from the item type XXX
, for example:
- GENERICSTACKITEMTYPE2TYPE_CHAR
-
generates
char
- GENERICSTACKITEMTYPE2TYPE_SHORT
-
generates
short
and so on.
ARRAY
An array is a special case of PTR, associated to a length. Internally, it is represented with the typedef genericStackItemTypeArray_t
:
typedef struct genericStackItemTypeArray {
void *p;
size_t lengthl;
} genericStackItemTypeArray_t;
nevertheless, the convenient macros should be used:
- GENERICSTACKITEMTYPE2TYPE_ARRAY
-
The array type.
- GENERICSTACK_ARRAY_PTR(a)
-
Pointer associated to the array. Can be an l-value.
- GENERICSTACK_ARRAYP_PTR(a)
-
Idem, except that
a
is now a pointer to the array structure. - GENERICSTACK_ARRAY_LENGTH(a)
-
Length associated to the array. Can be an l-value.
- GENERICSTACK_ARRAYP_LENGTH(a)
-
Idem, except that
a
is now a pointer to the array structure.
NOTES
- ARRAY and ARRAYP interfaces
-
Whenever ARRAYP interface exist, it means its argument is a pointer to the array internal structure. That is, for example:
*GENERICSTACK_GET_ARRAYP(stackName, indice)
and
GENERICSTACK_GET_ARRAY(stackName, indice)
will return the same information.
There is no GENERICSTACK_POP_ARRAYP, because when popped, the structure describing an array leave only in user-space, no more within the generic stack.
- C99 datatypes
-
C99 data types are all available if the
GENERICSTACK_C99
macro is defined. Otherwise, partial support of C99 from the compiler support is handled like this: - Usage
-
This genericStack should fit ok for small up to medium size stacks, not huge stacks because of its internal usage of an array instead of a linked list. The later implementation is not that hard, but left as an exercise to the reader.
- Memory management
-
The default is:
- Constants driving the stack
-
- GENERICSTACK_DEFAULT_LENGTH
-
Minimum number of items that are always available. If necessary the stack will use the heap for increase. Default value is 128.
- GENERICSTACK_ZERO_INT_IS_NOT_ZERO_BYTES
-
You should set this only if your system is not using only zero bytes to describe the integer nummber 0. Not defined by default.
- GENERICSTACK_HAVE_LONG_LONG
-
If this #define is a true value, then
long long
is supported. - GENERICSTACK_HAVE__BOOL
-
If this #define is a true value, then
_Bool
is supported. - GENERICSTACK_HAVE__COMPLEX
-
If this #define is a true value, then
float _Complex
,double _Complex
andlong double _Complex
are supported. - GENERICSTACK_HAVE_CUSTOM
-
If this #define is a true value, then
GENERICSTACK_CUSTOM
custom type, that has to be defined prior to the include ofgenericStack.h
, is supported, - GENERICSTACK_CUSTOM
-
If this #define is a true value, this must be a valid datatype, then
GENERICSTACK_HAVE_CUSTOM
is automatically set to a true value. Example:typedef struct myStruct { short isstring; union { int i; char *s; } u; } myStruct_t; #define GENERICSTACK_CUSTOM myStruct_t #include <genericStack.h>
The
GENERICSTACK_GET_CUSTOMP
macro is in particulary very convenient if you want to work with the data directly in the stack.
- Sequence points
-
This generic stack implementation supports indices that are expressions. The side-effect is that it is recommended to not use more than one generic stack macro on the same stack in statements where the order of execution is undefined. Basically, this mean: use one generic stack macro at a time for a given stack.