R14:rawptr[X] -> X*(41 文件 / 2037 行改动),X 含模块限定名与嵌套下标(rawptr[GSList[NameEntry]] -> GSList[NameEntry]*)。保留 6 处 rawptr[t.CPtr](规范例外:存纯裸指针);# 注释与字符串里的 rawptr[...] 属元语法描述,未动。 R16(保守子集):t.CConst | str/bytes -> const str/bytes,t.CConst | char | t.CPtr -> const str;typedef 右值位置豁免(const str 在该处无法注册,与 R1 同源)。 验证:TPC 自举三重重编 SUCCESS;TransPyV.exe 全量 77/77 顺序回归通过。
235 lines
9.6 KiB
Plaintext
235 lines
9.6 KiB
Plaintext
import t, c
|
||
from stdint import *
|
||
|
||
|
||
# =============================================================================
|
||
# POSIX Type Alias
|
||
# Note: ssize_t has already been defined as t.CPtrDiffT in stdint.py, so we won’t repeat it here.
|
||
# =============================================================================
|
||
DIR: t.CTypedef = t.CPtr # Opaque directory stream handle
|
||
mode_t: t.CTypedef = uint32 # File mode/permission bits
|
||
pid_t: t.CTypedef = int32 # Process ID
|
||
off_t: t.CTypedef = int64 # File offset (Linux x86_64)
|
||
dev_t: t.CTypedef = uint64 # Device number
|
||
ino_t: t.CTypedef = uint64 # inode number
|
||
nlink_t: t.CTypedef = uint64 # Hard link count
|
||
uid_t: t.CTypedef = uint32 # User ID
|
||
gid_t: t.CTypedef = uint32 # Group ID
|
||
blksize_t: t.CTypedef = int64 # File I/O block size
|
||
blkcnt_t: t.CTypedef = int64 # Allocated block count
|
||
time_t: t.CTypedef = int64 # Calendar time seconds
|
||
|
||
|
||
# =============================================================================
|
||
# open() Flags
|
||
# =============================================================================
|
||
define O_RDONLY = 0
|
||
define O_WRONLY = 1
|
||
define O_RDWR = 2
|
||
define O_CREAT = 0o100
|
||
define O_EXCL = 0o200
|
||
define O_TRUNC = 0o1000
|
||
define O_APPEND = 0o2000
|
||
define O_NONBLOCK = 0o4000
|
||
define O_CLOEXEC = 0o2000000
|
||
|
||
|
||
# =============================================================================
|
||
# access() Test Flags
|
||
# =============================================================================
|
||
define F_OK = 0 # File exists
|
||
define R_OK = 4 # Read permission
|
||
define W_OK = 2 # Write permission
|
||
define X_OK = 1 # Execute permission
|
||
|
||
|
||
# =============================================================================
|
||
# stat struct st_mode Mask and Type Bits
|
||
# =============================================================================
|
||
define S_IFMT = 0o170000 # Type mask bits
|
||
define S_IFSOCK = 0o140000 # Socket
|
||
define S_IFLNK = 0o120000 # Symbolic link
|
||
define S_IFREG = 0o100000 # Regular file
|
||
define S_IFBLK = 0o060000 # Block device
|
||
define S_IFDIR = 0o040000 # Directory
|
||
define S_IFCHR = 0o020000 # Character device
|
||
define S_IFIFO = 0o010000 # FIFO/pipe
|
||
|
||
# Permission Bits
|
||
define S_ISUID = 0o4000 # Set-user-ID
|
||
define S_ISGID = 0o2000 # Set-group-ID
|
||
define S_ISVTX = 0o1000 # Sticky bit
|
||
define S_IRWXU = 0o700 # Read/write/execute permission
|
||
define S_IRUSR = 0o400 # User read permission
|
||
define S_IWUSR = 0o200 # User write permission
|
||
define S_IXUSR = 0o100 # User execute permission
|
||
define S_IRWXG = 0o070 # Read/write/execute permission
|
||
define S_IRGRP = 0o040 # Read permission
|
||
define S_IWGRP = 0o020 # Write
|
||
define S_IXGRP = 0o010 # Execute
|
||
define S_IRWXO = 0o007 # Read/write/execute permission
|
||
define S_IROTH = 0o004 # Other read permission
|
||
define S_IWOTH = 0o002 # Other write permission
|
||
define S_IXOTH = 0o001 # Other execute permission
|
||
|
||
|
||
# =============================================================================
|
||
# lseek() whence values
|
||
# =============================================================================
|
||
define SEEK_SET = 0
|
||
define SEEK_CUR = 1
|
||
define SEEK_END = 2
|
||
|
||
|
||
# =============================================================================
|
||
# Path/name length limits
|
||
# =============================================================================
|
||
define PATH_MAX = 4096
|
||
define NAME_MAX = 255
|
||
|
||
|
||
# =============================================================================
|
||
# sysconf() parameters
|
||
# =============================================================================
|
||
define _SC_NPROCESSORS_ONLN = 84
|
||
define _SC_PAGESIZE = 30
|
||
define _SC_CLK_TCK = 2
|
||
|
||
|
||
# =============================================================================
|
||
# dirent struct d_type values
|
||
# =============================================================================
|
||
define DT_UNKNOWN = 0
|
||
define DT_FIFO = 1
|
||
define DT_CHR = 2
|
||
define DT_DIR = 4
|
||
define DT_BLK = 6
|
||
define DT_REG = 8
|
||
define DT_LNK = 10
|
||
define DT_SOCK = 12
|
||
define DT_WHT = 14
|
||
|
||
|
||
# =============================================================================
|
||
# waitpid() options
|
||
# =============================================================================
|
||
define WNOHANG = 1
|
||
define WUNTRACED = 2
|
||
define WCONTINUED = 8
|
||
|
||
|
||
# =============================================================================
|
||
# Struct: Linux x86_64 Layout
|
||
# =============================================================================
|
||
|
||
# struct stat (144 bytes, Linux x86_64 glibc layout)
|
||
# Note: st_atim/st_mtim/st_ctim in C are struct timespec { tv_sec; tv_nsec; }
|
||
# Here split into _sec/_nsec two LONGLONG fields to maintain binary compatibility
|
||
class Stat:
|
||
st_dev: dev_t # @ 0
|
||
st_ino: ino_t # @ 8
|
||
st_nlink: nlink_t # @ 16
|
||
st_mode: mode_t # @ 24
|
||
st_uid: uid_t # @ 28
|
||
st_gid: gid_t # @ 32
|
||
__pad0: INT # @ 36
|
||
st_rdev: dev_t # @ 40
|
||
st_size: off_t # @ 48
|
||
st_blksize: blksize_t # @ 56
|
||
st_blocks: blkcnt_t # @ 64
|
||
st_atim_sec: time_t # @ 72
|
||
st_atim_nsec: LONGLONG # @ 80
|
||
st_mtim_sec: time_t # @ 88
|
||
st_mtim_nsec: LONGLONG # @ 96
|
||
st_ctim_sec: time_t # @ 104
|
||
st_ctim_nsec: LONGLONG # @ 112
|
||
__unused0: LONGLONG # @ 120
|
||
__unused1: LONGLONG # @ 128
|
||
__unused2: LONGLONG # @ 136
|
||
|
||
|
||
# struct dirent (Linux x86_64, d_name is char[256])
|
||
# Note: d_name is actually a fixed-length char[256], TransPyC uses CHARPTR as a placeholder (8 bytes).
|
||
# Users usually access it via the read-only pointer returned by readdir, not by directly allocating a Dirent structure.
|
||
class Dirent():
|
||
d_ino: ino_t # @ 0
|
||
d_off: off_t # @ 8
|
||
d_reclen: USHORT # @ 16
|
||
d_type: BYTE # @ 18
|
||
d_name: CHARPTR # @ 19 (actually char[256], this is a placeholder)
|
||
|
||
|
||
# =============================================================================
|
||
# File operations (10)
|
||
# =============================================================================
|
||
extern def open(path: const str, oflag: INT, *args) -> INT
|
||
extern def close(fd: INT) -> INT
|
||
extern def read(fd: INT, buf: bytes, count: sizet) -> ssize_t
|
||
extern def write(fd: INT, buf: const bytes, count: sizet) -> ssize_t
|
||
extern def lseek(fd: INT, offset: off_t, whence: INT) -> off_t
|
||
extern def unlink(path: const str) -> INT
|
||
extern def access(path: const str, amode: INT) -> INT
|
||
extern def realpath(path: const str, resolved: CHARPTR) -> CHARPTR
|
||
extern def rename(oldpath: const str, newpath: const str) -> INT
|
||
extern def chmod(path: const str, mode: mode_t) -> INT
|
||
|
||
# =============================================================================
|
||
# stat series (2)
|
||
# =============================================================================
|
||
extern def stat(path: const str, buf: Stat*) -> INT
|
||
extern def fstat(fd: INT, buf: Stat*) -> INT
|
||
|
||
|
||
# =============================================================================
|
||
# Directory operations (6)
|
||
# =============================================================================
|
||
extern def opendir(name: const str) -> DIR
|
||
extern def readdir(dirp: DIR) -> Dirent*
|
||
extern def closedir(dirp: DIR) -> INT
|
||
extern def mkdir(path: const str, mode: mode_t) -> INT
|
||
extern def rmdir(path: const str) -> INT
|
||
extern def getcwd(buf: CHARPTR, size: sizet) -> CHARPTR
|
||
extern def chdir(path: const str) -> INT
|
||
|
||
|
||
# =============================================================================
|
||
# Process operations (8)
|
||
# =============================================================================
|
||
extern def fork() -> pid_t
|
||
extern def execvp(file: const str, argv: CHARPTR*) -> INT
|
||
extern def execv(path: const str, argv: CHARPTR*) -> INT
|
||
extern def waitpid(pid: pid_t, status: INT*, options: INT) -> pid_t
|
||
extern def pipe(fds: INT*) -> INT
|
||
extern def dup2(oldfd: INT, newfd: INT) -> INT
|
||
extern def _exit(status: INT)
|
||
extern def getpid() -> pid_t
|
||
|
||
|
||
# =============================================================================
|
||
# Environment operations (4)
|
||
# =============================================================================
|
||
extern def getenv(name: const str) -> CHARPTR
|
||
extern def setenv(name: const str, value: const str, overwrite: INT) -> INT
|
||
extern def sysconf(name: INT) -> LONG
|
||
extern def isatty(fd: INT) -> INT
|
||
|
||
|
||
# =============================================================================
|
||
# Inline macros (C macros, implemented as normal functions, not marked as extern)
|
||
# =============================================================================
|
||
|
||
# st_mode type determination
|
||
def S_ISREG(mode: mode_t) -> bool: return (mode & S_IFMT) == S_IFREG
|
||
def S_ISDIR(mode: mode_t) -> bool: return (mode & S_IFMT) == S_IFDIR
|
||
def S_ISLNK(mode: mode_t) -> bool: return (mode & S_IFMT) == S_IFLNK
|
||
def S_ISCHR(mode: mode_t) -> bool: return (mode & S_IFMT) == S_IFCHR
|
||
def S_ISBLK(mode: mode_t) -> bool: return (mode & S_IFMT) == S_IFBLK
|
||
def S_ISFIFO(mode: mode_t) -> bool: return (mode & S_IFMT) == S_IFIFO
|
||
def S_ISSOCK(mode: mode_t) -> bool: return (mode & S_IFMT) == S_IFSOCK
|
||
|
||
# waitpid status parsing
|
||
def WIFEXITED(status: INT) -> bool: return (status & 0x7F) == 0
|
||
def WEXITSTATUS(status: INT) -> INT: return (status >> 8) & 0xFF
|
||
def WIFSIGNALED(status: INT) -> bool: return ((status & 0x7F) != 0) and ((status & 0x7F) != 0x7F)
|
||
def WTERMSIG(status: INT) -> INT: return status & 0x7F
|