diff --git a/README.md b/README.md index 0e42469e..1622678c 100644 --- a/README.md +++ b/README.md @@ -271,6 +271,20 @@ python3 ./m2c.py --visualize=c --context ctx.c -f my_fn my_asm.s > my_fn_c.svg python3 ./m2c.py --visualize=asm --context ctx.c -f my_fn my_asm.s > my_fn_asm.svg ``` +### Preprocessing + +There currently is a pseudo-macro in lieu of a full preprocessor that allows for the conditional switching of code in a context file. This allows for both m2c and e.g. a compiler to use the same context file if both need to define e.g. structs or typedefs slightly differently. + +```c +#ifdef M2C +... +#else +... +#endif +``` + +Any other macros besides `#ifdef M2C` currently will fail, and you also need the `#else` between `#ifdef M2C` and `#endif` for the pattern to match. + ### Migrating from `mips_to_c.py` This tool was originally known as `mips_to_c`. As part of the rename, deprecated command line arguments were removed. diff --git a/m2c/c_types.py b/m2c/c_types.py index 5083c2a5..bc42d14a 100644 --- a/m2c/c_types.py +++ b/m2c/c_types.py @@ -647,6 +647,18 @@ def replacer(match: Match[str]) -> str: return re.sub(pattern, replacer, text) +def process_ifdef(text: str) -> str: + pattern = re.compile( + r"^[ \t]*#ifdef[ \t]+M2C\s+" + r"(?P.*?)" + r"^[ \t]*#else\s+" + r".*?" + r"^[ \t]*#endif.*?$", + flags=re.DOTALL | re.MULTILINE, + ) + return re.sub(pattern, lambda m: m.group("ifdef_body"), text) + + def strip_macro_defs(text: str) -> str: """Strip macro definitions from C source. m2c does not run the preprocessor, for a bunch of reasons: @@ -740,6 +752,7 @@ def _build_typemap(source_paths: Tuple[Path, ...], use_cache: bool) -> TypeMap: source = add_builtin_typedefs(source) source = strip_comments(source) + source = process_ifdef(source) source = strip_macro_defs(source) ast, result_scope = parse_c(source, typemap.cparser_scope)