/* ar.h - decls for variable size arrays * **************************************************************** * Copyright (C) 1998, 2000 Thomas Lord * * See the file "COPYING" for further information about * the copyright and warranty status of this work. */ #ifndef INCLUDE__ARRAYS__AR_H #define INCLUDE__ARRAYS__AR_H #include "hackerlab/machine/types.h" #include "hackerlab/mem/talloc.h" typedef union { void * void_ptr; /* for passing to ar_* functions */ t_uchar * uchar_ptr; /* array of char */ t_uchar ** uchar_ptr_ptr; /* array of char * */ void ** void_ptr_ptr; /* array of void * */ int * int_ptr; /* array of int */ off_t *off_t_ptr; /* array of off_t */ } t_converter; /* automatically generated __STDC__ prototypes */ extern int ar_size (void * base); #define ar_ref(base, n, szof) _ar_ref (base, n, szof, "ar_ref: "__location__) extern void * _ar_ref (void ** base, int n, int szof, char const * name); #define ar_setsize(base, n, szof) _ar_setsize (base, n, szof, "ar_setsize: "__location__) extern int _ar_setsize (void ** base, int n, size_t szof, char const * name); extern void ar_compact (void ** base, size_t szof); extern void ar_free (void ** base); extern void * ar_pop (void ** base, size_t szof); extern void * ar_copy (void * base, size_t szof); extern void * ar_insert (void **base, int index, int szof); extern void * ar_base (void *base); /* macros for too-trivial-routines */ /************************************************************************ *(h2 "Variable Sized Arrays as Stacks") */ /*(c ar_push) * void * ar_push (void ** base, size_t szof); * * Return the address of element `n' in an array previously containing * only `n-1' elements. * * `base' is a pointer to a pointer to the array. * * `szof' is the size, in bytes, of one element. * * The new array element is filled with 0 bytes. * * This function may resize and relocate the array. If it does, * `*base' is updated to point to the new location of the array. */ #define ar_push(base, szof) ar_ref (base, ar_size (*base), szof) /* macros for typesafe inline methods */ /* TODO factor out into and the majority becomes AR_TYPEDEF_.. #define AR_TYPEDEF(type, name) AR_TYPEDEF_(type, ar_ ## name) however the fn calls dont support that at the moment */ #define AR_TYPEDEF(type, ar_type_name) \ typedef type * ar_##ar_type_name; \ static inline ar_##ar_type_name \ ar_ref_##ar_type_name (ar_##ar_type_name *array, int index) \ { \ return (ar_##ar_type_name)_ar_ref ((void **)array, \ index, \ sizeof (type), \ "ar_ref_"#ar_type_name": "__location__); \ } \ \ static inline int \ ar_size_##ar_type_name (ar_##ar_type_name array) \ { \ return ar_size (array); \ } \ \ static inline void \ ar_free_##ar_type_name (ar_##ar_type_name *array) \ { \ ar_free ((void **)(array)); \ *array = NULL; \ } \ \ static inline ar_##ar_type_name \ ar_push_##ar_type_name (ar_##ar_type_name *array, type value) \ { \ ar_##ar_type_name result = \ (ar_##ar_type_name)ar_push ((void **)array, \ sizeof (type)); \ *result = value; \ talloc_set_name_const (ar_base (*array), "ar_push: " __location__); \ return result; \ } \ static inline ar_##ar_type_name \ ar_push_ext_##ar_type_name (ar_##ar_type_name *array, type value, char const * name) \ { \ ar_##ar_type_name result = \ (ar_##ar_type_name)ar_push ((void **)array, \ sizeof (type)); \ *result = value; \ talloc_set_name_const (ar_base (*array), name); \ return result; \ } \ static inline type \ ar_pop_##ar_type_name (ar_##ar_type_name *array) \ { \ return *(ar_##ar_type_name)ar_pop ((void **)array, \ sizeof (type)); \ } \ \ static inline void \ ar_insert_##ar_type_name (ar_##ar_type_name *array, int index, type value) \ { \ * (ar_##ar_type_name) ar_insert ((void **)array, \ index, \ sizeof (type)) = value; \ } \ static inline void \ ar_remove_##ar_type_name (ar_##ar_type_name *array, int toDelete) \ { \ int position = toDelete; \ if (toDelete < 0 || toDelete + 1 > ar_size_##ar_type_name (*array)) \ return; \ for (position = toDelete; position + 1 < ar_size_##ar_type_name (*array); ++position) \ { \ *ar_ref_##ar_type_name (array, position) = *ar_ref_##ar_type_name (array, position + 1); \ } \ ar_pop_##ar_type_name (array); \ } \ static inline int \ ar_setsize_##ar_type_name (ar_##ar_type_name *array, int count) \ { \ return _ar_setsize ((void **)array, \ count, \ sizeof (type), \ "ar_setsize_"#ar_type_name": "__location__); \ } \ static inline int \ ar_setsize_ext_##ar_type_name (ar_##ar_type_name *array, int count, char const * name) \ { \ return _ar_setsize ((void **)array, \ count, \ sizeof (type), \ name); \ } #define ar_for_each(array, varname) for (varname = 0; varname < ar_size (array); ++varname) /* common types */ AR_TYPEDEF (int, int); AR_TYPEDEF (size_t, size_t); AR_TYPEDEF (long, long); AR_TYPEDEF (unsigned long, ulong); AR_TYPEDEF (off_t, off_t); AR_TYPEDEF (char *, char_star); AR_TYPEDEF (unsigned char *, uchar_star); #endif /* INCLUDE__ARRAYS__AR_H */