From 226795c03e743ce3a599f88c80da194f7adb6149 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sat, 5 Nov 2011 00:50:55 +0000 Subject: [PATCH] added qse_fmtintmaxtombs()/qse_fmtintmaxtowcs() and related functions. changed qse_awk_t to use these new formatting functions. redefined some primitive types --- qse/include/qse/cmn/fmt.h | 214 +++++++++++++++++++--- qse/include/qse/types.h | 124 ++++++++++++- qse/lib/awk/misc.c | 19 -- qse/lib/awk/misc.h | 8 - qse/lib/awk/run.c | 35 ++-- qse/lib/awk/tree.c | 23 ++- qse/lib/cmn/fmt.c | 342 ++++++++++++++++++++++++++++++++---- qse/samples/cmn/Makefile.am | 3 +- qse/samples/cmn/Makefile.in | 32 ++-- qse/samples/cmn/fmt01.c | 33 +++- qse/samples/cmn/fmt02.c | 50 ++++++ 11 files changed, 751 insertions(+), 132 deletions(-) create mode 100644 qse/samples/cmn/fmt02.c diff --git a/qse/include/qse/cmn/fmt.h b/qse/include/qse/cmn/fmt.h index a43d0a06..465976f3 100644 --- a/qse/include/qse/cmn/fmt.h +++ b/qse/include/qse/cmn/fmt.h @@ -15,7 +15,7 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with QSE. If not, see . + License aintmax with QSE. If not, see . */ #ifndef _QSE_CMN_FMT_H_ @@ -28,54 +28,210 @@ * This file defines various formatting functions. */ -enum qse_fmtulongtowcs_flag_t +/** + * The qse_fmtintmaxtombs_flag_t type defines enumerators to change the + * behavior of qse_fmtintmaxtombs() and qse_fmtuintmaxtombs(). + */ +enum qse_fmtintmaxtombs_flag_t { - QSE_FMTULONGTOWCS_UPPERCASE = (0x100 << 0), -#define QSE_FMTULONGTOWCS_UPPERCASE QSE_FMTULONGTOWCS_UPPERCASE - QSE_FMTULONGTOWCS_FILLRIGHT = (0x100 << 1) -#define QSE_FMTULONGTOWCS_FILLRIGHT QSE_FMTULONGTOWCS_FILLRIGHT + /** Don't truncate if the buffer is not large enough */ + QSE_FMTINTMAXTOMBS_NOTRUNC = (0x100 << 0), + /** Don't append a terminating null */ + QSE_FMTINTMAXTOMBS_NONULL = (0x100 << 1), + /** Use uppercase letters for alphabetic digits */ + QSE_FMTINTMAXTOMBS_UPPERCASE = (0x100 << 2), + /** Insert a plus sign for a positive integer including 0 */ + QSE_FMTINTMAXTOMBS_PLUSSIGN = (0x100 << 3), + /** Fill the right part of the string */ + QSE_FMTINTMAXTOMBS_FILLRIGHT = (0x100 << 4), + /** Fill between the sign chacter and the digit part */ + QSE_FMTINTMAXTOMBS_FILLCENTER = (0x100 << 5) }; +#define QSE_FMTINTMAXTOMBS_NOTRUNC QSE_FMTINTMAXTOMBS_NOTRUNC +#define QSE_FMTINTMAXTOMBS_NONULL QSE_FMTINTMAXTOMBS_NONULL +#define QSE_FMTINTMAXTOMBS_UPPERCASE QSE_FMTINTMAXTOMBS_UPPERCASE +#define QSE_FMTINTMAXTOMBS_PLUSSIGN QSE_FMTINTMAXTOMBS_PLUSSIGN +#define QSE_FMTINTMAXTOMBS_FILLRIGHT QSE_FMTINTMAXTOMBS_FILLRIGHT +#define QSE_FMTINTMAXTOMBS_FILLCENTER QSE_FMTINTMAXTOMBS_FILLCENTER -enum qse_fmtulongtombs_flag_t +/** + * The qse_fmtintmaxtowcs_flag_t type defines enumerators to change the + * behavior of qse_fmtintmaxtowcs() and qse_fmtuintmaxtowcs(). + */ +enum qse_fmtintmaxtowcs_flag_t { - QSE_FMTULONGTOMBS_UPPERCASE = (0x100 << 0), -#define QSE_FMTULONGTOMBS_UPPERCASE QSE_FMTULONGTOMBS_UPPERCASE - QSE_FMTULONGTOMBS_FILLRIGHT = (0x100 << 1) -#define QSE_FMTULONGTOMBS_FILLRIGHT QSE_FMTULONGTOMBS_FILLRIGHT + /** Don't truncate if the buffer is not large enough */ + QSE_FMTINTMAXTOWCS_NOTRUNC = (0x100 << 0), + /** Don't append a terminating null */ + QSE_FMTINTMAXTOWCS_NONULL = (0x100 << 1), + /** Use uppercase letters for alphabetic digits */ + QSE_FMTINTMAXTOWCS_UPPERCASE = (0x100 << 2), + /** Insert a plus sign for a positive integer including 0 */ + QSE_FMTINTMAXTOWCS_PLUSSIGN = (0x100 << 3), + /** Fill the right part of the string */ + QSE_FMTINTMAXTOWCS_FILLRIGHT = (0x100 << 4), + /** Fill between the sign chacter and the digit part */ + QSE_FMTINTMAXTOWCS_FILLCENTER = (0x100 << 5) }; +#define QSE_FMTINTMAXTOWCS_NOTRUNC QSE_FMTINTMAXTOWCS_NOTRUNC +#define QSE_FMTINTMAXTOWCS_NONULL QSE_FMTINTMAXTOWCS_NONULL +#define QSE_FMTINTMAXTOWCS_UPPERCASE QSE_FMTINTMAXTOWCS_UPPERCASE +#define QSE_FMTINTMAXTOWCS_PLUSSIGN QSE_FMTINTMAXTOWCS_PLUSSIGN +#define QSE_FMTINTMAXTOWCS_FILLRIGHT QSE_FMTINTMAXTOWCS_FILLRIGHT +#define QSE_FMTINTMAXTOWCS_FILLCENTER QSE_FMTINTMAXTOWCS_FILLCENTER #ifdef QSE_CHAR_IS_MCHAR -# define QSE_FMTULONG_UPPERCASE QSE_FMTULONGTOMBS_UPPERCASE -# define QSE_FMTULONG_FILLRIGHT QSE_FMTULONGTOMBS_FILLRIGHT +# define QSE_FMTINTMAX_NOTRUNC QSE_FMTINTMAXTOMBS_NOTRUNC +# define QSE_FMTINTMAX_NONULL QSE_FMTINTMAXTOMBS_NONULL +# define QSE_FMTINTMAX_UPPERCASE QSE_FMTINTMAXTOMBS_UPPERCASE +# define QSE_FMTINTMAX_PLUSSIGN QSE_FMTINTMAXTOMBS_PLUSSIGN +# define QSE_FMTINTMAX_FILLRIGHT QSE_FMTINTMAXTOMBS_FILLRIGHT +# define QSE_FMTINTMAX_FILLCENTER QSE_FMTINTMAXTOMBS_FILLCENTER #else -# define QSE_FMTULONG_UPPERCASE QSE_FMTULONGTOWCS_UPPERCASE -# define QSE_FMTULONG_FILLRIGHT QSE_FMTULONGTOWCS_FILLRIGHT +# define QSE_FMTINTMAX_NOTRUNC QSE_FMTINTMAXTOWCS_NOTRUNC +# define QSE_FMTINTMAX_NONULL QSE_FMTINTMAXTOWCS_NONULL +# define QSE_FMTINTMAX_UPPERCASE QSE_FMTINTMAXTOWCS_UPPERCASE +# define QSE_FMTINTMAX_PLUSSIGN QSE_FMTINTMAXTOWCS_PLUSSIGN +# define QSE_FMTINTMAX_FILLRIGHT QSE_FMTINTMAXTOWCS_FILLRIGHT +# define QSE_FMTINTMAX_FILLCENTER QSE_FMTINTMAXTOWCS_FILLCENTER #endif #ifdef __cplusplus extern "C" { #endif -qse_size_t qse_fmtulongtombs ( - qse_mchar_t* buf, - qse_size_t size, - qse_long_t value, - int base_and_flags, - qse_mchar_t fill_char +/** + * The qse_fmtintmaxtombs() function formats an integer @a value to a + * multibyte string according to the given base and writes it to a buffer + * pointed to by @a buf. It writes to the buffer at most @a size characters + * including the terminating null. The base must be between 2 and 36 inclusive + * and can be ORed with zero or more #qse_fmtintmaxtombs_flag_t enumerators. + * This ORed value is passed to the function via the @a base_and_flags + * parameter. If the formatted string is shorter than @a bufsize, the redundant + * slots are filled with the fill character @a fillchar if it is not a null + * character. The filling behavior is determined by the flags shown below: + * + * - If #QSE_FMTINTMAXTOMBS_FILLRIGHT is set in @a base_and_flags, slots + * after the formatting string are filled. + * - If #QSE_FMTINTMAXTOMBS_FILLCENTER is set in @a base_and_flags, slots + * before the formatting string are filled. However, if it contains the + * sign character, the slots between the sign character and the digit part + * are filled. + * - If neither #QSE_FMTINTMAXTOMBS_FILLRIGHT nor #QSE_FMTINTMAXTOMBS_FILLCENTER + * , slots before the formatting string are filled. + * + * The terminating null is not added if #QSE_FMTINTMAXTOMBS_NONULL is set; + * The #QSE_FMTINTMAXTOMBS_UPPERCASE flag indicates that the function should + * use the uppercase letter for a alphabetic digit; + * You can set #QSE_FMTINTMAXTOMBS_NOTRUNC if you require lossless formatting. + * The #QSE_FMTINTMAXTOMBS_PLUSSIGN flag ensures that the plug sign is added + * for a positive integer including 0. + * + * @return + * - -1 if the base is not between 2 and 36 inclusive. + * - negated number of characters required for lossless formatting + * - if @a bufsize is 0. + * - if #QSE_FMTINTMAXTOMBS_NOTRUNC is set and @a bufsize is less than + * the minimum required for lossless formatting. + * - number of characters written to the buffer excluding a terminating + * null in all other cases. + */ +int qse_fmtintmaxtombs ( + qse_mchar_t* buf, /**< buffer pointer */ + int bufsize, /**< buffer size */ + qse_intmax_t value, /**< integer to format */ + int base_and_flags, /**< base ORed with flags */ + qse_mchar_t fillchar /**< fill character */ ); -qse_size_t qse_fmtulongtowcs ( - qse_wchar_t* buf, - qse_size_t size, - qse_long_t value, - int base_and_flags, - qse_wchar_t fill_char +/** + * The qse_fmtintmaxtowcs() function formats an integer @a value to a + * wide-character string according to the given base and writes it to a buffer + * pointed to by @a buf. It writes to the buffer at most @a size characters + * including the terminating null. The base must be between 2 and 36 inclusive + * and can be ORed with zero or more #qse_fmtintmaxtowcs_flag_t enumerators. + * This ORed value is passed to the function via the @a base_and_flags + * parameter. If the formatted string is shorter than @a bufsize, the redundant + * slots are filled with the fill character @a fillchar if it is not a null + * character. The filling behavior is determined by the flags shown below: + * + * - If #QSE_FMTINTMAXTOWCS_FILLRIGHT is set in @a base_and_flags, slots + * after the formatting string are filled. + * - If #QSE_FMTINTMAXTOWCS_FILLCENTER is set in @a base_and_flags, slots + * before the formatting string are filled. However, if it contains the + * sign character, the slots between the sign character and the digit part + * are filled. + * - If neither #QSE_FMTINTMAXTOWCS_FILLRIGHT nor #QSE_FMTINTMAXTOWCS_FILLCENTER + * , slots before the formatting string are filled. + * + * The terminating null is not added if #QSE_FMTINTMAXTOWCS_NONULL is set; + * The #QSE_FMTINTMAXTOWCS_UPPERCASE flag indicates that the function should + * use the uppercase letter for a alphabetic digit; + * You can set #QSE_FMTINTMAXTOWCS_NOTRUNC if you require lossless formatting. + * The #QSE_FMTINTMAXTOWCS_PLUSSIGN flag ensures that the plug sign is added + * for a positive integer including 0. + * + * @return + * - -1 if the base is not between 2 and 36 inclusive. + * - negated number of characters required for lossless formatting + * - if @a bufsize is 0. + * - if #QSE_FMTINTMAXTOWCS_NOTRUNC is set and @a bufsize is less than + * the minimum required for lossless formatting. + * - number of characters written to the buffer excluding a terminating + * null in all other cases. + */ +int qse_fmtintmaxtowcs ( + qse_wchar_t* buf, /**< buffer pointer */ + int bufsize, /**< buffer size */ + qse_intmax_t value, /**< integer to format */ + int base_and_flags, /**< base ORed with flags */ + qse_wchar_t fillchar /**< fill character */ ); +/** @def qse_fmtintmax + * The qse_fmtintmax() macro maps to qse_fmtintmaxtombs() if + * #QSE_CHAR_IS_MCHAR, and qse_fmtintmaxtowcs() if #QSE_CHAR_IS_WCHAR. + */ #ifdef QSE_CHAR_IS_MCHAR -# define qse_fmtulong(b,sz,v,bf,fc) qse_fmtulongtombs(b,sz,v,bf,fc) +# define qse_fmtintmax(b,sz,v,bf,fc) qse_fmtintmaxtombs(b,sz,v,bf,fc) #else -# define qse_fmtulong(b,sz,v,bf,fc) qse_fmtulongtowcs(b,sz,v,bf,fc) +# define qse_fmtintmax(b,sz,v,bf,fc) qse_fmtintmaxtowcs(b,sz,v,bf,fc) +#endif + +/** + * The qse_fmtuintmaxtombs() function formats an unsigned integer @a value + * to a multibyte string buffer. It behaves the same as qse_fmtuintmaxtombs() + * except that it handles an unsigned integer. + */ +int qse_fmtuintmaxtombs ( + qse_mchar_t* buf, /**< buffer pointer */ + int bufsize, /**< buffer size */ + qse_uintmax_t value, /**< integer to format */ + int base_and_flags, /**< base ORed with flags */ + qse_mchar_t fillchar /**< fill character */ +); + +/** + * The qse_fmtuintmaxtowcs() function formats an unsigned integer @a value + * to a wide-character string buffer. It behaves the same as + * qse_fmtuintmaxtowcs() except that it handles an unsigned integer. + */ +int qse_fmtuintmaxtowcs ( + qse_wchar_t* buf, /**< buffer pointer */ + int bufsize, /**< buffer size */ + qse_uintmax_t value, /**< integer to format */ + int base_and_flags, /**< base ORed with flags */ + qse_wchar_t fillchar /**< fill character */ +); + +/** @def qse_fmtuintmax + * The qse_fmtuintmax() macro maps to qse_fmtuintmaxtombs() if + * #QSE_CHAR_IS_MCHAR, and qse_fmtuintmaxtowcs() if #QSE_CHAR_IS_WCHAR. + */ +#ifdef QSE_CHAR_IS_MCHAR +# define qse_fmtuintmax(b,sz,v,bf,fc) qse_fmtuintmaxtombs(b,sz,v,bf,fc) +#else +# define qse_fmtuintmax(b,sz,v,bf,fc) qse_fmtuintmaxtowcs(b,sz,v,bf,fc) #endif #ifdef __cplusplus diff --git a/qse/include/qse/types.h b/qse/include/qse/types.h index 16c21306..2ed0b479 100644 --- a/qse/include/qse/types.h +++ b/qse/include/qse/types.h @@ -104,22 +104,41 @@ typedef enum qse_tri_t qse_tri_t; typedef unsigned __int32 qse_uint_t; #define QSE_SIZEOF_INT_T QSE_SIZEOF___INT32 #define QSE_SIZEOF_UINT_T QSE_SIZEOF___INT32 +#elif QSE_SIZEOF_VOID_P == QSE_SIZEOF___INT32_T + typedef __int32_t qse_int_t; + typedef unsigned __int32_t qse_uint_t; + #define QSE_SIZEOF_INT_T QSE_SIZEOF___INT32_T + #define QSE_SIZEOF_UINT_T QSE_SIZEOF___INT32_T #elif QSE_SIZEOF_VOID_P == QSE_SIZEOF___INT64 typedef __int64 qse_int_t; typedef unsigned __int64 qse_uint_t; #define QSE_SIZEOF_INT_T QSE_SIZEOF___INT64 #define QSE_SIZEOF_UINT_T QSE_SIZEOF___INT64 +#elif QSE_SIZEOF_VOID_P == QSE_SIZEOF___INT64_T + typedef __int64_t qse_int_t; + typedef unsigned __int64_t qse_uint_t; + #define QSE_SIZEOF_INT_T QSE_SIZEOF___INT64_T + #define QSE_SIZEOF_UINT_T QSE_SIZEOF___INT64_T +#elif QSE_SIZEOF_VOID_P == QSE_SIZEOF___INT128 + typedef __int128 qse_int_t; + typedef unsigned __int128 qse_uint_t; + #define QSE_SIZEOF_INT_T QSE_SIZEOF___INT128 + #define QSE_SIZEOF_UINT_T QSE_SIZEOF___INT128 +#elif QSE_SIZEOF_VOID_P == QSE_SIZEOF___INT128_T + typedef __int128_t qse_int_t; + typedef unsigned __int128_t qse_uint_t; + #define QSE_SIZEOF_INT_T QSE_SIZEOF___INT128_T + #define QSE_SIZEOF_UINT_T QSE_SIZEOF___INT128_T #else # error unsupported pointer size #endif /** @typedef qse_long_t - * The qse_long_t type defines the largest signed integer type supported + * The qse_long_t type defines the largest signed integer type that supported. */ /** @typedef qse_ulong_t - * The qse_ulong_t type defines the largest unsigned integer type supported + * The qse_ulong_t type defines the largest unsigned integer type supported. */ -/* TODO: use qse_int128_t in defining qse_long_t */ #if QSE_SIZEOF_LONG >= QSE_SIZEOF_LONG_LONG typedef long qse_long_t; typedef unsigned long qse_ulong_t; @@ -135,6 +154,11 @@ typedef enum qse_tri_t qse_tri_t; typedef unsigned __int64 qse_ulong_t; #define QSE_SIZEOF_LONG_T QSE_SIZEOF___INT64 #define QSE_SIZEOF_ULONG_T QSE_SIZEOF___INT64 +#elif QSE_SIZEOF___INT64_T > 0 + typedef __int64_t qse_long_t; + typedef unsigned __int64_t qse_ulong_t; + #define QSE_SIZEOF_LONG_T QSE_SIZEOF___INT64_T + #define QSE_SIZEOF_ULONG_T QSE_SIZEOF___INT64_T #else typedef long qse_long_t; typedef unsigned long qse_ulong_t; @@ -142,6 +166,11 @@ typedef enum qse_tri_t qse_tri_t; #define QSE_SIZEOF_ULONG_T QSE_SIZEOF_LONG #endif +/* these two items are revised whenever the size of a + * fixed-size integer is determined */ +#define QSE_SIZEOF_INTMAX_T 0 +#define QSE_SIZEOF_UINTMAX_T 0 + /** @typedef qse_int8_t * The qse_int8_t defines an 8-bit signed integer type. */ @@ -165,9 +194,16 @@ typedef enum qse_tri_t qse_tri_t; typedef __uint8_t qse_uint8_t; #endif -#ifdef QSE_HAVE_INT32_T -# define QSE_SIZEOF_INT16_T 1 -# define QSE_SIZEOF_UINT16_T 1 +#ifdef QSE_HAVE_INT8_T +# define QSE_SIZEOF_INT8_T 1 +# define QSE_SIZEOF_UINT8_T 1 +# undef QSE_SIZEOF_INTMAX_T +# undef QSE_SIZEOF_UINTMAX_T +# define QSE_SIZEOF_INTMAX_T 1 +# define QSE_SIZEOF_UINTMAX_T 1 +#else +# define QSE_SIZEOF_INT8_T 0 +# define QSE_SIZEOF_UINT8_T 0 #endif /** @typedef qse_int16_t @@ -193,9 +229,16 @@ typedef enum qse_tri_t qse_tri_t; typedef __uint16_t qse_uint16_t; #endif -#ifdef QSE_HAVE_INT32_T +#ifdef QSE_HAVE_INT16_T # define QSE_SIZEOF_INT16_T 2 # define QSE_SIZEOF_UINT16_T 2 +# undef QSE_SIZEOF_INTMAX_T +# undef QSE_SIZEOF_UINTMAX_T +# define QSE_SIZEOF_INTMAX_T 2 +# define QSE_SIZEOF_UINTMAX_T 2 +#else +# define QSE_SIZEOF_INT16_T 0 +# define QSE_SIZEOF_UINT16_T 0 #endif /** @typedef qse_int32_t @@ -229,6 +272,13 @@ typedef enum qse_tri_t qse_tri_t; #ifdef QSE_HAVE_INT32_T # define QSE_SIZEOF_INT32_T 4 # define QSE_SIZEOF_UINT32_T 4 +# undef QSE_SIZEOF_INTMAX_T +# undef QSE_SIZEOF_UINTMAX_T +# define QSE_SIZEOF_INTMAX_T 4 +# define QSE_SIZEOF_UINTMAX_T 4 +#else +# define QSE_SIZEOF_INT32_T 0 +# define QSE_SIZEOF_UINT32_T 0 #endif /** @typedef qse_int64_t @@ -267,6 +317,13 @@ typedef enum qse_tri_t qse_tri_t; #ifdef QSE_HAVE_INT64_T # define QSE_SIZEOF_INT64_T 8 # define QSE_SIZEOF_UINT64_T 8 +# undef QSE_SIZEOF_INTMAX_T +# undef QSE_SIZEOF_UINTMAX_T +# define QSE_SIZEOF_INTMAX_T 8 +# define QSE_SIZEOF_UINTMAX_T 8 +#else +# define QSE_SIZEOF_INT64_T 0 +# define QSE_SIZEOF_UINT64_T 0 #endif #if QSE_SIZEOF_INT == 16 @@ -299,12 +356,20 @@ typedef enum qse_tri_t qse_tri_t; #ifdef QSE_HAVE_INT128_T # define QSE_SIZEOF_INT128_T 16 # define QSE_SIZEOF_UINT128_T 16 +# undef QSE_SIZEOF_INTMAX_T +# undef QSE_SIZEOF_UINTMAX_T +# define QSE_SIZEOF_INTMAX_T 16 +# define QSE_SIZEOF_UINTMAX_T 16 +#else +# define QSE_SIZEOF_INT128_T 0 +# define QSE_SIZEOF_UINT128_T 0 #endif /** * The qse_byte_t defines a byte type. */ typedef qse_uint8_t qse_byte_t; +#define QSE_SIZEOF_BYTE_T QSE_SIZEOF_UINT8_T /** * The qse_size_t type defines an unsigned integer type that is as large as @@ -323,7 +388,7 @@ typedef qse_uint8_t qse_byte_t; * to hold a pointer value. */ typedef qse_int_t qse_ssize_t; -# define QSE_SIZEOF_SSIZE_T QSE_SIZEOF_INT_T +#define QSE_SIZEOF_SSIZE_T QSE_SIZEOF_INT_T /** * The qse_word_t type redefines qse_uint_t. @@ -345,6 +410,47 @@ typedef qse_uint_t qse_uintptr_t; typedef qse_int_t qse_intptr_t; #define QSE_SIZEOF_INTPTR_T QSE_SIZEOF_INT_T +/** @typedef qse_intmax_t + * The qse_llong_t type defines the largest signed integer type supported. + */ +/** @typedef qse_uintmax_t + * The qse_ullong_t type defines the largest unsigned integer type supported. + */ +#if (QSE_SIZEOF_LONG >= QSE_SIZEOF_LONG_LONG) && \ + (QSE_SIZEOF_LONG >= QSE_SIZEOF_INTMAX_T) + typedef long qse_intmax_t; + typedef unsigned long qse_uintmax_t; + #undef QSE_SIZEOF_INTMAX_T + #undef QSE_SIZEOF_UINTMAX_T + #define QSE_SIZEOF_INTMAX_T QSE_SIZEOF_LONG + #define QSE_SIZEOF_UINTMAX_T QSE_SIZEOF_LONG +#elif (QSE_SIZEOF_LONG_LONG >= QSE_SIZEOF_INTMAX_T) + typedef long long qse_intmax_t; + typedef unsigned long long qse_uintmax_t; + #undef QSE_SIZEOF_INTMAX_T + #undef QSE_SIZEOF_UINTMAX_T + #define QSE_SIZEOF_INTMAX_T QSE_SIZEOF_LONG_LONG + #define QSE_SIZEOF_UINTMAX_T QSE_SIZEOF_LONG_LONG +#elif (QSE_SIZEOF_INTMAX_T == QSE_SIZEOF_INT128_T) + typedef qse_int128_t qse_intmax_t; + typedef qse_uint128_t qse_uintmax_t; +#elif (QSE_SIZEOF_INTMAX_T == QSE_SIZEOF_INT64_T) + typedef qse_int64_t qse_intmax_t; + typedef qse_uint64_t qse_uintmax_t; +#elif (QSE_SIZEOF_INTMAX_T == QSE_SIZEOF_INT32_T) + typedef qse_int32_t qse_intmax_t; + typedef qse_uint32_t qse_uintmax_t; +#elif (QSE_SIZEOF_INTMAX_T == QSE_SIZEOF_INT16_T) + typedef qse_int16_t qse_intmax_t; + typedef qse_uint16_t qse_uintmax_t; +#elif (QSE_SIZEOF_INTMAX_T == QSE_SIZEOF_INT8_T) + typedef qse_int8_t qse_intmax_t; + typedef qse_uint8_t qse_uintmax_t; +#else +# error FATAL. THIS MUST NOT HAPPEN +#endif + + /** @typedef qse_real_t * The qse_real_t type defines the largest floating-pointer number type * supported. @@ -646,6 +752,8 @@ union qse_ubi_t qse_word_t word; qse_intptr_t intptr; qse_uintptr_t uintptr; + qse_intmax_t intmax; + qse_uintmax_t uintmax; qse_real_t real; qse_char_t cha; diff --git a/qse/lib/awk/misc.c b/qse/lib/awk/misc.c index 284a93c3..9c55da99 100644 --- a/qse/lib/awk/misc.c +++ b/qse/lib/awk/misc.c @@ -1108,25 +1108,6 @@ void qse_awk_rtx_freemem (qse_awk_rtx_t* rtx, void* ptr) qse_awk_freemem (rtx->awk, ptr); } -int qse_awk_sprintlong ( - qse_awk_t* awk, qse_char_t* buf, qse_size_t len, qse_long_t num) -{ - return awk->prm.sprintf ( - awk, buf, len, - #if QSE_SIZEOF_LONG_LONG > 0 - QSE_T("%lld"), (long long)num - #elif QSE_SIZEOF___INT64 > 0 - QSE_T("%I64d"), (__int64)num - #elif QSE_SIZEOF_LONG > 0 - QSE_T("%ld"), (long)num - #elif QSE_SIZEOF_INT > 0 - QSE_T("%d"), (int)num - #else - #error unsupported size - #endif - ); -} - int qse_awk_sprintreal ( qse_awk_t* awk, qse_char_t* buf, qse_size_t len, qse_real_t num) { diff --git a/qse/lib/awk/misc.h b/qse/lib/awk/misc.h index 67381a87..b562a69b 100644 --- a/qse/lib/awk/misc.h +++ b/qse/lib/awk/misc.h @@ -76,14 +76,6 @@ int qse_awk_matchrex ( qse_cstr_t* match, qse_awk_errnum_t* errnum ); -int qse_awk_sprintlong ( - qse_awk_t* awk, - qse_char_t* buf, - qse_size_t len, - qse_long_t num -); - - int qse_awk_sprintreal ( qse_awk_t* awk, qse_char_t* buf, diff --git a/qse/lib/awk/run.c b/qse/lib/awk/run.c index 860e28b1..e8eb70cb 100644 --- a/qse/lib/awk/run.c +++ b/qse/lib/awk/run.c @@ -19,6 +19,7 @@ */ #include "awk.h" +#include #ifdef DEBUG_RUN #include @@ -6777,14 +6778,19 @@ qse_char_t* qse_awk_rtx_format ( do { - n = qse_awk_sprintlong ( - rtx->awk, + n = qse_fmtintmax ( rtx->format.tmp.ptr, rtx->format.tmp.len, - width - ); - if (n == -1) + width, + 10 | QSE_FMTINTMAX_NOTRUNC, + QSE_T('\0') + ); + if (n <= -1) { + /* TODO: utilize n in GROW. + * since -n is the number of characters required + * including terminating null, it can be used there + * this doesn't have to be in the loop any more */ GROW (&rtx->format.tmp); if (rtx->format.tmp.ptr == QSE_NULL) { @@ -6799,6 +6805,8 @@ qse_char_t* qse_awk_rtx_format ( } while (1); + /* TODO: we know that n is the length. + * the contents can be added without scanning the whole string again */ p = rtx->format.tmp.ptr; while (*p != QSE_T('\0')) { @@ -6870,14 +6878,19 @@ qse_char_t* qse_awk_rtx_format ( do { - n = qse_awk_sprintlong ( - rtx->awk, + n = qse_fmtintmax ( rtx->format.tmp.ptr, rtx->format.tmp.len, - prec - ); - if (n == -1) + prec, + 10 | QSE_FMTINTMAX_NOTRUNC, + QSE_T('\0') + ); + if (n <= -1) { + /* TODO: utilize n in GROW. + * since -n is the number of characters required + * including terminating null, it can be used there. + * this doesn't have to be in the loop any more */ GROW (&rtx->format.tmp); if (rtx->format.tmp.ptr == QSE_NULL) { @@ -6891,6 +6904,8 @@ qse_char_t* qse_awk_rtx_format ( } while (1); + /* TODO: we know that n is the length. + * the contents can be added without scanning the whole string again */ p = rtx->format.tmp.ptr; while (*p != QSE_T('\0')) { diff --git a/qse/lib/awk/tree.c b/qse/lib/awk/tree.c index afba4d96..2cdff4ad 100644 --- a/qse/lib/awk/tree.c +++ b/qse/lib/awk/tree.c @@ -19,6 +19,7 @@ */ #include "awk.h" +#include static const qse_char_t* assop_str[] = { @@ -268,10 +269,24 @@ static int print_expr (qse_awk_t* awk, qse_awk_nde_t* nde) } else { - qse_char_t buf[64]; - qse_awk_sprintlong ( - awk, buf, QSE_COUNTOF(buf), - ((qse_awk_nde_int_t*)nde)->val); + /* Note that the array sizing fomula is not accurate + * but should be good enoug consiering the followings. + * + * size minval digits sign + * 1 -128 3 1 + * 2 -32768 5 1 + * 4 -2147483648 10 1 + * 8 -9223372036854775808 19 1 + * 16 -170141183460469231731687303715884105728 39 1 + */ + qse_char_t buf[QSE_SIZEOF(qse_long_t) * 3 + 2]; + + qse_fmtintmax ( + buf, QSE_COUNTOF(buf), + ((qse_awk_nde_int_t*)nde)->val, + 10, + QSE_T('\0') + ); PUT_SRCSTR (awk, buf); } break; diff --git a/qse/lib/cmn/fmt.c b/qse/lib/cmn/fmt.c index 9f6be3b4..38b446a6 100644 --- a/qse/lib/cmn/fmt.c +++ b/qse/lib/cmn/fmt.c @@ -21,25 +21,23 @@ #include /* ==================== multibyte ===================================== */ -qse_size_t qse_fmtulongtombs ( - qse_mchar_t* buf, qse_size_t size, - qse_long_t value, int base_and_flags, qse_mchar_t fillchar) +static int fmt_unsigned_to_mbs ( + qse_mchar_t* buf, int size, + qse_uintmax_t value, int base_and_flags, + qse_mchar_t fillchar, qse_mchar_t signchar) { - qse_mchar_t tmp[(QSE_SIZEOF(qse_ulong_t) * 8)]; + qse_mchar_t tmp[(QSE_SIZEOF(qse_uintmax_t) * 8)]; + int reslen, base, xsize, reqlen; qse_mchar_t* p, * bp, * be; - int base; qse_mchar_t xbasechar; base = base_and_flags & 0xFF; - if (base < 2 || base > 36 || size <= 0) return 0; + if (base < 2 || base > 36) return -1; - p = tmp; - bp = buf; - be = buf + size - 1; - - xbasechar = (base_and_flags & QSE_FMTULONGTOMBS_UPPERCASE)? QSE_MT('A'): QSE_MT('a'); + xbasechar = (base_and_flags & QSE_FMTINTMAXTOMBS_UPPERCASE)? QSE_MT('A'): QSE_MT('a'); /* store the resulting numeric string into 'tmp' first */ + p = tmp; do { int digit = value % base; @@ -49,66 +47,152 @@ qse_size_t qse_fmtulongtombs ( } while (value > 0); + /* reslen is the length of the resulting string without padding. */ + reslen = (int)(p - tmp); + if (signchar) reslen++; /* increment reslen for the sign character */ + + /* get the required buffer size for lossless formatting */ + reqlen = (base_and_flags & QSE_FMTINTMAXTOMBS_NONULL)? reslen: (reslen + 1); + + if (size <= 0 || + ((base_and_flags & QSE_FMTINTMAXTOMBS_NOTRUNC) && size < reqlen)) + { + return -reqlen; + } + + xsize = (base_and_flags & QSE_FMTINTMAXTOMBS_NONULL)? size: (size - 1); + bp = buf; + be = buf + xsize; + /* fill space */ if (fillchar != QSE_MT('\0')) { - qse_size_t tmplen = p - tmp; - if (base_and_flags & QSE_FMTULONGTOMBS_FILLRIGHT) + if (base_and_flags & QSE_FMTINTMAXTOMBS_FILLRIGHT) { + /* emit sign */ + if (signchar && bp < be) *bp++ = signchar; + /* copy the numeric string to the destination buffer */ while (p > tmp && bp < be) *bp++ = *--p; /* fill the right side */ - while (size - 1 > tmplen) + while (xsize > reslen) { *bp++ = fillchar; - size--; + xsize--; } } + else if (base_and_flags & QSE_FMTINTMAXTOMBS_FILLCENTER) + { + /* emit sign */ + if (signchar && bp < be) *bp++ = signchar; + + /* fill the left side */ + while (xsize > reslen) + { + *bp++ = fillchar; + xsize--; + } + + /* copy the numeric string to the destination buffer */ + while (p > tmp && bp < be) *bp++ = *--p; + } else { /* fill the left side */ - while (size - 1 > tmplen) + while (xsize > reslen) { *bp++ = fillchar; - size--; + xsize--; } + /* emit sign */ + if (signchar && bp < be) *bp++ = signchar; + /* copy the numeric string to the destination buffer */ while (p > tmp && bp < be) *bp++ = *--p; } } else { + /* emit sign */ + if (signchar && bp < be) *bp++ = signchar; + /* copy the numeric string to the destination buffer */ while (p > tmp && bp < be) *bp++ = *--p; } - *bp = QSE_MT('\0'); + if (!(base_and_flags & QSE_FMTINTMAXTOMBS_NONULL)) *bp = QSE_MT('\0'); return bp - buf; } -/* ==================== wide-char ===================================== */ -qse_size_t qse_fmtulongtowcs ( - qse_wchar_t* buf, qse_size_t size, - qse_long_t value, int base_and_flags, qse_wchar_t fillchar) +int qse_fmtintmaxtombs ( + qse_mchar_t* buf, int size, + qse_intmax_t value, int base_and_flags, qse_mchar_t fillchar) { - qse_wchar_t tmp[(QSE_SIZEOF(qse_ulong_t) * 8)]; + qse_mchar_t signchar; + qse_uintmax_t absvalue; + + if (value < 0) + { + signchar = QSE_MT('-'); + absvalue = -value; + } + else if (base_and_flags & QSE_FMTINTMAXTOMBS_PLUSSIGN) + { + signchar = QSE_MT('+'); + absvalue = value; + } + else + { + signchar = QSE_MT('\0'); + absvalue = value; + } + + return fmt_unsigned_to_mbs (buf, size, absvalue, base_and_flags, fillchar, signchar); +} + +int qse_fmtuintmaxtombs ( + qse_mchar_t* buf, int size, + qse_uintmax_t value, int base_and_flags, qse_mchar_t fillchar) +{ + qse_mchar_t signchar; + + /* determine if a sign character is needed */ + if (base_and_flags & QSE_FMTINTMAXTOMBS_PLUSSIGN) + { + signchar = QSE_MT('+'); + } + else + { + signchar = QSE_MT('\0'); + } + + return fmt_unsigned_to_mbs (buf, size, value, base_and_flags, fillchar, signchar); +} + + +/* ==================== wide-char ===================================== */ + +#if 0 +static int fmt_unsigned_to_wcs ( + qse_wchar_t* buf, int size, + qse_uintmax_t value, int base_and_flags, + qse_wchar_t fillchar, qse_wchar_t signchar) +{ + qse_wchar_t tmp[(QSE_SIZEOF(qse_uintmax_t) * 8)]; + int reslen, base; qse_wchar_t* p, * bp, * be; - int base; qse_wchar_t xbasechar; base = base_and_flags & 0xFF; - if (base < 2 || base > 36 || size <= 0) return 0; + if (base < 2 || base > 36) return -1; - p = tmp; - bp = buf; - be = buf + size - 1; - - xbasechar = (base_and_flags & QSE_FMTULONGTOWCS_UPPERCASE)? QSE_WT('A'): QSE_WT('a'); + xbasechar = (base_and_flags & QSE_FMTINTMAXTOWCS_UPPERCASE)? QSE_WT('A'): QSE_WT('a'); /* store the resulting numeric string into 'tmp' first */ + p = tmp; do { int digit = value % base; @@ -118,38 +202,75 @@ qse_size_t qse_fmtulongtowcs ( } while (value > 0); + /* reslen is the length of the resulting string without padding. */ + reslen = (int)(p - tmp); + if (signchar) reslen++; /* increment reslen for the sign character */ + + if (size <= 0 || + ((base_and_flags & QSE_FMTINTMAXTOWCS_NOTRUNC) && size <= reslen)) + { + /* conversion without loss requires at least 'reslen + 1'. */ + return -(reslen + 1); + } + + bp = buf; + be = buf + size - 1; + /* fill space */ if (fillchar != QSE_WT('\0')) { - qse_size_t tmplen = p - tmp; - if (base_and_flags & QSE_FMTULONGTOWCS_FILLRIGHT) + if (base_and_flags & QSE_FMTINTMAXTOWCS_FILLRIGHT) { + /* emit sign */ + if (signchar && bp < be) *bp++ = signchar; + /* copy the numeric string to the destination buffer */ while (p > tmp && bp < be) *bp++ = *--p; /* fill the right side */ - while (size - 1 > tmplen) + while (size - 1 > reslen) { *bp++ = fillchar; size--; } } - else + else if (base_and_flags & QSE_FMTINTMAXTOWCS_FILLCENTER) { + /* emit sign */ + if (signchar && bp < be) *bp++ = signchar; + /* fill the left side */ - while (size - 1 > tmplen) + while (size - 1 > reslen) { *bp++ = fillchar; size--; } + /* copy the numeric string to the destination buffer */ + while (p > tmp && bp < be) *bp++ = *--p; + } + else + { + /* fill the left side */ + while (size - 1 > reslen) + { + *bp++ = fillchar; + size--; + } + + /* emit sign */ + if (signchar && bp < be) *bp++ = signchar; + /* copy the numeric string to the destination buffer */ while (p > tmp && bp < be) *bp++ = *--p; } } else { + /* emit sign */ + if (signchar && bp < be) *bp++ = signchar; + /* copy the numeric string to the destination buffer */ while (p > tmp && bp < be) *bp++ = *--p; } @@ -157,5 +278,156 @@ qse_size_t qse_fmtulongtowcs ( *bp = QSE_WT('\0'); return bp - buf; } +#endif +static int fmt_unsigned_to_wcs ( + qse_wchar_t* buf, int size, + qse_uintmax_t value, int base_and_flags, + qse_wchar_t fillchar, qse_wchar_t signchar) +{ + qse_wchar_t tmp[(QSE_SIZEOF(qse_uintmax_t) * 8)]; + int reslen, base, xsize, reqlen; + qse_wchar_t* p, * bp, * be; + qse_wchar_t xbasechar; + + base = base_and_flags & 0xFF; + if (base < 2 || base > 36) return -1; + + xbasechar = (base_and_flags & QSE_FMTINTMAXTOWCS_UPPERCASE)? QSE_WT('A'): QSE_WT('a'); + + /* store the resulting numeric string into 'tmp' first */ + p = tmp; + do + { + int digit = value % base; + if (digit < 10) *p++ = digit + QSE_WT('0'); + else *p++ = digit + xbasechar - 10; + value /= base; + } + while (value > 0); + + /* reslen is the length of the resulting string without padding. */ + reslen = (int)(p - tmp); + if (signchar) reslen++; /* increment reslen for the sign character */ + + /* get the required buffer size for lossless formatting */ + reqlen = (base_and_flags & QSE_FMTINTMAXTOWCS_NONULL)? reslen: (reslen + 1); + + if (size <= 0 || + ((base_and_flags & QSE_FMTINTMAXTOWCS_NOTRUNC) && size < reqlen)) + { + return -reqlen; + } + + xsize = (base_and_flags & QSE_FMTINTMAXTOWCS_NONULL)? size: (size - 1); + bp = buf; + be = buf + xsize; + + /* fill space */ + if (fillchar != QSE_WT('\0')) + { + + if (base_and_flags & QSE_FMTINTMAXTOWCS_FILLRIGHT) + { + /* emit sign */ + if (signchar && bp < be) *bp++ = signchar; + + /* copy the numeric string to the destination buffer */ + while (p > tmp && bp < be) *bp++ = *--p; + + /* fill the right side */ + while (xsize > reslen) + { + *bp++ = fillchar; + xsize--; + } + } + else if (base_and_flags & QSE_FMTINTMAXTOWCS_FILLCENTER) + { + /* emit sign */ + if (signchar && bp < be) *bp++ = signchar; + + /* fill the left side */ + while (xsize > reslen) + { + *bp++ = fillchar; + xsize--; + } + + /* copy the numeric string to the destination buffer */ + while (p > tmp && bp < be) *bp++ = *--p; + } + else + { + /* fill the left side */ + while (xsize > reslen) + { + *bp++ = fillchar; + xsize--; + } + + /* emit sign */ + if (signchar && bp < be) *bp++ = signchar; + + /* copy the numeric string to the destination buffer */ + while (p > tmp && bp < be) *bp++ = *--p; + } + } + else + { + /* emit sign */ + if (signchar && bp < be) *bp++ = signchar; + + /* copy the numeric string to the destination buffer */ + while (p > tmp && bp < be) *bp++ = *--p; + } + + if (!(base_and_flags & QSE_FMTINTMAXTOWCS_NONULL)) *bp = QSE_WT('\0'); + return bp - buf; +} + +int qse_fmtintmaxtowcs ( + qse_wchar_t* buf, int size, + qse_intmax_t value, int base_and_flags, qse_wchar_t fillchar) +{ + qse_wchar_t signchar; + qse_uintmax_t absvalue; + + if (value < 0) + { + signchar = QSE_WT('-'); + absvalue = -value; + } + else if (base_and_flags & QSE_FMTINTMAXTOWCS_PLUSSIGN) + { + signchar = QSE_WT('+'); + absvalue = value; + } + else + { + signchar = QSE_WT('\0'); + absvalue = value; + } + + return fmt_unsigned_to_wcs (buf, size, absvalue, base_and_flags, fillchar, signchar); +} + +int qse_fmtuintmaxtowcs ( + qse_wchar_t* buf, int size, + qse_uintmax_t value, int base_and_flags, qse_wchar_t fillchar) +{ + qse_wchar_t signchar; + + /* determine if a sign character is needed */ + if (base_and_flags & QSE_FMTINTMAXTOWCS_PLUSSIGN) + { + signchar = QSE_WT('+'); + } + else + { + signchar = QSE_WT('\0'); + } + + return fmt_unsigned_to_wcs (buf, size, value, base_and_flags, fillchar, signchar); +} diff --git a/qse/samples/cmn/Makefile.am b/qse/samples/cmn/Makefile.am index 29b514af..967b7aad 100644 --- a/qse/samples/cmn/Makefile.am +++ b/qse/samples/cmn/Makefile.am @@ -6,7 +6,7 @@ AM_CPPFLAGS = \ -I$(includedir) -bin_PROGRAMS = xma fma pma chr str sll dll lda oht htb rbt fio pio sio time main main2 rex01 env path01 tre01 fmt01 +bin_PROGRAMS = xma fma pma chr str sll dll lda oht htb rbt fio pio sio time main main2 rex01 env path01 tre01 fmt01 fmt02 LDFLAGS = -L../../lib/cmn LDADD = -lqsecmn @@ -33,6 +33,7 @@ env_SOURCES = env.c path01_SOURCES = path01.c tre01_SOURCES = tre01.c fmt01_SOURCES = fmt01.c +fmt02_SOURCES = fmt02.c if ENABLE_CXX diff --git a/qse/samples/cmn/Makefile.in b/qse/samples/cmn/Makefile.in index a2ac12d0..485dcb4e 100644 --- a/qse/samples/cmn/Makefile.in +++ b/qse/samples/cmn/Makefile.in @@ -39,7 +39,7 @@ bin_PROGRAMS = xma$(EXEEXT) fma$(EXEEXT) pma$(EXEEXT) chr$(EXEEXT) \ oht$(EXEEXT) htb$(EXEEXT) rbt$(EXEEXT) fio$(EXEEXT) \ pio$(EXEEXT) sio$(EXEEXT) time$(EXEEXT) main$(EXEEXT) \ main2$(EXEEXT) rex01$(EXEEXT) env$(EXEEXT) path01$(EXEEXT) \ - tre01$(EXEEXT) fmt01$(EXEEXT) + tre01$(EXEEXT) fmt01$(EXEEXT) fmt02$(EXEEXT) subdir = samples/cmn DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -80,6 +80,10 @@ am_fmt01_OBJECTS = fmt01.$(OBJEXT) fmt01_OBJECTS = $(am_fmt01_OBJECTS) fmt01_LDADD = $(LDADD) fmt01_DEPENDENCIES = +am_fmt02_OBJECTS = fmt02.$(OBJEXT) +fmt02_OBJECTS = $(am_fmt02_OBJECTS) +fmt02_LDADD = $(LDADD) +fmt02_DEPENDENCIES = am_htb_OBJECTS = htb.$(OBJEXT) htb_OBJECTS = $(am_htb_OBJECTS) htb_LDADD = $(LDADD) @@ -158,17 +162,18 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(chr_SOURCES) $(dll_SOURCES) $(env_SOURCES) $(fio_SOURCES) \ - $(fma_SOURCES) $(fmt01_SOURCES) $(htb_SOURCES) $(lda_SOURCES) \ - $(main_SOURCES) $(main2_SOURCES) $(oht_SOURCES) \ - $(path01_SOURCES) $(pio_SOURCES) $(pma_SOURCES) $(rbt_SOURCES) \ - $(rex01_SOURCES) $(sio_SOURCES) $(sll_SOURCES) $(str_SOURCES) \ - $(time_SOURCES) $(tre01_SOURCES) $(xma_SOURCES) + $(fma_SOURCES) $(fmt01_SOURCES) $(fmt02_SOURCES) \ + $(htb_SOURCES) $(lda_SOURCES) $(main_SOURCES) $(main2_SOURCES) \ + $(oht_SOURCES) $(path01_SOURCES) $(pio_SOURCES) $(pma_SOURCES) \ + $(rbt_SOURCES) $(rex01_SOURCES) $(sio_SOURCES) $(sll_SOURCES) \ + $(str_SOURCES) $(time_SOURCES) $(tre01_SOURCES) $(xma_SOURCES) DIST_SOURCES = $(chr_SOURCES) $(dll_SOURCES) $(env_SOURCES) \ - $(fio_SOURCES) $(fma_SOURCES) $(fmt01_SOURCES) $(htb_SOURCES) \ - $(lda_SOURCES) $(main_SOURCES) $(main2_SOURCES) $(oht_SOURCES) \ - $(path01_SOURCES) $(pio_SOURCES) $(pma_SOURCES) $(rbt_SOURCES) \ - $(rex01_SOURCES) $(sio_SOURCES) $(sll_SOURCES) $(str_SOURCES) \ - $(time_SOURCES) $(tre01_SOURCES) $(xma_SOURCES) + $(fio_SOURCES) $(fma_SOURCES) $(fmt01_SOURCES) \ + $(fmt02_SOURCES) $(htb_SOURCES) $(lda_SOURCES) $(main_SOURCES) \ + $(main2_SOURCES) $(oht_SOURCES) $(path01_SOURCES) \ + $(pio_SOURCES) $(pma_SOURCES) $(rbt_SOURCES) $(rex01_SOURCES) \ + $(sio_SOURCES) $(sll_SOURCES) $(str_SOURCES) $(time_SOURCES) \ + $(tre01_SOURCES) $(xma_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -342,6 +347,7 @@ env_SOURCES = env.c path01_SOURCES = path01.c tre01_SOURCES = tre01.c fmt01_SOURCES = fmt01.c +fmt02_SOURCES = fmt02.c all: all-am .SUFFIXES: @@ -437,6 +443,9 @@ fma$(EXEEXT): $(fma_OBJECTS) $(fma_DEPENDENCIES) fmt01$(EXEEXT): $(fmt01_OBJECTS) $(fmt01_DEPENDENCIES) @rm -f fmt01$(EXEEXT) $(LINK) $(fmt01_OBJECTS) $(fmt01_LDADD) $(LIBS) +fmt02$(EXEEXT): $(fmt02_OBJECTS) $(fmt02_DEPENDENCIES) + @rm -f fmt02$(EXEEXT) + $(LINK) $(fmt02_OBJECTS) $(fmt02_LDADD) $(LIBS) htb$(EXEEXT): $(htb_OBJECTS) $(htb_DEPENDENCIES) @rm -f htb$(EXEEXT) $(LINK) $(htb_OBJECTS) $(htb_LDADD) $(LIBS) @@ -498,6 +507,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fio.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fma.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fmt01.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fmt02.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lda.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ diff --git a/qse/samples/cmn/fmt01.c b/qse/samples/cmn/fmt01.c index 056308c2..2273c5fc 100644 --- a/qse/samples/cmn/fmt01.c +++ b/qse/samples/cmn/fmt01.c @@ -3,14 +3,26 @@ static int test_main (int argc, qse_char_t* argv[], qse_char_t* envp[]) { - qse_char_t buf[50]; + qse_char_t buf[17]; int bases[] = { 2, 8, 10, 16 }; int flags[] = { - 0, - QSE_FMTULONG_UPPERCASE, - QSE_FMTULONG_FILLRIGHT, - QSE_FMTULONG_UPPERCASE | QSE_FMTULONG_FILLRIGHT + QSE_FMTINTMAX_NOTRUNC | 0, + QSE_FMTINTMAX_NOTRUNC | QSE_FMTINTMAX_UPPERCASE, + QSE_FMTINTMAX_NOTRUNC | QSE_FMTINTMAX_FILLRIGHT, + QSE_FMTINTMAX_NOTRUNC | QSE_FMTINTMAX_UPPERCASE | QSE_FMTINTMAX_PLUSSIGN, + QSE_FMTINTMAX_NOTRUNC | QSE_FMTINTMAX_UPPERCASE | QSE_FMTINTMAX_FILLRIGHT, + QSE_FMTINTMAX_NOTRUNC | QSE_FMTINTMAX_UPPERCASE | QSE_FMTINTMAX_FILLCENTER, + QSE_FMTINTMAX_NOTRUNC | QSE_FMTINTMAX_UPPERCASE | QSE_FMTINTMAX_FILLRIGHT | QSE_FMTINTMAX_PLUSSIGN, + QSE_FMTINTMAX_NOTRUNC | QSE_FMTINTMAX_UPPERCASE | QSE_FMTINTMAX_FILLCENTER | QSE_FMTINTMAX_PLUSSIGN, + QSE_FMTINTMAX_NOTRUNC | QSE_FMTINTMAX_NONULL | 0, + QSE_FMTINTMAX_NOTRUNC | QSE_FMTINTMAX_NONULL | QSE_FMTINTMAX_UPPERCASE, + QSE_FMTINTMAX_NOTRUNC | QSE_FMTINTMAX_NONULL | QSE_FMTINTMAX_FILLRIGHT, + QSE_FMTINTMAX_NOTRUNC | QSE_FMTINTMAX_NONULL | QSE_FMTINTMAX_UPPERCASE | QSE_FMTINTMAX_PLUSSIGN, + QSE_FMTINTMAX_NOTRUNC | QSE_FMTINTMAX_NONULL | QSE_FMTINTMAX_UPPERCASE | QSE_FMTINTMAX_FILLRIGHT, + QSE_FMTINTMAX_NOTRUNC | QSE_FMTINTMAX_NONULL | QSE_FMTINTMAX_UPPERCASE | QSE_FMTINTMAX_FILLCENTER, + QSE_FMTINTMAX_NOTRUNC | QSE_FMTINTMAX_NONULL | QSE_FMTINTMAX_UPPERCASE | QSE_FMTINTMAX_FILLRIGHT | QSE_FMTINTMAX_PLUSSIGN, + QSE_FMTINTMAX_NOTRUNC | QSE_FMTINTMAX_NONULL | QSE_FMTINTMAX_UPPERCASE | QSE_FMTINTMAX_FILLCENTER | QSE_FMTINTMAX_PLUSSIGN }; int i, j; int num = 0xF0F3; @@ -19,8 +31,15 @@ static int test_main (int argc, qse_char_t* argv[], qse_char_t* envp[]) { for (j = 0; j < QSE_COUNTOF(flags); j++) { - qse_fmtulong (buf, QSE_COUNTOF(buf), num, bases[i] | flags[j], QSE_T('.')); - qse_printf (QSE_T("%8X => [%4d:%04X] [%s]\n"), num, bases[i], flags[j], buf); + int n = qse_fmtuintmax (buf, QSE_COUNTOF(buf), num, bases[i] | flags[j], QSE_T('.')); + if (n <= -1) + { + qse_printf (QSE_T("%8X => [%4d:%04X] ERROR[%d]\n"), num, bases[i], flags[j], n); + } + else + { + qse_printf (QSE_T("%8X => [%4d:%04X] [%.*s][%d]\n"), num, bases[i], flags[j], n, buf, n); + } } } diff --git a/qse/samples/cmn/fmt02.c b/qse/samples/cmn/fmt02.c new file mode 100644 index 00000000..37ed17e9 --- /dev/null +++ b/qse/samples/cmn/fmt02.c @@ -0,0 +1,50 @@ +#include +#include + +static int test_main (int argc, qse_char_t* argv[], qse_char_t* envp[]) +{ + qse_char_t buf[129]; + int bases[] = { 2, 8, 10, 16 }; + int flags[] = + { + QSE_FMTINTMAX_PLUSSIGN, + QSE_FMTINTMAX_FILLRIGHT | QSE_FMTINTMAX_PLUSSIGN, + QSE_FMTINTMAX_FILLCENTER | QSE_FMTINTMAX_PLUSSIGN + }; + int i, j, k; + qse_intmax_t nums[] = { -12345, 12345, 0, QSE_TYPE_MAX(qse_intmax_t) }; + + /* note that nums[3] may not be printed properly with %d in printf(). + * however, the formatting result with qse_fmtintmax() should be printed + * properly. + */ + + + for (k = 0; k < QSE_COUNTOF(nums) ; k++) + { + for (i = 0; i < QSE_COUNTOF(bases); i++) + { + for (j = 0; j < QSE_COUNTOF(flags); j++) + { + int n = qse_fmtintmax (buf, QSE_COUNTOF(buf), nums[k], bases[i] | flags[j] | QSE_FMTINTMAX_NOTRUNC, QSE_T('.')); + if (n <= -1) + { + qse_printf (QSE_T("%8d => [%4d:%04X] ERROR[%d]\n"), (int)nums[k], bases[i], flags[j], n); + } + else + { + qse_printf (QSE_T("%8d => [%4d:%04X] [%s]\n"), (int)nums[k], bases[i], flags[j], buf); + } + } + } + qse_printf (QSE_T("------------------------------\n")); + } + + return 0; +} + +int qse_main (int argc, qse_achar_t* argv[], qse_achar_t* envp[]) +{ + return qse_runmainwithenv (argc, argv, envp, test_main); +} +