mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
* Updated re library + test * Copied over generate_sre_constants from cpython/Tools * Customized `generate_sre_constants.py` + ran to update `constants.rs` * Clarified `dump_enum` docstring in `generate_sre_constants.py`
140 lines
3.9 KiB
Python
140 lines
3.9 KiB
Python
#! /usr/bin/env python3
|
|
# This script generates crates/sre_engine/src/constants.rs from Lib/re/_constants.py.
|
|
|
|
SCRIPT_NAME = "scripts/generate_sre_constants.py"
|
|
|
|
|
|
def update_file(file, content):
|
|
try:
|
|
with open(file, "r") as fobj:
|
|
if fobj.read() == content:
|
|
return False
|
|
except (OSError, ValueError):
|
|
pass
|
|
with open(file, "w") as fobj:
|
|
fobj.write(content)
|
|
return True
|
|
|
|
|
|
sre_constants_header = f"""\
|
|
/*
|
|
* Secret Labs' Regular Expression Engine
|
|
*
|
|
* regular expression matching engine
|
|
*
|
|
* Auto-generated by {SCRIPT_NAME} from
|
|
* Lib/re/_constants.py.
|
|
*
|
|
* Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved.
|
|
*
|
|
* See the sre.c file for information on usage and redistribution.
|
|
*/
|
|
|
|
"""
|
|
|
|
|
|
def dump_enum(d, enum_name, derives, strip_prefix=""):
|
|
"""Generate Rust enum definitions from a Python dictionary.
|
|
|
|
Args:
|
|
d (list): The list containing the enum variants.
|
|
enum_name (str): The name of the enum to generate.
|
|
derives (str): The derive attributes to include.
|
|
strip_prefix (str, optional): A prefix to strip from the variant names. Defaults to "".
|
|
|
|
Returns:
|
|
list: A list of strings representing the enum definition.
|
|
"""
|
|
items = sorted(d)
|
|
print(f"items is {items}")
|
|
content = [f"{derives}\n"]
|
|
content.append("#[repr(u32)]\n")
|
|
content.append("#[allow(non_camel_case_types, clippy::upper_case_acronyms)]\n")
|
|
content.append(f"pub enum {enum_name} {{\n")
|
|
for i, item in enumerate(items):
|
|
name = str(item).removeprefix(strip_prefix)
|
|
content.append(f" {name} = {i},\n")
|
|
content.append("}\n\n")
|
|
return content
|
|
|
|
|
|
def dump_bitflags(d, prefix, derives, struct_name, int_t):
|
|
"""Generate Rust bitflags definitions from a Python dictionary.
|
|
|
|
Args:
|
|
d (dict): The dictionary containing the bitflag variants.
|
|
prefix (str): The prefix to strip from the variant names.
|
|
derives (str): The derive attributes to include.
|
|
struct_name (str): The name of the struct to generate.
|
|
int_t (str): The integer type to use for the bitflags.
|
|
|
|
Returns:
|
|
list: A list of strings representing the bitflags definition.
|
|
"""
|
|
items = [(value, name) for name, value in d.items() if name.startswith(prefix)]
|
|
content = ["bitflags! {\n"]
|
|
content.append(f"{derives}\n") if derives else None
|
|
content.append(f" pub struct {struct_name}: {int_t} {{\n")
|
|
for value, name in sorted(items):
|
|
name = str(name).removeprefix(prefix)
|
|
content.append(f" const {name} = {value};\n")
|
|
content.append(" }\n")
|
|
content.append("}\n\n")
|
|
return content
|
|
|
|
|
|
def main(
|
|
infile="Lib/re/_constants.py",
|
|
outfile_constants="crates/sre_engine/src/constants.rs",
|
|
):
|
|
ns = {}
|
|
with open(infile) as fp:
|
|
code = fp.read()
|
|
exec(code, ns)
|
|
|
|
content = [sre_constants_header]
|
|
content.append("use bitflags::bitflags;\n\n")
|
|
content.append(f"pub const SRE_MAGIC: usize = {ns['MAGIC']};\n")
|
|
content.extend(
|
|
dump_enum(
|
|
ns["OPCODES"],
|
|
"SreOpcode",
|
|
"#[derive(num_enum::TryFromPrimitive, Debug, PartialEq, Eq)]",
|
|
)
|
|
)
|
|
content.extend(
|
|
dump_enum(
|
|
ns["ATCODES"],
|
|
"SreAtCode",
|
|
"#[derive(num_enum::TryFromPrimitive, Debug, PartialEq, Eq)]",
|
|
"AT_",
|
|
)
|
|
)
|
|
content.extend(
|
|
dump_enum(
|
|
ns["CHCODES"],
|
|
"SreCatCode",
|
|
"#[derive(num_enum::TryFromPrimitive, Debug)]",
|
|
"CATEGORY_",
|
|
)
|
|
)
|
|
|
|
content.extend(
|
|
dump_bitflags(
|
|
ns,
|
|
"SRE_FLAG_",
|
|
"#[derive(Debug, PartialEq, Eq, Clone, Copy)]",
|
|
"SreFlag",
|
|
"u16",
|
|
)
|
|
)
|
|
content.extend(dump_bitflags(ns, "SRE_INFO_", "", "SreInfo", "u32"))
|
|
|
|
update_file(outfile_constants, "".join(content))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import sys
|
|
|
|
main(*sys.argv[1:])
|