1190 lines
		
	
	
		
			40 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1190 lines
		
	
	
		
			40 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|     Copyright (c) 2006-2020 Chung, Hyung-Hwan. All rights reserved.
 | |
| 
 | |
|     Redistribution and use in source and binary forms, with or without
 | |
|     modification, are permitted provided that the following conditions
 | |
|     are met:
 | |
|     1. Redistributions of source code must retain the above copyright
 | |
|        notice, this list of conditions and the following disclaimer.
 | |
|     2. Redistributions in binary form must reproduce the above copyright
 | |
|        notice, this list of conditions and the following disclaimer in the
 | |
|        documentation and/or other materials provided with the distribution.
 | |
| 
 | |
|     THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
 | |
|     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 | |
|     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 | |
|     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 | |
|     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 | |
|     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
|     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
|     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
|     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 | |
|     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
|  */
 | |
| 
 | |
| #ifndef _HAWK_UTL_H_
 | |
| #define _HAWK_UTL_H_
 | |
| 
 | |
| #include <hawk-cmn.h>
 | |
| #include <hawk-str.h>
 | |
| #include <stdarg.h>
 | |
| 
 | |
| #define HAWK_EPOCH_YEAR  (1970)
 | |
| #define HAWK_EPOCH_MON   (1)
 | |
| #define HAWK_EPOCH_DAY   (1)
 | |
| #define HAWK_EPOCH_WDAY  (4)
 | |
| 
 | |
| /* windows specific epoch time */
 | |
| #define HAWK_EPOCH_YEAR_WIN   (1601)
 | |
| #define HAWK_EPOCH_MON_WIN    (1)
 | |
| #define HAWK_EPOCH_DAY_WIN    (1)
 | |
| 
 | |
| /* =========================================================================
 | |
|  * ENDIAN CHANGE OF A CONSTANT
 | |
|  * ========================================================================= */
 | |
| #define HAWK_CONST_BSWAP16(x) \
 | |
| 	((hawk_uint16_t)((((hawk_uint16_t)(x) & ((hawk_uint16_t)0xff << 0)) << 8) | \
 | |
| 	                (((hawk_uint16_t)(x) & ((hawk_uint16_t)0xff << 8)) >> 8)))
 | |
| 
 | |
| #define HAWK_CONST_BSWAP32(x) \
 | |
| 	((hawk_uint32_t)((((hawk_uint32_t)(x) & ((hawk_uint32_t)0xff <<  0)) << 24) | \
 | |
| 	                (((hawk_uint32_t)(x) & ((hawk_uint32_t)0xff <<  8)) <<  8) | \
 | |
| 	                (((hawk_uint32_t)(x) & ((hawk_uint32_t)0xff << 16)) >>  8) | \
 | |
| 	                (((hawk_uint32_t)(x) & ((hawk_uint32_t)0xff << 24)) >> 24)))
 | |
| 
 | |
| #if defined(HAWK_HAVE_UINT64_T)
 | |
| #define HAWK_CONST_BSWAP64(x) \
 | |
| 	((hawk_uint64_t)((((hawk_uint64_t)(x) & ((hawk_uint64_t)0xff <<  0)) << 56) | \
 | |
| 	                (((hawk_uint64_t)(x) & ((hawk_uint64_t)0xff <<  8)) << 40) | \
 | |
| 	                (((hawk_uint64_t)(x) & ((hawk_uint64_t)0xff << 16)) << 24) | \
 | |
| 	                (((hawk_uint64_t)(x) & ((hawk_uint64_t)0xff << 24)) <<  8) | \
 | |
| 	                (((hawk_uint64_t)(x) & ((hawk_uint64_t)0xff << 32)) >>  8) | \
 | |
| 	                (((hawk_uint64_t)(x) & ((hawk_uint64_t)0xff << 40)) >> 24) | \
 | |
| 	                (((hawk_uint64_t)(x) & ((hawk_uint64_t)0xff << 48)) >> 40) | \
 | |
| 	                (((hawk_uint64_t)(x) & ((hawk_uint64_t)0xff << 56)) >> 56)))
 | |
| #endif
 | |
| 
 | |
| #if defined(HAWK_HAVE_UINT128_T)
 | |
| #define HAWK_CONST_BSWAP128(x) \
 | |
| 	((hawk_uint128_t)((((hawk_uint128_t)(x) & ((hawk_uint128_t)0xff << 0)) << 120) | \
 | |
| 	                 (((hawk_uint128_t)(x) & ((hawk_uint128_t)0xff << 8)) << 104) | \
 | |
| 	                 (((hawk_uint128_t)(x) & ((hawk_uint128_t)0xff << 16)) << 88) | \
 | |
| 	                 (((hawk_uint128_t)(x) & ((hawk_uint128_t)0xff << 24)) << 72) | \
 | |
| 	                 (((hawk_uint128_t)(x) & ((hawk_uint128_t)0xff << 32)) << 56) | \
 | |
| 	                 (((hawk_uint128_t)(x) & ((hawk_uint128_t)0xff << 40)) << 40) | \
 | |
| 	                 (((hawk_uint128_t)(x) & ((hawk_uint128_t)0xff << 48)) << 24) | \
 | |
| 	                 (((hawk_uint128_t)(x) & ((hawk_uint128_t)0xff << 56)) << 8) | \
 | |
| 	                 (((hawk_uint128_t)(x) & ((hawk_uint128_t)0xff << 64)) >> 8) | \
 | |
| 	                 (((hawk_uint128_t)(x) & ((hawk_uint128_t)0xff << 72)) >> 24) | \
 | |
| 	                 (((hawk_uint128_t)(x) & ((hawk_uint128_t)0xff << 80)) >> 40) | \
 | |
| 	                 (((hawk_uint128_t)(x) & ((hawk_uint128_t)0xff << 88)) >> 56) | \
 | |
| 	                 (((hawk_uint128_t)(x) & ((hawk_uint128_t)0xff << 96)) >> 72) | \
 | |
| 	                 (((hawk_uint128_t)(x) & ((hawk_uint128_t)0xff << 104)) >> 88) | \
 | |
| 	                 (((hawk_uint128_t)(x) & ((hawk_uint128_t)0xff << 112)) >> 104) | \
 | |
| 	                 (((hawk_uint128_t)(x) & ((hawk_uint128_t)0xff << 120)) >> 120)))
 | |
| #endif
 | |
| 
 | |
| #if defined(HAWK_ENDIAN_LITTLE)
 | |
| 
 | |
| #	if defined(HAWK_HAVE_UINT16_T)
 | |
| #	define HAWK_CONST_NTOH16(x) HAWK_CONST_BSWAP16(x)
 | |
| #	define HAWK_CONST_HTON16(x) HAWK_CONST_BSWAP16(x)
 | |
| #	define HAWK_CONST_HTOBE16(x) HAWK_CONST_BSWAP16(x)
 | |
| #	define HAWK_CONST_HTOLE16(x) (x)
 | |
| #	define HAWK_CONST_BE16TOH(x) HAWK_CONST_BSWAP16(x)
 | |
| #	define HAWK_CONST_LE16TOH(x) (x)
 | |
| #	endif
 | |
| 
 | |
| #	if defined(HAWK_HAVE_UINT32_T)
 | |
| #	define HAWK_CONST_NTOH32(x) HAWK_CONST_BSWAP32(x)
 | |
| #	define HAWK_CONST_HTON32(x) HAWK_CONST_BSWAP32(x)
 | |
| #	define HAWK_CONST_HTOBE32(x) HAWK_CONST_BSWAP32(x)
 | |
| #	define HAWK_CONST_HTOLE32(x) (x)
 | |
| #	define HAWK_CONST_BE32TOH(x) HAWK_CONST_BSWAP32(x)
 | |
| #	define HAWK_CONST_LE32TOH(x) (x)
 | |
| #	endif
 | |
| 
 | |
| #	if defined(HAWK_HAVE_UINT64_T)
 | |
| #	define HAWK_CONST_NTOH64(x) HAWK_CONST_BSWAP64(x)
 | |
| #	define HAWK_CONST_HTON64(x) HAWK_CONST_BSWAP64(x)
 | |
| #	define HAWK_CONST_HTOBE64(x) HAWK_CONST_BSWAP64(x)
 | |
| #	define HAWK_CONST_HTOLE64(x) (x)
 | |
| #	define HAWK_CONST_BE64TOH(x) HAWK_CONST_BSWAP64(x)
 | |
| #	define HAWK_CONST_LE64TOH(x) (x)
 | |
| #	endif
 | |
| 
 | |
| #	if defined(HAWK_HAVE_UINT128_T)
 | |
| #	define HAWK_CONST_NTOH128(x) HAWK_CONST_BSWAP128(x)
 | |
| #	define HAWK_CONST_HTON128(x) HAWK_CONST_BSWAP128(x)
 | |
| #	define HAWK_CONST_HTOBE128(x) HAWK_CONST_BSWAP128(x)
 | |
| #	define HAWK_CONST_HTOLE128(x) (x)
 | |
| #	define HAWK_CONST_BE128TOH(x) HAWK_CONST_BSWAP128(x)
 | |
| #	define HAWK_CONST_LE128TOH(x) (x)
 | |
| #endif
 | |
| 
 | |
| #elif defined(HAWK_ENDIAN_BIG)
 | |
| 
 | |
| #	if defined(HAWK_HAVE_UINT16_T)
 | |
| #	define HAWK_CONST_NTOH16(x) (x)
 | |
| #	define HAWK_CONST_HTON16(x) (x)
 | |
| #	define HAWK_CONST_HTOBE16(x) (x)
 | |
| #	define HAWK_CONST_HTOLE16(x) HAWK_CONST_BSWAP16(x)
 | |
| #	define HAWK_CONST_BE16TOH(x) (x)
 | |
| #	define HAWK_CONST_LE16TOH(x) HAWK_CONST_BSWAP16(x)
 | |
| #	endif
 | |
| 
 | |
| #	if defined(HAWK_HAVE_UINT32_T)
 | |
| #	define HAWK_CONST_NTOH32(x) (x)
 | |
| #	define HAWK_CONST_HTON32(x) (x)
 | |
| #	define HAWK_CONST_HTOBE32(x) (x)
 | |
| #	define HAWK_CONST_HTOLE32(x) HAWK_CONST_BSWAP32(x)
 | |
| #	define HAWK_CONST_BE32TOH(x) (x)
 | |
| #	define HAWK_CONST_LE32TOH(x) HAWK_CONST_BSWAP32(x)
 | |
| #	endif
 | |
| 
 | |
| #	if defined(HAWK_HAVE_UINT64_T)
 | |
| #	define HAWK_CONST_NTOH64(x) (x)
 | |
| #	define HAWK_CONST_HTON64(x) (x)
 | |
| #	define HAWK_CONST_HTOBE64(x) (x)
 | |
| #	define HAWK_CONST_HTOLE64(x) HAWK_CONST_BSWAP64(x)
 | |
| #	define HAWK_CONST_BE64TOH(x) (x)
 | |
| #	define HAWK_CONST_LE64TOH(x) HAWK_CONST_BSWAP64(x)
 | |
| #	endif
 | |
| 
 | |
| #	if defined(HAWK_HAVE_UINT128_T)
 | |
| #	define HAWK_CONST_NTOH128(x) (x)
 | |
| #	define HAWK_CONST_HTON128(x) (x)
 | |
| #	define HAWK_CONST_HTOBE128(x) (x)
 | |
| #	define HAWK_CONST_HTOLE128(x) HAWK_CONST_BSWAP128(x)
 | |
| #	define HAWK_CONST_BE128TOH(x) (x)
 | |
| #	define HAWK_CONST_LE128TOH(x) HAWK_CONST_BSWAP128(x)
 | |
| #	endif
 | |
| 
 | |
| #else
 | |
| #	error UNKNOWN ENDIAN
 | |
| #endif
 | |
| 
 | |
| 
 | |
| /* =========================================================================
 | |
|  * HASH
 | |
|  * ========================================================================= */
 | |
| #if (HAWK_SIZEOF_OOW_T == 4)
 | |
| #	define HAWK_HASH_FNV_MAGIC_INIT (0x811c9dc5)
 | |
| #	define HAWK_HASH_FNV_MAGIC_PRIME (0x01000193)
 | |
| #elif (HAWK_SIZEOF_OOW_T == 8)
 | |
| #	define HAWK_HASH_FNV_MAGIC_INIT (0xCBF29CE484222325)
 | |
| #	define HAWK_HASH_FNV_MAGIC_PRIME (0x100000001B3l)
 | |
| #elif (HAWK_SIZEOF_OOW_T == 16)
 | |
| #	define HAWK_HASH_FNV_MAGIC_INIT (0x6C62272E07BB014262B821756295C58D)
 | |
| #	define HAWK_HASH_FNV_MAGIC_PRIME (0x1000000000000000000013B)
 | |
| #endif
 | |
| 
 | |
| #if defined(HAWK_HASH_FNV_MAGIC_INIT)
 | |
| 	/* FNV-1 hash */
 | |
| #	define HAWK_HASH_INIT HAWK_HASH_FNV_MAGIC_INIT
 | |
| #	define HAWK_HASH_VALUE(hv,v) (((hv) ^ (v)) * HAWK_HASH_FNV_MAGIC_PRIME)
 | |
| 
 | |
| #else
 | |
| 	/* SDBM hash */
 | |
| #	define HAWK_HASH_INIT 0
 | |
| #	define HAWK_HASH_VALUE(hv,v) (((hv) << 6) + ((hv) << 16) - (hv) + (v))
 | |
| #endif
 | |
| 
 | |
| #define HAWK_HASH_VPTL(hv, ptr, len, type) do { \
 | |
| 	hv = HAWK_HASH_INIT; \
 | |
| 	HAWK_HASH_MORE_VPTL (hv, ptr, len, type); \
 | |
| } while(0)
 | |
| 
 | |
| #define HAWK_HASH_MORE_VPTL(hv, ptr, len, type) do { \
 | |
| 	type* __hawk_hash_more_vptl_p = (type*)(ptr); \
 | |
| 	type* __hawk_hash_more_vptl_q = (type*)__hawk_hash_more_vptl_p + (len); \
 | |
| 	while (__hawk_hash_more_vptl_p < __hawk_hash_more_vptl_q) \
 | |
| 	{ \
 | |
| 		hv = HAWK_HASH_VALUE(hv, *__hawk_hash_more_vptl_p); \
 | |
| 		__hawk_hash_more_vptl_p++; \
 | |
| 	} \
 | |
| } while(0)
 | |
| 
 | |
| #define HAWK_HASH_VPTR(hv, ptr, type) do { \
 | |
| 	hv = HAWK_HASH_INIT; \
 | |
| 	HAWK_HASH_MORE_VPTR (hv, ptr, type); \
 | |
| } while(0)
 | |
| 
 | |
| #define HAWK_HASH_MORE_VPTR(hv, ptr, type) do { \
 | |
| 	type* __hawk_hash_more_vptr_p = (type*)(ptr); \
 | |
| 	while (*__hawk_hash_more_vptr_p) \
 | |
| 	{ \
 | |
| 		hv = HAWK_HASH_VALUE(hv, *__hawk_hash_more_vptr_p); \
 | |
| 		__hawk_hash_more_vptr_p++; \
 | |
| 	} \
 | |
| } while(0)
 | |
| 
 | |
| #define HAWK_HASH_BYTES(hv, ptr, len) HAWK_HASH_VPTL(hv, ptr, len, const hawk_uint8_t)
 | |
| #define HAWK_HASH_MORE_BYTES(hv, ptr, len) HAWK_HASH_MORE_VPTL(hv, ptr, len, const hawk_uint8_t)
 | |
| 
 | |
| #define HAWK_HASH_BCHARS(hv, ptr, len) HAWK_HASH_VPTL(hv, ptr, len, const hawk_bch_t)
 | |
| #define HAWK_HASH_MORE_BCHARS(hv, ptr, len) HAWK_HASH_MORE_VPTL(hv, ptr, len, const hawk_bch_t)
 | |
| 
 | |
| #define HAWK_HASH_UCHARS(hv, ptr, len) HAWK_HASH_VPTL(hv, ptr, len, const hawk_uch_t)
 | |
| #define HAWK_HASH_MORE_UCHARS(hv, ptr, len) HAWK_HASH_MORE_VPTL(hv, ptr, len, const hawk_uch_t)
 | |
| 
 | |
| #define HAWK_HASH_BCSTR(hv, ptr) HAWK_HASH_VPTR(hv, ptr, const hawk_bch_t)
 | |
| #define HAWK_HASH_MORE_BCSTR(hv, ptr) HAWK_HASH_MORE_VPTR(hv, ptr, const hawk_bch_t)
 | |
| 
 | |
| #define HAWK_HASH_UCSTR(hv, ptr) HAWK_HASH_VPTR(hv, ptr, const hawk_uch_t)
 | |
| #define HAWK_HASH_MORE_UCSTR(hv, ptr) HAWK_HASH_MORE_VPTR(hv, ptr, const hawk_uch_t)
 | |
| 
 | |
| /* =========================================================================
 | |
|  * CMGR
 | |
|  * ========================================================================= */
 | |
| enum hawk_cmgr_id_t
 | |
| {
 | |
| 	HAWK_CMGR_UTF8,
 | |
| 	HAWK_CMGR_UTF16,
 | |
| 	HAWK_CMGR_MB8
 | |
| };
 | |
| typedef enum hawk_cmgr_id_t hawk_cmgr_id_t;
 | |
| 
 | |
| /* =========================================================================
 | |
|  * QUICK SORT
 | |
|  * ========================================================================= */
 | |
| 
 | |
| /**
 | |
|  * The hawk_sort_comper_t type defines a sort callback function.
 | |
|  * The callback function is called by sort functions for each comparison
 | |
|  * performed. It should return 0 if \a ptr1 and \a ptr2 are
 | |
|  * euqal, a positive integer if \a ptr1 is greater than \a ptr2, a negative
 | |
|  * if \a ptr2 is greater than \a ptr1. Both \a ptr1 and \a ptr2 are
 | |
|  * pointers to any two items in the array. \a ctx which is a pointer to
 | |
|  * user-defined data passed to a sort function is passed to the callback
 | |
|  * with no modification.
 | |
|  */
 | |
| typedef int (*hawk_sort_comper_t) (
 | |
| 	const void* ptr1,
 | |
| 	const void* ptr2,
 | |
| 	void*       ctx
 | |
| );
 | |
| 
 | |
| /**
 | |
|  * The hawk_sort_comperx_t type defines a sort callback function.
 | |
|  * It should return 0 on success and -1 on failure. the comparsion
 | |
|  * result must be put back into the variable pointed to by \a cv.
 | |
|  */
 | |
| typedef int (*hawk_sort_comperx_t) (
 | |
| 	const void* ptr1,
 | |
| 	const void* ptr2,
 | |
| 	void*       ctx,
 | |
| 	int*        cv
 | |
| );
 | |
| 
 | |
| 
 | |
| 
 | |
| /* =========================================================================
 | |
|  * SUBSTITUTION
 | |
|  * ========================================================================= */
 | |
| #define HAWK_SUBST_NOBUF ((void*)1)
 | |
| 
 | |
| /**
 | |
|  * The hawk_subst_ucs_t type defines a callback function for hawk_subst_for_uchars_to_ucstr()
 | |
|  * and hawk_subst_for_ucstr_to_ucstr() to substitue a new value for an identifier \a ident.
 | |
|  */
 | |
| typedef hawk_uch_t* (*hawk_subst_for_ucs_t) (
 | |
| 	hawk_uch_t*       buf,
 | |
| 	hawk_oow_t        bsz,
 | |
| 	const hawk_ucs_t* ident,
 | |
| 	void*             ctx
 | |
| );
 | |
| 
 | |
| /**
 | |
|  * The hawk_subst_bcs_t type defines a callback function for hawk_subst_for_bchars_to_bcstr()
 | |
|  * and hawk_subst_for_bcstr_to_bcstr() to substitue a new value for an identifier \a ident.
 | |
|  */
 | |
| typedef hawk_bch_t* (*hawk_subst_for_bcs_t) (
 | |
| 	hawk_bch_t*       buf,
 | |
| 	hawk_oow_t        bsz,
 | |
| 	const hawk_bcs_t* ident,
 | |
| 	void*             ctx
 | |
| );
 | |
| 
 | |
| #if defined(HAWK_OOCH_IS_UCH)
 | |
| #	define hawk_subst_for_oocs_t hawk_subst_for_ucs_t
 | |
| #else
 | |
| #	define hawk_subst_for_oocs_t hawk_subst_for_bcs_t
 | |
| #endif
 | |
| 
 | |
| #if defined(__cplusplus)
 | |
| extern "C" {
 | |
| #endif
 | |
| 
 | |
| /* =========================================================================
 | |
|  * HASH
 | |
|  * ========================================================================= */
 | |
| #if 0
 | |
| HAWK_EXPORT hawk_oow_t hawk_hash_bytes_ (
 | |
| 	const hawk_oob_t* ptr,
 | |
| 	hawk_oow_t        len
 | |
| );
 | |
| 
 | |
| #if defined(HAWK_HAVE_INLINE)
 | |
| 	static HAWK_INLINE hawk_oow_t hawk_hash_bytes (const hawk_oob_t* ptr, hawk_oow_t len)
 | |
| 	{
 | |
| 		hawk_oow_t hv;
 | |
| 		HAWK_HASH_BYTES (hv, ptr, len);
 | |
| 		/* constrain the hash value to be representable in a small integer
 | |
| 		 * for convenience sake */
 | |
| 		return hv % ((hawk_oow_t)HAWK_SMOOI_MAX + 1);
 | |
| 	}
 | |
| 
 | |
| 	static HAWK_INLINE hawk_oow_t hawk_hash_bchars (const hawk_bch_t* ptr, hawk_oow_t len)
 | |
| 	{
 | |
| 		return hawk_hash_bytes((const hawk_oob_t*)ptr, len * HAWK_SIZEOF(hawk_bch_t));
 | |
| 	}
 | |
| 
 | |
| 	static HAWK_INLINE hawk_oow_t hawk_hash_uchars (const hawk_uch_t* ptr, hawk_oow_t len)
 | |
| 	{
 | |
| 		return hawk_hash_bytes((const hawk_oob_t*)ptr, len * HAWK_SIZEOF(hawk_uch_t));
 | |
| 	}
 | |
| 
 | |
| 	static HAWK_INLINE hawk_oow_t hawk_hash_words (const hawk_oow_t* ptr, hawk_oow_t len)
 | |
| 	{
 | |
| 		return hawk_hash_bytes((const hawk_oob_t*)ptr, len * HAWK_SIZEOF(hawk_oow_t));
 | |
| 	}
 | |
| 
 | |
| 	static HAWK_INLINE hawk_oow_t hawk_hash_halfwords (const hawk_oohw_t* ptr, hawk_oow_t len)
 | |
| 	{
 | |
| 		return hawk_hash_bytes((const hawk_oob_t*)ptr, len * HAWK_SIZEOF(hawk_oohw_t));
 | |
| 	}
 | |
| #else
 | |
| #	define hawk_hash_bytes(ptr,len)     hawk_hash_bytes_(ptr, len)
 | |
| #	define hawk_hash_bchars(ptr,len)    hawk_hash_bytes_((const hawk_oob_t*)(ptr), (len) * HAWK_SIZEOF(hawk_bch_t))
 | |
| #	define hawk_hash_uchars(ptr,len)    hawk_hash_bytes_((const hawk_oob_t*)(ptr), (len) * HAWK_SIZEOF(hawk_uch_t))
 | |
| #	define hawk_hash_words(ptr,len)     hawk_hash_bytes_((const hawk_oob_t*)(ptr), (len) * HAWK_SIZEOF(hawk_oow_t))
 | |
| #	define hawk_hash_halfwords(ptr,len) hawk_hash_bytes_((const hawk_oob_t*)(ptr), (len) * HAWK_SIZEOF(hawk_oohw_t))
 | |
| #endif
 | |
| 
 | |
| #if defined(HAWK_OOCH_IS_UCH)
 | |
| #	define hawk_hash_oochars(ptr,len) hawk_hash_uchars(ptr,len)
 | |
| #else
 | |
| #	define hawk_hash_oochars(ptr,len) hawk_hash_bchars(ptr,len)
 | |
| #endif
 | |
| 
 | |
| #endif
 | |
| 
 | |
| /* =========================================================================
 | |
|  * STRING
 | |
|  * ========================================================================= */
 | |
| 
 | |
| HAWK_EXPORT hawk_oow_t hawk_subst_for_uchars_to_ucstr (
 | |
| 	hawk_uch_t*           buf,
 | |
| 	hawk_oow_t            bsz,
 | |
| 	const hawk_uch_t*     fmt,
 | |
| 	hawk_oow_t            fsz,
 | |
| 	hawk_subst_for_ucs_t  subst,
 | |
| 	void*                 ctx
 | |
| );
 | |
| 
 | |
| HAWK_EXPORT hawk_oow_t hawk_subst_for_bchars_to_bcstr (
 | |
| 	hawk_bch_t*           buf,
 | |
| 	hawk_oow_t            bsz,
 | |
| 	const hawk_bch_t*     fmt,
 | |
| 	hawk_oow_t            fsz,
 | |
| 	hawk_subst_for_bcs_t  subst,
 | |
| 	void*                 ctx
 | |
| );
 | |
| 
 | |
| HAWK_EXPORT hawk_oow_t hawk_subst_for_ucstr_to_ucstr (
 | |
| 	hawk_uch_t*           buf,
 | |
| 	hawk_oow_t            bsz,
 | |
| 	const hawk_uch_t*     fmt,
 | |
| 	hawk_subst_for_ucs_t  subst,
 | |
| 	void*                 ctx
 | |
| );
 | |
| 
 | |
| HAWK_EXPORT hawk_oow_t hawk_subst_for_bcstr_to_bcstr (
 | |
| 	hawk_bch_t*           buf,
 | |
| 	hawk_oow_t            bsz,
 | |
| 	const hawk_bch_t*     fmt,
 | |
| 	hawk_subst_for_bcs_t  subst,
 | |
| 	void*                 ctx
 | |
| );
 | |
| 
 | |
| HAWK_EXPORT void hawk_unescape_ucstr (
 | |
| 	hawk_uch_t* str
 | |
| );
 | |
| 
 | |
| HAWK_EXPORT void hawk_unescape_bcstr (
 | |
| 	hawk_bch_t* str
 | |
| );
 | |
| 
 | |
| #if defined(HAWK_OOCH_IS_UCH)
 | |
| #	define hawk_subst_for_oochars_to_oocstr hawk_subst_for_uchars_to_ucstr
 | |
| #	define hawk_subst_for_oocstr_to_oocstr hawk_subst_for_ucstr_to_ucstr
 | |
| #	define hawk_unescape_oocstr hawk_unescape_ucstr
 | |
| #else
 | |
| #	define hawk_subst_for_oochars_to_oocstr hawk_subst_for_bchars_to_bcstr
 | |
| #	define hawk_subst_for_oocstr_to_oocstr hawk_subst_for_bcstr_to_bcstr
 | |
| #	define hawk_unescape_oocstr hawk_unescape_bcstr
 | |
| #endif
 | |
| 
 | |
| /* ------------------------------------------------------------------------- */
 | |
| 
 | |
| HAWK_EXPORT int hawk_conv_bcstr_to_ucstr_with_cmgr (
 | |
| 	const hawk_bch_t* bcs,
 | |
| 	hawk_oow_t*       bcslen,
 | |
| 	hawk_uch_t*       ucs,
 | |
| 	hawk_oow_t*       ucslen,
 | |
| 	hawk_cmgr_t*      cmgr,
 | |
| 	int               all
 | |
| );
 | |
| 
 | |
| HAWK_EXPORT int hawk_conv_ucstr_to_bcstr_with_cmgr (
 | |
| 	const hawk_uch_t* ucs,
 | |
| 	hawk_oow_t*       ucslen,
 | |
| 	hawk_bch_t*       bcs,
 | |
| 	hawk_oow_t*       bcslen,
 | |
| 	hawk_cmgr_t*      cmgr
 | |
| );
 | |
| 
 | |
| HAWK_EXPORT int hawk_conv_bchars_to_uchars_with_cmgr (
 | |
| 	const hawk_bch_t* bcs,
 | |
| 	hawk_oow_t*       bcslen,
 | |
| 	hawk_uch_t*       ucs,
 | |
| 	hawk_oow_t*       ucslen,
 | |
| 	hawk_cmgr_t*      cmgr,
 | |
| 	int               all
 | |
| );
 | |
| 
 | |
| HAWK_EXPORT int hawk_conv_uchars_to_bchars_with_cmgr (
 | |
| 	const hawk_uch_t* ucs,
 | |
| 	hawk_oow_t*       ucslen,
 | |
| 	hawk_bch_t*       bcs,
 | |
| 	hawk_oow_t*       bcslen,
 | |
| 	hawk_cmgr_t*      cmgr
 | |
| );
 | |
| 
 | |
| HAWK_EXPORT int hawk_conv_bchars_to_uchars_upto_stopper_with_cmgr (
 | |
| 	const hawk_bch_t* bcs,
 | |
| 	hawk_oow_t*       bcslen,
 | |
| 	hawk_uch_t*       ucs,
 | |
| 	hawk_oow_t*       ucslen,
 | |
| 	hawk_uch_t        stopper,
 | |
| 	hawk_cmgr_t*      cmgr
 | |
| );
 | |
| 
 | |
| /* ------------------------------------------------------------------------- */
 | |
| 
 | |
| HAWK_EXPORT hawk_oow_t hawk_int_to_oocstr (
 | |
| 	hawk_int_t         value,
 | |
| 	int                radix,
 | |
| 	const hawk_ooch_t* prefix,
 | |
| 	hawk_ooch_t*       buf,
 | |
| 	hawk_oow_t         size
 | |
| );
 | |
| 
 | |
| #define HAWK_OOCHARS_TO_INT_MAKE_OPTION(ltrim,rtrim,base) (((!!(ltrim)) << 2) | ((!!(rtrim)) << 3) | ((base) << 8))
 | |
| #define HAWK_OOCHARS_TO_INT_GET_OPTION_LTRIM(option) ((option) & 4)
 | |
| #define HAWK_OOCHARS_TO_INT_GET_OPTION_RTRIM(option) ((option) & 8)
 | |
| #define HAWK_OOCHARS_TO_INT_GET_OPTION_BASE(option) ((option) >> 8)
 | |
| 
 | |
| /**
 | |
|  * The hawk_uchars_to_int() function converts a wide character string to an integer.
 | |
|  */
 | |
| HAWK_EXPORT hawk_int_t hawk_uchars_to_int (
 | |
| 	const hawk_uch_t*    str,
 | |
| 	hawk_oow_t           len,
 | |
| 	int                  option,
 | |
| 	const hawk_uch_t**   endptr,
 | |
| 	int*                 is_sober
 | |
| );
 | |
| 
 | |
| /**
 | |
|  * The hawk_bchars_to_int() function converts a multi-byte string to an integer.
 | |
|  */
 | |
| HAWK_EXPORT hawk_int_t hawk_bchars_to_int (
 | |
| 	const hawk_bch_t*    str,
 | |
| 	hawk_oow_t           len,
 | |
| 	int                  option,
 | |
| 	const hawk_bch_t**   endptr,
 | |
| 	int*                 is_sober
 | |
| );
 | |
| 
 | |
| /**
 | |
|  * The hawk_uchars_to_flt() function converts a wide character string to a floating-point
 | |
|  * number.
 | |
|  */
 | |
| HAWK_EXPORT hawk_flt_t hawk_uchars_to_flt (
 | |
| 	const hawk_uch_t*   str,
 | |
| 	hawk_oow_t          len,
 | |
| 	const hawk_uch_t**  endptr,
 | |
| 	int                 stripspc
 | |
| );
 | |
| 
 | |
| /**
 | |
|  * The hawk_bchars_to_flt() function converts a multi-byte string to a floating-point
 | |
|  * number.
 | |
|  */
 | |
| HAWK_EXPORT hawk_flt_t hawk_bchars_to_flt (
 | |
| 	const hawk_bch_t*   str,
 | |
| 	hawk_oow_t          len,
 | |
| 	const hawk_bch_t**  endptr,
 | |
| 	int                 stripspc
 | |
| );
 | |
| 
 | |
| /**
 | |
|  * The hawk_oochars_to_num() function converts a string to a number.
 | |
|  * A numeric string in the valid decimal, hexadecimal(0x), binary(0b),
 | |
|  * octal(0) notation is converted to an integer and it is stored into
 | |
|  * memory pointed to by \a l; A string containng '.', 'E', or 'e' is
 | |
|  * converted to a floating-pointer number and it is stored into memory
 | |
|  * pointed to by \a r. If \a strict is 0, the function takes up to the last
 | |
|  * valid character and never fails. If \a strict is 1, an invalid
 | |
|  * character causes the function to return an error.
 | |
|  *
 | |
|  * \return 0 if converted to an integer,
 | |
|  *         1 if converted to a floating-point number
 | |
|  *         -1 on error.
 | |
|  */
 | |
| #define HAWK_OOCHARS_TO_NUM_MAKE_OPTION(nopartial,reqsober,stripspc,base) (((!!(nopartial)) << 0) | ((!!(reqsober)) << 1) | ((!!(stripspc)) << 2) | ((base) << 8))
 | |
| #define HAWK_OOCHARS_TO_NUM_GET_OPTION_NOPARTIAL(option) ((option) & 1)
 | |
| #define HAWK_OOCHARS_TO_NUM_GET_OPTION_REQSOBER(option) ((option) & 2)
 | |
| #define HAWK_OOCHARS_TO_NUM_GET_OPTION_STRIPSPC(option) ((option) & 4)
 | |
| #define HAWK_OOCHARS_TO_NUM_GET_OPTION_BASE(option) ((option) >> 8)
 | |
| 
 | |
| HAWK_EXPORT int hawk_bchars_to_num (
 | |
| 	int                option,
 | |
| 	const hawk_bch_t*  ptr, /**< points to a string to convert */
 | |
| 	hawk_oow_t         len, /**< number of characters in a string */
 | |
| 	hawk_int_t*        l,   /**< stores a converted integer */
 | |
| 	hawk_flt_t*        r    /**< stores a converted floating-poing number */
 | |
| );
 | |
| 
 | |
| HAWK_EXPORT int hawk_uchars_to_num (
 | |
| 	int                option,
 | |
| 	const hawk_uch_t*  ptr, /**< points to a string to convert */
 | |
| 	hawk_oow_t         len, /**< number of characters in a string */
 | |
| 	hawk_int_t*        l,   /**< stores a converted integer */
 | |
| 	hawk_flt_t*        r    /**< stores a converted floating-poing number */
 | |
| );
 | |
| 
 | |
| #if defined(HAWK_OOCH_IS_UCH)
 | |
| #	define hawk_oochars_to_int hawk_uchars_to_int
 | |
| #	define hawk_oochars_to_flt hawk_uchars_to_flt
 | |
| #	define hawk_oochars_to_num hawk_uchars_to_num
 | |
| #else
 | |
| #	define hawk_oochars_to_int hawk_bchars_to_int
 | |
| #	define hawk_oochars_to_flt hawk_bchars_to_flt
 | |
| #	define hawk_oochars_to_num hawk_bchars_to_num
 | |
| #endif
 | |
| 
 | |
| /* ------------------------------------------------------------------------- */
 | |
| 
 | |
| HAWK_EXPORT int hawk_uchars_to_bin (
 | |
| 	const hawk_uch_t* hex,
 | |
| 	hawk_oow_t        hexlen,
 | |
| 	hawk_uint8_t*     buf,
 | |
| 	hawk_oow_t        buflen
 | |
| );
 | |
| 
 | |
| HAWK_EXPORT int hawk_bchars_to_bin (
 | |
| 	const hawk_bch_t* hex,
 | |
| 	hawk_oow_t        hexlen,
 | |
| 	hawk_uint8_t*     buf,
 | |
| 	hawk_oow_t        buflen
 | |
| );
 | |
| 
 | |
| #if defined(HAWK_OOCH_IS_UCH)
 | |
| #	define hawk_oochars_to_bin hawk_uchars_to_bin
 | |
| #else
 | |
| #	define hawk_oochars_to_bin hawk_bchars_to_bin
 | |
| #endif
 | |
| 
 | |
| /* ------------------------------------------------------------------------- */
 | |
| 
 | |
| HAWK_EXPORT hawk_cmgr_t* hawk_get_cmgr_by_id (
 | |
| 	hawk_cmgr_id_t id
 | |
| );
 | |
| 
 | |
| HAWK_EXPORT hawk_cmgr_t* hawk_get_cmgr_by_bcstr (
 | |
| 	const hawk_bch_t* name
 | |
| );
 | |
| 
 | |
| HAWK_EXPORT hawk_cmgr_t* hawk_get_cmgr_by_ucstr (
 | |
| 	const hawk_uch_t* name
 | |
| );
 | |
| 
 | |
| #if defined(HAWK_OOCH_IS_UCH)
 | |
| #	define hawk_get_cmgr_by_name(name) hawk_get_cmgr_by_ucstr(name)
 | |
| #else
 | |
| #	define hawk_get_cmgr_by_name(name) hawk_get_cmgr_by_bcstr(name)
 | |
| #endif
 | |
| 
 | |
| #define hawk_get_utf8_cmgr() hawk_get_cmgr_by_id(HAWK_CMGR_UTF8)
 | |
| #define hawk_get_utf16_cmgr() hawk_get_cmgr_by_id(HAWK_CMGR_UTF16)
 | |
| #define hawk_get_mb8_cmgr() hawk_get_cmgr_by_id(HAWK_CMGR_MB8)
 | |
| 
 | |
| /* ------------------------------------------------------------------------- */
 | |
| 
 | |
| /**
 | |
|  * The hawk_conv_uchars_to_utf8() function converts a unicode character string \a ucs
 | |
|  * to a UTF8 string and writes it into the buffer pointed to by \a bcs, but
 | |
|  * not more than \a bcslen bytes including the terminating null.
 | |
|  *
 | |
|  * Upon return, \a bcslen is modified to the actual number of bytes written to
 | |
|  * \a bcs excluding the terminating null; \a ucslen is modified to the number of
 | |
|  * wide characters converted.
 | |
|  *
 | |
|  * You may pass #HAWK_NULL for \a bcs to dry-run conversion or to get the
 | |
|  * required buffer size for conversion. -2 is never returned in this case.
 | |
|  *
 | |
|  * \return
 | |
|  * - 0 on full conversion,
 | |
|  * - -1 on no or partial conversion for an illegal character encountered,
 | |
|  * - -2 on no or partial conversion for a small buffer.
 | |
|  *
 | |
|  * \code
 | |
|  *   const hawk_uch_t ucs[] = { 'H', 'e', 'l', 'l', 'o' };
 | |
|  *   hawk_bch_t bcs[10];
 | |
|  *   hawk_oow_t ucslen = 5;
 | |
|  *   hawk_oow_t bcslen = HAWK_COUNTOF(bcs);
 | |
|  *   n = hawk_conv_uchars_to_utf8 (ucs, &ucslen, bcs, &bcslen);
 | |
|  *   if (n <= -1)
 | |
|  *   {
 | |
|  *      // conversion error
 | |
|  *   }
 | |
|  * \endcode
 | |
|  */
 | |
| HAWK_EXPORT int hawk_conv_uchars_to_utf8 (
 | |
| 	const hawk_uch_t*    ucs,
 | |
| 	hawk_oow_t*          ucslen,
 | |
| 	hawk_bch_t*          bcs,
 | |
| 	hawk_oow_t*          bcslen
 | |
| );
 | |
| 
 | |
| /**
 | |
|  * The hawk_conv_utf8_to_uchars() function converts a UTF8 string to a uncide string.
 | |
|  *
 | |
|  * It never returns -2 if \a ucs is #HAWK_NULL.
 | |
|  *
 | |
|  * \code
 | |
|  *  const hawk_bch_t* bcs = "test string";
 | |
|  *  hawk_uch_t ucs[100];
 | |
|  *  hawk_oow_t ucslen = HAWK_COUNTOF(buf), n;
 | |
|  *  hawk_oow_t bcslen = 11;
 | |
|  *  int n;
 | |
|  *  n = hawk_conv_utf8_to_uchars (bcs, &bcslen, ucs, &ucslen);
 | |
|  *  if (n <= -1) { invalid/incomplenete sequence or buffer to small }
 | |
|  * \endcode
 | |
|  *
 | |
|  * The resulting \a ucslen can still be greater than 0 even if the return
 | |
|  * value is negative. The value indiates the number of characters converted
 | |
|  * before the error has occurred.
 | |
|  *
 | |
|  * \return 0 on success.
 | |
|  *         -1 if \a bcs contains an illegal character.
 | |
|  *         -2 if the wide-character string buffer is too small.
 | |
|  *         -3 if \a bcs is not a complete sequence.
 | |
|  */
 | |
| HAWK_EXPORT int hawk_conv_utf8_to_uchars (
 | |
| 	const hawk_bch_t*   bcs,
 | |
| 	hawk_oow_t*         bcslen,
 | |
| 	hawk_uch_t*         ucs,
 | |
| 	hawk_oow_t*         ucslen
 | |
| );
 | |
| 
 | |
| 
 | |
| HAWK_EXPORT int hawk_conv_ucstr_to_utf8 (
 | |
| 	const hawk_uch_t*    ucs,
 | |
| 	hawk_oow_t*          ucslen,
 | |
| 	hawk_bch_t*          bcs,
 | |
| 	hawk_oow_t*          bcslen
 | |
| );
 | |
| 
 | |
| HAWK_EXPORT int hawk_conv_utf8_to_ucs (
 | |
| 	const hawk_bch_t*   bcs,
 | |
| 	hawk_oow_t*         bcslen,
 | |
| 	hawk_uch_t*         ucs,
 | |
| 	hawk_oow_t*         ucslen
 | |
| );
 | |
| 
 | |
| /* ------------------------------------------------------------------------- */
 | |
| 
 | |
| HAWK_EXPORT int hawk_conv_uchars_to_utf16 (
 | |
| 	const hawk_uch_t*    ucs,
 | |
| 	hawk_oow_t*          ucslen,
 | |
| 	hawk_bch_t*          bcs,
 | |
| 	hawk_oow_t*          bcslen
 | |
| );
 | |
| 
 | |
| HAWK_EXPORT int hawk_conv_utf16_to_uchars (
 | |
| 	const hawk_bch_t*   bcs,
 | |
| 	hawk_oow_t*         bcslen,
 | |
| 	hawk_uch_t*         ucs,
 | |
| 	hawk_oow_t*         ucslen
 | |
| );
 | |
| 
 | |
| 
 | |
| HAWK_EXPORT int hawk_conv_ucstr_to_utf16 (
 | |
| 	const hawk_uch_t*    ucs,
 | |
| 	hawk_oow_t*          ucslen,
 | |
| 	hawk_bch_t*          bcs,
 | |
| 	hawk_oow_t*          bcslen
 | |
| );
 | |
| 
 | |
| HAWK_EXPORT int hawk_conv_utf16_to_ucs (
 | |
| 	const hawk_bch_t*   bcs,
 | |
| 	hawk_oow_t*         bcslen,
 | |
| 	hawk_uch_t*         ucs,
 | |
| 	hawk_oow_t*         ucslen
 | |
| );
 | |
| 
 | |
| /* ------------------------------------------------------------------------- */
 | |
| 
 | |
| HAWK_EXPORT int hawk_conv_uchars_to_mb8 (
 | |
| 	const hawk_uch_t*    ucs,
 | |
| 	hawk_oow_t*          ucslen,
 | |
| 	hawk_bch_t*          bcs,
 | |
| 	hawk_oow_t*          bcslen
 | |
| );
 | |
| 
 | |
| HAWK_EXPORT int hawk_conv_mb8_to_uchars (
 | |
| 	const hawk_bch_t*   bcs,
 | |
| 	hawk_oow_t*         bcslen,
 | |
| 	hawk_uch_t*         ucs,
 | |
| 	hawk_oow_t*         ucslen
 | |
| );
 | |
| 
 | |
| HAWK_EXPORT int hawk_conv_ucstr_to_mb8 (
 | |
| 	const hawk_uch_t*    ucs,
 | |
| 	hawk_oow_t*          ucslen,
 | |
| 	hawk_bch_t*          bcs,
 | |
| 	hawk_oow_t*          bcslen
 | |
| );
 | |
| 
 | |
| HAWK_EXPORT int hawk_conv_mb8_to_ucs (
 | |
| 	const hawk_bch_t*   bcs,
 | |
| 	hawk_oow_t*         bcslen,
 | |
| 	hawk_uch_t*         ucs,
 | |
| 	hawk_oow_t*         ucslen
 | |
| );
 | |
| 
 | |
| /* =========================================================================
 | |
|  * PATH STRING
 | |
|  * ========================================================================= */
 | |
| HAWK_EXPORT const hawk_uch_t* hawk_get_base_name_ucstr (
 | |
| 	const hawk_uch_t* path
 | |
| );
 | |
| 
 | |
| HAWK_EXPORT const hawk_bch_t* hawk_get_base_name_bcstr (
 | |
| 	const hawk_bch_t* path
 | |
| );
 | |
| 
 | |
| #if defined(HAWK_OOCH_IS_UCH)
 | |
| #	define hawk_get_base_name_oocstr hawk_get_base_name_ucstr
 | |
| #else
 | |
| #	define hawk_get_base_name_oocstr hawk_get_base_name_bcstr
 | |
| #endif
 | |
| 
 | |
| /* =========================================================================
 | |
|  * BIT SWAP
 | |
|  * ========================================================================= */
 | |
| #if defined(HAWK_HAVE_INLINE)
 | |
| 
 | |
| #if defined(HAWK_HAVE_UINT16_T)
 | |
| static HAWK_INLINE hawk_uint16_t hawk_bswap16 (hawk_uint16_t x)
 | |
| {
 | |
| #if defined(HAWK_HAVE_BUILTIN_BSWAP16)
 | |
| 	return __builtin_bswap16(x);
 | |
| #elif defined(__GNUC__) && (defined(__x86_64) || defined(__amd64) || defined(__i386) || defined(i386))
 | |
| 	__asm__ /*volatile*/ ("xchgb %b0, %h0" : "=Q"(x): "0"(x));
 | |
| 	return x;
 | |
| #elif defined(__GNUC__) && defined(__arm__) && (defined(__ARM_ARCH) && (__ARM_ARCH >= 6))
 | |
| 	__asm__ /*volatile*/ ("rev16 %0, %0" : "+r"(x));
 | |
| 	return x;
 | |
| #else
 | |
| 	return (x << 8) | (x >> 8);
 | |
| #endif
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #if defined(HAWK_HAVE_UINT32_T)
 | |
| static HAWK_INLINE hawk_uint32_t hawk_bswap32 (hawk_uint32_t x)
 | |
| {
 | |
| #if defined(HAWK_HAVE_BUILTIN_BSWAP32)
 | |
| 	return __builtin_bswap32(x);
 | |
| #elif defined(__GNUC__) && (defined(__x86_64) || defined(__amd64) || defined(__i386) || defined(i386))
 | |
| 	__asm__ /*volatile*/ ("bswapl %0" : "=r"(x) : "0"(x));
 | |
| 	return x;
 | |
| #elif defined(__GNUC__) && defined(__aarch64__)
 | |
| 	__asm__ /*volatile*/ ("rev32 %0, %0" : "+r"(x));
 | |
| 	return x;
 | |
| #elif defined(__GNUC__) && defined(__arm__) && (defined(__ARM_ARCH) && (__ARM_ARCH >= 6))
 | |
| 	__asm__ /*volatile*/ ("rev %0, %0" : "+r"(x));
 | |
| 	return x;
 | |
| #elif defined(__GNUC__) && defined(__ARM_ARCH)
 | |
| 	hawk_uint32_t tmp;
 | |
| 	__asm__ /*volatile*/ (
 | |
| 		"eor %1, %0, %0, ror #16\n\t"
 | |
| 		"bic %1, %1, #0x00ff0000\n\t"
 | |
| 		"mov %0, %0, ror #8\n\t"
 | |
| 		"eor %0, %0, %1, lsr #8\n\t"
 | |
| 		:"+r"(x), "=&r"(tmp)
 | |
| 	);
 | |
| 	return x;
 | |
| #else
 | |
| 	return ((x >> 24)) |
 | |
| 	       ((x >>  8) & ((hawk_uint32_t)0xff << 8)) |
 | |
| 	       ((x <<  8) & ((hawk_uint32_t)0xff << 16)) |
 | |
| 	       ((x << 24));
 | |
| #endif
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #if defined(HAWK_HAVE_UINT64_T)
 | |
| static HAWK_INLINE hawk_uint64_t hawk_bswap64 (hawk_uint64_t x)
 | |
| {
 | |
| #if defined(HAWK_HAVE_BUILTIN_BSWAP64)
 | |
| 	return __builtin_bswap64(x);
 | |
| #elif defined(__GNUC__) && (defined(__x86_64) || defined(__amd64))
 | |
| 	__asm__ /*volatile*/ ("bswapq %0" : "=r"(x) : "0"(x));
 | |
| 	return x;
 | |
| #elif defined(__GNUC__) && defined(__aarch64__)
 | |
| 	__asm__ /*volatile*/ ("rev %0, %0" : "+r"(x));
 | |
| 	return x;
 | |
| #else
 | |
| 	return ((x >> 56)) |
 | |
| 	       ((x >> 40) & ((hawk_uint64_t)0xff << 8)) |
 | |
| 	       ((x >> 24) & ((hawk_uint64_t)0xff << 16)) |
 | |
| 	       ((x >>  8) & ((hawk_uint64_t)0xff << 24)) |
 | |
| 	       ((x <<  8) & ((hawk_uint64_t)0xff << 32)) |
 | |
| 	       ((x << 24) & ((hawk_uint64_t)0xff << 40)) |
 | |
| 	       ((x << 40) & ((hawk_uint64_t)0xff << 48)) |
 | |
| 	       ((x << 56));
 | |
| #endif
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #if defined(HAWK_HAVE_UINT128_T)
 | |
| static HAWK_INLINE hawk_uint128_t hawk_bswap128 (hawk_uint128_t x)
 | |
| {
 | |
| #if defined(HAWK_HAVE_BUILTIN_BSWAP128)
 | |
| 	return __builtin_bswap128(x);
 | |
| #else
 | |
| 	return ((x >> 120)) |
 | |
| 	       ((x >> 104) & ((hawk_uint128_t)0xff << 8)) |
 | |
| 	       ((x >>  88) & ((hawk_uint128_t)0xff << 16)) |
 | |
| 	       ((x >>  72) & ((hawk_uint128_t)0xff << 24)) |
 | |
| 	       ((x >>  56) & ((hawk_uint128_t)0xff << 32)) |
 | |
| 	       ((x >>  40) & ((hawk_uint128_t)0xff << 40)) |
 | |
| 	       ((x >>  24) & ((hawk_uint128_t)0xff << 48)) |
 | |
| 	       ((x >>   8) & ((hawk_uint128_t)0xff << 56)) |
 | |
| 	       ((x <<   8) & ((hawk_uint128_t)0xff << 64)) |
 | |
| 	       ((x <<  24) & ((hawk_uint128_t)0xff << 72)) |
 | |
| 	       ((x <<  40) & ((hawk_uint128_t)0xff << 80)) |
 | |
| 	       ((x <<  56) & ((hawk_uint128_t)0xff << 88)) |
 | |
| 	       ((x <<  72) & ((hawk_uint128_t)0xff << 96)) |
 | |
| 	       ((x <<  88) & ((hawk_uint128_t)0xff << 104)) |
 | |
| 	       ((x << 104) & ((hawk_uint128_t)0xff << 112)) |
 | |
| 	       ((x << 120));
 | |
| #endif
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #else
 | |
| 
 | |
| #if defined(HAWK_HAVE_UINT16_T)
 | |
| #	if defined(HAWK_HAVE_BUILTIN_BSWAP16)
 | |
| #	define hawk_bswap16(x) ((hawk_uint16_t)__builtin_bswap16((hawk_uint16_t)(x)))
 | |
| #	else
 | |
| #	define hawk_bswap16(x) ((hawk_uint16_t)(((hawk_uint16_t)(x)) << 8) | (((hawk_uint16_t)(x)) >> 8))
 | |
| #	endif
 | |
| #endif
 | |
| 
 | |
| #if defined(HAWK_HAVE_UINT32_T)
 | |
| #	if defined(HAWK_HAVE_BUILTIN_BSWAP32)
 | |
| #	define hawk_bswap32(x) ((hawk_uint32_t)__builtin_bswap32((hawk_uint32_t)(x)))
 | |
| #	else
 | |
| #	define hawk_bswap32(x) ((hawk_uint32_t)(((((hawk_uint32_t)(x)) >> 24)) | \
 | |
| 	                                      ((((hawk_uint32_t)(x)) >>  8) & ((hawk_uint32_t)0xff << 8)) | \
 | |
| 	                                      ((((hawk_uint32_t)(x)) <<  8) & ((hawk_uint32_t)0xff << 16)) | \
 | |
| 	                                      ((((hawk_uint32_t)(x)) << 24))))
 | |
| #	endif
 | |
| #endif
 | |
| 
 | |
| #if defined(HAWK_HAVE_UINT64_T)
 | |
| #	if defined(HAWK_HAVE_BUILTIN_BSWAP64)
 | |
| #	define hawk_bswap64(x) ((hawk_uint64_t)__builtin_bswap64((hawk_uint64_t)(x)))
 | |
| #	else
 | |
| #	define hawk_bswap64(x) ((hawk_uint64_t)(((((hawk_uint64_t)(x)) >> 56)) | \
 | |
| 	                                      ((((hawk_uint64_t)(x)) >> 40) & ((hawk_uint64_t)0xff << 8)) | \
 | |
| 	                                      ((((hawk_uint64_t)(x)) >> 24) & ((hawk_uint64_t)0xff << 16)) | \
 | |
| 	                                      ((((hawk_uint64_t)(x)) >>  8) & ((hawk_uint64_t)0xff << 24)) | \
 | |
| 	                                      ((((hawk_uint64_t)(x)) <<  8) & ((hawk_uint64_t)0xff << 32)) | \
 | |
| 	                                      ((((hawk_uint64_t)(x)) << 24) & ((hawk_uint64_t)0xff << 40)) | \
 | |
| 	                                      ((((hawk_uint64_t)(x)) << 40) & ((hawk_uint64_t)0xff << 48)) | \
 | |
| 	                                      ((((hawk_uint64_t)(x)) << 56))))
 | |
| #	endif
 | |
| #endif
 | |
| 
 | |
| #if defined(HAWK_HAVE_UINT128_T)
 | |
| #	if defined(HAWK_HAVE_BUILTIN_BSWAP128)
 | |
| #	define hawk_bswap128(x) ((hawk_uint128_t)__builtin_bswap128((hawk_uint128_t)(x)))
 | |
| #	else
 | |
| #	define hawk_bswap128(x) ((hawk_uint128_t)(((((hawk_uint128_t)(x)) >> 120)) |  \
 | |
| 	                                        ((((hawk_uint128_t)(x)) >> 104) & ((hawk_uint128_t)0xff << 8)) | \
 | |
| 	                                        ((((hawk_uint128_t)(x)) >>  88) & ((hawk_uint128_t)0xff << 16)) | \
 | |
| 	                                        ((((hawk_uint128_t)(x)) >>  72) & ((hawk_uint128_t)0xff << 24)) | \
 | |
| 	                                        ((((hawk_uint128_t)(x)) >>  56) & ((hawk_uint128_t)0xff << 32)) | \
 | |
| 	                                        ((((hawk_uint128_t)(x)) >>  40) & ((hawk_uint128_t)0xff << 40)) | \
 | |
| 	                                        ((((hawk_uint128_t)(x)) >>  24) & ((hawk_uint128_t)0xff << 48)) | \
 | |
| 	                                        ((((hawk_uint128_t)(x)) >>   8) & ((hawk_uint128_t)0xff << 56)) | \
 | |
| 	                                        ((((hawk_uint128_t)(x)) <<   8) & ((hawk_uint128_t)0xff << 64)) | \
 | |
| 	                                        ((((hawk_uint128_t)(x)) <<  24) & ((hawk_uint128_t)0xff << 72)) | \
 | |
| 	                                        ((((hawk_uint128_t)(x)) <<  40) & ((hawk_uint128_t)0xff << 80)) | \
 | |
| 	                                        ((((hawk_uint128_t)(x)) <<  56) & ((hawk_uint128_t)0xff << 88)) | \
 | |
| 	                                        ((((hawk_uint128_t)(x)) <<  72) & ((hawk_uint128_t)0xff << 96)) | \
 | |
| 	                                        ((((hawk_uint128_t)(x)) <<  88) & ((hawk_uint128_t)0xff << 104)) | \
 | |
| 	                                        ((((hawk_uint128_t)(x)) << 104) & ((hawk_uint128_t)0xff << 112)) | \
 | |
| 	                                        ((((hawk_uint128_t)(x)) << 120))))
 | |
| #	endif
 | |
| #endif
 | |
| 
 | |
| #endif /* HAWK_HAVE_INLINE */
 | |
| 
 | |
| 
 | |
| #if defined(HAWK_ENDIAN_LITTLE)
 | |
| 
 | |
| #	if defined(HAWK_HAVE_UINT16_T)
 | |
| #	define hawk_hton16(x) hawk_bswap16(x)
 | |
| #	define hawk_ntoh16(x) hawk_bswap16(x)
 | |
| #	define hawk_htobe16(x) hawk_bswap16(x)
 | |
| #	define hawk_be16toh(x) hawk_bswap16(x)
 | |
| #	define hawk_htole16(x) ((hawk_uint16_t)(x))
 | |
| #	define hawk_le16toh(x) ((hawk_uint16_t)(x))
 | |
| #	endif
 | |
| 
 | |
| #	if defined(HAWK_HAVE_UINT32_T)
 | |
| #	define hawk_hton32(x) hawk_bswap32(x)
 | |
| #	define hawk_ntoh32(x) hawk_bswap32(x)
 | |
| #	define hawk_htobe32(x) hawk_bswap32(x)
 | |
| #	define hawk_be32toh(x) hawk_bswap32(x)
 | |
| #	define hawk_htole32(x) ((hawk_uint32_t)(x))
 | |
| #	define hawk_le32toh(x) ((hawk_uint32_t)(x))
 | |
| #	endif
 | |
| 
 | |
| #	if defined(HAWK_HAVE_UINT64_T)
 | |
| #	define hawk_hton64(x) hawk_bswap64(x)
 | |
| #	define hawk_ntoh64(x) hawk_bswap64(x)
 | |
| #	define hawk_htobe64(x) hawk_bswap64(x)
 | |
| #	define hawk_be64toh(x) hawk_bswap64(x)
 | |
| #	define hawk_htole64(x) ((hawk_uint64_t)(x))
 | |
| #	define hawk_le64toh(x) ((hawk_uint64_t)(x))
 | |
| #	endif
 | |
| 
 | |
| #	if defined(HAWK_HAVE_UINT128_T)
 | |
| 
 | |
| #	define hawk_hton128(x) hawk_bswap128(x)
 | |
| #	define hawk_ntoh128(x) hawk_bswap128(x)
 | |
| #	define hawk_htobe128(x) hawk_bswap128(x)
 | |
| #	define hawk_be128toh(x) hawk_bswap128(x)
 | |
| #	define hawk_htole128(x) ((hawk_uint128_t)(x))
 | |
| #	define hawk_le128toh(x) ((hawk_uint128_t)(x))
 | |
| #	endif
 | |
| 
 | |
| #elif defined(HAWK_ENDIAN_BIG)
 | |
| 
 | |
| #	if defined(HAWK_HAVE_UINT16_T)
 | |
| #	define hawk_hton16(x) ((hawk_uint16_t)(x))
 | |
| #	define hawk_ntoh16(x) ((hawk_uint16_t)(x))
 | |
| #	define hawk_htobe16(x) ((hawk_uint16_t)(x))
 | |
| #	define hawk_be16toh(x) ((hawk_uint16_t)(x))
 | |
| #	define hawk_htole16(x) hawk_bswap16(x)
 | |
| #	define hawk_le16toh(x) hawk_bswap16(x)
 | |
| #	endif
 | |
| 
 | |
| #	if defined(HAWK_HAVE_UINT32_T)
 | |
| #	define hawk_hton32(x) ((hawk_uint32_t)(x))
 | |
| #	define hawk_ntoh32(x) ((hawk_uint32_t)(x))
 | |
| #	define hawk_htobe32(x) ((hawk_uint32_t)(x))
 | |
| #	define hawk_be32toh(x) ((hawk_uint32_t)(x))
 | |
| #	define hawk_htole32(x) hawk_bswap32(x)
 | |
| #	define hawk_le32toh(x) hawk_bswap32(x)
 | |
| #	endif
 | |
| 
 | |
| #	if defined(HAWK_HAVE_UINT64_T)
 | |
| #	define hawk_hton64(x) ((hawk_uint64_t)(x))
 | |
| #	define hawk_ntoh64(x) ((hawk_uint64_t)(x))
 | |
| #	define hawk_htobe64(x) ((hawk_uint64_t)(x))
 | |
| #	define hawk_be64toh(x) ((hawk_uint64_t)(x))
 | |
| #	define hawk_htole64(x) hawk_bswap64(x)
 | |
| #	define hawk_le64toh(x) hawk_bswap64(x)
 | |
| #	endif
 | |
| 
 | |
| #	if defined(HAWK_HAVE_UINT128_T)
 | |
| #	define hawk_hton128(x) ((hawk_uint128_t)(x))
 | |
| #	define hawk_ntoh128(x) ((hawk_uint128_t)(x))
 | |
| #	define hawk_htobe128(x) ((hawk_uint128_t)(x))
 | |
| #	define hawk_be128toh(x) ((hawk_uint128_t)(x))
 | |
| #	define hawk_htole128(x) hawk_bswap128(x)
 | |
| #	define hawk_le128toh(x) hawk_bswap128(x)
 | |
| #	endif
 | |
| 
 | |
| #else
 | |
| #	error UNKNOWN ENDIAN
 | |
| #endif
 | |
| 
 | |
| /* =========================================================================
 | |
|  * BIT POSITION
 | |
|  * ========================================================================= */
 | |
| static HAWK_INLINE int hawk_get_pos_of_msb_set_pow2 (hawk_oow_t x)
 | |
| {
 | |
| 	/* the caller must ensure that x is power of 2. if x happens to be zero,
 | |
| 	 * the return value is undefined as each method used may give different result. */
 | |
| #if defined(HAWK_HAVE_BUILTIN_CTZLL) && (HAWK_SIZEOF_OOW_T == HAWK_SIZEOF_LONG_LONG)
 | |
| 	return __builtin_ctzll(x); /* count the number of trailing zeros */
 | |
| #elif defined(HAWK_HAVE_BUILTIN_CTZL) && (HAWK_SIZEOF_OOW_T == HAWK_SIZEOF_LONG)
 | |
| 	return __builtin_ctzl(x); /* count the number of trailing zeros */
 | |
| #elif defined(HAWK_HAVE_BUILTIN_CTZ) && (HAWK_SIZEOF_OOW_T == HAWK_SIZEOF_INT)
 | |
| 	return __builtin_ctz(x); /* count the number of trailing zeros */
 | |
| #elif defined(__GNUC__) && (defined(__x86_64) || defined(__amd64) || defined(__i386) || defined(i386))
 | |
| 	hawk_oow_t pos;
 | |
| 	/* use the Bit Scan Forward instruction */
 | |
| #if 1
 | |
| 	__asm__ volatile (
 | |
| 		"bsf %1,%0\n\t"
 | |
| 		: "=r"(pos) /* output */
 | |
| 		: "r"(x) /* input */
 | |
| 	);
 | |
| #else
 | |
| 	__asm__ volatile (
 | |
| 		"bsf %[X],%[EXP]\n\t"
 | |
| 		: [EXP]"=r"(pos) /* output */
 | |
| 		: [X]"r"(x) /* input */
 | |
| 	);
 | |
| #endif
 | |
| 	return (int)pos;
 | |
| #elif defined(__GNUC__) && defined(__aarch64__) || (defined(__arm__) && (defined(__ARM_ARCH) && (__ARM_ARCH >= 5)))
 | |
| 	hawk_oow_t n;
 | |
| 	/* CLZ is available in ARMv5T and above. there is no instruction to
 | |
| 	 * count trailing zeros or something similar. using RBIT with CLZ
 | |
| 	 * would be good in ARMv6T2 and above to avoid further calculation
 | |
| 	 * afte CLZ */
 | |
| 	__asm__ volatile (
 | |
| 		"clz %0,%1\n\t"
 | |
| 		: "=r"(n) /* output */
 | |
| 		: "r"(x) /* input */
 | |
| 	);
 | |
| 	return (int)(HAWK_OOW_BITS - n - 1);
 | |
| 	/* TODO: PPC - use cntlz, cntlzw, cntlzd, SPARC - use lzcnt, MIPS clz */
 | |
| #else
 | |
| 	int pos = 0;
 | |
| 	while (x >>= 1) pos++;
 | |
| 	return pos;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| static HAWK_INLINE int hawk_get_pos_of_msb_set (hawk_oow_t x)
 | |
| {
 | |
| 	/* x doesn't have to be power of 2. if x is zero, the result is undefined */
 | |
| #if defined(HAWK_HAVE_BUILTIN_CLZLL) && (HAWK_SIZEOF_OOW_T == HAWK_SIZEOF_LONG_LONG)
 | |
| 	return HAWK_OOW_BITS - __builtin_clzll(x) - 1; /* count the number of leading zeros */
 | |
| #elif defined(HAWK_HAVE_BUILTIN_CLZL) && (HAWK_SIZEOF_OOW_T == HAWK_SIZEOF_LONG)
 | |
| 	return HAWK_OOW_BITS - __builtin_clzl(x) - 1; /* count the number of leading zeros */
 | |
| #elif defined(HAWK_HAVE_BUILTIN_CLZ) && (HAWK_SIZEOF_OOW_T == HAWK_SIZEOF_INT)
 | |
| 	return HAWK_OOW_BITS - __builtin_clz(x) - 1; /* count the number of leading zeros */
 | |
| #elif defined(__GNUC__) && (defined(__x86_64) || defined(__amd64) || defined(__i386) || defined(i386))
 | |
| 	/* bit scan reverse. not all x86 CPUs have LZCNT. */
 | |
| 	hawk_oow_t pos;
 | |
| 	__asm__ volatile (
 | |
| 		"bsr %1,%0\n\t"
 | |
| 		: "=r"(pos) /* output */
 | |
| 		: "r"(x) /* input */
 | |
| 	);
 | |
| 	return (int)pos;
 | |
| #elif defined(__GNUC__) && defined(__aarch64__) || (defined(__arm__) && (defined(__ARM_ARCH) && (__ARM_ARCH >= 5)))
 | |
| 	hawk_oow_t n;
 | |
| 	__asm__ volatile (
 | |
| 		"clz %0,%1\n\t"
 | |
| 		: "=r"(n) /* output */
 | |
| 		: "r"(x) /* input */
 | |
| 	);
 | |
| 	return (int)(HAWK_OOW_BITS - n - 1);
 | |
| 	/* TODO: PPC - use cntlz, cntlzw, cntlzd, SPARC - use lzcnt, MIPS clz */
 | |
| #else
 | |
| 	int pos = 0;
 | |
| 	while (x >>= 1) pos++;
 | |
| 	return pos;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| /* =========================================================================
 | |
|  * QUICK SORT
 | |
|  * ========================================================================= */
 | |
| 
 | |
| HAWK_EXPORT void hawk_qsort (
 | |
| 	void*              base,
 | |
| 	hawk_oow_t         nmemb,
 | |
| 	hawk_oow_t         size,
 | |
| 	hawk_sort_comper_t comper,
 | |
| 	void*              ctx
 | |
| );
 | |
| 
 | |
| HAWK_EXPORT int hawk_qsortx (
 | |
| 	void*               base,
 | |
| 	hawk_oow_t          nmemb,
 | |
| 	hawk_oow_t          size,
 | |
| 	hawk_sort_comperx_t comper,
 | |
| 	void*               ctx
 | |
| );
 | |
| 
 | |
| /* =========================================================================
 | |
|  * TIME
 | |
|  * ========================================================================= */
 | |
| HAWK_EXPORT int hawk_get_ntime (
 | |
| 	hawk_ntime_t* t
 | |
| );
 | |
| 
 | |
| HAWK_EXPORT int hawk_set_ntime (
 | |
| 	const hawk_ntime_t* t
 | |
| );
 | |
| 
 | |
| /**
 | |
|  * The hawk_add_ntime() adds two time structures pointed to by x and y and
 | |
|  * stores the result in z. Upon overflow, it sets z to the largest value
 | |
|  * the hawk_ntime_t type can represent. Upon underflow, it sets z to the
 | |
|  * smallest value. If you don't need this extra range check, you may use
 | |
|  * the HAWK_ADD_NTIME() macro.
 | |
|  */
 | |
| HAWK_EXPORT void hawk_add_ntime (
 | |
| 	hawk_ntime_t*       z,
 | |
| 	const hawk_ntime_t* x,
 | |
| 	const hawk_ntime_t* y
 | |
| );
 | |
| 
 | |
| HAWK_EXPORT void hawk_sub_ntime (
 | |
| 	hawk_ntime_t*       z,
 | |
| 	const hawk_ntime_t* x,
 | |
| 	const hawk_ntime_t* y
 | |
| );
 | |
| 
 | |
| /* =========================================================================
 | |
|  * RANDOM NUMBER GENERATOR
 | |
|  * ========================================================================= */
 | |
| HAWK_EXPORT hawk_uint32_t hawk_rand31 (
 | |
| 	hawk_uint32_t seed
 | |
| );
 | |
| 
 | |
| /* =========================================================================
 | |
|  * ASSERTION
 | |
|  * ========================================================================= */
 | |
| HAWK_EXPORT void hawk_assert_fail (
 | |
| 	const hawk_bch_t* expr,
 | |
| 	const hawk_bch_t* file,
 | |
| 	hawk_oow_t line
 | |
| );
 | |
| 
 | |
| #if defined(__cplusplus)
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #endif
 |