from stdint import *
import t, c


# 字符串复制函数
def strcpy(dest: str, src: str) -> str:
    if dest == None or src == None: return None
    original_dest: str = dest
    for s in src:
        dest[0] = s
        dest += 1
    dest[0] = 0
    return original_dest


# 字符串拼接函数: 将 src 追加到 dest 末尾
def strcat(dest: str, src: str) -> str:
    if dest == None or src == None: return dest
    original_dest: str = dest
    # 找到 dest 末尾
    while dest[0] != '\0':
        dest += 1
    # 复制 src
    for s in src:
        dest[0] = s
        dest += 1
    dest[0] = 0
    return original_dest


# 有限长度字符串复制函数
def strncpy(dest: str, src: str, n: t.CSizeT) -> str:
    if dest == None or src == None or n == 0: return dest
    original_dest: str = dest
    i: t.CSizeT = 0
    for s in src:
        if i >= n: break
        dest[0] = s
        dest += 1
        i += 1
    # 填充剩余空间为 '\0'
    for i in range(n):
        dest[0] = 0
        dest += 1
    return original_dest


# 字符串长度函数
def strlen(src: str) -> t.CSizeT | t.CExport:
    length: t.CSizeT = 0
    for _ in src:
        length += 1
    return length

# 字符串比较函数
def strcmp(str1: str, str2: str) -> t.CInt:
    while str1[0] != '\0' and str2[0] != '\0':
        if str1[0] != str2[0]:
            return str1[0] - str2[0]
        str1 += 1
        str2 += 1
    return str1[0] - str2[0]

def samestr(str1: str, str2: str) -> bool:
    return str1 == str2


# 有限长度字符串比较函数
def strncmp(str1: str, str2: str, n: t.CSizeT) -> t.CInt:
    i: t.CSizeT = 0
    while str1[0] != '\0' and str2[0] != '\0' and i < n:
        if str1[0] != str2[0]:
            return str1[0] - str2[0]
        str1 += 1
        str2 += 1
        i += 1
    if i < n:
        return str1[0] - str2[0]
    return 0


# 内存比较函数
def memcmp(ptr1: t.CVoid | t.CPtr, ptr2: t.CVoid | t.CPtr, n: t.CSizeT) -> t.CInt:
    p1: BYTEPTR = BYTEPTR(ptr1)
    p2: BYTEPTR = BYTEPTR(ptr2)
    i: t.CSizeT = 0
    while i < n:
        if p1[i] != p2[i]:
            return t.CInt(p1[i]) - t.CInt(p2[i])
        i += 1
    return 0


# 字符串查找函数
def strchr(s: str, cr: t.CInt) -> str:
    while s[0] != '\0':
        if s[0] == t.CChar(cr):
            return str(s)
        s += 1
    if cr == '\0':
        return str(s)
    return None

# 字符串反向查找函数（找最后一次出现的字符）
def strrchr(s: str, cr: t.CInt) -> str:
    last: str = None
    while s[0] != '\0':
        if s[0] == t.CChar(cr):
            last = s
        s += 1
    if cr == '\0': return s
    return last


# 子串查找函数（在 s 中查找 needle 第一次出现的位置，返回指向该位置的指针，未找到返回 None）
def strstr(s: str, needle: str) -> str:
    if needle[0] == 0:
        return s
    needle_len: t.CSizeT = strlen(needle)
    if needle_len == 0:
        return s
    i: t.CSizeT = 0
    s_len: t.CSizeT = strlen(s)
    while i + needle_len <= s_len:
        if strncmp(s + i, needle, needle_len) == 0:
            return s + i
        i += 1
    return None

# 跳过字符
def strspn(s: str, skip: str = " ") -> int:
    si: int = 0
    while s[si] != 0:
        found: int = 0
        sj: int = 0
        while skip[sj] != 0:
            if s[si] == skip[sj]:
                found = 1
                break
            sj += 1
        if found == 0:
            break
        si += 1
    return si

# 内存设置函数
def memset(ptr: t.CVoid | t.CPtr, value: t.CInt, num: t.CSizeT) -> t.CVoid | t.CPtr | t.CExport:
    # 原始实现:
    # p: BYTEPTR = BYTEPTR(ptr)
    # i: t.CSizeT
    # for i in range(num):
    #     p[i] = t.CUnsignedChar(value)
    if num == 0: return ptr
    c.Asm(f"""mov rdi, {c.AsmInp(ptr, t.ASM_DESCR.REG_ANY)}
              mov eax, {c.AsmInp(value, t.ASM_DESCR.REG_ANY)}
              mov rcx, {c.AsmInp(num, t.ASM_DESCR.REG_ANY)}
              rep stosb""",
          op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
              t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDI])
    return ptr


def memset32(ptr: t.CVoid | t.CPtr, value: t.CUInt32T, count: t.CSizeT) -> t.CVoid | t.CPtr:
    # 原始实现:
    # p: UINT32PTR = UINT32PTR(ptr)
    # i: t.CSizeT
    # for i in range(count):
    #     p[i] = value
    if count == 0: return ptr
    c.Asm(f"""mov rdi, {c.AsmInp(ptr, t.ASM_DESCR.REG_ANY)}
              mov eax, {c.AsmInp(value, t.ASM_DESCR.REG_ANY)}
              mov rcx, {c.AsmInp(count, t.ASM_DESCR.REG_ANY)}
              rep stosd""",
          op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
              t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDI])
    return ptr


# 内存复制函数
def memcpy(dest: t.CVoid | t.CPtr, src: t.CVoid | t.CPtr, num: t.CSizeT) -> t.CVoid | t.CPtr | t.CExport:
    # 原始实现:
    # d: BYTEPTR = BYTEPTR(dest)
    # s: BYTEPTR = BYTEPTR(src)
    # i: t.CSizeT
    # for i in range(num):
    #     d[i] = s[i]
    if num == 0: return dest
    c.Asm(f"""mov rdi, {c.AsmInp(dest, t.ASM_DESCR.REG_ANY)}
              mov rsi, {c.AsmInp(src, t.ASM_DESCR.REG_ANY)}
              mov rcx, {c.AsmInp(num, t.ASM_DESCR.REG_ANY)}
              rep movsb""",
          op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RCX,
              t.ASM_DESCR.CLOBBER_RDI, t.ASM_DESCR.CLOBBER_RSI])
    return dest


# 内存移动函数
def memmove(dest: t.CVoid | t.CPtr, src: t.CVoid | t.CPtr, num: t.CSizeT) -> t.CVoid | t.CPtr:
    # 原始实现:
    # d: BYTEPTR = BYTEPTR(dest)
    # s: BYTEPTR = BYTEPTR(src)
    # i: t.CSizeT
    # if d < s:
    #     for i in range(num):
    #         d[i] = s[i]
    # elif d > s:
    #     for i in range(num, 0, -1):
    #         d[i - 1] = s[i - 1]
    if num == 0: return dest
    c.Asm(f"""mov rdi, {c.AsmInp(dest, t.ASM_DESCR.REG_ANY)}
              mov rsi, {c.AsmInp(src, t.ASM_DESCR.REG_ANY)}
              mov rcx, {c.AsmInp(num, t.ASM_DESCR.REG_ANY)}
              cmp rdi, rsi
              jb 2f
              std
              add rdi, rcx
              dec rdi
              add rsi, rcx
              dec rsi
              rep movsb
              cld
              jmp 3f
              2:
              rep movsb
              3:""",
          op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RCX,
              t.ASM_DESCR.CLOBBER_RDI, t.ASM_DESCR.CLOBBER_RSI])
    return dest


def atoi(src: str) -> t.CInt:
    num: t.CInt = 0
    sign: t.CInt = 1
    s: str = src
    if s == None: return 0
    # 跳过空白
    while s[0] == ' ' or s[0] == '\t' or s[0] == '\n' or s[0] == '\r':
        s += 1
    # 符号
    if s[0] == '-':
        sign = -1
        s += 1
    elif s[0] == '+':
        s += 1
    for ch in s:
        if ch < '0' or ch > '9': break
        digit: t.CInt = ch - '0'
        num = num * 10 + digit
    return num * sign


def atoll(src: str) -> t.CInt64T:
    num: t.CInt64T = 0
    sign: t.CInt64T = 1
    s: str = src
    if s == None: return 0
    while s[0] == ' ' or s[0] == '\t' or s[0] == '\n' or s[0] == '\r':
        s += 1
    if s[0] == '-':
        sign = -1
        s += 1
    elif s[0] == '+':
        s += 1
    for ch in s:
        if ch < '0' or ch > '9': break
        d: t.CInt = ch - '0'
        digit: t.CInt64T = t.CInt64T(d)
        num = num * 10 + digit
    return num * sign


def atof(src: str) -> t.CDouble:
    s: str = src
    if s == None: return 0.0
    # 跳过空白
    while s[0] == ' ' or s[0] == '\t' or s[0] == '\n' or s[0] == '\r':
        s += 1
    # 符号
    sign: t.CDouble = 1.0
    if s[0] == '-':
        sign = -1.0
        s += 1
    elif s[0] == '+':
        s += 1
    # 整数部分
    int_part: t.CDouble = 0.0
    for ch in s:
        if ch < '0' or ch > '9': break
        d1: t.CInt = ch - '0'
        int_part = int_part * 10.0 + t.CDouble(d1)
        s += 1
    # 小数部分
    frac_part: t.CDouble = 0.0
    frac_div: t.CDouble = 1.0
    if s[0] == '.':
        s += 1
        for ch in s:
            if ch < '0' or ch > '9': break
            d2: t.CInt = ch - '0'
            frac_div = frac_div * 10.0
            frac_part = frac_part * 10.0 + t.CDouble(d2)
            s += 1
    # 指数部分
    exp: t.CInt = 0
    exp_sign: t.CInt = 1
    if s[0] == 'e' or s[0] == 'E':
        s += 1
        if s[0] == '-':
            exp_sign = -1
            s += 1
        elif s[0] == '+':
            s += 1
        for ch in s:
            if ch < '0' or ch > '9': break
            d3: t.CInt = ch - '0'
            exp = exp * 10 + d3
            s += 1
        exp = exp * exp_sign
    result: t.CDouble = sign * (int_part + frac_part / frac_div)
    # 应用指数
    if exp > 0:
        while exp > 0:
            result = result * 10.0
            exp -= 1
    elif exp < 0:
        while exp < 0:
            result = result / 10.0
            exp += 1
    return result

def split(s: str, delim: str, result: t.CArray[str]) -> int:
    count: int = 0
    start: str = s
    if not s or not delim or not result:
        return 0
    d: t.CChar = delim[0] # 单分隔符

    while start[0]:
        # 跳过分隔符
        while start[0] == d: start += 1
        if not start[0]: break

        # 记录token起始
        result[count] = start
        count += 1

        # 找到下一个分隔符，截断
        while start[0] and start[0] != d: start += 1
        if start[0]:
            start[0] = '\0'
            start += 1
    result[count] = None # 结尾标记
    return count


ascii_lowercase: str = "abcdefghijklmnopqrstuvwxyz"
ascii_uppercase: str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
ascii_letters: str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

digits: str = "0123456789"
hexdigits: str = "0123456789abcdefABCDEF"
octdigits: str = "01234567"
punctuation: str = "!\"#$%&'()*+,-./:;<=>?@[]^_`{|}~"
whitespace: str = " \t\n\r\f\v"
printable: str = "01234567890123456789abcdefABCDEF01234567!\"#$%&'()*+,-./:;<=>?@[]^_`{|}~ \t\n\r\f\v"
