Merges one section (universal or a title's specific scripts) across its roots. Roots come base-first (bundled, then SD): a later root's file with the same name replaces the earlier one and is flagged `overridden`. The merged section is appended to `out`, sorted alphabetically.
| 39 | // the same name replaces the earlier one and is flagged `overridden`. The |
| 40 | // merged section is appended to `out`, sorted alphabetically. |
| 41 | void scanSection(const std::vector<Root>& roots, bool universal, std::vector<Entry>& out) |
| 42 | { |
| 43 | const size_t first = out.size(); |
| 44 | for (const Root& root : roots) { |
| 45 | DIR* d = opendir(root.dir.c_str()); |
| 46 | if (!d) { |
| 47 | continue; |
| 48 | } |
| 49 | while (struct dirent* ent = readdir(d)) { |
| 50 | const std::string name = ent->d_name; |
| 51 | if (name.size() <= 2 || name.compare(name.size() - 2, 2, ".c") != 0) { |
| 52 | continue; |
| 53 | } |
| 54 | // Only files directly in the directory count; subfolders are assets. |
| 55 | const std::string path = root.dir + "/" + name; |
| 56 | struct stat st; |
| 57 | if (stat(path.c_str(), &st) != 0 || !S_ISREG(st.st_mode)) { |
| 58 | continue; |
| 59 | } |
| 60 | const std::string display = name.substr(0, name.size() - 2); |
| 61 | auto it = std::find_if(out.begin() + first, out.end(), [&](const Entry& e) { return e.name == display; }); |
| 62 | if (it != out.end()) { |
| 63 | // A later root shadows an earlier one: the SD file wins and |
| 64 | // is marked as an override of the bundled script. |
| 65 | it->path = path; |
| 66 | it->source = root.source; |
| 67 | it->overridden = true; |
| 68 | } |
| 69 | else { |
| 70 | out.push_back({display, path, universal, root.source, false}); |
| 71 | } |
| 72 | } |
| 73 | closedir(d); |
| 74 | } |
| 75 | |
| 76 | std::sort(out.begin() + first, out.end(), [](const Entry& a, const Entry& b) { return a.name < b.name; }); |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | std::vector<ScriptCatalog::Entry> ScriptCatalog::scan(const std::vector<Root>& universalRoots, const std::vector<Root>& specificRoots) |