#!/usr/bin/env python3 """gen_nametable.py - build orbisrpc/nametable.h from config/titles.json. titles.json maps TITLEID -> display name (extracted from the PS4's /system_data/priv/mms/app.db tbl_appbrowse_* tables, or extended by hand). The generated table is compiled in, so name lookup needs no filesystem access and works inside any console sandbox. Usage: python3 scripts/gen_nametable.py """ import json import os ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) SRC = os.path.join(ROOT, "config", "titles.json") DST = os.path.join(ROOT, "orbisrpc", "nametable.h") def c_escape(s): out = [] for ch in s: o = ord(ch) if ch == '"': out.append('\\"') elif ch == "\\": out.append("\\\\") elif 32 <= o < 127: out.append(ch) else: # octal: unlike \x, always stops after 3 digits, so a hex # digit following the escape can never merge into it. for b in ch.encode("utf-8"): out.append("\\%03o" % b) return "".join(out) def main(): with open(SRC, encoding="utf-8") as fh: titles = json.load(fh) items = sorted(titles.items()) with open(DST, "w", encoding="utf-8") as fh: fh.write("/* nametable.h - GENERATED by scripts/gen_nametable.py. Do not edit. */\n") fh.write("#ifndef NAMETABLE_H\n#define NAMETABLE_H\n"); fh.write("#include \n#include \n") fh.write("typedef struct { const char *id; const char *name; } nt_entry_t;\n") fh.write("static const nt_entry_t g_nametable[] = {\n") for tid, name in items: fh.write(' { "%s", "%s" },\n' % (c_escape(tid), c_escape(name))) fh.write("};\n") fh.write("static const size_t g_nametable_count = sizeof g_nametable / sizeof g_nametable[0];\n") fh.write("static int nametable_lookup(const char *tid, char *out, size_t cap){\n") fh.write(" if(!tid || !out || cap == 0) return -1;\n") fh.write(" for(size_t i = 0; i < g_nametable_count; i++){\n") fh.write(" if(!strcmp(tid, g_nametable[i].id)){\n") fh.write(" strncpy(out, g_nametable[i].name, cap - 1);\n") fh.write(" out[cap - 1] = 0;\n") fh.write(" return out[0] ? 0 : -1;\n") fh.write(" }\n") fh.write(" }\n") fh.write(" return -1;\n") fh.write("}\n#endif\n") print("wrote %s with %d entries" % (DST, len(items))) if __name__ == "__main__": main()