added prefix to qse_fmtintmax() and qse_fmtuintmax().
chnaged awk's printf to use qse_fmtintmax().
This commit is contained in:
		| @ -29,72 +29,50 @@ | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| /**  | /**  | ||||||
|  * The qse_fmtintmaxtombs_flag_t type defines enumerators to change the |  * The qse_fmtintmax_flag_t type defines enumerators to change the | ||||||
|  * behavior of qse_fmtintmaxtombs() and qse_fmtuintmaxtombs(). |  * behavior of qse_fmtintmax() and qse_fmtuintmax(). | ||||||
|  */ |  */ | ||||||
| enum qse_fmtintmaxtombs_flag_t | enum qse_fmtintmax_flag_t | ||||||
| { | { | ||||||
| 	/** Don't truncate if the buffer is not large enough */ | 	/** Don't truncate if the buffer is not large enough */ | ||||||
| 	QSE_FMTINTMAXTOMBS_NOTRUNC = (0x100 << 0), | 	QSE_FMTINTMAX_NOTRUNC = (0x100 << 0), | ||||||
| 	/** Don't append a terminating null */ | 	/** Don't append a terminating null */ | ||||||
|      QSE_FMTINTMAXTOMBS_NONULL = (0x100 << 1), | 	QSE_FMTINTMAX_NONULL = (0x100 << 1), | ||||||
| 	/** Use uppercase letters for alphabetic digits */ | 	/** Use uppercase letters for alphabetic digits */ | ||||||
| 	QSE_FMTINTMAXTOMBS_UPPERCASE = (0x100 << 2), | 	QSE_FMTINTMAX_UPPERCASE = (0x100 << 2), | ||||||
| 	/** Insert a plus sign for a positive integer including 0 */ | 	/** Insert a plus sign for a positive integer including 0 */ | ||||||
| 	QSE_FMTINTMAXTOMBS_PLUSSIGN = (0x100 << 3), | 	QSE_FMTINTMAX_PLUSSIGN = (0x100 << 3), | ||||||
|  | 	/** Insert a space for a positive integer including 0 */ | ||||||
|  | 	QSE_FMTINTMAX_EMPTYSIGN = (0x100 << 4), | ||||||
| 	/** Fill the right part of the string */ | 	/** Fill the right part of the string */ | ||||||
| 	QSE_FMTINTMAXTOMBS_FILLRIGHT = (0x100 << 4), | 	QSE_FMTINTMAX_FILLRIGHT = (0x100 << 5), | ||||||
| 	/** Fill between the sign chacter and the digit part */ | 	/** Fill between the sign chacter and the digit part */ | ||||||
| 	QSE_FMTINTMAXTOMBS_FILLCENTER = (0x100 << 5) | 	QSE_FMTINTMAX_FILLCENTER = (0x100 << 6) | ||||||
| }; | }; | ||||||
| #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 |  | ||||||
|  |  | ||||||
| /**  | #define QSE_FMTINTMAX_NOTRUNC         QSE_FMTINTMAX_NOTRUNC | ||||||
|  * The qse_fmtintmaxtowcs_flag_t type defines enumerators to change the | #define QSE_FMTINTMAX_NONULL          QSE_FMTINTMAX_NONULL | ||||||
|  * behavior of qse_fmtintmaxtowcs() and qse_fmtuintmaxtowcs(). | #define QSE_FMTINTMAX_UPPERCASE       QSE_FMTINTMAX_UPPERCASE | ||||||
|  */ | #define QSE_FMTINTMAX_PLUSSIGN        QSE_FMTINTMAX_PLUSSIGN | ||||||
| enum qse_fmtintmaxtowcs_flag_t | #define QSE_FMTINTMAX_EMPTYSIGN       QSE_FMTINTMAX_EMPTYSIGN | ||||||
| { | #define QSE_FMTINTMAX_FILLRIGHT       QSE_FMTINTMAX_FILLRIGHT | ||||||
| 	/** Don't truncate if the buffer is not large enough */ | #define QSE_FMTINTMAX_FILLCENTER      QSE_FMTINTMAX_FILLCENTER | ||||||
| 	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_FMTINTMAXTOMBS_NOTRUNC    QSE_FMTINTMAX_NOTRUNC | ||||||
| #	define QSE_FMTINTMAX_NOTRUNC    QSE_FMTINTMAXTOMBS_NOTRUNC | #define QSE_FMTINTMAXTOMBS_NONULL     QSE_FMTINTMAX_NONULL | ||||||
| #	define QSE_FMTINTMAX_NONULL     QSE_FMTINTMAXTOMBS_NONULL | #define QSE_FMTINTMAXTOMBS_UPPERCASE  QSE_FMTINTMAX_UPPERCASE | ||||||
| #	define QSE_FMTINTMAX_UPPERCASE  QSE_FMTINTMAXTOMBS_UPPERCASE | #define QSE_FMTINTMAXTOMBS_PLUSSIGN   QSE_FMTINTMAX_PLUSSIGN | ||||||
| #	define QSE_FMTINTMAX_PLUSSIGN   QSE_FMTINTMAXTOMBS_PLUSSIGN | #define QSE_FMTINTMAXTOMBS_EMPTYSIGN  QSE_FMTINTMAX_EMPTYSIGN | ||||||
| #	define QSE_FMTINTMAX_FILLRIGHT  QSE_FMTINTMAXTOMBS_FILLRIGHT | #define QSE_FMTINTMAXTOMBS_FILLRIGHT  QSE_FMTINTMAX_FILLRIGHT | ||||||
| #	define QSE_FMTINTMAX_FILLCENTER QSE_FMTINTMAXTOMBS_FILLCENTER | #define QSE_FMTINTMAXTOMBS_FILLCENTER QSE_FMTINTMAX_FILLCENTER | ||||||
| #else |  | ||||||
| #	define QSE_FMTINTMAX_NOTRUNC    QSE_FMTINTMAXTOWCS_NOTRUNC | #define QSE_FMTINTMAXTOWCS_NOTRUNC    QSE_FMTINTMAX_NOTRUNC | ||||||
| #	define QSE_FMTINTMAX_NONULL     QSE_FMTINTMAXTOWCS_NONULL | #define QSE_FMTINTMAXTOWCS_NONULL     QSE_FMTINTMAX_NONULL | ||||||
| #	define QSE_FMTINTMAX_UPPERCASE  QSE_FMTINTMAXTOWCS_UPPERCASE | #define QSE_FMTINTMAXTOWCS_UPPERCASE  QSE_FMTINTMAX_UPPERCASE | ||||||
| #	define QSE_FMTINTMAX_PLUSSIGN   QSE_FMTINTMAXTOWCS_PLUSSIGN | #define QSE_FMTINTMAXTOWCS_PLUSSIGN   QSE_FMTINTMAX_PLUSSIGN | ||||||
| #	define QSE_FMTINTMAX_FILLRIGHT  QSE_FMTINTMAXTOWCS_FILLRIGHT | #define QSE_FMTINTMAXTOWCS_EMPTYSIGN  QSE_FMTINTMAX_EMPTYSIGN | ||||||
| #	define QSE_FMTINTMAX_FILLCENTER QSE_FMTINTMAXTOWCS_FILLCENTER | #define QSE_FMTINTMAXTOWCS_FILLRIGHT  QSE_FMTINTMAX_FILLRIGHT | ||||||
| #endif | #define QSE_FMTINTMAXTOWCS_FILLCENTER QSE_FMTINTMAX_FILLCENTER | ||||||
|  |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| extern "C" { | extern "C" { | ||||||
| @ -124,8 +102,11 @@ extern "C" { | |||||||
|  * The #QSE_FMTINTMAXTOMBS_UPPERCASE flag indicates that the function should |  * The #QSE_FMTINTMAXTOMBS_UPPERCASE flag indicates that the function should | ||||||
|  * use the uppercase letter for a alphabetic digit;  |  * use the uppercase letter for a alphabetic digit;  | ||||||
|  * You can set #QSE_FMTINTMAXTOMBS_NOTRUNC if you require lossless formatting. |  * You can set #QSE_FMTINTMAXTOMBS_NOTRUNC if you require lossless formatting. | ||||||
|  * The #QSE_FMTINTMAXTOMBS_PLUSSIGN flag ensures that the plug sign is added |  * The #QSE_FMTINTMAXTOMBS_PLUSSIGN flag and #QSE_FMTINTMAXTOMBS_EMPTYSIGN  | ||||||
|  * for a positive integer including 0. |  * ensures that the plus sign and a space is added for a positive integer  | ||||||
|  |  * including 0 respectively. | ||||||
|  |  *  | ||||||
|  |  * If @a prefix is not #QSE_NULL, it is inserted before the digits. | ||||||
|  *  |  *  | ||||||
|  * @return |  * @return | ||||||
|  *  - -1 if the base is not between 2 and 36 inclusive.  |  *  - -1 if the base is not between 2 and 36 inclusive.  | ||||||
| @ -137,11 +118,12 @@ extern "C" { | |||||||
|  *    null in all other cases. |  *    null in all other cases. | ||||||
|  */ |  */ | ||||||
| int qse_fmtintmaxtombs ( | int qse_fmtintmaxtombs ( | ||||||
| 	qse_mchar_t* buf,             /**< buffer pointer */ | 	qse_mchar_t*       buf,             /**< buffer pointer */ | ||||||
| 	int          bufsize,         /**< buffer size */ | 	int                bufsize,         /**< buffer size */ | ||||||
| 	qse_intmax_t value,           /**< integer to format */ | 	qse_intmax_t       value,           /**< integer to format */ | ||||||
| 	int          base_and_flags,  /**< base ORed with flags */ | 	int                base_and_flags,  /**< base ORed with flags */ | ||||||
| 	qse_mchar_t  fillchar         /**< fill character */ | 	qse_mchar_t        fillchar,        /**< fill character */ | ||||||
|  | 	const qse_mchar_t* prefix           /**< prefix */ | ||||||
| ); | ); | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @ -168,8 +150,11 @@ int qse_fmtintmaxtombs ( | |||||||
|  * The #QSE_FMTINTMAXTOWCS_UPPERCASE flag indicates that the function should |  * The #QSE_FMTINTMAXTOWCS_UPPERCASE flag indicates that the function should | ||||||
|  * use the uppercase letter for a alphabetic digit;  |  * use the uppercase letter for a alphabetic digit;  | ||||||
|  * You can set #QSE_FMTINTMAXTOWCS_NOTRUNC if you require lossless formatting. |  * You can set #QSE_FMTINTMAXTOWCS_NOTRUNC if you require lossless formatting. | ||||||
|  * The #QSE_FMTINTMAXTOWCS_PLUSSIGN flag ensures that the plug sign is added |  * The #QSE_FMTINTMAXTOWCS_PLUSSIGN flag and #QSE_FMTINTMAXTOWCS_EMPTYSIGN  | ||||||
|  * for a positive integer including 0. |  * ensures that the plus sign and a space is added for a positive integer  | ||||||
|  |  * including 0 respectively. | ||||||
|  |  * | ||||||
|  |  * If @a prefix is not #QSE_NULL, it is inserted before the digits. | ||||||
|  *  |  *  | ||||||
|  * @return |  * @return | ||||||
|  *  - -1 if the base is not between 2 and 36 inclusive.  |  *  - -1 if the base is not between 2 and 36 inclusive.  | ||||||
| @ -181,11 +166,12 @@ int qse_fmtintmaxtombs ( | |||||||
|  *    null in all other cases. |  *    null in all other cases. | ||||||
|  */ |  */ | ||||||
| int qse_fmtintmaxtowcs ( | int qse_fmtintmaxtowcs ( | ||||||
| 	qse_wchar_t* buf,             /**< buffer pointer */ | 	qse_wchar_t*       buf,             /**< buffer pointer */ | ||||||
| 	int          bufsize,         /**< buffer size */ | 	int                bufsize,         /**< buffer size */ | ||||||
| 	qse_intmax_t value,           /**< integer to format */ | 	qse_intmax_t       value,           /**< integer to format */ | ||||||
| 	int          base_and_flags,  /**< base ORed with flags */ | 	int                base_and_flags,  /**< base ORed with flags */ | ||||||
| 	qse_wchar_t  fillchar         /**< fill character */ | 	qse_wchar_t        fillchar,        /**< fill character */ | ||||||
|  | 	const qse_wchar_t* prefix           /**< prefix */ | ||||||
| ); | ); | ||||||
|  |  | ||||||
| /** @def qse_fmtintmax | /** @def qse_fmtintmax | ||||||
| @ -193,9 +179,9 @@ int qse_fmtintmaxtowcs ( | |||||||
|  * #QSE_CHAR_IS_MCHAR, and qse_fmtintmaxtowcs() if #QSE_CHAR_IS_WCHAR. |  * #QSE_CHAR_IS_MCHAR, and qse_fmtintmaxtowcs() if #QSE_CHAR_IS_WCHAR. | ||||||
|  */ |  */ | ||||||
| #ifdef QSE_CHAR_IS_MCHAR | #ifdef QSE_CHAR_IS_MCHAR | ||||||
| #	define qse_fmtintmax(b,sz,v,bf,fc) qse_fmtintmaxtombs(b,sz,v,bf,fc) | #	define qse_fmtintmax(b,sz,v,bf,fc,pf) qse_fmtintmaxtombs(b,sz,v,bf,fc,pf) | ||||||
| #else | #else | ||||||
| #	define qse_fmtintmax(b,sz,v,bf,fc) qse_fmtintmaxtowcs(b,sz,v,bf,fc) | #	define qse_fmtintmax(b,sz,v,bf,fc,pf) qse_fmtintmaxtowcs(b,sz,v,bf,fc,pf) | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @ -204,11 +190,12 @@ int qse_fmtintmaxtowcs ( | |||||||
|  * except that it handles an unsigned integer. |  * except that it handles an unsigned integer. | ||||||
|  */ |  */ | ||||||
| int qse_fmtuintmaxtombs ( | int qse_fmtuintmaxtombs ( | ||||||
| 	qse_mchar_t*  buf,             /**< buffer pointer */ | 	qse_mchar_t*       buf,             /**< buffer pointer */ | ||||||
| 	int           bufsize,         /**< buffer size */ | 	int                bufsize,         /**< buffer size */ | ||||||
| 	qse_uintmax_t value,           /**< integer to format */ | 	qse_uintmax_t      value,           /**< integer to format */ | ||||||
| 	int           base_and_flags,  /**< base ORed with flags */ | 	int                base_and_flags,  /**< base ORed with flags */ | ||||||
| 	qse_mchar_t   fillchar         /**< fill character */ | 	qse_mchar_t        fillchar,        /**< fill character */ | ||||||
|  | 	const qse_mchar_t* prefix           /**< prefix */ | ||||||
| ); | ); | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @ -217,11 +204,12 @@ int qse_fmtuintmaxtombs ( | |||||||
|  * qse_fmtuintmaxtowcs() except that it handles an unsigned integer. |  * qse_fmtuintmaxtowcs() except that it handles an unsigned integer. | ||||||
|  */ |  */ | ||||||
| int qse_fmtuintmaxtowcs ( | int qse_fmtuintmaxtowcs ( | ||||||
| 	qse_wchar_t*  buf,             /**< buffer pointer */ | 	qse_wchar_t*       buf,             /**< buffer pointer */ | ||||||
| 	int           bufsize,         /**< buffer size */ | 	int                bufsize,         /**< buffer size */ | ||||||
| 	qse_uintmax_t value,           /**< integer to format */ | 	qse_uintmax_t      value,           /**< integer to format */ | ||||||
| 	int           base_and_flags,  /**< base ORed with flags */ | 	int                base_and_flags,  /**< base ORed with flags */ | ||||||
| 	qse_wchar_t   fillchar         /**< fill character */ | 	qse_wchar_t        fillchar,        /**< fill character */ | ||||||
|  | 	const qse_wchar_t* prefix           /**< prefix */ | ||||||
| ); | ); | ||||||
|  |  | ||||||
| /** @def qse_fmtuintmax | /** @def qse_fmtuintmax | ||||||
| @ -229,9 +217,9 @@ int qse_fmtuintmaxtowcs ( | |||||||
|  * #QSE_CHAR_IS_MCHAR, and qse_fmtuintmaxtowcs() if #QSE_CHAR_IS_WCHAR. |  * #QSE_CHAR_IS_MCHAR, and qse_fmtuintmaxtowcs() if #QSE_CHAR_IS_WCHAR. | ||||||
|  */ |  */ | ||||||
| #ifdef QSE_CHAR_IS_MCHAR | #ifdef QSE_CHAR_IS_MCHAR | ||||||
| #	define qse_fmtuintmax(b,sz,v,bf,fc) qse_fmtuintmaxtombs(b,sz,v,bf,fc) | #	define qse_fmtuintmax(b,sz,v,bf,fc,pf) qse_fmtuintmaxtombs(b,sz,v,bf,fc,pf) | ||||||
| #else | #else | ||||||
| #	define qse_fmtuintmax(b,sz,v,bf,fc) qse_fmtuintmaxtowcs(b,sz,v,bf,fc) | #	define qse_fmtuintmax(b,sz,v,bf,fc,pf) qse_fmtuintmaxtowcs(b,sz,v,bf,fc,pf) | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
|  | |||||||
| @ -691,8 +691,8 @@ qse_awk_rtx_t* qse_awk_rtx_open ( | |||||||
| { | { | ||||||
| 	qse_awk_rtx_t* rtx; | 	qse_awk_rtx_t* rtx; | ||||||
|  |  | ||||||
|         QSE_ASSERTX (awk->prm.math.pow != QSE_NULL, "Call qse_awk_setprm() first"); | 	QSE_ASSERTX (awk->prm.math.pow != QSE_NULL, "Call qse_awk_setprm() first"); | ||||||
|         QSE_ASSERTX (awk->prm.sprintf != QSE_NULL, "Call qse_awk_setprm() first"); | 	QSE_ASSERTX (awk->prm.sprintf != QSE_NULL, "Call qse_awk_setprm() first"); | ||||||
|  |  | ||||||
| 	/* clear the awk error code */ | 	/* clear the awk error code */ | ||||||
| 	qse_awk_seterrnum (awk, QSE_AWK_ENOERR, QSE_NULL); | 	qse_awk_seterrnum (awk, QSE_AWK_ENOERR, QSE_NULL); | ||||||
| @ -6662,7 +6662,7 @@ qse_char_t* qse_awk_rtx_format ( | |||||||
| 	const qse_char_t* fmt, qse_size_t fmt_len,  | 	const qse_char_t* fmt, qse_size_t fmt_len,  | ||||||
| 	qse_size_t nargs_on_stack, qse_awk_nde_t* args, qse_size_t* len) | 	qse_size_t nargs_on_stack, qse_awk_nde_t* args, qse_size_t* len) | ||||||
| { | { | ||||||
| 	qse_size_t i, j; | 	qse_size_t i; | ||||||
| 	qse_size_t stack_arg_idx = 1; | 	qse_size_t stack_arg_idx = 1; | ||||||
| 	qse_awk_val_t* val; | 	qse_awk_val_t* val; | ||||||
|  |  | ||||||
| @ -6674,6 +6674,14 @@ qse_char_t* qse_awk_rtx_format ( | |||||||
| 	} \ | 	} \ | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | #define OUT_STR(ptr,len) QSE_BLOCK( \ | ||||||
|  | 	if (qse_str_ncat (out, (ptr), (len)) == -1) \ | ||||||
|  | 	{ \ | ||||||
|  | 		SETERR_COD (rtx, QSE_AWK_ENOMEM); \ | ||||||
|  | 		return QSE_NULL; \ | ||||||
|  | 	} \ | ||||||
|  | ) | ||||||
|  |  | ||||||
| #define FMT_CHAR(c) QSE_BLOCK( \ | #define FMT_CHAR(c) QSE_BLOCK( \ | ||||||
| 	if (qse_str_ccat (fbu, (c)) == -1) \ | 	if (qse_str_ccat (fbu, (c)) == -1) \ | ||||||
| 	{ \ | 	{ \ | ||||||
| @ -6682,8 +6690,16 @@ qse_char_t* qse_awk_rtx_format ( | |||||||
| 	} \ | 	} \ | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | #define FMT_STR(ptr,len) QSE_BLOCK( \ | ||||||
|  | 	if (qse_str_ncat (fbu, (ptr), (len)) == -1) \ | ||||||
|  | 	{ \ | ||||||
|  | 		SETERR_COD (rtx, QSE_AWK_ENOMEM); \ | ||||||
|  | 		return QSE_NULL; \ | ||||||
|  | 	} \ | ||||||
|  | ) | ||||||
|  |  | ||||||
| #define GROW(buf) QSE_BLOCK( \ | #define GROW(buf) QSE_BLOCK( \ | ||||||
| 	if ((buf)->ptr != QSE_NULL) \ | 	if ((buf)->ptr) \ | ||||||
| 	{ \ | 	{ \ | ||||||
| 		QSE_AWK_FREE (rtx->awk, (buf)->ptr); \ | 		QSE_AWK_FREE (rtx->awk, (buf)->ptr); \ | ||||||
| 		(buf)->ptr = QSE_NULL; \ | 		(buf)->ptr = QSE_NULL; \ | ||||||
| @ -6695,6 +6711,24 @@ qse_char_t* qse_awk_rtx_format ( | |||||||
| 	{ \ | 	{ \ | ||||||
| 		SETERR_COD (rtx, QSE_AWK_ENOMEM); \ | 		SETERR_COD (rtx, QSE_AWK_ENOMEM); \ | ||||||
| 		(buf)->len = 0; \ | 		(buf)->len = 0; \ | ||||||
|  | 		return QSE_NULL; \ | ||||||
|  | 	} \ | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | #define GROW_WITH_INC(buf,incv) QSE_BLOCK( \ | ||||||
|  | 	if ((buf)->ptr) \ | ||||||
|  | 	{ \ | ||||||
|  | 		QSE_AWK_FREE (rtx->awk, (buf)->ptr); \ | ||||||
|  | 		(buf)->ptr = QSE_NULL; \ | ||||||
|  | 	} \ | ||||||
|  | 	(buf)->len += ((incv) > (buf)->inc)? (incv): (buf)->inc; \ | ||||||
|  | 	(buf)->ptr = (qse_char_t*)QSE_AWK_ALLOC ( \ | ||||||
|  | 		rtx->awk, (buf)->len * QSE_SIZEOF(qse_char_t)); \ | ||||||
|  | 	if ((buf)->ptr == QSE_NULL) \ | ||||||
|  | 	{ \ | ||||||
|  | 		SETERR_COD (rtx, QSE_AWK_ENOMEM); \ | ||||||
|  | 		(buf)->len = 0; \ | ||||||
|  | 		return QSE_NULL; \ | ||||||
| 	} \ | 	} \ | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @ -6719,16 +6753,36 @@ qse_char_t* qse_awk_rtx_format ( | |||||||
|  |  | ||||||
| 	for (i = 0; i < fmt_len; i++) | 	for (i = 0; i < fmt_len; i++) | ||||||
| 	{ | 	{ | ||||||
| 		qse_long_t width = -1, prec = -1; | 		qse_long_t wp[2]; | ||||||
| 		int minus = 0; | 		int wp_idx; | ||||||
|  | #define WP_WIDTH     0 | ||||||
|  | #define WP_PRECISION 1 | ||||||
|  |  | ||||||
|  | 		int flags; | ||||||
|  | #define FLAG_SPACE (1 << 0) | ||||||
|  | #define FLAG_HASH  (1 << 1) | ||||||
|  | #define FLAG_ZERO  (1 << 2) | ||||||
|  | #define FLAG_PLUS  (1 << 3) | ||||||
|  | #define FLAG_MINUS (1 << 4) | ||||||
|  |  | ||||||
| 		if (QSE_STR_LEN(fbu) == 0) | 		if (QSE_STR_LEN(fbu) == 0) | ||||||
| 		{ | 		{ | ||||||
| 			if (fmt[i] == QSE_T('%')) FMT_CHAR (fmt[i]); | 			/* format specifier is empty */ | ||||||
| 			else OUT_CHAR (fmt[i]); | 			if (fmt[i] == QSE_T('%'))  | ||||||
|  | 			{ | ||||||
|  | 				/* add % to format specifier (fbu) */ | ||||||
|  | 				FMT_CHAR (fmt[i]); | ||||||
|  | 			} | ||||||
|  | 			else  | ||||||
|  | 			{ | ||||||
|  | 				/* normal output */ | ||||||
|  | 				OUT_CHAR (fmt[i]); | ||||||
|  | 			} | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		/* handle flags */ | ||||||
|  | #if 0 | ||||||
| 		while (i < fmt_len && | 		while (i < fmt_len && | ||||||
| 		       (fmt[i] == QSE_T(' ') || fmt[i] == QSE_T('#') || | 		       (fmt[i] == QSE_T(' ') || fmt[i] == QSE_T('#') || | ||||||
| 		        fmt[i] == QSE_T('0') || fmt[i] == QSE_T('+') || | 		        fmt[i] == QSE_T('0') || fmt[i] == QSE_T('+') || | ||||||
| @ -6737,111 +6791,47 @@ qse_char_t* qse_awk_rtx_format ( | |||||||
| 			if (fmt[i] == QSE_T('-')) minus = 1; | 			if (fmt[i] == QSE_T('-')) minus = 1; | ||||||
| 			FMT_CHAR (fmt[i]); i++; | 			FMT_CHAR (fmt[i]); i++; | ||||||
| 		} | 		} | ||||||
|  | #endif | ||||||
|  |  | ||||||
| 		if (i < fmt_len && fmt[i] == QSE_T('*')) | 		flags = 0; | ||||||
|  | 		while (i < fmt_len) | ||||||
| 		{ | 		{ | ||||||
| 			qse_awk_val_t* v; | 			switch (fmt[i]) | ||||||
| 			qse_char_t* p; |  | ||||||
| 			int n; |  | ||||||
|  |  | ||||||
| 			if (args == QSE_NULL) |  | ||||||
| 			{ | 			{ | ||||||
| 				if (stack_arg_idx >= nargs_on_stack) | 				case QSE_T(' '): | ||||||
| 				{ | 					flags |= FLAG_SPACE; | ||||||
| 					SETERR_COD (rtx, QSE_AWK_EFMTARG); | 					break; | ||||||
| 					return QSE_NULL; | 				case QSE_T('#'): | ||||||
| 				} | 					flags |= FLAG_HASH; | ||||||
| 				v = qse_awk_rtx_getarg (rtx, stack_arg_idx); | 					break; | ||||||
| 			} | 				case QSE_T('0'): | ||||||
| 			else | 					flags |= FLAG_ZERO; | ||||||
| 			{ | 					break; | ||||||
| 				if (val != QSE_NULL)  | 				case QSE_T('+'): | ||||||
| 				{ | 					flags |= FLAG_PLUS; | ||||||
| 					if (stack_arg_idx >= nargs_on_stack) | 					break; | ||||||
| 					{ | 				case QSE_T('-'): | ||||||
| 						SETERR_COD (rtx, QSE_AWK_EFMTARG); | 					flags |= FLAG_MINUS; | ||||||
| 						return QSE_NULL; | 					break; | ||||||
| 					} | 				default: | ||||||
| 					v = val; | 					goto wp_mod_init; | ||||||
| 				} |  | ||||||
| 				else  |  | ||||||
| 				{ |  | ||||||
| 					v = eval_expression (rtx, args); |  | ||||||
| 					if (v == QSE_NULL) return QSE_NULL; |  | ||||||
| 				} |  | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			qse_awk_rtx_refupval (rtx, v); |  | ||||||
| 			n = qse_awk_rtx_valtolong (rtx, v, &width); |  | ||||||
| 			qse_awk_rtx_refdownval (rtx, v); |  | ||||||
| 			if (n <= -1) return QSE_NULL;  |  | ||||||
|  |  | ||||||
| 			do |  | ||||||
| 			{ |  | ||||||
| 				n = qse_fmtintmax ( |  | ||||||
| 					rtx->format.tmp.ptr, |  | ||||||
| 					rtx->format.tmp.len, |  | ||||||
| 					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) |  | ||||||
| 					{ |  | ||||||
| 						SETERR_COD (rtx, QSE_AWK_ENOMEM); |  | ||||||
| 						return QSE_NULL; |  | ||||||
| 					} |  | ||||||
|  |  | ||||||
| 					continue; |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				break; |  | ||||||
| 			} |  | ||||||
| 			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')) |  | ||||||
| 			{ |  | ||||||
| 				FMT_CHAR (*p); |  | ||||||
| 				p++; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			if (args == QSE_NULL || val != QSE_NULL) stack_arg_idx++; |  | ||||||
| 			else args = args->next; |  | ||||||
| 			i++; |  | ||||||
| 		} |  | ||||||
| 		else |  | ||||||
| 		{ |  | ||||||
| 			if (i < fmt_len && QSE_AWK_ISDIGIT(rtx->awk, fmt[i])) |  | ||||||
| 			{ |  | ||||||
| 				width = 0; |  | ||||||
| 				do |  | ||||||
| 				{ |  | ||||||
| 					width = width * 10 + fmt[i] - QSE_T('0'); |  | ||||||
| 					FMT_CHAR (fmt[i]); i++; |  | ||||||
| 				} |  | ||||||
| 				while (i < fmt_len && QSE_AWK_ISDIGIT(rtx->awk, fmt[i])); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if (i < fmt_len && fmt[i] == QSE_T('.')) |  | ||||||
| 		{ |  | ||||||
| 			prec = 0; |  | ||||||
| 			FMT_CHAR (fmt[i]); i++; | 			FMT_CHAR (fmt[i]); i++; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | wp_mod_init: | ||||||
|  | 		wp[WP_WIDTH] = -1; /* width */ | ||||||
|  | 		wp[WP_PRECISION] = -1; /* precision */ | ||||||
|  | 		wp_idx = WP_WIDTH; /* width first */ | ||||||
|  |  | ||||||
|  | wp_mod_main: | ||||||
| 		if (i < fmt_len && fmt[i] == QSE_T('*')) | 		if (i < fmt_len && fmt[i] == QSE_T('*')) | ||||||
| 		{ | 		{ | ||||||
|  | 			/* variable width/precision modifier. | ||||||
|  | 			 * take the width/precision from a parameter and | ||||||
|  | 			 * transform it to a fixed length format */ | ||||||
| 			qse_awk_val_t* v; | 			qse_awk_val_t* v; | ||||||
| 			qse_char_t* p; |  | ||||||
| 			int n; | 			int n; | ||||||
|  |  | ||||||
| 			if (args == QSE_NULL) | 			if (args == QSE_NULL) | ||||||
| @ -6872,7 +6862,7 @@ qse_char_t* qse_awk_rtx_format ( | |||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			qse_awk_rtx_refupval (rtx, v); | 			qse_awk_rtx_refupval (rtx, v); | ||||||
| 			n = qse_awk_rtx_valtolong (rtx, v, &prec); | 			n = qse_awk_rtx_valtolong (rtx, v, &wp[wp_idx]); | ||||||
| 			qse_awk_rtx_refdownval (rtx, v); | 			qse_awk_rtx_refdownval (rtx, v); | ||||||
| 			if (n <= -1) return QSE_NULL;  | 			if (n <= -1) return QSE_NULL;  | ||||||
|  |  | ||||||
| @ -6881,22 +6871,16 @@ qse_char_t* qse_awk_rtx_format ( | |||||||
| 				n = qse_fmtintmax ( | 				n = qse_fmtintmax ( | ||||||
| 					rtx->format.tmp.ptr, | 					rtx->format.tmp.ptr, | ||||||
| 					rtx->format.tmp.len, | 					rtx->format.tmp.len, | ||||||
| 					prec,  | 					wp[wp_idx],  | ||||||
| 					10 | QSE_FMTINTMAX_NOTRUNC, | 					10 | QSE_FMTINTMAX_NOTRUNC | QSE_FMTINTMAX_NONULL, | ||||||
| 					QSE_T('\0') | 					QSE_T('\0'), | ||||||
|  | 					QSE_NULL | ||||||
| 				);	 | 				);	 | ||||||
| 				if (n <= -1) | 				if (n <= -1) | ||||||
| 				{ | 				{ | ||||||
| 					/* TODO: utilize n in GROW. | 					/* -n is the number of characters required | ||||||
| 					 * since -n is the number of characters required | 					 * including terminating null  */ | ||||||
| 					 * including terminating null, it can be used there. | 					GROW_WITH_INC (&rtx->format.tmp, -n); | ||||||
| 					 * this doesn't have to be in the loop any more */ |  | ||||||
| 					GROW (&rtx->format.tmp); |  | ||||||
| 					if (rtx->format.tmp.ptr == QSE_NULL) |  | ||||||
| 					{ |  | ||||||
| 						SETERR_COD (rtx, QSE_AWK_ENOMEM); |  | ||||||
| 						return QSE_NULL; |  | ||||||
| 					} |  | ||||||
| 					continue; | 					continue; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| @ -6904,14 +6888,7 @@ qse_char_t* qse_awk_rtx_format ( | |||||||
| 			} | 			} | ||||||
| 			while (1); | 			while (1); | ||||||
|  |  | ||||||
| 			/* TODO: we know that n is the length. | 			FMT_STR(rtx->format.tmp.ptr, n); | ||||||
| 			 * the contents can be added without scanning the whole string again */ |  | ||||||
| 			p = rtx->format.tmp.ptr; |  | ||||||
| 			while (*p != QSE_T('\0')) |  | ||||||
| 			{ |  | ||||||
| 				FMT_CHAR (*p); |  | ||||||
| 				p++; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			if (args == QSE_NULL || val != QSE_NULL) stack_arg_idx++; | 			if (args == QSE_NULL || val != QSE_NULL) stack_arg_idx++; | ||||||
| 			else args = args->next; | 			else args = args->next; | ||||||
| @ -6919,18 +6896,28 @@ qse_char_t* qse_awk_rtx_format ( | |||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
|  | 			/* fixed width/precision modifier */ | ||||||
| 			if (i < fmt_len && QSE_AWK_ISDIGIT(rtx->awk, fmt[i])) | 			if (i < fmt_len && QSE_AWK_ISDIGIT(rtx->awk, fmt[i])) | ||||||
| 			{ | 			{ | ||||||
| 				prec = 0; | 				wp[wp_idx] = 0; | ||||||
| 				do | 				do | ||||||
| 				{ | 				{ | ||||||
| 					prec = prec * 10 + fmt[i] - QSE_T('0'); | 					wp[wp_idx] = wp[wp_idx] * 10 + fmt[i] - QSE_T('0'); | ||||||
| 					FMT_CHAR (fmt[i]); i++; | 					FMT_CHAR (fmt[i]); i++; | ||||||
| 				} | 				} | ||||||
| 				while (i < fmt_len && QSE_AWK_ISDIGIT(rtx->awk, fmt[i])); | 				while (i < fmt_len && QSE_AWK_ISDIGIT(rtx->awk, fmt[i])); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		if (wp_idx == WP_WIDTH && i < fmt_len && fmt[i] == QSE_T('.')) | ||||||
|  | 		{ | ||||||
|  | 			wp[WP_PRECISION] = 0; | ||||||
|  | 			FMT_CHAR (fmt[i]); i++; | ||||||
|  |  | ||||||
|  | 			wp_idx = WP_PRECISION; /* change index to precision */ | ||||||
|  | 			goto wp_mod_main; | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		if (i >= fmt_len) break; | 		if (i >= fmt_len) break; | ||||||
|  |  | ||||||
| 		if (fmt[i] == QSE_T('d') || fmt[i] == QSE_T('i') ||  | 		if (fmt[i] == QSE_T('d') || fmt[i] == QSE_T('i') ||  | ||||||
| @ -6939,27 +6926,8 @@ qse_char_t* qse_awk_rtx_format ( | |||||||
| 		{ | 		{ | ||||||
| 			qse_awk_val_t* v; | 			qse_awk_val_t* v; | ||||||
| 			qse_long_t l; | 			qse_long_t l; | ||||||
| 			qse_char_t* p; |  | ||||||
| 			int n; | 			int n; | ||||||
|  |  | ||||||
| 		#if QSE_SIZEOF_LONG_LONG > 0 |  | ||||||
| 			FMT_CHAR (QSE_T('l')); |  | ||||||
| 			FMT_CHAR (QSE_T('l')); |  | ||||||
| 			FMT_CHAR (fmt[i]); |  | ||||||
| 		#elif QSE_SIZEOF___INT64 > 0 |  | ||||||
| 			FMT_CHAR (QSE_T('I')); |  | ||||||
| 			FMT_CHAR (QSE_T('6')); |  | ||||||
| 			FMT_CHAR (QSE_T('4')); |  | ||||||
| 			FMT_CHAR (fmt[i]); |  | ||||||
| 		#elif QSE_SIZEOF_LONG > 0 |  | ||||||
| 			FMT_CHAR (QSE_T('l')); |  | ||||||
| 			FMT_CHAR (fmt[i]); |  | ||||||
| 		#elif QSE_SIZEOF_INT > 0 |  | ||||||
| 			FMT_CHAR (fmt[i]); |  | ||||||
| 		#else |  | ||||||
| 			#error unsupported integer size |  | ||||||
| 		#endif	 |  | ||||||
|  |  | ||||||
| 			if (args == QSE_NULL) | 			if (args == QSE_NULL) | ||||||
| 			{ | 			{ | ||||||
| 				if (stack_arg_idx >= nargs_on_stack) | 				if (stack_arg_idx >= nargs_on_stack) | ||||||
| @ -6992,6 +6960,110 @@ qse_char_t* qse_awk_rtx_format ( | |||||||
| 			qse_awk_rtx_refdownval (rtx, v); | 			qse_awk_rtx_refdownval (rtx, v); | ||||||
| 			if (n <= -1) return QSE_NULL;  | 			if (n <= -1) return QSE_NULL;  | ||||||
|  |  | ||||||
|  | #if 0 | ||||||
|  | /* TODO: finish this part... replace sprintf */ | ||||||
|  | { | ||||||
|  | int fmt_flags; | ||||||
|  | int fmt_uint = 0; | ||||||
|  | qse_char_t fmt_fill = QSE_T('\0'); | ||||||
|  | const qse_char_t* fmt_prefix = QSE_NULL; | ||||||
|  |  | ||||||
|  | 			if (l == 0 && wp[WP_PRECISION] == 0) | ||||||
|  | 			{ | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			fmt_flags = QSE_FMTINTMAX_NOTRUNC | QSE_FMTINTMAX_NONULL; | ||||||
|  | 			if (flags & FLAG_ZERO)  | ||||||
|  | 			{ | ||||||
|  | 				fmt_fill = QSE_T('0'); | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			{ | ||||||
|  | 				if (!(flags & FLAG_MINUS)) fmt_flags |= QSE_FMTINTMAX_FILLCENTER; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			switch (fmt[i]) | ||||||
|  | 			{ | ||||||
|  | 				case QSE_T('X'): | ||||||
|  | 					fmt_flags |= QSE_FMTINTMAX_UPPERCASE; | ||||||
|  | 				case QSE_T('x'): | ||||||
|  | 					fmt_flags |= 16; | ||||||
|  | 					fmt_uint = 1; | ||||||
|  | 					if (l && (flags & FLAG_HASH)) fmt_prefix = QSE_T("0x"); | ||||||
|  | 					break; | ||||||
|  |  | ||||||
|  | 				case QSE_T('o'): | ||||||
|  | 					fmt_flags |= 8; | ||||||
|  | 					fmt_uint = 1; | ||||||
|  | 					if (l && (flags & FLAG_HASH)) fmt_prefix = QSE_T("0"); | ||||||
|  | 					break; | ||||||
|  | 	 | ||||||
|  | 				default: | ||||||
|  | 					fmt_flags |= 10; | ||||||
|  | 					if (flags & FLAG_PLUS) fmt_flags |= QSE_FMTINTMAX_PLUSSIGN; | ||||||
|  | 					if (flags & FLAG_SPACE) fmt_flags |= QSE_FMTINTMAX_EMPTYSIGN; | ||||||
|  | 					break; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | qse_printf (QSE_T("width=>%d precision=%d\n"), wp[0], wp[1]); | ||||||
|  | 			do | ||||||
|  | 			{ | ||||||
|  | 				if (fmt_uint) | ||||||
|  | 				{ | ||||||
|  | 					n = qse_fmtuintmax ( | ||||||
|  | 						rtx->format.tmp.ptr, | ||||||
|  | 						rtx->format.tmp.len, | ||||||
|  | 						l, | ||||||
|  | 						fmt_flags, | ||||||
|  | 						fmt_fill, | ||||||
|  | 						fmt_prefix | ||||||
|  | 					); | ||||||
|  | 				} | ||||||
|  | 				else | ||||||
|  | 				{ | ||||||
|  | 					n = qse_fmtintmax ( | ||||||
|  | 						rtx->format.tmp.ptr, | ||||||
|  | 						rtx->format.tmp.len, | ||||||
|  | 						l, | ||||||
|  | 						fmt_flags, | ||||||
|  | 						fmt_fill, | ||||||
|  | 						fmt_prefix | ||||||
|  | 					); | ||||||
|  | 				} | ||||||
|  | 				if (n <= -1) | ||||||
|  | 				{ | ||||||
|  | 					/* -n is the number of characters required | ||||||
|  | 					 * including terminating null  */ | ||||||
|  | 					GROW_WITH_INC (&rtx->format.tmp, -n); | ||||||
|  | 					continue; | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				break; | ||||||
|  | 			} | ||||||
|  | 			while (1); | ||||||
|  |  | ||||||
|  | 			OUT_STR (rtx->format.tmp.ptr, n); | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | 		#if QSE_SIZEOF_LONG_LONG > 0 | ||||||
|  | 			FMT_CHAR (QSE_T('l')); | ||||||
|  | 			FMT_CHAR (QSE_T('l')); | ||||||
|  | 			FMT_CHAR (fmt[i]); | ||||||
|  | 		#elif QSE_SIZEOF___INT64 > 0 | ||||||
|  | 			FMT_CHAR (QSE_T('I')); | ||||||
|  | 			FMT_CHAR (QSE_T('6')); | ||||||
|  | 			FMT_CHAR (QSE_T('4')); | ||||||
|  | 			FMT_CHAR (fmt[i]); | ||||||
|  | 		#elif QSE_SIZEOF_LONG > 0 | ||||||
|  | 			FMT_CHAR (QSE_T('l')); | ||||||
|  | 			FMT_CHAR (fmt[i]); | ||||||
|  | 		#elif QSE_SIZEOF_INT > 0 | ||||||
|  | 			FMT_CHAR (fmt[i]); | ||||||
|  | 		#else | ||||||
|  | 			#error unsupported integer size | ||||||
|  | 		#endif	 | ||||||
|  |  | ||||||
| 			do | 			do | ||||||
| 			{ | 			{ | ||||||
| 				n = rtx->awk->prm.sprintf ( | 				n = rtx->awk->prm.sprintf ( | ||||||
| @ -7013,12 +7085,6 @@ qse_char_t* qse_awk_rtx_format ( | |||||||
| 				if (n == -1) | 				if (n == -1) | ||||||
| 				{ | 				{ | ||||||
| 					GROW (&rtx->format.tmp); | 					GROW (&rtx->format.tmp); | ||||||
| 					if (rtx->format.tmp.ptr == QSE_NULL) |  | ||||||
| 					{ |  | ||||||
| 						SETERR_COD (rtx, QSE_AWK_ENOMEM); |  | ||||||
| 						return QSE_NULL; |  | ||||||
| 					} |  | ||||||
|  |  | ||||||
| 					continue; | 					continue; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| @ -7026,12 +7092,7 @@ qse_char_t* qse_awk_rtx_format ( | |||||||
| 			} | 			} | ||||||
| 			while (1); | 			while (1); | ||||||
|  |  | ||||||
| 			p = rtx->format.tmp.ptr; | 			OUT_STR (rtx->format.tmp.ptr, n); | ||||||
| 			while (*p != QSE_T('\0')) |  | ||||||
| 			{ |  | ||||||
| 				OUT_CHAR (*p); |  | ||||||
| 				p++; |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
| 		else if (fmt[i] == QSE_T('e') || fmt[i] == QSE_T('E') || | 		else if (fmt[i] == QSE_T('e') || fmt[i] == QSE_T('E') || | ||||||
| 		         fmt[i] == QSE_T('g') || fmt[i] == QSE_T('G') || | 		         fmt[i] == QSE_T('g') || fmt[i] == QSE_T('G') || | ||||||
| @ -7039,7 +7100,6 @@ qse_char_t* qse_awk_rtx_format ( | |||||||
| 		{ | 		{ | ||||||
| 			qse_awk_val_t* v; | 			qse_awk_val_t* v; | ||||||
| 			qse_real_t r; | 			qse_real_t r; | ||||||
| 			qse_char_t* p; |  | ||||||
| 			int n; | 			int n; | ||||||
| 	 | 	 | ||||||
| 			FMT_CHAR (QSE_T('L')); | 			FMT_CHAR (QSE_T('L')); | ||||||
| @ -7094,12 +7154,6 @@ qse_char_t* qse_awk_rtx_format ( | |||||||
| 				if (n == -1) | 				if (n == -1) | ||||||
| 				{ | 				{ | ||||||
| 					GROW (&rtx->format.tmp); | 					GROW (&rtx->format.tmp); | ||||||
| 					if (rtx->format.tmp.ptr == QSE_NULL) |  | ||||||
| 					{ |  | ||||||
| 						SETERR_COD (rtx, QSE_AWK_ENOMEM); |  | ||||||
| 						return QSE_NULL; |  | ||||||
| 					} |  | ||||||
|  |  | ||||||
| 					continue; | 					continue; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| @ -7107,12 +7161,7 @@ qse_char_t* qse_awk_rtx_format ( | |||||||
| 			} | 			} | ||||||
| 			while (1); | 			while (1); | ||||||
|  |  | ||||||
| 			p = rtx->format.tmp.ptr; | 			OUT_STR (rtx->format.tmp.ptr, n); | ||||||
| 			while (*p != QSE_T('\0')) |  | ||||||
| 			{ |  | ||||||
| 				OUT_CHAR (*p); |  | ||||||
| 				p++; |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
| 		else if (fmt[i] == QSE_T('c'))  | 		else if (fmt[i] == QSE_T('c'))  | ||||||
| 		{ | 		{ | ||||||
| @ -7180,16 +7229,17 @@ qse_char_t* qse_awk_rtx_format ( | |||||||
| 				return QSE_NULL; | 				return QSE_NULL; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if (prec == -1 || prec == 0 || prec > (qse_long_t)ch_len)  | 			if (wp[WP_PRECISION] == -1 || wp[WP_PRECISION] == 0 || wp[WP_PRECISION] > (qse_long_t)ch_len)  | ||||||
| 			{ | 			{ | ||||||
| 				prec = (qse_long_t)ch_len; | 				wp[WP_PRECISION] = (qse_long_t)ch_len; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if (prec > width) width = prec; | 			if (wp[WP_PRECISION] > wp[WP_WIDTH]) wp[WP_WIDTH] = wp[WP_PRECISION]; | ||||||
|  |  | ||||||
| 			if (!minus) | 			if (!(flags & FLAG_MINUS)) | ||||||
| 			{ | 			{ | ||||||
| 				while (width > prec)  | 				/* right align */ | ||||||
|  | 				while (wp[WP_WIDTH] > wp[WP_PRECISION])  | ||||||
| 				{ | 				{ | ||||||
| 					if (qse_str_ccat (out, QSE_T(' ')) == -1)  | 					if (qse_str_ccat (out, QSE_T(' ')) == -1)  | ||||||
| 					{  | 					{  | ||||||
| @ -7197,11 +7247,11 @@ qse_char_t* qse_awk_rtx_format ( | |||||||
| 						SETERR_COD (rtx, QSE_AWK_ENOMEM); | 						SETERR_COD (rtx, QSE_AWK_ENOMEM); | ||||||
| 						return QSE_NULL;  | 						return QSE_NULL;  | ||||||
| 					}  | 					}  | ||||||
| 					width--; | 					wp[WP_WIDTH]--; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if (prec > 0) | 			if (wp[WP_PRECISION] > 0) | ||||||
| 			{ | 			{ | ||||||
| 				if (qse_str_ccat (out, ch) == -1)  | 				if (qse_str_ccat (out, ch) == -1)  | ||||||
| 				{  | 				{  | ||||||
| @ -7211,9 +7261,10 @@ qse_char_t* qse_awk_rtx_format ( | |||||||
| 				}  | 				}  | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if (minus) | 			if (flags & FLAG_MINUS) | ||||||
| 			{ | 			{ | ||||||
| 				while (width > prec)  | 				/* left align */ | ||||||
|  | 				while (wp[WP_WIDTH] > wp[WP_PRECISION])  | ||||||
| 				{ | 				{ | ||||||
| 					if (qse_str_ccat (out, QSE_T(' ')) == -1)  | 					if (qse_str_ccat (out, QSE_T(' ')) == -1)  | ||||||
| 					{  | 					{  | ||||||
| @ -7221,7 +7272,7 @@ qse_char_t* qse_awk_rtx_format ( | |||||||
| 						SETERR_COD (rtx, QSE_AWK_ENOMEM); | 						SETERR_COD (rtx, QSE_AWK_ENOMEM); | ||||||
| 						return QSE_NULL;  | 						return QSE_NULL;  | ||||||
| 					}  | 					}  | ||||||
| 					width--; | 					wp[WP_WIDTH]--; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| @ -7295,12 +7346,13 @@ qse_char_t* qse_awk_rtx_format ( | |||||||
| 				str_free = str_ptr; | 				str_free = str_ptr; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if (prec == -1 || prec > (qse_long_t)str_len) prec = (qse_long_t)str_len; | 			if (wp[WP_PRECISION] == -1 || wp[WP_PRECISION] > (qse_long_t)str_len) wp[WP_PRECISION] = (qse_long_t)str_len; | ||||||
| 			if (prec > width) width = prec; | 			if (wp[WP_PRECISION] > wp[WP_WIDTH]) wp[WP_WIDTH] = wp[WP_PRECISION]; | ||||||
|  |  | ||||||
| 			if (!minus) | 			if (!(flags & FLAG_MINUS)) | ||||||
| 			{ | 			{ | ||||||
| 				while (width > prec)  | 				/* right align */ | ||||||
|  | 				while (wp[WP_WIDTH] > wp[WP_PRECISION])  | ||||||
| 				{ | 				{ | ||||||
| 					if (qse_str_ccat (out, QSE_T(' ')) == -1)  | 					if (qse_str_ccat (out, QSE_T(' ')) == -1)  | ||||||
| 					{  | 					{  | ||||||
| @ -7310,11 +7362,11 @@ qse_char_t* qse_awk_rtx_format ( | |||||||
| 						SETERR_COD (rtx, QSE_AWK_ENOMEM); | 						SETERR_COD (rtx, QSE_AWK_ENOMEM); | ||||||
| 						return QSE_NULL;  | 						return QSE_NULL;  | ||||||
| 					}  | 					}  | ||||||
| 					width--; | 					wp[WP_WIDTH]--; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			for (k = 0; k < prec; k++)  | 			for (k = 0; k < wp[WP_PRECISION]; k++)  | ||||||
| 			{ | 			{ | ||||||
| 				if (qse_str_ccat (out, str_ptr[k]) == -1)  | 				if (qse_str_ccat (out, str_ptr[k]) == -1)  | ||||||
| 				{  | 				{  | ||||||
| @ -7328,9 +7380,10 @@ qse_char_t* qse_awk_rtx_format ( | |||||||
|  |  | ||||||
| 			if (str_free != QSE_NULL) QSE_AWK_FREE (rtx->awk, str_free); | 			if (str_free != QSE_NULL) QSE_AWK_FREE (rtx->awk, str_free); | ||||||
|  |  | ||||||
| 			if (minus) | 			if (flags & FLAG_MINUS) | ||||||
| 			{ | 			{ | ||||||
| 				while (width > prec)  | 				/* left align */ | ||||||
|  | 				while (wp[WP_WIDTH] > wp[WP_PRECISION])  | ||||||
| 				{ | 				{ | ||||||
| 					if (qse_str_ccat (out, QSE_T(' ')) == -1)  | 					if (qse_str_ccat (out, QSE_T(' ')) == -1)  | ||||||
| 					{  | 					{  | ||||||
| @ -7338,7 +7391,7 @@ qse_char_t* qse_awk_rtx_format ( | |||||||
| 						SETERR_COD (rtx, QSE_AWK_ENOMEM); | 						SETERR_COD (rtx, QSE_AWK_ENOMEM); | ||||||
| 						return QSE_NULL;  | 						return QSE_NULL;  | ||||||
| 					}  | 					}  | ||||||
| 					width--; | 					wp[WP_WIDTH]--; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| @ -7346,8 +7399,11 @@ qse_char_t* qse_awk_rtx_format ( | |||||||
| 		} | 		} | ||||||
| 		else /*if (fmt[i] == QSE_T('%'))*/ | 		else /*if (fmt[i] == QSE_T('%'))*/ | ||||||
| 		{ | 		{ | ||||||
|  | 			OUT_STR (QSE_STR_PTR(fbu), QSE_STR_LEN(fbu)); | ||||||
|  | 		#if 0 | ||||||
| 			for (j = 0; j < QSE_STR_LEN(fbu); j++) | 			for (j = 0; j < QSE_STR_LEN(fbu); j++) | ||||||
| 				OUT_CHAR (QSE_STR_CHAR(fbu,j)); | 				OUT_CHAR (QSE_STR_CHAR(fbu,j)); | ||||||
|  | 		#endif | ||||||
| 			OUT_CHAR (fmt[i]); | 			OUT_CHAR (fmt[i]); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @ -7357,8 +7413,7 @@ qse_char_t* qse_awk_rtx_format ( | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/* flush uncompleted formatting sequence */ | 	/* flush uncompleted formatting sequence */ | ||||||
| 	for (j = 0; j < QSE_STR_LEN(fbu); j++) | 	OUT_STR (QSE_STR_PTR(fbu), QSE_STR_LEN(fbu)); | ||||||
| 		OUT_CHAR (QSE_STR_CHAR(fbu,j)); |  | ||||||
|  |  | ||||||
| 	*len = QSE_STR_LEN(out); | 	*len = QSE_STR_LEN(out); | ||||||
| 	return QSE_STR_PTR(out); | 	return QSE_STR_PTR(out); | ||||||
|  | |||||||
| @ -285,7 +285,8 @@ static int print_expr (qse_awk_t* awk, qse_awk_nde_t* nde) | |||||||
| 					buf, QSE_COUNTOF(buf), | 					buf, QSE_COUNTOF(buf), | ||||||
| 					((qse_awk_nde_int_t*)nde)->val, | 					((qse_awk_nde_int_t*)nde)->val, | ||||||
| 					10,  | 					10,  | ||||||
| 					QSE_T('\0') | 					QSE_T('\0'), | ||||||
|  | 					QSE_NULL | ||||||
| 				); | 				); | ||||||
| 				PUT_SRCSTR (awk, buf); | 				PUT_SRCSTR (awk, buf); | ||||||
| 			} | 			} | ||||||
|  | |||||||
| @ -19,15 +19,16 @@ | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include <qse/cmn/fmt.h> | #include <qse/cmn/fmt.h> | ||||||
|  | #include <qse/cmn/str.h> | ||||||
|  |  | ||||||
| /* ==================== multibyte ===================================== */ | /* ==================== multibyte ===================================== */ | ||||||
| static int fmt_unsigned_to_mbs ( | static int fmt_unsigned_to_mbs ( | ||||||
| 	qse_mchar_t* buf, int size,  | 	qse_mchar_t* buf, int size,  | ||||||
| 	qse_uintmax_t value, int base_and_flags,  | 	qse_uintmax_t value, int base_and_flags,  | ||||||
| 	qse_mchar_t fillchar, qse_mchar_t signchar) | 	qse_mchar_t fillchar, qse_mchar_t signchar, const qse_mchar_t* prefix) | ||||||
| { | { | ||||||
| 	qse_mchar_t tmp[(QSE_SIZEOF(qse_uintmax_t) * 8)]; | 	qse_mchar_t tmp[(QSE_SIZEOF(qse_uintmax_t) * 8)]; | ||||||
| 	int reslen, base, xsize, reqlen; | 	int reslen, base, xsize, reqlen, pflen; | ||||||
| 	qse_mchar_t* p, * bp, * be; | 	qse_mchar_t* p, * bp, * be; | ||||||
| 	qse_mchar_t xbasechar; | 	qse_mchar_t xbasechar; | ||||||
|  |  | ||||||
| @ -50,6 +51,14 @@ static int fmt_unsigned_to_mbs ( | |||||||
| 	/* reslen is the length of the resulting string without padding. */ | 	/* reslen is the length of the resulting string without padding. */ | ||||||
| 	reslen = (int)(p - tmp); | 	reslen = (int)(p - tmp); | ||||||
| 	if (signchar) reslen++; /* increment reslen for the sign character */ | 	if (signchar) reslen++; /* increment reslen for the sign character */ | ||||||
|  | 	if (prefix) | ||||||
|  | 	{ | ||||||
|  | 		/* since the length can be truncated for different type sizes, | ||||||
|  | 		 * don't pass in a very long prefix. */ | ||||||
|  | 		pflen = (int)qse_mbslen(prefix);  | ||||||
|  | 		reslen += pflen; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
| 	/* get the required buffer size for lossless formatting */ | 	/* get the required buffer size for lossless formatting */ | ||||||
| 	reqlen = (base_and_flags & QSE_FMTINTMAXTOMBS_NONULL)? reslen: (reslen + 1); | 	reqlen = (base_and_flags & QSE_FMTINTMAXTOMBS_NONULL)? reslen: (reslen + 1); | ||||||
| @ -67,12 +76,13 @@ static int fmt_unsigned_to_mbs ( | |||||||
| 	/* fill space */ | 	/* fill space */ | ||||||
| 	if (fillchar != QSE_MT('\0')) | 	if (fillchar != QSE_MT('\0')) | ||||||
| 	{ | 	{ | ||||||
|  |  | ||||||
| 		if (base_and_flags & QSE_FMTINTMAXTOMBS_FILLRIGHT) | 		if (base_and_flags & QSE_FMTINTMAXTOMBS_FILLRIGHT) | ||||||
| 		{ | 		{ | ||||||
| 			/* emit sign */ | 			/* emit sign */ | ||||||
| 			if (signchar && bp < be) *bp++ = signchar; | 			if (signchar && bp < be) *bp++ = signchar; | ||||||
|  |  | ||||||
|  | 			/* copy prefix if necessary */ | ||||||
|  | 			if (prefix) while (*prefix && bp < be) *bp++ = *prefix++; | ||||||
| 			/* copy the numeric string to the destination buffer */ | 			/* copy the numeric string to the destination buffer */ | ||||||
| 			while (p > tmp && bp < be) *bp++ = *--p; | 			while (p > tmp && bp < be) *bp++ = *--p; | ||||||
|  |  | ||||||
| @ -95,6 +105,8 @@ static int fmt_unsigned_to_mbs ( | |||||||
| 				xsize--; | 				xsize--; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | 			/* copy prefix if necessary */ | ||||||
|  | 			if (prefix) while (*prefix && bp < be) *bp++ = *prefix++; | ||||||
| 			/* copy the numeric string to the destination buffer */ | 			/* copy the numeric string to the destination buffer */ | ||||||
| 			while (p > tmp && bp < be) *bp++ = *--p; | 			while (p > tmp && bp < be) *bp++ = *--p; | ||||||
| 		} | 		} | ||||||
| @ -110,6 +122,8 @@ static int fmt_unsigned_to_mbs ( | |||||||
| 			/* emit sign */ | 			/* emit sign */ | ||||||
| 			if (signchar && bp < be) *bp++ = signchar; | 			if (signchar && bp < be) *bp++ = signchar; | ||||||
|  |  | ||||||
|  | 			/* copy prefix if necessary */ | ||||||
|  | 			if (prefix) while (*prefix && bp < be) *bp++ = *prefix++; | ||||||
| 			/* copy the numeric string to the destination buffer */ | 			/* copy the numeric string to the destination buffer */ | ||||||
| 			while (p > tmp && bp < be) *bp++ = *--p; | 			while (p > tmp && bp < be) *bp++ = *--p; | ||||||
| 		} | 		} | ||||||
| @ -119,6 +133,8 @@ static int fmt_unsigned_to_mbs ( | |||||||
| 		/* emit sign */ | 		/* emit sign */ | ||||||
| 		if (signchar && bp < be) *bp++ = signchar; | 		if (signchar && bp < be) *bp++ = signchar; | ||||||
|  |  | ||||||
|  | 		/* copy prefix if necessary */ | ||||||
|  | 		if (prefix) while (*prefix && bp < be) *bp++ = *prefix++; | ||||||
| 		/* copy the numeric string to the destination buffer */ | 		/* copy the numeric string to the destination buffer */ | ||||||
| 		while (p > tmp && bp < be) *bp++ = *--p; | 		while (p > tmp && bp < be) *bp++ = *--p; | ||||||
| 	} | 	} | ||||||
| @ -129,7 +145,8 @@ static int fmt_unsigned_to_mbs ( | |||||||
|  |  | ||||||
| int qse_fmtintmaxtombs ( | int qse_fmtintmaxtombs ( | ||||||
| 	qse_mchar_t* buf, int size,  | 	qse_mchar_t* buf, int size,  | ||||||
| 	qse_intmax_t value, int base_and_flags, qse_mchar_t fillchar) | 	qse_intmax_t value, int base_and_flags, | ||||||
|  | 	qse_mchar_t fillchar, const qse_mchar_t* prefix) | ||||||
| { | { | ||||||
| 	qse_mchar_t signchar; | 	qse_mchar_t signchar; | ||||||
| 	qse_uintmax_t absvalue; | 	qse_uintmax_t absvalue; | ||||||
| @ -144,18 +161,24 @@ int qse_fmtintmaxtombs ( | |||||||
| 		signchar = QSE_MT('+'); | 		signchar = QSE_MT('+'); | ||||||
| 		absvalue = value; | 		absvalue = value; | ||||||
| 	} | 	} | ||||||
|  | 	else if (base_and_flags & QSE_FMTINTMAXTOMBS_EMPTYSIGN) | ||||||
|  | 	{ | ||||||
|  | 		signchar = QSE_MT(' '); | ||||||
|  | 		absvalue = value; | ||||||
|  | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		signchar = QSE_MT('\0'); | 		signchar = QSE_MT('\0'); | ||||||
| 		absvalue = value; | 		absvalue = value; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return fmt_unsigned_to_mbs (buf, size, absvalue, base_and_flags, fillchar, signchar); | 	return fmt_unsigned_to_mbs (buf, size, absvalue, base_and_flags, fillchar, signchar, prefix); | ||||||
| } | } | ||||||
|  |  | ||||||
| int qse_fmtuintmaxtombs ( | int qse_fmtuintmaxtombs ( | ||||||
| 	qse_mchar_t* buf, int size,  | 	qse_mchar_t* buf, int size,  | ||||||
| 	qse_uintmax_t value, int base_and_flags, qse_mchar_t fillchar) | 	qse_uintmax_t value, int base_and_flags, | ||||||
|  | 	qse_mchar_t fillchar, const qse_mchar_t* prefix) | ||||||
| { | { | ||||||
| 	qse_mchar_t signchar; | 	qse_mchar_t signchar; | ||||||
|  |  | ||||||
| @ -164,25 +187,28 @@ int qse_fmtuintmaxtombs ( | |||||||
| 	{ | 	{ | ||||||
| 		signchar = QSE_MT('+'); | 		signchar = QSE_MT('+'); | ||||||
| 	} | 	} | ||||||
|  | 	else if (base_and_flags & QSE_FMTINTMAXTOMBS_EMPTYSIGN) | ||||||
|  | 	{ | ||||||
|  | 		signchar = QSE_MT(' '); | ||||||
|  | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		signchar = QSE_MT('\0'); | 		signchar = QSE_MT('\0'); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return fmt_unsigned_to_mbs (buf, size, value, base_and_flags, fillchar, signchar); | 	return fmt_unsigned_to_mbs (buf, size, value, base_and_flags, fillchar, signchar, prefix); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| /* ==================== wide-char ===================================== */ | /* ==================== wide-char ===================================== */ | ||||||
|  |  | ||||||
| #if 0 |  | ||||||
| static int fmt_unsigned_to_wcs ( | static int fmt_unsigned_to_wcs ( | ||||||
| 	qse_wchar_t* buf, int size,  | 	qse_wchar_t* buf, int size,  | ||||||
| 	qse_uintmax_t value, int base_and_flags,  | 	qse_uintmax_t value, int base_and_flags,  | ||||||
| 	qse_wchar_t fillchar, qse_wchar_t signchar) | 	qse_wchar_t fillchar, qse_wchar_t signchar, const qse_wchar_t* prefix) | ||||||
| { | { | ||||||
| 	qse_wchar_t tmp[(QSE_SIZEOF(qse_uintmax_t) * 8)]; | 	qse_wchar_t tmp[(QSE_SIZEOF(qse_uintmax_t) * 8)]; | ||||||
| 	int reslen, base; | 	int reslen, base, xsize, reqlen, pflen; | ||||||
| 	qse_wchar_t* p, * bp, * be; | 	qse_wchar_t* p, * bp, * be; | ||||||
| 	qse_wchar_t xbasechar; | 	qse_wchar_t xbasechar; | ||||||
|  |  | ||||||
| @ -205,111 +231,14 @@ static int fmt_unsigned_to_wcs ( | |||||||
| 	/* reslen is the length of the resulting string without padding. */ | 	/* reslen is the length of the resulting string without padding. */ | ||||||
| 	reslen = (int)(p - tmp); | 	reslen = (int)(p - tmp); | ||||||
| 	if (signchar) reslen++; /* increment reslen for the sign character */ | 	if (signchar) reslen++; /* increment reslen for the sign character */ | ||||||
|  | 	if (prefix) | ||||||
| 	if (size <= 0 || |  | ||||||
| 	    ((base_and_flags & QSE_FMTINTMAXTOWCS_NOTRUNC) && size <= reslen)) |  | ||||||
| 	{ | 	{ | ||||||
| 		/* conversion without loss requires at least 'reslen + 1'. */ | 		/* since the length can be truncated for different type sizes, | ||||||
| 		return -(reslen + 1); | 		 * don't pass in a very long prefix. */ | ||||||
|  | 		pflen = (int)qse_wcslen(prefix);  | ||||||
|  | 		reslen += pflen; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bp = buf; |  | ||||||
| 	be = buf + size - 1; |  | ||||||
|  |  | ||||||
| 	/* 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 (size - 1 > reslen) |  | ||||||
| 			{ |  | ||||||
| 				*bp++ = fillchar; |  | ||||||
| 				size--; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		else if (base_and_flags & QSE_FMTINTMAXTOWCS_FILLCENTER) |  | ||||||
| 		{ |  | ||||||
| 			/* emit sign */ |  | ||||||
| 			if (signchar && bp < be) *bp++ = signchar; |  | ||||||
|  |  | ||||||
| 			/* fill the left side */ |  | ||||||
| 			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; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	*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 */ | 	/* get the required buffer size for lossless formatting */ | ||||||
| 	reqlen = (base_and_flags & QSE_FMTINTMAXTOWCS_NONULL)? reslen: (reslen + 1); | 	reqlen = (base_and_flags & QSE_FMTINTMAXTOWCS_NONULL)? reslen: (reslen + 1); | ||||||
|  |  | ||||||
| @ -326,12 +255,13 @@ static int fmt_unsigned_to_wcs ( | |||||||
| 	/* fill space */ | 	/* fill space */ | ||||||
| 	if (fillchar != QSE_WT('\0')) | 	if (fillchar != QSE_WT('\0')) | ||||||
| 	{ | 	{ | ||||||
|  |  | ||||||
| 		if (base_and_flags & QSE_FMTINTMAXTOWCS_FILLRIGHT) | 		if (base_and_flags & QSE_FMTINTMAXTOWCS_FILLRIGHT) | ||||||
| 		{ | 		{ | ||||||
| 			/* emit sign */ | 			/* emit sign */ | ||||||
| 			if (signchar && bp < be) *bp++ = signchar; | 			if (signchar && bp < be) *bp++ = signchar; | ||||||
|  |  | ||||||
|  | 			/* copy prefix if necessary */ | ||||||
|  | 			if (prefix) while (*prefix && bp < be) *bp++ = *prefix++; | ||||||
| 			/* copy the numeric string to the destination buffer */ | 			/* copy the numeric string to the destination buffer */ | ||||||
| 			while (p > tmp && bp < be) *bp++ = *--p; | 			while (p > tmp && bp < be) *bp++ = *--p; | ||||||
|  |  | ||||||
| @ -354,6 +284,8 @@ static int fmt_unsigned_to_wcs ( | |||||||
| 				xsize--; | 				xsize--; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | 			/* copy prefix if necessary */ | ||||||
|  | 			if (prefix) while (*prefix && bp < be) *bp++ = *prefix++; | ||||||
| 			/* copy the numeric string to the destination buffer */ | 			/* copy the numeric string to the destination buffer */ | ||||||
| 			while (p > tmp && bp < be) *bp++ = *--p; | 			while (p > tmp && bp < be) *bp++ = *--p; | ||||||
| 		} | 		} | ||||||
| @ -369,6 +301,8 @@ static int fmt_unsigned_to_wcs ( | |||||||
| 			/* emit sign */ | 			/* emit sign */ | ||||||
| 			if (signchar && bp < be) *bp++ = signchar; | 			if (signchar && bp < be) *bp++ = signchar; | ||||||
|  |  | ||||||
|  | 			/* copy prefix if necessary */ | ||||||
|  | 			if (prefix) while (*prefix && bp < be) *bp++ = *prefix++; | ||||||
| 			/* copy the numeric string to the destination buffer */ | 			/* copy the numeric string to the destination buffer */ | ||||||
| 			while (p > tmp && bp < be) *bp++ = *--p; | 			while (p > tmp && bp < be) *bp++ = *--p; | ||||||
| 		} | 		} | ||||||
| @ -378,6 +312,8 @@ static int fmt_unsigned_to_wcs ( | |||||||
| 		/* emit sign */ | 		/* emit sign */ | ||||||
| 		if (signchar && bp < be) *bp++ = signchar; | 		if (signchar && bp < be) *bp++ = signchar; | ||||||
|  |  | ||||||
|  | 		/* copy prefix if necessary */ | ||||||
|  | 		if (prefix) while (*prefix && bp < be) *bp++ = *prefix++; | ||||||
| 		/* copy the numeric string to the destination buffer */ | 		/* copy the numeric string to the destination buffer */ | ||||||
| 		while (p > tmp && bp < be) *bp++ = *--p; | 		while (p > tmp && bp < be) *bp++ = *--p; | ||||||
| 	} | 	} | ||||||
| @ -388,7 +324,8 @@ static int fmt_unsigned_to_wcs ( | |||||||
|  |  | ||||||
| int qse_fmtintmaxtowcs ( | int qse_fmtintmaxtowcs ( | ||||||
| 	qse_wchar_t* buf, int size,  | 	qse_wchar_t* buf, int size,  | ||||||
| 	qse_intmax_t value, int base_and_flags, qse_wchar_t fillchar) | 	qse_intmax_t value, int base_and_flags, | ||||||
|  | 	qse_wchar_t fillchar, const qse_wchar_t* prefix) | ||||||
| { | { | ||||||
| 	qse_wchar_t signchar; | 	qse_wchar_t signchar; | ||||||
| 	qse_uintmax_t absvalue; | 	qse_uintmax_t absvalue; | ||||||
| @ -403,18 +340,24 @@ int qse_fmtintmaxtowcs ( | |||||||
| 		signchar = QSE_WT('+'); | 		signchar = QSE_WT('+'); | ||||||
| 		absvalue = value; | 		absvalue = value; | ||||||
| 	} | 	} | ||||||
|  | 	else if (base_and_flags & QSE_FMTINTMAXTOMBS_EMPTYSIGN) | ||||||
|  | 	{ | ||||||
|  | 		signchar = QSE_WT(' '); | ||||||
|  | 		absvalue = value; | ||||||
|  | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		signchar = QSE_WT('\0'); | 		signchar = QSE_WT('\0'); | ||||||
| 		absvalue = value; | 		absvalue = value; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return fmt_unsigned_to_wcs (buf, size, absvalue, base_and_flags, fillchar, signchar); | 	return fmt_unsigned_to_wcs (buf, size, absvalue, base_and_flags, fillchar, signchar, prefix); | ||||||
| } | } | ||||||
|  |  | ||||||
| int qse_fmtuintmaxtowcs ( | int qse_fmtuintmaxtowcs ( | ||||||
| 	qse_wchar_t* buf, int size,  | 	qse_wchar_t* buf, int size,  | ||||||
| 	qse_uintmax_t value, int base_and_flags, qse_wchar_t fillchar) | 	qse_uintmax_t value, int base_and_flags,  | ||||||
|  | 	qse_wchar_t fillchar, const qse_wchar_t* prefix) | ||||||
| { | { | ||||||
| 	qse_wchar_t signchar; | 	qse_wchar_t signchar; | ||||||
|  |  | ||||||
| @ -423,11 +366,15 @@ int qse_fmtuintmaxtowcs ( | |||||||
| 	{ | 	{ | ||||||
| 		signchar = QSE_WT('+'); | 		signchar = QSE_WT('+'); | ||||||
| 	} | 	} | ||||||
|  | 	else if (base_and_flags & QSE_FMTINTMAXTOMBS_EMPTYSIGN) | ||||||
|  | 	{ | ||||||
|  | 		signchar = QSE_WT(' '); | ||||||
|  | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		signchar = QSE_WT('\0'); | 		signchar = QSE_WT('\0'); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return fmt_unsigned_to_wcs (buf, size, value, base_and_flags, fillchar, signchar); | 	return fmt_unsigned_to_wcs (buf, size, value, base_and_flags, fillchar, signchar, prefix); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | |||||||
| @ -3,8 +3,9 @@ | |||||||
|  |  | ||||||
| static int test_main (int argc, qse_char_t* argv[], qse_char_t* envp[]) | static int test_main (int argc, qse_char_t* argv[], qse_char_t* envp[]) | ||||||
| { | { | ||||||
| 	qse_char_t buf[17];	 | 	qse_char_t buf[19];	 | ||||||
| 	int bases[] = { 2, 8, 10, 16 }; | 	int bases[] = { 2, 8, 10, 16 }; | ||||||
|  | 	qse_char_t* prefix[] = { QSE_T("0b"), QSE_T("0"), QSE_NULL, QSE_T("0x") }; | ||||||
| 	int flags[] = | 	int flags[] = | ||||||
| 	{ | 	{ | ||||||
| 		QSE_FMTINTMAX_NOTRUNC | 0, | 		QSE_FMTINTMAX_NOTRUNC | 0, | ||||||
| @ -31,7 +32,7 @@ static int test_main (int argc, qse_char_t* argv[], qse_char_t* envp[]) | |||||||
| 	{ | 	{ | ||||||
| 		for (j = 0; j < QSE_COUNTOF(flags); j++) | 		for (j = 0; j < QSE_COUNTOF(flags); j++) | ||||||
| 		{ | 		{ | ||||||
| 			int n = qse_fmtuintmax (buf, QSE_COUNTOF(buf), num, bases[i] | flags[j], QSE_T('.')); | 			int n = qse_fmtuintmax (buf, QSE_COUNTOF(buf), num, bases[i] | flags[j], QSE_T('.'), prefix[i]); | ||||||
| 			if (n <= -1) | 			if (n <= -1) | ||||||
| 			{ | 			{ | ||||||
| 				qse_printf (QSE_T("%8X => [%4d:%04X] ERROR[%d]\n"), num, bases[i], flags[j],  n); | 				qse_printf (QSE_T("%8X => [%4d:%04X] ERROR[%d]\n"), num, bases[i], flags[j],  n); | ||||||
|  | |||||||
| @ -5,6 +5,7 @@ static int test_main (int argc, qse_char_t* argv[], qse_char_t* envp[]) | |||||||
| { | { | ||||||
| 	qse_char_t buf[129];	 | 	qse_char_t buf[129];	 | ||||||
| 	int bases[] = { 2, 8, 10, 16 }; | 	int bases[] = { 2, 8, 10, 16 }; | ||||||
|  | 	qse_char_t* prefix[] = { QSE_T("0b"), QSE_T("0"), QSE_NULL, QSE_T("0x") }; | ||||||
| 	int flags[] = | 	int flags[] = | ||||||
| 	{ | 	{ | ||||||
| 		QSE_FMTINTMAX_PLUSSIGN, | 		QSE_FMTINTMAX_PLUSSIGN, | ||||||
| @ -26,7 +27,7 @@ static int test_main (int argc, qse_char_t* argv[], qse_char_t* envp[]) | |||||||
| 		{ | 		{ | ||||||
| 			for (j = 0; j < QSE_COUNTOF(flags); j++) | 			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('.')); | 				int n = qse_fmtintmax (buf, QSE_COUNTOF(buf), nums[k], bases[i] | flags[j] | QSE_FMTINTMAX_NOTRUNC, QSE_T('.'), prefix[i]); | ||||||
| 				if (n <= -1) | 				if (n <= -1) | ||||||
| 				{ | 				{ | ||||||
| 					qse_printf (QSE_T("%8d => [%4d:%04X] ERROR[%d]\n"), (int)nums[k], bases[i], flags[j],  n); | 					qse_printf (QSE_T("%8d => [%4d:%04X] ERROR[%d]\n"), (int)nums[k], bases[i], flags[j],  n); | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user