home *** CD-ROM | disk | FTP | other *** search
- /* Generic package to manipulate dynamic arrays represented like
- argc/argv (but not necessarily containing character pointers).
- Operations provided are macros that expand to groups of statements;
- their arguments should be side-effect-free. The arguments argc and
- argv should be single identifiers, since they are assigned to.
- (L_DECLARE expands to a series of declarations.)
-
- This code was written because I found myself writing code very
- similar to it times and times over, or, worse, using fixed-length
- arrays out of laziness. It's slow for large arrays (although this
- could be improved easily by rounding up the sizes passed to
- malloc/realloc), but this shouldn't be a problem for the applications
- I am currently using it for. It sure helped me write some array
- processing code faster.
-
- Operations:
-
- L_DECLARE(argc, argv, type) declare a list with element type 'type'
- L_INIT(argc, argv) initialize a list
- L_DEALLOC(argc, argv) deallocate a list
- L_SETSIZE(argc, argv, type, size) set list to size 'size'
- L_EXTEND(argc, argv, type, count) append 'count' unitinialized elements
- L_APPEND(argc, argv, type, elem) append a given element
- L_REMOVE(argc, argv, type, index) remove element number 'index'
- L_INSERT(argc, argv, type, index, elem) insert 'elem' at 'index'
- L_SORT(argc, argv, type, compare) sort the list ('compare' is a function)
-
- (There should also be operations to insert in the middle and to
- remove elements.)
-
- NB: the 'type' argument could be discarded (except for L_DECLARE)
- if we could live with warnings about assignments from malloc/realloc
- to other pointer types.
-
- */
-
- #ifdef __STDC__
- #ifndef _SIZE_T
- #include <stddef.h>
- #include <stdlib.h>
- #include <memory.h>
- #include <string.h>
- # ifdef atarist
- # include <unixlib.h>
- # endif
- #endif
-
- #define _UNIVPTR void * /* Universal pointer; 'void *' for ANSI C */
-
- extern _UNIVPTR malloc(size_t);
- extern _UNIVPTR realloc(void *, size_t);
-
- #ifdef GOOD_REALLOC
- #define _REALLOC(p, size) realloc((void *)(p), (size_t)(size))
- #else
- #define _REALLOC(p, size) ((p) ? realloc((void *)(p), (size_t)(size)) \
- : malloc((size_t)(size)))
- #endif
-
- #define L_DECLARE(argc, argv, type) int argc= 0; type *argv= 0
-
- #define L_INIT(argc, argv) argc= 0; argv= 0
-
- #define L_DEALLOC(argc, argv) argc= 0; \
- if (argv != 0) { \
- free((void *)argv); \
- argv= 0; \
- }
-
- #define L_SETSIZE(argc, argv, type, size) \
- argv= (type *) _REALLOC((_UNIVPTR) argv, \
- (size_t) (size) * sizeof(type)); \
- argc= (argv == 0) ? 0 : size
-
- #define L_EXTEND(argc, argv, type, count) \
- L_SETSIZE(argc, argv, type, argc+count)
-
- #define L_APPEND(argc, argv, type, elem) \
- argv= (type *) _REALLOC((_UNIVPTR) argv, \
- (size_t) (argc+1) * sizeof(type)); \
- if (argv == 0) \
- argc= 0; \
- else \
- argv[argc++]= elem
-
- #define L_REMOVE(argc, argv, type, index) \
- { \
- int k_; \
- for (k_= index+1; k_ < argc; ++k_) \
- argv[k_-1]= argv[k_]; \
- L_SETSIZE(argc, argv, type, argc-1); \
- }
-
- #define L_INSERT(argc, argv, type, index, item) \
- { \
- int k_; \
- L_SETSIZE(argc, argv, type, argc+1); \
- for (k_= argc-1; k_ > index; --k_) \
- argv[k_]= argv[k_-1]; \
- argv[index]= item; \
- }
-
- #define L_SORT(argc, argv, type, compare) \
- qsort((_UNIVPTR)argv, (size_t)(argc), (size_t)sizeof(type), compare)
- #else
-
- #define _UNIVPTR char * /* Universal pointer; 'void *' for ANSI C */
-
- extern _UNIVPTR malloc();
- extern _UNIVPTR realloc();
-
- #ifdef GOOD_REALLOC
- #define _REALLOC(p, size) realloc(p, size)
- #else
- #define _REALLOC(p, size) ((p) ? realloc(p, size) : malloc(size))
- #endif
-
- #define L_DECLARE(argc, argv, type) int argc= 0; type *argv= 0
-
- #define L_INIT(argc, argv) argc= 0; argv= 0
-
- #define L_DEALLOC(argc, argv) argc= 0; \
- if (argv != 0) { \
- free((char*)argv); \
- argv= 0; \
- }
-
- #define L_SETSIZE(argc, argv, type, size) \
- argv= (type *) _REALLOC((_UNIVPTR) argv, \
- (unsigned) (size) * sizeof(type)); \
- argc= (argv == 0) ? 0 : size
-
- #define L_EXTEND(argc, argv, type, count) \
- L_SETSIZE(argc, argv, type, argc+count)
-
- #define L_APPEND(argc, argv, type, elem) \
- argv= (type *) _REALLOC((_UNIVPTR) argv, \
- (unsigned) (argc+1) * sizeof(type)); \
- if (argv == 0) \
- argc= 0; \
- else \
- argv[argc++]= elem
-
- #define L_REMOVE(argc, argv, type, index) \
- { \
- int k_; \
- for (k_= index+1; k_ < argc; ++k_) \
- argv[k_-1]= argv[k_]; \
- L_SETSIZE(argc, argv, type, argc-1); \
- }
-
- #define L_INSERT(argc, argv, type, index, item) \
- { \
- int k_; \
- L_SETSIZE(argc, argv, type, argc+1); \
- for (k_= argc-1; k_ > index; --k_) \
- argv[k_]= argv[k_-1]; \
- argv[index]= item; \
- }
-
- #define L_SORT(argc, argv, type, compare) \
- qsort((_UNIVPTR)argv, argc, sizeof(type), compare)
-
- #endif /* __STDC__ */
-