The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
Travis CI build status GitHub version License MIT

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 a char.

GENERICSTACK_SET_SHORT

Set var expression result, explicitely typecasted into a short.

GENERICSTACK_SET_INT

Set var expression result, explicitely typecasted into an int.

GENERICSTACK_SET_LONG

Set var expression result, explicitely typecasted into a long.

GENERICSTACK_SET_LONG_DOUBLE

Set var expression result, explicitely typecasted into a long double.

GENERICSTACK_SET_FLOAT

Set var expression result, explicitely typecasted into a float.

GENERICSTACK_SET_DOUBLE

Set var expression result, explicitely typecasted into a double.

GENERICSTACK_SET_PTR

Set var expression result, explicitely typecasted into a void *.

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 a long long.

GENERICSTACK_SET__BOOL

Set var expression result, explicitely typecasted into a _Bool.

GENERICSTACK_SET_FLOAT__COMPLEX

Set var expression result, explicitely typecasted into a float _Complex.

GENERICSTACK_SET_DOUBLE__COMPLEX

Set var expression result, explicitely typecasted into a double _Complex.

GENERICSTACK_SET_LONG_DOUBLE__COMPLEX

Set var expression result, explicitely typecasted into a long double _Complex.

Custom datatype (see NOTES) is available via:

GENERICSTACK_SET_CUSTOM

Set var expression result, explicitely typecasted into a GENERICSTACK_CUSTOM.

GENERICSTACK_SET_CUSTOMP

Set *var expression result, explicitely typecasted into a GENERICSTACK_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:

GENERICSTACK_SORT(stackName, callback)

Convenient macro to qsort a generic stack.

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:

a PUSH always increases the stack size if necessary
a POP always decreases the stack size if possible
a SET always increases the stack size if necessary
a GET never changes stack size
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 and long 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 of genericStack.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.