diff --git a/hawk/lib/Makefile.am b/hawk/lib/Makefile.am index 431229a3..5f552df0 100644 --- a/hawk/lib/Makefile.am +++ b/hawk/lib/Makefile.am @@ -31,6 +31,15 @@ CPPFLAGS_PFMOD += -DHAWK_DEFAULT_MODPOSTFIX=\".so\" endif endif +EXTRA_DIST = \ + hawk-str.h.m4 \ + utl-str.c.m4 \ + utl-str.m4 + +BUILT_SOURCES = \ + hawk-str.h \ + utl-str.c + ################################################## # include files to deploy ################################################## @@ -283,3 +292,11 @@ install-data-hook: uninstall-hook: @rm -f "$(DESTDIR)$(pkgincludedir)/hawk-cfg.h" + + +hawk-str.h: utl-str.m4 hawk-str.h.m4 + m4 -I$(srcdir) $(srcdir)/hawk-str.h.m4 > $(srcdir)/hawk-str.h + +utl-str.c: utl-str.m4 utl-str.c.m4 + m4 -I$(srcdir) $(srcdir)/utl-str.c.m4 > $(srcdir)/utl-str.c + diff --git a/hawk/lib/Makefile.in b/hawk/lib/Makefile.in index 1878811e..22736aff 100644 --- a/hawk/lib/Makefile.in +++ b/hawk/lib/Makefile.in @@ -602,6 +602,15 @@ CXXFLAGS_ALL_COMMON = @WIN32_TRUE@ -DHAWK_DEFAULT_MODPREFIX=\"libhawk-\" \ @WIN32_TRUE@ -DHAWK_DEFAULT_MODPOSTFIX=\"-1.dll\" \ @WIN32_TRUE@ $(am__append_1) $(am__append_2) +EXTRA_DIST = \ + hawk-str.h.m4 \ + utl-str.c.m4 \ + utl-str.m4 + +BUILT_SOURCES = \ + hawk-str.h \ + utl-str.c + pkginclude_HEADERS = hawk.h hawk-arr.h hawk-chr.h hawk-cmn.h \ hawk-dir.h hawk-ecs.h hawk-fmt.h hawk-gem.h hawk-htb.h \ hawk-map.h hawk-rbt.h hawk-pac1.h hawk-skad.h hawk-utl.h \ @@ -675,7 +684,7 @@ libhawk_la_LIBADD = $(LIBM) $(SOCKET_LIBS) $(am__append_4) \ @ENABLE_STATIC_MODULE_FALSE@libhawk_sys_la_CXXFLAGS = $(CXXFLAGS_MOD_COMMON) @ENABLE_STATIC_MODULE_FALSE@libhawk_sys_la_LDFLAGS = $(LDFLAGS_MOD_COMMON) @ENABLE_STATIC_MODULE_FALSE@libhawk_sys_la_LIBADD = $(LIBADD_MOD_COMMON) $(SOCKET_LIBS) -all: hawk-cfg.h +all: $(BUILT_SOURCES) hawk-cfg.h $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: @@ -1453,13 +1462,15 @@ distdir-am: $(DISTFILES) fi; \ done check-am: all-am -check: check-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) hawk-cfg.h installdirs: for dir in "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(pkgincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done -install: install-am +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am @@ -1489,6 +1500,7 @@ distclean-generic: maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ @@ -1686,7 +1698,8 @@ ps-am: uninstall-am: uninstall-pkgincludeHEADERS uninstall-pkglibLTLIBRARIES @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) uninstall-hook -.MAKE: all install-am install-data-am install-strip uninstall-am +.MAKE: all check install install-am install-data-am install-strip \ + uninstall-am .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ @@ -1722,6 +1735,12 @@ install-data-hook: uninstall-hook: @rm -f "$(DESTDIR)$(pkgincludedir)/hawk-cfg.h" +hawk-str.h: utl-str.m4 hawk-str.h.m4 + m4 -I$(srcdir) $(srcdir)/hawk-str.h.m4 > $(srcdir)/hawk-str.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. .NOEXPORT: diff --git a/hawk/lib/err.c b/hawk/lib/err.c index 81c40fc9..f85d5c3e 100644 --- a/hawk/lib/err.c +++ b/hawk/lib/err.c @@ -482,7 +482,7 @@ void hawk_gem_seterror (hawk_gem_t* gem, const hawk_loc_t* errloc, hawk_errnum_t errfmt = gem->errstr(gem->errnum); HAWK_ASSERT (errfmt != HAWK_NULL); - hawk_copy_oofcs_to_oochars (gem->errmsg, HAWK_COUNTOF(gem->errmsg), errfmt, errarg); + hawk_copy_fmt_oocses_to_oocstr (gem->errmsg, HAWK_COUNTOF(gem->errmsg), errfmt, errarg); if (errloc != HAWK_NULL) gem->errloc = *errloc; else HAWK_MEMSET (&gem->errloc, 0, HAWK_SIZEOF(gem->errloc)); diff --git a/hawk/lib/hawk-str.h.m4 b/hawk/lib/hawk-str.h.m4 new file mode 100644 index 00000000..c65a7b77 --- /dev/null +++ b/hawk/lib/hawk-str.h.m4 @@ -0,0 +1,733 @@ +/* + Copyright (c) 2006-2020 Chung, Hyung-Hwan. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Do NOT edit hawk-str.h. Edit hawk-str.h.m4 instead. + * + * Generate hawk-str.h.m4 with m4 + * $ m4 hawk-str.h.m4 > hawk-str.h + */ + +#ifndef _HAWK_STR_H_ +#define _HAWK_STR_H_ + +#include + +dnl --------------------------------------------------------------------------- +dnl include utl-str.m4 for c++ template functions far below +include(`utl-str.m4') +dnl --------------------------------------------------------------------------- + +/* ========================================================================= + * STRING + * ========================================================================= */ + +enum hawk_trim_oochars_flag_t +{ + HAWK_TRIM_OOCHARS_LEFT = (1 << 0), /**< trim leading spaces */ +#define HAWK_TRIM_OOCHARS_LEFT HAWK_TRIM_OOCHARS_LEFT +#define HAWK_TRIM_UCHARS_LEFT HAWK_TRIM_OOCHARS_LEFT +#define HAWK_TRIM_BCHARS_LEFT HAWK_TRIM_OOCHARS_LEFT + HAWK_TRIM_OOCHARS_RIGHT = (1 << 1) /**< trim trailing spaces */ +#define HAWK_TRIM_OOCHARS_RIGHT HAWK_TRIM_OOCHARS_RIGHT +#define HAWK_TRIM_UCHARS_RIGHT HAWK_TRIM_OOCHARS_RIGHT +#define HAWK_TRIM_BCHARS_RIGHT HAWK_TRIM_OOCHARS_RIGHT +}; + +#if defined(__cplusplus) +extern "C" { +#endif + + +/* ------------------------------------ */ + +HAWK_EXPORT int hawk_comp_uchars ( + const hawk_uch_t* str1, + hawk_oow_t len1, + const hawk_uch_t* str2, + hawk_oow_t len2, + int ignorecase +); + +HAWK_EXPORT int hawk_comp_bchars ( + const hawk_bch_t* str1, + hawk_oow_t len1, + const hawk_bch_t* str2, + hawk_oow_t len2, + int ignorecase +); + +HAWK_EXPORT int hawk_comp_ucstr ( + const hawk_uch_t* str1, + const hawk_uch_t* str2, + int ignorecase +); + +HAWK_EXPORT int hawk_comp_bcstr ( + const hawk_bch_t* str1, + const hawk_bch_t* str2, + int ignorecase +); + +HAWK_EXPORT int hawk_comp_ucstr_limited ( + const hawk_uch_t* str1, + const hawk_uch_t* str2, + hawk_oow_t maxlen, + int ignorecase +); + +HAWK_EXPORT int hawk_comp_bcstr_limited ( + const hawk_bch_t* str1, + const hawk_bch_t* str2, + hawk_oow_t maxlen, + int ignorecase +); + +HAWK_EXPORT int hawk_comp_uchars_ucstr ( + const hawk_uch_t* str1, + hawk_oow_t len, + const hawk_uch_t* str2, + int ignorecase +); + +HAWK_EXPORT int hawk_comp_bchars_bcstr ( + const hawk_bch_t* str1, + hawk_oow_t len, + const hawk_bch_t* str2, + int ignorecase +); + +/* ------------------------------------ */ + +HAWK_EXPORT hawk_oow_t hawk_concat_uchars_to_ucstr ( + hawk_uch_t* buf, + hawk_oow_t bsz, + const hawk_uch_t* src, + hawk_oow_t len +); + +HAWK_EXPORT hawk_oow_t hawk_concat_bchars_to_bcstr ( + hawk_bch_t* buf, + hawk_oow_t bsz, + const hawk_bch_t* src, + hawk_oow_t len +); + +HAWK_EXPORT hawk_oow_t hawk_concat_ucstr ( + hawk_uch_t* buf, + hawk_oow_t bsz, + const hawk_uch_t* src +); + +HAWK_EXPORT hawk_oow_t hawk_concat_bcstr ( + hawk_bch_t* buf, + hawk_oow_t bsz, + const hawk_bch_t* src +); + +/* ------------------------------------ */ + +HAWK_EXPORT void hawk_copy_uchars ( + hawk_uch_t* dst, + const hawk_uch_t* src, + hawk_oow_t len +); + +HAWK_EXPORT void hawk_copy_bchars ( + hawk_bch_t* dst, + const hawk_bch_t* src, + hawk_oow_t len +); + +HAWK_EXPORT void hawk_copy_bchars_to_uchars ( + hawk_uch_t* dst, + const hawk_bch_t* src, + hawk_oow_t len +); +HAWK_EXPORT void hawk_copy_uchars_to_bchars ( + hawk_bch_t* dst, + const hawk_uch_t* src, + hawk_oow_t len +); + +HAWK_EXPORT hawk_oow_t hawk_copy_uchars_to_ucstr ( + hawk_uch_t* dst, + hawk_oow_t dlen, + const hawk_uch_t* src, + hawk_oow_t slen +); + +HAWK_EXPORT hawk_oow_t hawk_copy_bchars_to_bcstr ( + hawk_bch_t* dst, + hawk_oow_t dlen, + const hawk_bch_t* src, + hawk_oow_t slen +); + +HAWK_EXPORT hawk_oow_t hawk_copy_uchars_to_ucstr_unlimited ( + hawk_uch_t* dst, + const hawk_uch_t* src, + hawk_oow_t len +); + +HAWK_EXPORT hawk_oow_t hawk_copy_bchars_to_bcstr_unlimited ( + hawk_bch_t* dst, + const hawk_bch_t* src, + hawk_oow_t len +); + +HAWK_EXPORT hawk_oow_t hawk_copy_ucstr_to_uchars ( + hawk_uch_t* dst, + hawk_oow_t dlen, + const hawk_uch_t* src +); + +HAWK_EXPORT hawk_oow_t hawk_copy_bcstr_to_bchars ( + hawk_bch_t* dst, + hawk_oow_t dlen, + const hawk_bch_t* src +); + +HAWK_EXPORT hawk_oow_t hawk_copy_ucstr ( + hawk_uch_t* dst, + hawk_oow_t len, + const hawk_uch_t* src +); + +HAWK_EXPORT hawk_oow_t hawk_copy_bcstr ( + hawk_bch_t* dst, + hawk_oow_t len, + const hawk_bch_t* src +); + +HAWK_EXPORT hawk_oow_t hawk_copy_ucstr_unlimited ( + hawk_uch_t* dst, + const hawk_uch_t* src +); + +HAWK_EXPORT hawk_oow_t hawk_copy_bcstr_unlimited ( + hawk_bch_t* dst, + const hawk_bch_t* src +); + +HAWK_EXPORT hawk_oow_t hawk_copy_fmt_ucstrs_to_ucstr ( + hawk_uch_t* buf, + hawk_oow_t bsz, + const hawk_uch_t* fmt, + const hawk_uch_t* str[] +); + +HAWK_EXPORT hawk_oow_t hawk_copy_fmt_bcstrs_to_bcstr ( + hawk_bch_t* buf, + hawk_oow_t bsz, + const hawk_bch_t* fmt, + const hawk_bch_t* str[] +); + +HAWK_EXPORT hawk_oow_t hawk_copy_fmt_ucses_to_ucstr ( + hawk_uch_t* buf, + hawk_oow_t bsz, + const hawk_uch_t* fmt, + const hawk_ucs_t str[] +); + +HAWK_EXPORT hawk_oow_t hawk_copy_fmt_bcses_to_bcstr ( + hawk_bch_t* buf, + hawk_oow_t bsz, + const hawk_bch_t* fmt, + const hawk_bcs_t str[] +); + +/* ------------------------------------ */ + +HAWK_EXPORT hawk_oow_t hawk_count_ucstr ( + const hawk_uch_t* str +); + +HAWK_EXPORT hawk_oow_t hawk_count_bcstr ( + const hawk_bch_t* str +); + +HAWK_EXPORT hawk_oow_t hawk_count_ucstr_limited ( + const hawk_uch_t* str, + hawk_oow_t maxlen +); + +HAWK_EXPORT hawk_oow_t hawk_count_bcstr_limited ( + const hawk_bch_t* str, + hawk_oow_t maxlen +); + +/* ------------------------------------ */ + +/** + * The hawk_equal_uchars() function determines equality of two strings + * of the same length \a len. + */ +HAWK_EXPORT int hawk_equal_uchars ( + const hawk_uch_t* str1, + const hawk_uch_t* str2, + hawk_oow_t len +); + +HAWK_EXPORT int hawk_equal_bchars ( + const hawk_bch_t* str1, + const hawk_bch_t* str2, + hawk_oow_t len +); + +/* ------------------------------------ */ + + +HAWK_EXPORT void hawk_fill_uchars ( + hawk_uch_t* dst, + const hawk_uch_t ch, + hawk_oow_t len +); + +HAWK_EXPORT void hawk_fill_bchars ( + hawk_bch_t* dst, + const hawk_bch_t ch, + hawk_oow_t len +); + +/* ------------------------------------ */ + +HAWK_EXPORT const hawk_bch_t* hawk_find_bcstr_word_in_bcstr ( + const hawk_bch_t* str, + const hawk_bch_t* word, + hawk_bch_t extra_delim, + int ignorecase +); + +HAWK_EXPORT const hawk_uch_t* hawk_find_ucstr_word_in_ucstr ( + const hawk_uch_t* str, + const hawk_uch_t* word, + hawk_uch_t extra_delim, + int ignorecase +); + +HAWK_EXPORT hawk_uch_t* hawk_find_uchar_in_uchars ( + const hawk_uch_t* ptr, + hawk_oow_t len, + hawk_uch_t c +); + +HAWK_EXPORT hawk_bch_t* hawk_find_bchar_in_bchars ( + const hawk_bch_t* ptr, + hawk_oow_t len, + hawk_bch_t c +); + +HAWK_EXPORT hawk_uch_t* hawk_rfind_uchar_in_uchars ( + const hawk_uch_t* ptr, + hawk_oow_t len, + hawk_uch_t c +); + +HAWK_EXPORT hawk_bch_t* hawk_rfind_bchar_in_bchars ( + const hawk_bch_t* ptr, + hawk_oow_t len, + hawk_bch_t c +); + +HAWK_EXPORT hawk_uch_t* hawk_find_uchar_in_ucstr ( + const hawk_uch_t* ptr, + hawk_uch_t c +); + +HAWK_EXPORT hawk_bch_t* hawk_find_bchar_in_bcstr ( + const hawk_bch_t* ptr, + hawk_bch_t c +); + +HAWK_EXPORT hawk_uch_t* hawk_rfind_uchar_in_ucstr ( + const hawk_uch_t* ptr, + hawk_uch_t c +); + +HAWK_EXPORT hawk_bch_t* hawk_rfind_bchar_in_bcstr ( + const hawk_bch_t* ptr, + hawk_bch_t c +); + +HAWK_EXPORT hawk_uch_t* hawk_find_uchars_in_uchars ( + const hawk_uch_t* str, + hawk_oow_t strsz, + const hawk_uch_t* sub, + hawk_oow_t subsz, + int inorecase +); + +HAWK_EXPORT hawk_bch_t* hawk_find_bchars_in_bchars ( + const hawk_bch_t* str, + hawk_oow_t strsz, + const hawk_bch_t* sub, + hawk_oow_t subsz, + int inorecase +); + +HAWK_EXPORT hawk_uch_t* hawk_rfind_uchars_in_uchars ( + const hawk_uch_t* str, + hawk_oow_t strsz, + const hawk_uch_t* sub, + hawk_oow_t subsz, + int inorecase +); + +HAWK_EXPORT hawk_bch_t* hawk_rfind_bchars_in_bchars ( + const hawk_bch_t* str, + hawk_oow_t strsz, + const hawk_bch_t* sub, + hawk_oow_t subsz, + int inorecase +); + +/* ------------------------------------ */ + +HAWK_EXPORT hawk_oow_t hawk_compact_uchars ( + hawk_uch_t* str, + hawk_oow_t len +); + +HAWK_EXPORT hawk_oow_t hawk_compact_bchars ( + hawk_bch_t* str, + hawk_oow_t len +); + + +HAWK_EXPORT hawk_oow_t hawk_rotate_uchars ( + hawk_uch_t* str, + hawk_oow_t len, + int dir, + hawk_oow_t n +); + +HAWK_EXPORT hawk_oow_t hawk_rotate_bchars ( + hawk_bch_t* str, + hawk_oow_t len, + int dir, + hawk_oow_t n +); + + +HAWK_EXPORT hawk_uch_t* hawk_trim_uchars ( + const hawk_uch_t* str, + hawk_oow_t* len, + int flags +); + +HAWK_EXPORT hawk_bch_t* hawk_trim_bchars ( + const hawk_bch_t* str, + hawk_oow_t* len, + int flags +); + +HAWK_EXPORT int hawk_split_ucstr ( + hawk_uch_t* s, + const hawk_uch_t* delim, + hawk_uch_t lquote, + hawk_uch_t rquote, + hawk_uch_t escape +); + +HAWK_EXPORT int hawk_split_bcstr ( + hawk_bch_t* s, + const hawk_bch_t* delim, + hawk_bch_t lquote, + hawk_bch_t rquote, + hawk_bch_t escape +); + + +#if defined(HAWK_OOCH_IS_UCH) +# define hawk_count_oocstr hawk_count_ucstr +# define hawk_count_oocstr_limited hawk_count_ucstr_limited + +# define hawk_equal_oochars hawk_equal_uchars +# define hawk_comp_oochars hawk_comp_uchars +# define hawk_comp_oocstr_bcstr hawk_comp_ucstr_bcstr +# define hawk_comp_oochars_bcstr hawk_comp_uchars_bcstr +# define hawk_comp_oochars_ucstr hawk_comp_uchars_ucstr +# define hawk_comp_oochars_oocstr hawk_comp_uchars_ucstr +# define hawk_comp_oocstr hawk_comp_ucstr +# define hawk_comp_oocstr_limited hawk_comp_ucstr_limited + +# define hawk_copy_oochars hawk_copy_uchars +# define hawk_copy_bchars_to_oochars hawk_copy_bchars_to_uchars +# define hawk_copy_oochars_to_bchars hawk_copy_uchars_to_bchars +# define hawk_copy_uchars_to_oochars hawk_copy_uchars +# define hawk_copy_oochars_to_uchars hawk_copy_uchars + +# define hawk_copy_oochars_to_oocstr hawk_copy_uchars_to_ucstr +# define hawk_copy_oochars_to_oocstr_unlimited hawk_copy_uchars_to_ucstr_unlimited +# define hawk_copy_oocstr hawk_copy_ucstr +# define hawk_copy_oocstr_unlimited hawk_copy_ucstr_unlimited +# define hawk_copy_fmt_oocses_to_oocstr hawk_copy_fmt_ucses_to_ucstr +# define hawk_copy_fmt_oocstr_to_oocstr hawk_copy_fmt_ucstr_to_ucstr + +# define hawk_concat_oochars_to_ucstr hawk_concat_uchars_to_ucstr +# define hawk_concat_oocstr hawk_concat_ucstr + +# define hawk_fill_oochars hawk_fill_uchars +# define hawk_find_oocstr_word_in_oocstr hawk_find_ucstr_word_in_ucstr +# define hawk_find_oochar_in_oochars hawk_find_uchar_in_uchars +# define hawk_rfind_oochar_in_oochars hawk_rfind_uchar_in_uchars +# define hawk_find_oochar_in_oocstr hawk_find_uchar_in_ucstr +# define hawk_find_oochars_in_oochars hawk_find_uchars_in_uchars +# define hawk_rfind_oochars_in_oochars hawk_rfind_uchars_in_uchars + +# define hawk_compact_oochars hawk_compact_uchars +# define hawk_rotate_oochars hawk_rotate_uchars +# define hawk_trim_oochars hawk_trim_uchars +# define hawk_split_oocstr hawk_split_ucstr +#else +# define hawk_count_oocstr hawk_count_bcstr +# define hawk_count_oocstr_limited hawk_count_bcstr_limited + +# define hawk_equal_oochars hawk_equal_bchars +# define hawk_comp_oochars hawk_comp_bchars +# define hawk_comp_oocstr_bcstr hawk_comp_bcstr +# define hawk_comp_oochars_bcstr hawk_comp_bchars_bcstr +# define hawk_comp_oochars_ucstr hawk_comp_bchars_ucstr +# define hawk_comp_oochars_oocstr hawk_comp_bchars_bcstr +# define hawk_comp_oocstr hawk_comp_bcstr +# define hawk_comp_oocstr_limited hawk_comp_bcstr_limited + +# define hawk_copy_oochars hawk_copy_bchars +# define hawk_copy_bchars_to_oochars hawk_copy_bchars +# define hawk_copy_oochars_to_bchars hawk_copy_bchars +# define hawk_copy_uchars_to_oochars hawk_copy_uchars_to_bchars +# define hawk_copy_oochars_to_uchars hawk_copy_bchars_to_uchars + +# define hawk_copy_oochars_to_oocstr hawk_copy_bchars_to_bcstr +# define hawk_copy_oochars_to_oocstr_unlimited hawk_copy_bchars_to_bcstr_unlimited +# define hawk_copy_oocstr hawk_copy_bcstr +# define hawk_copy_oocstr_unlimited hawk_copy_bcstr_unlimited +# define hawk_copy_fmt_oocses_to_oocstr hawk_copy_fmt_bcses_to_bcstr +# define hawk_copy_fmt_oocstr_to_oocstr hawk_copy_fmt_bcstr_to_bcstr + +# define hawk_concat_oochars_to_bcstr hawk_concat_bchars_to_bcstr +# define hawk_concat_oocstr hawk_concat_bcstr + +# define hawk_fill_oochars hawk_fill_bchars +# define hawk_find_oocstr_word_in_oocstr hawk_find_bcstr_word_in_bcstr +# define hawk_find_oochar_in_oochars hawk_find_bchar_in_bchars +# define hawk_rfind_oochar_in_oochars hawk_rfind_bchar_in_bchars +# define hawk_find_oochar_in_oocstr hawk_find_bchar_in_bcstr +# define hawk_find_oochars_in_oochars hawk_find_bchars_in_bchars +# define hawk_rfind_oochars_in_oochars hawk_rfind_bchars_in_bchars + +# define hawk_compact_oochars hawk_compact_uchars +# define hawk_rotate_oochars hawk_rotate_uchars +# define hawk_trim_oochars hawk_trim_bchars +# define hawk_split_oocstr hawk_split_bcstr +#endif + +/* ------------------------------------------------------------------------- */ + +#define HAWK_BYTE_TO_OOCSTR_RADIXMASK (0xFF) +#define HAWK_BYTE_TO_OOCSTR_LOWERCASE (1 << 8) + +#define HAWK_BYTE_TO_UCSTR_RADIXMASK HAWK_BYTE_TO_OOCSTR_RADIXMASK +#define HAWK_BYTE_TO_UCSTR_LOWERCASE HAWK_BYTE_TO_OOCSTR_LOWERCASE + +#define HAWK_BYTE_TO_BCSTR_RADIXMASK HAWK_BYTE_TO_OOCSTR_RADIXMASK +#define HAWK_BYTE_TO_BCSTR_LOWERCASE HAWK_BYTE_TO_OOCSTR_LOWERCASE + +HAWK_EXPORT hawk_oow_t hawk_byte_to_bcstr ( + hawk_uint8_t byte, + hawk_bch_t* buf, + hawk_oow_t size, + int flagged_radix, + hawk_bch_t fill +); + +HAWK_EXPORT hawk_oow_t hawk_byte_to_ucstr ( + hawk_uint8_t byte, + hawk_uch_t* buf, + hawk_oow_t size, + int flagged_radix, + hawk_uch_t fill +); + +#if defined(HAWK_OOCH_IS_UCH) +# define hawk_byte_to_oocstr hawk_byte_to_ucstr +#else +# define hawk_byte_to_oocstr hawk_byte_to_bcstr +#endif + +/* ------------------------------------------------------------------------- */ + +HAWK_EXPORT hawk_oow_t hawk_int_to_ucstr ( + hawk_int_t value, + int radix, + const hawk_uch_t* prefix, + hawk_uch_t* buf, + hawk_oow_t size +); + +HAWK_EXPORT hawk_oow_t hawk_int_to_bcstr ( + hawk_int_t value, + int radix, + const hawk_bch_t* prefix, + hawk_bch_t* buf, + hawk_oow_t size +); + +HAWK_EXPORT hawk_oow_t hawk_uint_to_ucstr ( + hawk_uint_t value, + int radix, + const hawk_uch_t* prefix, + hawk_uch_t* buf, + hawk_oow_t size +); + +HAWK_EXPORT hawk_oow_t hawk_uint_to_bcstr ( + hawk_uint_t value, + int radix, + const hawk_bch_t* prefix, + hawk_bch_t* buf, + hawk_oow_t size +); + +#if defined(HAWK_OOCH_IS_UCH) +# define hawk_int_to_oocstr hawk_int_to_ucstr +# define hawk_uint_to_oocstr hawk_uint_to_ucstr +#else +# define hawk_int_to_oocstr hawk_int_to_bcstr +# define hawk_uint_to_oocstr hawk_uint_to_bcstr +#endif + + +/* ------------------------------------------------------------------------- */ + +#define HAWK_CHARS_TO_INT_MAKE_OPTION(e,ltrim,rtrim,base) (((!!(e)) << 0) | ((!!(ltrim)) << 2) | ((!!(rtrim)) << 3) | ((base) << 8)) +#define HAWK_CHARS_TO_INT_GET_OPTION_E(option) ((option) & 1) +#define HAWK_CHARS_TO_INT_GET_OPTION_LTRIM(option) ((option) & 4) +#define HAWK_CHARS_TO_INT_GET_OPTION_RTRIM(option) ((option) & 8) +#define HAWK_CHARS_TO_INT_GET_OPTION_BASE(option) ((option) >> 8) + +#define HAWK_CHARS_TO_UINT_MAKE_OPTION(e,ltrim,rtrim,base) (((!!(e)) << 0) | ((!!(ltrim)) << 2) | ((!!(rtrim)) << 3) | ((base) << 8)) +#define HAWK_CHARS_TO_UINT_GET_OPTION_E(option) ((option) & 1) +#define HAWK_CHARS_TO_UINT_GET_OPTION_LTRIM(option) ((option) & 4) +#define HAWK_CHARS_TO_UINT_GET_OPTION_RTRIM(option) ((option) & 8) +#define HAWK_CHARS_TO_UINT_GET_OPTION_BASE(option) ((option) >> 8) + +#define HAWK_OOCHARS_TO_INTMAX_MAKE_OPTION(e,ltrim,rtrim,base) HAWK_CHARS_TO_INT_MAKE_OPTION(e,ltrim,rtrim,base) +#define HAWK_OOCHARS_TO_INTMAX_GET_OPTION_E(option) HAWK_CHARS_TO_INT_GET_OPTION_E(option) +#define HAWK_OOCHARS_TO_INTMAX_GET_OPTION_LTRIM(option) HAWK_CHARS_TO_INT_GET_OPTION_LTRIM(option) +#define HAWK_OOCHARS_TO_INTMAX_GET_OPTION_RTRIM(option) HAWK_CHARS_TO_INT_GET_OPTION_RTRIM(option) +#define HAWK_OOCHARS_TO_INTMAX_GET_OPTION_BASE(option) HAWK_CHARS_TO_INT_GET_OPTION_BASE(option) + +#define HAWK_OOCHARS_TO_UINTMAX_MAKE_OPTION(e,ltrim,rtrim,base) HAWK_CHARS_TO_UINT_MAKE_OPTION(e,ltrim,rtrim,base) +#define HAWK_OOCHARS_TO_UINTMAX_GET_OPTION_E(option) HAWK_CHARS_TO_UINT_GET_OPTION_E(option) +#define HAWK_OOCHARS_TO_UINTMAX_GET_OPTION_LTRIM(option) HAWK_CHARS_TO_UINT_GET_OPTION_LTRIM(option) +#define HAWK_OOCHARS_TO_UINTMAX_GET_OPTION_RTRIM(option) HAWK_CHARS_TO_UINT_GET_OPTION_RTRIM(option) +#define HAWK_OOCHARS_TO_UINTMAX_GET_OPTION_BASE(option) HAWK_CHARS_TO_UINT_GET_OPTION_BASE(option) + +#define HAWK_UCHARS_TO_INTMAX_MAKE_OPTION(e,ltrim,rtrim,base) HAWK_CHARS_TO_INT_MAKE_OPTION(e,ltrim,rtrim,base) +#define HAWK_UCHARS_TO_INTMAX_GET_OPTION_E(option) HAWK_CHARS_TO_INT_GET_OPTION_E(option) +#define HAWK_UCHARS_TO_INTMAX_GET_OPTION_LTRIM(option) HAWK_CHARS_TO_INT_GET_OPTION_LTRIM(option) +#define HAWK_UCHARS_TO_INTMAX_GET_OPTION_RTRIM(option) HAWK_CHARS_TO_INT_GET_OPTION_RTRIM(option) +#define HAWK_UCHARS_TO_INTMAX_GET_OPTION_BASE(option) HAWK_CHARS_TO_INT_GET_OPTION_BASE(option) + +#define HAWK_BCHARS_TO_INTMAX_MAKE_OPTION(e,ltrim,rtrim,base) HAWK_CHARS_TO_INT_MAKE_OPTION(e,ltrim,rtrim,base) +#define HAWK_BCHARS_TO_INTMAX_GET_OPTION_E(option) HAWK_CHARS_TO_INT_GET_OPTION_E(option) +#define HAWK_BCHARS_TO_INTMAX_GET_OPTION_LTRIM(option) HAWK_CHARS_TO_INT_GET_OPTION_LTRIM(option) +#define HAWK_BCHARS_TO_INTMAX_GET_OPTION_RTRIM(option) HAWK_CHARS_TO_INT_GET_OPTION_RTRIM(option) +#define HAWK_BCHARS_TO_INTMAX_GET_OPTION_BASE(option) HAWK_CHARS_TO_INT_GET_OPTION_BASE(option) + +#define HAWK_UCHARS_TO_UINTMAX_MAKE_OPTION(e,ltrim,rtrim,base) HAWK_CHARS_TO_UINT_MAKE_OPTION(e,ltrim,rtrim,base) +#define HAWK_UCHARS_TO_UINTMAX_GET_OPTION_E(option) HAWK_CHARS_TO_UINT_GET_OPTION_E(option) +#define HAWK_UCHARS_TO_UINTMAX_GET_OPTION_LTRIM(option) HAWK_CHARS_TO_UINT_GET_OPTION_LTRIM(option) +#define HAWK_UCHARS_TO_UINTMAX_GET_OPTION_RTRIM(option) HAWK_CHARS_TO_UINT_GET_OPTION_RTRIM(option) +#define HAWK_UCHARS_TO_UINTMAX_GET_OPTION_BASE(option) HAWK_CHARS_TO_UINT_GET_OPTION_BASE(option) + +#define HAWK_BCHARS_TO_UINTMAX_MAKE_OPTION(e,ltrim,rtrim,base) HAWK_CHARS_TO_UINT_MAKE_OPTION(e,ltrim,rtrim,base) +#define HAWK_BCHARS_TO_UINTMAX_GET_OPTION_E(option) HAWK_CHARS_TO_UINT_GET_OPTION_E(option) +#define HAWK_BCHARS_TO_UINTMAX_GET_OPTION_LTRIM(option) HAWK_CHARS_TO_UINT_GET_OPTION_LTRIM(option) +#define HAWK_BCHARS_TO_UINTMAX_GET_OPTION_RTRIM(option) HAWK_CHARS_TO_UINT_GET_OPTION_RTRIM(option) +#define HAWK_BCHARS_TO_UINTMAX_GET_OPTION_BASE(option) HAWK_CHARS_TO_UINT_GET_OPTION_BASE(option) + +HAWK_EXPORT hawk_int_t hawk_uchars_to_int ( + const hawk_uch_t* str, + hawk_oow_t len, + int option, + const hawk_uch_t** endptr, + int* is_sober +); + +HAWK_EXPORT hawk_int_t hawk_bchars_to_int ( + const hawk_bch_t* str, + hawk_oow_t len, + int option, + const hawk_bch_t** endptr, + int* is_sober +); + +HAWK_EXPORT hawk_uint_t hawk_uchars_to_uint ( + const hawk_uch_t* str, + hawk_oow_t len, + int option, + const hawk_uch_t** endptr, + int* is_sober +); + +HAWK_EXPORT hawk_uint_t hawk_bchars_to_uint ( + const hawk_bch_t* str, + hawk_oow_t len, + int option, + const hawk_bch_t** endptr, + int* is_sober +); +#if defined(HAWK_OOCH_IS_UCH) +# define hawk_oochars_to_int hawk_uchars_to_int +# define hawk_oochars_to_uint hawk_uchars_to_uint +#else +# define hawk_oochars_to_int hawk_bchars_to_int +# define hawk_oochars_to_uint hawk_bchars_to_uint +#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 = hawk_chars_to_uint("0x12345", 7, 0, NULL, NULL); +unsigned y = hawk_chars_to_uint(L"0x12345", 7, 0, NULL, NULL); +int a = hawk_chars_to_int("-0x12345", 8, 0, NULL, NULL); +int b = hawk_chars_to_int(L"-0x12345", 8, 0, NULL, NULL); +*/ +templatefn_chars_to_int(hawk_chars_to_int, CHAR_TYPE, INT_TYPE, IS_SPACE, HAWK_CHARS_TO_INT) +templatefn_chars_to_uint(hawk_chars_to_uint, CHAR_TYPE, UINT_TYPE, IS_SPACE, HAWK_CHARS_TO_UINT) + +#endif + +#endif diff --git a/hawk/lib/hawk-utl.h b/hawk/lib/hawk-utl.h index 755cbe2f..6db943fe 100644 --- a/hawk/lib/hawk-utl.h +++ b/hawk/lib/hawk-utl.h @@ -26,6 +26,7 @@ #define _HAWK_UTL_H_ #include +#include #include #define HAWK_EPOCH_YEAR (1970) @@ -233,23 +234,6 @@ #define HAWK_HASH_UCSTR(hv, ptr) HAWK_HASH_VPTR(hv, ptr, const hawk_uch_t) #define HAWK_HASH_MORE_UCSTR(hv, ptr) HAWK_HASH_MORE_VPTR(hv, ptr, const hawk_uch_t) -/* ========================================================================= - * STRING - * ========================================================================= */ - -enum hawk_trim_oochars_flag_t -{ - HAWK_TRIM_OOCHARS_LEFT = (1 << 0), /**< trim leading spaces */ -#define HAWK_TRIM_OOCHARS_LEFT HAWK_TRIM_OOCHARS_LEFT -#define HAWK_TRIM_UCHARS_LEFT HAWK_TRIM_OOCHARS_LEFT -#define HAWK_TRIM_BCHARS_LEFT HAWK_TRIM_OOCHARS_LEFT - HAWK_TRIM_OOCHARS_RIGHT = (1 << 1) /**< trim trailing spaces */ -#define HAWK_TRIM_OOCHARS_RIGHT HAWK_TRIM_OOCHARS_RIGHT -#define HAWK_TRIM_UCHARS_RIGHT HAWK_TRIM_OOCHARS_RIGHT -#define HAWK_TRIM_BCHARS_RIGHT HAWK_TRIM_OOCHARS_RIGHT -}; - - /* ========================================================================= * CMGR * ========================================================================= */ @@ -390,77 +374,12 @@ HAWK_EXPORT hawk_oow_t hawk_hash_bytes_ ( * STRING * ========================================================================= */ -/** - * The hawk_equal_uchars() function determines equality of two strings - * of the same length \a len. - */ -HAWK_EXPORT int hawk_equal_uchars ( - const hawk_uch_t* str1, - const hawk_uch_t* str2, - hawk_oow_t len -); - -HAWK_EXPORT int hawk_equal_bchars ( - const hawk_bch_t* str1, - const hawk_bch_t* str2, - hawk_oow_t len -); - -HAWK_EXPORT int hawk_comp_uchars ( - const hawk_uch_t* str1, - hawk_oow_t len1, - const hawk_uch_t* str2, - hawk_oow_t len2, - int ignorecase -); - -HAWK_EXPORT int hawk_comp_bchars ( - const hawk_bch_t* str1, - hawk_oow_t len1, - const hawk_bch_t* str2, - hawk_oow_t len2, - int ignorecase -); - -HAWK_EXPORT int hawk_comp_ucstr ( - const hawk_uch_t* str1, - const hawk_uch_t* str2, - int ignorecase -); - -HAWK_EXPORT int hawk_comp_bcstr ( - const hawk_bch_t* str1, - const hawk_bch_t* str2, - int ignorecase -); - -HAWK_EXPORT int hawk_comp_ucstr_limited ( - const hawk_uch_t* str1, - const hawk_uch_t* str2, - hawk_oow_t maxlen, - int ignorecase -); - -HAWK_EXPORT int hawk_comp_bcstr_limited ( - const hawk_bch_t* str1, - const hawk_bch_t* str2, - hawk_oow_t maxlen, - int ignorecase -); - HAWK_EXPORT int hawk_comp_ucstr_bcstr ( const hawk_uch_t* str1, const hawk_bch_t* str2, int ignorecase ); -HAWK_EXPORT int hawk_comp_uchars_ucstr ( - const hawk_uch_t* str1, - hawk_oow_t len, - const hawk_uch_t* str2, - int ignorecase -); - HAWK_EXPORT int hawk_comp_uchars_bcstr ( const hawk_uch_t* str1, hawk_oow_t len, @@ -468,13 +387,6 @@ HAWK_EXPORT int hawk_comp_uchars_bcstr ( int ignorecase ); -HAWK_EXPORT int hawk_comp_bchars_bcstr ( - const hawk_bch_t* str1, - hawk_oow_t len, - const hawk_bch_t* str2, - int ignorecase -); - HAWK_EXPORT int hawk_comp_bchars_ucstr ( const hawk_bch_t* str1, hawk_oow_t len, @@ -482,366 +394,6 @@ HAWK_EXPORT int hawk_comp_bchars_ucstr ( int ignorecase ); -HAWK_EXPORT void hawk_copy_uchars ( - hawk_uch_t* dst, - const hawk_uch_t* src, - hawk_oow_t len -); - -HAWK_EXPORT void hawk_copy_bchars ( - hawk_bch_t* dst, - const hawk_bch_t* src, - hawk_oow_t len -); - -HAWK_EXPORT void hawk_copy_bchars_to_uchars ( - hawk_uch_t* dst, - const hawk_bch_t* src, - hawk_oow_t len -); -HAWK_EXPORT void hawk_copy_uchars_to_bchars ( - hawk_bch_t* dst, - const hawk_uch_t* src, - hawk_oow_t len -); - -HAWK_EXPORT hawk_oow_t hawk_copy_uchars_to_ucstr_unlimited ( - hawk_uch_t* dst, - const hawk_uch_t* src, - hawk_oow_t len -); - -HAWK_EXPORT hawk_oow_t hawk_copy_bchars_to_bcstr_unlimited ( - hawk_bch_t* dst, - const hawk_bch_t* src, - hawk_oow_t len -); - -HAWK_EXPORT hawk_oow_t hawk_copy_ucstr_to_uchars ( - hawk_uch_t* dst, - hawk_oow_t dlen, - const hawk_uch_t* src -); - -HAWK_EXPORT hawk_oow_t hawk_copy_bcstr_to_bchars ( - hawk_bch_t* dst, - hawk_oow_t dlen, - const hawk_bch_t* src -); - -HAWK_EXPORT hawk_oow_t hawk_copy_ucstr ( - hawk_uch_t* dst, - hawk_oow_t len, - const hawk_uch_t* src -); - -HAWK_EXPORT hawk_oow_t hawk_copy_bcstr ( - hawk_bch_t* dst, - hawk_oow_t len, - const hawk_bch_t* src -); - -HAWK_EXPORT hawk_oow_t hawk_copy_uchars_to_ucstr ( - hawk_uch_t* dst, - hawk_oow_t dlen, - const hawk_uch_t* src, - hawk_oow_t slen -); - -HAWK_EXPORT hawk_oow_t hawk_copy_bchars_to_bcstr ( - hawk_bch_t* dst, - hawk_oow_t dlen, - const hawk_bch_t* src, - hawk_oow_t slen -); - -HAWK_EXPORT hawk_oow_t hawk_copy_ucstr_unlimited ( - hawk_uch_t* dst, - const hawk_uch_t* src -); - -HAWK_EXPORT hawk_oow_t hawk_copy_bcstr_unlimited ( - hawk_bch_t* dst, - const hawk_bch_t* src -); - -HAWK_EXPORT hawk_oow_t hawk_copy_fmt_ucses_to_ucstr ( - hawk_uch_t* buf, - hawk_oow_t bsz, - const hawk_uch_t* fmt, - const hawk_ucs_t str[] -); - -HAWK_EXPORT hawk_oow_t hawk_copy_fmt_bcses_to_bcstr ( - hawk_bch_t* buf, - hawk_oow_t bsz, - const hawk_bch_t* fmt, - const hawk_bcs_t str[] -); - -HAWK_EXPORT hawk_oow_t hawk_count_ucstr ( - const hawk_uch_t* str -); - -HAWK_EXPORT hawk_oow_t hawk_count_ucstr_limited ( - const hawk_uch_t* str, - hawk_oow_t maxlen -); - -HAWK_EXPORT hawk_oow_t hawk_count_bcstr ( - const hawk_bch_t* str -); - -HAWK_EXPORT hawk_oow_t hawk_count_bcstr_limited ( - const hawk_bch_t* str, - hawk_oow_t maxlen -); - -HAWK_EXPORT void hawk_fill_uchars ( - hawk_uch_t* dst, - const hawk_uch_t ch, - hawk_oow_t len -); - -HAWK_EXPORT void hawk_fill_bchars ( - hawk_bch_t* dst, - const hawk_bch_t ch, - hawk_oow_t len -); - -HAWK_EXPORT hawk_uch_t* hawk_find_uchar_in_uchars ( - const hawk_uch_t* ptr, - hawk_oow_t len, - hawk_uch_t c -); - -HAWK_EXPORT hawk_bch_t* hawk_find_bchar_in_bchars ( - const hawk_bch_t* ptr, - hawk_oow_t len, - hawk_bch_t c -); - -HAWK_EXPORT hawk_uch_t* hawk_rfind_uchar_in_uchars ( - const hawk_uch_t* ptr, - hawk_oow_t len, - hawk_uch_t c -); - -HAWK_EXPORT hawk_bch_t* hawk_rfind_bchar_in_bchars ( - const hawk_bch_t* ptr, - hawk_oow_t len, - hawk_bch_t c -); - -HAWK_EXPORT hawk_uch_t* hawk_find_uchar_in_ucstr ( - const hawk_uch_t* ptr, - hawk_uch_t c -); - -HAWK_EXPORT hawk_uch_t* hawk_rfind_uchar_in_ucstr ( - const hawk_uch_t* ptr, - hawk_uch_t c -); - -HAWK_EXPORT hawk_bch_t* hawk_find_bchar_in_bcstr ( - const hawk_bch_t* ptr, - hawk_bch_t c -); - -HAWK_EXPORT hawk_bch_t* hawk_rfind_bchar_in_bcstr ( - const hawk_bch_t* ptr, - hawk_bch_t c -); - -HAWK_EXPORT hawk_uch_t* hawk_find_uchars_in_uchars ( - const hawk_uch_t* str, - hawk_oow_t strsz, - const hawk_uch_t* sub, - hawk_oow_t subsz, - int ignorecase -); - -HAWK_EXPORT hawk_bch_t* hawk_find_bchars_in_bchars ( - const hawk_bch_t* str, - hawk_oow_t strsz, - const hawk_bch_t* sub, - hawk_oow_t subsz, - int ignorecase -); - -HAWK_EXPORT hawk_uch_t* hawk_rfind_uchars_in_uchars ( - const hawk_uch_t* str, - hawk_oow_t strsz, - const hawk_uch_t* sub, - hawk_oow_t subsz, - int ignorecase -); - -HAWK_EXPORT hawk_bch_t* hawk_rfind_bchars_in_bchars ( - const hawk_bch_t* str, - hawk_oow_t strsz, - const hawk_bch_t* sub, - hawk_oow_t subsz, - int ignorecase -); - -HAWK_EXPORT hawk_oow_t hawk_compact_uchars ( - hawk_uch_t* str, - hawk_oow_t len -); - -HAWK_EXPORT hawk_oow_t hawk_compact_bchars ( - hawk_bch_t* str, - hawk_oow_t len -); - -HAWK_EXPORT hawk_oow_t hawk_rotate_uchars ( - hawk_uch_t* str, - hawk_oow_t len, - int dir, - hawk_oow_t n -); - -HAWK_EXPORT hawk_oow_t hawk_rotate_bchars ( - hawk_bch_t* str, - hawk_oow_t len, - int dir, - hawk_oow_t n -); - -HAWK_EXPORT hawk_uch_t* hawk_trim_uchars ( - const hawk_uch_t* str, - hawk_oow_t* len, - int flags -); - -HAWK_EXPORT hawk_bch_t* hawk_trim_bchars ( - const hawk_bch_t* str, - hawk_oow_t* len, - int flags -); - -HAWK_EXPORT int hawk_split_ucstr ( - hawk_uch_t* s, - const hawk_uch_t* delim, - hawk_uch_t lquote, - hawk_uch_t rquote, - hawk_uch_t escape -); - -HAWK_EXPORT int hawk_split_bcstr ( - hawk_bch_t* s, - const hawk_bch_t* delim, - hawk_bch_t lquote, - hawk_bch_t rquote, - hawk_bch_t escape -); - -HAWK_EXPORT hawk_uch_t* hawk_tokenize_uchars ( - const hawk_uch_t* s, - hawk_oow_t len, - const hawk_uch_t* delim, - hawk_oow_t delim_len, - hawk_ucs_t* tok, - int ignorecase -); - -HAWK_EXPORT hawk_bch_t* hawk_tokenize_bchars ( - const hawk_bch_t* s, - hawk_oow_t len, - const hawk_bch_t* delim, - hawk_oow_t delim_len, - hawk_bcs_t* tok, - int ignorecase -); - -#if defined(HAWK_OOCH_IS_UCH) -# define hawk_equal_oochars hawk_equal_uchars -# define hawk_comp_oochars hawk_comp_uchars -# define hawk_comp_oocstr_bcstr hawk_comp_ucstr_bcstr -# define hawk_comp_oochars_bcstr hawk_comp_uchars_bcstr -# define hawk_comp_oochars_ucstr hawk_comp_uchars_ucstr -# define hawk_comp_oochars_oocstr hawk_comp_uchars_ucstr -# define hawk_comp_oocstr hawk_comp_ucstr -# define hawk_comp_oocstr_limited hawk_comp_ucstr_limited - -# define hawk_copy_oochars hawk_copy_uchars -# define hawk_copy_bchars_to_oochars hawk_copy_bchars_to_uchars -# define hawk_copy_oochars_to_bchars hawk_copy_uchars_to_bchars -# define hawk_copy_uchars_to_oochars hawk_copy_uchars -# define hawk_copy_oochars_to_uchars hawk_copy_uchars - -# define hawk_copy_oochars_to_oocstr hawk_copy_uchars_to_ucstr -# define hawk_copy_oochars_to_oocstr_unlimited hawk_copy_uchars_to_ucstr_unlimited -# define hawk_copy_oocstr_to_oochars hawk_copy_ucstr_to_uchars -# define hawk_copy_oocstr hawk_copy_ucstr -# define hawk_copy_oocstr_unlimited hawk_copy_ucstr_unlimited - -# define hawk_copy_oofcs_to_oochars hawk_copy_fmt_ucses_to_ucstr - -# define hawk_count_oocstr hawk_count_ucstr -# define hawk_count_oocstr_limited hawk_count_ucstr_limited - -# define hawk_fill_oochars hawk_fill_uchars -# define hawk_find_oochar_in_oochars hawk_find_uchar_in_uchars -# define hawk_rfind_oochar_in_oochars hawk_rfind_uchar_in_uchars -# define hawk_find_oochar_in_oocstr hawk_find_uchar_in_ucstr -# define hawk_rfind_oochar_in_oocstr hawk_rfind_uchar_in_ucstr - -# define hawk_find_oochars_in_oochars hawk_find_uchars_in_uchars -# define hawk_rfind_oochars_in_oochars hawk_rfind_uchars_in_uchars - -# define hawk_compact_oochars hawk_compact_uchars -# define hawk_rotate_oochars hawk_rotate_uchars -# define hawk_trim_oochars hawk_trim_uchars - -# define hawk_split_oocstr hawk_split_ucstr -# define hawk_tokenize_oochars hawk_tokenize_uchars - -#else -# define hawk_equal_oochars hawk_equal_bchars -# define hawk_comp_oochars hawk_comp_bchars -# define hawk_comp_oocstr_bcstr hawk_comp_bcstr -# define hawk_comp_oochars_bcstr hawk_comp_bchars_bcstr -# define hawk_comp_oochars_ucstr hawk_comp_bchars_ucstr -# define hawk_comp_oochars_oocstr hawk_comp_bchars_bcstr -# define hawk_comp_oocstr hawk_comp_bcstr -# define hawk_comp_oocstr_limited hawk_comp_bcstr_limited - -# define hawk_copy_oochars hawk_copy_bchars -# define hawk_copy_bchars_to_oochars hawk_copy_bchars -# define hawk_copy_oochars_to_bchars hawk_copy_bchars -# define hawk_copy_uchars_to_oochars hawk_copy_uchars_to_bchars -# define hawk_copy_oochars_to_uchars hawk_copy_bchars_to_uchars - -# define hawk_copy_oochars_to_oocstr hawk_copy_bchars_to_bcstr -# define hawk_copy_oochars_to_oocstr_unlimited hawk_copy_bchars_to_bcstr_unlimited -# define hawk_copy_oocstr_to_oochars hawk_copy_bcstr_to_bchars -# define hawk_copy_oocstr hawk_copy_bcstr -# define hawk_copy_oocstr_unlimited hawk_copy_bcstr_unlimited - -# define hawk_copy_oofcs_to_oochars hawk_copy_fmt_bcses_to_bcstr - -# define hawk_count_oocstr hawk_count_bcstr -# define hawk_count_oocstr_limited hawk_count_bcstr_limited - -# define hawk_fill_oochars hawk_fill_bchars -# define hawk_find_oochar_in_oochars hawk_find_bchar_in_bchars -# define hawk_rfind_oochar_in_oochars hawk_rfind_bchar_in_bchars -# define hawk_find_oochar_in_oocstr hawk_find_bchar_in_bcstr -# define hawk_rfind_oochar_in_oocstr hawk_rfind_bchar_in_bcstr - -# define hawk_find_oochars_in_oochars hawk_find_bchars_in_bchars -# define hawk_rfind_oochars_in_oochars hawk_rfind_bchars_in_bchars - -# define hawk_compact_oochars hawk_compact_bchars -# define hawk_rotate_oochars hawk_rotate_bchars -# define hawk_trim_oochars hawk_trim_bchars - -# define hawk_split_oocstr hawk_split_bcstr -# define hawk_tokenize_oochars hawk_tokenize_bchars -#endif - /* ------------------------------------------------------------------------- */ HAWK_EXPORT hawk_oow_t hawk_subst_for_uchars_to_ucstr ( @@ -1237,41 +789,6 @@ HAWK_EXPORT int hawk_conv_mb8_to_ucs ( hawk_oow_t* ucslen ); -/* ========================================================================= - * NUMBER TO STRING CONVERSION - * ========================================================================= */ - -#define HAWK_BYTE_TO_OOCSTR_RADIXMASK (0xFF) -#define HAWK_BYTE_TO_OOCSTR_LOWERCASE (1 << 8) - -#define HAWK_BYTE_TO_UCSTR_RADIXMASK HAWK_BYTE_TO_OOCSTR_RADIXMASK -#define HAWK_BYTE_TO_UCSTR_LOWERCASE HAWK_BYTE_TO_OOCSTR_LOWERCASE - -#define HAWK_BYTE_TO_BCSTR_RADIXMASK HAWK_BYTE_TO_OOCSTR_RADIXMASK -#define HAWK_BYTE_TO_BCSTR_LOWERCASE HAWK_BYTE_TO_OOCSTR_LOWERCASE - -hawk_oow_t hawk_byte_to_ucstr ( - hawk_oob_t byte, - hawk_uch_t* buf, - hawk_oow_t size, - int flagged_radix, - hawk_uch_t fill -); - -hawk_oow_t hawk_byte_to_bcstr ( - hawk_uint8_t byte, - hawk_bch_t* buf, - hawk_oow_t size, - int flagged_radix, - hawk_bch_t fill -); - -#if defined(HAWK_OOCH_IS_UCH) -# define hawk_byte_to_oocstr hawk_byte_to_ucstr -#else -# define hawk_byte_to_oocstr hawk_byte_to_bcstr -#endif - /* ========================================================================= * PATH STRING * ========================================================================= */ diff --git a/hawk/lib/utl-str.c b/hawk/lib/utl-str.c index 9023070c..6aaa69f7 100644 --- a/hawk/lib/utl-str.c +++ b/hawk/lib/utl-str.c @@ -22,17 +22,16 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +/* + * 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 + */ + +#include "hawk-prv.h" #include -/* some naming conventions - * bchars, uchars -> pointer and length - * bcstr, ucstr -> null-terminated string pointer - * btouchars -> bchars to uchars - * utobchars -> uchars to bchars - * btoucstr -> bcstr to ucstr - * utobcstr -> ucstr to bcstr - */ int hawk_comp_uchars (const hawk_uch_t* str1, hawk_oow_t len1, const hawk_uch_t* str2, hawk_oow_t len2, int ignorecase) { @@ -194,13 +193,13 @@ int hawk_comp_bcstr_limited (const hawk_bch_t* str1, const hawk_bch_t* str2, haw if (ignorecase) { - while (hawk_to_uch_lower(*str1) == hawk_to_uch_lower(*str2)) + while (hawk_to_bch_lower(*str1) == hawk_to_bch_lower(*str2)) { if (*str1 == '\0' || maxlen == 1) return 0; str1++; str2++; maxlen--; } - return ((hawk_bchu_t)hawk_to_uch_lower(*str1) > (hawk_bchu_t)hawk_to_uch_lower(*str2))? 1: -1; + return ((hawk_bchu_t)hawk_to_bch_lower(*str1) > (hawk_bchu_t)hawk_to_bch_lower(*str2))? 1: -1; } else { @@ -264,7 +263,7 @@ int hawk_comp_bchars_bcstr (const hawk_bch_t* str1, hawk_oow_t len, const hawk_b if (c1 != c2) return ((hawk_bchu_t)c1 > (hawk_bchu_t)c2)? 1: -1; str1++; str2++; } - return (str1 < end)? 1: (*str2 == '\0'? 0: -1); + return (str1 < end)? 1: (*str2 == '\0'? 0: -1); } else { @@ -278,7 +277,6 @@ int hawk_comp_bchars_bcstr (const hawk_bch_t* str1, hawk_oow_t len, const hawk_b } } -/* ------------------------------------------------------------------------ */ hawk_oow_t hawk_concat_uchars_to_ucstr (hawk_uch_t* buf, hawk_oow_t bsz, const hawk_uch_t* str, hawk_oow_t len) { hawk_uch_t* p, * p2; @@ -419,12 +417,12 @@ hawk_oow_t hawk_copy_bchars_to_bcstr_unlimited (hawk_bch_t* dst, const hawk_bch_ return i; } -hawk_oow_t hawk_copy_ucstr_to_uchars (hawk_uch_t* dst, hawk_oow_t dlen, const hawk_uch_t* src) +hawk_oow_t hawk_copy_ucstr_to_uchars (hawk_uch_t* dst, hawk_oow_t len, const hawk_uch_t* src) { /* no null termination */ hawk_uch_t* p, * p2; - p = dst; p2 = dst + dlen; + p = dst; p2 = dst + len - 1; while (p < p2) { @@ -435,12 +433,12 @@ hawk_oow_t hawk_copy_ucstr_to_uchars (hawk_uch_t* dst, hawk_oow_t dlen, const ha return p - dst; } -hawk_oow_t hawk_copy_bcstr_to_bchars (hawk_bch_t* dst, hawk_oow_t dlen, const hawk_bch_t* src) +hawk_oow_t hawk_copy_bcstr_to_bchars (hawk_bch_t* dst, hawk_oow_t len, const hawk_bch_t* src) { /* no null termination */ hawk_bch_t* p, * p2; - p = dst; p2 = dst + dlen; + p = dst; p2 = dst + len - 1; while (p < p2) { @@ -459,8 +457,8 @@ hawk_oow_t hawk_copy_ucstr (hawk_uch_t* dst, hawk_oow_t len, const hawk_uch_t* s while (p < p2) { - if (*src == '\0') break; - *p++ = *src++; + if (*src == '\0') break; + *p++ = *src++; } if (len > 0) *p = '\0'; @@ -475,8 +473,8 @@ hawk_oow_t hawk_copy_bcstr (hawk_bch_t* dst, hawk_oow_t len, const hawk_bch_t* s while (p < p2) { - if (*src == '\0') break; - *p++ = *src++; + if (*src == '\0') break; + *p++ = *src++; } if (len > 0) *p = '\0'; @@ -502,58 +500,57 @@ hawk_oow_t hawk_copy_fmt_ucstrs_to_ucstr (hawk_uch_t* buf, hawk_oow_t bsz, const hawk_uch_t* b = buf; hawk_uch_t* end = buf + bsz - 1; const hawk_uch_t* f = fmt; - + if (bsz <= 0) return 0; - - while (*f != HAWK_UT('\0')) + + while (*f != '\0') { - if (*f == HAWK_UT('\\')) + if (*f == '\\') { /* get the escaped character and treat it normally. - * if the escaper is the last character, treat it + * if the escaper is the last character, treat it * normally also. */ - if (f[1] != HAWK_UT('\0')) f++; + if (f[1] != '\0') f++; } - else if (*f == HAWK_UT('$')) + else if (*f == '$') { - if (f[1] == HAWK_UT('{') && - (f[2] >= HAWK_UT('0') && f[2] <= HAWK_UT('9'))) + if (f[1] == '{' && (f[2] >= '0' && f[2] <= '9')) { const hawk_uch_t* tmp; hawk_oow_t idx = 0; - + tmp = f; f += 2; - - do idx = idx * 10 + (*f++ - HAWK_UT('0')); - while (*f >= HAWK_UT('0') && *f <= HAWK_UT('9')); - - if (*f != HAWK_UT('}')) + + do idx = idx * 10 + (*f++ - '0'); + while (*f >= '0' && *f <= '9'); + + if (*f != '}') { f = tmp; goto normal; } - + f++; - + tmp = str[idx]; - while (*tmp != HAWK_UT('\0')) + while (*tmp != '\0') { if (b >= end) goto fini; *b++ = *tmp++; } continue; } - else if (f[1] == HAWK_UT('$')) f++; + else if (f[1] == '$') f++; } - + normal: if (b >= end) break; *b++ = *f++; } - + fini: - *b = HAWK_UT('\0'); + *b = '\0'; return b - buf; } @@ -562,58 +559,57 @@ hawk_oow_t hawk_copy_fmt_bcstrs_to_bcstr (hawk_bch_t* buf, hawk_oow_t bsz, const hawk_bch_t* b = buf; hawk_bch_t* end = buf + bsz - 1; const hawk_bch_t* f = fmt; - + if (bsz <= 0) return 0; - - while (*f != HAWK_BT('\0')) + + while (*f != '\0') { - if (*f == HAWK_BT('\\')) + if (*f == '\\') { /* get the escaped character and treat it normally. - * if the escaper is the last character, treat it + * if the escaper is the last character, treat it * normally also. */ - if (f[1] != HAWK_BT('\0')) f++; + if (f[1] != '\0') f++; } - else if (*f == HAWK_BT('$')) + else if (*f == '$') { - if (f[1] == HAWK_BT('{') && - (f[2] >= HAWK_BT('0') && f[2] <= HAWK_BT('9'))) + if (f[1] == '{' && (f[2] >= '0' && f[2] <= '9')) { const hawk_bch_t* tmp; hawk_oow_t idx = 0; - + tmp = f; f += 2; - - do idx = idx * 10 + (*f++ - HAWK_BT('0')); - while (*f >= HAWK_BT('0') && *f <= HAWK_BT('9')); - - if (*f != HAWK_BT('}')) + + do idx = idx * 10 + (*f++ - '0'); + while (*f >= '0' && *f <= '9'); + + if (*f != '}') { f = tmp; goto normal; } - + f++; - + tmp = str[idx]; - while (*tmp != HAWK_BT('\0')) + while (*tmp != '\0') { if (b >= end) goto fini; *b++ = *tmp++; } continue; } - else if (f[1] == HAWK_BT('$')) f++; + else if (f[1] == '$') f++; } - + normal: if (b >= end) break; *b++ = *f++; } - + fini: - *b = HAWK_BT('\0'); + *b = '\0'; return b - buf; } @@ -625,19 +621,18 @@ hawk_oow_t hawk_copy_fmt_ucses_to_ucstr (hawk_uch_t* buf, hawk_oow_t bsz, const if (bsz <= 0) return 0; - while (*f != HAWK_UT('\0')) + while (*f != '\0') { - if (*f == HAWK_UT('\\')) + if (*f == '\\') { /* get the escaped character and treat it normally. * if the escaper is the last character, treat it * normally also. */ - if (f[1] != HAWK_UT('\0')) f++; + if (f[1] != '\0') f++; } - else if (*f == HAWK_UT('$')) + else if (*f == '$') { - if (f[1] == HAWK_UT('{') && - (f[2] >= HAWK_UT('0') && f[2] <= HAWK_UT('9'))) + if (f[1] == '{' && (f[2] >= '0' && f[2] <= '9')) { const hawk_uch_t* tmp, * tmpend; hawk_oow_t idx = 0; @@ -645,10 +640,10 @@ hawk_oow_t hawk_copy_fmt_ucses_to_ucstr (hawk_uch_t* buf, hawk_oow_t bsz, const tmp = f; f += 2; - do idx = idx * 10 + (*f++ - HAWK_UT('0')); - while (*f >= HAWK_UT('0') && *f <= HAWK_UT('9')); + do idx = idx * 10 + (*f++ - '0'); + while (*f >= '0' && *f <= '9'); - if (*f != HAWK_UT('}')) + if (*f != '}') { f = tmp; goto normal; @@ -666,7 +661,7 @@ hawk_oow_t hawk_copy_fmt_ucses_to_ucstr (hawk_uch_t* buf, hawk_oow_t bsz, const } continue; } - else if (f[1] == HAWK_UT('$')) f++; + else if (f[1] == '$') f++; } normal: @@ -675,7 +670,7 @@ hawk_oow_t hawk_copy_fmt_ucses_to_ucstr (hawk_uch_t* buf, hawk_oow_t bsz, const } fini: - *b = HAWK_UT('\0'); + *b = '\0'; return b - buf; } @@ -687,19 +682,18 @@ hawk_oow_t hawk_copy_fmt_bcses_to_bcstr (hawk_bch_t* buf, hawk_oow_t bsz, const if (bsz <= 0) return 0; - while (*f != HAWK_BT('\0')) + while (*f != '\0') { - if (*f == HAWK_BT('\\')) + if (*f == '\\') { /* get the escaped character and treat it normally. * if the escaper is the last character, treat it * normally also. */ - if (f[1] != HAWK_BT('\0')) f++; + if (f[1] != '\0') f++; } - else if (*f == HAWK_BT('$')) + else if (*f == '$') { - if (f[1] == HAWK_BT('{') && - (f[2] >= HAWK_BT('0') && f[2] <= HAWK_BT('9'))) + if (f[1] == '{' && (f[2] >= '0' && f[2] <= '9')) { const hawk_bch_t* tmp, * tmpend; hawk_oow_t idx = 0; @@ -707,10 +701,10 @@ hawk_oow_t hawk_copy_fmt_bcses_to_bcstr (hawk_bch_t* buf, hawk_oow_t bsz, const tmp = f; f += 2; - do idx = idx * 10 + (*f++ - HAWK_BT('0')); - while (*f >= HAWK_BT('0') && *f <= HAWK_BT('9')); + do idx = idx * 10 + (*f++ - '0'); + while (*f >= '0' && *f <= '9'); - if (*f != HAWK_BT('}')) + if (*f != '}') { f = tmp; goto normal; @@ -728,7 +722,7 @@ hawk_oow_t hawk_copy_fmt_bcses_to_bcstr (hawk_bch_t* buf, hawk_oow_t bsz, const } continue; } - else if (f[1] == HAWK_BT('$')) f++; + else if (f[1] == '$') f++; } normal: @@ -737,26 +731,23 @@ hawk_oow_t hawk_copy_fmt_bcses_to_bcstr (hawk_bch_t* buf, hawk_oow_t bsz, const } fini: - *b = HAWK_BT('\0'); + *b = '\0'; return b - buf; } - -/* ------------------------------------------------------------------------ */ - hawk_oow_t hawk_count_ucstr (const hawk_uch_t* str) { const hawk_uch_t* ptr = str; while (*ptr != '\0') ptr++; return ptr - str; -} +} hawk_oow_t hawk_count_bcstr (const hawk_bch_t* str) { const hawk_bch_t* ptr = str; while (*ptr != '\0') ptr++; return ptr - str; -} +} hawk_oow_t hawk_count_ucstr_limited (const hawk_uch_t* str, hawk_oow_t maxlen) { @@ -778,13 +769,11 @@ hawk_oow_t hawk_count_bcstr_limited (const hawk_bch_t* str, hawk_oow_t maxlen) return i; } -/* ------------------------------------------------------------------------ */ - int hawk_equal_uchars (const hawk_uch_t* str1, const hawk_uch_t* str2, hawk_oow_t len) { hawk_oow_t i; - /* [NOTE] you should call this function after having ensured that + /* NOTE: you should call this function after having ensured that * str1 and str2 are in the same length */ for (i = 0; i < len; i++) @@ -799,8 +788,8 @@ int hawk_equal_bchars (const hawk_bch_t* str1, const hawk_bch_t* str2, hawk_oow_ { hawk_oow_t i; - /* [NOTE] you should call this function after having ensured that - * str1 and str2 are in the same length */ + /* NOTE: you should call this function after having ensured that + * str1 and str2 are in the same length */ for (i = 0; i < len; i++) { @@ -809,22 +798,19 @@ int hawk_equal_bchars (const hawk_bch_t* str1, const hawk_bch_t* str2, hawk_oow_ return 1; } -/* ------------------------------------------------------------------------ */ void hawk_fill_uchars (hawk_uch_t* dst, hawk_uch_t ch, hawk_oow_t len) { - hawk_oow_t i; - for (i = 0; i < len; i++) dst[i] = ch; + hawk_oow_t i; + for (i = 0; i < len; i++) dst[i] = ch; } void hawk_fill_bchars (hawk_bch_t* dst, hawk_bch_t ch, hawk_oow_t len) { - hawk_oow_t i; - for (i = 0; i < len; i++) dst[i] = ch; + hawk_oow_t i; + for (i = 0; i < len; i++) dst[i] = ch; } -/* ------------------------------------------------------------------------ */ - hawk_uch_t* hawk_find_uchar_in_uchars (const hawk_uch_t* ptr, hawk_oow_t len, hawk_uch_t c) { const hawk_uch_t* end; @@ -903,17 +889,33 @@ hawk_bch_t* hawk_find_bchar_in_bcstr (const hawk_bch_t* ptr, hawk_bch_t c) return HAWK_NULL; } -hawk_uch_t* hawk_rfind_uchar_in_ucstr (const hawk_uch_t* ptr, hawk_uch_t c) +hawk_uch_t* hawk_rfind_uchar_in_ucstr (const hawk_uch_t* str, hawk_uch_t c) { - return hawk_rfind_uchar_in_uchars(ptr, hawk_count_ucstr(ptr), c); + const hawk_uch_t* ptr = str; + while (*ptr != '\0') ptr++; + + while (ptr > str) + { + --ptr; + if (*ptr == c) return (hawk_uch_t*)ptr; + } + + return HAWK_NULL; } -hawk_bch_t* hawk_rfind_bchar_in_bcstr (const hawk_bch_t* ptr, hawk_bch_t c) +hawk_bch_t* hawk_rfind_bchar_in_bcstr (const hawk_bch_t* str, hawk_bch_t c) { - return hawk_rfind_bchar_in_bchars(ptr, hawk_count_bcstr(ptr), c); -} + const hawk_bch_t* ptr = str; + while (*ptr != '\0') ptr++; -/* ------------------------------------------------------------------------ */ + while (ptr > str) + { + --ptr; + if (*ptr == c) return (hawk_bch_t*)ptr; + } + + return HAWK_NULL; +} hawk_uch_t* hawk_find_uchars_in_uchars (const hawk_uch_t* str, hawk_oow_t strsz, const hawk_uch_t* sub, hawk_oow_t subsz, int ignorecase) { @@ -985,7 +987,7 @@ hawk_bch_t* hawk_find_bchars_in_bchars (const hawk_bch_t* str, hawk_oow_t strsz, if (y >= subp) return (hawk_bch_t*)str; if (hawk_to_bch_lower(*x) != hawk_to_bch_lower(*y)) break; x++; y++; - } + } str++; } @@ -1002,7 +1004,7 @@ hawk_bch_t* hawk_find_bchars_in_bchars (const hawk_bch_t* str, hawk_oow_t strsz, if (y >= subp) return (hawk_bch_t*)str; if (*x != *y) break; x++; y++; - } + } str++; } @@ -1098,7 +1100,7 @@ hawk_bch_t* hawk_rfind_bchars_in_bchars (const hawk_bch_t* str, hawk_oow_t strsz if (y >= subp) return (hawk_bch_t*)p; if (*x != *y) break; x++; y++; - } + } p--; } @@ -1107,8 +1109,6 @@ hawk_bch_t* hawk_rfind_bchars_in_bchars (const hawk_bch_t* str, hawk_oow_t strsz return HAWK_NULL; } -/* ------------------------------------------------------------------------ */ - hawk_oow_t hawk_compact_uchars (hawk_uch_t* str, hawk_oow_t len) { hawk_uch_t* p = str, * q = str, * end = str + len; @@ -1187,8 +1187,6 @@ hawk_oow_t hawk_compact_bchars (hawk_bch_t* str, hawk_oow_t len) return (followed_by_space) ? (q - str -1): (q - str); } -/* ------------------------------------------------------------------------ */ - hawk_oow_t hawk_rotate_uchars (hawk_uch_t* str, hawk_oow_t len, int dir, hawk_oow_t n) { hawk_oow_t first, last, count, index, nk; @@ -1257,8 +1255,6 @@ hawk_oow_t hawk_rotate_bchars (hawk_bch_t* str, hawk_oow_t len, int dir, hawk_oo return len; } -/* ------------------------------------------------------------------------ */ - hawk_uch_t* hawk_trim_uchars (const hawk_uch_t* str, hawk_oow_t* len, int flags) { const hawk_uch_t* p = str, * end = str + *len; @@ -1342,7 +1338,6 @@ hawk_bch_t* hawk_trim_bchars (const hawk_bch_t* str, hawk_oow_t* len, int flags) return (hawk_bch_t*)str; } -/* ------------------------------------------------------------------------ */ int hawk_split_ucstr (hawk_uch_t* s, const hawk_uch_t* delim, hawk_uch_t lquote, hawk_uch_t rquote, hawk_uch_t escape) { @@ -1355,7 +1350,7 @@ int hawk_split_ucstr (hawk_uch_t* s, const hawk_uch_t* delim, hawk_uch_t lquote, else { delim_mode = 1; - for (d = (hawk_uch_t*)delim; *d != HAWK_UT('\0'); d++) + for (d = (hawk_uch_t*)delim; *d != '\0'; d++) if (!hawk_is_uch_space(*d)) delim_mode = 2; } @@ -1366,15 +1361,15 @@ int hawk_split_ucstr (hawk_uch_t* s, const hawk_uch_t* delim, hawk_uch_t lquote, /* when 0 is given as "delim", it has an effect of cutting preceding and trailing space characters off "s". */ - if (lquote != HAWK_UT('\0') && *p == lquote) + if (lquote != '\0' && *p == lquote) { hawk_copy_ucstr_unlimited (p, p + 1); for (;;) { - if (*p == HAWK_UT('\0')) return -1; + if (*p == '\0') return -1; - if (escape != HAWK_UT('\0') && *p == escape) + if (escape != '\0' && *p == escape) { hawk_copy_ucstr_unlimited (p, p + 1); } @@ -1392,12 +1387,12 @@ int hawk_split_ucstr (hawk_uch_t* s, const hawk_uch_t* delim, hawk_uch_t lquote, p++; } while (hawk_is_uch_space(*p)) p++; - if (*p != HAWK_UT('\0')) return -1; + if (*p != '\0') return -1; - if (sp == 0 && ep == 0) s[0] = HAWK_UT('\0'); + if (sp == 0 && ep == 0) s[0] = '\0'; else { - ep[1] = HAWK_UT('\0'); + ep[1] = '\0'; if (s != (hawk_uch_t*)sp) hawk_copy_ucstr_unlimited (s, sp); cnt++; } @@ -1414,10 +1409,10 @@ int hawk_split_ucstr (hawk_uch_t* s, const hawk_uch_t* delim, hawk_uch_t lquote, p++; } - if (sp == 0 && ep == 0) s[0] = HAWK_UT('\0'); + if (sp == 0 && ep == 0) s[0] = '\0'; else { - ep[1] = HAWK_UT('\0'); + ep[1] = '\0'; if (s != (hawk_uch_t*)sp) hawk_copy_ucstr_unlimited (s, sp); cnt++; } @@ -1433,15 +1428,15 @@ int hawk_split_ucstr (hawk_uch_t* s, const hawk_uch_t* delim, hawk_uch_t lquote, while (hawk_is_uch_space(*p)) p++; if (o != p) { hawk_copy_ucstr_unlimited (o, p); p = o; } - if (lquote != HAWK_UT('\0') && *p == lquote) + if (lquote != '\0' && *p == lquote) { hawk_copy_ucstr_unlimited (p, p + 1); for (;;) { - if (*p == HAWK_UT('\0')) return -1; + if (*p == '\0') return -1; - if (escape != HAWK_UT('\0') && *p == escape) + if (escape != '\0' && *p == escape) { hawk_copy_ucstr_unlimited (p, p + 1); } @@ -1449,7 +1444,7 @@ int hawk_split_ucstr (hawk_uch_t* s, const hawk_uch_t* delim, hawk_uch_t lquote, { if (*p == rquote) { - *p++ = HAWK_UT('\0'); + *p++ = '\0'; cnt++; break; } @@ -1462,14 +1457,14 @@ int hawk_split_ucstr (hawk_uch_t* s, const hawk_uch_t* delim, hawk_uch_t lquote, o = p; for (;;) { - if (*p == HAWK_UT('\0')) + if (*p == '\0') { if (o != p) cnt++; break; } - if (hawk_is_uch_space (*p)) + if (hawk_is_uch_space(*p)) { - *p++ = HAWK_UT('\0'); + *p++ = '\0'; cnt++; break; } @@ -1483,21 +1478,21 @@ int hawk_split_ucstr (hawk_uch_t* s, const hawk_uch_t* delim, hawk_uch_t lquote, hawk_uch_t* o; int ok; - while (*p != HAWK_UT('\0')) + while (*p != '\0') { o = p; while (hawk_is_uch_space(*p)) p++; if (o != p) { hawk_copy_ucstr_unlimited (o, p); p = o; } - if (lquote != HAWK_UT('\0') && *p == lquote) + if (lquote != '\0' && *p == lquote) { hawk_copy_ucstr_unlimited (p, p + 1); for (;;) { - if (*p == HAWK_UT('\0')) return -1; + if (*p == '\0') return -1; - if (escape != HAWK_UT('\0') && *p == escape) + if (escape != '\0' && *p == escape) { hawk_copy_ucstr_unlimited (p, p + 1); } @@ -1505,7 +1500,7 @@ int hawk_split_ucstr (hawk_uch_t* s, const hawk_uch_t* delim, hawk_uch_t lquote, { if (*p == rquote) { - *p++ = HAWK_UT('\0'); + *p++ = '\0'; cnt++; break; } @@ -1515,8 +1510,8 @@ int hawk_split_ucstr (hawk_uch_t* s, const hawk_uch_t* delim, hawk_uch_t lquote, ok = 0; while (hawk_is_uch_space(*p)) p++; - if (*p == HAWK_UT('\0')) ok = 1; - for (d = (hawk_uch_t*)delim; *d != HAWK_UT('\0'); d++) + if (*p == '\0') ok = 1; + for (d = (hawk_uch_t*)delim; *d != '\0'; d++) { if (*p == *d) { @@ -1533,40 +1528,40 @@ int hawk_split_ucstr (hawk_uch_t* s, const hawk_uch_t* delim, hawk_uch_t lquote, for (;;) { - if (*p == HAWK_UT('\0')) + if (*p == '\0') { if (ep) { - ep[1] = HAWK_UT('\0'); + ep[1] = '\0'; p = &ep[1]; } cnt++; break; } - for (d = (hawk_uch_t*)delim; *d != HAWK_UT('\0'); d++) + for (d = (hawk_uch_t*)delim; *d != '\0'; d++) { if (*p == *d) { if (sp == HAWK_NULL) { hawk_copy_ucstr_unlimited (o, p); p = o; - *p++ = HAWK_UT('\0'); + *p++ = '\0'; } else { hawk_copy_ucstr_unlimited (&ep[1], p); hawk_copy_ucstr_unlimited (o, sp); - o[ep - sp + 1] = HAWK_UT('\0'); + o[ep - sp + 1] = '\0'; p = &o[ep - sp + 2]; } cnt++; /* last empty field after delim */ - if (*p == HAWK_UT('\0')) cnt++; + if (*p == '\0') cnt++; goto exit_point; } } - if (!hawk_is_uch_space (*p)) + if (!hawk_is_uch_space(*p)) { if (sp == HAWK_NULL) sp = p; ep = p; @@ -1593,7 +1588,7 @@ int hawk_split_bcstr (hawk_bch_t* s, const hawk_bch_t* delim, hawk_bch_t lquote, else { delim_mode = 1; - for (d = (hawk_bch_t*)delim; *d != HAWK_BT('\0'); d++) + for (d = (hawk_bch_t*)delim; *d != '\0'; d++) if (!hawk_is_bch_space(*d)) delim_mode = 2; } @@ -1604,15 +1599,15 @@ int hawk_split_bcstr (hawk_bch_t* s, const hawk_bch_t* delim, hawk_bch_t lquote, /* when 0 is given as "delim", it has an effect of cutting preceding and trailing space characters off "s". */ - if (lquote != HAWK_BT('\0') && *p == lquote) + if (lquote != '\0' && *p == lquote) { hawk_copy_bcstr_unlimited (p, p + 1); for (;;) { - if (*p == HAWK_BT('\0')) return -1; + if (*p == '\0') return -1; - if (escape != HAWK_BT('\0') && *p == escape) + if (escape != '\0' && *p == escape) { hawk_copy_bcstr_unlimited (p, p + 1); } @@ -1630,12 +1625,12 @@ int hawk_split_bcstr (hawk_bch_t* s, const hawk_bch_t* delim, hawk_bch_t lquote, p++; } while (hawk_is_bch_space(*p)) p++; - if (*p != HAWK_BT('\0')) return -1; + if (*p != '\0') return -1; - if (sp == 0 && ep == 0) s[0] = HAWK_BT('\0'); + if (sp == 0 && ep == 0) s[0] = '\0'; else { - ep[1] = HAWK_BT('\0'); + ep[1] = '\0'; if (s != (hawk_bch_t*)sp) hawk_copy_bcstr_unlimited (s, sp); cnt++; } @@ -1652,10 +1647,10 @@ int hawk_split_bcstr (hawk_bch_t* s, const hawk_bch_t* delim, hawk_bch_t lquote, p++; } - if (sp == 0 && ep == 0) s[0] = HAWK_BT('\0'); + if (sp == 0 && ep == 0) s[0] = '\0'; else { - ep[1] = HAWK_BT('\0'); + ep[1] = '\0'; if (s != (hawk_bch_t*)sp) hawk_copy_bcstr_unlimited (s, sp); cnt++; } @@ -1671,15 +1666,15 @@ int hawk_split_bcstr (hawk_bch_t* s, const hawk_bch_t* delim, hawk_bch_t lquote, while (hawk_is_bch_space(*p)) p++; if (o != p) { hawk_copy_bcstr_unlimited (o, p); p = o; } - if (lquote != HAWK_BT('\0') && *p == lquote) + if (lquote != '\0' && *p == lquote) { hawk_copy_bcstr_unlimited (p, p + 1); for (;;) { - if (*p == HAWK_BT('\0')) return -1; + if (*p == '\0') return -1; - if (escape != HAWK_BT('\0') && *p == escape) + if (escape != '\0' && *p == escape) { hawk_copy_bcstr_unlimited (p, p + 1); } @@ -1687,7 +1682,7 @@ int hawk_split_bcstr (hawk_bch_t* s, const hawk_bch_t* delim, hawk_bch_t lquote, { if (*p == rquote) { - *p++ = HAWK_BT('\0'); + *p++ = '\0'; cnt++; break; } @@ -1700,14 +1695,14 @@ int hawk_split_bcstr (hawk_bch_t* s, const hawk_bch_t* delim, hawk_bch_t lquote, o = p; for (;;) { - if (*p == HAWK_BT('\0')) + if (*p == '\0') { if (o != p) cnt++; break; } - if (hawk_is_bch_space (*p)) + if (hawk_is_bch_space(*p)) { - *p++ = HAWK_BT('\0'); + *p++ = '\0'; cnt++; break; } @@ -1721,21 +1716,21 @@ int hawk_split_bcstr (hawk_bch_t* s, const hawk_bch_t* delim, hawk_bch_t lquote, hawk_bch_t* o; int ok; - while (*p != HAWK_BT('\0')) + while (*p != '\0') { o = p; while (hawk_is_bch_space(*p)) p++; if (o != p) { hawk_copy_bcstr_unlimited (o, p); p = o; } - if (lquote != HAWK_BT('\0') && *p == lquote) + if (lquote != '\0' && *p == lquote) { hawk_copy_bcstr_unlimited (p, p + 1); for (;;) { - if (*p == HAWK_BT('\0')) return -1; + if (*p == '\0') return -1; - if (escape != HAWK_BT('\0') && *p == escape) + if (escape != '\0' && *p == escape) { hawk_copy_bcstr_unlimited (p, p + 1); } @@ -1743,7 +1738,7 @@ int hawk_split_bcstr (hawk_bch_t* s, const hawk_bch_t* delim, hawk_bch_t lquote, { if (*p == rquote) { - *p++ = HAWK_BT('\0'); + *p++ = '\0'; cnt++; break; } @@ -1753,8 +1748,8 @@ int hawk_split_bcstr (hawk_bch_t* s, const hawk_bch_t* delim, hawk_bch_t lquote, ok = 0; while (hawk_is_bch_space(*p)) p++; - if (*p == HAWK_BT('\0')) ok = 1; - for (d = (hawk_bch_t*)delim; *d != HAWK_BT('\0'); d++) + if (*p == '\0') ok = 1; + for (d = (hawk_bch_t*)delim; *d != '\0'; d++) { if (*p == *d) { @@ -1771,40 +1766,40 @@ int hawk_split_bcstr (hawk_bch_t* s, const hawk_bch_t* delim, hawk_bch_t lquote, for (;;) { - if (*p == HAWK_BT('\0')) + if (*p == '\0') { if (ep) { - ep[1] = HAWK_BT('\0'); + ep[1] = '\0'; p = &ep[1]; } cnt++; break; } - for (d = (hawk_bch_t*)delim; *d != HAWK_BT('\0'); d++) + for (d = (hawk_bch_t*)delim; *d != '\0'; d++) { if (*p == *d) { if (sp == HAWK_NULL) { hawk_copy_bcstr_unlimited (o, p); p = o; - *p++ = HAWK_BT('\0'); + *p++ = '\0'; } else { hawk_copy_bcstr_unlimited (&ep[1], p); hawk_copy_bcstr_unlimited (o, sp); - o[ep - sp + 1] = HAWK_BT('\0'); + o[ep - sp + 1] = '\0'; p = &o[ep - sp + 2]; } cnt++; /* last empty field after delim */ - if (*p == HAWK_BT('\0')) cnt++; + if (*p == '\0') cnt++; goto exit_point; } } - if (!hawk_is_bch_space (*p)) + if (!hawk_is_bch_space(*p)) { if (sp == HAWK_NULL) sp = p; ep = p; @@ -1820,7 +1815,6 @@ exit_point: return cnt; } -/* ------------------------------------------------------------------------ */ hawk_uch_t* hawk_tokenize_uchars (const hawk_uch_t* s, hawk_oow_t len, const hawk_uch_t* delim, hawk_oow_t delim_len, hawk_ucs_t* tok, int ignorecase) { const hawk_uch_t* p = s, *d; @@ -2003,12 +1997,10 @@ exit_loop: /* if HAWK_NULL is returned, this function should not be called again */ if (p >= end) return HAWK_NULL; - if (delim_mode == __DELIM_EMPTY || - delim_mode == __DELIM_SPACES) return (hawk_uch_t*)p; + if (delim_mode == __DELIM_EMPTY || delim_mode == __DELIM_SPACES) return (hawk_uch_t*)p; return (hawk_uch_t*)++p; } - hawk_bch_t* hawk_tokenize_bchars (const hawk_bch_t* s, hawk_oow_t len, const hawk_bch_t* delim, hawk_oow_t delim_len, hawk_bcs_t* tok, int ignorecase) { const hawk_bch_t* p = s, *d; @@ -2191,20 +2183,85 @@ exit_loop: /* if HAWK_NULL is returned, this function should not be called again */ if (p >= end) return HAWK_NULL; - if (delim_mode == __DELIM_EMPTY || - delim_mode == __DELIM_SPACES) return (hawk_bch_t*)p; + if (delim_mode == __DELIM_EMPTY || delim_mode == __DELIM_SPACES) return (hawk_bch_t*)p; return (hawk_bch_t*)++p; } -/* ------------------------------------------------------------------------ */ +hawk_oow_t hawk_byte_to_ucstr (hawk_uint8_t byte, hawk_uch_t* buf, hawk_oow_t size, int flagged_radix, hawk_uch_t fill) +{ + hawk_uch_t tmp[(HAWK_SIZEOF(hawk_uint8_t) * HAWK_BITS_PER_BYTE)]; + hawk_uch_t* p = tmp, * bp = buf, * be = buf + size - 1; + int radix; + hawk_uch_t radix_char; -hawk_oow_t hawk_int_to_oocstr (hawk_int_t value, int radix, const hawk_ooch_t* prefix, hawk_ooch_t* buf, hawk_oow_t size) + radix = (flagged_radix & HAWK_BYTE_TO_UCSTR_RADIXMASK); + radix_char = (flagged_radix & HAWK_BYTE_TO_UCSTR_LOWERCASE)? 'a': 'A'; + if (radix < 2 || radix > 36 || size <= 0) return 0; + + do + { + hawk_uint8_t digit = byte % radix; + if (digit < 10) *p++ = digit + '0'; + else *p++ = digit + radix_char - 10; + byte /= radix; + } + while (byte > 0); + + if (fill != '\0') + { + while (size - 1 > p - tmp) + { + *bp++ = fill; + size--; + } + } + + while (p > tmp && bp < be) *bp++ = *--p; + *bp = '\0'; + return bp - buf; +} + +hawk_oow_t hawk_byte_to_bcstr (hawk_uint8_t byte, hawk_bch_t* buf, hawk_oow_t size, int flagged_radix, hawk_bch_t fill) +{ + hawk_bch_t tmp[(HAWK_SIZEOF(hawk_uint8_t) * HAWK_BITS_PER_BYTE)]; + hawk_bch_t* p = tmp, * bp = buf, * be = buf + size - 1; + int radix; + hawk_bch_t radix_char; + + radix = (flagged_radix & HAWK_BYTE_TO_BCSTR_RADIXMASK); + radix_char = (flagged_radix & HAWK_BYTE_TO_BCSTR_LOWERCASE)? 'a': 'A'; + if (radix < 2 || radix > 36 || size <= 0) return 0; + + do + { + hawk_uint8_t digit = byte % radix; + if (digit < 10) *p++ = digit + '0'; + else *p++ = digit + radix_char - 10; + byte /= radix; + } + while (byte > 0); + + if (fill != '\0') + { + while (size - 1 > p - tmp) + { + *bp++ = fill; + size--; + } + } + + while (p > tmp && bp < be) *bp++ = *--p; + *bp = '\0'; + return bp - buf; +} + +hawk_oow_t hawk_int_to_ucstr (hawk_int_t value, int radix, const hawk_uch_t* prefix, hawk_uch_t* buf, hawk_oow_t size) { hawk_int_t t, rem; hawk_oow_t len, ret, i; hawk_oow_t prefix_len; - prefix_len = (prefix != HAWK_NULL)? hawk_count_oocstr(prefix): 0; + prefix_len = (prefix != HAWK_NULL)? hawk_count_ucstr(prefix): 0; t = value; if (t == 0) @@ -2224,7 +2281,7 @@ hawk_oow_t hawk_int_to_oocstr (hawk_int_t value, int radix, const hawk_ooch_t* p } for (i = 0; i < prefix_len; i++) buf[i] = prefix[i]; - buf[prefix_len] = HAWK_T('0'); + buf[prefix_len] = '0'; if (size > prefix_len+1) buf[prefix_len+1] = '\0'; return prefix_len+1; } @@ -2251,9 +2308,9 @@ hawk_oow_t hawk_int_to_oocstr (hawk_int_t value, int radix, const hawk_ooch_t* p { rem = t % radix; if (rem >= 10) - buf[--len] = (hawk_ooch_t)rem + 'a' - 10; + buf[--len] = (hawk_uch_t)rem + 'a' - 10; else - buf[--len] = (hawk_ooch_t)rem + '0'; + buf[--len] = (hawk_uch_t)rem + '0'; t /= radix; } @@ -2274,7 +2331,233 @@ hawk_oow_t hawk_int_to_oocstr (hawk_int_t value, int radix, const hawk_ooch_t* p return ret; } -/* ------------------------------------------------------------------------ */ +hawk_oow_t hawk_int_to_bcstr (hawk_int_t value, int radix, const hawk_bch_t* prefix, hawk_bch_t* buf, hawk_oow_t size) +{ + hawk_int_t t, rem; + hawk_oow_t len, ret, i; + hawk_oow_t prefix_len; + + prefix_len = (prefix != HAWK_NULL)? hawk_count_bcstr(prefix): 0; + + t = value; + if (t == 0) + { + /* zero */ + if (buf == HAWK_NULL) + { + /* if buf is not given, + * return the number of bytes required */ + return prefix_len + 1; + } + + if (size < prefix_len+1) + { + /* buffer too small */ + return (hawk_oow_t)-1; + } + + for (i = 0; i < prefix_len; i++) buf[i] = prefix[i]; + buf[prefix_len] = '0'; + if (size > prefix_len+1) buf[prefix_len+1] = '\0'; + return prefix_len+1; + } + + /* non-zero values */ + len = prefix_len; + if (t < 0) { t = -t; len++; } + while (t > 0) { len++; t /= radix; } + + if (buf == HAWK_NULL) + { + /* if buf is not given, return the number of bytes required */ + return len; + } + + if (size < len) return (hawk_oow_t)-1; /* buffer too small */ + if (size > len) buf[len] = '\0'; + ret = len; + + t = value; + if (t < 0) t = -t; + + while (t > 0) + { + rem = t % radix; + if (rem >= 10) + buf[--len] = (hawk_bch_t)rem + 'a' - 10; + else + buf[--len] = (hawk_bch_t)rem + '0'; + t /= radix; + } + + if (value < 0) + { + for (i = 1; i <= prefix_len; i++) + { + buf[i] = prefix[i-1]; + len--; + } + buf[--len] = '-'; + } + else + { + for (i = 0; i < prefix_len; i++) buf[i] = prefix[i]; + } + + return ret; +} + +hawk_oow_t hawk_uint_to_ucstr (hawk_uint_t value, int radix, const hawk_uch_t* prefix, hawk_uch_t* buf, hawk_oow_t size) +{ + hawk_uint_t t, rem; + hawk_oow_t len, ret, i; + hawk_oow_t prefix_len; + + prefix_len = (prefix != HAWK_NULL)? hawk_count_ucstr(prefix): 0; + + t = value; + if (t == 0) + { + /* zero */ + if (buf == HAWK_NULL) + { + /* if buf is not given, + * return the number of bytes required */ + return prefix_len + 1; + } + + if (size < prefix_len+1) + { + /* buffer too small */ + return (hawk_oow_t)-1; + } + + for (i = 0; i < prefix_len; i++) buf[i] = prefix[i]; + buf[prefix_len] = '0'; + if (size > prefix_len+1) buf[prefix_len+1] = '\0'; + return prefix_len+1; + } + + /* non-zero values */ + len = prefix_len; + if (t < 0) { t = -t; len++; } + while (t > 0) { len++; t /= radix; } + + if (buf == HAWK_NULL) + { + /* if buf is not given, return the number of bytes required */ + return len; + } + + if (size < len) return (hawk_oow_t)-1; /* buffer too small */ + if (size > len) buf[len] = '\0'; + ret = len; + + t = value; + if (t < 0) t = -t; + + while (t > 0) + { + rem = t % radix; + if (rem >= 10) + buf[--len] = (hawk_uch_t)rem + 'a' - 10; + else + buf[--len] = (hawk_uch_t)rem + '0'; + t /= radix; + } + + if (value < 0) + { + for (i = 1; i <= prefix_len; i++) + { + buf[i] = prefix[i-1]; + len--; + } + buf[--len] = '-'; + } + else + { + for (i = 0; i < prefix_len; i++) buf[i] = prefix[i]; + } + + return ret; +} + +hawk_oow_t hawk_uint_to_bcstr (hawk_uint_t value, int radix, const hawk_bch_t* prefix, hawk_bch_t* buf, hawk_oow_t size) +{ + hawk_uint_t t, rem; + hawk_oow_t len, ret, i; + hawk_oow_t prefix_len; + + prefix_len = (prefix != HAWK_NULL)? hawk_count_bcstr(prefix): 0; + + t = value; + if (t == 0) + { + /* zero */ + if (buf == HAWK_NULL) + { + /* if buf is not given, + * return the number of bytes required */ + return prefix_len + 1; + } + + if (size < prefix_len+1) + { + /* buffer too small */ + return (hawk_oow_t)-1; + } + + for (i = 0; i < prefix_len; i++) buf[i] = prefix[i]; + buf[prefix_len] = '0'; + if (size > prefix_len+1) buf[prefix_len+1] = '\0'; + return prefix_len+1; + } + + /* non-zero values */ + len = prefix_len; + if (t < 0) { t = -t; len++; } + while (t > 0) { len++; t /= radix; } + + if (buf == HAWK_NULL) + { + /* if buf is not given, return the number of bytes required */ + return len; + } + + if (size < len) return (hawk_oow_t)-1; /* buffer too small */ + if (size > len) buf[len] = '\0'; + ret = len; + + t = value; + if (t < 0) t = -t; + + while (t > 0) + { + rem = t % radix; + if (rem >= 10) + buf[--len] = (hawk_bch_t)rem + 'a' - 10; + else + buf[--len] = (hawk_bch_t)rem + '0'; + t /= radix; + } + + if (value < 0) + { + for (i = 1; i <= prefix_len; i++) + { + buf[i] = prefix[i-1]; + len--; + } + buf[--len] = '-'; + } + else + { + for (i = 0; i < prefix_len; i++) buf[i] = prefix[i]; + } + + return ret; +} hawk_int_t hawk_uchars_to_int (const hawk_uch_t* str, hawk_oow_t len, int option, const hawk_uch_t** endptr, int* is_sober) { @@ -2283,12 +2566,12 @@ hawk_int_t hawk_uchars_to_int (const hawk_uch_t* str, hawk_oow_t len, int option const hawk_uch_t* end; hawk_oow_t rem; int digit, negative = 0; - int base = HAWK_OOCHARS_TO_INT_GET_OPTION_BASE(option); + int base = HAWK_UCHARS_TO_INTMAX_GET_OPTION_BASE(option); p = str; end = str + len; - if (HAWK_OOCHARS_TO_INT_GET_OPTION_LTRIM(option)) + if (HAWK_UCHARS_TO_INTMAX_GET_OPTION_LTRIM(option)) { /* strip off leading spaces */ while (p < end && hawk_is_uch_space(*p)) p++; @@ -2346,11 +2629,40 @@ hawk_int_t hawk_uchars_to_int (const hawk_uch_t* str, hawk_oow_t len, int option p++; } + if (HAWK_UCHARS_TO_INTMAX_GET_OPTION_E(option)) + { + if (*p == 'E' || *p == 'e') + { + hawk_int_t e = 0, i; + int e_neg = 0; + p++; + if (*p == '+') + { + p++; + } + else if (*p == '-') + { + p++; e_neg = 1; + } + while (p < end) + { + digit = HAWK_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 (HAWK_OOCHARS_TO_INT_GET_OPTION_RTRIM(option)) + if (HAWK_UCHARS_TO_INTMAX_GET_OPTION_RTRIM(option)) { /* consume trailing spaces */ while (p < end && hawk_is_uch_space(*p)) p++; @@ -2367,12 +2679,12 @@ hawk_int_t hawk_bchars_to_int (const hawk_bch_t* str, hawk_oow_t len, int option const hawk_bch_t* end; hawk_oow_t rem; int digit, negative = 0; - int base = HAWK_OOCHARS_TO_INT_GET_OPTION_BASE(option); + int base = HAWK_BCHARS_TO_INTMAX_GET_OPTION_BASE(option); p = str; end = str + len; - - if (HAWK_OOCHARS_TO_INT_GET_OPTION_LTRIM(option)) + + if (HAWK_BCHARS_TO_INTMAX_GET_OPTION_LTRIM(option)) { /* strip off leading spaces */ while (p < end && hawk_is_bch_space(*p)) p++; @@ -2430,11 +2742,40 @@ hawk_int_t hawk_bchars_to_int (const hawk_bch_t* str, hawk_oow_t len, int option p++; } + if (HAWK_BCHARS_TO_INTMAX_GET_OPTION_E(option)) + { + if (*p == 'E' || *p == 'e') + { + hawk_int_t e = 0, i; + int e_neg = 0; + p++; + if (*p == '+') + { + p++; + } + else if (*p == '-') + { + p++; e_neg = 1; + } + while (p < end) + { + digit = HAWK_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 (is_sober) *is_sober = (base == 8 || p > pp); - if (HAWK_OOCHARS_TO_INT_GET_OPTION_RTRIM(option)) + if (HAWK_BCHARS_TO_INTMAX_GET_OPTION_RTRIM(option)) { /* consume trailing spaces */ while (p < end && hawk_is_bch_space(*p)) p++; @@ -2443,3 +2784,220 @@ hawk_int_t hawk_bchars_to_int (const hawk_bch_t* str, hawk_oow_t len, int option if (endptr) *endptr = p; return (negative)? -n: n; } + +hawk_uint_t hawk_uchars_to_uint (const hawk_uch_t* str, hawk_oow_t len, int option, const hawk_uch_t** endptr, int* is_sober) +{ + hawk_uint_t n = 0; + const hawk_uch_t* p, * pp; + const hawk_uch_t* end; + hawk_oow_t rem; + int digit; + int base = HAWK_UCHARS_TO_UINTMAX_GET_OPTION_BASE(option); + + p = str; + end = str + len; + + if (HAWK_UCHARS_TO_UINTMAX_GET_OPTION_LTRIM(option)) + { + /* strip off leading spaces */ + while (p < end && hawk_is_uch_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 = HAWK_ZDIGIT_TO_NUM(*p, base); + if (digit >= base) break; + n = n * base + digit; + p++; + } + + if (HAWK_UCHARS_TO_UINTMAX_GET_OPTION_E(option)) + { + if (*p == 'E' || *p == 'e') + { + hawk_uint_t e = 0, i; + int e_neg = 0; + p++; + if (*p == '+') + { + p++; + } + else if (*p == '-') + { + p++; e_neg = 1; + } + while (p < end) + { + digit = HAWK_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 (HAWK_UCHARS_TO_UINTMAX_GET_OPTION_RTRIM(option)) + { + /* consume trailing spaces */ + while (p < end && hawk_is_uch_space(*p)) p++; + } + + if (endptr) *endptr = p; + return n; +} + +hawk_uint_t hawk_bchars_to_uint (const hawk_bch_t* str, hawk_oow_t len, int option, const hawk_bch_t** endptr, int* is_sober) +{ + hawk_uint_t n = 0; + const hawk_bch_t* p, * pp; + const hawk_bch_t* end; + hawk_oow_t rem; + int digit; + int base = HAWK_BCHARS_TO_UINTMAX_GET_OPTION_BASE(option); + + p = str; + end = str + len; + + if (HAWK_BCHARS_TO_UINTMAX_GET_OPTION_LTRIM(option)) + { + /* strip off leading spaces */ + while (p < end && hawk_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 = HAWK_ZDIGIT_TO_NUM(*p, base); + if (digit >= base) break; + n = n * base + digit; + p++; + } + + if (HAWK_BCHARS_TO_UINTMAX_GET_OPTION_E(option)) + { + if (*p == 'E' || *p == 'e') + { + hawk_uint_t e = 0, i; + int e_neg = 0; + p++; + if (*p == '+') + { + p++; + } + else if (*p == '-') + { + p++; e_neg = 1; + } + while (p < end) + { + digit = HAWK_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 (HAWK_BCHARS_TO_UINTMAX_GET_OPTION_RTRIM(option)) + { + /* consume trailing spaces */ + while (p < end && hawk_is_bch_space(*p)) p++; + } + + if (endptr) *endptr = p; + return n; +} + diff --git a/hawk/lib/utl-str.c.m4 b/hawk/lib/utl-str.c.m4 new file mode 100644 index 00000000..9b88be64 --- /dev/null +++ b/hawk/lib/utl-str.c.m4 @@ -0,0 +1,138 @@ +/* + Copyright (c) 2006-2020 Chung, Hyung-Hwan. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * 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 + */ + +#include "hawk-prv.h" +#include +dnl +dnl --------------------------------------------------------------------------- +include(`utl-str.m4')dnl +dnl --------------------------------------------------------------------------- +dnl -- +fn_comp_chars(hawk_comp_uchars, hawk_uch_t, hawk_uchu_t, hawk_to_uch_lower) +fn_comp_chars(hawk_comp_bchars, hawk_bch_t, hawk_bchu_t, hawk_to_bch_lower) +dnl -- +fn_comp_cstr(hawk_comp_ucstr, hawk_uch_t, hawk_uchu_t, hawk_to_uch_lower) +fn_comp_cstr(hawk_comp_bcstr, hawk_bch_t, hawk_bchu_t, hawk_to_bch_lower) +dnl -- +fn_comp_cstr_limited(hawk_comp_ucstr_limited, hawk_uch_t, hawk_uchu_t, hawk_to_uch_lower) +fn_comp_cstr_limited(hawk_comp_bcstr_limited, hawk_bch_t, hawk_bchu_t, hawk_to_bch_lower) +dnl -- +fn_comp_chars_cstr(hawk_comp_uchars_ucstr, hawk_uch_t, hawk_uchu_t, hawk_to_uch_lower) +fn_comp_chars_cstr(hawk_comp_bchars_bcstr, hawk_bch_t, hawk_bchu_t, hawk_to_bch_lower) +dnl -- +fn_concat_chars_to_cstr(hawk_concat_uchars_to_ucstr, hawk_uch_t, hawk_count_ucstr) +fn_concat_chars_to_cstr(hawk_concat_bchars_to_bcstr, hawk_bch_t, hawk_count_bcstr) +dnl -- +fn_concat_cstr(hawk_concat_ucstr, hawk_uch_t, hawk_count_ucstr) +fn_concat_cstr(hawk_concat_bcstr, hawk_bch_t, hawk_count_bcstr) +dnl -- +fn_copy_chars(hawk_copy_uchars, hawk_uch_t) +fn_copy_chars(hawk_copy_bchars, hawk_bch_t) +dnl -- +fn_copy_chars_to_cstr(hawk_copy_uchars_to_ucstr, hawk_uch_t) +fn_copy_chars_to_cstr(hawk_copy_bchars_to_bcstr, hawk_bch_t) +dnl -- +fn_copy_chars_to_cstr_unlimited(hawk_copy_uchars_to_ucstr_unlimited, hawk_uch_t) +fn_copy_chars_to_cstr_unlimited(hawk_copy_bchars_to_bcstr_unlimited, hawk_bch_t) +dnl -- +fn_copy_cstr_to_chars(hawk_copy_ucstr_to_uchars, hawk_uch_t) +fn_copy_cstr_to_chars(hawk_copy_bcstr_to_bchars, hawk_bch_t) +dnl -- +fn_copy_cstr(hawk_copy_ucstr, hawk_uch_t) +fn_copy_cstr(hawk_copy_bcstr, hawk_bch_t) +dnl -- +fn_copy_cstr_unlimited(hawk_copy_ucstr_unlimited, hawk_uch_t) +fn_copy_cstr_unlimited(hawk_copy_bcstr_unlimited, hawk_bch_t) +dnl -- +fn_copy_fmt_cstrs_to_cstr(hawk_copy_fmt_ucstrs_to_ucstr, hawk_uch_t) +fn_copy_fmt_cstrs_to_cstr(hawk_copy_fmt_bcstrs_to_bcstr, hawk_bch_t) +dnl -- +fn_copy_fmt_cses_to_cstr(hawk_copy_fmt_ucses_to_ucstr, hawk_uch_t, hawk_ucs_t) +fn_copy_fmt_cses_to_cstr(hawk_copy_fmt_bcses_to_bcstr, hawk_bch_t, hawk_bcs_t) +dnl -- +fn_count_cstr(hawk_count_ucstr, hawk_uch_t) +fn_count_cstr(hawk_count_bcstr, hawk_bch_t) +dnl -- +fn_count_cstr_limited(hawk_count_ucstr_limited, hawk_uch_t) +fn_count_cstr_limited(hawk_count_bcstr_limited, hawk_bch_t) +dnl -- +fn_equal_chars(hawk_equal_uchars, hawk_uch_t) +fn_equal_chars(hawk_equal_bchars, hawk_bch_t) +dnl -- +fn_fill_chars(hawk_fill_uchars, hawk_uch_t) +fn_fill_chars(hawk_fill_bchars, hawk_bch_t) +dnl -- +fn_find_char_in_chars(hawk_find_uchar_in_uchars, hawk_uch_t) +fn_find_char_in_chars(hawk_find_bchar_in_bchars, hawk_bch_t) +dnl -- +fn_rfind_char_in_chars(hawk_rfind_uchar_in_uchars, hawk_uch_t) +fn_rfind_char_in_chars(hawk_rfind_bchar_in_bchars, hawk_bch_t) +dnl -- +fn_find_char_in_cstr(hawk_find_uchar_in_ucstr, hawk_uch_t) +fn_find_char_in_cstr(hawk_find_bchar_in_bcstr, hawk_bch_t) +dnl -- +fn_rfind_char_in_cstr(hawk_rfind_uchar_in_ucstr, hawk_uch_t) +fn_rfind_char_in_cstr(hawk_rfind_bchar_in_bcstr, hawk_bch_t) +dnl -- +fn_find_chars_in_chars(hawk_find_uchars_in_uchars, hawk_uch_t, hawk_to_uch_lower) +fn_find_chars_in_chars(hawk_find_bchars_in_bchars, hawk_bch_t, hawk_to_bch_lower) +dnl -- +fn_rfind_chars_in_chars(hawk_rfind_uchars_in_uchars, hawk_uch_t, hawk_to_uch_lower) +fn_rfind_chars_in_chars(hawk_rfind_bchars_in_bchars, hawk_bch_t, hawk_to_bch_lower) +dnl -- +fn_compact_chars(hawk_compact_uchars, hawk_uch_t, hawk_is_uch_space) +fn_compact_chars(hawk_compact_bchars, hawk_bch_t, hawk_is_bch_space) +dnl -- +fn_rotate_chars(hawk_rotate_uchars, hawk_uch_t) +fn_rotate_chars(hawk_rotate_bchars, hawk_bch_t) +dnl -- +fn_trim_chars(hawk_trim_uchars, hawk_uch_t, hawk_is_uch_space, HAWK_TRIM_UCHARS) +fn_trim_chars(hawk_trim_bchars, hawk_bch_t, hawk_is_bch_space, HAWK_TRIM_BCHARS) +dnl -- +fn_split_cstr(hawk_split_ucstr, hawk_uch_t, hawk_is_uch_space, hawk_copy_ucstr_unlimited) +fn_split_cstr(hawk_split_bcstr, hawk_bch_t, hawk_is_bch_space, hawk_copy_bcstr_unlimited) +dnl -- +fn_tokenize_chars(hawk_tokenize_uchars, hawk_uch_t, hawk_ucs_t, hawk_is_uch_space, hawk_to_uch_lower) +fn_tokenize_chars(hawk_tokenize_bchars, hawk_bch_t, hawk_bcs_t, hawk_is_bch_space, hawk_to_bch_lower) +dnl -- +fn_byte_to_cstr(hawk_byte_to_ucstr, hawk_uch_t, HAWK_BYTE_TO_UCSTR) +fn_byte_to_cstr(hawk_byte_to_bcstr, hawk_bch_t, HAWK_BYTE_TO_BCSTR) +dnl -- +fn_int_to_cstr(hawk_int_to_ucstr, hawk_uch_t, hawk_int_t, hawk_count_ucstr) +fn_int_to_cstr(hawk_int_to_bcstr, hawk_bch_t, hawk_int_t, hawk_count_bcstr) +fn_int_to_cstr(hawk_uint_to_ucstr, hawk_uch_t, hawk_uint_t, hawk_count_ucstr) +fn_int_to_cstr(hawk_uint_to_bcstr, hawk_bch_t, hawk_uint_t, hawk_count_bcstr) +dnl -- +fn_chars_to_int(hawk_uchars_to_int, hawk_uch_t, hawk_int_t, hawk_is_uch_space, HAWK_UCHARS_TO_INTMAX) +fn_chars_to_int(hawk_bchars_to_int, hawk_bch_t, hawk_int_t, hawk_is_bch_space, HAWK_BCHARS_TO_INTMAX) +dnl -- +fn_chars_to_uint(hawk_uchars_to_uint, hawk_uch_t, hawk_uint_t, hawk_is_uch_space, HAWK_UCHARS_TO_UINTMAX) +fn_chars_to_uint(hawk_bchars_to_uint, hawk_bch_t, hawk_uint_t, hawk_is_bch_space, HAWK_BCHARS_TO_UINTMAX) diff --git a/hawk/lib/utl-str.m4 b/hawk/lib/utl-str.m4 new file mode 100644 index 00000000..2ce69363 --- /dev/null +++ b/hawk/lib/utl-str.m4 @@ -0,0 +1,1509 @@ +dnl --------------------------------------------------------------------------- +changequote(`[[', `]]')dnl +dnl --------------------------------------------------------------------------- +define([[fn_comp_chars]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_chau_type_]], $3)pushdef([[_to_lower_]], $4)dnl +int _fn_name_ (const _char_type_* str1, hawk_oow_t len1, const _char_type_* str2, hawk_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 = _to_lower_()(*str1); + if (str2 < end2) + { + c2 = _to_lower_()(*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; +} +popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_chau_type_]])popdef([[_to_lower_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_comp_cstr]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_chau_type_]], $3)pushdef([[_to_lower_]], $4)dnl +int _fn_name_ (const _char_type_* str1, const _char_type_* str2, int ignorecase) +{ + if (ignorecase) + { + while (_to_lower_()(*str1) == _to_lower_()(*str2)) + { + if (*str1 == '\0') return 0; + str1++; str2++; + } + + return ((_chau_type_)_to_lower_()(*str1) > (_chau_type_)_to_lower_()(*str2))? 1: -1; + } + else + { + while (*str1 == *str2) + { + if (*str1 == '\0') return 0; + str1++; str2++; + } + + return ((_chau_type_)*str1 > (_chau_type_)*str2)? 1: -1; + } +} +popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_chau_type_]])popdef([[_to_lower_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_comp_cstr_limited]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_chau_type_]], $3)pushdef([[_to_lower_]], $4)dnl +int _fn_name_ (const _char_type_* str1, const _char_type_* str2, hawk_oow_t maxlen, int ignorecase) +{ + if (maxlen == 0) return 0; + + if (ignorecase) + { + while (_to_lower_()(*str1) == _to_lower_()(*str2)) + { + if (*str1 == '\0' || maxlen == 1) return 0; + str1++; str2++; maxlen--; + } + + return ((_chau_type_)_to_lower_()(*str1) > (_chau_type_)_to_lower_()(*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; + } +} +popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_chau_type_]])popdef([[_to_lower_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_comp_chars_cstr]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_chau_type_]], $3)pushdef([[_to_lower_]], $4)dnl +int _fn_name_ (const _char_type_* str1, hawk_oow_t len, const _char_type_* str2, int ignorecase) +{ + /* for "abc\0" of length 4 vs "abc", the fourth character + * of the first string is equal to the terminating null of + * the second string. the first string is still considered + * bigger */ + if (ignorecase) + { + const _char_type_* end = str1 + len; + _char_type_ c1; + _char_type_ c2; + while (str1 < end && *str2 != '\0') + { + c1 = _to_lower_()(*str1); + c2 = _to_lower_()(*str2); + if (c1 != c2) return ((_chau_type_)c1 > (_chau_type_)c2)? 1: -1; + str1++; str2++; + } + return (str1 < end)? 1: (*str2 == '\0'? 0: -1); + } + else + { + const _char_type_* end = str1 + len; + while (str1 < end && *str2 != '\0') + { + if (*str1 != *str2) return ((_chau_type_)*str1 > (_chau_type_)*str2)? 1: -1; + str1++; str2++; + } + return (str1 < end)? 1: (*str2 == '\0'? 0: -1); + } +} +popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_chau_type_]])popdef([[_to_lower_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_concat_chars_to_cstr]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_count_str_]], $3)dnl +hawk_oow_t _fn_name_ (_char_type_* buf, hawk_oow_t bsz, const _char_type_* str, hawk_oow_t len) +{ + _char_type_* p, * p2; + const _char_type_* end; + hawk_oow_t blen; + + blen = _count_str_()(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; +} +popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_count_str_]])dnl +]])dnl + +dnl --------------------------------------------------------------------------- +define([[fn_concat_cstr]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_count_str_]], $3)dnl +hawk_oow_t _fn_name_ (_char_type_* buf, hawk_oow_t bsz, const _char_type_* str) +{ + _char_type_* p, * p2; + hawk_oow_t blen; + + blen = _count_str_()(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; +} +popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_count_str_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_copy_chars]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl +void _fn_name_ (_char_type_* dst, const _char_type_* src, hawk_oow_t len) +{ + /* take note of no forced null termination */ + hawk_oow_t i; + for (i = 0; i < len; i++) dst[i] = src[i]; +} +popdef([[_fn_name_]])popdef([[_char_type_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_copy_chars_to_cstr]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl +hawk_oow_t _fn_name_ (_char_type_* dst, hawk_oow_t dlen, const _char_type_* src, hawk_oow_t slen) +{ + hawk_oow_t i; + if (dlen <= 0) return 0; + if (dlen <= slen) slen = dlen - 1; + for (i = 0; i < slen; i++) dst[i] = src[i]; + dst[i] = '\0'; + return i; +} +popdef([[_fn_name_]])popdef([[_char_type_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_copy_chars_to_cstr_unlimited]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl +hawk_oow_t _fn_name_ (_char_type_* dst, const _char_type_* src, hawk_oow_t len) +{ + hawk_oow_t i; + for (i = 0; i < len; i++) dst[i] = src[i]; + dst[i] = '\0'; + return i; +} +popdef([[_fn_name_]])popdef([[_char_type_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_copy_cstr_to_chars]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl +hawk_oow_t _fn_name_ (_char_type_* dst, hawk_oow_t len, const _char_type_* src) +{ + /* no null termination */ + _char_type_* p, * p2; + + p = dst; p2 = dst + len - 1; + + while (p < p2) + { + if (*src == '\0') break; + *p++ = *src++; + } + + return p - dst; +} +popdef([[_fn_name_]])popdef([[_char_type_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_copy_cstr]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl +hawk_oow_t _fn_name_ (_char_type_* dst, hawk_oow_t len, const _char_type_* src) +{ + _char_type_* p, * p2; + + p = dst; p2 = dst + len - 1; + + while (p < p2) + { + if (*src == '\0') break; + *p++ = *src++; + } + + if (len > 0) *p = '\0'; + return p - dst; +} +popdef([[_fn_name_]])popdef([[_char_type_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_copy_cstr_unlimited]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl +hawk_oow_t _fn_name_ (_char_type_* dst, const _char_type_* src) +{ + _char_type_* org = dst; + while ((*dst++ = *src++) != '\0'); + return dst - org - 1; +} +popdef([[_fn_name_]])popdef([[_char_type_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_copy_fmt_cstrs_to_cstr]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl +hawk_oow_t _fn_name_ (_char_type_* buf, hawk_oow_t bsz, const _char_type_* fmt, const _char_type_* str[]) +{ + _char_type_* b = buf; + _char_type_* end = buf + bsz - 1; + const _char_type_* f = fmt; + + if (bsz <= 0) return 0; + + while (*f != '\0') + { + if (*f == '\\') + { + /* get the escaped character and treat it normally. + * if the escaper is the last character, treat it + * normally also. */ + if (f[1] != '\0') f++; + } + else if (*f == '$') + { + if (f[1] == '{' && (f[2] >= '0' && f[2] <= '9')) + { + const _char_type_* tmp; + hawk_oow_t idx = 0; + + tmp = f; + f += 2; + + do idx = idx * 10 + (*f++ - '0'); + while (*f >= '0' && *f <= '9'); + + if (*f != '}') + { + f = tmp; + goto normal; + } + + f++; + + tmp = str[idx]; + while (*tmp != '\0') + { + if (b >= end) goto fini; + *b++ = *tmp++; + } + continue; + } + else if (f[1] == '$') f++; + } + + normal: + if (b >= end) break; + *b++ = *f++; + } + +fini: + *b = '\0'; + return b - buf; +} +popdef([[_fn_name_]])popdef([[_char_type_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_copy_fmt_cses_to_cstr]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_cs_type_]], $3)dnl +hawk_oow_t _fn_name_ (_char_type_* buf, hawk_oow_t bsz, const _char_type_* fmt, const _cs_type_ str[]) +{ + _char_type_* b = buf; + _char_type_* end = buf + bsz - 1; + const _char_type_* f = fmt; + + if (bsz <= 0) return 0; + + while (*f != '\0') + { + if (*f == '\\') + { + /* get the escaped character and treat it normally. + * if the escaper is the last character, treat it + * normally also. */ + if (f[1] != '\0') f++; + } + else if (*f == '$') + { + if (f[1] == '{' && (f[2] >= '0' && f[2] <= '9')) + { + const _char_type_* tmp, * tmpend; + hawk_oow_t idx = 0; + + tmp = f; + f += 2; + + do idx = idx * 10 + (*f++ - '0'); + while (*f >= '0' && *f <= '9'); + + if (*f != '}') + { + f = tmp; + goto normal; + } + + f++; + + tmp = str[idx].ptr; + tmpend = tmp + str[idx].len; + + while (tmp < tmpend) + { + if (b >= end) goto fini; + *b++ = *tmp++; + } + continue; + } + else if (f[1] == '$') f++; + } + + normal: + if (b >= end) break; + *b++ = *f++; + } + +fini: + *b = '\0'; + return b - buf; +} +popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_cs_type_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_count_cstr]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl +hawk_oow_t _fn_name_ (const _char_type_* str) +{ + const _char_type_* ptr = str; + while (*ptr != '\0') ptr++; + return ptr - str; +} +popdef([[_fn_name_]])popdef([[_char_type_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_count_cstr_limited]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl +hawk_oow_t _fn_name_ (const _char_type_* str, hawk_oow_t maxlen) +{ + hawk_oow_t i; + for (i = 0; i < maxlen; i++) + { + if (str[i] == '\0') break; + } + return i; +} +popdef([[_fn_name_]])popdef([[_char_type_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_equal_chars]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl +int _fn_name_ (const _char_type_* str1, const _char_type_* str2, hawk_oow_t len) +{ + hawk_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; +} +popdef([[_fn_name_]])popdef([[_char_type_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_fill_chars]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl +void _fn_name_ (_char_type_* dst, _char_type_ ch, hawk_oow_t len) +{ + hawk_oow_t i; + for (i = 0; i < len; i++) dst[i] = ch; +} +popdef([[_fn_name_]])popdef([[_char_type_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_find_char_in_chars]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl +_char_type_* _fn_name_ (const _char_type_* ptr, hawk_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 HAWK_NULL; +} +popdef([[_fn_name_]])popdef([[_char_type_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_rfind_char_in_chars]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl +_char_type_* _fn_name_ (const _char_type_* ptr, hawk_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 HAWK_NULL; +} +popdef([[_fn_name_]])popdef([[_char_type_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_find_char_in_cstr]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl +_char_type_* _fn_name_ (const _char_type_* ptr, _char_type_ c) +{ + while (*ptr != '\0') + { + if (*ptr == c) return (_char_type_*)ptr; + ptr++; + } + + return HAWK_NULL; +} +popdef([[_fn_name_]])popdef([[_char_type_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_rfind_char_in_cstr]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl +_char_type_* _fn_name_ (const _char_type_* str, _char_type_ c) +{ + const _char_type_* ptr = str; + while (*ptr != '\0') ptr++; + + while (ptr > str) + { + --ptr; + if (*ptr == c) return (_char_type_*)ptr; + } + + return HAWK_NULL; +} +popdef([[_fn_name_]])popdef([[_char_type_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_find_chars_in_chars]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_to_lower_]], $3)dnl +_char_type_* _fn_name_ (const _char_type_* str, hawk_oow_t strsz, const _char_type_* sub, hawk_oow_t subsz, int ignorecase) +{ + const _char_type_* end, * subp; + + if (subsz == 0) return (_char_type_*)str; + if (strsz < subsz) return HAWK_NULL; + + end = str + strsz - subsz; + subp = sub + subsz; + + if (HAWK_UNLIKELY(ignorecase)) + { + while (str <= end) + { + const _char_type_* x = str; + const _char_type_* y = sub; + + while (1) + { + if (y >= subp) return (_char_type_*)str; + if (_to_lower_()(*x) != _to_lower_()(*y)) break; + x++; y++; + } + + str++; + } + } + else + { + while (str <= end) + { + const _char_type_* x = str; + const _char_type_* y = sub; + + while (1) + { + if (y >= subp) return (_char_type_*)str; + if (*x != *y) break; + x++; y++; + } + + str++; + } + } + + return HAWK_NULL; +} +popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_to_lower_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_rfind_chars_in_chars]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_to_lower_]], $3)dnl +_char_type_* _fn_name_ (const _char_type_* str, hawk_oow_t strsz, const _char_type_* sub, hawk_oow_t subsz, int ignorecase) +{ + const _char_type_* p = str + strsz; + const _char_type_* subp = sub + subsz; + + if (subsz == 0) return (_char_type_*)p; + if (strsz < subsz) return HAWK_NULL; + + p = p - subsz; + + if (HAWK_UNLIKELY(ignorecase)) + { + while (p >= str) + { + const _char_type_* x = p; + const _char_type_* y = sub; + + while (1) + { + if (y >= subp) return (_char_type_*)p; + if (_to_lower_()(*x) != _to_lower_()(*y)) break; + x++; y++; + } + + p--; + } + } + else + { + while (p >= str) + { + const _char_type_* x = p; + const _char_type_* y = sub; + + while (1) + { + if (y >= subp) return (_char_type_*)p; + if (*x != *y) break; + x++; y++; + } + + p--; + } + } + + return HAWK_NULL; +} +popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_to_lower_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_compact_chars]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_is_space_]], $3)dnl +hawk_oow_t _fn_name_ (_char_type_* str, hawk_oow_t len) +{ + _char_type_* p = str, * q = str, * end = str + len; + int followed_by_space = 0; + int state = 0; + + while (p < end) + { + if (state == 0) + { + if (!_is_space_()(*p)) + { + *q++ = *p; + state = 1; + } + } + else if (state == 1) + { + if (_is_space_()(*p)) + { + if (!followed_by_space) + { + followed_by_space = 1; + *q++ = *p; + } + } + else + { + followed_by_space = 0; + *q++ = *p; + } + } + + p++; + } + + return (followed_by_space) ? (q - str -1): (q - str); +} +popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_is_space_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_rotate_chars]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)dnl +hawk_oow_t _fn_name_ (_char_type_* str, hawk_oow_t len, int dir, hawk_oow_t n) +{ + hawk_oow_t first, last, count, index, nk; + _char_type_ c; + + if (dir == 0 || len == 0) return len; + if ((n %= len) == 0) return len; + + if (dir > 0) n = len - n; + first = 0; nk = len - n; count = 0; + + while (count < n) + { + last = first + nk; + index = first; + c = str[first]; + do + { + count++; + while (index < nk) + { + str[index] = str[index + n]; + index += n; + } + if (index == last) break; + str[index] = str[index - nk]; + index -= nk; + } + while (1); + str[last] = c; first++; + } + return len; +} +popdef([[_fn_name_]])popdef([[_char_type_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_trim_chars]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_is_space_]], $3)pushdef([[_prefix_]], $4)dnl +_char_type_* _fn_name_ (const _char_type_* str, hawk_oow_t* len, int flags) +{ + const _char_type_* p = str, * end = str + *len; + + if (p < end) + { + const _char_type_* s = HAWK_NULL, * e = HAWK_NULL; + + do + { + if (!_is_space_()(*p)) + { + if (s == HAWK_NULL) s = p; + e = p; + } + p++; + } + while (p < end); + + if (e) + { + if (flags & _prefix_()_RIGHT) + { + *len -= end - e - 1; + } + if (flags & _prefix_()_LEFT) + { + *len -= s - str; + str = s; + } + } + else + { + /* the entire string need to be deleted */ + if ((flags & _prefix_()_RIGHT) || + (flags & _prefix_()_LEFT)) *len = 0; + } + } + + return (_char_type_*)str; +} +popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_is_space_]])popdef([[_prefix_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_split_cstr]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_is_space_]], $3)pushdef([[_copy_str_unlimited_]], $4)dnl +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 = HAWK_NULL, * ep = HAWK_NULL; + int delim_mode; + int cnt = 0; + + if (delim == HAWK_NULL) delim_mode = 0; + else + { + delim_mode = 1; + for (d = (_char_type_*)delim; *d != '\0'; d++) + if (!_is_space_()(*d)) delim_mode = 2; + } + + if (delim_mode == 0) + { + /* skip preceding space characters */ + while (_is_space_()(*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) + { + _copy_str_unlimited_ (p, p + 1); + + for (;;) + { + if (*p == '\0') return -1; + + if (escape != '\0' && *p == escape) + { + _copy_str_unlimited_ (p, p + 1); + } + else + { + if (*p == rquote) + { + p++; + break; + } + } + + if (sp == 0) sp = p; + ep = p; + p++; + } + while (_is_space_()(*p)) p++; + if (*p != '\0') return -1; + + if (sp == 0 && ep == 0) s[0] = '\0'; + else + { + ep[1] = '\0'; + if (s != (_char_type_*)sp) _copy_str_unlimited_ (s, sp); + cnt++; + } + } + else + { + while (*p) + { + if (!_is_space_()(*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) _copy_str_unlimited_ (s, sp); + cnt++; + } + } + } + else if (delim_mode == 1) + { + _char_type_* o; + + while (*p) + { + o = p; + while (_is_space_()(*p)) p++; + if (o != p) { _copy_str_unlimited_ (o, p); p = o; } + + if (lquote != '\0' && *p == lquote) + { + _copy_str_unlimited_ (p, p + 1); + + for (;;) + { + if (*p == '\0') return -1; + + if (escape != '\0' && *p == escape) + { + _copy_str_unlimited_ (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 (_is_space_()(*p)) + { + *p++ = '\0'; + cnt++; + break; + } + p++; + } + } + } + } + else /* if (delim_mode == 2) */ + { + _char_type_* o; + int ok; + + while (*p != '\0') + { + o = p; + while (_is_space_()(*p)) p++; + if (o != p) { _copy_str_unlimited_ (o, p); p = o; } + + if (lquote != '\0' && *p == lquote) + { + _copy_str_unlimited_ (p, p + 1); + + for (;;) + { + if (*p == '\0') return -1; + + if (escape != '\0' && *p == escape) + { + _copy_str_unlimited_ (p, p + 1); + } + else + { + if (*p == rquote) + { + *p++ = '\0'; + cnt++; + break; + } + } + p++; + } + + ok = 0; + while (_is_space_()(*p)) p++; + if (*p == '\0') ok = 1; + for (d = (_char_type_*)delim; *d != '\0'; d++) + { + if (*p == *d) + { + ok = 1; + _copy_str_unlimited_ (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 == HAWK_NULL) + { + _copy_str_unlimited_ (o, p); p = o; + *p++ = '\0'; + } + else + { + _copy_str_unlimited_ (&ep[1], p); + _copy_str_unlimited_ (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 (!_is_space_()(*p)) + { + if (sp == HAWK_NULL) sp = p; + ep = p; + } + p++; + } +exit_point: + ; + } + } + } + + return cnt; +} +popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_is_space_]])popdef([[_copy_str_unlimited_]])dnl +]])dnl +define([[fn_tokenize_chars]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_cs_type_]], $3)pushdef([[_is_space_]], $4)pushdef([[_to_lower_]], $5)dnl +_char_type_* _fn_name_ (const _char_type_* s, hawk_oow_t len, const _char_type_* delim, hawk_oow_t delim_len, _cs_type_* tok, int ignorecase) +{ + const _char_type_* p = s, *d; + const _char_type_* end = s + len; + const _char_type_* sp = HAWK_NULL, * ep = HAWK_NULL; + const _char_type_* delim_end = delim + delim_len; + _char_type_ c; + int delim_mode; + +#define __DELIM_NULL 0 +#define __DELIM_EMPTY 1 +#define __DELIM_SPACES 2 +#define __DELIM_NOSPACES 3 +#define __DELIM_COMPOSITE 4 + if (delim == HAWK_NULL) delim_mode = __DELIM_NULL; + else + { + delim_mode = __DELIM_EMPTY; + + for (d = delim; d < delim_end; d++) + { + if (_is_space_()(*d)) + { + if (delim_mode == __DELIM_EMPTY) + delim_mode = __DELIM_SPACES; + else if (delim_mode == __DELIM_NOSPACES) + { + delim_mode = __DELIM_COMPOSITE; + break; + } + } + else + { + if (delim_mode == __DELIM_EMPTY) + delim_mode = __DELIM_NOSPACES; + else if (delim_mode == __DELIM_SPACES) + { + delim_mode = __DELIM_COMPOSITE; + break; + } + } + } + + /* TODO: verify the following statement... */ + if (delim_mode == __DELIM_SPACES && delim_len == 1 && delim[0] != ' ') delim_mode = __DELIM_NOSPACES; + } + + if (delim_mode == __DELIM_NULL) + { + /* when HAWK_NULL is given as "delim", it trims off the + * leading and trailing spaces characters off the source + * string "s" eventually. */ + + while (p < end && _is_space_()(*p)) p++; + while (p < end) + { + c = *p; + + if (!_is_space_()(c)) + { + if (sp == HAWK_NULL) sp = p; + ep = p; + } + p++; + } + } + else if (delim_mode == __DELIM_EMPTY) + { + /* each character in the source string "s" becomes a token. */ + if (p < end) + { + c = *p; + sp = p; + ep = p++; + } + } + else if (delim_mode == __DELIM_SPACES) + { + /* each token is delimited by space characters. all leading + * and trailing spaces are removed. */ + + while (p < end && _is_space_()(*p)) p++; + while (p < end) + { + c = *p; + if (_is_space_()(c)) break; + if (sp == HAWK_NULL) sp = p; + ep = p++; + } + while (p < end && _is_space_()(*p)) p++; + } + else if (delim_mode == __DELIM_NOSPACES) + { + /* each token is delimited by one of charaters + * in the delimeter set "delim". */ + if (ignorecase) + { + while (p < end) + { + c = _to_lower_()(*p); + for (d = delim; d < delim_end; d++) + { + if (c == _to_lower_()(*d)) goto exit_loop; + } + + if (sp == HAWK_NULL) sp = p; + ep = p++; + } + } + else + { + while (p < end) + { + c = *p; + for (d = delim; d < delim_end; d++) + { + if (c == *d) goto exit_loop; + } + + if (sp == HAWK_NULL) sp = p; + ep = p++; + } + } + } + else /* if (delim_mode == __DELIM_COMPOSITE) */ + { + /* each token is delimited by one of non-space charaters + * in the delimeter set "delim". however, all space characters + * surrounding the token are removed */ + while (p < end && _is_space_()(*p)) p++; + if (ignorecase) + { + while (p < end) + { + c = _to_lower_()(*p); + if (_is_space_()(c)) + { + p++; + continue; + } + for (d = delim; d < delim_end; d++) + { + if (c == _to_lower_()(*d)) goto exit_loop; + } + if (sp == HAWK_NULL) sp = p; + ep = p++; + } + } + else + { + while (p < end) + { + c = *p; + if (_is_space_()(c)) + { + p++; + continue; + } + for (d = delim; d < delim_end; d++) + { + if (c == *d) goto exit_loop; + } + if (sp == HAWK_NULL) sp = p; + ep = p++; + } + } + } + +exit_loop: + if (sp == HAWK_NULL) + { + tok->ptr = HAWK_NULL; + tok->len = (hawk_oow_t)0; + } + else + { + tok->ptr = (_char_type_*)sp; + tok->len = ep - sp + 1; + } + + /* if HAWK_NULL is returned, this function should not be called again */ + if (p >= end) return HAWK_NULL; + if (delim_mode == __DELIM_EMPTY || delim_mode == __DELIM_SPACES) return (_char_type_*)p; + return (_char_type_*)++p; +} +popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_cs_type_]])popdef([[_is_space_]])popdef([[_to_lower_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_byte_to_cstr]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_prefix_]], $3)dnl +hawk_oow_t _fn_name_ (hawk_uint8_t byte, _char_type_* buf, hawk_oow_t size, int flagged_radix, _char_type_ fill) +{ + _char_type_ tmp[(HAWK_SIZEOF(hawk_uint8_t) * HAWK_BITS_PER_BYTE)]; + _char_type_* p = tmp, * bp = buf, * be = buf + size - 1; + int radix; + _char_type_ radix_char; + + radix = (flagged_radix & _prefix_()_RADIXMASK); + radix_char = (flagged_radix & _prefix_()_LOWERCASE)? 'a': 'A'; + if (radix < 2 || radix > 36 || size <= 0) return 0; + + do + { + hawk_uint8_t digit = byte % radix; + if (digit < 10) *p++ = digit + '0'; + else *p++ = digit + radix_char - 10; + byte /= radix; + } + while (byte > 0); + + if (fill != '\0') + { + while (size - 1 > p - tmp) + { + *bp++ = fill; + size--; + } + } + + while (p > tmp && bp < be) *bp++ = *--p; + *bp = '\0'; + return bp - buf; +} +popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_cs_type_]])popdef([[_prefix_]])dnl +dnl --------------------------------------------------------------------------- +]])dnl +define([[fn_int_to_cstr]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_int_type_]], $3)pushdef([[_count_cstr_]], $4)dnl +hawk_oow_t _fn_name_ (_int_type_ value, int radix, const _char_type_* prefix, _char_type_* buf, hawk_oow_t size) +{ + _int_type_ t, rem; + hawk_oow_t len, ret, i; + hawk_oow_t prefix_len; + + prefix_len = (prefix != HAWK_NULL)? _count_cstr_()(prefix): 0; + + t = value; + if (t == 0) + { + /* zero */ + if (buf == HAWK_NULL) + { + /* if buf is not given, + * return the number of bytes required */ + return prefix_len + 1; + } + + if (size < prefix_len+1) + { + /* buffer too small */ + return (hawk_oow_t)-1; + } + + for (i = 0; i < prefix_len; i++) buf[i] = prefix[i]; + buf[prefix_len] = '0'; + if (size > prefix_len+1) buf[prefix_len+1] = '\0'; + return prefix_len+1; + } + + /* non-zero values */ + len = prefix_len; + if (t < 0) { t = -t; len++; } + while (t > 0) { len++; t /= radix; } + + if (buf == HAWK_NULL) + { + /* if buf is not given, return the number of bytes required */ + return len; + } + + if (size < len) return (hawk_oow_t)-1; /* buffer too small */ + if (size > len) buf[len] = '\0'; + ret = len; + + t = value; + if (t < 0) t = -t; + + while (t > 0) + { + rem = t % radix; + if (rem >= 10) + buf[--len] = (_char_type_)rem + 'a' - 10; + else + buf[--len] = (_char_type_)rem + '0'; + t /= radix; + } + + if (value < 0) + { + for (i = 1; i <= prefix_len; i++) + { + buf[i] = prefix[i-1]; + len--; + } + buf[--len] = '-'; + } + else + { + for (i = 0; i < prefix_len; i++) buf[i] = prefix[i]; + } + + return ret; +} +popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_int_type_]])popdef([[_count_cstr_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_chars_to_int]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_int_type_]], $3)pushdef([[_is_space_]], $4)pushdef([[_prefix_]], $5)dnl +_int_type_ _fn_name_ (const _char_type_* str, hawk_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; + hawk_oow_t rem; + int digit, negative = 0; + int base = _prefix_()_GET_OPTION_BASE(option); + + p = str; + end = str + len; + + if (_prefix_()_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 = HAWK_ZDIGIT_TO_NUM(*p, base); + if (digit >= base) break; + n = n * base + digit; + p++; + } + + if (_prefix_()_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 = HAWK_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 (_prefix_()_GET_OPTION_RTRIM(option)) + { + /* consume trailing spaces */ + while (p < end && _is_space_()(*p)) p++; + } + + if (endptr) *endptr = p; + return (negative)? -n: n; +} +popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_int_type_]])popdef([[_is_space_]])popdef([[_prefix_]])dnl +]])dnl +dnl --------------------------------------------------------------------------- +define([[fn_chars_to_uint]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_int_type_]], $3)pushdef([[_is_space_]], $4)pushdef([[_prefix_]], $5)dnl +_int_type_ _fn_name_ (const _char_type_* str, hawk_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; + hawk_oow_t rem; + int digit; + int base = _prefix_()_GET_OPTION_BASE(option); + + p = str; + end = str + len; + + if (_prefix_()_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 = HAWK_ZDIGIT_TO_NUM(*p, base); + if (digit >= base) break; + n = n * base + digit; + p++; + } + + if (_prefix_()_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 = HAWK_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 (_prefix_()_GET_OPTION_RTRIM(option)) + { + /* consume trailing spaces */ + while (p < end && _is_space_()(*p)) p++; + } + + if (endptr) *endptr = p; + return n; +} +popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_int_type_]])popdef([[_is_space_]])popdef([[_prefix_]])dnl +]]) diff --git a/hawk/lib/utl.c b/hawk/lib/utl.c index 21ecf037..f9570719 100644 --- a/hawk/lib/utl.c +++ b/hawk/lib/utl.c @@ -130,76 +130,6 @@ void hawk_copy_uchars_to_bchars (hawk_bch_t* dst, const hawk_uch_t* src, hawk_oo /* ----------------------------------------------------------------------- */ -hawk_oow_t hawk_byte_to_ucstr (hawk_oob_t byte, hawk_uch_t* buf, hawk_oow_t size, int flagged_radix, hawk_uch_t fill) -{ - hawk_uch_t tmp[(HAWK_SIZEOF(hawk_oob_t) * HAWK_BITS_PER_BYTE)]; - hawk_uch_t* p = tmp, * bp = buf, * be = buf + size - 1; - int radix; - hawk_uch_t radix_char; - - radix = (flagged_radix & HAWK_BYTE_TO_UCSTR_RADIXMASK); - radix_char = (flagged_radix & HAWK_BYTE_TO_UCSTR_LOWERCASE)? 'a': 'A'; - if (radix < 2 || radix > 36 || size <= 0) return 0; - - do - { - hawk_uint8_t digit = byte % radix; - if (digit < 10) *p++ = digit + '0'; - else *p++ = digit + radix_char - 10; - byte /= radix; - } - while (byte > 0); - - if (fill != '\0') - { - while (size - 1 > p - tmp) - { - *bp++ = fill; - size--; - } - } - - while (p > tmp && bp < be) *bp++ = *--p; - *bp = '\0'; - return bp - buf; -} - -hawk_oow_t hawk_byte_to_bcstr (hawk_oob_t byte, hawk_bch_t* buf, hawk_oow_t size, int flagged_radix, hawk_bch_t fill) -{ - hawk_bch_t tmp[(HAWK_SIZEOF(hawk_oob_t) * HAWK_BITS_PER_BYTE)]; - hawk_bch_t* p = tmp, * bp = buf, * be = buf + size - 1; - int radix; - hawk_bch_t radix_char; - - radix = (flagged_radix & HAWK_BYTE_TO_BCSTR_RADIXMASK); - radix_char = (flagged_radix & HAWK_BYTE_TO_BCSTR_LOWERCASE)? 'a': 'A'; - if (radix < 2 || radix > 36 || size <= 0) return 0; - - do - { - hawk_uint8_t digit = byte % radix; - if (digit < 10) *p++ = digit + '0'; - else *p++ = digit + radix_char - 10; - byte /= radix; - } - while (byte > 0); - - if (fill != '\0') - { - while (size - 1 > p - tmp) - { - *bp++ = fill; - size--; - } - } - - while (p > tmp && bp < be) *bp++ = *--p; - *bp = '\0'; - return bp - buf; -} - -/* ------------------------------------------------------------------------ */ - int hawk_conv_bchars_to_uchars_with_cmgr ( const hawk_bch_t* bcs, hawk_oow_t* bcslen, hawk_uch_t* ucs, hawk_oow_t* ucslen, hawk_cmgr_t* cmgr, int all)