1 Commits
Author SHA1 Message Date
libretroadmin d580522058 Patch: the loaded patches, the pnach parser and the loaders in C
The patch store was a std::vector<IniPatch> exported to Counters and
VMManager, each walking it for the places it wanted; a 'bytes'
payload was a std::vector<u8> inside each patch; the dynamic patches
were copies of the game database's vectors; the parser split lines
into std::vector<std::string_view>; the loaders took std::string and
went through std::string buffers, std::optional and FileSystem's
std::vector of results.

Now:
- The patches are a plain array in Patch.cpp, read through
  LoadedPatchCount/LoadedPatch, and applied by ApplyLoadedPatches with
  a mask of places, in load order as before. A payload is a malloc'd
  run with its length, freed by ForgetLoadedPatches, and only
  allocated once the line has passed every check.
- The dynamic patches' entries are copied into one array of their
  own, a pattern run then a replacement run per patch, so a reload of
  the game database cannot leave them dangling.
- The parser splits into five (pointer, length) fields on the stack,
  with the stripping and empty-field rules SplitString had, and the
  command table takes the same.
- LoadPatchesFromZip and LoadPatchesFromDir take C strings. The zip
  member is inflated into a malloc'd buffer. The folder is walked with
  retro_opendir directly, with FindFiles's filter (files, hidden ones
  included, "*.pnach", sizable) and its order, and each file is read
  with filestream_read_file, which terminates it. The "not found"
  message no longer has a newline in the middle of the path.

tests/patch gains a lane that links Patch.cpp against the real
libretro-common directory, file and inflate code: pnach files for the
CRC in either case and with suffixes beside another CRC's, a .txt, a
hidden file, a directory named like a pnach and an empty folder; and
archives written by Python's zipfile with the member deflated, stored
under an upper-case name, only under a subfolder, and behind a
comment, plus every truncation and every one-byte corruption of one.
It fails if the CRC match turns case-sensitive.
2026-11-03 22:29:43 +01:00