diff --git a/hio/lib/Makefile.am b/hio/lib/Makefile.am index bc38f46..2ca425c 100644 --- a/hio/lib/Makefile.am +++ b/hio/lib/Makefile.am @@ -8,7 +8,7 @@ CPPFLAGS_ALL_COMMON = \ CFLAGS_ALL_COMMON = LDFLAGS_ALL_COMMON = -L$(abs_builddir) -L$(libdir) -EXTRA_DIST = utl-str.c.m4 +EXTRA_DIST = hio-utl.h.m4 utl-str.c.m4 ################################################## # MAIN LIBRARY @@ -132,5 +132,9 @@ install-data-hook: uninstall-hook: @rm -f "$(DESTDIR)$(includedir)/hio-cfg.h" -utl-str.c: utl-str.c.m4 - m4 $(abs_srcdir)/utl-str.c.m4 > $(abs_srcdir)/utl-str.c +$(srcdir)/hio-utl.h: utl-str.m4 hio-utl.h.m4 + m4 -I$(srcdir) $(srcdir)/hio-utl.h.m4 > $(srcdir)/hio-utl.h + +utl-str.c: utl-str.m4 utl-str.c.m4 + m4 -I$(srcdir) $(srcdir)/utl-str.c.m4 > $(srcdir)/utl-str.c + diff --git a/hio/lib/Makefile.in b/hio/lib/Makefile.in index f1b0d64..44c4fb5 100644 --- a/hio/lib/Makefile.in +++ b/hio/lib/Makefile.in @@ -426,7 +426,7 @@ CPPFLAGS_ALL_COMMON = \ CFLAGS_ALL_COMMON = LDFLAGS_ALL_COMMON = -L$(abs_builddir) -L$(libdir) -EXTRA_DIST = utl-str.c.m4 +EXTRA_DIST = hio-utl.h.m4 utl-str.c.m4 ################################################## # MAIN LIBRARY @@ -1248,8 +1248,11 @@ install-data-hook: uninstall-hook: @rm -f "$(DESTDIR)$(includedir)/hio-cfg.h" -utl-str.c: utl-str.c.m4 - m4 $(abs_srcdir)/utl-str.c.m4 > $(abs_srcdir)/utl-str.c +$(srcdir)/hio-utl.h: utl-str.m4 hio-utl.h.m4 + m4 -I$(srcdir) $(srcdir)/hio-utl.h.m4 > $(srcdir)/hio-utl.h + +utl-str.c: utl-str.m4 utl-str.c.m4 + m4 -I$(srcdir) $(srcdir)/utl-str.c.m4 > $(srcdir)/utl-str.c # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/hio/lib/hio-utl.h b/hio/lib/hio-utl.h index b79b281..14b5acb 100644 --- a/hio/lib/hio-utl.h +++ b/hio/lib/hio-utl.h @@ -22,12 +22,52 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* + * Do NOT edit hio-utl.h. Edit hio-utl.h.m4 instead. + * + * Generate hio-utl.h.m4 with m4 + * $ m4 hio-utl.h.m4 > hio-utl.h + */ + #ifndef _HIO_UTL_H_ #define _HIO_UTL_H_ #include #include + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /* ========================================================================= * ENDIAN CHANGE OF A CONSTANT * ========================================================================= */ @@ -608,41 +648,53 @@ HIO_EXPORT hio_oow_t hio_byte_to_bcstr ( ); /* ------------------------------------------------------------------------- */ -#define HIO_OOCHARS_TO_INTMAX_MAKE_OPTION(e,ltrim,rtrim,base) (((!!(e)) << 0) | ((!!(ltrim)) << 2) | ((!!(rtrim)) << 3) | ((base) << 8)) -#define HIO_OOCHARS_TO_INTMAX_GET_OPTION_E(option) ((option) & 1) -#define HIO_OOCHARS_TO_INTMAX_GET_OPTION_LTRIM(option) ((option) & 4) -#define HIO_OOCHARS_TO_INTMAX_GET_OPTION_RTRIM(option) ((option) & 8) -#define HIO_OOCHARS_TO_INTMAX_GET_OPTION_BASE(option) ((option) >> 8) +#define HIO_CHARS_TO_INTMAX_MAKE_OPTION(e,ltrim,rtrim,base) (((!!(e)) << 0) | ((!!(ltrim)) << 2) | ((!!(rtrim)) << 3) | ((base) << 8)) +#define HIO_CHARS_TO_INTMAX_GET_OPTION_E(option) ((option) & 1) +#define HIO_CHARS_TO_INTMAX_GET_OPTION_LTRIM(option) ((option) & 4) +#define HIO_CHARS_TO_INTMAX_GET_OPTION_RTRIM(option) ((option) & 8) +#define HIO_CHARS_TO_INTMAX_GET_OPTION_BASE(option) ((option) >> 8) -#define HIO_OOCHARS_TO_UINTMAX_MAKE_OPTION(e,ltrim,rtrim,base) (((!!(e)) << 0) | ((!!(ltrim)) << 2) | ((!!(rtrim)) << 3) | ((base) << 8)) -#define HIO_OOCHARS_TO_UINTMAX_GET_OPTION_E(option) ((option) & 1) -#define HIO_OOCHARS_TO_UINTMAX_GET_OPTION_LTRIM(option) ((option) & 4) -#define HIO_OOCHARS_TO_UINTMAX_GET_OPTION_RTRIM(option) ((option) & 8) -#define HIO_OOCHARS_TO_UINTMAX_GET_OPTION_BASE(option) ((option) >> 8) +#define HIO_CHARS_TO_UINTMAX_MAKE_OPTION(e,ltrim,rtrim,base) (((!!(e)) << 0) | ((!!(ltrim)) << 2) | ((!!(rtrim)) << 3) | ((base) << 8)) +#define HIO_CHARS_TO_UINTMAX_GET_OPTION_E(option) ((option) & 1) +#define HIO_CHARS_TO_UINTMAX_GET_OPTION_LTRIM(option) ((option) & 4) +#define HIO_CHARS_TO_UINTMAX_GET_OPTION_RTRIM(option) ((option) & 8) +#define HIO_CHARS_TO_UINTMAX_GET_OPTION_BASE(option) ((option) >> 8) -#define HIO_UCHARS_TO_INTMAX_MAKE_OPTION(e,ltrim,rtrim,base) HIO_OOCHARS_TO_INTMAX_MAKE_OPTION(e,ltrim,rtrim,base) -#define HIO_UCHARS_TO_INTMAX_GET_OPTION_E(option) HIO_OOCHARS_TO_INTMAX_GET_OPTION_E(option) -#define HIO_UCHARS_TO_INTMAX_GET_OPTION_LTRIM(option) HIO_OOCHARS_TO_INTMAX_GET_OPTION_LTRIM(option) -#define HIO_UCHARS_TO_INTMAX_GET_OPTION_RTRIM(option) HIO_OOCHARS_TO_INTMAX_GET_OPTION_RTRIM(option) -#define HIO_UCHARS_TO_INTMAX_GET_OPTION_BASE(option) HIO_OOCHARS_TO_INTMAX_GET_OPTION_BASE(option) +#define HIO_OOCHARS_TO_INTMAX_MAKE_OPTION(e,ltrim,rtrim,base) HIO_CHARS_TO_INTMAX_MAKE_OPTION(e,ltrim,rtrim,base) +#define HIO_OOCHARS_TO_INTMAX_GET_OPTION_E(option) HIO_CHARS_TO_INTMAX_GET_OPTION_E(option) +#define HIO_OOCHARS_TO_INTMAX_GET_OPTION_LTRIM(option) HIO_CHARS_TO_INTMAX_GET_OPTION_LTRIM(option) +#define HIO_OOCHARS_TO_INTMAX_GET_OPTION_RTRIM(option) HIO_CHARS_TO_INTMAX_GET_OPTION_RTRIM(option) +#define HIO_OOCHARS_TO_INTMAX_GET_OPTION_BASE(option) HIO_CHARS_TO_INTMAX_GET_OPTION_BASE(option) -#define HIO_BCHARS_TO_INTMAX_MAKE_OPTION(e,ltrim,rtrim,base) HIO_OOCHARS_TO_INTMAX_MAKE_OPTION(e,ltrim,rtrim,base) -#define HIO_BCHARS_TO_INTMAX_GET_OPTION_E(option) HIO_OOCHARS_TO_INTMAX_GET_OPTION_E(option) -#define HIO_BCHARS_TO_INTMAX_GET_OPTION_LTRIM(option) HIO_OOCHARS_TO_INTMAX_GET_OPTION_LTRIM(option) -#define HIO_BCHARS_TO_INTMAX_GET_OPTION_RTRIM(option) HIO_OOCHARS_TO_INTMAX_GET_OPTION_RTRIM(option) -#define HIO_BCHARS_TO_INTMAX_GET_OPTION_BASE(option) HIO_OOCHARS_TO_INTMAX_GET_OPTION_BASE(option) +#define HIO_OOCHARS_TO_UINTMAX_MAKE_OPTION(e,ltrim,rtrim,base) HIO_CHARS_TO_UINTMAX_MAKE_OPTION(e,ltrim,rtrim,base) +#define HIO_OOCHARS_TO_UINTMAX_GET_OPTION_E(option) HIO_CHARS_TO_UINTMAX_GET_OPTION_E(option) +#define HIO_OOCHARS_TO_UINTMAX_GET_OPTION_LTRIM(option) HIO_CHARS_TO_UINTMAX_GET_OPTION_LTRIM(option) +#define HIO_OOCHARS_TO_UINTMAX_GET_OPTION_RTRIM(option) HIO_CHARS_TO_UINTMAX_GET_OPTION_RTRIM(option) +#define HIO_OOCHARS_TO_UINTMAX_GET_OPTION_BASE(option) HIO_CHARS_TO_UINTMAX_GET_OPTION_BASE(option) -#define HIO_UCHARS_TO_UINTMAX_MAKE_OPTION(e,ltrim,rtrim,base) HIO_OOCHARS_TO_UINTMAX_MAKE_OPTION(e,ltrim,rtrim,base) -#define HIO_UCHARS_TO_UINTMAX_GET_OPTION_E(option) HIO_OOCHARS_TO_UINTMAX_GET_OPTION_E(option) -#define HIO_UCHARS_TO_UINTMAX_GET_OPTION_LTRIM(option) HIO_OOCHARS_TO_UINTMAX_GET_OPTION_LTRIM(option) -#define HIO_UCHARS_TO_UINTMAX_GET_OPTION_RTRIM(option) HIO_OOCHARS_TO_UINTMAX_GET_OPTION_RTRIM(option) -#define HIO_UCHARS_TO_UINTMAX_GET_OPTION_BASE(option) HIO_OOCHARS_TO_UINTMAX_GET_OPTION_BASE(option) +#define HIO_UCHARS_TO_INTMAX_MAKE_OPTION(e,ltrim,rtrim,base) HIO_CHARS_TO_INTMAX_MAKE_OPTION(e,ltrim,rtrim,base) +#define HIO_UCHARS_TO_INTMAX_GET_OPTION_E(option) HIO_CHARS_TO_INTMAX_GET_OPTION_E(option) +#define HIO_UCHARS_TO_INTMAX_GET_OPTION_LTRIM(option) HIO_CHARS_TO_INTMAX_GET_OPTION_LTRIM(option) +#define HIO_UCHARS_TO_INTMAX_GET_OPTION_RTRIM(option) HIO_CHARS_TO_INTMAX_GET_OPTION_RTRIM(option) +#define HIO_UCHARS_TO_INTMAX_GET_OPTION_BASE(option) HIO_CHARS_TO_INTMAX_GET_OPTION_BASE(option) -#define HIO_BCHARS_TO_UINTMAX_MAKE_OPTION(e,ltrim,rtrim,base) HIO_OOCHARS_TO_UINTMAX_MAKE_OPTION(e,ltrim,rtrim,base) -#define HIO_BCHARS_TO_UINTMAX_GET_OPTION_E(option) HIO_OOCHARS_TO_UINTMAX_GET_OPTION_E(option) -#define HIO_BCHARS_TO_UINTMAX_GET_OPTION_LTRIM(option) HIO_OOCHARS_TO_UINTMAX_GET_OPTION_LTRIM(option) -#define HIO_BCHARS_TO_UINTMAX_GET_OPTION_RTRIM(option) HIO_OOCHARS_TO_UINTMAX_GET_OPTION_RTRIM(option) -#define HIO_BCHARS_TO_UINTMAX_GET_OPTION_BASE(option) HIO_OOCHARS_TO_UINTMAX_GET_OPTION_BASE(option) +#define HIO_BCHARS_TO_INTMAX_MAKE_OPTION(e,ltrim,rtrim,base) HIO_CHARS_TO_INTMAX_MAKE_OPTION(e,ltrim,rtrim,base) +#define HIO_BCHARS_TO_INTMAX_GET_OPTION_E(option) HIO_CHARS_TO_INTMAX_GET_OPTION_E(option) +#define HIO_BCHARS_TO_INTMAX_GET_OPTION_LTRIM(option) HIO_CHARS_TO_INTMAX_GET_OPTION_LTRIM(option) +#define HIO_BCHARS_TO_INTMAX_GET_OPTION_RTRIM(option) HIO_CHARS_TO_INTMAX_GET_OPTION_RTRIM(option) +#define HIO_BCHARS_TO_INTMAX_GET_OPTION_BASE(option) HIO_CHARS_TO_INTMAX_GET_OPTION_BASE(option) + +#define HIO_UCHARS_TO_UINTMAX_MAKE_OPTION(e,ltrim,rtrim,base) HIO_CHARS_TO_UINTMAX_MAKE_OPTION(e,ltrim,rtrim,base) +#define HIO_UCHARS_TO_UINTMAX_GET_OPTION_E(option) HIO_CHARS_TO_UINTMAX_GET_OPTION_E(option) +#define HIO_UCHARS_TO_UINTMAX_GET_OPTION_LTRIM(option) HIO_CHARS_TO_UINTMAX_GET_OPTION_LTRIM(option) +#define HIO_UCHARS_TO_UINTMAX_GET_OPTION_RTRIM(option) HIO_CHARS_TO_UINTMAX_GET_OPTION_RTRIM(option) +#define HIO_UCHARS_TO_UINTMAX_GET_OPTION_BASE(option) HIO_CHARS_TO_UINTMAX_GET_OPTION_BASE(option) + +#define HIO_BCHARS_TO_UINTMAX_MAKE_OPTION(e,ltrim,rtrim,base) HIO_CHARS_TO_UINTMAX_MAKE_OPTION(e,ltrim,rtrim,base) +#define HIO_BCHARS_TO_UINTMAX_GET_OPTION_E(option) HIO_CHARS_TO_UINTMAX_GET_OPTION_E(option) +#define HIO_BCHARS_TO_UINTMAX_GET_OPTION_LTRIM(option) HIO_CHARS_TO_UINTMAX_GET_OPTION_LTRIM(option) +#define HIO_BCHARS_TO_UINTMAX_GET_OPTION_RTRIM(option) HIO_CHARS_TO_UINTMAX_GET_OPTION_RTRIM(option) +#define HIO_BCHARS_TO_UINTMAX_GET_OPTION_BASE(option) HIO_CHARS_TO_UINTMAX_GET_OPTION_BASE(option) HIO_EXPORT hio_intmax_t hio_uchars_to_intmax ( const hio_uch_t* str, @@ -1079,4 +1131,235 @@ HIO_EXPORT void hio_sip_hash_24 ( } #endif +/* Some C++ utilities below */ +#if defined(__cplusplus) +template +INT_TYPE hio_chars_to_uint (const CHAR_TYPE* str, hio_oow_t len, int option, const CHAR_TYPE** endptr, int* is_sober) +{ + INT_TYPE n = 0; + const CHAR_TYPE* p, * pp; + const CHAR_TYPE* end; + hio_oow_t rem; + int digit, negative = 0; + int base = HIO_CHARS_TO_INTMAX_GET_OPTION_BASE(option); + + p = str; + end = str + len; + + if (HIO_CHARS_TO_INTMAX_GET_OPTION_LTRIM(option)) + { + /* strip off leading spaces */ + while (p < end && hio_is_bch_space(*p)) p++; + } + + /* check for a sign */ + while (p < end) + { + if (*p == '-') + { + negative = ~negative; + p++; + } + else if (*p == '+') p++; + else break; + } + + /* check for a binary/octal/hexadecimal notation */ + rem = end - p; + if (base == 0) + { + if (rem >= 1 && *p == '0') + { + p++; + + if (rem == 1) base = 8; + else if (*p == 'x' || *p == 'X') + { + p++; base = 16; + } + else if (*p == 'b' || *p == 'B') + { + p++; base = 2; + } + else base = 8; + } + else base = 10; + } + else if (rem >= 2 && base == 16) + { + if (*p == '0' && + (*(p + 1) == 'x' || *(p + 1) == 'X')) p += 2; + } + else if (rem >= 2 && base == 2) + { + if (*p == '0' && + (*(p + 1) == 'b' || *(p + 1) == 'B')) p += 2; + } + + /* process the digits */ + pp = p; + while (p < end) + { + digit = HIO_ZDIGIT_TO_NUM(*p, base); + if (digit >= base) break; + n = n * base + digit; + p++; + } + + if (HIO_CHARS_TO_INTMAX_GET_OPTION_E(option)) + { + if (*p == 'E' || *p == 'e') + { + INT_TYPE e = 0, i; + int e_neg = 0; + p++; + if (*p == '+') + { + p++; + } + else if (*p == '-') + { + p++; e_neg = 1; + } + while (p < end) + { + digit = HIO_ZDIGIT_TO_NUM(*p, base); + if (digit >= base) break; + e = e * base + digit; + p++; + } + if (e_neg) + for (i = 0; i < e; i++) n /= 10; + else + for (i = 0; i < e; i++) n *= 10; + } + } + + /* base 8: at least a zero digit has been seen. + * other case: p > pp to be able to have at least 1 meaningful digit. */ + if (is_sober) *is_sober = (base == 8 || p > pp); + + if (HIO_CHARS_TO_INTMAX_GET_OPTION_RTRIM(option)) + { + /* consume trailing spaces */ + while (p < end && hio_is_bch_space(*p)) p++; + } + + if (endptr) *endptr = p; + return (negative)? -n: n; +} + +template +UINT_TYPE hio_chars_to_uint (const CHAR_TYPE* str, hio_oow_t len, int option, const CHAR_TYPE** endptr, int* is_sober) +{ + UINT_TYPE n = 0; + const CHAR_TYPE* p, * pp; + const CHAR_TYPE* end; + hio_oow_t rem; + int digit; + int base = HIO_CHARS_TO_UINTMAX_GET_OPTION_BASE(option); + + p = str; + end = str + len; + + if (HIO_CHARS_TO_UINTMAX_GET_OPTION_LTRIM(option)) + { + /* strip off leading spaces */ + while (p < end && hio_is_bch_space(*p)) p++; + } + + /* check for a sign */ + while (p < end) + { + if (*p == '+') p++; + else break; + } + + /* check for a binary/octal/hexadecimal notation */ + rem = end - p; + if (base == 0) + { + if (rem >= 1 && *p == '0') + { + p++; + + if (rem == 1) base = 8; + else if (*p == 'x' || *p == 'X') + { + p++; base = 16; + } + else if (*p == 'b' || *p == 'B') + { + p++; base = 2; + } + else base = 8; + } + else base = 10; + } + else if (rem >= 2 && base == 16) + { + if (*p == '0' && + (*(p + 1) == 'x' || *(p + 1) == 'X')) p += 2; + } + else if (rem >= 2 && base == 2) + { + if (*p == '0' && + (*(p + 1) == 'b' || *(p + 1) == 'B')) p += 2; + } + + /* process the digits */ + pp = p; + while (p < end) + { + digit = HIO_ZDIGIT_TO_NUM(*p, base); + if (digit >= base) break; + n = n * base + digit; + p++; + } + + if (HIO_CHARS_TO_UINTMAX_GET_OPTION_E(option)) + { + if (*p == 'E' || *p == 'e') + { + UINT_TYPE e = 0, i; + int e_neg = 0; + p++; + if (*p == '+') + { + p++; + } + else if (*p == '-') + { + p++; e_neg = 1; + } + while (p < end) + { + digit = HIO_ZDIGIT_TO_NUM(*p, base); + if (digit >= base) break; + e = e * base + digit; + p++; + } + if (e_neg) + for (i = 0; i < e; i++) n /= 10; + else + for (i = 0; i < e; i++) n *= 10; + } + } + + /* base 8: at least a zero digit has been seen. + * other case: p > pp to be able to have at least 1 meaningful digit. */ + if (is_sober) *is_sober = (base == 8 || p > pp); + + if (HIO_CHARS_TO_UINTMAX_GET_OPTION_RTRIM(option)) + { + /* consume trailing spaces */ + while (p < end && hio_is_bch_space(*p)) p++; + } + + if (endptr) *endptr = p; + return n; +} + +#endif + #endif diff --git a/hio/lib/hio-utl.h.m4 b/hio/lib/hio-utl.h.m4 new file mode 100644 index 0000000..7d3a5ff --- /dev/null +++ b/hio/lib/hio-utl.h.m4 @@ -0,0 +1,1111 @@ +/* + Copyright (c) 2016-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. + */ + +/* + * Do NOT edit hio-utl.h. Edit hio-utl.h.m4 instead. + * + * Generate hio-utl.h.m4 with m4 + * $ m4 hio-utl.h.m4 > hio-utl.h + */ + +#ifndef _HIO_UTL_H_ +#define _HIO_UTL_H_ + +#include +#include + +dnl --------------------------------------------------------------------------- +include(`utl-str.m4') +dnl --------------------------------------------------------------------------- + +/* ========================================================================= + * ENDIAN CHANGE OF A CONSTANT + * ========================================================================= */ +#define HIO_CONST_BSWAP16(x) \ + ((hio_uint16_t)((((hio_uint16_t)(x) & ((hio_uint16_t)0xff << 0)) << 8) | \ + (((hio_uint16_t)(x) & ((hio_uint16_t)0xff << 8)) >> 8))) + +#define HIO_CONST_BSWAP32(x) \ + ((hio_uint32_t)((((hio_uint32_t)(x) & ((hio_uint32_t)0xff << 0)) << 24) | \ + (((hio_uint32_t)(x) & ((hio_uint32_t)0xff << 8)) << 8) | \ + (((hio_uint32_t)(x) & ((hio_uint32_t)0xff << 16)) >> 8) | \ + (((hio_uint32_t)(x) & ((hio_uint32_t)0xff << 24)) >> 24))) + +#if defined(HIO_HAVE_UINT64_T) +#define HIO_CONST_BSWAP64(x) \ + ((hio_uint64_t)((((hio_uint64_t)(x) & ((hio_uint64_t)0xff << 0)) << 56) | \ + (((hio_uint64_t)(x) & ((hio_uint64_t)0xff << 8)) << 40) | \ + (((hio_uint64_t)(x) & ((hio_uint64_t)0xff << 16)) << 24) | \ + (((hio_uint64_t)(x) & ((hio_uint64_t)0xff << 24)) << 8) | \ + (((hio_uint64_t)(x) & ((hio_uint64_t)0xff << 32)) >> 8) | \ + (((hio_uint64_t)(x) & ((hio_uint64_t)0xff << 40)) >> 24) | \ + (((hio_uint64_t)(x) & ((hio_uint64_t)0xff << 48)) >> 40) | \ + (((hio_uint64_t)(x) & ((hio_uint64_t)0xff << 56)) >> 56))) +#endif + +#if defined(HIO_HAVE_UINT128_T) +#define HIO_CONST_BSWAP128(x) \ + ((hio_uint128_t)((((hio_uint128_t)(x) & ((hio_uint128_t)0xff << 0)) << 120) | \ + (((hio_uint128_t)(x) & ((hio_uint128_t)0xff << 8)) << 104) | \ + (((hio_uint128_t)(x) & ((hio_uint128_t)0xff << 16)) << 88) | \ + (((hio_uint128_t)(x) & ((hio_uint128_t)0xff << 24)) << 72) | \ + (((hio_uint128_t)(x) & ((hio_uint128_t)0xff << 32)) << 56) | \ + (((hio_uint128_t)(x) & ((hio_uint128_t)0xff << 40)) << 40) | \ + (((hio_uint128_t)(x) & ((hio_uint128_t)0xff << 48)) << 24) | \ + (((hio_uint128_t)(x) & ((hio_uint128_t)0xff << 56)) << 8) | \ + (((hio_uint128_t)(x) & ((hio_uint128_t)0xff << 64)) >> 8) | \ + (((hio_uint128_t)(x) & ((hio_uint128_t)0xff << 72)) >> 24) | \ + (((hio_uint128_t)(x) & ((hio_uint128_t)0xff << 80)) >> 40) | \ + (((hio_uint128_t)(x) & ((hio_uint128_t)0xff << 88)) >> 56) | \ + (((hio_uint128_t)(x) & ((hio_uint128_t)0xff << 96)) >> 72) | \ + (((hio_uint128_t)(x) & ((hio_uint128_t)0xff << 104)) >> 88) | \ + (((hio_uint128_t)(x) & ((hio_uint128_t)0xff << 112)) >> 104) | \ + (((hio_uint128_t)(x) & ((hio_uint128_t)0xff << 120)) >> 120))) +#endif + +#if defined(HIO_ENDIAN_LITTLE) + +# if defined(HIO_HAVE_UINT16_T) +# define HIO_CONST_NTOH16(x) HIO_CONST_BSWAP16(x) +# define HIO_CONST_HTON16(x) HIO_CONST_BSWAP16(x) +# define HIO_CONST_HTOBE16(x) HIO_CONST_BSWAP16(x) +# define HIO_CONST_HTOLE16(x) (x) +# define HIO_CONST_BE16TOH(x) HIO_CONST_BSWAP16(x) +# define HIO_CONST_LE16TOH(x) (x) +# endif + +# if defined(HIO_HAVE_UINT32_T) +# define HIO_CONST_NTOH32(x) HIO_CONST_BSWAP32(x) +# define HIO_CONST_HTON32(x) HIO_CONST_BSWAP32(x) +# define HIO_CONST_HTOBE32(x) HIO_CONST_BSWAP32(x) +# define HIO_CONST_HTOLE32(x) (x) +# define HIO_CONST_BE32TOH(x) HIO_CONST_BSWAP32(x) +# define HIO_CONST_LE32TOH(x) (x) +# endif + +# if defined(HIO_HAVE_UINT64_T) +# define HIO_CONST_NTOH64(x) HIO_CONST_BSWAP64(x) +# define HIO_CONST_HTON64(x) HIO_CONST_BSWAP64(x) +# define HIO_CONST_HTOBE64(x) HIO_CONST_BSWAP64(x) +# define HIO_CONST_HTOLE64(x) (x) +# define HIO_CONST_BE64TOH(x) HIO_CONST_BSWAP64(x) +# define HIO_CONST_LE64TOH(x) (x) +# endif + +# if defined(HIO_HAVE_UINT128_T) +# define HIO_CONST_NTOH128(x) HIO_CONST_BSWAP128(x) +# define HIO_CONST_HTON128(x) HIO_CONST_BSWAP128(x) +# define HIO_CONST_HTOBE128(x) HIO_CONST_BSWAP128(x) +# define HIO_CONST_HTOLE128(x) (x) +# define HIO_CONST_BE128TOH(x) HIO_CONST_BSWAP128(x) +# define HIO_CONST_LE128TOH(x) (x) +#endif + +#elif defined(HIO_ENDIAN_BIG) + +# if defined(HIO_HAVE_UINT16_T) +# define HIO_CONST_NTOH16(x) (x) +# define HIO_CONST_HTON16(x) (x) +# define HIO_CONST_HTOBE16(x) (x) +# define HIO_CONST_HTOLE16(x) HIO_CONST_BSWAP16(x) +# define HIO_CONST_BE16TOH(x) (x) +# define HIO_CONST_LE16TOH(x) HIO_CONST_BSWAP16(x) +# endif + +# if defined(HIO_HAVE_UINT32_T) +# define HIO_CONST_NTOH32(x) (x) +# define HIO_CONST_HTON32(x) (x) +# define HIO_CONST_HTOBE32(x) (x) +# define HIO_CONST_HTOLE32(x) HIO_CONST_BSWAP32(x) +# define HIO_CONST_BE32TOH(x) (x) +# define HIO_CONST_LE32TOH(x) HIO_CONST_BSWAP32(x) +# endif + +# if defined(HIO_HAVE_UINT64_T) +# define HIO_CONST_NTOH64(x) (x) +# define HIO_CONST_HTON64(x) (x) +# define HIO_CONST_HTOBE64(x) (x) +# define HIO_CONST_HTOLE64(x) HIO_CONST_BSWAP64(x) +# define HIO_CONST_BE64TOH(x) (x) +# define HIO_CONST_LE64TOH(x) HIO_CONST_BSWAP64(x) +# endif + +# if defined(HIO_HAVE_UINT128_T) +# define HIO_CONST_NTOH128(x) (x) +# define HIO_CONST_HTON128(x) (x) +# define HIO_CONST_HTOBE128(x) (x) +# define HIO_CONST_HTOLE128(x) HIO_CONST_BSWAP128(x) +# define HIO_CONST_BE128TOH(x) (x) +# define HIO_CONST_LE128TOH(x) HIO_CONST_BSWAP128(x) +# endif + +#else +# error UNKNOWN ENDIAN +#endif + + +/* ========================================================================= + * HASH + * ========================================================================= */ +#if (HIO_SIZEOF_OOW_T == 4) +# define HIO_HASH_FNV_MAGIC_INIT (0x811c9dc5) +# define HIO_HASH_FNV_MAGIC_PRIME (0x01000193) +#elif (HIO_SIZEOF_OOW_T == 8) +# define HIO_HASH_FNV_MAGIC_INIT (0xCBF29CE484222325) +# define HIO_HASH_FNV_MAGIC_PRIME (0x100000001B3l) +#elif (HIO_SIZEOF_OOW_T == 16) +# define HIO_HASH_FNV_MAGIC_INIT (0x6C62272E07BB014262B821756295C58D) +# define HIO_HASH_FNV_MAGIC_PRIME (0x1000000000000000000013B) +#endif + +#if defined(HIO_HASH_FNV_MAGIC_INIT) + /* FNV-1 hash */ +# define HIO_HASH_INIT HIO_HASH_FNV_MAGIC_INIT +# define HIO_HASH_VALUE(hv,v) (((hv) ^ (v)) * HIO_HASH_FNV_MAGIC_PRIME) + +#else + /* SDBM hash */ +# define HIO_HASH_INIT 0 +# define HIO_HASH_VALUE(hv,v) (((hv) << 6) + ((hv) << 16) - (hv) + (v)) +#endif + +#define HIO_HASH_VPTL(hv, ptr, len, type) do { \ + hv = HIO_HASH_INIT; \ + HIO_HASH_MORE_VPTL (hv, ptr, len, type); \ +} while(0) + +#define HIO_HASH_MORE_VPTL(hv, ptr, len, type) do { \ + type* __hio_hash_more_vptl_p = (type*)(ptr); \ + type* __hio_hash_more_vptl_q = (type*)__hio_hash_more_vptl_p + (len); \ + while (__hio_hash_more_vptl_p < __hio_hash_more_vptl_q) \ + { \ + hv = HIO_HASH_VALUE(hv, *__hio_hash_more_vptl_p); \ + __hio_hash_more_vptl_p++; \ + } \ +} while(0) + +#define HIO_HASH_VPTR(hv, ptr, type) do { \ + hv = HIO_HASH_INIT; \ + HIO_HASH_MORE_VPTR (hv, ptr, type); \ +} while(0) + +#define HIO_HASH_MORE_VPTR(hv, ptr, type) do { \ + type* __hio_hash_more_vptr_p = (type*)(ptr); \ + while (*__hio_hash_more_vptr_p) \ + { \ + hv = HIO_HASH_VALUE(hv, *__hio_hash_more_vptr_p); \ + __hio_hash_more_vptr_p++; \ + } \ +} while(0) + +#define HIO_HASH_BYTES(hv, ptr, len) HIO_HASH_VPTL(hv, ptr, len, const hio_uint8_t) +#define HIO_HASH_MORE_BYTES(hv, ptr, len) HIO_HASH_MORE_VPTL(hv, ptr, len, const hio_uint8_t) + +#define HIO_HASH_BCHARS(hv, ptr, len) HIO_HASH_VPTL(hv, ptr, len, const hio_bch_t) +#define HIO_HASH_MORE_BCHARS(hv, ptr, len) HIO_HASH_MORE_VPTL(hv, ptr, len, const hio_bch_t) + +#define HIO_HASH_UCHARS(hv, ptr, len) HIO_HASH_VPTL(hv, ptr, len, const hio_uch_t) +#define HIO_HASH_MORE_UCHARS(hv, ptr, len) HIO_HASH_MORE_VPTL(hv, ptr, len, const hio_uch_t) + +#define HIO_HASH_BCSTR(hv, ptr) HIO_HASH_VPTR(hv, ptr, const hio_bch_t) +#define HIO_HASH_MORE_BCSTR(hv, ptr) HIO_HASH_MORE_VPTR(hv, ptr, const hio_bch_t) + +#define HIO_HASH_UCSTR(hv, ptr) HIO_HASH_VPTR(hv, ptr, const hio_uch_t) +#define HIO_HASH_MORE_UCSTR(hv, ptr) HIO_HASH_MORE_VPTR(hv, ptr, const hio_uch_t) + +/* ========================================================================= + * STRING + * ========================================================================= */ + +enum hio_trim_oochars_flag_t +{ + HIO_TRIM_OOCHARS_LEFT = (1 << 0), /**< trim leading spaces */ +#define HIO_TRIM_OOCHARS_LEFT HIO_TRIM_OOCHARS_LEFT +#define HIO_TRIM_UCHARS_LEFT HIO_TRIM_OOCHARS_LEFT +#define HIO_TRIM_BCHARS_LEFT HIO_TRIM_OOCHARS_LEFT + HIO_TRIM_OOCHARS_RIGHT = (1 << 1) /**< trim trailing spaces */ +#define HIO_TRIM_OOCHARS_RIGHT HIO_TRIM_OOCHARS_RIGHT +#define HIO_TRIM_UCHARS_RIGHT HIO_TRIM_OOCHARS_RIGHT +#define HIO_TRIM_BCHARS_RIGHT HIO_TRIM_OOCHARS_RIGHT +}; + +#if defined(__cplusplus) +extern "C" { +#endif + +HIO_EXPORT hio_oow_t hio_count_ucstr ( + const hio_uch_t* str +); + +HIO_EXPORT hio_oow_t hio_count_bcstr ( + const hio_bch_t* str +); + +/** + * The hio_equal_uchars() function determines equality of two strings + * of the same length \a len. + */ +HIO_EXPORT int hio_equal_uchars ( + const hio_uch_t* str1, + const hio_uch_t* str2, + hio_oow_t len +); + +HIO_EXPORT int hio_equal_bchars ( + const hio_bch_t* str1, + const hio_bch_t* str2, + hio_oow_t len +); + +HIO_EXPORT int hio_comp_uchars ( + const hio_uch_t* str1, + hio_oow_t len1, + const hio_uch_t* str2, + hio_oow_t len2, + int ignorecase +); + +HIO_EXPORT int hio_comp_bchars ( + const hio_bch_t* str1, + hio_oow_t len1, + const hio_bch_t* str2, + hio_oow_t len2, + int ignorecase +); + +HIO_EXPORT int hio_comp_ucstr ( + const hio_uch_t* str1, + const hio_uch_t* str2, + int ignorecase +); + +HIO_EXPORT int hio_comp_bcstr ( + const hio_bch_t* str1, + const hio_bch_t* str2, + int ignorecase +); + +HIO_EXPORT int hio_comp_ucstr_limited ( + const hio_uch_t* str1, + const hio_uch_t* str2, + hio_oow_t maxlen, + int ignorecase +); + +HIO_EXPORT int hio_comp_bcstr_limited ( + const hio_bch_t* str1, + const hio_bch_t* str2, + hio_oow_t maxlen, + int ignorecase +); + +HIO_EXPORT int hio_comp_ucstr_bcstr ( + const hio_uch_t* str1, + const hio_bch_t* str2, + int ignorecase +); + +HIO_EXPORT int hio_comp_uchars_ucstr ( + const hio_uch_t* str1, + hio_oow_t len, + const hio_uch_t* str2, + int ignorecase +); + +HIO_EXPORT int hio_comp_uchars_bcstr ( + const hio_uch_t* str1, + hio_oow_t len, + const hio_bch_t* str2, + int ignorecase +); + +HIO_EXPORT int hio_comp_bchars_bcstr ( + const hio_bch_t* str1, + hio_oow_t len, + const hio_bch_t* str2, + int ignorecase +); + +HIO_EXPORT int hio_comp_bchars_ucstr ( + const hio_bch_t* str1, + hio_oow_t len, + const hio_uch_t* str2, + int ignorecase +); + +HIO_EXPORT void hio_copy_uchars ( + hio_uch_t* dst, + const hio_uch_t* src, + hio_oow_t len +); + +HIO_EXPORT void hio_copy_bchars ( + hio_bch_t* dst, + const hio_bch_t* src, + hio_oow_t len +); + +HIO_EXPORT void hio_copy_bchars_to_uchars ( + hio_uch_t* dst, + const hio_bch_t* src, + hio_oow_t len +); +HIO_EXPORT void hio_copy_uchars_to_bchars ( + hio_bch_t* dst, + const hio_uch_t* src, + hio_oow_t len +); + +HIO_EXPORT hio_oow_t hio_copy_uchars_to_ucstr_unlimited ( + hio_uch_t* dst, + const hio_uch_t* src, + hio_oow_t len +); + +HIO_EXPORT hio_oow_t hio_copy_bchars_to_bcstr_unlimited ( + hio_bch_t* dst, + const hio_bch_t* src, + hio_oow_t len +); + +HIO_EXPORT hio_oow_t hio_copy_ucstr ( + hio_uch_t* dst, + hio_oow_t len, + const hio_uch_t* src +); + +HIO_EXPORT hio_oow_t hio_copy_bcstr ( + hio_bch_t* dst, + hio_oow_t len, + const hio_bch_t* src +); + +HIO_EXPORT hio_oow_t hio_copy_uchars_to_ucstr ( + hio_uch_t* dst, + hio_oow_t dlen, + const hio_uch_t* src, + hio_oow_t slen +); + +HIO_EXPORT hio_oow_t hio_copy_bchars_to_bcstr ( + hio_bch_t* dst, + hio_oow_t dlen, + const hio_bch_t* src, + hio_oow_t slen +); + +HIO_EXPORT hio_oow_t hio_copy_ucstr_unlimited ( + hio_uch_t* dst, + const hio_uch_t* src +); + +HIO_EXPORT hio_oow_t hio_copy_bcstr_unlimited ( + hio_bch_t* dst, + const hio_bch_t* src +); + +HIO_EXPORT hio_oow_t hio_concat_uchars_to_ucstr ( + hio_uch_t* buf, + hio_oow_t bsz, + const hio_uch_t* src, + hio_oow_t len +); + +HIO_EXPORT hio_oow_t hio_concat_bchars_to_bcstr ( + hio_bch_t* buf, + hio_oow_t bsz, + const hio_bch_t* src, + hio_oow_t len +); + +HIO_EXPORT hio_oow_t hio_concat_ucstr ( + hio_uch_t* buf, + hio_oow_t bsz, + const hio_uch_t* src +); + +HIO_EXPORT hio_oow_t hio_concat_bcstr ( + hio_bch_t* buf, + hio_oow_t bsz, + const hio_bch_t* src +); + +HIO_EXPORT void hio_fill_uchars ( + hio_uch_t* dst, + const hio_uch_t ch, + hio_oow_t len +); + +HIO_EXPORT void hio_fill_bchars ( + hio_bch_t* dst, + const hio_bch_t ch, + hio_oow_t len +); + +HIO_EXPORT const hio_bch_t* hio_find_bcstr_word_in_bcstr ( + const hio_bch_t* str, + const hio_bch_t* word, + hio_bch_t extra_delim, + int ignorecase +); + +HIO_EXPORT const hio_uch_t* hio_find_ucstr_word_in_ucstr ( + const hio_uch_t* str, + const hio_uch_t* word, + hio_uch_t extra_delim, + int ignorecase +); + +HIO_EXPORT hio_uch_t* hio_find_uchar ( + const hio_uch_t* ptr, + hio_oow_t len, + hio_uch_t c +); + +HIO_EXPORT hio_bch_t* hio_find_bchar ( + const hio_bch_t* ptr, + hio_oow_t len, + hio_bch_t c +); + +HIO_EXPORT hio_uch_t* hio_rfind_uchar ( + const hio_uch_t* ptr, + hio_oow_t len, + hio_uch_t c +); + +HIO_EXPORT hio_bch_t* hio_rfind_bchar ( + const hio_bch_t* ptr, + hio_oow_t len, + hio_bch_t c +); + +HIO_EXPORT hio_uch_t* hio_find_uchar_in_ucstr ( + const hio_uch_t* ptr, + hio_uch_t c +); + +HIO_EXPORT hio_bch_t* hio_find_bchar_in_bcstr ( + const hio_bch_t* ptr, + hio_bch_t c +); + +HIO_EXPORT hio_uch_t* hio_trim_uchars ( + const hio_uch_t* str, + hio_oow_t* len, + int flags +); + +HIO_EXPORT hio_bch_t* hio_trim_bchars ( + const hio_bch_t* str, + hio_oow_t* len, + int flags +); + +HIO_EXPORT int hio_split_ucstr ( + hio_uch_t* s, + const hio_uch_t* delim, + hio_uch_t lquote, + hio_uch_t rquote, + hio_uch_t escape +); + +HIO_EXPORT int hio_split_bcstr ( + hio_bch_t* s, + const hio_bch_t* delim, + hio_bch_t lquote, + hio_bch_t rquote, + hio_bch_t escape +); + + +#if defined(HIO_OOCH_IS_UCH) +# define hio_count_oocstr hio_count_ucstr +# define hio_equal_oochars hio_equal_uchars +# define hio_comp_oochars hio_comp_uchars +# define hio_comp_oocstr_bcstr hio_comp_ucstr_bcstr +# define hio_comp_oochars_bcstr hio_comp_uchars_bcstr +# define hio_comp_oochars_ucstr hio_comp_uchars_ucstr +# define hio_comp_oochars_oocstr hio_comp_uchars_ucstr +# define hio_comp_oocstr hio_comp_ucstr + +# define hio_copy_oochars hio_copy_uchars +# define hio_copy_bchars_to_oochars hio_copy_bchars_to_uchars +# define hio_copy_oochars_to_bchars hio_copy_uchars_to_bchars +# define hio_copy_uchars_to_oochars hio_copy_uchars +# define hio_copy_oochars_to_uchars hio_copy_uchars + +# define hio_copy_oochars_to_oocstr hio_copy_uchars_to_ucstr +# define hio_copy_oochars_to_oocstr_unlimited hio_copy_uchars_to_ucstr_unlimited +# define hio_copy_oocstr hio_copy_ucstr +# define hio_copy_oocstr_unlimited hio_copy_ucstr_unlimited + +# define hio_concat_oochars_to_ucstr hio_concat_uchars_to_ucstr +# define hio_concat_oocstr hio_concat_ucstr + +# define hio_fill_oochars hio_fill_uchars +# define hio_find_oocstr_word_in_oocstr hio_find_ucstr_word_in_ucstr +# define hio_find_oochar hio_find_uchar +# define hio_rfind_oochar hio_rfind_uchar +# define hio_find_oochar_in_oocstr hio_find_uchar_in_ucstr + +# define hio_trim_oochars hio_trim_uchars +# define hio_split_oocstr hio_split_ucstr +#else +# define hio_count_oocstr hio_count_bcstr +# define hio_equal_oochars hio_equal_bchars +# define hio_comp_oochars hio_comp_bchars +# define hio_comp_oocstr_bcstr hio_comp_bcstr +# define hio_comp_oochars_bcstr hio_comp_bchars_bcstr +# define hio_comp_oochars_ucstr hio_comp_bchars_ucstr +# define hio_comp_oochars_oocstr hio_comp_bchars_bcstr +# define hio_comp_oocstr hio_comp_bcstr + +# define hio_copy_oochars hio_copy_bchars +# define hio_copy_bchars_to_oochars hio_copy_bchars +# define hio_copy_oochars_to_bchars hio_copy_bchars +# define hio_copy_uchars_to_oochars hio_copy_uchars_to_bchars +# define hio_copy_oochars_to_uchars hio_copy_bchars_to_uchars + +# define hio_copy_oochars_to_oocstr hio_copy_bchars_to_bcstr +# define hio_copy_oochars_to_oocstr_unlimited hio_copy_bchars_to_bcstr_unlimited +# define hio_copy_oocstr hio_copy_bcstr +# define hio_copy_oocstr_unlimited hio_copy_bcstr_unlimited + +# define hio_concat_oochars_to_bcstr hio_concat_bchars_to_bcstr +# define hio_concat_oocstr hio_concat_bcstr + +# define hio_fill_oochars hio_fill_bchars +# define hio_find_oocstr_word_in_oocstr hio_find_bcstr_word_in_bcstr +# define hio_find_oochar hio_find_bchar +# define hio_rfind_oochar hio_rfind_bchar +# define hio_find_oochar_in_oocstr hio_find_bchar_in_bcstr + +# define hio_trim_oochars hio_trim_bchars +# define hio_split_oocstr hio_split_bcstr +#endif +/* ------------------------------------------------------------------------- */ + +#define HIO_BYTE_TO_BCSTR_RADIXMASK (0xFF) +#define HIO_BYTE_TO_BCSTR_LOWERCASE (1 << 8) + +HIO_EXPORT hio_oow_t hio_byte_to_bcstr ( + hio_uint8_t byte, + hio_bch_t* buf, + hio_oow_t size, + int flagged_radix, + hio_bch_t fill +); + +/* ------------------------------------------------------------------------- */ +#define HIO_CHARS_TO_INTMAX_MAKE_OPTION(e,ltrim,rtrim,base) (((!!(e)) << 0) | ((!!(ltrim)) << 2) | ((!!(rtrim)) << 3) | ((base) << 8)) +#define HIO_CHARS_TO_INTMAX_GET_OPTION_E(option) ((option) & 1) +#define HIO_CHARS_TO_INTMAX_GET_OPTION_LTRIM(option) ((option) & 4) +#define HIO_CHARS_TO_INTMAX_GET_OPTION_RTRIM(option) ((option) & 8) +#define HIO_CHARS_TO_INTMAX_GET_OPTION_BASE(option) ((option) >> 8) + +#define HIO_CHARS_TO_UINTMAX_MAKE_OPTION(e,ltrim,rtrim,base) (((!!(e)) << 0) | ((!!(ltrim)) << 2) | ((!!(rtrim)) << 3) | ((base) << 8)) +#define HIO_CHARS_TO_UINTMAX_GET_OPTION_E(option) ((option) & 1) +#define HIO_CHARS_TO_UINTMAX_GET_OPTION_LTRIM(option) ((option) & 4) +#define HIO_CHARS_TO_UINTMAX_GET_OPTION_RTRIM(option) ((option) & 8) +#define HIO_CHARS_TO_UINTMAX_GET_OPTION_BASE(option) ((option) >> 8) + +#define HIO_OOCHARS_TO_INTMAX_MAKE_OPTION(e,ltrim,rtrim,base) HIO_CHARS_TO_INTMAX_MAKE_OPTION(e,ltrim,rtrim,base) +#define HIO_OOCHARS_TO_INTMAX_GET_OPTION_E(option) HIO_CHARS_TO_INTMAX_GET_OPTION_E(option) +#define HIO_OOCHARS_TO_INTMAX_GET_OPTION_LTRIM(option) HIO_CHARS_TO_INTMAX_GET_OPTION_LTRIM(option) +#define HIO_OOCHARS_TO_INTMAX_GET_OPTION_RTRIM(option) HIO_CHARS_TO_INTMAX_GET_OPTION_RTRIM(option) +#define HIO_OOCHARS_TO_INTMAX_GET_OPTION_BASE(option) HIO_CHARS_TO_INTMAX_GET_OPTION_BASE(option) + +#define HIO_OOCHARS_TO_UINTMAX_MAKE_OPTION(e,ltrim,rtrim,base) HIO_CHARS_TO_UINTMAX_MAKE_OPTION(e,ltrim,rtrim,base) +#define HIO_OOCHARS_TO_UINTMAX_GET_OPTION_E(option) HIO_CHARS_TO_UINTMAX_GET_OPTION_E(option) +#define HIO_OOCHARS_TO_UINTMAX_GET_OPTION_LTRIM(option) HIO_CHARS_TO_UINTMAX_GET_OPTION_LTRIM(option) +#define HIO_OOCHARS_TO_UINTMAX_GET_OPTION_RTRIM(option) HIO_CHARS_TO_UINTMAX_GET_OPTION_RTRIM(option) +#define HIO_OOCHARS_TO_UINTMAX_GET_OPTION_BASE(option) HIO_CHARS_TO_UINTMAX_GET_OPTION_BASE(option) + +#define HIO_UCHARS_TO_INTMAX_MAKE_OPTION(e,ltrim,rtrim,base) HIO_CHARS_TO_INTMAX_MAKE_OPTION(e,ltrim,rtrim,base) +#define HIO_UCHARS_TO_INTMAX_GET_OPTION_E(option) HIO_CHARS_TO_INTMAX_GET_OPTION_E(option) +#define HIO_UCHARS_TO_INTMAX_GET_OPTION_LTRIM(option) HIO_CHARS_TO_INTMAX_GET_OPTION_LTRIM(option) +#define HIO_UCHARS_TO_INTMAX_GET_OPTION_RTRIM(option) HIO_CHARS_TO_INTMAX_GET_OPTION_RTRIM(option) +#define HIO_UCHARS_TO_INTMAX_GET_OPTION_BASE(option) HIO_CHARS_TO_INTMAX_GET_OPTION_BASE(option) + +#define HIO_BCHARS_TO_INTMAX_MAKE_OPTION(e,ltrim,rtrim,base) HIO_CHARS_TO_INTMAX_MAKE_OPTION(e,ltrim,rtrim,base) +#define HIO_BCHARS_TO_INTMAX_GET_OPTION_E(option) HIO_CHARS_TO_INTMAX_GET_OPTION_E(option) +#define HIO_BCHARS_TO_INTMAX_GET_OPTION_LTRIM(option) HIO_CHARS_TO_INTMAX_GET_OPTION_LTRIM(option) +#define HIO_BCHARS_TO_INTMAX_GET_OPTION_RTRIM(option) HIO_CHARS_TO_INTMAX_GET_OPTION_RTRIM(option) +#define HIO_BCHARS_TO_INTMAX_GET_OPTION_BASE(option) HIO_CHARS_TO_INTMAX_GET_OPTION_BASE(option) + +#define HIO_UCHARS_TO_UINTMAX_MAKE_OPTION(e,ltrim,rtrim,base) HIO_CHARS_TO_UINTMAX_MAKE_OPTION(e,ltrim,rtrim,base) +#define HIO_UCHARS_TO_UINTMAX_GET_OPTION_E(option) HIO_CHARS_TO_UINTMAX_GET_OPTION_E(option) +#define HIO_UCHARS_TO_UINTMAX_GET_OPTION_LTRIM(option) HIO_CHARS_TO_UINTMAX_GET_OPTION_LTRIM(option) +#define HIO_UCHARS_TO_UINTMAX_GET_OPTION_RTRIM(option) HIO_CHARS_TO_UINTMAX_GET_OPTION_RTRIM(option) +#define HIO_UCHARS_TO_UINTMAX_GET_OPTION_BASE(option) HIO_CHARS_TO_UINTMAX_GET_OPTION_BASE(option) + +#define HIO_BCHARS_TO_UINTMAX_MAKE_OPTION(e,ltrim,rtrim,base) HIO_CHARS_TO_UINTMAX_MAKE_OPTION(e,ltrim,rtrim,base) +#define HIO_BCHARS_TO_UINTMAX_GET_OPTION_E(option) HIO_CHARS_TO_UINTMAX_GET_OPTION_E(option) +#define HIO_BCHARS_TO_UINTMAX_GET_OPTION_LTRIM(option) HIO_CHARS_TO_UINTMAX_GET_OPTION_LTRIM(option) +#define HIO_BCHARS_TO_UINTMAX_GET_OPTION_RTRIM(option) HIO_CHARS_TO_UINTMAX_GET_OPTION_RTRIM(option) +#define HIO_BCHARS_TO_UINTMAX_GET_OPTION_BASE(option) HIO_CHARS_TO_UINTMAX_GET_OPTION_BASE(option) + +HIO_EXPORT hio_intmax_t hio_uchars_to_intmax ( + const hio_uch_t* str, + hio_oow_t len, + int option, + const hio_uch_t** endptr, + int* is_sober +); + +HIO_EXPORT hio_intmax_t hio_bchars_to_intmax ( + const hio_bch_t* str, + hio_oow_t len, + int option, + const hio_bch_t** endptr, + int* is_sober +); + +HIO_EXPORT hio_uintmax_t hio_uchars_to_uintmax ( + const hio_uch_t* str, + hio_oow_t len, + int option, + const hio_uch_t** endptr, + int* is_sober +); + +HIO_EXPORT hio_uintmax_t hio_bchars_to_uintmax ( + const hio_bch_t* str, + hio_oow_t len, + int option, + const hio_bch_t** endptr, + int* is_sober +); +#if defined(HIO_OOCH_IS_UCH) +# define hio_oochars_to_intmax hio_uchars_to_intmax +# define hio_oochars_to_uintmax hio_uchars_to_uintmax +#else +# define hio_oochars_to_intmax hio_bchars_to_intmax +# define hio_oochars_to_uintmax hio_bchars_to_uintmax +#endif + +/* ------------------------------------------------------------------------- */ + +#if defined(HIO_OOCH_IS_UCH) +# define hio_conv_oocstr_to_bcstr_with_cmgr(oocs,oocslen,bcs,bcslen,cmgr) hio_conv_ucstr_to_bcstr_with_cmgr(oocs,oocslen,bcs,bcslen,cmgr) +# define hio_conv_oochars_to_bchars_with_cmgr(oocs,oocslen,bcs,bcslen,cmgr) hio_conv_uchars_to_bchars_with_cmgr(oocs,oocslen,bcs,bcslen,cmgr) +#else +# define hio_conv_oocstr_to_ucstr_with_cmgr(oocs,oocslen,ucs,ucslen,cmgr) hio_conv_bcstr_to_ucstr_with_cmgr(oocs,oocslen,ucs,ucslen,cmgr,0) +# define hio_conv_oochars_to_uchars_with_cmgr(oocs,oocslen,ucs,ucslen,cmgr) hio_conv_bchars_to_uchars_with_cmgr(oocs,oocslen,ucs,ucslen,cmgr,0) +#endif + + +HIO_EXPORT int hio_conv_bcstr_to_ucstr_with_cmgr ( + const hio_bch_t* bcs, + hio_oow_t* bcslen, + hio_uch_t* ucs, + hio_oow_t* ucslen, + hio_cmgr_t* cmgr, + int all +); + +HIO_EXPORT int hio_conv_bchars_to_uchars_with_cmgr ( + const hio_bch_t* bcs, + hio_oow_t* bcslen, + hio_uch_t* ucs, + hio_oow_t* ucslen, + hio_cmgr_t* cmgr, + int all +); + +HIO_EXPORT int hio_conv_ucstr_to_bcstr_with_cmgr ( + const hio_uch_t* ucs, + hio_oow_t* ucslen, + hio_bch_t* bcs, + hio_oow_t* bcslen, + hio_cmgr_t* cmgr +); + +HIO_EXPORT int hio_conv_uchars_to_bchars_with_cmgr ( + const hio_uch_t* ucs, + hio_oow_t* ucslen, + hio_bch_t* bcs, + hio_oow_t* bcslen, + hio_cmgr_t* cmgr +); + +/* ------------------------------------------------------------------------- */ + +HIO_EXPORT hio_cmgr_t* hio_get_utf8_cmgr ( + void +); + +/** + * The hio_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 #HIO_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 hio_uch_t ucs[] = { 'H', 'e', 'l', 'l', 'o' }; + * hio_bch_t bcs[10]; + * hio_oow_t ucslen = 5; + * hio_oow_t bcslen = HIO_COUNTOF(bcs); + * n = hio_conv_uchars_to_utf8 (ucs, &ucslen, bcs, &bcslen); + * if (n <= -1) + * { + * // conversion error + * } + * \endcode + */ +HIO_EXPORT int hio_conv_uchars_to_utf8 ( + const hio_uch_t* ucs, + hio_oow_t* ucslen, + hio_bch_t* bcs, + hio_oow_t* bcslen +); + +/** + * The hio_conv_utf8_to_uchars() function converts a UTF8 string to a uncide string. + * + * It never returns -2 if \a ucs is #HIO_NULL. + * + * \code + * const hio_bch_t* bcs = "test string"; + * hio_uch_t ucs[100]; + * hio_oow_t ucslen = HIO_COUNTOF(buf), n; + * hio_oow_t bcslen = 11; + * int n; + * n = hio_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. + */ +HIO_EXPORT int hio_conv_utf8_to_uchars ( + const hio_bch_t* bcs, + hio_oow_t* bcslen, + hio_uch_t* ucs, + hio_oow_t* ucslen +); + + +HIO_EXPORT int hio_conv_ucstr_to_utf8 ( + const hio_uch_t* ucs, + hio_oow_t* ucslen, + hio_bch_t* bcs, + hio_oow_t* bcslen +); + +HIO_EXPORT int hio_conv_utf8_to_ucstr ( + const hio_bch_t* bcs, + hio_oow_t* bcslen, + hio_uch_t* ucs, + hio_oow_t* ucslen +); + + +HIO_EXPORT hio_oow_t hio_uc_to_utf8 ( + hio_uch_t uc, + hio_bch_t* utf8, + hio_oow_t size +); + +HIO_EXPORT hio_oow_t hio_utf8_to_uc ( + const hio_bch_t* utf8, + hio_oow_t size, + hio_uch_t* uc +); + +/* ========================================================================= + * TIME CALCULATION WITH OVERFLOW/UNDERFLOW DETECTION + * ========================================================================= */ + +/** + * The hio_add_ntime() function adds two time structures pointed to by \a x and \a y + * and stores the result in the structure pointed to by \a z. If it detects overflow/ + * underflow, it stores the largest/least possible value respectively. + * You may use the HIO_ADD_NTIME() macro if overflow/underflow check isn't needed. + */ +HIO_EXPORT void hio_add_ntime ( + hio_ntime_t* z, + const hio_ntime_t* x, + const hio_ntime_t* y +); + +/** + * The hio_sub_ntime() function subtracts the time value \a y from the time value \a x + * and stores the result in the structure pointed to by \a z. If it detects overflow/ + * underflow, it stores the largest/least possible value respectively. + * You may use the HIO_SUB_NTIME() macro if overflow/underflow check isn't needed. + */ +HIO_EXPORT void hio_sub_ntime ( + hio_ntime_t* z, + const hio_ntime_t* x, + const hio_ntime_t* y +); + + +/* ========================================================================= + * BIT SWAP + * ========================================================================= */ +#if defined(HIO_HAVE_INLINE) + +#if defined(HIO_HAVE_UINT16_T) +static HIO_INLINE hio_uint16_t hio_bswap16 (hio_uint16_t x) +{ +#if defined(HIO_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; +#else + return (x << 8) | (x >> 8); +#endif +} +#endif + +#if defined(HIO_HAVE_UINT32_T) +static HIO_INLINE hio_uint32_t hio_bswap32 (hio_uint32_t x) +{ +#if defined(HIO_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; +#else + return ((x >> 24)) | + ((x >> 8) & ((hio_uint32_t)0xff << 8)) | + ((x << 8) & ((hio_uint32_t)0xff << 16)) | + ((x << 24)); +#endif +} +#endif + +#if defined(HIO_HAVE_UINT64_T) +static HIO_INLINE hio_uint64_t hio_bswap64 (hio_uint64_t x) +{ +#if defined(HIO_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; +#else + return ((x >> 56)) | + ((x >> 40) & ((hio_uint64_t)0xff << 8)) | + ((x >> 24) & ((hio_uint64_t)0xff << 16)) | + ((x >> 8) & ((hio_uint64_t)0xff << 24)) | + ((x << 8) & ((hio_uint64_t)0xff << 32)) | + ((x << 24) & ((hio_uint64_t)0xff << 40)) | + ((x << 40) & ((hio_uint64_t)0xff << 48)) | + ((x << 56)); +#endif +} +#endif + +#if defined(HIO_HAVE_UINT128_T) +static HIO_INLINE hio_uint128_t hio_bswap128 (hio_uint128_t x) +{ + return ((x >> 120)) | + ((x >> 104) & ((hio_uint128_t)0xff << 8)) | + ((x >> 88) & ((hio_uint128_t)0xff << 16)) | + ((x >> 72) & ((hio_uint128_t)0xff << 24)) | + ((x >> 56) & ((hio_uint128_t)0xff << 32)) | + ((x >> 40) & ((hio_uint128_t)0xff << 40)) | + ((x >> 24) & ((hio_uint128_t)0xff << 48)) | + ((x >> 8) & ((hio_uint128_t)0xff << 56)) | + ((x << 8) & ((hio_uint128_t)0xff << 64)) | + ((x << 24) & ((hio_uint128_t)0xff << 72)) | + ((x << 40) & ((hio_uint128_t)0xff << 80)) | + ((x << 56) & ((hio_uint128_t)0xff << 88)) | + ((x << 72) & ((hio_uint128_t)0xff << 96)) | + ((x << 88) & ((hio_uint128_t)0xff << 104)) | + ((x << 104) & ((hio_uint128_t)0xff << 112)) | + ((x << 120)); +} +#endif + +#else + +#if defined(HIO_HAVE_UINT16_T) +# define hio_bswap16(x) ((hio_uint16_t)(((hio_uint16_t)(x)) << 8) | (((hio_uint16_t)(x)) >> 8)) +#endif + +#if defined(HIO_HAVE_UINT32_T) +# define hio_bswap32(x) ((hio_uint32_t)(((((hio_uint32_t)(x)) >> 24)) | \ + ((((hio_uint32_t)(x)) >> 8) & ((hio_uint32_t)0xff << 8)) | \ + ((((hio_uint32_t)(x)) << 8) & ((hio_uint32_t)0xff << 16)) | \ + ((((hio_uint32_t)(x)) << 24)))) +#endif + +#if defined(HIO_HAVE_UINT64_T) +# define hio_bswap64(x) ((hio_uint64_t)(((((hio_uint64_t)(x)) >> 56)) | \ + ((((hio_uint64_t)(x)) >> 40) & ((hio_uint64_t)0xff << 8)) | \ + ((((hio_uint64_t)(x)) >> 24) & ((hio_uint64_t)0xff << 16)) | \ + ((((hio_uint64_t)(x)) >> 8) & ((hio_uint64_t)0xff << 24)) | \ + ((((hio_uint64_t)(x)) << 8) & ((hio_uint64_t)0xff << 32)) | \ + ((((hio_uint64_t)(x)) << 24) & ((hio_uint64_t)0xff << 40)) | \ + ((((hio_uint64_t)(x)) << 40) & ((hio_uint64_t)0xff << 48)) | \ + ((((hio_uint64_t)(x)) << 56)))) +#endif + +#if defined(HIO_HAVE_UINT128_T) +# define hio_bswap128(x) ((hio_uint128_t)(((((hio_uint128_t)(x)) >> 120)) | \ + ((((hio_uint128_t)(x)) >> 104) & ((hio_uint128_t)0xff << 8)) | \ + ((((hio_uint128_t)(x)) >> 88) & ((hio_uint128_t)0xff << 16)) | \ + ((((hio_uint128_t)(x)) >> 72) & ((hio_uint128_t)0xff << 24)) | \ + ((((hio_uint128_t)(x)) >> 56) & ((hio_uint128_t)0xff << 32)) | \ + ((((hio_uint128_t)(x)) >> 40) & ((hio_uint128_t)0xff << 40)) | \ + ((((hio_uint128_t)(x)) >> 24) & ((hio_uint128_t)0xff << 48)) | \ + ((((hio_uint128_t)(x)) >> 8) & ((hio_uint128_t)0xff << 56)) | \ + ((((hio_uint128_t)(x)) << 8) & ((hio_uint128_t)0xff << 64)) | \ + ((((hio_uint128_t)(x)) << 24) & ((hio_uint128_t)0xff << 72)) | \ + ((((hio_uint128_t)(x)) << 40) & ((hio_uint128_t)0xff << 80)) | \ + ((((hio_uint128_t)(x)) << 56) & ((hio_uint128_t)0xff << 88)) | \ + ((((hio_uint128_t)(x)) << 72) & ((hio_uint128_t)0xff << 96)) | \ + ((((hio_uint128_t)(x)) << 88) & ((hio_uint128_t)0xff << 104)) | \ + ((((hio_uint128_t)(x)) << 104) & ((hio_uint128_t)0xff << 112)) | \ + ((((hio_uint128_t)(x)) << 120)))) +#endif + +#endif /* HIO_HAVE_INLINE */ + + +#if defined(HIO_ENDIAN_LITTLE) + +# if defined(HIO_HAVE_UINT16_T) +# define hio_hton16(x) hio_bswap16(x) +# define hio_ntoh16(x) hio_bswap16(x) +# define hio_htobe16(x) hio_bswap16(x) +# define hio_be16toh(x) hio_bswap16(x) +# define hio_htole16(x) ((hio_uint16_t)(x)) +# define hio_le16toh(x) ((hio_uint16_t)(x)) +# endif + +# if defined(HIO_HAVE_UINT32_T) +# define hio_hton32(x) hio_bswap32(x) +# define hio_ntoh32(x) hio_bswap32(x) +# define hio_htobe32(x) hio_bswap32(x) +# define hio_be32toh(x) hio_bswap32(x) +# define hio_htole32(x) ((hio_uint32_t)(x)) +# define hio_le32toh(x) ((hio_uint32_t)(x)) +# endif + +# if defined(HIO_HAVE_UINT64_T) +# define hio_hton64(x) hio_bswap64(x) +# define hio_ntoh64(x) hio_bswap64(x) +# define hio_htobe64(x) hio_bswap64(x) +# define hio_be64toh(x) hio_bswap64(x) +# define hio_htole64(x) ((hio_uint64_t)(x)) +# define hio_le64toh(x) ((hio_uint64_t)(x)) +# endif + +# if defined(HIO_HAVE_UINT128_T) + +# define hio_hton128(x) hio_bswap128(x) +# define hio_ntoh128(x) hio_bswap128(x) +# define hio_htobe128(x) hio_bswap128(x) +# define hio_be128toh(x) hio_bswap128(x) +# define hio_htole128(x) ((hio_uint128_t)(x)) +# define hio_le128toh(x) ((hio_uint128_t)(x)) +# endif + +#elif defined(HIO_ENDIAN_BIG) + +# if defined(HIO_HAVE_UINT16_T) +# define hio_hton16(x) ((hio_uint16_t)(x)) +# define hio_ntoh16(x) ((hio_uint16_t)(x)) +# define hio_htobe16(x) ((hio_uint16_t)(x)) +# define hio_be16toh(x) ((hio_uint16_t)(x)) +# define hio_htole16(x) hio_bswap16(x) +# define hio_le16toh(x) hio_bswap16(x) +# endif + +# if defined(HIO_HAVE_UINT32_T) +# define hio_hton32(x) ((hio_uint32_t)(x)) +# define hio_ntoh32(x) ((hio_uint32_t)(x)) +# define hio_htobe32(x) ((hio_uint32_t)(x)) +# define hio_be32toh(x) ((hio_uint32_t)(x)) +# define hio_htole32(x) hio_bswap32(x) +# define hio_le32toh(x) hio_bswap32(x) +# endif + +# if defined(HIO_HAVE_UINT64_T) +# define hio_hton64(x) ((hio_uint64_t)(x)) +# define hio_ntoh64(x) ((hio_uint64_t)(x)) +# define hio_htobe64(x) ((hio_uint64_t)(x)) +# define hio_be64toh(x) ((hio_uint64_t)(x)) +# define hio_htole64(x) hio_bswap64(x) +# define hio_le64toh(x) hio_bswap64(x) +# endif + +# if defined(HIO_HAVE_UINT128_T) +# define hio_hton128(x) ((hio_uint128_t)(x)) +# define hio_ntoh128(x) ((hio_uint128_t)(x)) +# define hio_htobe128(x) ((hio_uint128_t)(x)) +# define hio_be128toh(x) ((hio_uint128_t)(x)) +# define hio_htole128(x) hio_bswap128(x) +# define hio_le128toh(x) hio_bswap128(x) +# endif + +#else +# error UNKNOWN ENDIAN +#endif + + +/* ========================================================================= + * SIP-HASH-PRF + * ========================================================================= */ +HIO_EXPORT void hio_sip_hash_24 ( + const hio_uint8_t key[16], + const void* dptr, + hio_oow_t dlen, + hio_uint8_t out[8] +); + +#if defined(__cplusplus) +} +#endif + +/* Some C++ utilities below */ +#if defined(__cplusplus) +templatefn_chars_to_int(hio_chars_to_uint, CHAR_TYPE, INT_TYPE, hio_is_bch_space, HIO_CHARS_TO_INTMAX) +templatefn_chars_to_uint(hio_chars_to_uint, CHAR_TYPE, UINT_TYPE, hio_is_bch_space, HIO_CHARS_TO_UINTMAX) +#endif + +#endif diff --git a/hio/lib/utl-str.c b/hio/lib/utl-str.c index 70d6d44..b81de5c 100644 --- a/hio/lib/utl-str.c +++ b/hio/lib/utl-str.c @@ -23,7 +23,7 @@ */ /* - * Do NOT edit utl-str.c. + * Do NOT edit utl-str.c. Edit utl-str.c.m4 instead. * * Generate utl-str.c with m4 * $ m4 utl-str.c.m4 > utl-str.c @@ -35,6 +35,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + hio_oow_t hio_count_ucstr (const hio_uch_t* str) { @@ -52,7 +82,6 @@ hio_oow_t hio_count_bcstr (const hio_bch_t* str) } - int hio_equal_uchars (const hio_uch_t* str1, const hio_uch_t* str2, hio_oow_t len) { @@ -86,7 +115,6 @@ int hio_equal_bchars (const hio_bch_t* str1, const hio_bch_t* str2, hio_oow_t le } - int hio_comp_uchars (const hio_uch_t* str1, hio_oow_t len1, const hio_uch_t* str2, hio_oow_t len2, int ignorecase) { @@ -170,8 +198,6 @@ int hio_comp_bchars (const hio_bch_t* str1, hio_oow_t len1, const hio_bch_t* str } - - int hio_comp_ucstr (const hio_uch_t* str1, const hio_uch_t* str2, int ignorecase) { @@ -223,7 +249,6 @@ int hio_comp_bcstr (const hio_bch_t* str1, const hio_bch_t* str2, int ignorecase } - int hio_comp_ucstr_limited (const hio_uch_t* str1, const hio_uch_t* str2, hio_oow_t maxlen, int ignorecase) { @@ -279,8 +304,6 @@ int hio_comp_bcstr_limited (const hio_bch_t* str1, const hio_bch_t* str2, hio_oo } - - hio_oow_t hio_concat_uchars_to_ucstr (hio_uch_t* buf, hio_oow_t bsz, const hio_uch_t* str, hio_oow_t len) { hio_uch_t* p, * p2; @@ -330,8 +353,8 @@ int hio_comp_bcstr_limited (const hio_bch_t* str1, const hio_bch_t* str2, hio_oo } - - hio_oow_t hio_concat_ucstr (hio_uch_t* buf, hio_oow_t bsz, const hio_uch_t* str) + +hio_oow_t hio_concat_ucstr (hio_uch_t* buf, hio_oow_t bsz, const hio_uch_t* str) { hio_uch_t* p, * p2; hio_oow_t blen; @@ -352,7 +375,8 @@ int hio_comp_bcstr_limited (const hio_bch_t* str1, const hio_bch_t* str2, hio_oo return p - buf; } - hio_oow_t hio_concat_bcstr (hio_bch_t* buf, hio_oow_t bsz, const hio_bch_t* str) + +hio_oow_t hio_concat_bcstr (hio_bch_t* buf, hio_oow_t bsz, const hio_bch_t* str) { hio_bch_t* p, * p2; hio_oow_t blen; @@ -374,8 +398,6 @@ int hio_comp_bcstr_limited (const hio_bch_t* str1, const hio_bch_t* str2, hio_oo } - - void hio_fill_uchars (hio_uch_t* dst, hio_uch_t ch, hio_oow_t len) { @@ -391,7 +413,6 @@ void hio_fill_bchars (hio_bch_t* dst, hio_bch_t ch, hio_oow_t len) } - hio_uch_t* hio_find_uchar (const hio_uch_t* ptr, hio_oow_t len, hio_uch_t c) { @@ -423,7 +444,6 @@ hio_bch_t* hio_find_bchar (const hio_bch_t* ptr, hio_oow_t len, hio_bch_t c) } - hio_uch_t* hio_rfind_uchar (const hio_uch_t* ptr, hio_oow_t len, hio_uch_t c) { @@ -455,8 +475,6 @@ hio_bch_t* hio_rfind_bchar (const hio_bch_t* ptr, hio_oow_t len, hio_bch_t c) } - - hio_uch_t* hio_find_uchar_in_ucstr (const hio_uch_t* ptr, hio_uch_t c) { @@ -482,9 +500,7 @@ hio_bch_t* hio_find_bchar_in_bcstr (const hio_bch_t* ptr, hio_bch_t c) } - - - + hio_uch_t* hio_trim_uchars (const hio_uch_t* str, hio_oow_t* len, int flags) { const hio_uch_t* p = str, * end = str + *len; @@ -527,7 +543,7 @@ hio_uch_t* hio_trim_uchars (const hio_uch_t* str, hio_oow_t* len, int flags) return (hio_uch_t*)str; } - + hio_bch_t* hio_trim_bchars (const hio_bch_t* str, hio_oow_t* len, int flags) { const hio_bch_t* p = str, * end = str + *len; @@ -571,9 +587,7 @@ hio_bch_t* hio_trim_bchars (const hio_bch_t* str, hio_oow_t* len, int flags) } - - - + int hio_split_ucstr (hio_uch_t* s, const hio_uch_t* delim, hio_uch_t lquote, hio_uch_t rquote, hio_uch_t escape) { hio_uch_t* p = s, *d; @@ -812,7 +826,7 @@ exit_point: return cnt; } - + int hio_split_bcstr (hio_bch_t* s, const hio_bch_t* delim, hio_bch_t lquote, hio_bch_t rquote, hio_bch_t escape) { hio_bch_t* p = s, *d; @@ -1052,7 +1066,6 @@ exit_point: } - hio_intmax_t hio_uchars_to_intmax (const hio_uch_t* str, hio_oow_t len, int option, const hio_uch_t** endptr, int* is_sober) { @@ -1286,9 +1299,6 @@ hio_intmax_t hio_bchars_to_intmax (const hio_bch_t* str, hio_oow_t len, int opti } - - - hio_uintmax_t hio_uchars_to_uintmax (const hio_uch_t* str, hio_oow_t len, int option, const hio_uch_t** endptr, int* is_sober) { diff --git a/hio/lib/utl-str.c.m4 b/hio/lib/utl-str.c.m4 index b14f512..869b886 100644 --- a/hio/lib/utl-str.c.m4 +++ b/hio/lib/utl-str.c.m4 @@ -1,6 +1,4 @@ /* - * $Id$ - * Copyright (c) 2016-2020 Chung, Hyung-Hwan. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +23,7 @@ */ /* - * Do NOT edit utl-str.c. + * Do NOT edit utl-str.c. Edit utl-str.c.m4 instead. * * Generate utl-str.c with m4 * $ m4 utl-str.c.m4 > utl-str.c @@ -35,796 +33,50 @@ #include dnl --------------------------------------------------------------------------- -changequote(`[[', `]]') - +include(`utl-str.m4') dnl --------------------------------------------------------------------------- -define([[fn_count_cstr]], [[ define([[fn_name]], $1) define([[char_type]], $2) -hio_oow_t fn_name (const char_type* str) -{ - const char_type* ptr = str; - while (*ptr != '\0') ptr++; - return ptr - str; -} -]]) + fn_count_cstr(hio_count_ucstr, hio_uch_t) fn_count_cstr(hio_count_bcstr, hio_bch_t) -dnl --------------------------------------------------------------------------- -define([[fn_equal_chars]], [[ define([[fn_name]], $1) define([[char_type]], $2) -int fn_name (const char_type* str1, const char_type* str2, hio_oow_t len) -{ - hio_oow_t i; - - /* NOTE: you should call this function after having ensured that - * str1 and str2 are in the same length */ - - for (i = 0; i < len; i++) - { - if (str1[i] != str2[i]) return 0; - } - - return 1; -} -]]) fn_equal_chars(hio_equal_uchars, hio_uch_t) fn_equal_chars(hio_equal_bchars, hio_bch_t) -dnl --------------------------------------------------------------------------- -define([[fn_comp_chars]], [[ define([[fn_name]], $1) define([[char_type]], $2) define([[chau_type]], $3) -int fn_name (const char_type* str1, hio_oow_t len1, const char_type* str2, hio_oow_t len2, int ignorecase) -{ - chau_type c1, c2; - const char_type* end1 = str1 + len1; - const char_type* end2 = str2 + len2; - - if (ignorecase) - { - while (str1 < end1) - { - c1 = $4(*str1); - if (str2 < end2) - { - c2 = $4(*str2); - if (c1 > c2) return 1; - if (c1 < c2) return -1; - } - else return 1; - str1++; str2++; - } - } - else - { - while (str1 < end1) - { - c1 = *str1; - if (str2 < end2) - { - c2 = *str2; - if (c1 > c2) return 1; - if (c1 < c2) return -1; - } - else return 1; - str1++; str2++; - } - } - - return (str2 < end2)? -1: 0; -} -]]) fn_comp_chars(hio_comp_uchars, hio_uch_t, hio_uchu_t, hio_to_uch_lower) fn_comp_chars(hio_comp_bchars, hio_bch_t, hio_bchu_t, hio_to_bch_lower) - -dnl --------------------------------------------------------------------------- -define([[fn_comp_cstr]], [[ define([[fn_name]], $1) define([[char_type]], $2) define([[chau_type]], $3) -int fn_name (const char_type* str1, const char_type* str2, int ignorecase) -{ - if (ignorecase) - { - while ($4(*str1) == $4(*str2)) - { - if (*str1 == '\0') return 0; - str1++; str2++; - } - - return ((chau_type)$4(*str1) > (chau_type)$4(*str2))? 1: -1; - } - else - { - while (*str1 == *str2) - { - if (*str1 == '\0') return 0; - str1++; str2++; - } - - return ((chau_type)*str1 > (chau_type)*str2)? 1: -1; - } -} -]]) fn_comp_cstr(hio_comp_ucstr, hio_uch_t, hio_uchu_t, hio_to_uch_lower) fn_comp_cstr(hio_comp_bcstr, hio_bch_t, hio_bchu_t, hio_to_bch_lower) -dnl --------------------------------------------------------------------------- -define([[fn_comp_cstr_limited]], [[ define([[fn_name]], $1) define([[char_type]], $2) define([[chau_type]], $3) -int fn_name (const char_type* str1, const char_type* str2, hio_oow_t maxlen, int ignorecase) -{ - if (maxlen == 0) return 0; - - if (ignorecase) - { - while ($4(*str1) == $4(*str2)) - { - if (*str1 == '\0' || maxlen == 1) return 0; - str1++; str2++; maxlen--; - } - - return ((chau_type)$4(*str1) > (chau_type)$4(*str2))? 1: -1; - } - else - { - while (*str1 == *str2) - { - if (*str1 == '\0' || maxlen == 1) return 0; - str1++; str2++; maxlen--; - } - - return ((chau_type)*str1 > (chau_type)*str2)? 1: -1; - } -} -]]) fn_comp_cstr_limited(hio_comp_ucstr_limited, hio_uch_t, hio_uchu_t, hio_to_uch_lower) fn_comp_cstr_limited(hio_comp_bcstr_limited, hio_bch_t, hio_bchu_t, hio_to_bch_lower) - -dnl --------------------------------------------------------------------------- -define([[fn_concat_chars_to_cstr]], [[ define([[fn_name]], $1) define([[char_type]], $2) dnl: $3 count_str -hio_oow_t fn_name (char_type* buf, hio_oow_t bsz, const char_type* str, hio_oow_t len) -{ - char_type* p, * p2; - const char_type* end; - hio_oow_t blen; - - blen = $3(buf); - if (blen >= bsz) return blen; /* something wrong */ - - p = buf + blen; - p2 = buf + bsz - 1; - - end = str + len; - - while (p < p2) - { - if (str >= end) break; - *p++ = *str++; - } - - if (bsz > 0) *p = '\0'; - return p - buf; -} -]]) fn_concat_chars_to_cstr(hio_concat_uchars_to_ucstr, hio_uch_t, hio_count_ucstr) fn_concat_chars_to_cstr(hio_concat_bchars_to_bcstr, hio_bch_t, hio_count_bcstr) -dnl --------------------------------------------------------------------------- -define([[fn_concat_cstr]], [[ define([[fn_name]], $1) define([[char_type]], $2) dnl: $3 count_str -hio_oow_t fn_name (char_type* buf, hio_oow_t bsz, const char_type* str) -{ - char_type* p, * p2; - hio_oow_t blen; - - blen = $3(buf); - if (blen >= bsz) return blen; /* something wrong */ - - p = buf + blen; - p2 = buf + bsz - 1; - - while (p < p2) - { - if (*str == '\0') break; - *p++ = *str++; - } - - if (bsz > 0) *p = '\0'; - return p - buf; -} -]]) fn_concat_cstr(hio_concat_ucstr, hio_uch_t, hio_count_ucstr) fn_concat_cstr(hio_concat_bcstr, hio_bch_t, hio_count_bcstr) - -dnl --------------------------------------------------------------------------- -define([[fn_fill_chars]], [[ define([[fn_name]], $1) define([[char_type]], $2) -void fn_name (char_type* dst, char_type ch, hio_oow_t len) -{ - hio_oow_t i; - for (i = 0; i < len; i++) dst[i] = ch; -} -]]) fn_fill_chars(hio_fill_uchars, hio_uch_t) fn_fill_chars(hio_fill_bchars, hio_bch_t) -dnl --------------------------------------------------------------------------- -define([[fn_find_char]], [[ define([[fn_name]], $1) define([[char_type]], $2) -char_type* fn_name (const char_type* ptr, hio_oow_t len, char_type c) -{ - const char_type* end; - - end = ptr + len; - while (ptr < end) - { - if (*ptr == c) return (char_type*)ptr; - ptr++; - } - - return HIO_NULL; -} -]]) fn_find_char(hio_find_uchar, hio_uch_t) fn_find_char(hio_find_bchar, hio_bch_t) -dnl --------------------------------------------------------------------------- -define([[fn_rfind_char]], [[ define([[fn_name]], $1) define([[char_type]], $2) -char_type* fn_name (const char_type* ptr, hio_oow_t len, char_type c) -{ - const char_type* cur; - - cur = ptr + len; - while (cur > ptr) - { - --cur; - if (*cur == c) return (char_type*)cur; - } - - return HIO_NULL; -} -]]) fn_rfind_char(hio_rfind_uchar, hio_uch_t) fn_rfind_char(hio_rfind_bchar, hio_bch_t) - -dnl --------------------------------------------------------------------------- -define([[fn_find_char_in_cstr]], [[ define([[fn_name]], $1) define([[char_type]], $2) -char_type* fn_name (const char_type* ptr, char_type c) -{ - while (*ptr != '\0') - { - if (*ptr == c) return (char_type*)ptr; - ptr++; - } - - return HIO_NULL; -} -]]) fn_find_char_in_cstr(hio_find_uchar_in_ucstr, hio_uch_t) fn_find_char_in_cstr(hio_find_bchar_in_bcstr, hio_bch_t) - -dnl --------------------------------------------------------------------------- -define([[fn_trim_chars]], [[define([[fn_name]], $1) define([[char_type]], $2) dnl $3: is_space $4: prefix for option values - -char_type* fn_name (const char_type* str, hio_oow_t* len, int flags) -{ - const char_type* p = str, * end = str + *len; - - if (p < end) - { - const char_type* s = HIO_NULL, * e = HIO_NULL; - - do - { - if (!$3(*p)) - { - if (s == HIO_NULL) s = p; - e = p; - } - p++; - } - while (p < end); - - if (e) - { - if (flags & $4_RIGHT) - { - *len -= end - e - 1; - } - if (flags & $4_LEFT) - { - *len -= s - str; - str = s; - } - } - else - { - /* the entire string need to be deleted */ - if ((flags & $4_RIGHT) || - (flags & $4_LEFT)) *len = 0; - } - } - - return (char_type*)str; -} -]]) fn_trim_chars(hio_trim_uchars, hio_uch_t, hio_is_uch_space, HIO_TRIM_UCHARS) fn_trim_chars(hio_trim_bchars, hio_bch_t, hio_is_bch_space, HIO_TRIM_BCHARS) - -dnl --------------------------------------------------------------------------- -define([[fn_split_cstr]], [[ define([[fn_name]], $1) define([[char_type]], $2) dnl: $3 is_space $4: copy_str_unlimited - -int fn_name (char_type* s, const char_type* delim, char_type lquote, char_type rquote, char_type escape) -{ - char_type* p = s, *d; - char_type* sp = HIO_NULL, * ep = HIO_NULL; - int delim_mode; - int cnt = 0; - - if (delim == HIO_NULL) delim_mode = 0; - else - { - delim_mode = 1; - for (d = (char_type*)delim; *d != '\0'; d++) - if (!$3(*d)) delim_mode = 2; - } - - if (delim_mode == 0) - { - /* skip preceding space characters */ - while ($3(*p)) p++; - - /* when 0 is given as "delim", it has an effect of cutting - preceding and trailing space characters off "s". */ - if (lquote != '\0' && *p == lquote) - { - $4 (p, p + 1); - - for (;;) - { - if (*p == '\0') return -1; - - if (escape != '\0' && *p == escape) - { - $4 (p, p + 1); - } - else - { - if (*p == rquote) - { - p++; - break; - } - } - - if (sp == 0) sp = p; - ep = p; - p++; - } - while ($3(*p)) p++; - if (*p != '\0') return -1; - - if (sp == 0 && ep == 0) s[0] = '\0'; - else - { - ep[1] = '\0'; - if (s != (char_type*)sp) $4 (s, sp); - cnt++; - } - } - else - { - while (*p) - { - if (!$3(*p)) - { - if (sp == 0) sp = p; - ep = p; - } - p++; - } - - if (sp == 0 && ep == 0) s[0] = '\0'; - else - { - ep[1] = '\0'; - if (s != (char_type*)sp) $4 (s, sp); - cnt++; - } - } - } - else if (delim_mode == 1) - { - char_type* o; - - while (*p) - { - o = p; - while ($3(*p)) p++; - if (o != p) { $4 (o, p); p = o; } - - if (lquote != '\0' && *p == lquote) - { - $4 (p, p + 1); - - for (;;) - { - if (*p == '\0') return -1; - - if (escape != '\0' && *p == escape) - { - $4 (p, p + 1); - } - else - { - if (*p == rquote) - { - *p++ = '\0'; - cnt++; - break; - } - } - p++; - } - } - else - { - o = p; - for (;;) - { - if (*p == '\0') - { - if (o != p) cnt++; - break; - } - if ($3(*p)) - { - *p++ = '\0'; - cnt++; - break; - } - p++; - } - } - } - } - else /* if (delim_mode == 2) */ - { - char_type* o; - int ok; - - while (*p != '\0') - { - o = p; - while ($3(*p)) p++; - if (o != p) { $4 (o, p); p = o; } - - if (lquote != '\0' && *p == lquote) - { - $4 (p, p + 1); - - for (;;) - { - if (*p == '\0') return -1; - - if (escape != '\0' && *p == escape) - { - $4 (p, p + 1); - } - else - { - if (*p == rquote) - { - *p++ = '\0'; - cnt++; - break; - } - } - p++; - } - - ok = 0; - while ($3(*p)) p++; - if (*p == '\0') ok = 1; - for (d = (char_type*)delim; *d != '\0'; d++) - { - if (*p == *d) - { - ok = 1; - $4 (p, p + 1); - break; - } - } - if (ok == 0) return -1; - } - else - { - o = p; sp = ep = 0; - - for (;;) - { - if (*p == '\0') - { - if (ep) - { - ep[1] = '\0'; - p = &ep[1]; - } - cnt++; - break; - } - for (d = (char_type*)delim; *d != '\0'; d++) - { - if (*p == *d) - { - if (sp == HIO_NULL) - { - $4 (o, p); p = o; - *p++ = '\0'; - } - else - { - $4 (&ep[1], p); - $4 (o, sp); - o[ep - sp + 1] = '\0'; - p = &o[ep - sp + 2]; - } - cnt++; - /* last empty field after delim */ - if (*p == '\0') cnt++; - goto exit_point; - } - } - - if (!$3(*p)) - { - if (sp == HIO_NULL) sp = p; - ep = p; - } - p++; - } -exit_point: - ; - } - } - } - - return cnt; -} -]]) fn_split_cstr(hio_split_ucstr, hio_uch_t, hio_is_uch_space, hio_copy_ucstr_unlimited) fn_split_cstr(hio_split_bcstr, hio_bch_t, hio_is_bch_space, hio_copy_bcstr_unlimited) -dnl --------------------------------------------------------------------------- -define([[fn_chars_to_int]], [[ define([[fn_name]], $1) define([[char_type]], $2) define([[int_type]], $3) -int_type fn_name (const char_type* str, hio_oow_t len, int option, const char_type** endptr, int* is_sober) -{ - int_type n = 0; - const char_type* p, * pp; - const char_type* end; - hio_oow_t rem; - int digit, negative = 0; - int base = $5_GET_OPTION_BASE(option); - - p = str; - end = str + len; - - if ($5_GET_OPTION_LTRIM(option)) - { - /* strip off leading spaces */ - while (p < end && $4(*p)) p++; - } - - /* check for a sign */ - while (p < end) - { - if (*p == '-') - { - negative = ~negative; - p++; - } - else if (*p == '+') p++; - else break; - } - - /* check for a binary/octal/hexadecimal notation */ - rem = end - p; - if (base == 0) - { - if (rem >= 1 && *p == '0') - { - p++; - - if (rem == 1) base = 8; - else if (*p == 'x' || *p == 'X') - { - p++; base = 16; - } - else if (*p == 'b' || *p == 'B') - { - p++; base = 2; - } - else base = 8; - } - else base = 10; - } - else if (rem >= 2 && base == 16) - { - if (*p == '0' && - (*(p + 1) == 'x' || *(p + 1) == 'X')) p += 2; - } - else if (rem >= 2 && base == 2) - { - if (*p == '0' && - (*(p + 1) == 'b' || *(p + 1) == 'B')) p += 2; - } - - /* process the digits */ - pp = p; - while (p < end) - { - digit = HIO_ZDIGIT_TO_NUM(*p, base); - if (digit >= base) break; - n = n * base + digit; - p++; - } - - if ($5_GET_OPTION_E(option)) - { - if (*p == 'E' || *p == 'e') - { - int_type e = 0, i; - int e_neg = 0; - p++; - if (*p == '+') - { - p++; - } - else if (*p == '-') - { - p++; e_neg = 1; - } - while (p < end) - { - digit = HIO_ZDIGIT_TO_NUM(*p, base); - if (digit >= base) break; - e = e * base + digit; - p++; - } - if (e_neg) - for (i = 0; i < e; i++) n /= 10; - else - for (i = 0; i < e; i++) n *= 10; - } - } - - /* base 8: at least a zero digit has been seen. - * other case: p > pp to be able to have at least 1 meaningful digit. */ - if (is_sober) *is_sober = (base == 8 || p > pp); - - if ($5_GET_OPTION_RTRIM(option)) - { - /* consume trailing spaces */ - while (p < end && $4(*p)) p++; - } - - if (endptr) *endptr = p; - return (negative)? -n: n; -} -]]) fn_chars_to_int(hio_uchars_to_intmax, hio_uch_t, hio_intmax_t, hio_is_uch_space, HIO_UCHARS_TO_INTMAX) fn_chars_to_int(hio_bchars_to_intmax, hio_bch_t, hio_intmax_t, hio_is_bch_space, HIO_BCHARS_TO_INTMAX) - - -dnl --------------------------------------------------------------------------- -define([[fn_chars_to_uint]], [[ define([[fn_name]], $1) define([[char_type]], $2) define([[int_type]], $3) -int_type fn_name (const char_type* str, hio_oow_t len, int option, const char_type** endptr, int* is_sober) -{ - int_type n = 0; - const char_type* p, * pp; - const char_type* end; - hio_oow_t rem; - int digit; - int base = $5_GET_OPTION_BASE(option); - - p = str; - end = str + len; - - if ($5_GET_OPTION_LTRIM(option)) - { - /* strip off leading spaces */ - while (p < end && $4(*p)) p++; - } - - /* check for a sign */ - while (p < end) - { - if (*p == '+') p++; - else break; - } - - /* check for a binary/octal/hexadecimal notation */ - rem = end - p; - if (base == 0) - { - if (rem >= 1 && *p == '0') - { - p++; - - if (rem == 1) base = 8; - else if (*p == 'x' || *p == 'X') - { - p++; base = 16; - } - else if (*p == 'b' || *p == 'B') - { - p++; base = 2; - } - else base = 8; - } - else base = 10; - } - else if (rem >= 2 && base == 16) - { - if (*p == '0' && - (*(p + 1) == 'x' || *(p + 1) == 'X')) p += 2; - } - else if (rem >= 2 && base == 2) - { - if (*p == '0' && - (*(p + 1) == 'b' || *(p + 1) == 'B')) p += 2; - } - - /* process the digits */ - pp = p; - while (p < end) - { - digit = HIO_ZDIGIT_TO_NUM(*p, base); - if (digit >= base) break; - n = n * base + digit; - p++; - } - - if ($5_GET_OPTION_E(option)) - { - if (*p == 'E' || *p == 'e') - { - int_type e = 0, i; - int e_neg = 0; - p++; - if (*p == '+') - { - p++; - } - else if (*p == '-') - { - p++; e_neg = 1; - } - while (p < end) - { - digit = HIO_ZDIGIT_TO_NUM(*p, base); - if (digit >= base) break; - e = e * base + digit; - p++; - } - if (e_neg) - for (i = 0; i < e; i++) n /= 10; - else - for (i = 0; i < e; i++) n *= 10; - } - } - - /* base 8: at least a zero digit has been seen. - * other case: p > pp to be able to have at least 1 meaningful digit. */ - if (is_sober) *is_sober = (base == 8 || p > pp); - - if ($5_GET_OPTION_RTRIM(option)) - { - /* consume trailing spaces */ - while (p < end && $4(*p)) p++; - } - - if (endptr) *endptr = p; - return n; -} -]]) fn_chars_to_uint(hio_uchars_to_uintmax, hio_uch_t, hio_uintmax_t, hio_is_uch_space, HIO_UCHARS_TO_UINTMAX) fn_chars_to_uint(hio_bchars_to_uintmax, hio_bch_t, hio_uintmax_t, hio_is_bch_space, HIO_BCHARS_TO_UINTMAX) diff --git a/hio/lib/utl-str.m4 b/hio/lib/utl-str.m4 new file mode 100644 index 0000000..a424377 --- /dev/null +++ b/hio/lib/utl-str.m4 @@ -0,0 +1,757 @@ +dnl --------------------------------------------------------------------------- +changequote(`[[', `]]') + +dnl --------------------------------------------------------------------------- +define([[fn_count_cstr]], [[ define([[_fn_name_]], $1) define([[_char_type_]], $2) +hio_oow_t _fn_name_ (const _char_type_* str) +{ + const _char_type_* ptr = str; + while (*ptr != '\0') ptr++; + return ptr - str; +} +]]) + +dnl --------------------------------------------------------------------------- +define([[fn_equal_chars]], [[ define([[_fn_name_]], $1) define([[_char_type_]], $2) +int _fn_name_ (const _char_type_* str1, const _char_type_* str2, hio_oow_t len) +{ + hio_oow_t i; + + /* NOTE: you should call this function after having ensured that + * str1 and str2 are in the same length */ + + for (i = 0; i < len; i++) + { + if (str1[i] != str2[i]) return 0; + } + + return 1; +} +]]) + +dnl --------------------------------------------------------------------------- +define([[fn_comp_chars]], [[ define([[_fn_name_]], $1) define([[_char_type_]], $2) define([[_chau_type_]], $3) +int _fn_name_ (const _char_type_* str1, hio_oow_t len1, const _char_type_* str2, hio_oow_t len2, int ignorecase) +{ + _chau_type_ c1, c2; + const _char_type_* end1 = str1 + len1; + const _char_type_* end2 = str2 + len2; + + if (ignorecase) + { + while (str1 < end1) + { + c1 = $4(*str1); + if (str2 < end2) + { + c2 = $4(*str2); + if (c1 > c2) return 1; + if (c1 < c2) return -1; + } + else return 1; + str1++; str2++; + } + } + else + { + while (str1 < end1) + { + c1 = *str1; + if (str2 < end2) + { + c2 = *str2; + if (c1 > c2) return 1; + if (c1 < c2) return -1; + } + else return 1; + str1++; str2++; + } + } + + return (str2 < end2)? -1: 0; +} +]]) + +dnl --------------------------------------------------------------------------- +define([[fn_comp_cstr]], [[ define([[_fn_name_]], $1) define([[_char_type_]], $2) define([[_chau_type_]], $3) +int _fn_name_ (const _char_type_* str1, const _char_type_* str2, int ignorecase) +{ + if (ignorecase) + { + while ($4(*str1) == $4(*str2)) + { + if (*str1 == '\0') return 0; + str1++; str2++; + } + + return ((_chau_type_)$4(*str1) > (_chau_type_)$4(*str2))? 1: -1; + } + else + { + while (*str1 == *str2) + { + if (*str1 == '\0') return 0; + str1++; str2++; + } + + return ((_chau_type_)*str1 > (_chau_type_)*str2)? 1: -1; + } +} +]]) + +dnl --------------------------------------------------------------------------- +define([[fn_comp_cstr_limited]], [[ define([[_fn_name_]], $1) define([[_char_type_]], $2) define([[_chau_type_]], $3) +int _fn_name_ (const _char_type_* str1, const _char_type_* str2, hio_oow_t maxlen, int ignorecase) +{ + if (maxlen == 0) return 0; + + if (ignorecase) + { + while ($4(*str1) == $4(*str2)) + { + if (*str1 == '\0' || maxlen == 1) return 0; + str1++; str2++; maxlen--; + } + + return ((_chau_type_)$4(*str1) > (_chau_type_)$4(*str2))? 1: -1; + } + else + { + while (*str1 == *str2) + { + if (*str1 == '\0' || maxlen == 1) return 0; + str1++; str2++; maxlen--; + } + + return ((_chau_type_)*str1 > (_chau_type_)*str2)? 1: -1; + } +} +]]) + +dnl --------------------------------------------------------------------------- +define([[fn_concat_chars_to_cstr]], [[ define([[_fn_name_]], $1) define([[_char_type_]], $2) dnl: $3 count_str +hio_oow_t _fn_name_ (_char_type_* buf, hio_oow_t bsz, const _char_type_* str, hio_oow_t len) +{ + _char_type_* p, * p2; + const _char_type_* end; + hio_oow_t blen; + + blen = $3(buf); + if (blen >= bsz) return blen; /* something wrong */ + + p = buf + blen; + p2 = buf + bsz - 1; + + end = str + len; + + while (p < p2) + { + if (str >= end) break; + *p++ = *str++; + } + + if (bsz > 0) *p = '\0'; + return p - buf; +} +]]) + +dnl --------------------------------------------------------------------------- +dnl $3: count_str +define([[fn_concat_cstr]], [[ define([[_fn_name_]], $1) define([[_char_type_]], $2) +hio_oow_t _fn_name_ (_char_type_* buf, hio_oow_t bsz, const _char_type_* str) +{ + _char_type_* p, * p2; + hio_oow_t blen; + + blen = $3(buf); + if (blen >= bsz) return blen; /* something wrong */ + + p = buf + blen; + p2 = buf + bsz - 1; + + while (p < p2) + { + if (*str == '\0') break; + *p++ = *str++; + } + + if (bsz > 0) *p = '\0'; + return p - buf; +} +]]) + +dnl --------------------------------------------------------------------------- +define([[fn_fill_chars]], [[ define([[_fn_name_]], $1) define([[_char_type_]], $2) +void _fn_name_ (_char_type_* dst, _char_type_ ch, hio_oow_t len) +{ + hio_oow_t i; + for (i = 0; i < len; i++) dst[i] = ch; +} +]]) + +dnl --------------------------------------------------------------------------- +define([[fn_find_char]], [[ define([[_fn_name_]], $1) define([[_char_type_]], $2) +_char_type_* _fn_name_ (const _char_type_* ptr, hio_oow_t len, _char_type_ c) +{ + const _char_type_* end; + + end = ptr + len; + while (ptr < end) + { + if (*ptr == c) return (_char_type_*)ptr; + ptr++; + } + + return HIO_NULL; +} +]]) + +dnl --------------------------------------------------------------------------- +define([[fn_rfind_char]], [[ define([[_fn_name_]], $1) define([[_char_type_]], $2) +_char_type_* _fn_name_ (const _char_type_* ptr, hio_oow_t len, _char_type_ c) +{ + const _char_type_* cur; + + cur = ptr + len; + while (cur > ptr) + { + --cur; + if (*cur == c) return (_char_type_*)cur; + } + + return HIO_NULL; +} +]]) + +dnl --------------------------------------------------------------------------- +define([[fn_find_char_in_cstr]], [[ define([[_fn_name_]], $1) define([[_char_type_]], $2) +_char_type_* _fn_name_ (const _char_type_* ptr, _char_type_ c) +{ + while (*ptr != '\0') + { + if (*ptr == c) return (_char_type_*)ptr; + ptr++; + } + + return HIO_NULL; +} +]]) + +dnl --------------------------------------------------------------------------- +dnl $3: is_space $4: prefix for option values +define([[fn_trim_chars]], [[define([[_fn_name_]], $1) define([[_char_type_]], $2) +_char_type_* _fn_name_ (const _char_type_* str, hio_oow_t* len, int flags) +{ + const _char_type_* p = str, * end = str + *len; + + if (p < end) + { + const _char_type_* s = HIO_NULL, * e = HIO_NULL; + + do + { + if (!$3(*p)) + { + if (s == HIO_NULL) s = p; + e = p; + } + p++; + } + while (p < end); + + if (e) + { + if (flags & $4_RIGHT) + { + *len -= end - e - 1; + } + if (flags & $4_LEFT) + { + *len -= s - str; + str = s; + } + } + else + { + /* the entire string need to be deleted */ + if ((flags & $4_RIGHT) || + (flags & $4_LEFT)) *len = 0; + } + } + + return (_char_type_*)str; +} +]]) + +dnl --------------------------------------------------------------------------- +dnl $3 is_space $4: copy_str_unlimited +define([[fn_split_cstr]], [[ define([[_fn_name_]], $1) define([[_char_type_]], $2) +int _fn_name_ (_char_type_* s, const _char_type_* delim, _char_type_ lquote, _char_type_ rquote, _char_type_ escape) +{ + _char_type_* p = s, *d; + _char_type_* sp = HIO_NULL, * ep = HIO_NULL; + int delim_mode; + int cnt = 0; + + if (delim == HIO_NULL) delim_mode = 0; + else + { + delim_mode = 1; + for (d = (_char_type_*)delim; *d != '\0'; d++) + if (!$3(*d)) delim_mode = 2; + } + + if (delim_mode == 0) + { + /* skip preceding space characters */ + while ($3(*p)) p++; + + /* when 0 is given as "delim", it has an effect of cutting + preceding and trailing space characters off "s". */ + if (lquote != '\0' && *p == lquote) + { + $4 (p, p + 1); + + for (;;) + { + if (*p == '\0') return -1; + + if (escape != '\0' && *p == escape) + { + $4 (p, p + 1); + } + else + { + if (*p == rquote) + { + p++; + break; + } + } + + if (sp == 0) sp = p; + ep = p; + p++; + } + while ($3(*p)) p++; + if (*p != '\0') return -1; + + if (sp == 0 && ep == 0) s[0] = '\0'; + else + { + ep[1] = '\0'; + if (s != (_char_type_*)sp) $4 (s, sp); + cnt++; + } + } + else + { + while (*p) + { + if (!$3(*p)) + { + if (sp == 0) sp = p; + ep = p; + } + p++; + } + + if (sp == 0 && ep == 0) s[0] = '\0'; + else + { + ep[1] = '\0'; + if (s != (_char_type_*)sp) $4 (s, sp); + cnt++; + } + } + } + else if (delim_mode == 1) + { + _char_type_* o; + + while (*p) + { + o = p; + while ($3(*p)) p++; + if (o != p) { $4 (o, p); p = o; } + + if (lquote != '\0' && *p == lquote) + { + $4 (p, p + 1); + + for (;;) + { + if (*p == '\0') return -1; + + if (escape != '\0' && *p == escape) + { + $4 (p, p + 1); + } + else + { + if (*p == rquote) + { + *p++ = '\0'; + cnt++; + break; + } + } + p++; + } + } + else + { + o = p; + for (;;) + { + if (*p == '\0') + { + if (o != p) cnt++; + break; + } + if ($3(*p)) + { + *p++ = '\0'; + cnt++; + break; + } + p++; + } + } + } + } + else /* if (delim_mode == 2) */ + { + _char_type_* o; + int ok; + + while (*p != '\0') + { + o = p; + while ($3(*p)) p++; + if (o != p) { $4 (o, p); p = o; } + + if (lquote != '\0' && *p == lquote) + { + $4 (p, p + 1); + + for (;;) + { + if (*p == '\0') return -1; + + if (escape != '\0' && *p == escape) + { + $4 (p, p + 1); + } + else + { + if (*p == rquote) + { + *p++ = '\0'; + cnt++; + break; + } + } + p++; + } + + ok = 0; + while ($3(*p)) p++; + if (*p == '\0') ok = 1; + for (d = (_char_type_*)delim; *d != '\0'; d++) + { + if (*p == *d) + { + ok = 1; + $4 (p, p + 1); + break; + } + } + if (ok == 0) return -1; + } + else + { + o = p; sp = ep = 0; + + for (;;) + { + if (*p == '\0') + { + if (ep) + { + ep[1] = '\0'; + p = &ep[1]; + } + cnt++; + break; + } + for (d = (_char_type_*)delim; *d != '\0'; d++) + { + if (*p == *d) + { + if (sp == HIO_NULL) + { + $4 (o, p); p = o; + *p++ = '\0'; + } + else + { + $4 (&ep[1], p); + $4 (o, sp); + o[ep - sp + 1] = '\0'; + p = &o[ep - sp + 2]; + } + cnt++; + /* last empty field after delim */ + if (*p == '\0') cnt++; + goto exit_point; + } + } + + if (!$3(*p)) + { + if (sp == HIO_NULL) sp = p; + ep = p; + } + p++; + } +exit_point: + ; + } + } + } + + return cnt; +} +]]) + +dnl --------------------------------------------------------------------------- +define([[fn_chars_to_int]], [[ define([[_fn_name_]], $1) define([[_char_type_]], $2) define([[_int_type_]], $3) +_int_type_ _fn_name_ (const _char_type_* str, hio_oow_t len, int option, const _char_type_** endptr, int* is_sober) +{ + _int_type_ n = 0; + const _char_type_* p, * pp; + const _char_type_* end; + hio_oow_t rem; + int digit, negative = 0; + int base = $5_GET_OPTION_BASE(option); + + p = str; + end = str + len; + + if ($5_GET_OPTION_LTRIM(option)) + { + /* strip off leading spaces */ + while (p < end && $4(*p)) p++; + } + + /* check for a sign */ + while (p < end) + { + if (*p == '-') + { + negative = ~negative; + p++; + } + else if (*p == '+') p++; + else break; + } + + /* check for a binary/octal/hexadecimal notation */ + rem = end - p; + if (base == 0) + { + if (rem >= 1 && *p == '0') + { + p++; + + if (rem == 1) base = 8; + else if (*p == 'x' || *p == 'X') + { + p++; base = 16; + } + else if (*p == 'b' || *p == 'B') + { + p++; base = 2; + } + else base = 8; + } + else base = 10; + } + else if (rem >= 2 && base == 16) + { + if (*p == '0' && + (*(p + 1) == 'x' || *(p + 1) == 'X')) p += 2; + } + else if (rem >= 2 && base == 2) + { + if (*p == '0' && + (*(p + 1) == 'b' || *(p + 1) == 'B')) p += 2; + } + + /* process the digits */ + pp = p; + while (p < end) + { + digit = HIO_ZDIGIT_TO_NUM(*p, base); + if (digit >= base) break; + n = n * base + digit; + p++; + } + + if ($5_GET_OPTION_E(option)) + { + if (*p == 'E' || *p == 'e') + { + _int_type_ e = 0, i; + int e_neg = 0; + p++; + if (*p == '+') + { + p++; + } + else if (*p == '-') + { + p++; e_neg = 1; + } + while (p < end) + { + digit = HIO_ZDIGIT_TO_NUM(*p, base); + if (digit >= base) break; + e = e * base + digit; + p++; + } + if (e_neg) + for (i = 0; i < e; i++) n /= 10; + else + for (i = 0; i < e; i++) n *= 10; + } + } + + /* base 8: at least a zero digit has been seen. + * other case: p > pp to be able to have at least 1 meaningful digit. */ + if (is_sober) *is_sober = (base == 8 || p > pp); + + if ($5_GET_OPTION_RTRIM(option)) + { + /* consume trailing spaces */ + while (p < end && $4(*p)) p++; + } + + if (endptr) *endptr = p; + return (negative)? -n: n; +} +]]) + +dnl --------------------------------------------------------------------------- +define([[fn_chars_to_uint]], [[ define([[_fn_name_]], $1) define([[_char_type_]], $2) define([[_int_type_]], $3) +_int_type_ _fn_name_ (const _char_type_* str, hio_oow_t len, int option, const _char_type_** endptr, int* is_sober) +{ + _int_type_ n = 0; + const _char_type_* p, * pp; + const _char_type_* end; + hio_oow_t rem; + int digit; + int base = $5_GET_OPTION_BASE(option); + + p = str; + end = str + len; + + if ($5_GET_OPTION_LTRIM(option)) + { + /* strip off leading spaces */ + while (p < end && $4(*p)) p++; + } + + /* check for a sign */ + while (p < end) + { + if (*p == '+') p++; + else break; + } + + /* check for a binary/octal/hexadecimal notation */ + rem = end - p; + if (base == 0) + { + if (rem >= 1 && *p == '0') + { + p++; + + if (rem == 1) base = 8; + else if (*p == 'x' || *p == 'X') + { + p++; base = 16; + } + else if (*p == 'b' || *p == 'B') + { + p++; base = 2; + } + else base = 8; + } + else base = 10; + } + else if (rem >= 2 && base == 16) + { + if (*p == '0' && + (*(p + 1) == 'x' || *(p + 1) == 'X')) p += 2; + } + else if (rem >= 2 && base == 2) + { + if (*p == '0' && + (*(p + 1) == 'b' || *(p + 1) == 'B')) p += 2; + } + + /* process the digits */ + pp = p; + while (p < end) + { + digit = HIO_ZDIGIT_TO_NUM(*p, base); + if (digit >= base) break; + n = n * base + digit; + p++; + } + + if ($5_GET_OPTION_E(option)) + { + if (*p == 'E' || *p == 'e') + { + _int_type_ e = 0, i; + int e_neg = 0; + p++; + if (*p == '+') + { + p++; + } + else if (*p == '-') + { + p++; e_neg = 1; + } + while (p < end) + { + digit = HIO_ZDIGIT_TO_NUM(*p, base); + if (digit >= base) break; + e = e * base + digit; + p++; + } + if (e_neg) + for (i = 0; i < e; i++) n /= 10; + else + for (i = 0; i < e; i++) n *= 10; + } + } + + /* base 8: at least a zero digit has been seen. + * other case: p > pp to be able to have at least 1 meaningful digit. */ + if (is_sober) *is_sober = (base == 8 || p > pp); + + if ($5_GET_OPTION_RTRIM(option)) + { + /* consume trailing spaces */ + while (p < end && $4(*p)) p++; + } + + if (endptr) *endptr = p; + return n; +} +]])