reorganizing hio-utl.h with hio-utl.h.m4
This commit is contained in:
		@ -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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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.
 | 
			
		||||
 | 
			
		||||
@ -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 <hio-cmn.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* =========================================================================
 | 
			
		||||
 * 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<CHAR_TYPE, INT_TYPE>   
 | 
			
		||||
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<CHAR_TYPE, UINT_TYPE>   
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1111
									
								
								hio/lib/hio-utl.h.m4
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1111
									
								
								hio/lib/hio-utl.h.m4
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -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)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@ -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 <hio-chr.h>
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										757
									
								
								hio/lib/utl-str.m4
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										757
									
								
								hio/lib/utl-str.m4
									
									
									
									
									
										Normal file
									
								
							@ -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;
 | 
			
		||||
}
 | 
			
		||||
]])
 | 
			
		||||
		Reference in New Issue
	
	Block a user