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);
+}
+