updated hawk_arr_t callback functions to be more consistent with hawk_rbt_t/hawk_htb_t by creating hawk_arr_style_t and adding hawk_arr_setstyle()/hawk_arr_getstyle().
remove hawk_arr_getcopier()/hawk_arr_setcopier()/hawk_arr_getcomper()/hawk_arr_setcomper()
This commit is contained in:
parent
75dc7d8fbc
commit
6e857ff4f2
149
hawk/lib/arr.c
149
hawk/lib/arr.c
@ -42,9 +42,7 @@
|
||||
|
||||
/* the default comparator is not proper for number comparision.
|
||||
* the first different byte decides whice side is greater */
|
||||
static int default_comparator (hawk_arr_t* arr,
|
||||
const void* dptr1, hawk_oow_t dlen1,
|
||||
const void* dptr2, hawk_oow_t dlen2)
|
||||
int hawk_arr_dflcomp (hawk_arr_t* arr, const void* dptr1, hawk_oow_t dlen1, const void* dptr2, hawk_oow_t dlen2)
|
||||
{
|
||||
/*
|
||||
if (dlen1 == dlen2) return HAWK_MEMCMP(dptr1, dptr2, TOB(arr,dlen1));
|
||||
@ -68,26 +66,26 @@ static HAWK_INLINE slot_t* alloc_slot (hawk_arr_t* arr, void* dptr, hawk_oow_t d
|
||||
{
|
||||
slot_t* n;
|
||||
|
||||
if (arr->copier == HAWK_ARR_COPIER_SIMPLE)
|
||||
if (arr->style->copier == HAWK_ARR_COPIER_SIMPLE)
|
||||
{
|
||||
n = (slot_t*)hawk_gem_allocmem(arr->gem, HAWK_SIZEOF(slot_t));
|
||||
if (HAWK_UNLIKELY(!n)) return HAWK_NULL;
|
||||
DPTR(n) = dptr;
|
||||
DPTR(n) = dptr; /* store the pointer */
|
||||
}
|
||||
else if (arr->copier == HAWK_ARR_COPIER_INLINE)
|
||||
else if (arr->style->copier == HAWK_ARR_COPIER_INLINE)
|
||||
{
|
||||
n = (slot_t*)hawk_gem_allocmem(arr->gem, HAWK_SIZEOF(slot_t) + TOB(arr,dlen));
|
||||
if (HAWK_UNLIKELY(!n)) return HAWK_NULL;
|
||||
if (HAWK_UNLIKELY(!n)) return HAWK_NULL;
|
||||
|
||||
HAWK_MEMCPY (n + 1, dptr, TOB(arr,dlen));
|
||||
HAWK_MEMCPY (n + 1, dptr, TOB(arr,dlen)); /* copy data contents */
|
||||
DPTR(n) = n + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
n = (slot_t*)hawk_gem_allocmem(arr->gem, HAWK_SIZEOF(slot_t));
|
||||
if (HAWK_UNLIKELY(!n)) return HAWK_NULL;
|
||||
DPTR(n) = arr->copier(arr, dptr, dlen);
|
||||
if (DPTR(n) == HAWK_NULL)
|
||||
DPTR(n) = arr->style->copier(arr, dptr, dlen); /* call the custom copier */
|
||||
if (HAWK_UNLIKELY(!DPTR(n)))
|
||||
{
|
||||
hawk_gem_freemem (arr->gem, n);
|
||||
return HAWK_NULL;
|
||||
@ -122,6 +120,32 @@ void hawk_arr_close (hawk_arr_t* arr)
|
||||
hawk_gem_freemem (arr->gem, arr);
|
||||
}
|
||||
|
||||
|
||||
static hawk_arr_style_t style[] =
|
||||
{
|
||||
{
|
||||
HAWK_ARR_COPIER_DEFAULT,
|
||||
HAWK_ARR_FREEER_DEFAULT,
|
||||
HAWK_ARR_COMPER_DEFAULT,
|
||||
HAWK_ARR_KEEPER_DEFAULT,
|
||||
HAWK_ARR_SIZER_DEFAULT
|
||||
},
|
||||
|
||||
{
|
||||
HAWK_ARR_COPIER_INLINE,
|
||||
HAWK_ARR_FREEER_DEFAULT,
|
||||
HAWK_ARR_COMPER_DEFAULT,
|
||||
HAWK_ARR_KEEPER_DEFAULT,
|
||||
HAWK_ARR_SIZER_DEFAULT
|
||||
}
|
||||
};
|
||||
|
||||
const hawk_arr_style_t* hawk_get_arr_style (hawk_arr_style_kind_t kind)
|
||||
{
|
||||
return &style[kind];
|
||||
}
|
||||
|
||||
|
||||
int hawk_arr_init (hawk_arr_t* arr, hawk_gem_t* gem, hawk_oow_t capa)
|
||||
{
|
||||
HAWK_MEMSET (arr, 0, HAWK_SIZEOF(*arr));
|
||||
@ -132,9 +156,7 @@ int hawk_arr_init (hawk_arr_t* arr, hawk_gem_t* gem, hawk_oow_t capa)
|
||||
arr->slot = HAWK_NULL;
|
||||
arr->scale = 1;
|
||||
arr->heap_pos_offset = HAWK_ARR_NIL;
|
||||
|
||||
arr->copier = HAWK_ARR_COPIER_SIMPLE;
|
||||
arr->comper = default_comparator;
|
||||
arr->style = &style[0];
|
||||
|
||||
return (hawk_arr_setcapa(arr, capa) == HAWK_NULL)? -1: 0;
|
||||
}
|
||||
@ -168,56 +190,15 @@ void hawk_arr_setscale (hawk_arr_t* arr, int scale)
|
||||
arr->scale = scale;
|
||||
}
|
||||
|
||||
copier_t hawk_arr_getcopier (hawk_arr_t* arr)
|
||||
const hawk_arr_style_t* hawk_arr_getstyle (hawk_arr_t* arr)
|
||||
{
|
||||
return arr->copier;
|
||||
return &arr->style;
|
||||
}
|
||||
|
||||
void hawk_arr_setcopier (hawk_arr_t* arr, copier_t copier)
|
||||
void hawk_arr_setstyle (hawk_arr_t* arr, const hawk_arr_style_t* style)
|
||||
{
|
||||
if (copier == HAWK_NULL) copier = HAWK_ARR_COPIER_SIMPLE;
|
||||
arr->copier = copier;
|
||||
}
|
||||
|
||||
freeer_t hawk_arr_getfreeer (hawk_arr_t* arr)
|
||||
{
|
||||
return arr->freeer;
|
||||
}
|
||||
|
||||
void hawk_arr_setfreeer (hawk_arr_t* arr, freeer_t freeer)
|
||||
{
|
||||
arr->freeer = freeer;
|
||||
}
|
||||
|
||||
comper_t hawk_arr_getcomper (hawk_arr_t* arr)
|
||||
{
|
||||
return arr->comper;
|
||||
}
|
||||
|
||||
void hawk_arr_setcomper (hawk_arr_t* arr, comper_t comper)
|
||||
{
|
||||
if (comper == HAWK_NULL) comper = default_comparator;
|
||||
arr->comper = comper;
|
||||
}
|
||||
|
||||
keeper_t hawk_arr_getkeeper (hawk_arr_t* arr)
|
||||
{
|
||||
return arr->keeper;
|
||||
}
|
||||
|
||||
void hawk_arr_setkeeper (hawk_arr_t* arr, keeper_t keeper)
|
||||
{
|
||||
arr->keeper = keeper;
|
||||
}
|
||||
|
||||
sizer_t hawk_arr_getsizer (hawk_arr_t* arr)
|
||||
{
|
||||
return arr->sizer;
|
||||
}
|
||||
|
||||
void hawk_arr_setsizer (hawk_arr_t* arr, sizer_t sizer)
|
||||
{
|
||||
arr->sizer = sizer;
|
||||
HAWK_ASSERT (style != HAWK_NULL);
|
||||
arr->style = style;
|
||||
}
|
||||
|
||||
hawk_oow_t hawk_arr_getsize (hawk_arr_t* arr)
|
||||
@ -272,7 +253,7 @@ hawk_oow_t hawk_arr_search (hawk_arr_t* arr, hawk_oow_t pos, const void* dptr, h
|
||||
for (i = pos; i < arr->size; i++)
|
||||
{
|
||||
if (arr->slot[i] == HAWK_NULL) continue;
|
||||
if (arr->comper(arr, DPTR(arr->slot[i]), DLEN(arr->slot[i]), dptr, dlen) == 0) return i;
|
||||
if (arr->style->comper(arr, DPTR(arr->slot[i]), DLEN(arr->slot[i]), dptr, dlen) == 0) return i;
|
||||
}
|
||||
|
||||
hawk_gem_seterrnum (arr->gem, HAWK_NULL, HAWK_ENOENT);
|
||||
@ -290,7 +271,7 @@ hawk_oow_t hawk_arr_rsearch (hawk_arr_t* arr, hawk_oow_t pos, const void* dptr,
|
||||
for (i = pos + 1; i-- > 0; )
|
||||
{
|
||||
if (arr->slot[i] == HAWK_NULL) continue;
|
||||
if (arr->comper (arr, DPTR(arr->slot[i]), DLEN(arr->slot[i]), dptr, dlen) == 0) return i;
|
||||
if (arr->style->comper(arr, DPTR(arr->slot[i]), DLEN(arr->slot[i]), dptr, dlen) == 0) return i;
|
||||
}
|
||||
}
|
||||
|
||||
@ -310,8 +291,8 @@ hawk_oow_t hawk_arr_insert (hawk_arr_t* arr, hawk_oow_t pos, void* dptr, hawk_oo
|
||||
slot_t* slot;
|
||||
|
||||
/* allocate the slot first */
|
||||
slot = alloc_slot (arr, dptr, dlen);
|
||||
if (slot == HAWK_NULL) return HAWK_ARR_NIL;
|
||||
slot = alloc_slot(arr, dptr, dlen);
|
||||
if (HAWK_UNLIKELY(!slot)) return HAWK_ARR_NIL;
|
||||
|
||||
/* do resizeing if necessary.
|
||||
* resizing is performed after slot allocation because that way, it
|
||||
@ -323,9 +304,9 @@ hawk_oow_t hawk_arr_insert (hawk_arr_t* arr, hawk_oow_t pos, void* dptr, hawk_oo
|
||||
/* get the minimum capacity needed */
|
||||
mincapa = (pos >= arr->size)? (pos + 1): (arr->size + 1);
|
||||
|
||||
if (arr->sizer)
|
||||
if (arr->style->sizer)
|
||||
{
|
||||
capa = arr->sizer(arr, mincapa);
|
||||
capa = arr->style->sizer(arr, mincapa);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -348,7 +329,7 @@ hawk_oow_t hawk_arr_insert (hawk_arr_t* arr, hawk_oow_t pos, void* dptr, hawk_oo
|
||||
|
||||
if (capa <= mincapa)
|
||||
{
|
||||
if (arr->freeer) arr->freeer (arr, DPTR(slot), DLEN(slot));
|
||||
if (arr->style->freeer) arr->style->freeer (arr, DPTR(slot), DLEN(slot));
|
||||
hawk_gem_freemem (arr->gem, slot);
|
||||
return HAWK_ARR_NIL;
|
||||
}
|
||||
@ -360,7 +341,7 @@ hawk_oow_t hawk_arr_insert (hawk_arr_t* arr, hawk_oow_t pos, void* dptr, hawk_oo
|
||||
if (pos >= arr->capa || arr->size >= arr->capa) /* can happen if the sizer() callback isn't good enough */
|
||||
{
|
||||
/* the buffer is not still enough after resizing */
|
||||
if (arr->freeer) arr->freeer (arr, DPTR(slot), DLEN(slot));
|
||||
if (arr->style->freeer) arr->style->freeer (arr, DPTR(slot), DLEN(slot));
|
||||
hawk_gem_freemem (arr->gem, slot);
|
||||
hawk_gem_seterrnum (arr->gem, HAWK_NULL, HAWK_EBUFFULL);
|
||||
return HAWK_ARR_NIL;
|
||||
@ -404,15 +385,15 @@ hawk_oow_t hawk_arr_update (hawk_arr_t* arr, hawk_oow_t pos, void* dptr, hawk_oo
|
||||
if (dptr == DPTR(c) && dlen == DLEN(c))
|
||||
{
|
||||
/* updated to the same data */
|
||||
if (arr->keeper) arr->keeper (arr, dptr, dlen);
|
||||
if (arr->style->keeper) arr->style->keeper (arr, dptr, dlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* updated to different data */
|
||||
slot_t* slot = alloc_slot(arr, dptr, dlen);
|
||||
if (slot == HAWK_NULL) return HAWK_ARR_NIL;
|
||||
if (HAWK_UNLIKELY(!slot)) return HAWK_ARR_NIL;
|
||||
|
||||
if (arr->freeer) arr->freeer (arr, DPTR(c), DLEN(c));
|
||||
if (arr->style->freeer) arr->style->freeer (arr, DPTR(c), DLEN(c));
|
||||
hawk_gem_freemem (arr->gem, c);
|
||||
|
||||
arr->slot[pos] = slot;
|
||||
@ -437,7 +418,7 @@ hawk_oow_t hawk_arr_delete (hawk_arr_t* arr, hawk_oow_t index, hawk_oow_t count)
|
||||
|
||||
if (c != HAWK_NULL)
|
||||
{
|
||||
if (arr->freeer) arr->freeer (arr, DPTR(c), DLEN(c));
|
||||
if (arr->style->freeer) arr->style->freeer (arr, DPTR(c), DLEN(c));
|
||||
hawk_gem_freemem (arr->gem, c);
|
||||
arr->slot[i] = HAWK_NULL;
|
||||
}
|
||||
@ -468,7 +449,7 @@ hawk_oow_t hawk_arr_uplete (hawk_arr_t* arr, hawk_oow_t index, hawk_oow_t count)
|
||||
|
||||
if (c != HAWK_NULL)
|
||||
{
|
||||
if (arr->freeer) arr->freeer (arr, DPTR(c), DLEN(c));
|
||||
if (arr->style->freeer) arr->style->freeer (arr, DPTR(c), DLEN(c));
|
||||
hawk_gem_freemem (arr->gem, c);
|
||||
arr->slot[i] = HAWK_NULL;
|
||||
}
|
||||
@ -486,7 +467,7 @@ void hawk_arr_clear (hawk_arr_t* arr)
|
||||
slot_t* c = arr->slot[i];
|
||||
if (c != HAWK_NULL)
|
||||
{
|
||||
if (arr->freeer) arr->freeer (arr, DPTR(c), DLEN(c));
|
||||
if (arr->style->freeer) arr->style->freeer (arr, DPTR(c), DLEN(c));
|
||||
hawk_gem_freemem (arr->gem, c);
|
||||
arr->slot[i] = HAWK_NULL;
|
||||
}
|
||||
@ -590,9 +571,7 @@ static hawk_oow_t sift_up (hawk_arr_t* arr, hawk_oow_t index)
|
||||
int n;
|
||||
|
||||
parent = HEAP_PARENT(index);
|
||||
n = arr->comper (arr,
|
||||
DPTR(arr->slot[index]), DLEN(arr->slot[index]),
|
||||
DPTR(arr->slot[parent]), DLEN(arr->slot[parent]));
|
||||
n = arr->style->comper(arr, DPTR(arr->slot[index]), DLEN(arr->slot[index]), DPTR(arr->slot[parent]), DLEN(arr->slot[parent]));
|
||||
if (n > 0)
|
||||
{
|
||||
slot_t* tmp;
|
||||
@ -609,9 +588,7 @@ static hawk_oow_t sift_up (hawk_arr_t* arr, hawk_oow_t index)
|
||||
|
||||
if (index <= 0) break;
|
||||
|
||||
n = arr->comper (arr,
|
||||
DPTR(tmp), DLEN(tmp),
|
||||
DPTR(arr->slot[parent]), DLEN(arr->slot[parent]));
|
||||
n = arr->style->comper(arr, DPTR(tmp), DLEN(tmp), DPTR(arr->slot[parent]), DLEN(arr->slot[parent]));
|
||||
if (n <= 0) break;
|
||||
}
|
||||
|
||||
@ -644,7 +621,7 @@ static hawk_oow_t sift_down (hawk_arr_t* arr, hawk_oow_t index)
|
||||
|
||||
if (right < arr->size)
|
||||
{
|
||||
n = arr->comper (arr,
|
||||
n = arr->style->comper(arr,
|
||||
DPTR(arr->slot[right]), DLEN(arr->slot[right]),
|
||||
DPTR(arr->slot[left]), DLEN(arr->slot[left]));
|
||||
child = (n > 0)? right: left;
|
||||
@ -654,9 +631,7 @@ static hawk_oow_t sift_down (hawk_arr_t* arr, hawk_oow_t index)
|
||||
child = left;
|
||||
}
|
||||
|
||||
n = arr->comper (arr,
|
||||
DPTR(tmp), DLEN(tmp),
|
||||
DPTR(arr->slot[child]), DLEN(arr->slot[child]));
|
||||
n = arr->style->comper(arr, DPTR(tmp), DLEN(tmp), DPTR(arr->slot[child]), DLEN(arr->slot[child]));
|
||||
if (n > 0) break;
|
||||
|
||||
arr->slot[index] = arr->slot[child];
|
||||
@ -715,15 +690,13 @@ void hawk_arr_deleteheap (hawk_arr_t* arr, hawk_oow_t index)
|
||||
|
||||
/* move it up if the last item is greater than the item to be deleted,
|
||||
* move it down otherwise. */
|
||||
n = arr->comper (arr,
|
||||
DPTR(arr->slot[index]), DLEN(arr->slot[index]),
|
||||
DPTR(tmp), DLEN(tmp));
|
||||
n = arr->style->comper(arr, DPTR(arr->slot[index]), DLEN(arr->slot[index]), DPTR(tmp), DLEN(tmp));
|
||||
if (n > 0) sift_up (arr, index);
|
||||
else if (n < 0) sift_down (arr, index);
|
||||
}
|
||||
|
||||
/* destroy the actual item */
|
||||
if (arr->freeer) arr->freeer (arr, DPTR(tmp), DLEN(tmp));
|
||||
if (arr->style->freeer) arr->style->freeer (arr, DPTR(tmp), DLEN(tmp));
|
||||
hawk_gem_freemem (arr->gem, tmp);
|
||||
|
||||
/* empty the last slot */
|
||||
@ -738,7 +711,7 @@ hawk_oow_t hawk_arr_updateheap (hawk_arr_t* arr, hawk_oow_t index, void* dptr, h
|
||||
tmp = arr->slot[index];
|
||||
HAWK_ASSERT (tmp != HAWK_NULL);
|
||||
|
||||
n = arr->comper(arr, dptr, dlen, DPTR(tmp), DLEN(tmp));
|
||||
n = arr->style->comper(arr, dptr, dlen, DPTR(tmp), DLEN(tmp));
|
||||
if (n)
|
||||
{
|
||||
if (hawk_arr_update(arr, index, dptr, dlen) == HAWK_ARR_NIL) return HAWK_ARR_NIL;
|
||||
|
@ -125,6 +125,15 @@ static int compare_dirent (hawk_arr_t* arr, const void* dptr1, hawk_oow_t dlen1,
|
||||
|
||||
int hawk_dir_init (hawk_dir_t* dir, hawk_gem_t* gem, const hawk_ooch_t* path, int flags)
|
||||
{
|
||||
static hawk_arr_style_t stab_style =
|
||||
{
|
||||
HAWK_ARR_COPIER_INLINE,
|
||||
HAWK_ARR_FREEER_DEFAULT,
|
||||
compare_dirent,
|
||||
HAWK_ARR_KEEPER_DEFAULT,
|
||||
HAWK_ARR_SIZER_DEFAULT
|
||||
};
|
||||
|
||||
int n;
|
||||
int path_flags;
|
||||
|
||||
@ -159,11 +168,11 @@ int hawk_dir_init (hawk_dir_t* dir, hawk_gem_t* gem, const hawk_ooch_t* path, in
|
||||
if (dir->flags & HAWK_DIR_SORT)
|
||||
{
|
||||
dir->stab = hawk_arr_open(gem, 0, 128);
|
||||
if (dir->stab == HAWK_NULL) goto oops_3;
|
||||
if (HAWK_UNLIKELY(!dir->stab)) goto oops_3;
|
||||
|
||||
/*hawk_arr_setscale (dir->stab, 1);*/
|
||||
hawk_arr_setcopier (dir->stab, HAWK_ARR_COPIER_INLINE);
|
||||
hawk_arr_setcomper (dir->stab, compare_dirent);
|
||||
hawk_arr_setstyle (dir->stab, &stab_style);
|
||||
|
||||
if (read_ahead_and_sort(dir, path) <= -1) goto oops_4;
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,7 @@ static int fnc_typename (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
|
||||
static int fnc_gcrefs (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
|
||||
static int fnc_isnil (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
|
||||
static int fnc_ismap (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
|
||||
static int fnc_isarr (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
|
||||
static int fnc_asort (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
|
||||
static int fnc_asorti (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi);
|
||||
|
||||
@ -58,6 +59,7 @@ static hawk_fnc_t sysfnctab[] =
|
||||
|
||||
/* type info/conversion */
|
||||
{ {HAWK_T("int"), 3}, 0, { {1, 1, HAWK_NULL}, fnc_int, 0 }, HAWK_NULL},
|
||||
{ {HAWK_T("isarray"), 7}, 0, { {1, 1, HAWK_NULL}, fnc_isarr, 0 }, HAWK_NULL},
|
||||
{ {HAWK_T("isnil"), 5}, 0, { {1, 1, HAWK_NULL}, fnc_isnil, 0 }, HAWK_NULL},
|
||||
{ {HAWK_T("ismap"), 5}, 0, { {1, 1, HAWK_NULL}, fnc_ismap, 0 }, HAWK_NULL},
|
||||
{ {HAWK_T("typename"), 8}, 0, { {1, 1, HAWK_NULL}, fnc_typename, 0 }, HAWK_NULL},
|
||||
@ -1774,7 +1776,21 @@ static int fnc_ismap (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
a0 = hawk_rtx_getarg(rtx, 0);
|
||||
|
||||
r = hawk_rtx_makeintval(rtx, HAWK_RTX_GETVALTYPE(rtx, a0) == HAWK_VAL_MAP);
|
||||
if (r == HAWK_NULL) return -1;
|
||||
if (HAWK_UNLIKELY(!r)) return -1;
|
||||
|
||||
hawk_rtx_setretval (rtx, r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fnc_isarr (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
hawk_val_t* a0;
|
||||
hawk_val_t* r;
|
||||
|
||||
a0 = hawk_rtx_getarg(rtx, 0);
|
||||
|
||||
r = hawk_rtx_makeintval(rtx, HAWK_RTX_GETVALTYPE(rtx, a0) == HAWK_VAL_ARR);
|
||||
if (HAWK_UNLIKELY(!r)) return -1;
|
||||
|
||||
hawk_rtx_setretval (rtx, r);
|
||||
return 0;
|
||||
|
@ -48,6 +48,12 @@ typedef enum hawk_arr_walk_t hawk_arr_walk_t;
|
||||
#define HAWK_ARR_COPIER_SIMPLE ((hawk_arr_copier_t)1)
|
||||
#define HAWK_ARR_COPIER_INLINE ((hawk_arr_copier_t)2)
|
||||
|
||||
#define HAWK_ARR_COPIER_DEFAULT (HAWK_ARR_COPIER_SIMPLE)
|
||||
#define HAWK_ARR_FREEER_DEFAULT (HAWK_NULL)
|
||||
#define HAWK_ARR_COMPER_DEFAULT (hawk_arr_dflcomp)
|
||||
#define HAWK_ARR_KEEPER_DEFAULT (HAWK_NULL)
|
||||
#define HAWK_ARR_SIZER_DEFAULT (HAWK_NULL)
|
||||
|
||||
#define HAWK_ARR_NIL ((hawk_oow_t)-1)
|
||||
|
||||
#define HAWK_ARR_SIZE(arr) (*(const hawk_oow_t*)&(arr)->size)
|
||||
@ -64,17 +70,16 @@ typedef enum hawk_arr_walk_t hawk_arr_walk_t;
|
||||
* define how the data to add can be maintained in the array. A dynamic
|
||||
* array not specified with any copiers stores the data pointer and
|
||||
* the data length into a slot. A special copier HAWK_ARR_COPIER_INLINE copies
|
||||
* the contents of the data a user provided into the slot. You can use the
|
||||
* hawk_arr_setcopier() function to change the copier.
|
||||
*
|
||||
* the contents of the data a user provided into the slot.
|
||||
*
|
||||
* A copier should return the pointer to the copied data. If it fails to copy
|
||||
* data, it may return HAWK_NULL. You need to set a proper freeer to free up
|
||||
* memory allocated for copy.
|
||||
*/
|
||||
typedef void* (*hawk_arr_copier_t) (
|
||||
hawk_arr_t* arr /**< array */,
|
||||
void* dptr /**< pointer to data to copy */,
|
||||
hawk_oow_t dlen /**< length of data to copy */
|
||||
void* dptr /**< pointer to data to copy */,
|
||||
hawk_oow_t dlen /**< length of data to copy */
|
||||
);
|
||||
|
||||
/**
|
||||
@ -82,8 +87,8 @@ typedef void* (*hawk_arr_copier_t) (
|
||||
*/
|
||||
typedef void (*hawk_arr_freeer_t) (
|
||||
hawk_arr_t* arr /**< array */,
|
||||
void* dptr /**< pointer to data to free */,
|
||||
hawk_oow_t dlen /**< length of data to free */
|
||||
void* dptr /**< pointer to data to free */,
|
||||
hawk_oow_t dlen /**< length of data to free */
|
||||
);
|
||||
|
||||
/**
|
||||
@ -103,10 +108,10 @@ typedef void (*hawk_arr_freeer_t) (
|
||||
*/
|
||||
typedef int (*hawk_arr_comper_t) (
|
||||
hawk_arr_t* arr /* array */,
|
||||
const void* dptr1 /* data pointer */,
|
||||
hawk_oow_t dlen1 /* data length */,
|
||||
const void* dptr2 /* data pointer */,
|
||||
hawk_oow_t dlen2 /* data length */
|
||||
const void* dptr1 /* data pointer */,
|
||||
hawk_oow_t dlen1 /* data length */,
|
||||
const void* dptr2 /* data pointer */,
|
||||
hawk_oow_t dlen2 /* data length */
|
||||
);
|
||||
|
||||
/**
|
||||
@ -117,8 +122,8 @@ typedef int (*hawk_arr_comper_t) (
|
||||
*/
|
||||
typedef void (*hawk_arr_keeper_t) (
|
||||
hawk_arr_t* arr /**< array */,
|
||||
void* vptr /**< pointer to a value */,
|
||||
hawk_oow_t vlen /**< length of a value */
|
||||
void* vptr /**< pointer to a value */,
|
||||
hawk_oow_t vlen /**< length of a value */
|
||||
);
|
||||
|
||||
/**
|
||||
@ -127,13 +132,40 @@ typedef void (*hawk_arr_keeper_t) (
|
||||
*/
|
||||
typedef hawk_oow_t (*hawk_arr_sizer_t) (
|
||||
hawk_arr_t* arr, /**< array */
|
||||
hawk_oow_t hint /**< sizing hint */
|
||||
hawk_oow_t hint /**< sizing hint */
|
||||
);
|
||||
|
||||
|
||||
typedef struct hawk_arr_style_t hawk_arr_style_t;
|
||||
|
||||
struct hawk_arr_style_t
|
||||
{
|
||||
hawk_arr_copier_t copier; /* data copier */
|
||||
hawk_arr_freeer_t freeer; /* data freeer */
|
||||
hawk_arr_comper_t comper; /* data comparator */
|
||||
hawk_arr_keeper_t keeper; /* data keeper */
|
||||
hawk_arr_sizer_t sizer; /* size calculator */
|
||||
};
|
||||
|
||||
/**
|
||||
* The hawk_arr_style_kind_t type defines the type of predefined
|
||||
* callback set for pair manipulation.
|
||||
*/
|
||||
enum hawk_arr_style_kind_t
|
||||
{
|
||||
/** store element pointers */
|
||||
HAWK_ARR_STYLE_DEFAULT,
|
||||
/** copy elements */
|
||||
HAWK_ARR_STYLE_INLINE_COPIER
|
||||
};
|
||||
|
||||
typedef enum hawk_arr_style_kind_t hawk_arr_style_kind_t;
|
||||
|
||||
|
||||
typedef hawk_arr_walk_t (*hawk_arr_walker_t) (
|
||||
hawk_arr_t* arr /* array */,
|
||||
hawk_oow_t index /* index to the visited slot */,
|
||||
void* ctx /* user-defined context */
|
||||
hawk_oow_t index /* index to the visited slot */,
|
||||
void* ctx /* user-defined context */
|
||||
);
|
||||
|
||||
/**
|
||||
@ -142,11 +174,7 @@ typedef hawk_arr_walk_t (*hawk_arr_walker_t) (
|
||||
struct hawk_arr_t
|
||||
{
|
||||
hawk_gem_t* gem;
|
||||
hawk_arr_copier_t copier; /* data copier */
|
||||
hawk_arr_freeer_t freeer; /* data freeer */
|
||||
hawk_arr_comper_t comper; /* data comparator */
|
||||
hawk_arr_keeper_t keeper; /* data keeper */
|
||||
hawk_arr_sizer_t sizer; /* size calculator */
|
||||
const hawk_arr_style_t* style;
|
||||
hawk_uint8_t scale; /* scale factor */
|
||||
hawk_oow_t heap_pos_offset; /* offset in the data element where position
|
||||
* is stored when heap operation is performed. */
|
||||
@ -167,6 +195,14 @@ struct hawk_arr_slot_t
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The hawk_get_arr_style() functions returns a predefined callback set for
|
||||
* pair manipulation.
|
||||
*/
|
||||
HAWK_EXPORT const hawk_arr_style_t* hawk_get_arr_style (
|
||||
hawk_arr_style_kind_t kind
|
||||
);
|
||||
|
||||
/**
|
||||
* The hawk_arr_open() function creates a linear dynamic array.
|
||||
*/
|
||||
@ -228,65 +264,14 @@ HAWK_EXPORT hawk_arr_copier_t hawk_arr_getcopier (
|
||||
hawk_arr_t* arr /* array */
|
||||
);
|
||||
|
||||
/**
|
||||
* The hawk_arr_setcopier() specifies how to clone an element. The special
|
||||
* copier #HAWK_ARR_COPIER_INLINE copies the data inline to the internal slot.
|
||||
* No freeer is invoked when the slot is freeed. You may set the copier to
|
||||
* #HAWK_ARR_COPIER_SIMPLE to perform no special operation when the data
|
||||
* pointer is stored.
|
||||
*/
|
||||
HAWK_EXPORT void hawk_arr_setcopier (
|
||||
hawk_arr_t* arr /** arr */,
|
||||
hawk_arr_copier_t copier /** element copier */
|
||||
|
||||
HAWK_EXPORT void hawk_arr_setstyle (
|
||||
hawk_arr_t* arr,
|
||||
const hawk_arr_style_t* style
|
||||
);
|
||||
|
||||
/**
|
||||
* The hawk_arr_getfreeer() function returns a custom element destroyer.
|
||||
*/
|
||||
HAWK_EXPORT hawk_arr_freeer_t hawk_arr_getfreeer (
|
||||
hawk_arr_t* arr /**< arr */
|
||||
);
|
||||
|
||||
/**
|
||||
* The hawk_arr_setfreeer() function specifies how to destroy an element.
|
||||
* The @a freeer is called when a slot containing the element is destroyed.
|
||||
*/
|
||||
HAWK_EXPORT void hawk_arr_setfreeer (
|
||||
hawk_arr_t* arr /**< arr */,
|
||||
hawk_arr_freeer_t freeer /**< element freeer */
|
||||
);
|
||||
|
||||
HAWK_EXPORT hawk_arr_comper_t hawk_arr_getcomper (
|
||||
hawk_arr_t* arr /**< arr */
|
||||
);
|
||||
|
||||
/**
|
||||
* The hawk_arr_setcomper() function specifies how to compare two elements
|
||||
* for equality test. The comparator @a comper must return 0 if two elements
|
||||
* compared are equal, 1 if the first element is greater than the
|
||||
* second, -1 if the second element is greater than the first.
|
||||
*/
|
||||
HAWK_EXPORT void hawk_arr_setcomper (
|
||||
hawk_arr_t* arr /**< arr */,
|
||||
hawk_arr_comper_t comper /**< comparator */
|
||||
);
|
||||
|
||||
HAWK_EXPORT hawk_arr_keeper_t hawk_arr_getkeeper (
|
||||
hawk_arr_t* arr
|
||||
);
|
||||
|
||||
HAWK_EXPORT void hawk_arr_setkeeper (
|
||||
hawk_arr_t* arr,
|
||||
hawk_arr_keeper_t keeper
|
||||
);
|
||||
|
||||
HAWK_EXPORT hawk_arr_sizer_t hawk_arr_getsizer (
|
||||
hawk_arr_t* arr
|
||||
);
|
||||
|
||||
HAWK_EXPORT void hawk_arr_setsizer (
|
||||
hawk_arr_t* arr,
|
||||
hawk_arr_sizer_t sizer
|
||||
HAWK_EXPORT const hawk_arr_style_t* hawk_arr_getstyle (
|
||||
hawk_arr_t* arr
|
||||
);
|
||||
|
||||
HAWK_EXPORT hawk_oow_t hawk_arr_getsize (
|
||||
@ -475,6 +460,19 @@ HAWK_EXPORT void hawk_arr_setheapposoffset (
|
||||
hawk_oow_t offset
|
||||
);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The hawk_arr_dflcomp() function is the default comparator
|
||||
*/
|
||||
HAWK_EXPORT int hawk_arr_dflcomp (
|
||||
hawk_arr_t* arr,
|
||||
const void* dptr1,
|
||||
hawk_oow_t dlen1,
|
||||
const void* dptr2,
|
||||
hawk_oow_t dlen2
|
||||
);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
@ -233,15 +233,15 @@ int hawk_init (hawk_t* hawk, hawk_mmgr_t* mmgr, hawk_cmgr_t* cmgr, const hawk_pr
|
||||
|
||||
*(hawk_t**)(hawk->parse.gbls + 1) = hawk;
|
||||
hawk_arr_setscale (hawk->parse.gbls, HAWK_SIZEOF(hawk_ooch_t));
|
||||
hawk_arr_setcopier (hawk->parse.gbls, HAWK_ARR_COPIER_INLINE);
|
||||
hawk_arr_setstyle (hawk->parse.gbls, hawk_get_arr_style(HAWK_ARR_STYLE_INLINE_COPIER));
|
||||
|
||||
*(hawk_t**)(hawk->parse.lcls + 1) = hawk;
|
||||
hawk_arr_setscale (hawk->parse.lcls, HAWK_SIZEOF(hawk_ooch_t));
|
||||
hawk_arr_setcopier (hawk->parse.lcls, HAWK_ARR_COPIER_INLINE);
|
||||
hawk_arr_setstyle (hawk->parse.lcls, hawk_get_arr_style(HAWK_ARR_STYLE_INLINE_COPIER));
|
||||
|
||||
*(hawk_t**)(hawk->parse.params + 1) = hawk;
|
||||
hawk_arr_setscale (hawk->parse.params, HAWK_SIZEOF(hawk_ooch_t));
|
||||
hawk_arr_setcopier (hawk->parse.params, HAWK_ARR_COPIER_INLINE);
|
||||
hawk_arr_setstyle (hawk->parse.params, hawk_get_arr_style(HAWK_ARR_STYLE_INLINE_COPIER));
|
||||
|
||||
*(hawk_t**)(hawk->fnc.user + 1) = hawk;
|
||||
hawk_htb_setstyle (hawk->fnc.user, &fncusercbs);
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <hawk-htb.h> /* for rtx->named */
|
||||
#define HAWK_MAP_IS_RBT
|
||||
#include <hawk-map.h>
|
||||
#include <hawk-arr.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/** \file
|
||||
@ -272,6 +273,22 @@ struct hawk_val_map_t
|
||||
};
|
||||
typedef struct hawk_val_map_t hawk_val_map_t;
|
||||
|
||||
/**
|
||||
* The hawk_val_arr_t type defines a arr type. The type field is
|
||||
* #HAWK_VAL_MAP.
|
||||
*/
|
||||
struct hawk_val_arr_t
|
||||
{
|
||||
HAWK_VAL_HDR;
|
||||
|
||||
/* TODO: make val_arr to array if the indices used are all
|
||||
* integers switch to arr dynamically once the
|
||||
* non-integral index is seen.
|
||||
*/
|
||||
hawk_arr_t* arr;
|
||||
};
|
||||
typedef struct hawk_val_arr_t hawk_val_arr_t;
|
||||
|
||||
/**
|
||||
* The hawk_val_ref_t type defines a reference type that is used
|
||||
* internally only. The type field is #HAWK_VAL_REF.
|
||||
@ -1371,9 +1388,10 @@ enum hawk_val_type_t
|
||||
HAWK_VAL_MBS = 4, /**< byte array */
|
||||
HAWK_VAL_FUN = 5, /**< function pointer */
|
||||
HAWK_VAL_MAP = 6, /**< map */
|
||||
HAWK_VAL_ARR = 7, /**< array */
|
||||
|
||||
HAWK_VAL_REX = 7, /**< regular expression */
|
||||
HAWK_VAL_REF = 8 /**< reference to other types */
|
||||
HAWK_VAL_REX = 8, /**< regular expression */
|
||||
HAWK_VAL_REF = 9 /**< reference to other types */
|
||||
};
|
||||
typedef enum hawk_val_type_t hawk_val_type_t;
|
||||
|
||||
@ -2867,8 +2885,9 @@ HAWK_EXPORT hawk_val_t* hawk_rtx_makerexval (
|
||||
* The hawk_rtx_makemapval() function creates an empty array value.
|
||||
* \return value on success, #HAWK_NULL on failure
|
||||
*/
|
||||
HAWK_EXPORT hawk_val_t* hawk_rtx_makearrayval (
|
||||
hawk_rtx_t* rtx
|
||||
HAWK_EXPORT hawk_val_t* hawk_rtx_makearrval (
|
||||
hawk_rtx_t* rtx,
|
||||
hawk_oow_t init_capa
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -217,7 +217,7 @@ static int fnc_array (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
hawk_val_t* tmp;
|
||||
|
||||
tmp = hawk_rtx_makearrayval(rtx);
|
||||
tmp = hawk_rtx_makearrval(rtx, 0);
|
||||
if (HAWK_UNLIKELY(!tmp)) return -1; /* hard failure */
|
||||
|
||||
/* TODO: take arguments and put them to the map */
|
||||
|
@ -1610,12 +1610,12 @@ static int fnc_fchmod (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
/*
|
||||
d = sys::opendir("/etc", sys::DIR_SORT);
|
||||
if (d >= 0)
|
||||
{
|
||||
while (sys::readdir(d,a) > 0) print a;
|
||||
sys::closedir(d);
|
||||
}
|
||||
d = sys::opendir("/etc", sys::DIR_SORT);
|
||||
if (d >= 0)
|
||||
{
|
||||
while (sys::readdir(d,a) > 0) print a;
|
||||
sys::closedir(d);
|
||||
}
|
||||
|
||||
#################################################
|
||||
|
||||
|
102
hawk/lib/val.c
102
hawk/lib/val.c
@ -891,11 +891,103 @@ hawk_val_t* hawk_rtx_makerexval (hawk_rtx_t* rtx, const hawk_oocs_t* str, hawk_t
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
hawk_val_t* hawk_rtx_makearrayval (hawk_rtx_t* rtx)
|
||||
static void free_arrayval (hawk_arr_t* arr, void* dptr, hawk_oow_t dlen)
|
||||
{
|
||||
/* TODO: */
|
||||
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ENOIMPL);
|
||||
return HAWK_NULL;
|
||||
hawk_rtx_t* rtx = *(hawk_rtx_t**)hawk_arr_getxtn(arr);
|
||||
hawk_val_t* v = (hawk_val_t*)dptr;
|
||||
|
||||
#if defined(DEBUG_VAL)
|
||||
hawk_logfmt (hawk_rtx_gethawk(rtx), HAWK_LOG_STDERR, HAWK_T("refdown in arr free - [%O]\n"), v);
|
||||
#endif
|
||||
|
||||
#if defined(HAWK_ENABLE_GC)
|
||||
if (HAWK_VTR_IS_POINTER(v) && v->v_gc && hawk_val_to_gch(v)->gc_refs == GCH_UNREACHABLE)
|
||||
{
|
||||
/* do nothing if the element is unreachable.
|
||||
* this behavior pairs up with gc_free_unreachables() to
|
||||
* achieve safe disposal of a value */
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
hawk_rtx_refdownval (rtx, v);
|
||||
}
|
||||
|
||||
static void same_arrayval (hawk_arr_t* map, void* dptr, hawk_oow_t dlen)
|
||||
{
|
||||
hawk_rtx_t* run = *(hawk_rtx_t**)hawk_arr_getxtn(map);
|
||||
#if defined(DEBUG_VAL)
|
||||
hawk_logfmt (hawk_rtx_gethawk(rtx), HAWK_LOG_STDERR, HAWK_T("refdown nofree in map free - [%O]\n"), dptr);
|
||||
#endif
|
||||
hawk_rtx_refdownval_nofree (run, dptr);
|
||||
}
|
||||
|
||||
|
||||
hawk_val_t* hawk_rtx_makearrval (hawk_rtx_t* rtx, hawk_oow_t init_capa)
|
||||
{
|
||||
static hawk_arr_style_t style =
|
||||
{
|
||||
/* the key is copied inline into a pair and is freed when the pair
|
||||
* is destroyed. not setting copier for a value means that the pointer
|
||||
* to the data allocated somewhere else is remembered in a pair. but
|
||||
* freeing the actual value is handled by free_arrval and same_arrval */
|
||||
|
||||
HAWK_ARR_COPIER_DEFAULT,
|
||||
free_arrayval,
|
||||
HAWK_ARR_COMPER_DEFAULT,
|
||||
same_arrayval,
|
||||
HAWK_ARR_SIZER_DEFAULT
|
||||
};
|
||||
#if defined(HAWK_ENABLE_GC)
|
||||
int retried = 0;
|
||||
#endif
|
||||
hawk_val_arr_t* val;
|
||||
|
||||
#if defined(HAWK_ENABLE_GC)
|
||||
retry:
|
||||
val = (hawk_val_arr_t*)gc_calloc_val(rtx, HAWK_SIZEOF(hawk_val_arr_t) + HAWK_SIZEOF(hawk_arr_t) + HAWK_SIZEOF(rtx));
|
||||
#else
|
||||
val = (hawk_val_arr_t*)hawk_rtx_callocmem(rtx, HAWK_SIZEOF(hawk_val_arr_t) + HAWK_SIZEOF(hawk_arr_t) + HAWK_SIZEOF(rtx));
|
||||
#endif
|
||||
if (HAWK_UNLIKELY(!val)) return HAWK_NULL;
|
||||
|
||||
val->v_type = HAWK_VAL_ARR;
|
||||
val->v_refs = 0;
|
||||
val->v_static = 0;
|
||||
val->nstr = 0;
|
||||
val->v_gc = 0;
|
||||
val->arr = (hawk_arr_t*)(val + 1);
|
||||
|
||||
if (init_capa <= 0) init_capa = 64; /* TODO: what is the best initial value? */
|
||||
if (HAWK_UNLIKELY(hawk_arr_init(val->arr, hawk_rtx_getgem(rtx), init_capa) <= -1))
|
||||
{
|
||||
#if defined(HAWK_ENABLE_GC)
|
||||
gc_free_val (rtx, (hawk_val_t*)val);
|
||||
if (HAWK_LIKELY(!retried))
|
||||
{
|
||||
/* this arr involves non-gc allocatinon, which happens outside gc_calloc_val().
|
||||
* reattempt to allocate after full gc like gc_calloc_val() */
|
||||
hawk_rtx_gc (rtx, HAWK_COUNTOF(rtx->gc.g) - 1);
|
||||
retried = 1;
|
||||
goto retry;
|
||||
}
|
||||
#else
|
||||
hawk_rtx_freemem (rtx, val);
|
||||
#endif
|
||||
return HAWK_NULL;
|
||||
}
|
||||
*(hawk_rtx_t**)hawk_arr_getxtn(val->arr) = rtx;
|
||||
hawk_arr_setstyle (val->arr, &style);
|
||||
|
||||
#if defined(HAWK_ENABLE_GC)
|
||||
gc_chain_val (&rtx->gc.g[0], (hawk_val_t*)val);
|
||||
val->v_gc = 1;
|
||||
#if defined(DEBUG_GC)
|
||||
hawk_logbfmt (hawk_rtx_gethawk(rtx), HAWK_LOG_STDERR, "[GC] MADE GCH %p VAL %p\n", hawk_val_to_gch(val), val);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return (hawk_val_t*)val;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
@ -981,7 +1073,7 @@ retry:
|
||||
if (HAWK_LIKELY(!retried))
|
||||
{
|
||||
/* this map involves non-gc allocatinon, which happens outside gc_calloc_val().
|
||||
* reattempt to allocate after full gc like gc_calloc_val() */
|
||||
* reattempt to allocate after full gc like gc_calloc_val() */
|
||||
hawk_rtx_gc (rtx, HAWK_COUNTOF(rtx->gc.g) - 1);
|
||||
retried = 1;
|
||||
goto retry;
|
||||
|
Loading…
Reference in New Issue
Block a user