diff --git a/hio/lib/hio-str.h b/hio/lib/hio-str.h new file mode 100644 index 0000000..6a75bae --- /dev/null +++ b/hio/lib/hio-str.h @@ -0,0 +1,1036 @@ +/* + 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