Files
TransPyC/includes/viperlib.py
2026-06-16 16:09:42 +08:00

373 lines
14 KiB
Python

import t, c
import viperio
from stdarg import arg
TEMP_BUF_SIZE: t.CDefine = 24
def get_digit_count(num: t.CUnsignedInt, base: t.CInt) -> t.CStatic | t.CInt | t.State:
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.State:
if buf == None or rule == None: return
snprintf(buf, 0, rule, 0)
def vsprintf(buf: t.CChar | t.CPtr, rule: str, *args) -> t.CInt | t.State:
if buf == None or rule == None: return 0
return snprintf(buf, 0, rule, 0)
def snprintf(buf: t.CChar | t.CPtr, size: t.CSizeT, fmt: str, *args) -> t.CInt | t.State:
if buf == None or fmt == None or size == 0: return 0
ptr: t.CChar | t.CPtr = buf
write_count: t.CInt = 0
temp: list[t.CChar, 24]
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
precision: t.CInt = -1
is_long: t.CInt = 0
is_long_long: t.CInt = 0
is_size: 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
else: break
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) == 122:
is_size = 1
fmt += 1
if c.Deref(fmt) == 99:
if write_count < size - 1:
ptr_i: t.CInt = arg()
ptr[0] = t.CChar(ptr_i)
write_count += 1
ptr += 1
else:
ptr_i: t.CInt = arg()
elif c.Deref(fmt) == 115:
s: str = arg()
if s == 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:
if is_long or is_long_long or is_size:
num: t.CInt = t.CInt(arg())
else:
num: t.CInt = arg()
sign: t.CInt = 0
if num < 0:
sign = 1
if num == -2147483648:
u_num: t.CUnsignedInt = 2147483648
else:
u_num: t.CUnsignedInt = t.CUnsignedInt(-num)
else:
u_num: t.CUnsignedInt = t.CUnsignedInt(num)
if show_sign: sign = 2
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
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 = arg(t.CUInt64T)
else:
u_num_l: t.CUInt64T = t.CUInt64T(t.CUnsignedInt(arg()))
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 = arg(t.CUInt64T)
else:
u_num_l: t.CUInt64T = t.CUInt64T(t.CUnsignedInt(arg()))
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
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) == 88:
if is_long or is_long_long or is_size:
u_num_l: t.CUInt64T = arg()
else:
u_num_l: t.CUInt64T = t.CUInt64T(t.CUnsignedInt(arg()))
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
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:
if precision < 0: precision = 6
fv: float = arg()
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
di: t.CInt = 0
int_part: t.CUnsignedLong = t.CUnsignedLong(t.CLongLong(fv))
frac_val: float = fv - float(int_part)
p: t.CInt = 0
while p < precision:
frac_val *= 10.0
p += 1
frac_part: t.CUnsignedLong = t.CUnsignedLong(frac_val + 0.5)
if int_part == 0:
temp[0] = 48
di = 1
else:
while int_part > 0 and di < TEMP_BUF_SIZE - 1:
temp[di] = t.CChar(int_part % 10 + 48)
di += 1
int_part //= 10
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 > 0 and write_count < size - 1:
fi -= 1
ptr[0] = temp[fi]
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) == 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