/* 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-str.h. Edit hio-str.h.m4 instead. * * Generate hio-str.h.m4 with m4 * $ m4 hio-str.h.m4 > hio-str.h */ #ifndef _HIO_STR_H_ #define _HIO_STR_H_ #include /* ========================================================================= * STRING * ========================================================================= */ enum hio_trim_flag_t { HIO_TRIM_LEFT = (1 << 0), /**< trim leading spaces */ #define HIO_TRIM_LEFT HIO_TRIM_LEFT #define HIO_TRIM_OOCHARS_LEFT HIO_TRIM_LEFT #define HIO_TRIM_UCHARS_LEFT HIO_TRIM_LEFT #define HIO_TRIM_BCHARS_LEFT HIO_TRIM_LEFT HIO_TRIM_RIGHT = (1 << 1) /**< trim trailing spaces */ #define HIO_TRIM_RIGHT HIO_TRIM_RIGHT #define HIO_TRIM_OOCHARS_RIGHT HIO_TRIM_RIGHT #define HIO_TRIM_UCHARS_RIGHT HIO_TRIM_RIGHT #define HIO_TRIM_BCHARS_RIGHT HIO_TRIM_RIGHT }; enum hio_fnmat_flag_t { HIO_FNMAT_PATHNAME = (1 << 0), #define HIO_FNMAT_PATHNAME HIO_FNMAT_PATHNAME HIO_FNMAT_NOESCAPE = (1 << 1), #define HIO_FNMAT_NOESCAPE HIO_FNMAT_NOESCAPE HIO_FNMAT_PERIOD = (1 << 2), #define HIO_FNMAT_PERIOD HIO_FNMAT_PERIOD HIO_FNMAT_IGNORECASE = (1 << 3) #define HIO_FNMAT_IGNORECASE HIO_FNMAT_IGNORECASE }; #if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) /* i don't support escaping in these systems */ # define HIO_FNMAT_IS_ESC(c) (0) # define HIO_FNMAT_IS_SEP(c) ((c) == '/' || (c) == '\\') #else # define HIO_FNMAT_IS_ESC(c) ((c) == '\\') # define HIO_FNMAT_IS_SEP(c) ((c) == '/') #endif #if defined(__cplusplus) extern "C" { #endif /* ------------------------------------ */ 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_uchars_ucstr ( const hio_uch_t* str1, hio_oow_t len, const hio_uch_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 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_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 ( 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_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_to_uchars ( hio_uch_t* dst, hio_oow_t dlen, const hio_uch_t* src ); HIO_EXPORT hio_oow_t hio_copy_bcstr_to_bchars ( hio_bch_t* dst, hio_oow_t dlen, const hio_bch_t* src ); 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_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_copy_fmt_ucstrs_to_ucstr ( hio_uch_t* buf, hio_oow_t bsz, const hio_uch_t* fmt, const hio_uch_t* str[] ); HIO_EXPORT hio_oow_t hio_copy_fmt_bcstrs_to_bcstr ( hio_bch_t* buf, hio_oow_t bsz, const hio_bch_t* fmt, const hio_bch_t* str[] ); HIO_EXPORT hio_oow_t hio_copy_fmt_ucses_to_ucstr ( hio_uch_t* buf, hio_oow_t bsz, const hio_uch_t* fmt, const hio_ucs_t str[] ); HIO_EXPORT hio_oow_t hio_copy_fmt_bcses_to_bcstr ( hio_bch_t* buf, hio_oow_t bsz, const hio_bch_t* fmt, const hio_bcs_t str[] ); /* ------------------------------------ */ 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 ); HIO_EXPORT hio_oow_t hio_count_ucstr_limited ( const hio_uch_t* str, hio_oow_t maxlen ); HIO_EXPORT hio_oow_t hio_count_bcstr_limited ( const hio_bch_t* str, hio_oow_t maxlen ); /* ------------------------------------ */ /** * 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 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_in_uchars ( const hio_uch_t* ptr, hio_oow_t len, hio_uch_t c ); HIO_EXPORT hio_bch_t* hio_find_bchar_in_bchars ( const hio_bch_t* ptr, hio_oow_t len, hio_bch_t c ); HIO_EXPORT hio_uch_t* hio_rfind_uchar_in_uchars ( const hio_uch_t* ptr, hio_oow_t len, hio_uch_t c ); HIO_EXPORT hio_bch_t* hio_rfind_bchar_in_bchars ( 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_rfind_uchar_in_ucstr ( const hio_uch_t* ptr, hio_uch_t c ); HIO_EXPORT hio_bch_t* hio_rfind_bchar_in_bcstr ( const hio_bch_t* ptr, hio_bch_t c ); HIO_EXPORT hio_uch_t* hio_find_uchars_in_uchars ( const hio_uch_t* str, hio_oow_t strsz, const hio_uch_t* sub, hio_oow_t subsz, int inorecase ); HIO_EXPORT hio_bch_t* hio_find_bchars_in_bchars ( const hio_bch_t* str, hio_oow_t strsz, const hio_bch_t* sub, hio_oow_t subsz, int inorecase ); HIO_EXPORT hio_uch_t* hio_rfind_uchars_in_uchars ( const hio_uch_t* str, hio_oow_t strsz, const hio_uch_t* sub, hio_oow_t subsz, int inorecase ); HIO_EXPORT hio_bch_t* hio_rfind_bchars_in_bchars ( const hio_bch_t* str, hio_oow_t strsz, const hio_bch_t* sub, hio_oow_t subsz, int inorecase ); /* ------------------------------------ */ HIO_EXPORT hio_oow_t hio_compact_uchars ( hio_uch_t* str, hio_oow_t len ); HIO_EXPORT hio_oow_t hio_compact_bchars ( hio_bch_t* str, hio_oow_t len ); HIO_EXPORT hio_oow_t hio_rotate_uchars ( hio_uch_t* str, hio_oow_t len, int dir, hio_oow_t n ); HIO_EXPORT hio_oow_t hio_rotate_bchars ( hio_bch_t* str, hio_oow_t len, int dir, hio_oow_t n ); HIO_EXPORT hio_uch_t* hio_tokenize_uchars ( const hio_uch_t* s, hio_oow_t len, const hio_uch_t* delim, hio_oow_t delim_len, hio_ucs_t* tok, int ignorecase ); HIO_EXPORT hio_bch_t* hio_tokenize_bchars ( const hio_bch_t* s, hio_oow_t len, const hio_bch_t* delim, hio_oow_t delim_len, hio_bcs_t* tok, int ignorecase ); 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 ); HIO_EXPORT int hio_fnmat_uchars_i ( const hio_uch_t* str, hio_oow_t slen, const hio_uch_t* ptn, hio_oow_t plen, int flags, int no_first_period ); HIO_EXPORT int hio_fnmat_bchars_i ( const hio_bch_t* str, hio_oow_t slen, const hio_bch_t* ptn, hio_oow_t plen, int flags, int no_first_period ); #define hio_fnmat_uchars(str, slen, ptn, plen, flags) hio_fnmat_uchars_i(str, slen, ptn, plen, flags, 0) #define hio_fnmat_ucstr(str, ptn, flags) hio_fnmat_uchars_i(str, hio_count_ucstr(str), ptn, hio_count_ucstr(ptn), flags, 0) #define hio_fnmat_uchars_ucstr(str, slen, ptn, flags) hio_fnmat_uchars_i(str, slen, ptn, hio_count_ucstr(ptn), flags, 0) #define hio_fnmat_ucstr_uchars(str, ptn, plen, flags) hio_fnmat_uchars_i(str, hio_count_ucstr(str), ptn, plen, flags, 0) #define hio_fnmat_bchars(str, slen, ptn, plen, flags) hio_fnmat_bchars_i(str, slen, ptn, plen, flags, 0) #define hio_fnmat_bcstr(str, ptn, flags) hio_fnmat_bchars_i(str, hio_count_bcstr(str), ptn, hio_count_bcstr(ptn), flags, 0) #define hio_fnmat_bchars_bcstr(str, slen, ptn, flags) hio_fnmat_bchars_i(str, slen, ptn, hio_count_bcstr(ptn), flags, 0) #define hio_fnmat_bcstr_bchars(str, ptn, plen, flags) hio_fnmat_bchars_i(str, hio_count_bcstr(str), ptn, plen, flags, 0) #if defined(HIO_OOCH_IS_UCH) # define hio_count_oocstr hio_count_ucstr # define hio_count_oocstr_limited hio_count_ucstr_limited # 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_comp_oocstr_limited hio_comp_ucstr_limited # 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_copy_fmt_oocses_to_oocstr hio_copy_fmt_ucses_to_ucstr # define hio_copy_fmt_oocstr_to_oocstr hio_copy_fmt_ucstr_to_ucstr # 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_in_oochars hio_find_uchar_in_uchars # define hio_rfind_oochar_in_oochars hio_rfind_uchar_in_uchars # define hio_find_oochar_in_oocstr hio_find_uchar_in_ucstr # define hio_find_oochars_in_oochars hio_find_uchars_in_uchars # define hio_rfind_oochars_in_oochars hio_rfind_uchars_in_uchars # define hio_compact_oochars hio_compact_uchars # define hio_rotate_oochars hio_rotate_uchars # define hio_tokenize_oochars hio_tokenize_uchars # define hio_trim_oochars hio_trim_uchars # define hio_split_oocstr hio_split_ucstr # define hawk_fnmat_oochars_i hawk_fnmat_uchars_i # define hawk_fnmat_oochars hawk_fnmat_uchars # define hawk_fnmat_oocstr hawk_fnmat_ucstr # define hawk_fnmat_oochars_oocstr hawk_fnmat_uchars_ucstr # define hawk_fnmat_oocstr_oochars hawk_fnmat_ucstr_uchars #else # define hio_count_oocstr hio_count_bcstr # define hio_count_oocstr_limited hio_count_bcstr_limited # 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_comp_oocstr_limited hio_comp_bcstr_limited # 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_copy_fmt_oocses_to_oocstr hio_copy_fmt_bcses_to_bcstr # define hio_copy_fmt_oocstr_to_oocstr hio_copy_fmt_bcstr_to_bcstr # 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_in_oochars hio_find_bchar_in_bchars # define hio_rfind_oochar_in_oochars hio_rfind_bchar_in_bchars # define hio_find_oochar_in_oocstr hio_find_bchar_in_bcstr # define hio_find_oochars_in_oochars hio_find_bchars_in_bchars # define hio_rfind_oochars_in_oochars hio_rfind_bchars_in_bchars # define hio_compact_oochars hio_compact_bchars # define hio_rotate_oochars hio_rotate_bchars # define hio_tokenize_oochars hio_tokenize_bchars # define hio_trim_oochars hio_trim_bchars # define hio_split_oocstr hio_split_bcstr # define hawk_fnmat_oochars_i hawk_fnmat_bchars_i # define hawk_fnmat_oochars hawk_fnmat_bchars # define hawk_fnmat_oocstr hawk_fnmat_bcstr # define hawk_fnmat_oochars_oocstr hawk_fnmat_bchars_bcstr # define hawk_fnmat_oocstr_oochars hawk_fnmat_bcstr_bchars #endif /* ------------------------------------------------------------------------- */ #define HIO_BYTE_TO_OOCSTR_RADIXMASK (0xFF) #define HIO_BYTE_TO_OOCSTR_LOWERCASE (1 << 8) #define HIO_BYTE_TO_UCSTR_RADIXMASK HIO_BYTE_TO_OOCSTR_RADIXMASK #define HIO_BYTE_TO_UCSTR_LOWERCASE HIO_BYTE_TO_OOCSTR_LOWERCASE #define HIO_BYTE_TO_BCSTR_RADIXMASK HIO_BYTE_TO_OOCSTR_RADIXMASK #define HIO_BYTE_TO_BCSTR_LOWERCASE HIO_BYTE_TO_OOCSTR_LOWERCASE 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 ); HIO_EXPORT hio_oow_t hio_byte_to_ucstr ( hio_uint8_t byte, hio_uch_t* buf, hio_oow_t size, int flagged_radix, hio_uch_t fill ); #if defined(HIO_OOCH_IS_UCH) # define hio_byte_to_oocstr hio_byte_to_ucstr #else # define hio_byte_to_oocstr hio_byte_to_bcstr #endif /* ------------------------------------------------------------------------- */ HIO_EXPORT hio_oow_t hio_intmax_to_ucstr ( hio_intmax_t value, int radix, const hio_uch_t* prefix, hio_uch_t* buf, hio_oow_t size ); HIO_EXPORT hio_oow_t hio_intmax_to_bcstr ( hio_intmax_t value, int radix, const hio_bch_t* prefix, hio_bch_t* buf, hio_oow_t size ); HIO_EXPORT hio_oow_t hio_uintmax_to_ucstr ( hio_uintmax_t value, int radix, const hio_uch_t* prefix, hio_uch_t* buf, hio_oow_t size ); HIO_EXPORT hio_oow_t hio_uintmax_to_bcstr ( hio_uintmax_t value, int radix, const hio_bch_t* prefix, hio_bch_t* buf, hio_oow_t size ); #if defined(HIO_OOCH_IS_UCH) # define hio_intmax_to_oocstr hio_intmax_to_ucstr # define hio_uintmax_to_oocstr hio_uintmax_to_ucstr #else # define hio_intmax_to_oocstr hio_intmax_to_bcstr # define hio_uintmax_to_oocstr hio_uintmax_to_bcstr #endif /* ------------------------------------------------------------------------- */ #define HIO_CHARS_TO_INT_MAKE_OPTION(e,ltrim,rtrim,base) (((!!(e)) << 0) | ((!!(ltrim)) << 2) | ((!!(rtrim)) << 3) | ((base) << 8)) #define HIO_CHARS_TO_INT_GET_OPTION_E(option) ((option) & 1) #define HIO_CHARS_TO_INT_GET_OPTION_LTRIM(option) ((option) & 4) #define HIO_CHARS_TO_INT_GET_OPTION_RTRIM(option) ((option) & 8) #define HIO_CHARS_TO_INT_GET_OPTION_BASE(option) ((option) >> 8) #define HIO_CHARS_TO_UINT_MAKE_OPTION(e,ltrim,rtrim,base) (((!!(e)) << 0) | ((!!(ltrim)) << 2) | ((!!(rtrim)) << 3) | ((base) << 8)) #define HIO_CHARS_TO_UINT_GET_OPTION_E(option) ((option) & 1) #define HIO_CHARS_TO_UINT_GET_OPTION_LTRIM(option) ((option) & 4) #define HIO_CHARS_TO_UINT_GET_OPTION_RTRIM(option) ((option) & 8) #define HIO_CHARS_TO_UINT_GET_OPTION_BASE(option) ((option) >> 8) #define HIO_OOCHARS_TO_INTMAX_MAKE_OPTION(e,ltrim,rtrim,base) HIO_CHARS_TO_INT_MAKE_OPTION(e,ltrim,rtrim,base) #define HIO_OOCHARS_TO_INTMAX_GET_OPTION_E(option) HIO_CHARS_TO_INT_GET_OPTION_E(option) #define HIO_OOCHARS_TO_INTMAX_GET_OPTION_LTRIM(option) HIO_CHARS_TO_INT_GET_OPTION_LTRIM(option) #define HIO_OOCHARS_TO_INTMAX_GET_OPTION_RTRIM(option) HIO_CHARS_TO_INT_GET_OPTION_RTRIM(option) #define HIO_OOCHARS_TO_INTMAX_GET_OPTION_BASE(option) HIO_CHARS_TO_INT_GET_OPTION_BASE(option) #define HIO_OOCHARS_TO_UINTMAX_MAKE_OPTION(e,ltrim,rtrim,base) HIO_CHARS_TO_UINT_MAKE_OPTION(e,ltrim,rtrim,base) #define HIO_OOCHARS_TO_UINTMAX_GET_OPTION_E(option) HIO_CHARS_TO_UINT_GET_OPTION_E(option) #define HIO_OOCHARS_TO_UINTMAX_GET_OPTION_LTRIM(option) HIO_CHARS_TO_UINT_GET_OPTION_LTRIM(option) #define HIO_OOCHARS_TO_UINTMAX_GET_OPTION_RTRIM(option) HIO_CHARS_TO_UINT_GET_OPTION_RTRIM(option) #define HIO_OOCHARS_TO_UINTMAX_GET_OPTION_BASE(option) HIO_CHARS_TO_UINT_GET_OPTION_BASE(option) #define HIO_UCHARS_TO_INTMAX_MAKE_OPTION(e,ltrim,rtrim,base) HIO_CHARS_TO_INT_MAKE_OPTION(e,ltrim,rtrim,base) #define HIO_UCHARS_TO_INTMAX_GET_OPTION_E(option) HIO_CHARS_TO_INT_GET_OPTION_E(option) #define HIO_UCHARS_TO_INTMAX_GET_OPTION_LTRIM(option) HIO_CHARS_TO_INT_GET_OPTION_LTRIM(option) #define HIO_UCHARS_TO_INTMAX_GET_OPTION_RTRIM(option) HIO_CHARS_TO_INT_GET_OPTION_RTRIM(option) #define HIO_UCHARS_TO_INTMAX_GET_OPTION_BASE(option) HIO_CHARS_TO_INT_GET_OPTION_BASE(option) #define HIO_BCHARS_TO_INTMAX_MAKE_OPTION(e,ltrim,rtrim,base) HIO_CHARS_TO_INT_MAKE_OPTION(e,ltrim,rtrim,base) #define HIO_BCHARS_TO_INTMAX_GET_OPTION_E(option) HIO_CHARS_TO_INT_GET_OPTION_E(option) #define HIO_BCHARS_TO_INTMAX_GET_OPTION_LTRIM(option) HIO_CHARS_TO_INT_GET_OPTION_LTRIM(option) #define HIO_BCHARS_TO_INTMAX_GET_OPTION_RTRIM(option) HIO_CHARS_TO_INT_GET_OPTION_RTRIM(option) #define HIO_BCHARS_TO_INTMAX_GET_OPTION_BASE(option) HIO_CHARS_TO_INT_GET_OPTION_BASE(option) #define HIO_UCHARS_TO_UINTMAX_MAKE_OPTION(e,ltrim,rtrim,base) HIO_CHARS_TO_UINT_MAKE_OPTION(e,ltrim,rtrim,base) #define HIO_UCHARS_TO_UINTMAX_GET_OPTION_E(option) HIO_CHARS_TO_UINT_GET_OPTION_E(option) #define HIO_UCHARS_TO_UINTMAX_GET_OPTION_LTRIM(option) HIO_CHARS_TO_UINT_GET_OPTION_LTRIM(option) #define HIO_UCHARS_TO_UINTMAX_GET_OPTION_RTRIM(option) HIO_CHARS_TO_UINT_GET_OPTION_RTRIM(option) #define HIO_UCHARS_TO_UINTMAX_GET_OPTION_BASE(option) HIO_CHARS_TO_UINT_GET_OPTION_BASE(option) #define HIO_BCHARS_TO_UINTMAX_MAKE_OPTION(e,ltrim,rtrim,base) HIO_CHARS_TO_UINT_MAKE_OPTION(e,ltrim,rtrim,base) #define HIO_BCHARS_TO_UINTMAX_GET_OPTION_E(option) HIO_CHARS_TO_UINT_GET_OPTION_E(option) #define HIO_BCHARS_TO_UINTMAX_GET_OPTION_LTRIM(option) HIO_CHARS_TO_UINT_GET_OPTION_LTRIM(option) #define HIO_BCHARS_TO_UINTMAX_GET_OPTION_RTRIM(option) HIO_CHARS_TO_UINT_GET_OPTION_RTRIM(option) #define HIO_BCHARS_TO_UINTMAX_GET_OPTION_BASE(option) HIO_CHARS_TO_UINT_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(__cplusplus) } #endif /* Some C++ utilities below */ #if defined(__cplusplus) /* static inline bool is_space (char c) { return isspace(c); } static inline bool is_wspace (wchar_t c) { return iswspace(c); } unsigned x = hio_chars_to_uint("0x12345", 7, 0, NULL, NULL); unsigned y = hio_chars_to_uint(L"0x12345", 7, 0, NULL, NULL); int a = hio_chars_to_int("-0x12345", 8, 0, NULL, NULL); int b = hio_chars_to_int(L"-0x12345", 8, 0, NULL, NULL); */ templateINT_TYPE hio_chars_to_int (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_INT_GET_OPTION_BASE(option); p = str; end = str + len; if (HIO_CHARS_TO_INT_GET_OPTION_LTRIM(option)) { /* strip off leading spaces */ while (p < end && IS_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_INT_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_INT_GET_OPTION_RTRIM(option)) { /* consume trailing spaces */ while (p < end && IS_SPACE(*p)) p++; } if (endptr) *endptr = p; return (negative)? -n: n; } templateUINT_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_UINT_GET_OPTION_BASE(option); p = str; end = str + len; if (HIO_CHARS_TO_UINT_GET_OPTION_LTRIM(option)) { /* strip off leading spaces */ while (p < end && IS_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_UINT_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_UINT_GET_OPTION_RTRIM(option)) { /* consume trailing spaces */ while (p < end && IS_SPACE(*p)) p++; } if (endptr) *endptr = p; return n; } #endif #endif