根因: _check_special_float 的位双关 (把 double 位模式读成 uint64) 被 TPC 前端静默丢弃——IR 里 fbits 恒为 0 (store i64 0 后直接 load,没有把 fv 写进 fbits),函数恒返回 0,于是 %f/%e/%g/%a 的 inf/nan 保护全部失效。 后果: inf 落入 %g 的指数归一化循环 while fv>=10.0 (inf/10==inf 恒真) → 死循环,实测卡死在 vsnprintf:974(Ctrl+C 栈转储权威帧 #0)。 修复: _check_special_float 改为纯浮点语义判定 (fv!=fv 判 NaN;fv-fv!=fv-fv 判 +-inf);另给 4 处对 inf 不收敛的循环各加迭代上界 400 (正常最多约 308 次) 作纵深防御。 注: 位双关语句被静默丢弃属 TPC 前端缺陷,需另立项;va_arg(ap, double) 经生成 IR 核对是正确的 (va_arg 内建读 XMM 保存区且 gp/fp 各自推进),非本次原因。
1397 lines
58 KiB
Plaintext
1397 lines
58 KiB
Plaintext
import t, c
|
||
import viperio
|
||
from stdarg import arg, va_arg
|
||
|
||
define TEMP_BUF_SIZE = 68
|
||
|
||
def get_digit_count(num: uint, base: int) -> int:
|
||
count: int = 0
|
||
if num == 0: return 1
|
||
while num > 0:
|
||
count += 1
|
||
num //= base
|
||
return count
|
||
|
||
# 返回类型必须与 CRT `sprintf` 以及 includes/stdio.vp 的
|
||
# 语义上直接返回 vsnprintf 的写入长度(与 CRT 一致)。
|
||
export def sprintf(buf: str, rule: str, *args) -> int:
|
||
if buf is None or rule is None: return 0
|
||
return vsnprintf(buf, 0x7FFFFFFF, rule, args)
|
||
|
||
def vsprintf(buf: str, rule: str, *args) -> int:
|
||
if buf is None or rule is None: return 0
|
||
return vsnprintf(buf, 0x7FFFFFFF, rule, args)
|
||
|
||
export def snprintf(buf: str, size: sizet, fmt: str, *args) -> int:
|
||
if fmt is None: return 0
|
||
if buf is None or size == 0: return vsnprintf(None, 0, fmt, args)
|
||
ret: int = vsnprintf(buf, size, fmt, args)
|
||
return ret
|
||
|
||
# 检查浮点特殊值(IEEE 754)
|
||
# 返回:0=正常, 1=+inf, 2=-inf, 3=nan
|
||
# 注意:不可用位双关 `*&fbits = *&fv` 读取 IEEE 位模式——该赋值会被编译器静默
|
||
# 丢弃(IR 中 fbits 恒为 0,见 TransPyV/output/db514c1af999c5f5.text.ll),会使
|
||
# 本函数恒返回 0、特殊值检查彻底失效,进而让 inf 进入浮点格式化循环而死循环。
|
||
# 这里改用纯浮点语义判定,不依赖任何位操作:
|
||
# NaN :fv != fv 为真
|
||
# ±inf:fv - fv 得到 NaN(有限值得到 0.0)
|
||
def _check_special_float(fv: double) -> int:
|
||
if fv != fv:
|
||
return 3
|
||
diff: double = fv - fv
|
||
if diff != diff:
|
||
if fv < 0.0:
|
||
return 2
|
||
return 1
|
||
return 0
|
||
|
||
export def vsnprintf(buf: bytes, size: sizet, fmt: str, ap: str) -> int:
|
||
if fmt is None: return 0
|
||
# Length detection mode: when buf is None, only calculate the formatted length, without actually writing
|
||
# _step=0 makes ptr not advance, repeatedly writing the same dummy byte (harmless), write_count accumulates correctly
|
||
count_mode: int = 0
|
||
_step: int = 1
|
||
_dummy: char = '\0'
|
||
if buf is None or size == 0:
|
||
count_mode = 1
|
||
_step = 0
|
||
buf = &_dummy
|
||
size = 0x7FFFFFFF
|
||
ptr: str = buf
|
||
write_count: int = 0
|
||
temp: t.CArray[char, 68]
|
||
temp[0] = '\t'
|
||
while *fmt != 0 and write_count < size - 1:
|
||
if *fmt != 37:
|
||
ptr[0] = *fmt
|
||
write_count += 1
|
||
ptr += _step
|
||
fmt += 1
|
||
else:
|
||
fmt += 1
|
||
if *fmt == 0: break
|
||
width: int = 0
|
||
pad_zero: int = 0
|
||
left_align: int = 0
|
||
show_sign: int = 0
|
||
space_sign: int = 0
|
||
alt_form: int = 0
|
||
precision: int = -1
|
||
is_long: int = 0
|
||
is_long_long: int = 0
|
||
is_size: int = 0
|
||
is_short: int = 0
|
||
is_char: int = 0
|
||
while True:
|
||
if *fmt == 45:
|
||
left_align = 1
|
||
fmt += 1
|
||
elif *fmt == 48:
|
||
pad_zero = 1
|
||
fmt += 1
|
||
elif *fmt == 43:
|
||
show_sign = 1
|
||
fmt += 1
|
||
elif *fmt == 32:
|
||
space_sign = 1
|
||
fmt += 1
|
||
elif *fmt == 35:
|
||
alt_form = 1
|
||
fmt += 1
|
||
else: break
|
||
if show_sign: space_sign = 0
|
||
while *fmt >= 48 and *fmt <= 57:
|
||
width = width * 10 + (*fmt - 48)
|
||
fmt += 1
|
||
if *fmt == 46:
|
||
fmt += 1
|
||
precision = 0
|
||
while *fmt >= 48 and *fmt <= 57:
|
||
precision = precision * 10 + (*fmt - 48)
|
||
fmt += 1
|
||
if left_align: pad_zero = 0
|
||
if *fmt == 108:
|
||
is_long = 1
|
||
fmt += 1
|
||
if *fmt == 108:
|
||
is_long_long = 1
|
||
is_long = 0
|
||
fmt += 1
|
||
elif *fmt == 104:
|
||
is_short = 1
|
||
fmt += 1
|
||
if *fmt == 104:
|
||
is_char = 1
|
||
is_short = 0
|
||
fmt += 1
|
||
elif *fmt == 122:
|
||
is_size = 1
|
||
fmt += 1
|
||
elif *fmt == 106:
|
||
is_long_long = 1
|
||
fmt += 1
|
||
elif *fmt == 116:
|
||
is_long = 1
|
||
fmt += 1
|
||
if *fmt == 99:
|
||
if write_count < size - 1:
|
||
ptr_i: int = va_arg(ap)
|
||
ptr[0] = char(ptr_i)
|
||
write_count += 1
|
||
ptr += _step
|
||
else:
|
||
ptr_i: int = va_arg(ap)
|
||
elif *fmt == 115:
|
||
s: str = va_arg(ap, t.CPtr)
|
||
if s is None: s = "(None)"
|
||
slen: int = 0
|
||
sc: str = s
|
||
while c.Deref(sc) != 0:
|
||
slen += 1
|
||
sc += 1
|
||
if not left_align and width > slen:
|
||
pad_count: int = width - slen
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
while c.Deref(s) != 0 and write_count < size - 1:
|
||
ptr[0] = c.Deref(s)
|
||
write_count += 1
|
||
ptr += _step
|
||
s += 1
|
||
if left_align and width > slen:
|
||
pad_count = width - slen
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
elif *fmt == 100 or *fmt == 105:
|
||
if is_long_long or is_size or is_long:
|
||
num_l: int64 = va_arg(ap, int64)
|
||
else:
|
||
num_l: int64 = int64(va_arg(ap, int))
|
||
if is_char:
|
||
num_l = int64(char(num_l))
|
||
elif is_short:
|
||
num_l = int64(short(num_l))
|
||
sign: int = 0
|
||
if num_l < 0:
|
||
sign = 1
|
||
if num_l == (-9223372036854775807 - 1):
|
||
u_num: uint64 = uint64(0x8000000000000000)
|
||
else:
|
||
u_num: uint64 = uint64(-num_l)
|
||
else:
|
||
u_num: uint64 = uint64(num_l)
|
||
if show_sign: sign = 2
|
||
elif space_sign: sign = 3
|
||
i: int = 0
|
||
while True:
|
||
if i >= TEMP_BUF_SIZE - 1: break
|
||
temp[i] = char(u_num % 10 + 48)
|
||
i += 1
|
||
u_num //= 10
|
||
if u_num <= 0: break
|
||
if sign == 1 and i < TEMP_BUF_SIZE - 1:
|
||
temp[i] = 45
|
||
i += 1
|
||
elif sign == 2 and i < TEMP_BUF_SIZE - 1:
|
||
temp[i] = 43
|
||
i += 1
|
||
elif sign == 3 and i < TEMP_BUF_SIZE - 1:
|
||
temp[i] = 32
|
||
i += 1
|
||
if not left_align and not pad_zero and width > i:
|
||
pad_count = width - i
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
if pad_zero and width > i:
|
||
pad_count = width - i
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 48
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
while i > 0 and write_count < size - 1:
|
||
i -= 1
|
||
ptr[0] = temp[i]
|
||
write_count += 1
|
||
ptr += _step
|
||
if left_align and width > i:
|
||
pad_count = width - i
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
elif *fmt == 117:
|
||
if is_long or is_long_long or is_size:
|
||
u_num_l: uint64 = va_arg(ap, uint64)
|
||
else:
|
||
u_num_l: uint64 = uint64(uint(va_arg(ap)))
|
||
i = 0
|
||
while True:
|
||
if i >= TEMP_BUF_SIZE - 1: break
|
||
temp[i] = char(u_num_l % 10 + 48)
|
||
i += 1
|
||
u_num_l //= 10
|
||
if u_num_l <= 0: break
|
||
if not left_align and not pad_zero and width > i:
|
||
pad_count = width - i
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
if pad_zero and width > i:
|
||
pad_count = width - i
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 48
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
while i > 0 and write_count < size - 1:
|
||
i -= 1
|
||
ptr[0] = temp[i]
|
||
write_count += 1
|
||
ptr += _step
|
||
if left_align and width > i:
|
||
pad_count = width - i
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
elif *fmt == 120:
|
||
if is_long or is_long_long or is_size:
|
||
u_num_l: uint64 = va_arg(ap, uint64)
|
||
else:
|
||
u_num_l: uint64 = uint64(uint(va_arg(ap)))
|
||
is_nonzero: int = 0
|
||
if u_num_l != 0:
|
||
is_nonzero = 1
|
||
i = 0
|
||
while True:
|
||
if i >= TEMP_BUF_SIZE - 1: break
|
||
digit: int = int(u_num_l % 16)
|
||
if digit < 10:
|
||
temp[i] = char(digit + 48)
|
||
else:
|
||
temp[i] = char(digit - 10 + 97)
|
||
u_num_l //= 16
|
||
i += 1
|
||
if u_num_l <= 0: break
|
||
digit_count: int = i
|
||
prefix_len: int = 0
|
||
if alt_form and is_nonzero:
|
||
prefix_len = 2
|
||
effective_len: int = digit_count + prefix_len
|
||
if not left_align and not pad_zero and width > effective_len:
|
||
pad_count = width - effective_len
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
if prefix_len > 0:
|
||
if write_count < size - 1:
|
||
ptr[0] = 48
|
||
write_count += 1
|
||
ptr += _step
|
||
if write_count < size - 1:
|
||
ptr[0] = 120
|
||
write_count += 1
|
||
ptr += _step
|
||
if pad_zero and width > effective_len:
|
||
pad_count = width - effective_len
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 48
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
while i > 0 and write_count < size - 1:
|
||
i -= 1
|
||
ptr[0] = temp[i]
|
||
write_count += 1
|
||
ptr += _step
|
||
if left_align and width > effective_len:
|
||
pad_count = width - effective_len
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
elif *fmt == 88:
|
||
if is_long or is_long_long or is_size:
|
||
u_num_l: uint64 = va_arg(ap)
|
||
else:
|
||
u_num_l: uint64 = uint64(uint(va_arg(ap)))
|
||
is_nonzero = 0
|
||
if u_num_l != 0:
|
||
is_nonzero = 1
|
||
i = 0
|
||
while True:
|
||
if i >= TEMP_BUF_SIZE - 1: break
|
||
digit = int(u_num_l % 16)
|
||
if digit < 10:
|
||
temp[i] = char(digit + 48)
|
||
else:
|
||
temp[i] = char(digit - 10 + 65)
|
||
u_num_l //= 16
|
||
i += 1
|
||
if u_num_l <= 0: break
|
||
digit_count = i
|
||
prefix_len = 0
|
||
if alt_form and is_nonzero:
|
||
prefix_len = 2
|
||
effective_len = digit_count + prefix_len
|
||
if not left_align and not pad_zero and width > effective_len:
|
||
pad_count = width - effective_len
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
if prefix_len > 0:
|
||
if write_count < size - 1:
|
||
ptr[0] = 48
|
||
write_count += 1
|
||
ptr += _step
|
||
if write_count < size - 1:
|
||
ptr[0] = 88
|
||
write_count += 1
|
||
ptr += _step
|
||
if pad_zero and width > effective_len:
|
||
pad_count = width - effective_len
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 48
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
while i > 0 and write_count < size - 1:
|
||
i -= 1
|
||
ptr[0] = temp[i]
|
||
write_count += 1
|
||
ptr += _step
|
||
if left_align and width > effective_len:
|
||
pad_count = width - effective_len
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
elif *fmt == 111:
|
||
if is_long or is_long_long or is_size:
|
||
u_num_l: uint64 = va_arg(ap, uint64)
|
||
else:
|
||
u_num_l: uint64 = uint64(uint(va_arg(ap)))
|
||
if is_char:
|
||
u_num_l = uint64(char(u_num_l))
|
||
elif is_short:
|
||
u_num_l = uint64(short(u_num_l))
|
||
i = 0
|
||
if u_num_l == 0 and not alt_form:
|
||
temp[0] = 48
|
||
i = 1
|
||
else:
|
||
while True:
|
||
if i >= TEMP_BUF_SIZE - 1: break
|
||
temp[i] = char(u_num_l % 8 + 48)
|
||
i += 1
|
||
u_num_l //= 8
|
||
if u_num_l <= 0: break
|
||
if alt_form and i < TEMP_BUF_SIZE - 1:
|
||
temp[i] = 48
|
||
i += 1
|
||
if not left_align and not pad_zero and width > i:
|
||
pad_count = width - i
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
if pad_zero and width > i:
|
||
pad_count = width - i
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 48
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
while i > 0 and write_count < size - 1:
|
||
i -= 1
|
||
ptr[0] = temp[i]
|
||
write_count += 1
|
||
ptr += _step
|
||
if left_align and width > i:
|
||
pad_count = width - i
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
elif *fmt == 98:
|
||
if is_long or is_long_long or is_size:
|
||
u_num_l: uint64 = va_arg(ap, uint64)
|
||
else:
|
||
u_num_l: uint64 = uint64(uint(va_arg(ap)))
|
||
if is_char:
|
||
u_num_l = uint64(char(u_num_l))
|
||
elif is_short:
|
||
u_num_l = uint64(short(u_num_l))
|
||
i = 0
|
||
if u_num_l == 0:
|
||
temp[0] = 48
|
||
i = 1
|
||
else:
|
||
while True:
|
||
if i >= TEMP_BUF_SIZE - 1: break
|
||
temp[i] = char(u_num_l % 2 + 48)
|
||
i += 1
|
||
u_num_l //= 2
|
||
if u_num_l <= 0: break
|
||
if alt_form and i < TEMP_BUF_SIZE - 1:
|
||
temp[i] = 98
|
||
i += 1
|
||
if not left_align and not pad_zero and width > i:
|
||
pad_count = width - i
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
if pad_zero and width > i:
|
||
pad_count = width - i
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 48
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
while i > 0 and write_count < size - 1:
|
||
i -= 1
|
||
ptr[0] = temp[i]
|
||
write_count += 1
|
||
ptr += _step
|
||
if left_align and width > i:
|
||
pad_count = width - i
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
elif *fmt == 112:
|
||
ptr_val: uint64 = uint64(va_arg(ap, t.CPtr))
|
||
if ptr_val == 0:
|
||
temp[0] = 40
|
||
temp[1] = 110
|
||
temp[2] = 105
|
||
temp[3] = 108
|
||
temp[4] = 41
|
||
i = 5
|
||
else:
|
||
u_num_l = ptr_val
|
||
i = 0
|
||
while True:
|
||
if i >= TEMP_BUF_SIZE - 1: break
|
||
digit = int(u_num_l % 16)
|
||
if digit < 10:
|
||
temp[i] = char(digit + 48)
|
||
else:
|
||
temp[i] = char(digit - 10 + 97)
|
||
u_num_l //= 16
|
||
i += 1
|
||
if u_num_l <= 0: break
|
||
if i < TEMP_BUF_SIZE - 1:
|
||
temp[i] = 120
|
||
i += 1
|
||
if i < TEMP_BUF_SIZE - 1:
|
||
temp[i] = 48
|
||
i += 1
|
||
if not left_align and not pad_zero and width > i:
|
||
pad_count = width - i
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
if pad_zero and width > i:
|
||
pad_count = width - i
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 48
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
while i > 0 and write_count < size - 1:
|
||
i -= 1
|
||
ptr[0] = temp[i]
|
||
write_count += 1
|
||
ptr += _step
|
||
if left_align and width > i:
|
||
pad_count = width - i
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
elif *fmt == 102 or *fmt == 70:
|
||
f_upper: int = 1 if *fmt == 70 else 0
|
||
if precision < 0: precision = 6
|
||
fv: double = va_arg(ap, double)
|
||
f_sp: int = _check_special_float(fv)
|
||
if f_sp != 0:
|
||
f_sgn_len: int = 0
|
||
if f_sp == 2:
|
||
f_sgn_len = 1
|
||
elif f_sp == 1 and show_sign:
|
||
f_sgn_len = 1
|
||
elif f_sp == 1 and space_sign:
|
||
f_sgn_len = 1
|
||
f_total_len: int = f_sgn_len + 3
|
||
if not left_align and width > f_total_len:
|
||
f_pad: int = width - f_total_len
|
||
while f_pad > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
f_pad -= 1
|
||
if f_sp == 2:
|
||
if write_count < size - 1:
|
||
ptr[0] = 45
|
||
write_count += 1
|
||
ptr += _step
|
||
elif f_sp == 1 and show_sign:
|
||
if write_count < size - 1:
|
||
ptr[0] = 43
|
||
write_count += 1
|
||
ptr += _step
|
||
elif f_sp == 1 and space_sign:
|
||
if write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
fi_c: int = 0
|
||
while fi_c < 3 and write_count < size - 1:
|
||
fc: int = 0
|
||
if f_sp == 3:
|
||
# nan
|
||
if fi_c == 0:
|
||
fc = 110
|
||
elif fi_c == 1:
|
||
fc = 97
|
||
else:
|
||
fc = 110
|
||
else:
|
||
# inf (f_sp==1 +inf 或 f_sp==2 -inf)
|
||
if fi_c == 0:
|
||
fc = 105
|
||
elif fi_c == 1:
|
||
fc = 110
|
||
else:
|
||
fc = 102
|
||
if f_upper and fc >= 97 and fc <= 122:
|
||
fc -= 32
|
||
ptr[0] = char(fc)
|
||
write_count += 1
|
||
ptr += _step
|
||
fi_c += 1
|
||
if left_align and width > f_total_len:
|
||
f_pad = width - f_total_len
|
||
while f_pad > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
f_pad -= 1
|
||
fmt += 1
|
||
continue
|
||
if fv < 0.0:
|
||
if write_count < size - 1:
|
||
ptr[0] = 45
|
||
write_count += 1
|
||
ptr += _step
|
||
fv = 0.0 - fv
|
||
elif show_sign:
|
||
if write_count < size - 1:
|
||
ptr[0] = 43
|
||
write_count += 1
|
||
ptr += _step
|
||
elif space_sign:
|
||
if write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
di: int = 0
|
||
work: double = fv
|
||
if work < 1.0:
|
||
temp[0] = 48
|
||
di = 1
|
||
else:
|
||
scale: double = 1.0
|
||
# 上界防护:inf 会让 `work >= scale*10.0` 永真,正常有限值最多 308 次
|
||
scale_guard: int = 0
|
||
while work >= scale * 10.0 and scale_guard < 400:
|
||
scale *= 10.0
|
||
scale_guard += 1
|
||
while scale >= 1.0 and di < TEMP_BUF_SIZE - 1:
|
||
d: int = int(work / scale)
|
||
if d > 9: d = 9
|
||
temp[di] = char(d + 48)
|
||
di += 1
|
||
work = work - double(d) * scale
|
||
scale /= 10.0
|
||
frac_val: double = work
|
||
p: int = 0
|
||
while p < precision:
|
||
frac_val *= 10.0
|
||
p += 1
|
||
frac_part: uint64 = uint64(frac_val + 0.5)
|
||
f_total: int = di + (precision + 1 if precision > 0 else 0)
|
||
if not left_align and not pad_zero and width > f_total:
|
||
pad_count = width - f_total
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
if pad_zero and width > f_total:
|
||
pad_count = width - f_total
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 48
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
while di > 0 and write_count < size - 1:
|
||
di -= 1
|
||
ptr[0] = temp[di]
|
||
write_count += 1
|
||
ptr += _step
|
||
if precision > 0:
|
||
if write_count < size - 1:
|
||
ptr[0] = 46
|
||
write_count += 1
|
||
ptr += _step
|
||
fi: int = 0
|
||
while fi < precision and fi < TEMP_BUF_SIZE - 1:
|
||
temp[fi] = char(frac_part % 10 + 48)
|
||
fi += 1
|
||
frac_part //= 10
|
||
while fi < precision and fi < TEMP_BUF_SIZE - 1:
|
||
temp[fi] = 48
|
||
fi += 1
|
||
while fi > 0 and write_count < size - 1:
|
||
fi -= 1
|
||
ptr[0] = temp[fi]
|
||
write_count += 1
|
||
ptr += _step
|
||
elif alt_form:
|
||
if write_count < size - 1:
|
||
ptr[0] = 46
|
||
write_count += 1
|
||
ptr += _step
|
||
if left_align and width > f_total:
|
||
pad_count = width - f_total
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
elif *fmt == 101 or *fmt == 69:
|
||
if precision < 0: precision = 6
|
||
fv: double = va_arg(ap, double)
|
||
e_upper: int = 1 if *fmt == 69 else 0
|
||
e_sp: int = _check_special_float(fv)
|
||
if e_sp != 0:
|
||
e_sgn_len: int = 0
|
||
if e_sp == 2:
|
||
e_sgn_len = 1
|
||
elif e_sp == 1 and show_sign:
|
||
e_sgn_len = 1
|
||
elif e_sp == 1 and space_sign:
|
||
e_sgn_len = 1
|
||
e_total_len: int = e_sgn_len + 3
|
||
if not left_align and width > e_total_len:
|
||
e_pad: int = width - e_total_len
|
||
while e_pad > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
e_pad -= 1
|
||
if e_sp == 2:
|
||
if write_count < size - 1:
|
||
ptr[0] = 45
|
||
write_count += 1
|
||
ptr += _step
|
||
elif e_sp == 1 and show_sign:
|
||
if write_count < size - 1:
|
||
ptr[0] = 43
|
||
write_count += 1
|
||
ptr += _step
|
||
elif e_sp == 1 and space_sign:
|
||
if write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
ei_c: int = 0
|
||
while ei_c < 3 and write_count < size - 1:
|
||
ec: int = 0
|
||
if e_sp == 3:
|
||
# nan
|
||
if ei_c == 0:
|
||
ec = 110
|
||
elif ei_c == 1:
|
||
ec = 97
|
||
else:
|
||
ec = 110
|
||
else:
|
||
# inf (e_sp==1 +inf 或 e_sp==2 -inf)
|
||
if ei_c == 0:
|
||
ec = 105
|
||
elif ei_c == 1:
|
||
ec = 110
|
||
else:
|
||
ec = 102
|
||
if e_upper and ec >= 97 and ec <= 122:
|
||
ec -= 32
|
||
ptr[0] = char(ec)
|
||
write_count += 1
|
||
ptr += _step
|
||
ei_c += 1
|
||
if left_align and width > e_total_len:
|
||
e_pad = width - e_total_len
|
||
while e_pad > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
e_pad -= 1
|
||
fmt += 1
|
||
continue
|
||
if fv < 0.0:
|
||
if write_count < size - 1:
|
||
ptr[0] = 45
|
||
write_count += 1
|
||
ptr += _step
|
||
fv = 0.0 - fv
|
||
elif show_sign:
|
||
if write_count < size - 1:
|
||
ptr[0] = 43
|
||
write_count += 1
|
||
ptr += _step
|
||
elif space_sign:
|
||
if write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
exp10: int = 0
|
||
if fv != 0.0:
|
||
# 上界防护:inf 会让下面两个循环永真(inf/10==inf、inf*10==inf)
|
||
exp_guard: int = 0
|
||
while fv >= 10.0 and exp_guard < 400:
|
||
fv /= 10.0
|
||
exp10 += 1
|
||
exp_guard += 1
|
||
exp_guard = 0
|
||
while fv < 1.0 and exp_guard < 400:
|
||
fv *= 10.0
|
||
exp10 -= 1
|
||
exp_guard += 1
|
||
int_digit: int = int(fv)
|
||
if int_digit > 9: int_digit = 9
|
||
if int_digit < 0: int_digit = 0
|
||
frac_v: double = fv - double(int_digit)
|
||
p: int = 0
|
||
while p < precision:
|
||
frac_v *= 10.0
|
||
p += 1
|
||
frac_p: uint64 = uint64(frac_v + 0.5)
|
||
carry: uint64 = 1
|
||
p = 0
|
||
while p < precision:
|
||
carry *= 10
|
||
p += 1
|
||
if frac_p >= carry and carry > 0:
|
||
frac_p = 0
|
||
int_digit += 1
|
||
if int_digit > 9:
|
||
int_digit = 1
|
||
exp10 += 1
|
||
e_total: int = 1 + (precision + 1 if precision > 0 else 0) + 4
|
||
if not left_align and not pad_zero and width > e_total:
|
||
pad_count = width - e_total
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
if pad_zero and width > e_total:
|
||
pad_count = width - e_total
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 48
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
if write_count < size - 1:
|
||
ptr[0] = char(int_digit + 48)
|
||
write_count += 1
|
||
ptr += _step
|
||
if precision > 0:
|
||
if write_count < size - 1:
|
||
ptr[0] = 46
|
||
write_count += 1
|
||
ptr += _step
|
||
fi: int = 0
|
||
while fi < precision and fi < TEMP_BUF_SIZE - 1:
|
||
temp[fi] = char(frac_p % 10 + 48)
|
||
fi += 1
|
||
frac_p //= 10
|
||
while fi < precision and fi < TEMP_BUF_SIZE - 1:
|
||
temp[fi] = 48
|
||
fi += 1
|
||
while fi > 0 and write_count < size - 1:
|
||
fi -= 1
|
||
ptr[0] = temp[fi]
|
||
write_count += 1
|
||
ptr += _step
|
||
elif alt_form:
|
||
if write_count < size - 1:
|
||
ptr[0] = 46
|
||
write_count += 1
|
||
ptr += _step
|
||
if write_count < size - 1:
|
||
ptr[0] = 101 if e_upper == 0 else 69
|
||
write_count += 1
|
||
ptr += _step
|
||
if write_count < size - 1:
|
||
ptr[0] = 45 if exp10 < 0 else 43
|
||
write_count += 1
|
||
ptr += _step
|
||
exp_abs: uint64 = uint64(exp10) if exp10 >= 0 else uint64(0 - exp10)
|
||
ei: int = 0
|
||
if exp_abs == 0:
|
||
temp[0] = 48
|
||
temp[1] = 48
|
||
ei = 2
|
||
else:
|
||
while exp_abs > 0 and ei < TEMP_BUF_SIZE - 1:
|
||
temp[ei] = char(exp_abs % 10 + 48)
|
||
ei += 1
|
||
exp_abs //= 10
|
||
while ei < 2:
|
||
temp[ei] = 48
|
||
ei += 1
|
||
while ei > 0 and write_count < size - 1:
|
||
ei -= 1
|
||
ptr[0] = temp[ei]
|
||
write_count += 1
|
||
ptr += _step
|
||
if left_align and width > e_total:
|
||
pad_count = width - e_total
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
elif *fmt == 103 or *fmt == 71:
|
||
if precision < 0: precision = 6
|
||
if precision == 0: precision = 1
|
||
fv: double = va_arg(ap, double)
|
||
g_upper: int = 1 if *fmt == 71 else 0
|
||
g_sp: int = _check_special_float(fv)
|
||
if g_sp != 0:
|
||
g_sgn_len: int = 0
|
||
if g_sp == 2:
|
||
g_sgn_len = 1
|
||
elif g_sp == 1 and show_sign:
|
||
g_sgn_len = 1
|
||
elif g_sp == 1 and space_sign:
|
||
g_sgn_len = 1
|
||
g_total_len: int = g_sgn_len + 3
|
||
if not left_align and width > g_total_len:
|
||
g_pad: int = width - g_total_len
|
||
while g_pad > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
g_pad -= 1
|
||
if g_sp == 2:
|
||
if write_count < size - 1:
|
||
ptr[0] = 45
|
||
write_count += 1
|
||
ptr += _step
|
||
elif g_sp == 1 and show_sign:
|
||
if write_count < size - 1:
|
||
ptr[0] = 43
|
||
write_count += 1
|
||
ptr += _step
|
||
elif g_sp == 1 and space_sign:
|
||
if write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
gi_c: int = 0
|
||
while gi_c < 3 and write_count < size - 1:
|
||
gc: int = 0
|
||
if g_sp == 3:
|
||
# nan
|
||
if gi_c == 0:
|
||
gc = 110
|
||
elif gi_c == 1:
|
||
gc = 97
|
||
else:
|
||
gc = 110
|
||
else:
|
||
# inf (g_sp==1 +inf 或 g_sp==2 -inf)
|
||
if gi_c == 0:
|
||
gc = 105
|
||
elif gi_c == 1:
|
||
gc = 110
|
||
else:
|
||
gc = 102
|
||
if g_upper and gc >= 97 and gc <= 122:
|
||
gc -= 32
|
||
ptr[0] = char(gc)
|
||
write_count += 1
|
||
ptr += _step
|
||
gi_c += 1
|
||
if left_align and width > g_total_len:
|
||
g_pad = width - g_total_len
|
||
while g_pad > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
g_pad -= 1
|
||
fmt += 1
|
||
continue
|
||
if fv < 0.0:
|
||
if write_count < size - 1:
|
||
ptr[0] = 45
|
||
write_count += 1
|
||
ptr += _step
|
||
fv = 0.0 - fv
|
||
elif show_sign:
|
||
if write_count < size - 1:
|
||
ptr[0] = 43
|
||
write_count += 1
|
||
ptr += _step
|
||
elif space_sign:
|
||
if write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
fv_orig: double = fv
|
||
exp10: int = 0
|
||
if fv != 0.0:
|
||
# 上界防护:卡死现场即此循环(inf 会让 fv>=10.0 永真,inf/10==inf)
|
||
exp_guard: int = 0
|
||
while fv >= 10.0 and exp_guard < 400:
|
||
fv /= 10.0
|
||
exp10 += 1
|
||
exp_guard += 1
|
||
exp_guard = 0
|
||
while fv < 1.0 and exp_guard < 400:
|
||
fv *= 10.0
|
||
exp10 -= 1
|
||
exp_guard += 1
|
||
g_use_e: int = 0
|
||
if exp10 < -4 or exp10 >= precision:
|
||
g_use_e = 1
|
||
g_len: int = 0
|
||
if g_use_e:
|
||
int_digit: int = int(fv)
|
||
if int_digit > 9: int_digit = 9
|
||
if int_digit < 0: int_digit = 0
|
||
frac_v: double = fv - double(int_digit)
|
||
prec_e: int = precision - 1
|
||
p: int = 0
|
||
while p < prec_e:
|
||
frac_v *= 10.0
|
||
p += 1
|
||
frac_p: uint64 = uint64(frac_v + 0.5)
|
||
carry: uint64 = 1
|
||
p = 0
|
||
while p < prec_e:
|
||
carry *= 10
|
||
p += 1
|
||
if frac_p >= carry and carry > 0:
|
||
frac_p = 0
|
||
int_digit += 1
|
||
if int_digit > 9:
|
||
int_digit = 1
|
||
exp10 += 1
|
||
temp[0] = char(int_digit + 48)
|
||
g_len = 1
|
||
if prec_e > 0:
|
||
temp[1] = 46
|
||
g_len = 2
|
||
# 小数位逆序存入(个位放 g_len+prec_e-1),temp 直接为正序。
|
||
# 原交换反转循环在 TPV 编译产物中失效(小数位未反转,如 456->654),
|
||
# 改逆序存储,与 %f 的倒序输出一致,绕开三变量交换。
|
||
fi: int = 0
|
||
fp_inv: uint64 = frac_p
|
||
fp_idx: int = g_len + prec_e - 1
|
||
while fi < prec_e and fp_idx < TEMP_BUF_SIZE - 1:
|
||
temp[fp_idx] = char(fp_inv % 10 + 48)
|
||
fp_idx -= 1
|
||
fp_inv //= 10
|
||
fi += 1
|
||
g_len += prec_e
|
||
else:
|
||
prec_f: int = precision - 1 - exp10
|
||
if prec_f < 0: prec_f = 0
|
||
work: double = fv_orig
|
||
if work < 1.0:
|
||
temp[0] = 48
|
||
g_len = 1
|
||
else:
|
||
scale: double = 1.0
|
||
# 上界防护:inf 会让 `work >= scale*10.0` 永真,正常有限值最多 308 次
|
||
scale_guard: int = 0
|
||
while work >= scale * 10.0 and scale_guard < 400:
|
||
scale *= 10.0
|
||
scale_guard += 1
|
||
while scale >= 1.0 and g_len < TEMP_BUF_SIZE - 1:
|
||
d: int = int(work / scale)
|
||
if d > 9: d = 9
|
||
temp[g_len] = char(d + 48)
|
||
g_len += 1
|
||
work = work - double(d) * scale
|
||
scale /= 10.0
|
||
if prec_f > 0 and g_len < TEMP_BUF_SIZE - 1:
|
||
temp[g_len] = 46
|
||
g_len += 1
|
||
frac_val: double = work
|
||
p = 0
|
||
while p < prec_f:
|
||
frac_val *= 10.0
|
||
p += 1
|
||
frac_part: uint64 = uint64(frac_val + 0.5)
|
||
# Store decimal digits in reverse order (ones place goes to g_len prec_f-1), temp is directly in forward order.
|
||
# The original swap-reverse loop doesn't work in TPV compiled output (decimal digits aren't reversed, e.g., 456->654),
|
||
# Change to reverse storage, consistent with %f's reverse output, avoiding three-variable swapping.
|
||
fi = 0
|
||
fp_inv: uint64 = frac_part
|
||
fp_idx: int = g_len + prec_f - 1
|
||
while fi < prec_f and fp_idx < TEMP_BUF_SIZE - 1:
|
||
temp[fp_idx] = char(fp_inv % 10 + 48)
|
||
fp_idx -= 1
|
||
fp_inv //= 10
|
||
fi += 1
|
||
g_len += prec_f
|
||
if not alt_form and g_len > 0:
|
||
while g_len > 0:
|
||
if temp[g_len - 1] == 48:
|
||
g_len -= 1
|
||
else:
|
||
break
|
||
if g_len > 0 and temp[g_len - 1] == 46:
|
||
g_len -= 1
|
||
g_total: int = g_len
|
||
if g_use_e: g_total = g_len + 4
|
||
if not left_align and not pad_zero and width > g_total:
|
||
pad_count = width - g_total
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
if pad_zero and width > g_total:
|
||
pad_count = width - g_total
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 48
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
gi: int = 0
|
||
while gi < g_len and write_count < size - 1:
|
||
ptr[0] = temp[gi]
|
||
write_count += 1
|
||
ptr += _step
|
||
gi += 1
|
||
if g_use_e:
|
||
if write_count < size - 1:
|
||
ptr[0] = 101 if g_upper == 0 else 69
|
||
write_count += 1
|
||
ptr += _step
|
||
if write_count < size - 1:
|
||
ptr[0] = 45 if exp10 < 0 else 43
|
||
write_count += 1
|
||
ptr += _step
|
||
exp_abs: uint64 = uint64(exp10) if exp10 >= 0 else uint64(0 - exp10)
|
||
ei: int = 0
|
||
if exp_abs == 0:
|
||
temp[0] = 48
|
||
temp[1] = 48
|
||
ei = 2
|
||
else:
|
||
while exp_abs > 0 and ei < TEMP_BUF_SIZE - 1:
|
||
temp[ei] = char(exp_abs % 10 + 48)
|
||
ei += 1
|
||
exp_abs //= 10
|
||
while ei < 2:
|
||
temp[ei] = 48
|
||
ei += 1
|
||
while ei > 0 and write_count < size - 1:
|
||
ei -= 1
|
||
ptr[0] = temp[ei]
|
||
write_count += 1
|
||
ptr += _step
|
||
if left_align and width > g_total:
|
||
pad_count = width - g_total
|
||
while pad_count > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
pad_count -= 1
|
||
elif *fmt == 97 or *fmt == 65:
|
||
a_upper: int = 1 if *fmt == 65 else 0
|
||
fv: double = va_arg(ap, double)
|
||
a_sp: int = _check_special_float(fv)
|
||
if a_sp != 0:
|
||
a_sgn_len: int = 0
|
||
if a_sp == 2:
|
||
a_sgn_len = 1
|
||
elif a_sp == 1 and show_sign:
|
||
a_sgn_len = 1
|
||
elif a_sp == 1 and space_sign:
|
||
a_sgn_len = 1
|
||
a_total_len: int = a_sgn_len + 3
|
||
if not left_align and width > a_total_len:
|
||
a_pad: int = width - a_total_len
|
||
while a_pad > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
a_pad -= 1
|
||
if a_sp == 2:
|
||
if write_count < size - 1:
|
||
ptr[0] = 45
|
||
write_count += 1
|
||
ptr += _step
|
||
elif a_sp == 1 and show_sign:
|
||
if write_count < size - 1:
|
||
ptr[0] = 43
|
||
write_count += 1
|
||
ptr += _step
|
||
elif a_sp == 1 and space_sign:
|
||
if write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
ai_c: int = 0
|
||
while ai_c < 3 and write_count < size - 1:
|
||
ac: int = 0
|
||
if a_sp == 3:
|
||
# nan
|
||
if ai_c == 0:
|
||
ac = 110
|
||
elif ai_c == 1:
|
||
ac = 97
|
||
else:
|
||
ac = 110
|
||
else:
|
||
# inf (a_sp==1 +inf 或 a_sp==2 -inf)
|
||
if ai_c == 0:
|
||
ac = 105
|
||
elif ai_c == 1:
|
||
ac = 110
|
||
else:
|
||
ac = 102
|
||
if a_upper and ac >= 97 and ac <= 122:
|
||
ac -= 32
|
||
ptr[0] = char(ac)
|
||
write_count += 1
|
||
ptr += _step
|
||
ai_c += 1
|
||
if left_align and width > a_total_len:
|
||
a_pad = width - a_total_len
|
||
while a_pad > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
a_pad -= 1
|
||
fmt += 1
|
||
continue
|
||
fbits: uint64 = 0
|
||
c.Load(c.Addr(fbits), c.Addr(fv))
|
||
a_neg: int = 1 if (fbits >> 63) != 0 else 0
|
||
a_exp: int = int((fbits >> 52) & 0x7FF)
|
||
a_frac: uint64 = fbits & 0x000FFFFFFFFFFFFF
|
||
a_leading: int = 0
|
||
a_binexp: int = 0
|
||
if a_exp == 0:
|
||
a_leading = 0
|
||
if a_frac == 0:
|
||
a_binexp = 0
|
||
else:
|
||
a_binexp = -1022
|
||
else:
|
||
a_leading = 1
|
||
a_binexp = a_exp - 1023
|
||
a_prec: int = precision
|
||
if a_prec < 0:
|
||
a_prec = 13
|
||
if a_prec > 50:
|
||
a_prec = 50
|
||
a_hi: int = 0
|
||
while a_hi < 13 and a_hi < a_prec:
|
||
a_digit: int = int((a_frac >> (48 - 4 * a_hi)) & 0xF)
|
||
if a_digit < 10:
|
||
temp[a_hi] = char(a_digit + 48)
|
||
else:
|
||
if a_upper:
|
||
temp[a_hi] = char(a_digit - 10 + 65)
|
||
else:
|
||
temp[a_hi] = char(a_digit - 10 + 97)
|
||
a_hi += 1
|
||
while a_hi < a_prec:
|
||
temp[a_hi] = 48
|
||
a_hi += 1
|
||
a_hd_count: int = a_prec
|
||
if precision < 0:
|
||
while a_hd_count > 0 and temp[a_hd_count - 1] == 48:
|
||
a_hd_count -= 1
|
||
a_has_dot: int = 0
|
||
if a_hd_count > 0:
|
||
a_has_dot = 1
|
||
elif alt_form:
|
||
a_has_dot = 1
|
||
a_eb: int = a_binexp
|
||
a_esign: int = 0
|
||
if a_binexp < 0:
|
||
a_esign = 1
|
||
a_eb = -a_binexp
|
||
a_ei: int = 0
|
||
if a_eb == 0:
|
||
temp[60] = 48
|
||
a_ei = 1
|
||
else:
|
||
while a_eb > 0 and a_ei < 7:
|
||
temp[60 + a_ei] = char(a_eb % 10 + 48)
|
||
a_ei += 1
|
||
a_eb //= 10
|
||
a_ecount: int = a_ei
|
||
a_sign_len: int = 0
|
||
if a_neg:
|
||
a_sign_len = 1
|
||
elif show_sign:
|
||
a_sign_len = 1
|
||
elif space_sign:
|
||
a_sign_len = 1
|
||
a_content_len: int = a_sign_len + 2 + 1 + a_has_dot + a_hd_count + 1 + 1 + a_ecount
|
||
if not left_align and not pad_zero and width > a_content_len:
|
||
a_pad = width - a_content_len
|
||
while a_pad > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
a_pad -= 1
|
||
if a_neg:
|
||
if write_count < size - 1:
|
||
ptr[0] = 45
|
||
write_count += 1
|
||
ptr += _step
|
||
elif show_sign:
|
||
if write_count < size - 1:
|
||
ptr[0] = 43
|
||
write_count += 1
|
||
ptr += _step
|
||
elif space_sign:
|
||
if write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
if pad_zero and width > a_content_len:
|
||
a_pad = width - a_content_len
|
||
while a_pad > 0 and write_count < size - 1:
|
||
ptr[0] = 48
|
||
write_count += 1
|
||
ptr += _step
|
||
a_pad -= 1
|
||
if write_count < size - 1:
|
||
ptr[0] = 48
|
||
write_count += 1
|
||
ptr += _step
|
||
if write_count < size - 1:
|
||
if a_upper:
|
||
ptr[0] = 88
|
||
else:
|
||
ptr[0] = 120
|
||
write_count += 1
|
||
ptr += _step
|
||
if write_count < size - 1:
|
||
ptr[0] = char(a_leading + 48)
|
||
write_count += 1
|
||
ptr += _step
|
||
if a_has_dot:
|
||
if write_count < size - 1:
|
||
ptr[0] = 46
|
||
write_count += 1
|
||
ptr += _step
|
||
a_hj: int = 0
|
||
while a_hj < a_hd_count and write_count < size - 1:
|
||
ptr[0] = temp[a_hj]
|
||
write_count += 1
|
||
ptr += _step
|
||
a_hj += 1
|
||
if write_count < size - 1:
|
||
if a_upper:
|
||
ptr[0] = 80
|
||
else:
|
||
ptr[0] = 112
|
||
write_count += 1
|
||
ptr += _step
|
||
if write_count < size - 1:
|
||
if a_esign:
|
||
ptr[0] = 45
|
||
else:
|
||
ptr[0] = 43
|
||
write_count += 1
|
||
ptr += _step
|
||
a_ek: int = a_ecount
|
||
while a_ek > 0 and write_count < size - 1:
|
||
a_ek -= 1
|
||
ptr[0] = temp[60 + a_ek]
|
||
write_count += 1
|
||
ptr += _step
|
||
if left_align and width > a_content_len:
|
||
a_pad = width - a_content_len
|
||
while a_pad > 0 and write_count < size - 1:
|
||
ptr[0] = 32
|
||
write_count += 1
|
||
ptr += _step
|
||
a_pad -= 1
|
||
elif *fmt == 110:
|
||
if is_long_long or is_long:
|
||
np: int64* = va_arg(ap, int64*)
|
||
if np != None:
|
||
np[0] = int64(write_count)
|
||
elif is_short:
|
||
sp: short* = va_arg(ap, short*)
|
||
if sp != None:
|
||
sp[0] = short(write_count)
|
||
elif is_char:
|
||
cp: str = va_arg(ap, str)
|
||
if cp != None:
|
||
cp[0] = char(write_count)
|
||
else:
|
||
ip: int* = va_arg(ap, int*)
|
||
if ip != None:
|
||
ip[0] = write_count
|
||
elif *fmt == 37:
|
||
if write_count < size - 1:
|
||
ptr[0] = 37
|
||
write_count += 1
|
||
ptr += _step
|
||
else:
|
||
if write_count < size - 1:
|
||
ptr[0] = *fmt
|
||
write_count += 1
|
||
ptr += _step
|
||
fmt += 1
|
||
ptr[0] = 0
|
||
return write_count
|