home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / gnustuff / tos / progut~1 / stdwin.zoo / h / l_defs.h < prev    next >
Encoding:
C/C++ Source or Header  |  1990-03-29  |  4.7 KB  |  165 lines

  1. /* Generic package to manipulate dynamic arrays represented like
  2.    argc/argv (but not necessarily containing character pointers).
  3.    Operations provided are macros that expand to groups of statements;
  4.    their arguments should be side-effect-free.  The arguments argc and
  5.    argv should be single identifiers, since they are assigned to.
  6.    (L_DECLARE expands to a series of declarations.)
  7.    
  8.    This code was written because I found myself writing code very
  9.    similar to it times and times over, or, worse, using fixed-length
  10.    arrays out of laziness.  It's slow for large arrays (although this
  11.    could be improved easily by rounding up the sizes passed to
  12.    malloc/realloc), but this shouldn't be a problem for the applications
  13.    I am currently using it for.  It sure helped me write some array
  14.    processing code faster.
  15.    
  16.    Operations:
  17.    
  18.    L_DECLARE(argc, argv, type)        declare a list with element type 'type'
  19.    L_INIT(argc, argv)            initialize a list
  20.    L_DEALLOC(argc, argv)        deallocate a list
  21.    L_SETSIZE(argc, argv, type, size)    set list to size 'size'
  22.    L_EXTEND(argc, argv, type, count)    append 'count' unitinialized elements
  23.    L_APPEND(argc, argv, type, elem)    append a given element
  24.    L_REMOVE(argc, argv, type, index)    remove element number 'index'
  25.    L_INSERT(argc, argv, type, index, elem)    insert 'elem' at 'index'
  26.    L_SORT(argc, argv, type, compare)    sort the list ('compare' is a function)
  27.    
  28.    (There should also be operations to insert in the middle and to
  29.    remove elements.)
  30.    
  31.    NB: the 'type' argument could be discarded (except for L_DECLARE)
  32.    if we could live with warnings about assignments from malloc/realloc
  33.    to other pointer types.
  34.    
  35. */
  36.  
  37. #ifdef __STDC__
  38. #ifndef _SIZE_T
  39. #include <stddef.h>
  40. #include <stdlib.h>
  41. #include <memory.h>
  42. #include <string.h>
  43. #  ifdef atarist
  44. #    include <unixlib.h>
  45. #  endif
  46. #endif
  47.  
  48. #define _UNIVPTR void *        /* Universal pointer; 'void *' for ANSI C */
  49.  
  50. extern _UNIVPTR malloc(size_t);
  51. extern _UNIVPTR realloc(void *, size_t);
  52.  
  53. #ifdef GOOD_REALLOC
  54. #define _REALLOC(p, size) realloc((void *)(p), (size_t)(size))
  55. #else
  56. #define _REALLOC(p, size) ((p) ? realloc((void *)(p), (size_t)(size)) \
  57.                 : malloc((size_t)(size)))
  58. #endif
  59.  
  60. #define L_DECLARE(argc, argv, type)    int argc= 0; type *argv= 0
  61.  
  62. #define L_INIT(argc, argv)        argc= 0; argv= 0
  63.  
  64. #define L_DEALLOC(argc, argv)        argc= 0; \
  65.                     if (argv != 0) { \
  66.                         free((void *)argv); \
  67.                         argv= 0; \
  68.                     }
  69.  
  70. #define L_SETSIZE(argc, argv, type, size) \
  71.     argv= (type *) _REALLOC((_UNIVPTR) argv, \
  72.         (size_t) (size) * sizeof(type)); \
  73.     argc= (argv == 0) ? 0 : size
  74.  
  75. #define L_EXTEND(argc, argv, type, count) \
  76.     L_SETSIZE(argc, argv, type, argc+count)
  77.  
  78. #define L_APPEND(argc, argv, type, elem) \
  79.     argv= (type *) _REALLOC((_UNIVPTR) argv, \
  80.         (size_t) (argc+1) * sizeof(type)); \
  81.     if (argv == 0) \
  82.         argc= 0; \
  83.     else \
  84.         argv[argc++]= elem
  85.  
  86. #define L_REMOVE(argc, argv, type, index) \
  87.     { \
  88.         int k_; \
  89.         for (k_= index+1; k_ < argc; ++k_) \
  90.             argv[k_-1]= argv[k_]; \
  91.         L_SETSIZE(argc, argv, type, argc-1); \
  92.     }
  93.  
  94. #define L_INSERT(argc, argv, type, index, item) \
  95.     { \
  96.         int k_; \
  97.         L_SETSIZE(argc, argv, type, argc+1); \
  98.         for (k_= argc-1; k_ > index; --k_) \
  99.             argv[k_]= argv[k_-1]; \
  100.         argv[index]= item; \
  101.     }
  102.  
  103. #define L_SORT(argc, argv, type, compare) \
  104.     qsort((_UNIVPTR)argv, (size_t)(argc), (size_t)sizeof(type), compare)
  105. #else
  106.  
  107. #define _UNIVPTR char *        /* Universal pointer; 'void *' for ANSI C */
  108.  
  109. extern _UNIVPTR malloc();
  110. extern _UNIVPTR realloc();
  111.  
  112. #ifdef GOOD_REALLOC
  113. #define _REALLOC(p, size) realloc(p, size)
  114. #else
  115. #define _REALLOC(p, size) ((p) ? realloc(p, size) : malloc(size))
  116. #endif
  117.  
  118. #define L_DECLARE(argc, argv, type)    int argc= 0; type *argv= 0
  119.  
  120. #define L_INIT(argc, argv)        argc= 0; argv= 0
  121.  
  122. #define L_DEALLOC(argc, argv)        argc= 0; \
  123.                     if (argv != 0) { \
  124.                         free((char*)argv); \
  125.                         argv= 0; \
  126.                     }
  127.  
  128. #define L_SETSIZE(argc, argv, type, size) \
  129.     argv= (type *) _REALLOC((_UNIVPTR) argv, \
  130.         (unsigned) (size) * sizeof(type)); \
  131.     argc= (argv == 0) ? 0 : size
  132.  
  133. #define L_EXTEND(argc, argv, type, count) \
  134.     L_SETSIZE(argc, argv, type, argc+count)
  135.  
  136. #define L_APPEND(argc, argv, type, elem) \
  137.     argv= (type *) _REALLOC((_UNIVPTR) argv, \
  138.         (unsigned) (argc+1) * sizeof(type)); \
  139.     if (argv == 0) \
  140.         argc= 0; \
  141.     else \
  142.         argv[argc++]= elem
  143.  
  144. #define L_REMOVE(argc, argv, type, index) \
  145.     { \
  146.         int k_; \
  147.         for (k_= index+1; k_ < argc; ++k_) \
  148.             argv[k_-1]= argv[k_]; \
  149.         L_SETSIZE(argc, argv, type, argc-1); \
  150.     }
  151.  
  152. #define L_INSERT(argc, argv, type, index, item) \
  153.     { \
  154.         int k_; \
  155.         L_SETSIZE(argc, argv, type, argc+1); \
  156.         for (k_= argc-1; k_ > index; --k_) \
  157.             argv[k_]= argv[k_-1]; \
  158.         argv[index]= item; \
  159.     }
  160.  
  161. #define L_SORT(argc, argv, type, compare) \
  162.     qsort((_UNIVPTR)argv, argc, sizeof(type), compare)
  163.  
  164. #endif /* __STDC__ */
  165.