21#define XWVSNPF_F_ZEROPAD 0x01
22#define XWVSNPF_F_SIGN 0x02
23#define XWVSNPF_F_PLUS 0x04
24#define XWVSNPF_F_SPACE 0x08
25#define XWVSNPF_F_LEFT 0x10
26#define XWVSNPF_F_SMALL 0x20
27#define XWVSNPF_F_SPECIAL 0x40
49#if defined(XWLIBCFG_SPF_FLOAT) && (1U == XWLIBCFG_SPF_FLOAT)
52# if defined(XWLIBCFG_SPF_LONG_DOUBLE) && (1U == XWLIBCFG_SPF_LONG_DOUBLE)
53 XWVSNPF_FT_LONG_DOUBLE,
54 XWVSNPF_FT_LONG_DOUBLE_SCI,
76 while (isdigit((
int)(**s))) {
77 i = i * 10 + **s -
'0';
86 unsigned int d3, d2, d1, d0;
92 d0 = 6 * (d3 + d2 + d1) + (q & 0xf);
93 q = (d0 * 0xcd) >> 11;
95 *buf++ = (char)d0 +
'0';
97 d1 = q + 9 * d3 + 5 * d2 + d1;
99 q = (d1 * 0xcd) >> 11;
101 *buf++ = (char)d1 +
'0';
104 if ((d2 != 0) || (d3 != 0)) {
107 *buf++ = (char)d2 +
'0';
111 q = (d3 * 0xcd) >> 11;
113 *buf++ = (char)d3 +
'0';
115 *buf++ = (char)q +
'0';
126 unsigned int d3, d2, d1, d0;
132 d0 = 6 * (d3 + d2 + d1) + (q & 0xf);
133 q = (d0 * 0xcd) >> 11;
135 *buf++ = (char)d0 +
'0';
137 d1 = q + 9 * d3 + 5 * d2 + d1;
138 q = (d1 * 0xcd) >> 11;
140 *buf++ = (char)d1 +
'0';
145 *buf++ = (char)d2 +
'0';
148 q = (d3 * 0xcd) >> 11;
151 *buf++ = (char)d3 +
'0';
152 *buf++ = (char)q +
'0';
180 bool is_zero = num == 0LL;
188 if ((
signed long long)num < 0) {
190 num = (
unsigned long long)(-(
signed long long)num);
201 if (16 == spec.
base || 2 == spec.
base) {
203 }
else if (!is_zero) {
210 if (num < spec.
base) {
218 }
else if (spec.
base != 10) {
219 int mask = spec.
base - 1;
222 if (spec.
base == 16) {
224 }
else if (spec.
base == 2) {
259 if (spec.
base == 16 || spec.
base == 2 || !is_zero) {
265 if (spec.
base == 16) {
267 *buf = (
'X' | locase);
270 }
else if (spec.
base == 2) {
272 *buf = (
'B' | locase);
321 if (size <= spaces) {
322 memset(buf,
' ', (
xwsz_t)size);
326 if (len > size - spaces) {
329 memmove(buf + spaces, buf, (
xwsz_t)len);
331 memset(buf,
' ', (
xwsz_t)spaces);
405 default_width = (int)(2 *
sizeof(
void *) +
417#if defined(XWLIBCFG_SPF_FLOAT) && (1U == XWLIBCFG_SPF_FLOAT)
419char * xwvsnpf_put_float_decimal(
char * buf,
char * end,
unsigned long long num,
int digits)
428 while (num > 0 && i < 29) {
429 tmp[i++] = (char)(
'0' + (num % 10));
434 while (i < digits && i < 29) {
438 for (j = i - 1; j >= 0; j--) {
448char * xwvsnpf_format_float(
char * buf,
char * end,
double num,
454 int precision = (spec.
precision == -1) ? 6 : spec.precision;
455 int is_sci = (spec.
type == XWVSNPF_FT_FLOAT_SCI);
457 unsigned long long int_part = 0;
458 unsigned long long frac_part = 0;
465 if (buf < end) *buf++ =
'n';
466 if (buf < end) *buf++ =
'a';
467 if (buf < end) *buf++ =
'n';
473 if (buf < end) *buf++ =
'-';
475 if (buf < end) *buf++ =
'i';
476 if (buf < end) *buf++ =
'n';
477 if (buf < end) *buf++ =
'f';
498 if (abs_num == 0.0) {
500 }
else if (abs_num >= 1.0) {
501 while (abs_num >= 10.0) {
506 while (abs_num < 1.0) {
513 int_part = (
unsigned long long)abs_num;
514 double frac = abs_num - (double)int_part;
516 for (i = 0; i < precision; i++) {
519 frac_part = (
unsigned long long)(frac * mult + 0.5);
521 if (frac_part >= (
unsigned long long)mult) {
522 frac_part -= (
unsigned long long)mult;
526 p = xwvsnpf_put_float_decimal(p, tmp + 99, int_part, 1);
530 p = xwvsnpf_put_float_decimal(p, tmp + 99, frac_part, precision);
544 p = xwvsnpf_put_float_decimal(p, tmp + 99, (
unsigned long long)exp, 1);
547 len = (int)(p - tmp);
549 int pad_len = (total_width > len + need_sign) ? (total_width - len - need_sign) : 0;
553 if (pad_char ==
'0' && sign) {
554 if (buf < end) *buf++ = sign;
558 for (i = 0; i < pad_len; i++) {
559 if (buf < end) *buf++ = pad_char;
564 if (buf < end) *buf++ = sign;
567 for (i = 0; i < len; i++) {
568 if (buf < end) *buf++ = tmp[i];
572 for (i = 0; i < pad_len; i++) {
573 if (buf < end) *buf++ =
' ';
580# if defined(XWLIBCFG_SPF_LONG_DOUBLE) && (1U == XWLIBCFG_SPF_LONG_DOUBLE)
582char * xwvsnpf_format_long_double(
char * buf,
char * end,
long double num,
588 int precision = (spec.
precision == -1) ? 6 : spec.precision;
589 int is_sci = (spec.
type == XWVSNPF_FT_LONG_DOUBLE_SCI);
591 unsigned long long int_part = 0;
592 unsigned long long frac_part = 0;
599 if (buf < end) *buf++ =
'n';
600 if (buf < end) *buf++ =
'a';
601 if (buf < end) *buf++ =
'n';
607 if (buf < end) *buf++ =
'-';
609 if (buf < end) *buf++ =
'i';
610 if (buf < end) *buf++ =
'n';
611 if (buf < end) *buf++ =
'f';
632 if (abs_num == 0.0L) {
634 }
else if (abs_num >= 1.0L) {
635 while (abs_num >= 10.0L) {
640 while (abs_num < 1.0L) {
647 int_part = (
unsigned long long)abs_num;
648 long double frac = abs_num - (
long double)int_part;
649 long double mult = 1.0L;
650 for (i = 0; i < precision; i++) {
653 frac_part = (
unsigned long long)(frac * mult + 0.5L);
655 if (frac_part >= (
unsigned long long)mult) {
656 frac_part -= (
unsigned long long)mult;
660 p = xwvsnpf_put_float_decimal(p, tmp + 99, int_part, 1);
664 p = xwvsnpf_put_float_decimal(p, tmp + 99, frac_part, precision);
678 p = xwvsnpf_put_float_decimal(p, tmp + 99, (
unsigned long long)exp, 1);
681 len = (int)(p - tmp);
683 int pad_len = (total_width > len + need_sign) ? (total_width - len - need_sign) : 0;
687 if (pad_char ==
'0' && sign) {
688 if (buf < end) *buf++ = sign;
692 for (i = 0; i < pad_len; i++) {
693 if (buf < end) *buf++ = pad_char;
698 if (buf < end) *buf++ = sign;
701 for (i = 0; i < len; i++) {
702 if (buf < end) *buf++ = tmp[i];
706 for (i = 0; i < pad_len; i++) {
707 if (buf < end) *buf++ =
' ';
720 const char * start = fmt;
743 for (; *fmt ; fmt++) {
750 if ((fmt != start) || !(*fmt)) {
787 if (isdigit((
int)(*fmt))) {
789 }
else if (
'*' == *fmt) {
801 if (isdigit((
int)(*fmt))) {
806 }
else if (*fmt ==
'*') {
817 if ((
'h' == *fmt) || (
'l' == *fmt) || (
'L' == *fmt) ||
818 (
'z' == *fmt) || (
'Z' == *fmt) || (
't' == *fmt)) {
876#if defined(XWLIBCFG_SPF_FLOAT) && (1U == XWLIBCFG_SPF_FLOAT)
878# if defined(XWLIBCFG_SPF_LONG_DOUBLE) && (1U == XWLIBCFG_SPF_LONG_DOUBLE)
880 spec->
type = XWVSNPF_FT_LONG_DOUBLE;
882 spec->
type = XWVSNPF_FT_FLOAT;
885 spec->
type = XWVSNPF_FT_FLOAT;
892# if defined(XWLIBCFG_SPF_LONG_DOUBLE) && (1U == XWLIBCFG_SPF_LONG_DOUBLE)
894 spec->
type = XWVSNPF_FT_LONG_DOUBLE_SCI;
896 spec->
type = XWVSNPF_FT_FLOAT_SCI;
899 spec->
type = XWVSNPF_FT_FLOAT_SCI;
905# if defined(XWLIBCFG_SPF_LONG_DOUBLE) && (1U == XWLIBCFG_SPF_LONG_DOUBLE)
907 spec->
type = XWVSNPF_FT_LONG_DOUBLE_SCI;
909 spec->
type = XWVSNPF_FT_FLOAT_SCI;
912 spec->
type = XWVSNPF_FT_FLOAT_SCI;
984 size = (
xwsz_t)(end - buf);
988 const char * oldfmt = fmt;
995 if (copy > end - str) {
998 memcpy(str, oldfmt, (
xwsz_t)copy);
1023 c = (char)va_arg(args,
int);
1044 va_arg(args,
void *), spec);
1045 while (isalnum((
int)(*fmt))) {
1064#if defined(XWLIBCFG_SPF_FLOAT) && (1U == XWLIBCFG_SPF_FLOAT)
1065 case XWVSNPF_FT_FLOAT:
1066 case XWVSNPF_FT_FLOAT_SCI:
1067 str = xwvsnpf_format_float(str, end, va_arg(args,
double), spec);
1070# if defined(XWLIBCFG_SPF_LONG_DOUBLE) && (1U == XWLIBCFG_SPF_LONG_DOUBLE)
1071 case XWVSNPF_FT_LONG_DOUBLE:
1072 case XWVSNPF_FT_LONG_DOUBLE_SCI:
1073 str = xwvsnpf_format_long_double(str, end, va_arg(args,
long double), spec);
1079 switch (spec.
type) {
1081 num = (
xwu64_t)va_arg(args,
long long);
1084 num = (
xwu64_t)va_arg(args,
unsigned long);
1087 num = (
xwu64_t)va_arg(args,
long);
1097 num = (
xwu64_t)va_arg(args, ptrdiff_t);
1100 num = (
xwu64_t)va_arg(args,
int);
1103 num = (
xwu64_t)va_arg(args,
int);
1106 num = (
xwu64_t)va_arg(args,
int);
1109 num = (
xwu64_t)va_arg(args,
int);
1112 num = (
xwu64_t)va_arg(args,
int);
1115 num = (
xwu64_t)va_arg(args,
unsigned int);
1138 va_start(args, fmt);
1139 i =
xwvsnpf(buf, size, fmt, args);
1145int xwvspf(
char * buf,
const char * fmt, va_list args)
1150int xwspf(
char * buf,
const char * fmt, ...)
1155 va_start(args, fmt);
1156 i =
xwvspf(buf, fmt, args);
xwu32_t xwdiv64(xwu64_t *n, xwu32_t divisor)
64位除法运算
int xwspf(char *buf, const char *fmt,...)
格式化字符串(同sprintf)
int xwsnpf(char *buf, xwsz_t size, const char *fmt,...)
格式化字符串(同snprintf)
int xwvsnpf(char *buf, xwsz_t size, const char *fmt, va_list args)
格式化字符串(同vsnprintf)
int xwvspf(char *buf, const char *fmt, va_list args)
格式化字符串(同vsprintf)
static char * xwvsnpf_format_widen_string(char *buf, xwssz_t n, char *end, struct xwvsnpf_format_spec spec)
static int xwvsnpf_format_decode(const char *fmt, struct xwvsnpf_format_spec *spec)
static char * xwvsnpf_format_string(char *buf, char *end, const char *s, struct xwvsnpf_format_spec spec)
static char * xwvsnpf_format_pointer(const char *fmt, char *buf, char *end, void *ptr, struct xwvsnpf_format_spec spec)
static char * xwvsnpf_format_string_nocheck(char *buf, char *end, const char *s, struct xwvsnpf_format_spec spec)
@ XWVSNPF_FT_PERCENT_CHAR
static char * xwvsnpf_put_dec_trunc(char *buf, unsigned int q)
#define XWVSNPF_F_SPECIAL
static void xwvsnpf_format_move_right(char *buf, char *end, xwssz_t len, xwssz_t spaces)
static const char xwvsnpf_nullstr[]
static char * xwvsnpf_put_dec_full(char *buf, unsigned int q)
#define XWVSNPF_F_ZEROPAD
static const char xwvsnpf_digits[]
static char * xwvsnpf_format_number(char *buf, char *end, xwu64_t num, struct xwvsnpf_format_spec spec)
static int xwvsnpf_skip_atoi(const char **s)
static char * xwvsnpf_put_dec(char *buf, unsigned long long num)