#!/usr/bin/env python3 import re import os import sys from typing import List ITEM_RE = re.compile( r"[ \t]*(?P\d+(-\d+)?)[ \t]+(?PAUE_[A-Z0-9a-z_]+)[ \t]+(?P[A-Z0-9]+([ \t]*\|[ \t]*[A-Z0-9]+)*)[ \t]*" r"(\{\s*\w+(\s+|\s*(\*)?\s*)(?P\w+)\s*\([^{}]*?\)(\s*NO_SYSCALL_STUB)?\s*;\s*\}(\s*\{[^}]+\}|([ \t]+(?P\w+)([ \t+]\w+){0,2})?)?|[^{\n]*)?\s+" ) NICE_OS_NAMES = { "freebsd": "FreeBSD", "macos": "macOS", } NICE_ARCH_NAMES = { "x86_64": "x86-64", "powerpc": "PowerPC", "powerpc64": "PowerPC64", "mips": "MIPS", "mips64": "MIPS64", "sparc64": "SPARC64", } def main(args: List[str]) -> None: if len(args) != 2: print("Usage: {} ".format(sys.argv[0])) sys.exit(1) repo_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) syscalls_fname = args[0] os_name = args[1] arches = [ name[len(os_name) + 1 :] for name in os.listdir(os.path.join(repo_path, "src/platform")) if name.startswith(os_name + "-") ] text = "" with open(syscalls_fname) as file: for line in file: line = line.strip() if line and not line.startswith( ("$", ";", "#include", "#if", "#ifdef", "#else", "#endif", "%%") ): text += line + "\n" syscalls = [] scanner = ITEM_RE.scanner(text) for match in iter(scanner.match, None): nr_range = match.group("nr_range") sc_types = [name.strip() for name in match.group("type").split("|")] name = (match.group("name") or "").upper() altname = (match.group("altname") or "").upper() if sc_types == ["RESERVED"]: continue if "-" in nr_range: assert not name continue nr = int(nr_range) if nr == 0 and name in ("NOSYS", "ENOSYS"): name = "SYSCALL" if os_name == "freebsd": if name.startswith("__") and name != "__SYSCALL": name = name[2:] if not name: continue if name in ("NOSYS", "ENOSYS"): if altname: name = altname else: continue if os_name == "freebsd": name = { "SYS_EXIT": "EXIT", }.get(name, name) if "COMPAT" in sc_types: continue for sc_type in sc_types: if sc_type.startswith("COMPAT"): name = "FREEBSD{}_{}".format(int(sc_type[6:]), name) break elif os_name == "macos": name = { "SYSCTL": "__SYSCTL", }.get(name, name) if name.startswith("SYS_"): name = name[4:] syscalls.append((name, nr)) for arch in arches: fpath = os.path.join(repo_path, "src/platform", os_name + "-" + arch, "nr.rs") with open(fpath, "w") as file: file.write( "//! System call numbers for {} {}.\n\n".format( NICE_ARCH_NAMES.get(arch, arch), NICE_OS_NAMES[os_name] ) ) file.write("/* Automatically generated by bsd_nr_from_src.py */\n\n") for (name, nr) in syscalls: file.write("pub const {}: usize = {};\n".format(name, nr)) if __name__ == "__main__": main(sys.argv[1:])