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:
		
							
								
								
									
										149
									
								
								hawk/lib/arr.c
									
									
									
									
									
								
							
							
						
						
									
										149
									
								
								hawk/lib/arr.c
									
									
									
									
									
								
							| @ -42,9 +42,7 @@ | |||||||
|  |  | ||||||
| /* the default comparator is not proper for number comparision. | /* the default comparator is not proper for number comparision. | ||||||
|  * the first different byte decides whice side is greater */ |  * the first different byte decides whice side is greater */ | ||||||
| static int default_comparator (hawk_arr_t* arr,  | int hawk_arr_dflcomp (hawk_arr_t* arr, const void* dptr1, hawk_oow_t dlen1, const void* dptr2, hawk_oow_t dlen2) | ||||||
| 	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)); | 	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; | 	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)); | 		n = (slot_t*)hawk_gem_allocmem(arr->gem, HAWK_SIZEOF(slot_t)); | ||||||
| 		if (HAWK_UNLIKELY(!n)) return HAWK_NULL; | 		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)); | 		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; | 		DPTR(n) = n + 1; | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		n = (slot_t*)hawk_gem_allocmem(arr->gem, HAWK_SIZEOF(slot_t)); | 		n = (slot_t*)hawk_gem_allocmem(arr->gem, HAWK_SIZEOF(slot_t)); | ||||||
| 		if (HAWK_UNLIKELY(!n)) return HAWK_NULL; | 		if (HAWK_UNLIKELY(!n)) return HAWK_NULL; | ||||||
| 		DPTR(n) = arr->copier(arr, dptr, dlen); | 		DPTR(n) = arr->style->copier(arr, dptr, dlen); /* call the custom copier */ | ||||||
| 		if (DPTR(n) == HAWK_NULL)  | 		if (HAWK_UNLIKELY(!DPTR(n)))  | ||||||
| 		{ | 		{ | ||||||
| 			hawk_gem_freemem (arr->gem, n); | 			hawk_gem_freemem (arr->gem, n); | ||||||
| 			return HAWK_NULL; | 			return HAWK_NULL; | ||||||
| @ -122,6 +120,32 @@ void hawk_arr_close (hawk_arr_t* arr) | |||||||
| 	hawk_gem_freemem (arr->gem, 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) | int hawk_arr_init (hawk_arr_t* arr, hawk_gem_t* gem, hawk_oow_t capa) | ||||||
| { | { | ||||||
| 	HAWK_MEMSET (arr, 0, HAWK_SIZEOF(*arr)); | 	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->slot = HAWK_NULL; | ||||||
| 	arr->scale = 1; | 	arr->scale = 1; | ||||||
| 	arr->heap_pos_offset = HAWK_ARR_NIL; | 	arr->heap_pos_offset = HAWK_ARR_NIL; | ||||||
|  | 	arr->style = &style[0]; | ||||||
| 	arr->copier = HAWK_ARR_COPIER_SIMPLE; |  | ||||||
| 	arr->comper = default_comparator; |  | ||||||
|  |  | ||||||
| 	return (hawk_arr_setcapa(arr, capa) == HAWK_NULL)? -1: 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; | 	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; | 	HAWK_ASSERT (style != HAWK_NULL); | ||||||
| 	arr->copier = copier; | 	arr->style = style; | ||||||
| } |  | ||||||
|  |  | ||||||
| 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_oow_t hawk_arr_getsize (hawk_arr_t* arr) | 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++)  | 	for (i = pos; i < arr->size; i++)  | ||||||
| 	{ | 	{ | ||||||
| 		if (arr->slot[i] == HAWK_NULL) continue; | 		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); | 	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; )  | 		for (i = pos + 1; i-- > 0; )  | ||||||
| 		{ | 		{ | ||||||
| 			if (arr->slot[i] == HAWK_NULL) continue; | 			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; | 	slot_t* slot; | ||||||
|  |  | ||||||
| 	/* allocate the slot first */ | 	/* allocate the slot first */ | ||||||
| 	slot = alloc_slot (arr, dptr, dlen); | 	slot = alloc_slot(arr, dptr, dlen); | ||||||
| 	if (slot == HAWK_NULL) return HAWK_ARR_NIL; | 	if (HAWK_UNLIKELY(!slot)) return HAWK_ARR_NIL; | ||||||
|  |  | ||||||
| 	/* do resizeing if necessary.  | 	/* do resizeing if necessary.  | ||||||
| 	 * resizing is performed after slot allocation because that way, it  | 	 * 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 */ | 		/* get the minimum capacity needed */ | ||||||
| 		mincapa = (pos >= arr->size)? (pos + 1): (arr->size + 1); | 		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 | 		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 (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); | 				hawk_gem_freemem (arr->gem, slot); | ||||||
| 				return HAWK_ARR_NIL; | 				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 */ | 		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 */ | 			/* 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_freemem (arr->gem, slot); | ||||||
| 			hawk_gem_seterrnum (arr->gem, HAWK_NULL, HAWK_EBUFFULL); | 			hawk_gem_seterrnum (arr->gem, HAWK_NULL, HAWK_EBUFFULL); | ||||||
| 			return HAWK_ARR_NIL; | 			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)) | 		if (dptr == DPTR(c) && dlen == DLEN(c)) | ||||||
| 		{ | 		{ | ||||||
| 			/* updated to the same data */ | 			/* updated to the same data */ | ||||||
| 			if (arr->keeper) arr->keeper (arr, dptr, dlen); | 			if (arr->style->keeper) arr->style->keeper (arr, dptr, dlen); | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			/* updated to different data */ | 			/* updated to different data */ | ||||||
| 			slot_t* slot = alloc_slot(arr, dptr, dlen); | 			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); | 			hawk_gem_freemem (arr->gem, c); | ||||||
|  |  | ||||||
| 			arr->slot[pos] = slot; | 			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 (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); | 			hawk_gem_freemem (arr->gem, c); | ||||||
| 			arr->slot[i] = HAWK_NULL; | 			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 (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); | 			hawk_gem_freemem (arr->gem, c); | ||||||
| 			arr->slot[i] = HAWK_NULL; | 			arr->slot[i] = HAWK_NULL; | ||||||
| 		} | 		} | ||||||
| @ -486,7 +467,7 @@ void hawk_arr_clear (hawk_arr_t* arr) | |||||||
| 		slot_t* c = arr->slot[i]; | 		slot_t* c = arr->slot[i]; | ||||||
| 		if (c != HAWK_NULL) | 		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); | 			hawk_gem_freemem (arr->gem, c); | ||||||
| 			arr->slot[i] = HAWK_NULL; | 			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; | 		int n; | ||||||
|  |  | ||||||
| 		parent = HEAP_PARENT(index); | 		parent = HEAP_PARENT(index); | ||||||
| 		n = arr->comper (arr, | 		n = arr->style->comper(arr, DPTR(arr->slot[index]), DLEN(arr->slot[index]), DPTR(arr->slot[parent]), DLEN(arr->slot[parent])); | ||||||
| 			DPTR(arr->slot[index]), DLEN(arr->slot[index]), |  | ||||||
| 			DPTR(arr->slot[parent]), DLEN(arr->slot[parent])); |  | ||||||
| 		if (n > 0) | 		if (n > 0) | ||||||
| 		{ | 		{ | ||||||
| 			slot_t* tmp; | 			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; | 				if (index <= 0) break; | ||||||
|  |  | ||||||
| 				n = arr->comper (arr, | 				n = arr->style->comper(arr, DPTR(tmp), DLEN(tmp), DPTR(arr->slot[parent]), DLEN(arr->slot[parent])); | ||||||
| 					DPTR(tmp), DLEN(tmp), |  | ||||||
| 					DPTR(arr->slot[parent]), DLEN(arr->slot[parent])); |  | ||||||
| 				if (n <= 0) break; | 				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) | 			if (right < arr->size) | ||||||
| 			{ | 			{ | ||||||
| 				n = arr->comper (arr, | 				n = arr->style->comper(arr, | ||||||
| 					DPTR(arr->slot[right]), DLEN(arr->slot[right]), | 					DPTR(arr->slot[right]), DLEN(arr->slot[right]), | ||||||
| 					DPTR(arr->slot[left]), DLEN(arr->slot[left])); | 					DPTR(arr->slot[left]), DLEN(arr->slot[left])); | ||||||
| 				child = (n > 0)? right: 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; | 				child = left; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			n = arr->comper (arr, | 			n = arr->style->comper(arr, DPTR(tmp), DLEN(tmp), DPTR(arr->slot[child]), DLEN(arr->slot[child])); | ||||||
| 				DPTR(tmp), DLEN(tmp), |  | ||||||
| 				DPTR(arr->slot[child]), DLEN(arr->slot[child])); |  | ||||||
| 			if (n > 0) break; | 			if (n > 0) break; | ||||||
|  |  | ||||||
| 			arr->slot[index] = arr->slot[child]; | 			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 up if the last item is greater than the item to be deleted, | ||||||
| 		 * move it down otherwise. */ | 		 * move it down otherwise. */ | ||||||
| 		n = arr->comper (arr, | 		n = arr->style->comper(arr, DPTR(arr->slot[index]), DLEN(arr->slot[index]), DPTR(tmp), DLEN(tmp)); | ||||||
| 			DPTR(arr->slot[index]), DLEN(arr->slot[index]), |  | ||||||
| 			DPTR(tmp), DLEN(tmp)); |  | ||||||
| 		if (n > 0) sift_up (arr, index); | 		if (n > 0) sift_up (arr, index); | ||||||
| 		else if (n < 0) sift_down (arr, index); | 		else if (n < 0) sift_down (arr, index); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/* destroy the actual item */ | 	/* 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); | 	hawk_gem_freemem (arr->gem, tmp); | ||||||
|  |  | ||||||
| 	/* empty the last slot */ | 	/* 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]; | 	tmp = arr->slot[index]; | ||||||
| 	HAWK_ASSERT (tmp != HAWK_NULL); | 	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 (n) | ||||||
| 	{ | 	{ | ||||||
| 		if (hawk_arr_update(arr, index, dptr, dlen) == HAWK_ARR_NIL) return HAWK_ARR_NIL; | 		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) | 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 n; | ||||||
| 	int path_flags; | 	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) | 	if (dir->flags & HAWK_DIR_SORT) | ||||||
| 	{ | 	{ | ||||||
| 		dir->stab = hawk_arr_open(gem, 0, 128); | 		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_setscale (dir->stab, 1);*/ | ||||||
| 		hawk_arr_setcopier (dir->stab, HAWK_ARR_COPIER_INLINE); | 		hawk_arr_setstyle (dir->stab, &stab_style); | ||||||
| 		hawk_arr_setcomper (dir->stab, compare_dirent); |  | ||||||
| 		if (read_ahead_and_sort(dir, path) <= -1) goto oops_4; | 		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_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_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_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_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); | 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 */ | 	/* type info/conversion */ | ||||||
| 	{ {HAWK_T("int"),      3}, 0, { {1,     1, HAWK_NULL},        fnc_int,              0 }, HAWK_NULL}, | 	{ {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("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("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}, | 	{ {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); | 	a0 = hawk_rtx_getarg(rtx, 0); | ||||||
|  |  | ||||||
| 	r = hawk_rtx_makeintval(rtx, HAWK_RTX_GETVALTYPE(rtx, a0) == HAWK_VAL_MAP); | 	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); | 	hawk_rtx_setretval (rtx, r); | ||||||
| 	return 0; | 	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_SIMPLE  ((hawk_arr_copier_t)1) | ||||||
| #define HAWK_ARR_COPIER_INLINE  ((hawk_arr_copier_t)2) | #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_NIL ((hawk_oow_t)-1) | ||||||
|  |  | ||||||
| #define HAWK_ARR_SIZE(arr)        (*(const hawk_oow_t*)&(arr)->size) | #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 |  *  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 |  *  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 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 |  *  the contents of the data a user provided into the slot. | ||||||
|  *  hawk_arr_setcopier() function to change the copier.  |  * | ||||||
|  *  |  | ||||||
|  *  A copier should return the pointer to the copied data. If it fails to copy |  *  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 |  *  data, it may return HAWK_NULL. You need to set a proper freeer to free up | ||||||
|  *  memory allocated for copy. |  *  memory allocated for copy. | ||||||
|  */ |  */ | ||||||
| typedef void* (*hawk_arr_copier_t) ( | typedef void* (*hawk_arr_copier_t) ( | ||||||
| 	hawk_arr_t* arr    /**< array */, | 	hawk_arr_t* arr    /**< array */, | ||||||
| 	void*      dptr   /**< pointer to data to copy */, | 	void*       dptr   /**< pointer to data to copy */, | ||||||
| 	hawk_oow_t dlen   /**< length of 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) ( | typedef void (*hawk_arr_freeer_t) ( | ||||||
| 	hawk_arr_t* arr    /**< array */, | 	hawk_arr_t* arr    /**< array */, | ||||||
| 	void*      dptr   /**< pointer to data to free */, | 	void*       dptr   /**< pointer to data to free */, | ||||||
| 	hawk_oow_t dlen   /**< length of 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) ( | typedef int (*hawk_arr_comper_t) ( | ||||||
| 	hawk_arr_t*  arr    /* array */,  | 	hawk_arr_t*  arr    /* array */,  | ||||||
| 	const void* dptr1  /* data pointer */, | 	const void*  dptr1  /* data pointer */, | ||||||
| 	hawk_oow_t  dlen1  /* data length */, | 	hawk_oow_t   dlen1  /* data length */, | ||||||
| 	const void* dptr2  /* data pointer */, | 	const void*  dptr2  /* data pointer */, | ||||||
| 	hawk_oow_t  dlen2  /* data length */ | 	hawk_oow_t   dlen2  /* data length */ | ||||||
| ); | ); | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @ -117,8 +122,8 @@ typedef int (*hawk_arr_comper_t) ( | |||||||
|  */ |  */ | ||||||
| typedef void (*hawk_arr_keeper_t) ( | typedef void (*hawk_arr_keeper_t) ( | ||||||
| 	hawk_arr_t* arr     /**< array */, | 	hawk_arr_t* arr     /**< array */, | ||||||
| 	void* vptr         /**< pointer to a value */, | 	void*       vptr    /**< pointer to a value */, | ||||||
| 	hawk_oow_t vlen    /**< length of 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) ( | typedef hawk_oow_t (*hawk_arr_sizer_t) ( | ||||||
| 	hawk_arr_t* arr,  /**< array */ | 	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) ( | typedef hawk_arr_walk_t (*hawk_arr_walker_t) ( | ||||||
| 	hawk_arr_t*      arr   /* array */, | 	hawk_arr_t*      arr   /* array */, | ||||||
| 	hawk_oow_t      index /* index to the visited slot */, | 	hawk_oow_t       index /* index to the visited slot */, | ||||||
| 	void*           ctx   /* user-defined context */ | 	void*            ctx   /* user-defined context */ | ||||||
| ); | ); | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @ -142,11 +174,7 @@ typedef hawk_arr_walk_t (*hawk_arr_walker_t) ( | |||||||
| struct hawk_arr_t | struct hawk_arr_t | ||||||
| { | { | ||||||
| 	hawk_gem_t*       gem; | 	hawk_gem_t*       gem; | ||||||
| 	hawk_arr_copier_t copier; /* data copier */ | 	const hawk_arr_style_t* style; | ||||||
| 	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 */ |  | ||||||
| 	hawk_uint8_t      scale;  /* scale factor */ | 	hawk_uint8_t      scale;  /* scale factor */ | ||||||
| 	hawk_oow_t        heap_pos_offset; /* offset in the data element where position  | 	hawk_oow_t        heap_pos_offset; /* offset in the data element where position  | ||||||
| 	                                   * is stored when heap operation is performed. */ | 	                                   * is stored when heap operation is performed. */ | ||||||
| @ -167,6 +195,14 @@ struct hawk_arr_slot_t | |||||||
| extern "C" { | extern "C" { | ||||||
| #endif | #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. |  * 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 */ | 	hawk_arr_t* arr   /* array */ | ||||||
| ); | ); | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * The hawk_arr_setcopier() specifies how to clone an element. The special  | HAWK_EXPORT void hawk_arr_setstyle ( | ||||||
|  * copier #HAWK_ARR_COPIER_INLINE copies the data inline to the internal slot. | 	hawk_arr_t*             arr, | ||||||
|  * No freeer is invoked when the slot is freeed. You may set the copier to  | 	const hawk_arr_style_t* style   | ||||||
|  * #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 const hawk_arr_style_t* hawk_arr_getstyle ( | ||||||
|  * The hawk_arr_getfreeer() function returns a custom element destroyer. | 	hawk_arr_t* arr | ||||||
|  */ |  | ||||||
| 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 hawk_oow_t hawk_arr_getsize ( | HAWK_EXPORT hawk_oow_t hawk_arr_getsize ( | ||||||
| @ -475,6 +460,19 @@ HAWK_EXPORT void hawk_arr_setheapposoffset ( | |||||||
| 	hawk_oow_t offset | 	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) | #if defined(__cplusplus) | ||||||
| } | } | ||||||
| #endif | #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_t**)(hawk->parse.gbls + 1) = hawk; | ||||||
| 	hawk_arr_setscale (hawk->parse.gbls, HAWK_SIZEOF(hawk_ooch_t)); | 	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_t**)(hawk->parse.lcls + 1) = hawk; | ||||||
| 	hawk_arr_setscale (hawk->parse.lcls, HAWK_SIZEOF(hawk_ooch_t)); | 	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_t**)(hawk->parse.params + 1) = hawk; | ||||||
| 	hawk_arr_setscale (hawk->parse.params, HAWK_SIZEOF(hawk_ooch_t)); | 	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_t**)(hawk->fnc.user + 1) = hawk; | ||||||
| 	hawk_htb_setstyle (hawk->fnc.user, &fncusercbs); | 	hawk_htb_setstyle (hawk->fnc.user, &fncusercbs); | ||||||
|  | |||||||
| @ -36,6 +36,7 @@ | |||||||
| #include <hawk-htb.h> /* for rtx->named */ | #include <hawk-htb.h> /* for rtx->named */ | ||||||
| #define HAWK_MAP_IS_RBT | #define HAWK_MAP_IS_RBT | ||||||
| #include <hawk-map.h> | #include <hawk-map.h> | ||||||
|  | #include <hawk-arr.h> | ||||||
| #include <stdarg.h> | #include <stdarg.h> | ||||||
|  |  | ||||||
| /** \file | /** \file | ||||||
| @ -272,6 +273,22 @@ struct hawk_val_map_t | |||||||
| }; | }; | ||||||
| typedef struct hawk_val_map_t  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 |  * The hawk_val_ref_t type defines a reference type that is used | ||||||
|  * internally only. The type field is #HAWK_VAL_REF. |  * 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_MBS     = 4, /**< byte array */ | ||||||
| 	HAWK_VAL_FUN     = 5, /**< function pointer */ | 	HAWK_VAL_FUN     = 5, /**< function pointer */ | ||||||
| 	HAWK_VAL_MAP     = 6, /**< map */ | 	HAWK_VAL_MAP     = 6, /**< map */ | ||||||
|  | 	HAWK_VAL_ARR     = 7, /**< array */ | ||||||
|  |  | ||||||
| 	HAWK_VAL_REX     = 7, /**< regular expression */ | 	HAWK_VAL_REX     = 8, /**< regular expression */ | ||||||
| 	HAWK_VAL_REF     = 8  /**< reference to other types */ | 	HAWK_VAL_REF     = 9  /**< reference to other types */ | ||||||
| }; | }; | ||||||
| typedef enum hawk_val_type_t hawk_val_type_t; | 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. |  * The hawk_rtx_makemapval() function creates an empty array value. | ||||||
|  * \return value on success, #HAWK_NULL on failure |  * \return value on success, #HAWK_NULL on failure | ||||||
|  */ |  */ | ||||||
| HAWK_EXPORT hawk_val_t* hawk_rtx_makearrayval ( | HAWK_EXPORT hawk_val_t* hawk_rtx_makearrval ( | ||||||
| 	hawk_rtx_t* rtx | 	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; | 	hawk_val_t* tmp; | ||||||
|  |  | ||||||
| 	tmp = hawk_rtx_makearrayval(rtx); | 	tmp = hawk_rtx_makearrval(rtx, 0); | ||||||
| 	if (HAWK_UNLIKELY(!tmp)) return -1; /* hard failure */ | 	if (HAWK_UNLIKELY(!tmp)) return -1; /* hard failure */ | ||||||
|  |  | ||||||
| /* TODO: take arguments and put them to the map */ | /* 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); | 	d = sys::opendir("/etc", sys::DIR_SORT); | ||||||
|         if (d >= 0) | 	if (d >= 0) | ||||||
|         { | 	{ | ||||||
|                 while (sys::readdir(d,a) > 0) print a; | 		while (sys::readdir(d,a) > 0) print a; | ||||||
|                 sys::closedir(d); | 		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_t* rtx = *(hawk_rtx_t**)hawk_arr_getxtn(arr); | ||||||
| 	hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ENOIMPL); | 	hawk_val_t* v = (hawk_val_t*)dptr; | ||||||
| 	return HAWK_NULL; |  | ||||||
|  | #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)) | 		if (HAWK_LIKELY(!retried)) | ||||||
| 		{ | 		{ | ||||||
| 			/* this map involves non-gc allocatinon, which happens outside gc_calloc_val(). | 			/* 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); | 			hawk_rtx_gc (rtx, HAWK_COUNTOF(rtx->gc.g) - 1); | ||||||
| 			retried = 1; | 			retried = 1; | ||||||
| 			goto retry; | 			goto retry; | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user