| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- #!/usr/bin/env python3
- import os
- import re
- from pathlib import Path
- def repo_root_from_script() -> Path:
- return Path(__file__).resolve().parents[2]
- def escape_c_byte(b: int) -> str:
- if b == 0x22:
- return r"\""
- if b == 0x5C:
- return r"\\"
- if b == 0x0A:
- return r"\n"
- if b == 0x0D:
- return r"\r"
- if b == 0x09:
- return r"\t"
- if b == 0x08:
- return r"\b"
- if b == 0x0C:
- return r"\f"
- if 0x20 <= b <= 0x7E:
- return chr(b)
- return f"\\{b:03o}"
- def format_c_string(data: bytes, indent: str = " ", max_line_len: int = 120) -> str:
- if data is None:
- return indent + "\"\"\n"
- lines = []
- current = indent + "\""
- for b in data:
- chunk = escape_c_byte(b)
- if len(current) + len(chunk) >= max_line_len:
- current += "\"\n"
- lines.append(current)
- current = indent + "\"" + chunk
- else:
- current += chunk
- current += "\"\n"
- lines.append(current)
- return "".join(lines)
- def main() -> None:
- repo_root = repo_root_from_script()
- data_dir = repo_root / "test" / "data" / "rfc8259"
- out_dir = repo_root / "test" / "unityTest" / "cases" / "RFC8259"
- out_c = out_dir / "rfc8259Embedded.c"
- out_h = out_dir / "rfc8259Embedded.h"
- names = sorted([p.name for p in data_dir.iterdir() if p.is_file() and p.name.endswith(".json")])
- if not names:
- raise SystemExit("No RFC8259 json files found.")
- out_dir.mkdir(parents=True, exist_ok=True)
- # Header
- header = []
- header.append("#ifndef RYANJSON_RFC8259_EMBEDDED_H\n")
- header.append("#define RYANJSON_RFC8259_EMBEDDED_H\n\n")
- header.append("#include <stdint.h>\n\n")
- header.append("typedef struct\n{")
- header.append("\tconst char *name;\n")
- header.append("\tconst unsigned char *data;\n")
- header.append("\tuint32_t len;\n")
- header.append("} rfc8259EmbeddedFile_t;\n\n")
- header.append("extern const rfc8259EmbeddedFile_t gRfc8259EmbeddedFiles[];\n")
- header.append("extern const uint32_t gRfc8259EmbeddedFileCount;\n\n")
- header.append("#endif // RYANJSON_RFC8259_EMBEDDED_H\n")
- out_h.write_text("".join(header), encoding="utf-8")
- # Source
- src = []
- src.append("// Auto-generated by scripts/tools/gen_rfc8259_embedded.py. Do not edit by hand.\n")
- src.append("#include \"rfc8259Embedded.h\"\n\n")
- entries = []
- for idx, name in enumerate(names):
- path = data_dir / name
- data = path.read_bytes()
- stem = Path(name).stem
- parts = [p for p in re.split(r"[^a-zA-Z0-9]+", stem) if p]
- if not parts:
- camel = f"case{idx:03d}"
- else:
- first = parts[0].lower()
- rest = "".join(p[:1].upper() + p[1:] for p in parts[1:])
- camel = first + rest
- var_name = f"rfc8259Embedded{idx:03d}{camel}Json"
- src.append(f"static const unsigned char {var_name}[] =\n")
- src.append(format_c_string(data))
- src.append(";\n\n")
- entries.append((name, var_name, len(data)))
- src.append("const rfc8259EmbeddedFile_t gRfc8259EmbeddedFiles[] = {\n")
- for name, var_name, length in entries:
- src.append(f"\t{{\"{name}\", {var_name}, {length}U}},\n")
- src.append("};\n\n")
- src.append("const uint32_t gRfc8259EmbeddedFileCount = ")
- src.append("(uint32_t)(sizeof(gRfc8259EmbeddedFiles) / sizeof(gRfc8259EmbeddedFiles[0]));\n")
- out_c.write_text("".join(src), encoding="utf-8")
- if __name__ == "__main__":
- main()
|