import t, c
import viperio
from stdarg import arg, va_arg

TEMP_BUF_SIZE: t.CDefine = 68

def get_digit_count(num: t.CUnsignedInt, base: t.CInt) -> t.CStatic | t.CInt:
    count: t.CInt = 0
    if num == 0: return 1
    while num > 0:
        count += 1
        num //= base
    return count

def sprintf(buf: t.CChar | t.CPtr, rule: str, *args) -> t.CVoid | t.CExport:
    if buf is None or rule is None: return
    vsnprintf(buf, 0x7FFFFFFF, rule, args)

def vsprintf(buf: t.CChar | t.CPtr, rule: str, *args) -> t.CInt:
    if buf is None or rule is None: return 0
    return vsnprintf(buf, 0x7FFFFFFF, rule, args)

def snprintf(buf: t.CChar | t.CPtr, size: t.CSizeT, fmt: str, *args) -> t.CInt | t.CExport:
    if buf is None or fmt is None or size == 0: return 0
    return vsnprintf(buf, size, fmt, args)

# 检测浮点特殊值（IEEE 754）
# 返回: 0=normal, 1=+inf, 2=-inf, 3=nan
def _check_special_float(fv: t.CDouble) -> t.CInt:
    fbits: t.CUInt64T = 0
    c.Load(c.Addr(fbits), c.Addr(fv))
    if ((fbits >> 52) & 0x7FF) != 0x7FF:
        return 0
    is_neg: t.CInt = 1 if (fbits >> 63) != 0 else 0
    if (fbits & 0x000FFFFFFFFFFFFF) == 0:
        if is_neg:
            return 2
        return 1
    return 3

def vsnprintf(buf: t.CChar | t.CPtr, size: t.CSizeT, fmt: str, ap: t.CChar | t.CPtr) -> t.CInt | t.CExport:
    if buf is None or fmt is None or size == 0: return 0
    ptr: t.CChar | t.CPtr = buf
    write_count: t.CInt = 0
    temp: t.CArray[t.CChar, 68]
    temp[0] = '\t'
    while c.Deref(fmt) != 0 and write_count < size - 1:
        if c.Deref(fmt) != 37:
            ptr[0] = c.Deref(fmt)
            write_count += 1
            ptr += 1
            fmt += 1
        else:
            fmt += 1
            if c.Deref(fmt) == 0: break
            width: t.CInt = 0
            pad_zero: t.CInt = 0
            left_align: t.CInt = 0
            show_sign: t.CInt = 0
            space_sign: t.CInt = 0
            alt_form: t.CInt = 0
            precision: t.CInt = -1
            is_long: t.CInt = 0
            is_long_long: t.CInt = 0
            is_size: t.CInt = 0
            is_short: t.CInt = 0
            is_char: t.CInt = 0
            while True:
                if c.Deref(fmt) == 45:
                    left_align = 1
                    fmt += 1
                elif c.Deref(fmt) == 48:
                    pad_zero = 1
                    fmt += 1
                elif c.Deref(fmt) == 43:
                    show_sign = 1
                    fmt += 1
                elif c.Deref(fmt) == 32:
                    space_sign = 1
                    fmt += 1
                elif c.Deref(fmt) == 35:
                    alt_form = 1
                    fmt += 1
                else: break
            if show_sign: space_sign = 0
            while c.Deref(fmt) >= 48 and c.Deref(fmt) <= 57:
                width = width * 10 + (c.Deref(fmt) - 48)
                fmt += 1
            if c.Deref(fmt) == 46:
                fmt += 1
                precision = 0
                while c.Deref(fmt) >= 48 and c.Deref(fmt) <= 57:
                    precision = precision * 10 + (c.Deref(fmt) - 48)
                    fmt += 1
            if left_align: pad_zero = 0
            if c.Deref(fmt) == 108:
                is_long = 1
                fmt += 1
                if c.Deref(fmt) == 108:
                    is_long_long = 1
                    is_long = 0
                    fmt += 1
            elif c.Deref(fmt) == 104:
                is_short = 1
                fmt += 1
                if c.Deref(fmt) == 104:
                    is_char = 1
                    is_short = 0
                    fmt += 1
            elif c.Deref(fmt) == 122:
                is_size = 1
                fmt += 1
            elif c.Deref(fmt) == 106:
                is_long_long = 1
                fmt += 1
            elif c.Deref(fmt) == 116:
                is_long = 1
                fmt += 1
            if c.Deref(fmt) == 99:
                if write_count < size - 1:
                    ptr_i: t.CInt = va_arg(ap)
                    ptr[0] = t.CChar(ptr_i)
                    write_count += 1
                    ptr += 1
                else:
                    ptr_i: t.CInt = va_arg(ap)
            elif c.Deref(fmt) == 115:
                s: str = va_arg(ap, t.CPtr)
                if s is None: s = "(None)"
                slen: t.CInt = 0
                sc: str = s
                while c.Deref(sc) != 0:
                    slen += 1
                    sc += 1
                if not left_align and width > slen:
                    pad_count: t.CInt = width - slen
                    while pad_count > 0 and write_count < size - 1:
                        ptr[0] = 32
                        write_count += 1
                        ptr += 1
                        pad_count -= 1
                while c.Deref(s) != 0 and write_count < size - 1:
                    ptr[0] = c.Deref(s)
                    write_count += 1
                    ptr += 1
                    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 += 1
                        pad_count -= 1
            elif c.Deref(fmt) == 100 or c.Deref(fmt) == 105:
                if is_long_long or is_size or is_long:
                    num_l: t.CInt64T = va_arg(ap, t.CInt64T)
                else:
                    num_l: t.CInt64T = t.CInt64T(va_arg(ap, t.CInt))
                if is_char:
                    num_l = t.CInt64T(t.CChar(num_l))
                elif is_short:
                    num_l = t.CInt64T(t.CShort(num_l))
                sign: t.CInt = 0
                if num_l < 0:
                    sign = 1
                    if num_l == (-9223372036854775807 - 1):
                        u_num: t.CUInt64T = t.CUInt64T(0x8000000000000000)
                    else:
                        u_num: t.CUInt64T = t.CUInt64T(-num_l)
                else:
                    u_num: t.CUInt64T = t.CUInt64T(num_l)
                    if show_sign: sign = 2
                    elif space_sign: sign = 3
                i: t.CInt = 0
                while True:
                    if i >= TEMP_BUF_SIZE - 1: break
                    temp[i] = t.CChar(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 += 1
                        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 += 1
                        pad_count -= 1
                while i > 0 and write_count < size - 1:
                    i -= 1
                    ptr[0] = temp[i]
                    write_count += 1
                    ptr += 1
                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 += 1
                        pad_count -= 1
            elif c.Deref(fmt) == 117:
                if is_long or is_long_long or is_size:
                    u_num_l: t.CUInt64T = va_arg(ap, t.CUInt64T)
                else:
                    u_num_l: t.CUInt64T = t.CUInt64T(t.CUnsignedInt(va_arg(ap)))
                i = 0
                while True:
                    if i >= TEMP_BUF_SIZE - 1: break
                    temp[i] = t.CChar(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 += 1
                        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 += 1
                        pad_count -= 1
                while i > 0 and write_count < size - 1:
                    i -= 1
                    ptr[0] = temp[i]
                    write_count += 1
                    ptr += 1
                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 += 1
                        pad_count -= 1
            elif c.Deref(fmt) == 120:
                if is_long or is_long_long or is_size:
                    u_num_l: t.CUInt64T = va_arg(ap, t.CUInt64T)
                else:
                    u_num_l: t.CUInt64T = t.CUInt64T(t.CUnsignedInt(va_arg(ap)))
                is_nonzero: t.CInt = 0
                if u_num_l != 0:
                    is_nonzero = 1
                i = 0
                while True:
                    if i >= TEMP_BUF_SIZE - 1: break
                    digit: t.CInt = t.CInt(u_num_l % 16)
                    if digit < 10:
                        temp[i] = t.CChar(digit + 48)
                    else:
                        temp[i] = t.CChar(digit - 10 + 97)
                    u_num_l //= 16
                    i += 1
                    if u_num_l <= 0: break
                digit_count: t.CInt = i
                prefix_len: t.CInt = 0
                if alt_form and is_nonzero:
                    prefix_len = 2
                effective_len: t.CInt = 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 += 1
                        pad_count -= 1
                if prefix_len > 0:
                    if write_count < size - 1:
                        ptr[0] = 48
                        write_count += 1
                        ptr += 1
                    if write_count < size - 1:
                        ptr[0] = 120
                        write_count += 1
                        ptr += 1
                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 += 1
                        pad_count -= 1
                while i > 0 and write_count < size - 1:
                    i -= 1
                    ptr[0] = temp[i]
                    write_count += 1
                    ptr += 1
                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 += 1
                        pad_count -= 1
            elif c.Deref(fmt) == 88:
                if is_long or is_long_long or is_size:
                    u_num_l: t.CUInt64T = va_arg(ap)
                else:
                    u_num_l: t.CUInt64T = t.CUInt64T(t.CUnsignedInt(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 = t.CInt(u_num_l % 16)
                    if digit < 10:
                        temp[i] = t.CChar(digit + 48)
                    else:
                        temp[i] = t.CChar(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 += 1
                        pad_count -= 1
                if prefix_len > 0:
                    if write_count < size - 1:
                        ptr[0] = 48
                        write_count += 1
                        ptr += 1
                    if write_count < size - 1:
                        ptr[0] = 88
                        write_count += 1
                        ptr += 1
                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 += 1
                        pad_count -= 1
                while i > 0 and write_count < size - 1:
                    i -= 1
                    ptr[0] = temp[i]
                    write_count += 1
                    ptr += 1
                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 += 1
                        pad_count -= 1
            elif c.Deref(fmt) == 111:
                if is_long or is_long_long or is_size:
                    u_num_l: t.CUInt64T = va_arg(ap, t.CUInt64T)
                else:
                    u_num_l: t.CUInt64T = t.CUInt64T(t.CUnsignedInt(va_arg(ap)))
                if is_char:
                    u_num_l = t.CUInt64T(t.CChar(u_num_l))
                elif is_short:
                    u_num_l = t.CUInt64T(t.CShort(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] = t.CChar(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 += 1
                        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 += 1
                        pad_count -= 1
                while i > 0 and write_count < size - 1:
                    i -= 1
                    ptr[0] = temp[i]
                    write_count += 1
                    ptr += 1
                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 += 1
                        pad_count -= 1
            elif c.Deref(fmt) == 98:
                if is_long or is_long_long or is_size:
                    u_num_l: t.CUInt64T = va_arg(ap, t.CUInt64T)
                else:
                    u_num_l: t.CUInt64T = t.CUInt64T(t.CUnsignedInt(va_arg(ap)))
                if is_char:
                    u_num_l = t.CUInt64T(t.CChar(u_num_l))
                elif is_short:
                    u_num_l = t.CUInt64T(t.CShort(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] = t.CChar(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 += 1
                        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 += 1
                        pad_count -= 1
                while i > 0 and write_count < size - 1:
                    i -= 1
                    ptr[0] = temp[i]
                    write_count += 1
                    ptr += 1
                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 += 1
                        pad_count -= 1
            elif c.Deref(fmt) == 112:
                ptr_val: t.CUInt64T = t.CUInt64T(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 = t.CInt(u_num_l % 16)
                        if digit < 10:
                            temp[i] = t.CChar(digit + 48)
                        else:
                            temp[i] = t.CChar(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 += 1
                        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 += 1
                        pad_count -= 1
                while i > 0 and write_count < size - 1:
                    i -= 1
                    ptr[0] = temp[i]
                    write_count += 1
                    ptr += 1
                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 += 1
                        pad_count -= 1
            elif c.Deref(fmt) == 102 or c.Deref(fmt) == 70:
                f_upper: t.CInt = 1 if c.Deref(fmt) == 70 else 0
                if precision < 0: precision = 6
                fv: t.CDouble = va_arg(ap, t.CDouble)
                f_sp: t.CInt = _check_special_float(fv)
                if f_sp != 0:
                    f_sgn_len: t.CInt = 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: t.CInt = f_sgn_len + 3
                    if not left_align and width > f_total_len:
                        f_pad: t.CInt = width - f_total_len
                        while f_pad > 0 and write_count < size - 1:
                            ptr[0] = 32
                            write_count += 1
                            ptr += 1
                            f_pad -= 1
                    if f_sp == 2:
                        if write_count < size - 1:
                            ptr[0] = 45
                            write_count += 1
                            ptr += 1
                    elif f_sp == 1 and show_sign:
                        if write_count < size - 1:
                            ptr[0] = 43
                            write_count += 1
                            ptr += 1
                    elif f_sp == 1 and space_sign:
                        if write_count < size - 1:
                            ptr[0] = 32
                            write_count += 1
                            ptr += 1
                    fi_c: t.CInt = 0
                    while fi_c < 3 and write_count < size - 1:
                        fc: t.CInt = 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] = t.CChar(fc)
                        write_count += 1
                        ptr += 1
                        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 += 1
                            f_pad -= 1
                    fmt += 1
                    continue
                if fv < 0.0:
                    if write_count < size - 1:
                        ptr[0] = 45
                        write_count += 1
                        ptr += 1
                    fv = 0.0 - fv
                elif show_sign:
                    if write_count < size - 1:
                        ptr[0] = 43
                        write_count += 1
                        ptr += 1
                elif space_sign:
                    if write_count < size - 1:
                        ptr[0] = 32
                        write_count += 1
                        ptr += 1
                di: t.CInt = 0
                work: t.CDouble = fv
                if work < 1.0:
                    temp[0] = 48
                    di = 1
                else:
                    scale: t.CDouble = 1.0
                    while work >= scale * 10.0:
                        scale *= 10.0
                    while scale >= 1.0 and di < TEMP_BUF_SIZE - 1:
                        d: t.CInt = t.CInt(work / scale)
                        if d > 9: d = 9
                        temp[di] = t.CChar(d + 48)
                        di += 1
                        work = work - t.CDouble(d) * scale
                        scale /= 10.0
                frac_val: t.CDouble = work
                p: t.CInt = 0
                while p < precision:
                    frac_val *= 10.0
                    p += 1
                frac_part: t.CUInt64T = t.CUInt64T(frac_val + 0.5)
                f_total: t.CInt = 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 += 1
                        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 += 1
                        pad_count -= 1
                while di > 0 and write_count < size - 1:
                    di -= 1
                    ptr[0] = temp[di]
                    write_count += 1
                    ptr += 1
                if precision > 0:
                    if write_count < size - 1:
                        ptr[0] = 46
                        write_count += 1
                        ptr += 1
                    fi: t.CInt = 0
                    while fi < precision and fi < TEMP_BUF_SIZE - 1:
                        temp[fi] = t.CChar(frac_part % 10 + 48)
                        fi += 1
                        frac_part //= 10
                    while fi < precision:
                        temp[fi] = 48
                        fi += 1
                    while fi > 0 and write_count < size - 1:
                        fi -= 1
                        ptr[0] = temp[fi]
                        write_count += 1
                        ptr += 1
                elif alt_form:
                    if write_count < size - 1:
                        ptr[0] = 46
                        write_count += 1
                        ptr += 1
                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 += 1
                        pad_count -= 1
            elif c.Deref(fmt) == 101 or c.Deref(fmt) == 69:
                if precision < 0: precision = 6
                fv: t.CDouble = va_arg(ap, t.CDouble)
                e_upper: t.CInt = 1 if c.Deref(fmt) == 69 else 0
                e_sp: t.CInt = _check_special_float(fv)
                if e_sp != 0:
                    e_sgn_len: t.CInt = 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: t.CInt = e_sgn_len + 3
                    if not left_align and width > e_total_len:
                        e_pad: t.CInt = width - e_total_len
                        while e_pad > 0 and write_count < size - 1:
                            ptr[0] = 32
                            write_count += 1
                            ptr += 1
                            e_pad -= 1
                    if e_sp == 2:
                        if write_count < size - 1:
                            ptr[0] = 45
                            write_count += 1
                            ptr += 1
                    elif e_sp == 1 and show_sign:
                        if write_count < size - 1:
                            ptr[0] = 43
                            write_count += 1
                            ptr += 1
                    elif e_sp == 1 and space_sign:
                        if write_count < size - 1:
                            ptr[0] = 32
                            write_count += 1
                            ptr += 1
                    ei_c: t.CInt = 0
                    while ei_c < 3 and write_count < size - 1:
                        ec: t.CInt = 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] = t.CChar(ec)
                        write_count += 1
                        ptr += 1
                        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 += 1
                            e_pad -= 1
                    fmt += 1
                    continue
                if fv < 0.0:
                    if write_count < size - 1:
                        ptr[0] = 45
                        write_count += 1
                        ptr += 1
                    fv = 0.0 - fv
                elif show_sign:
                    if write_count < size - 1:
                        ptr[0] = 43
                        write_count += 1
                        ptr += 1
                elif space_sign:
                    if write_count < size - 1:
                        ptr[0] = 32
                        write_count += 1
                        ptr += 1
                exp10: t.CInt = 0
                if fv != 0.0:
                    while fv >= 10.0:
                        fv /= 10.0
                        exp10 += 1
                    while fv < 1.0:
                        fv *= 10.0
                        exp10 -= 1
                int_digit: t.CInt = t.CInt(fv)
                if int_digit > 9: int_digit = 9
                if int_digit < 0: int_digit = 0
                frac_v: t.CDouble = fv - t.CDouble(int_digit)
                p: t.CInt = 0
                while p < precision:
                    frac_v *= 10.0
                    p += 1
                frac_p: t.CUInt64T = t.CUInt64T(frac_v + 0.5)
                carry: t.CUInt64T = 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: t.CInt = 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 += 1
                        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 += 1
                        pad_count -= 1
                if write_count < size - 1:
                    ptr[0] = t.CChar(int_digit + 48)
                    write_count += 1
                    ptr += 1
                if precision > 0:
                    if write_count < size - 1:
                        ptr[0] = 46
                        write_count += 1
                        ptr += 1
                    fi: t.CInt = 0
                    while fi < precision and fi < TEMP_BUF_SIZE - 1:
                        temp[fi] = t.CChar(frac_p % 10 + 48)
                        fi += 1
                        frac_p //= 10
                    while fi < precision:
                        temp[fi] = 48
                        fi += 1
                    while fi > 0 and write_count < size - 1:
                        fi -= 1
                        ptr[0] = temp[fi]
                        write_count += 1
                        ptr += 1
                elif alt_form:
                    if write_count < size - 1:
                        ptr[0] = 46
                        write_count += 1
                        ptr += 1
                if write_count < size - 1:
                    ptr[0] = 101 if e_upper == 0 else 69
                    write_count += 1
                    ptr += 1
                if write_count < size - 1:
                    ptr[0] = 45 if exp10 < 0 else 43
                    write_count += 1
                    ptr += 1
                exp_abs: t.CUInt64T = t.CUInt64T(exp10) if exp10 >= 0 else t.CUInt64T(0 - exp10)
                ei: t.CInt = 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] = t.CChar(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 += 1
                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 += 1
                        pad_count -= 1
            elif c.Deref(fmt) == 103 or c.Deref(fmt) == 71:
                if precision < 0: precision = 6
                if precision == 0: precision = 1
                fv: t.CDouble = va_arg(ap, t.CDouble)
                g_upper: t.CInt = 1 if c.Deref(fmt) == 71 else 0
                g_sp: t.CInt = _check_special_float(fv)
                if g_sp != 0:
                    g_sgn_len: t.CInt = 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: t.CInt = g_sgn_len + 3
                    if not left_align and width > g_total_len:
                        g_pad: t.CInt = width - g_total_len
                        while g_pad > 0 and write_count < size - 1:
                            ptr[0] = 32
                            write_count += 1
                            ptr += 1
                            g_pad -= 1
                    if g_sp == 2:
                        if write_count < size - 1:
                            ptr[0] = 45
                            write_count += 1
                            ptr += 1
                    elif g_sp == 1 and show_sign:
                        if write_count < size - 1:
                            ptr[0] = 43
                            write_count += 1
                            ptr += 1
                    elif g_sp == 1 and space_sign:
                        if write_count < size - 1:
                            ptr[0] = 32
                            write_count += 1
                            ptr += 1
                    gi_c: t.CInt = 0
                    while gi_c < 3 and write_count < size - 1:
                        gc: t.CInt = 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] = t.CChar(gc)
                        write_count += 1
                        ptr += 1
                        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 += 1
                            g_pad -= 1
                    fmt += 1
                    continue
                if fv < 0.0:
                    if write_count < size - 1:
                        ptr[0] = 45
                        write_count += 1
                        ptr += 1
                    fv = 0.0 - fv
                elif show_sign:
                    if write_count < size - 1:
                        ptr[0] = 43
                        write_count += 1
                        ptr += 1
                elif space_sign:
                    if write_count < size - 1:
                        ptr[0] = 32
                        write_count += 1
                        ptr += 1
                fv_orig: t.CDouble = fv
                exp10: t.CInt = 0
                if fv != 0.0:
                    while fv >= 10.0:
                        fv /= 10.0
                        exp10 += 1
                    while fv < 1.0:
                        fv *= 10.0
                        exp10 -= 1
                g_use_e: t.CInt = 0
                if exp10 < -4 or exp10 >= precision:
                    g_use_e = 1
                g_len: t.CInt = 0
                if g_use_e:
                    int_digit: t.CInt = t.CInt(fv)
                    if int_digit > 9: int_digit = 9
                    if int_digit < 0: int_digit = 0
                    frac_v: t.CDouble = fv - t.CDouble(int_digit)
                    prec_e: t.CInt = precision - 1
                    p: t.CInt = 0
                    while p < prec_e:
                        frac_v *= 10.0
                        p += 1
                    frac_p: t.CUInt64T = t.CUInt64T(frac_v + 0.5)
                    carry: t.CUInt64T = 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] = t.CChar(int_digit + 48)
                    g_len = 1
                    if prec_e > 0:
                        temp[1] = 46
                        g_len = 2
                        fi: t.CInt = 0
                        while fi < prec_e and g_len < TEMP_BUF_SIZE - 1:
                            temp[g_len] = t.CChar(frac_p % 10 + 48)
                            g_len += 1
                            frac_p //= 10
                        lo: t.CInt = 2
                        hi: t.CInt = g_len - 1
                        while lo < hi:
                            tc: t.CChar = temp[lo]
                            temp[lo] = temp[hi]
                            temp[hi] = tc
                            lo += 1
                            hi -= 1
                else:
                    prec_f: t.CInt = precision - 1 - exp10
                    if prec_f < 0: prec_f = 0
                    work: t.CDouble = fv_orig
                    if work < 1.0:
                        temp[0] = 48
                        g_len = 1
                    else:
                        scale: t.CDouble = 1.0
                        while work >= scale * 10.0:
                            scale *= 10.0
                        while scale >= 1.0 and g_len < TEMP_BUF_SIZE - 1:
                            d: t.CInt = t.CInt(work / scale)
                            if d > 9: d = 9
                            temp[g_len] = t.CChar(d + 48)
                            g_len += 1
                            work = work - t.CDouble(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: t.CDouble = work
                        p = 0
                        while p < prec_f:
                            frac_val *= 10.0
                            p += 1
                        frac_part: t.CUInt64T = t.CUInt64T(frac_val + 0.5)
                        fi = 0
                        while fi < prec_f and g_len < TEMP_BUF_SIZE - 1:
                            temp[g_len] = t.CChar(frac_part % 10 + 48)
                            g_len += 1
                            frac_part //= 10
                        lo = g_len - prec_f
                        hi = g_len - 1
                        while lo < hi:
                            tc = temp[lo]
                            temp[lo] = temp[hi]
                            temp[hi] = tc
                            lo += 1
                            hi -= 1
                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: t.CInt = 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 += 1
                        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 += 1
                        pad_count -= 1
                gi: t.CInt = 0
                while gi < g_len and write_count < size - 1:
                    ptr[0] = temp[gi]
                    write_count += 1
                    ptr += 1
                    gi += 1
                if g_use_e:
                    if write_count < size - 1:
                        ptr[0] = 101 if g_upper == 0 else 69
                        write_count += 1
                        ptr += 1
                    if write_count < size - 1:
                        ptr[0] = 45 if exp10 < 0 else 43
                        write_count += 1
                        ptr += 1
                    exp_abs: t.CUInt64T = t.CUInt64T(exp10) if exp10 >= 0 else t.CUInt64T(0 - exp10)
                    ei: t.CInt = 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] = t.CChar(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 += 1
                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 += 1
                        pad_count -= 1
            elif c.Deref(fmt) == 97 or c.Deref(fmt) == 65:
                a_upper: t.CInt = 1 if c.Deref(fmt) == 65 else 0
                fv: t.CDouble = va_arg(ap, t.CDouble)
                a_sp: t.CInt = _check_special_float(fv)
                if a_sp != 0:
                    a_sgn_len: t.CInt = 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: t.CInt = a_sgn_len + 3
                    if not left_align and width > a_total_len:
                        a_pad: t.CInt = width - a_total_len
                        while a_pad > 0 and write_count < size - 1:
                            ptr[0] = 32
                            write_count += 1
                            ptr += 1
                            a_pad -= 1
                    if a_sp == 2:
                        if write_count < size - 1:
                            ptr[0] = 45
                            write_count += 1
                            ptr += 1
                    elif a_sp == 1 and show_sign:
                        if write_count < size - 1:
                            ptr[0] = 43
                            write_count += 1
                            ptr += 1
                    elif a_sp == 1 and space_sign:
                        if write_count < size - 1:
                            ptr[0] = 32
                            write_count += 1
                            ptr += 1
                    ai_c: t.CInt = 0
                    while ai_c < 3 and write_count < size - 1:
                        ac: t.CInt = 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] = t.CChar(ac)
                        write_count += 1
                        ptr += 1
                        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 += 1
                            a_pad -= 1
                    fmt += 1
                    continue
                fbits: t.CUInt64T = 0
                c.Load(c.Addr(fbits), c.Addr(fv))
                a_neg: t.CInt = 1 if (fbits >> 63) != 0 else 0
                a_exp: t.CInt = t.CInt((fbits >> 52) & 0x7FF)
                a_frac: t.CUInt64T = fbits & 0x000FFFFFFFFFFFFF
                a_leading: t.CInt = 0
                a_binexp: t.CInt = 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: t.CInt = precision
                if a_prec < 0:
                    a_prec = 13
                if a_prec > 50:
                    a_prec = 50
                a_hi: t.CInt = 0
                while a_hi < 13 and a_hi < a_prec:
                    a_digit: t.CInt = t.CInt((a_frac >> (48 - 4 * a_hi)) & 0xF)
                    if a_digit < 10:
                        temp[a_hi] = t.CChar(a_digit + 48)
                    else:
                        if a_upper:
                            temp[a_hi] = t.CChar(a_digit - 10 + 65)
                        else:
                            temp[a_hi] = t.CChar(a_digit - 10 + 97)
                    a_hi += 1
                while a_hi < a_prec:
                    temp[a_hi] = 48
                    a_hi += 1
                a_hd_count: t.CInt = a_prec
                if precision < 0:
                    while a_hd_count > 0 and temp[a_hd_count - 1] == 48:
                        a_hd_count -= 1
                a_has_dot: t.CInt = 0
                if a_hd_count > 0:
                    a_has_dot = 1
                elif alt_form:
                    a_has_dot = 1
                a_eb: t.CInt = a_binexp
                a_esign: t.CInt = 0
                if a_binexp < 0:
                    a_esign = 1
                    a_eb = -a_binexp
                a_ei: t.CInt = 0
                if a_eb == 0:
                    temp[60] = 48
                    a_ei = 1
                else:
                    while a_eb > 0 and a_ei < 7:
                        temp[60 + a_ei] = t.CChar(a_eb % 10 + 48)
                        a_ei += 1
                        a_eb //= 10
                a_ecount: t.CInt = a_ei
                a_sign_len: t.CInt = 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: t.CInt = 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 += 1
                        a_pad -= 1
                if a_neg:
                    if write_count < size - 1:
                        ptr[0] = 45
                        write_count += 1
                        ptr += 1
                elif show_sign:
                    if write_count < size - 1:
                        ptr[0] = 43
                        write_count += 1
                        ptr += 1
                elif space_sign:
                    if write_count < size - 1:
                        ptr[0] = 32
                        write_count += 1
                        ptr += 1
                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 += 1
                        a_pad -= 1
                if write_count < size - 1:
                    ptr[0] = 48
                    write_count += 1
                    ptr += 1
                if write_count < size - 1:
                    if a_upper:
                        ptr[0] = 88
                    else:
                        ptr[0] = 120
                    write_count += 1
                    ptr += 1
                if write_count < size - 1:
                    ptr[0] = t.CChar(a_leading + 48)
                    write_count += 1
                    ptr += 1
                if a_has_dot:
                    if write_count < size - 1:
                        ptr[0] = 46
                        write_count += 1
                        ptr += 1
                    a_hj: t.CInt = 0
                    while a_hj < a_hd_count and write_count < size - 1:
                        ptr[0] = temp[a_hj]
                        write_count += 1
                        ptr += 1
                        a_hj += 1
                if write_count < size - 1:
                    if a_upper:
                        ptr[0] = 80
                    else:
                        ptr[0] = 112
                    write_count += 1
                    ptr += 1
                if write_count < size - 1:
                    if a_esign:
                        ptr[0] = 45
                    else:
                        ptr[0] = 43
                    write_count += 1
                    ptr += 1
                a_ek: t.CInt = a_ecount
                while a_ek > 0 and write_count < size - 1:
                    a_ek -= 1
                    ptr[0] = temp[60 + a_ek]
                    write_count += 1
                    ptr += 1
                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 += 1
                        a_pad -= 1
            elif c.Deref(fmt) == 110:
                if is_long_long or is_long:
                    np: t.CInt64T | t.CPtr = va_arg(ap, t.CInt64T | t.CPtr)
                    if np != None:
                        np[0] = t.CInt64T(write_count)
                elif is_short:
                    sp: t.CShort | t.CPtr = va_arg(ap, t.CShort | t.CPtr)
                    if sp != None:
                        sp[0] = t.CShort(write_count)
                elif is_char:
                    cp: t.CChar | t.CPtr = va_arg(ap, t.CChar | t.CPtr)
                    if cp != None:
                        cp[0] = t.CChar(write_count)
                else:
                    ip: t.CInt | t.CPtr = va_arg(ap, t.CInt | t.CPtr)
                    if ip != None:
                        ip[0] = write_count
            elif c.Deref(fmt) == 37:
                if write_count < size - 1:
                    ptr[0] = 37
                    write_count += 1
                    ptr += 1
            else:
                if write_count < size - 1:
                    ptr[0] = c.Deref(fmt)
                    write_count += 1
                    ptr += 1
            fmt += 1
    ptr[0] = 0
    return write_count
