JSON Metadata -
diff --git a/inbuild/Chapter 1/Main.w b/inbuild/Chapter 1/Main.w
index 2bba4fa9f..fbbc18a3e 100644
--- a/inbuild/Chapter 1/Main.w
+++ b/inbuild/Chapter 1/Main.w
@@ -13,6 +13,7 @@ int inbuild_task = INSPECT_TTASK;
pathname *path_to_tools = NULL;
int dry_run_mode = FALSE, build_trace_mode = FALSE;
inbuild_nest *destination_nest = NULL;
+inbuild_registry *selected_registry = NULL;
text_stream *filter_text = NULL;
@h Main routine.
@@ -311,6 +312,8 @@ other options to the selection defined here.
@e COPY_TO_CLSW
@e SYNC_TO_CLSW
@e VERSIONS_IN_FILENAMES_CLSW
+@e VERIFY_REGISTRY_CLSW
+@e BUILD_REGISTRY_CLSW
@ =
CommandLine::declare_heading(
@@ -356,6 +359,10 @@ other options to the selection defined here.
L"apply to all works in nest(s) matching requirement X");
CommandLine::declare_switch(CONTENTS_OF_CLSW, L"contents-of", 2,
L"apply to all targets in the directory X");
+ CommandLine::declare_switch(VERIFY_REGISTRY_CLSW, L"verify-registry", 2,
+ L"verify roster.json metadata of registry in the directory X");
+ CommandLine::declare_switch(BUILD_REGISTRY_CLSW, L"build-registry", 2,
+ L"construct HTML menu pages for registry in the directory X");
Supervisor::declare_options();
CommandLine::read(argc, argv, NULL, &Main::option, &Main::bareword);
@@ -396,6 +403,13 @@ void Main::option(int id, int val, text_stream *arg, void *state) {
break;
case VERSIONS_IN_FILENAMES_CLSW:
Editions::set_canonical_leaves_have_versions(val); break;
+ case VERIFY_REGISTRY_CLSW:
+ case BUILD_REGISTRY_CLSW:
+ selected_registry = Registries::new(Pathnames::from_text(arg));
+ if (Registries::read_roster(selected_registry) == FALSE) exit(1);
+ if (id == BUILD_REGISTRY_CLSW)
+ Registries::build(selected_registry);
+ break;
}
Supervisor::option(id, val, arg, state);
}
diff --git a/inbuild/Contents.w b/inbuild/Contents.w
index 9b2012c33..cc9156d14 100644
--- a/inbuild/Contents.w
+++ b/inbuild/Contents.w
@@ -18,6 +18,7 @@ Manual
A Guide to Kits
A Guide to Language Bundles
A Guide to Project Metadata
+ A Guide to Registries
Reference Card
Chapter 1: Outside of inform7
diff --git a/inbuild/Figures/help.txt b/inbuild/Figures/help.txt
index 6517cfc5a..e91d55e40 100644
--- a/inbuild/Figures/help.txt
+++ b/inbuild/Figures/help.txt
@@ -8,6 +8,7 @@ usage: inbuild [-TASK] TARGET1 TARGET2 ...
-build-locate show file paths of all the extensions, kits and so on needed to build
-build-missing show the extensions, kits and so on which are needed to build but missing
-build-needs show all the extensions, kits and so on needed to build
+-build-registry X construct HTML menu pages for registry in the directory X
-build-trace show verbose reasoning during -build (default is -no-build-trace)
-contents-of X apply to all targets in the directory X
-copy-to X copy target(s) to nest X
@@ -21,6 +22,7 @@ usage: inbuild [-TASK] TARGET1 TARGET2 ...
-use-locate show file paths of all the extensions, kits and so on needed to use
-use-missing show the extensions, kits and so on which are needed to use but missing
-use-needs show all the extensions, kits and so on needed to use
+-verify-registry X verify roster.json metadata of registry in the directory X
-no-versions-in-filenames don't append _v number to destination filenames on -copy-to or -sync-to (default is -versions-in-filenames)
for translating Inform source text to Inter:
diff --git a/inbuild/Manual/A Guide to Registries.w b/inbuild/Manual/A Guide to Registries.w
new file mode 100644
index 000000000..17256eb87
--- /dev/null
+++ b/inbuild/Manual/A Guide to Registries.w
@@ -0,0 +1,14 @@
+A Guide to Registries.
+
+Provisional documentation on how to scan and build registries of Inform resources.
+
+@h Registries.
+A "registry" is a collection of Inform resources gathered together for others
+to use. The Public Library presented in the Inform apps is a registry, for
+example, but the idea is being generalised in inbuild with a view to future
+developments.
+
+This page is a place-holder for now: see //supervisor: Registries// for
+very slightly more.
+
+The PL presented as a registry can be seen at //this repository -> https://github.com/ganelson/inform-public-library//.
diff --git a/inbuild/supervisor-module/Chapter 1/Supervisor Module.w b/inbuild/supervisor-module/Chapter 1/Supervisor Module.w
index 365c5f017..93125f5ed 100644
--- a/inbuild/supervisor-module/Chapter 1/Supervisor Module.w
+++ b/inbuild/supervisor-module/Chapter 1/Supervisor Module.w
@@ -27,6 +27,7 @@ which use this module:
@e inbuild_edition_CLASS
@e inbuild_genre_CLASS
@e inbuild_nest_CLASS
+@e inbuild_registry_CLASS
@e inbuild_requirement_CLASS
@e inbuild_search_result_CLASS
@e inbuild_work_CLASS
@@ -58,6 +59,7 @@ DECLARE_CLASS(inbuild_copy)
DECLARE_CLASS(inbuild_edition)
DECLARE_CLASS(inbuild_genre)
DECLARE_CLASS(inbuild_nest)
+DECLARE_CLASS(inbuild_registry)
DECLARE_CLASS(inbuild_requirement)
DECLARE_CLASS(inbuild_search_result)
DECLARE_CLASS(inbuild_work)
diff --git a/inbuild/supervisor-module/Chapter 2/JSON Metadata.w b/inbuild/supervisor-module/Chapter 2/JSON Metadata.w
index 6d16df102..7e434cbbc 100644
--- a/inbuild/supervisor-module/Chapter 2/JSON Metadata.w
+++ b/inbuild/supervisor-module/Chapter 2/JSON Metadata.w
@@ -237,7 +237,7 @@ dictionary *JSON_resource_metadata_requirements = NULL;
JSON_requirement *JSONMetadata::requirements(void) {
if (JSON_resource_metadata_requirements == NULL) {
- filename *F = InstalledFiles::filename(JSON_REQUIREMENTS_IRES);
+ filename *F = InstalledFiles::filename(RESOURCE_JSON_REQS_IRES);
JSON_resource_metadata_requirements = JSON::read_requirements_file(NULL, F);
}
JSON_requirement *req =
diff --git a/inbuild/supervisor-module/Chapter 2/Registries.w b/inbuild/supervisor-module/Chapter 2/Registries.w
new file mode 100644
index 000000000..99c6c3ae2
--- /dev/null
+++ b/inbuild/supervisor-module/Chapter 2/Registries.w
@@ -0,0 +1,641 @@
+[Registries::] Registries.
+
+Registries are nests provided with metadata and intended to be presented as
+an online source from which Inform resources can be downloaded.
+
+@h Creation.
+To "create" a registry here does not mean actually altering the file system, for
+example by making a directory: registries here are merely notes in memory of
+positions in the file system hierarchy which may or may not exist.
+
+=
+typedef struct inbuild_registry {
+ struct pathname *location;
+ struct inbuild_nest *nest;
+ struct JSON_value *roster;
+ CLASS_DEFINITION
+} inbuild_registry;
+
+@ =
+inbuild_registry *Registries::new(pathname *P) {
+ inbuild_registry *N = CREATE(inbuild_registry);
+ N->location = P;
+ N->nest = Nests::new(Pathnames::down(P, I"payloads"));
+ N->roster = NULL;
+ return N;
+}
+
+@h The roster.
+This is a JSON file called |roster.json|, whose schema must match the one specified
+by the file |registry-metadata.jsonr| in the standard Inform distribution.
+
+The following silently returns |TRUE| if it does, or prints errors and returns
+|FALSE| if not (or if it doesn't exist).
+
+=
+int Registries::read_roster(inbuild_registry *R) {
+ if (R == NULL) internal_error("no registry");
+ R->roster = NULL;
+ filename *F = Filenames::in(R->location, I"roster.json");
+ if (TextFiles::exists(F) == FALSE) {
+ WRITE_TO(STDERR, "%f: roster file does not exist\n", F);
+ return FALSE;
+ }
+ TEMPORARY_TEXT(contents)
+ TextFiles::read(F, FALSE, "unable to read file of JSON metadata", TRUE,
+ &JSONMetadata::read_metadata_file_helper, NULL, contents);
+ text_file_position tfp = TextFiles::at(F, 1);
+ JSON_value *obj = JSON::decode(contents, &tfp);
+ DISCARD_TEXT(contents)
+ if ((obj) && (obj->JSON_type == ERROR_JSONTYPE)) {
+ WRITE_TO(STDERR, "%f: JSON syntax error: %S\n", F, obj->if_error);
+ return FALSE;
+ } else {
+ JSON_requirement *req = Registries::requirements();
+ linked_list *validation_errors = NEW_LINKED_LIST(text_stream);
+ if (JSON::validate(obj, req, validation_errors) == FALSE) {
+ text_stream *err;
+ LOOP_OVER_LINKED_LIST(err, text_stream, validation_errors) {
+ WRITE_TO(STDERR, "%f: metadata did not validate: '%S'\n", F, err);
+ }
+ return FALSE;
+ }
+ }
+ R->roster = obj;
+ return TRUE;
+}
+
+@ The following schema validates the metadata for a registry, and is cached
+so that it only needs to load once.
+
+=
+dictionary *JSON_registry_metadata_requirements = NULL;
+
+JSON_requirement *Registries::requirements(void) {
+ if (JSON_registry_metadata_requirements == NULL) {
+ filename *F = InstalledFiles::filename(REGISTRY_JSON_REQS_IRES);
+ JSON_registry_metadata_requirements = JSON::read_requirements_file(NULL, F);
+ }
+ JSON_requirement *req =
+ JSON::look_up_requirements(JSON_registry_metadata_requirements, I"registry-metadata");
+ if (req == NULL) internal_error("JSON metadata file did not define ");
+ return req;
+}
+
+@h Building.
+To "build" a registry doesn't involve very much: just putting some indexing
+files together, using the preprocessor built into //foundation//.
+
+If the registry is |R|, we preprocess each file |R/source/X.Y| into |R/X.Y|:
+
+=
+void Registries::build(inbuild_registry *R) {
+ if (R == NULL) internal_error("no registry");
+ linked_list *ML = NEW_LINKED_LIST(preprocessor_macro);
+ @;
+ pathname *S = Pathnames::down(R->location, I"source");
+ linked_list *L = Directories::listing(S);
+ text_stream *entry;
+ LOOP_OVER_LINKED_LIST(entry, text_stream, L) {
+ if (Platform::is_folder_separator(Str::get_last_char(entry)) == FALSE) {
+ filename *F = Filenames::in(S, entry);
+ TEMPORARY_TEXT(EXT)
+ Filenames::write_extension(EXT, F);
+ if (Str::len(EXT) > 0) {
+ filename *T = Filenames::in(R->location, Filenames::get_leafname(F));
+ WRITE_TO(STDOUT, "%f -> %f\n", F, T);
+ Preprocessor::preprocess(F, T, NULL, ML,
+ STORE_POINTER_inbuild_registry(R), '#', UTF8_ENC);
+ }
+ DISCARD_TEXT(EXT)
+ }
+ }
+}
+
+@ =
+ Preprocessor::new_macro(ML, I"include", I"file: LEAFNAME",
+ Registries::include_expander, NULL);
+ Preprocessor::new_macro(ML, I"process", I"file: LEAFNAME",
+ Registries::process_expander, NULL);
+ Preprocessor::do_not_suppress_whitespace(
+ Preprocessor::new_macro(ML, I"section", I"of: ID",
+ Registries::section_expander, NULL));
+ Preprocessor::do_not_suppress_whitespace(
+ Preprocessor::new_macro(ML, I"subsection", I"of: ID",
+ Registries::subsection_expander, NULL));
+ Preprocessor::do_not_suppress_whitespace(
+ Preprocessor::new_macro(ML, I"author", I"of: ID ?escape: WHICH",
+ Registries::author_expander, NULL));
+ Preprocessor::do_not_suppress_whitespace(
+ Preprocessor::new_macro(ML, I"title", I"of: ID ?escape: WHICH",
+ Registries::title_expander, NULL));
+ Preprocessor::do_not_suppress_whitespace(
+ Preprocessor::new_macro(ML, I"version", I"of: ID ?escape: WHICH",
+ Registries::version_expander, NULL));
+ Preprocessor::do_not_suppress_whitespace(
+ Preprocessor::new_macro(ML, I"summary", I"of: ID ?escape: WHICH",
+ Registries::summary_expander, NULL));
+ Preprocessor::do_not_suppress_whitespace(
+ Preprocessor::new_macro(ML, I"forum-thread", I"of: ID",
+ Registries::thread_expander, NULL));
+ Preprocessor::do_not_suppress_whitespace(
+ Preprocessor::new_macro(ML, I"section-mark", I"of: ID",
+ Registries::section_mark_expander, NULL));
+ Preprocessor::do_not_suppress_whitespace(
+ Preprocessor::new_macro(ML, I"section-title", I"of: ID",
+ Registries::section_title_expander, NULL));
+ Preprocessor::do_not_suppress_whitespace(
+ Preprocessor::new_macro(ML, I"subsection-mark", I"of: ID",
+ Registries::subsection_mark_expander, NULL));
+ Preprocessor::do_not_suppress_whitespace(
+ Preprocessor::new_macro(ML, I"subsection-title", I"of: ID",
+ Registries::subsection_title_expander, NULL));
+ Preprocessor::new_loop_macro(ML, I"sections", NULL,
+ Registries::sections_expander, NULL);
+ Preprocessor::new_loop_macro(ML, I"subsections", I"in: SECTION",
+ Registries::subsections_expander, NULL);
+ Preprocessor::new_loop_macro(ML, I"resources", I"in: SECTION",
+ Registries::resources_expander, NULL);
+ Preprocessor::new_loop_macro(ML, I"if-forum-thread", I"for: ID",
+ Registries::if_forum_thread_expander, NULL);
+
+@ |{include file:I}| splices in the file |R/source/include/I|, unmodified.
+It can contain any textual material, and even braces and backslashes pass
+through exactly as written.
+
+=
+void Registries::include_expander(preprocessor_macro *mm, preprocessor_state *PPS,
+ text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) {
+ inbuild_registry *R = RETRIEVE_POINTER_inbuild_registry(PPS->specifics);
+ text_stream *leafname = parameter_values[0];
+ filename *prototype = Filenames::in(Pathnames::down(Pathnames::down(R->location, I"source"), I"include"), leafname);
+ TextFiles::read(prototype, FALSE, "can't open include file",
+ TRUE, Registries::scan_line, NULL, PPS);
+}
+
+void Registries::scan_line(text_stream *line, text_file_position *tfp, void *X) {
+ preprocessor_state *PPS = (preprocessor_state *) X;
+ WRITE_TO(PPS->dest, "%S\n", line);
+}
+
+@ |{process file:I}| also splices in the file |R/source/include/I|, but runs
+it through the preprocessor first. This means any macros it contains will be
+expanded, and it has to comply with the syntax rules on use of braces and
+backslash.
+
+=
+void Registries::process_expander(preprocessor_macro *mm, preprocessor_state *PPS,
+ text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) {
+ inbuild_registry *R = RETRIEVE_POINTER_inbuild_registry(PPS->specifics);
+ text_stream *leafname = parameter_values[0];
+ filename *prototype = Filenames::in(Pathnames::down(Pathnames::down(R->location, I"source"), I"include"), leafname);
+ TextFiles::read(prototype, FALSE, "can't open include file",
+ TRUE, Preprocessor::scan_line, NULL, PPS);
+}
+
+@ |{sections}| ... |{end-sections}| is a loop construct, which loops over each
+section of the registry's roster file. The loop variable |{SECTIONID}| holds
+the ID text for the section; right now, that's just |0|, |1|, |2|, ...
+
+=
+void Registries::sections_expander(preprocessor_macro *mm, preprocessor_state *PPS,
+ text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) {
+ inbuild_registry *R = RETRIEVE_POINTER_inbuild_registry(PPS->specifics);
+ Preprocessor::set_loop_var_name(loop, I"SECTIONID");
+ JSON_value *sections = JSON::look_up_object(R->roster, I"sections");
+ if (sections == NULL) internal_error("could not find roster sections");
+ JSON_value *E;
+ int i = 0;
+ LOOP_OVER_LINKED_LIST(E, JSON_value, sections->if_list) {
+ text_stream *sid = Str::new();
+ WRITE_TO(sid, "%d", i++);
+ Preprocessor::add_loop_iteration(loop, sid);
+ }
+}
+
+@ |{subsections in: SID}| ... |{end-subsections}| loops similarly over all
+subsections in the section with id |SID|. The loop variable is |{SUBSECTIONID}|.
+This also now counts up from 0 (but textually: all preprocessor variables are
+text), but note that this SSID is unique in the registry: i.e., it doesn't go back
+to |0| at the start of each section.
+
+=
+void Registries::subsections_expander(preprocessor_macro *mm, preprocessor_state *PPS,
+ text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) {
+ text_stream *in = parameter_values[0];
+ inbuild_registry *R = RETRIEVE_POINTER_inbuild_registry(PPS->specifics);
+ Preprocessor::set_loop_var_name(loop, I"SUBSECTIONID");
+ JSON_value *sections = JSON::look_up_object(R->roster, I"sections");
+ if (sections == NULL) internal_error("could not find roster sections");
+ JSON_value *E;
+ int i = 0, j = 0;
+ LOOP_OVER_LINKED_LIST(E, JSON_value, sections->if_list) {
+ TEMPORARY_TEXT(sid)
+ WRITE_TO(sid, "%d", i++);
+ JSON_value *subsections = JSON::look_up_object(E, I"subsections");
+ if (subsections == NULL) internal_error("could not find roster subsections");
+ JSON_value *F;
+ LOOP_OVER_LINKED_LIST(F, JSON_value, subsections->if_list) {
+ if (Str::eq(sid, in)) {
+ text_stream *ssid = Str::new();
+ WRITE_TO(ssid, "%d", j);
+ Preprocessor::add_loop_iteration(loop, ssid);
+ }
+ j++;
+ }
+ DISCARD_TEXT(sid)
+ }
+}
+
+@ |{resources in: SSID}| ... |{end-resources}| loops similarly over all
+resources in the subsection with id |SSID|, or over absolutely all resources
+if the id is given as |ALL|. The loop variable is |{ID}|.
+
+=
+void Registries::resources_expander(preprocessor_macro *mm, preprocessor_state *PPS,
+ text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) {
+ text_stream *in = parameter_values[0];
+ inbuild_registry *R = RETRIEVE_POINTER_inbuild_registry(PPS->specifics);
+ Preprocessor::set_loop_var_name(loop, I"ID");
+ JSON_value *sections = JSON::look_up_object(R->roster, I"sections");
+ if (sections == NULL) internal_error("could not find roster sections");
+ JSON_value *E;
+ int j = 0, k = 0;
+ LOOP_OVER_LINKED_LIST(E, JSON_value, sections->if_list) {
+ JSON_value *subsections = JSON::look_up_object(E, I"subsections");
+ if (subsections == NULL) internal_error("could not find roster subsections");
+ JSON_value *F;
+ LOOP_OVER_LINKED_LIST(F, JSON_value, subsections->if_list) {
+ TEMPORARY_TEXT(ssid)
+ WRITE_TO(ssid, "%d", j++);
+ JSON_value *holdings = JSON::look_up_object(F, I"holdings");
+ if (holdings == NULL) internal_error("could not find roster holdings");
+ JSON_value *G;
+ LOOP_OVER_LINKED_LIST(G, JSON_value, holdings->if_list) {
+ if ((Str::eq(in, I"ALL")) || (Str::eq(ssid, in))) {
+ text_stream *id = Str::new();
+ WRITE_TO(id, "%d", k);
+ Preprocessor::add_loop_iteration(loop, id);
+ }
+ k++;
+ }
+ DISCARD_TEXT(ssid)
+ }
+ }
+}
+
+@ We now have a run of macros which give details of the resource |ID|.
+
+First, |{section of: ID}| produces the SID of its section.
+
+=
+void Registries::section_expander(preprocessor_macro *mm, preprocessor_state *PPS,
+ text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) {
+ inbuild_registry *R = RETRIEVE_POINTER_inbuild_registry(PPS->specifics);
+ text_stream *of = parameter_values[0];
+ TEMPORARY_TEXT(section)
+ JSON_value *res = Registries::resource_from_textual_id(R, of, section, NULL);
+ if (res) WRITE_TO(PPS->dest, "%S", section);
+ DISCARD_TEXT(section)
+}
+
+@ |{subsection of: ID}| produces the SSID of its subsection.
+
+=
+void Registries::subsection_expander(preprocessor_macro *mm, preprocessor_state *PPS,
+ text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) {
+ inbuild_registry *R = RETRIEVE_POINTER_inbuild_registry(PPS->specifics);
+ text_stream *of = parameter_values[0];
+ TEMPORARY_TEXT(subsection)
+ JSON_value *res = Registries::resource_from_textual_id(R, of, NULL, subsection);
+ if (res) WRITE_TO(PPS->dest, "%S", subsection);
+ DISCARD_TEXT(subsection)
+}
+
+@ |{author of: ID escape: ESC}| produces the author's name, optionally escaped
+with the system below.
+
+=
+void Registries::author_expander(preprocessor_macro *mm, preprocessor_state *PPS,
+ text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) {
+ inbuild_registry *R = RETRIEVE_POINTER_inbuild_registry(PPS->specifics);
+ text_stream *of = parameter_values[0];
+ text_stream *escape = parameter_values[1];
+ JSON_value *res = Registries::resource_from_textual_id(R, of, NULL, NULL);
+ if (res) {
+ JSON_value *author = JSON::look_up_object(res, I"author");
+ if (author == NULL) internal_error("could not find author");
+ Registries::write_escaped(PPS->dest, author->if_string, escape);
+ }
+}
+
+@ |{title of: ID escape: ESC}| produces the title, optionally escaped with the
+system below.
+
+=
+void Registries::title_expander(preprocessor_macro *mm, preprocessor_state *PPS,
+ text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) {
+ inbuild_registry *R = RETRIEVE_POINTER_inbuild_registry(PPS->specifics);
+ text_stream *of = parameter_values[0];
+ text_stream *escape = parameter_values[1];
+ JSON_value *res = Registries::resource_from_textual_id(R, of, NULL, NULL);
+ if (res) {
+ JSON_value *title = JSON::look_up_object(res, I"title");
+ if (title == NULL) internal_error("could not find title");
+ Registries::write_escaped(PPS->dest, title->if_string, escape);
+ }
+}
+
+@ |{version of: ID escape: ESC}| produces the version, optionally escaped with the
+system below.
+
+=
+void Registries::version_expander(preprocessor_macro *mm, preprocessor_state *PPS,
+ text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) {
+ inbuild_registry *R = RETRIEVE_POINTER_inbuild_registry(PPS->specifics);
+ text_stream *of = parameter_values[0];
+ text_stream *escape = parameter_values[1];
+ JSON_value *res = Registries::resource_from_textual_id(R, of, NULL, NULL);
+ if (res) {
+ JSON_value *version = JSON::look_up_object(res, I"version");
+ if (version == NULL) internal_error("could not find version");
+ Registries::write_escaped(PPS->dest, version->if_string, escape);
+ }
+}
+
+@ |{summary of: ID escape: ESC}| produces the summary, optionally escaped with the
+system below.
+
+=
+void Registries::summary_expander(preprocessor_macro *mm, preprocessor_state *PPS,
+ text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) {
+ inbuild_registry *R = RETRIEVE_POINTER_inbuild_registry(PPS->specifics);
+ text_stream *of = parameter_values[0];
+ text_stream *escape = parameter_values[1];
+ JSON_value *res = Registries::resource_from_textual_id(R, of, NULL, NULL);
+ if (res) {
+ JSON_value *summary = JSON::look_up_object(res, I"summary");
+ if (summary == NULL) internal_error("could not find summary");
+ Registries::write_escaped(PPS->dest, summary->if_string, escape);
+ }
+}
+
+@ |{thread of: ID}| produces the forum thread number, if it exists, and prints
+nothing if it does not.
+
+=
+void Registries::thread_expander(preprocessor_macro *mm, preprocessor_state *PPS,
+ text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) {
+ inbuild_registry *R = RETRIEVE_POINTER_inbuild_registry(PPS->specifics);
+ text_stream *of = parameter_values[0];
+ JSON_value *res = Registries::resource_from_textual_id(R, of, NULL, NULL);
+ if (res) {
+ JSON_value *thread = JSON::look_up_object(res, I"forum-thread");
+ if (thread) WRITE_TO(PPS->dest, "%d", thread->if_integer);
+ }
+}
+
+@ |{if-forum-thread for: ID}| ... |{end-if-forum-thread}| checks whether the
+resource has a thread number, and if so, expands the material |...|. This is
+crudely done as either a 0- or 1-term loop.
+
+=
+void Registries::if_forum_thread_expander(preprocessor_macro *mm, preprocessor_state *PPS,
+ text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) {
+ text_stream *of_id = parameter_values[0];
+ inbuild_registry *R = RETRIEVE_POINTER_inbuild_registry(PPS->specifics);
+ Preprocessor::set_loop_var_name(loop, I"ID");
+ JSON_value *sections = JSON::look_up_object(R->roster, I"sections");
+ if (sections == NULL) internal_error("could not find roster sections");
+ JSON_value *E;
+ int k = 0;
+ LOOP_OVER_LINKED_LIST(E, JSON_value, sections->if_list) {
+ JSON_value *subsections = JSON::look_up_object(E, I"subsections");
+ if (subsections == NULL) internal_error("could not find roster subsections");
+ JSON_value *F;
+ LOOP_OVER_LINKED_LIST(F, JSON_value, subsections->if_list) {
+ JSON_value *holdings = JSON::look_up_object(F, I"holdings");
+ if (holdings == NULL) internal_error("could not find roster holdings");
+ JSON_value *G;
+ LOOP_OVER_LINKED_LIST(G, JSON_value, holdings->if_list) {
+ TEMPORARY_TEXT(id)
+ WRITE_TO(id, "%d", k++);
+ if (Str::eq(id, of_id)) {
+ JSON_value *thread = JSON::look_up_object(G, I"forum-thread");
+ if (thread) Preprocessor::add_loop_iteration(loop, id);
+ }
+ DISCARD_TEXT(id)
+ }
+ }
+ }
+}
+
+@ |{section-mark of: SID}| produces the "section mark" of the section.
+
+=
+void Registries::section_mark_expander(preprocessor_macro *mm, preprocessor_state *PPS,
+ text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) {
+ inbuild_registry *R = RETRIEVE_POINTER_inbuild_registry(PPS->specifics);
+ text_stream *of = parameter_values[0];
+ TEMPORARY_TEXT(mark)
+ JSON_value *section = Registries::section_from_textual_id(R, of, mark);
+ if (section) WRITE_TO(PPS->dest, "%S", mark);
+ DISCARD_TEXT(mark)
+}
+
+@ |{section-title of: SID}| produces the title of the section.
+
+=
+void Registries::section_title_expander(preprocessor_macro *mm, preprocessor_state *PPS,
+ text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) {
+ inbuild_registry *R = RETRIEVE_POINTER_inbuild_registry(PPS->specifics);
+ text_stream *of = parameter_values[0];
+ JSON_value *section = Registries::section_from_textual_id(R, of, NULL);
+ if (section) {
+ JSON_value *title = JSON::look_up_object(section, I"title");
+ if (title == NULL) internal_error("could not find title");
+ WRITE_TO(PPS->dest, "%S", title->if_string);
+ }
+}
+
+@ |{subsection-mark of: SID}| produces the "subsection mark" of the subsection.
+
+=
+void Registries::subsection_mark_expander(preprocessor_macro *mm, preprocessor_state *PPS,
+ text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) {
+ inbuild_registry *R = RETRIEVE_POINTER_inbuild_registry(PPS->specifics);
+ text_stream *of = parameter_values[0];
+ TEMPORARY_TEXT(mark)
+ JSON_value *subsection = Registries::subsection_from_textual_id(R, of, NULL, mark);
+ if (subsection) WRITE_TO(PPS->dest, "%S", mark);
+ DISCARD_TEXT(mark)
+}
+
+@ |{subsection-title of: SID}| produces the title of the subsection.
+
+=
+void Registries::subsection_title_expander(preprocessor_macro *mm, preprocessor_state *PPS,
+ text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) {
+ inbuild_registry *R = RETRIEVE_POINTER_inbuild_registry(PPS->specifics);
+ text_stream *of = parameter_values[0];
+ JSON_value *subsection = Registries::subsection_from_textual_id(R, of, NULL, NULL);
+ if (subsection) {
+ JSON_value *title = JSON::look_up_object(subsection, I"title");
+ if (title == NULL) internal_error("could not find title");
+ WRITE_TO(PPS->dest, "%S", title->if_string);
+ }
+}
+
+@h Escapology.
+|quotes| escapes single quotation marks by placing a backslash before them,
+as is necessary in JavaScript string literals.
+
+|spaces| escapes spaces as |%20|, as is necessary in URLs.
+
+|both| does both; |neither| does neither.
+
+=
+void Registries::write_escaped(OUTPUT_STREAM, text_stream *text, text_stream *escape) {
+ if (Str::eq(escape, I"quotes")) {
+ LOOP_THROUGH_TEXT(pos, text) {
+ wchar_t c = Str::get(pos);
+ if (c == '\'') {
+ PUT('\\');
+ PUT('\'');
+ } else {
+ PUT(c);
+ }
+ }
+ } else if (Str::eq(escape, I"spaces")) {
+ LOOP_THROUGH_TEXT(pos, text) {
+ wchar_t c = Str::get(pos);
+ if (c == ' ') {
+ WRITE("%%20");
+ } else {
+ PUT(c);
+ }
+ }
+ } else if (Str::eq(escape, I"both")) {
+ LOOP_THROUGH_TEXT(pos, text) {
+ wchar_t c = Str::get(pos);
+ if (c == '\'') {
+ PUT('\\');
+ PUT('\'');
+ } else if (c == ' ') {
+ WRITE("%%20");
+ } else {
+ PUT(c);
+ }
+ }
+ } else if ((Str::eq(escape, I"neither")) || (Str::len(escape) == 0)) {
+ WRITE("%S", text);
+ } else WRITE_TO(STDERR, "error: no such escape as '%S'\n", escape);
+}
+
+@h Looking up by textual ID.
+Given a textual resource id |id|, return the JSON object for it, or else
+print an error and return |NULL|.
+
+On success, the SID of its section is written to |sectionid|, and the SSID
+of its subsection to |subsectionid|.
+
+=
+JSON_value *Registries::resource_from_textual_id(inbuild_registry *R, text_stream *id,
+ text_stream *sectionid, text_stream *subsectionid) {
+ if ((R == NULL) || (R->roster == NULL)) internal_error("bad registry");
+ JSON_value *sections = JSON::look_up_object(R->roster, I"sections");
+ if (sections == NULL) internal_error("could not find roster sections");
+ JSON_value *E;
+ int i = 0, j = 0, k = 0;
+ LOOP_OVER_LINKED_LIST(E, JSON_value, sections->if_list) {
+ JSON_value *subsections = JSON::look_up_object(E, I"subsections");
+ if (subsections == NULL) internal_error("could not find roster subsections");
+ JSON_value *F;
+ LOOP_OVER_LINKED_LIST(F, JSON_value, subsections->if_list) {
+ JSON_value *holdings = JSON::look_up_object(F, I"holdings");
+ if (holdings == NULL) internal_error("could not find roster holdings");
+ JSON_value *G;
+ LOOP_OVER_LINKED_LIST(G, JSON_value, holdings->if_list) {
+ int match = FALSE;
+ TEMPORARY_TEXT(this_id)
+ WRITE_TO(this_id, "%d", k);
+ if (Str::eq(id, this_id)) match = TRUE;
+ DISCARD_TEXT(this_id)
+ if (match) {
+ WRITE_TO(sectionid, "%d", i);
+ WRITE_TO(subsectionid, "%d", j);
+ return G;
+ }
+ k++;
+ }
+ j++;
+ }
+ i++;
+ }
+ WRITE_TO(STDERR, "error: no such resource ID as '%S'\n", id);
+ return NULL;
+}
+
+@ Similarly for sections, with a |SID|.
+
+The "mark" for a section is 1, 2, 3, ...
+
+=
+JSON_value *Registries::section_from_textual_id(inbuild_registry *R, text_stream *sid,
+ text_stream *mark) {
+ if ((R == NULL) || (R->roster == NULL)) internal_error("bad registry");
+ JSON_value *sections = JSON::look_up_object(R->roster, I"sections");
+ if (sections == NULL) internal_error("could not find roster sections");
+ JSON_value *E;
+ int i = 0;
+ LOOP_OVER_LINKED_LIST(E, JSON_value, sections->if_list) {
+ int match = FALSE;
+ TEMPORARY_TEXT(this_sid)
+ WRITE_TO(this_sid, "%d", i);
+ if (Str::eq(sid, this_sid)) match = TRUE;
+ DISCARD_TEXT(this_sid)
+ if (match) {
+ WRITE_TO(mark, "%d", i+1);
+ return E;
+ }
+ i++;
+ }
+ WRITE_TO(STDERR, "error: no such section ID as '%S'\n", sid);
+ return NULL;
+}
+
+@ And subsections, with a |SSID|:
+
+The "mark" for a subsection is 1.1, 1.2, 1.3, ..., 2.1, 2.2, ...
+
+=
+JSON_value *Registries::subsection_from_textual_id(inbuild_registry *R, text_stream *ssid,
+ text_stream *mark, text_stream *submark) {
+ if ((R == NULL) || (R->roster == NULL)) internal_error("bad registry");
+ JSON_value *sections = JSON::look_up_object(R->roster, I"sections");
+ if (sections == NULL) internal_error("could not find roster sections");
+ JSON_value *E;
+ int i = 0, j = 0;
+ LOOP_OVER_LINKED_LIST(E, JSON_value, sections->if_list) {
+ JSON_value *subsections = JSON::look_up_object(E, I"subsections");
+ if (subsections == NULL) internal_error("could not find roster subsections");
+ int x = 1;
+ JSON_value *F;
+ LOOP_OVER_LINKED_LIST(F, JSON_value, subsections->if_list) {
+ int match = FALSE;
+ TEMPORARY_TEXT(this_ssid)
+ WRITE_TO(this_ssid, "%d", j);
+ if (Str::eq(ssid, this_ssid)) match = TRUE;
+ DISCARD_TEXT(this_ssid)
+ if (match) {
+ WRITE_TO(mark, "%d", i+1);
+ WRITE_TO(submark, "%d.%d", i+1, x);
+ return F;
+ }
+ j++, x++;
+ }
+ i++;
+ }
+ WRITE_TO(STDERR, "error: no such subsection ID as '%S'\n", ssid);
+ return NULL;
+}
diff --git a/inbuild/supervisor-module/Contents.w b/inbuild/supervisor-module/Contents.w
index a64722cf1..f36794088 100644
--- a/inbuild/supervisor-module/Contents.w
+++ b/inbuild/supervisor-module/Contents.w
@@ -19,6 +19,7 @@ Chapter 2: Conceptual Framework
Copy Errors
Requirements
Nests
+ Registries
JSON Metadata
Chapter 3: Incremental Builds
diff --git a/inform7/Figures/memory-diagnostics.txt b/inform7/Figures/memory-diagnostics.txt
index 305f03740..beb0ddf80 100644
--- a/inform7/Figures/memory-diagnostics.txt
+++ b/inform7/Figures/memory-diagnostics.txt
@@ -1,6 +1,6 @@
-Total memory consumption was 120981K = 118 MB
+Total memory consumption was 120989K = 118 MB
- ---- was used for 2048236 objects, in 364575 frames in 0 x 800K = 0K = 0 MB:
+ ---- was used for 2048237 objects, in 364576 frames in 0 x 800K = 0K = 0 MB:
33.7% inter_tree_node_array 58 x 8192 = 475136 objects, 41813824 bytes
21.0% text_stream_array 4620 x 100 = 462000 objects, 26019840 bytes
@@ -44,7 +44,7 @@ Total memory consumption was 120981K = 118 MB
0.2% inference_subject 666 objects, 261072 bytes
0.1% vanilla_function 3683 objects, 235712 bytes
0.1% binary_predicate 322 objects, 170016 bytes
- 0.1% hierarchy_location 1123 objects, 161712 bytes
+ 0.1% hierarchy_location 1124 objects, 161856 bytes
0.1% linguistic_stock_item 3318 objects, 159264 bytes
0.1% rule_family_data 401 objects, 147568 bytes
0.1% nonterminal 758 objects, 139472 bytes
@@ -59,7 +59,7 @@ Total memory consumption was 120981K = 118 MB
---- lexical_cluster 2519 objects, 80608 bytes
---- pcalc_term_array 2 x 1000 = 2000 objects, 80064 bytes
---- kind_variable_declaration 1655 objects, 79440 bytes
- ---- inter_tree 6 objects, 79296 bytes
+ ---- inter_tree 6 objects, 79344 bytes
---- label_namespace 1472 objects, 70656 bytes
---- rulebook 407 objects, 68376 bytes
---- spatial_data 671 objects, 64416 bytes
@@ -79,8 +79,8 @@ Total memory consumption was 120981K = 118 MB
---- ap_clause_array 2 x 400 = 800 objects, 51264 bytes
---- HTML_tag_array 1 x 1000 objects, 48032 bytes
---- text_substitution 437 objects, 41952 bytes
- ---- activity_list_array 1 x 1000 objects, 40032 bytes
---- anl_clause_array 1 x 1000 objects, 40032 bytes
+ ---- activity_list_array 1 x 1000 objects, 40032 bytes
---- to_family_data 497 objects, 39760 bytes
---- shared_variable_access_list_array 12 x 100 = 1200 objects, 38784 bytes
---- parsing_data 671 objects, 37576 bytes
@@ -107,8 +107,8 @@ Total memory consumption was 120981K = 118 MB
---- parse_node_tree 20 objects, 17280 bytes
---- understanding_reference_array 2 x 100 = 200 objects, 16064 bytes
---- to_phrase_request 59 objects, 16048 bytes
- ---- match_avinue_array 1 x 1000 objects, 16032 bytes
---- action_name_list_array 1 x 1000 objects, 16032 bytes
+ ---- match_avinue_array 1 x 1000 objects, 16032 bytes
---- JSON_value 182 objects, 16016 bytes
---- build_vertex 130 objects, 15600 bytes
---- adjective 137 objects, 15344 bytes
@@ -137,8 +137,8 @@ Total memory consumption was 120981K = 118 MB
---- section_md 45 objects, 4320 bytes
---- build_script 130 objects, 4160 bytes
---- compatibility_specification 86 objects, 4128 bytes
- ---- activity 35 objects, 3920 bytes
---- command_line_switch 49 objects, 3920 bytes
+ ---- activity 35 objects, 3920 bytes
---- submodule_request 94 objects, 3760 bytes
---- parse_node_annotation_type 114 objects, 3648 bytes
---- property_setting_bp_data 84 objects, 3360 bytes
@@ -183,8 +183,8 @@ Total memory consumption was 120981K = 118 MB
---- JSON_pair_requirement 26 objects, 832 bytes
---- phrase_option_array 1 x 100 objects, 824 bytes
---- inbuild_search_result 20 objects, 800 bytes
- ---- web_md 5 objects, 720 bytes
---- internal_test 15 objects, 720 bytes
+ ---- web_md 5 objects, 720 bytes
---- relation_guard 5 objects, 640 bytes
---- implication 13 objects, 624 bytes
---- code_generation 1 object, 576 bytes
@@ -192,42 +192,42 @@ Total memory consumption was 120981K = 118 MB
---- rulebook_outcome 17 objects, 544 bytes
---- small_word_set 11 objects, 528 bytes
---- inform_kit 5 objects, 520 bytes
- ---- equation 4 objects, 480 bytes
---- inform_language 6 objects, 480 bytes
+ ---- equation 4 objects, 480 bytes
---- i6_memory_setting 14 objects, 448 bytes
- ---- inference_family 11 objects, 440 bytes
---- chapter_md 5 objects, 440 bytes
+ ---- inference_family 11 objects, 440 bytes
---- bp_family 13 objects, 416 bytes
- ---- module 5 objects, 400 bytes
---- inter_annotation_form 10 objects, 400 bytes
+ ---- module 5 objects, 400 bytes
---- article_usage 8 objects, 384 bytes
---- source_file 5 objects, 360 bytes
---- inbuild_genre 7 objects, 336 bytes
+ ---- cached_kind_declaration 8 objects, 320 bytes
+ ---- module_request 8 objects, 320 bytes
---- grammatical_category 8 objects, 320 bytes
---- pronoun 8 objects, 320 bytes
- ---- cached_kind_declaration 8 objects, 320 bytes
---- door_dir_notice 5 objects, 320 bytes
- ---- module_request 8 objects, 320 bytes
- ---- tree_inventory 1 object, 312 bytes
---- inter_pipeline 1 object, 312 bytes
+ ---- tree_inventory 1 object, 312 bytes
---- up_family 9 objects, 288 bytes
- ---- compilation_unit 5 objects, 280 bytes
---- explicit_bp_data 5 objects, 280 bytes
- ---- contents_entry 7 objects, 280 bytes
---- door_to_notice 5 objects, 280 bytes
+ ---- contents_entry 7 objects, 280 bytes
+ ---- compilation_unit 5 objects, 280 bytes
---- verb_usage_tier 5 objects, 240 bytes
---- adjective_meaning_family 7 objects, 224 bytes
- ---- test_scenario 1 object, 216 bytes
---- inform_project 1 object, 216 bytes
+ ---- test_scenario 1 object, 216 bytes
---- release_instructions 1 object, 208 bytes
- ---- code_generator 5 objects, 200 bytes
---- build_skill 5 objects, 200 bytes
+ ---- code_generator 5 objects, 200 bytes
---- plural_dictionary_entry 4 objects, 192 bytes
---- kit_dependency 4 objects, 192 bytes
- ---- inference_subject_family 5 objects, 160 bytes
---- inter_architecture 4 objects, 160 bytes
- ---- imperative_defn_family 4 objects, 160 bytes
---- attachment_instruction 4 objects, 160 bytes
+ ---- imperative_defn_family 4 objects, 160 bytes
+ ---- inference_subject_family 5 objects, 160 bytes
---- element_activation 4 objects, 128 bytes
---- inbuild_nest 3 objects, 120 bytes
---- local_block_value 2 objects, 112 bytes
@@ -235,19 +235,19 @@ Total memory consumption was 120981K = 118 MB
---- group_together_function 2 objects, 80 bytes
---- compile_task_data 1 object, 80 bytes
---- article 2 objects, 80 bytes
- ---- figures_data 1 object, 56 bytes
---- inter_warehouse 1 object, 56 bytes
+ ---- figures_data 1 object, 56 bytes
---- build_methodology 1 object, 56 bytes
- ---- star_invention 1 object, 48 bytes
---- HTML_file_state 1 object, 48 bytes
- ---- loop_over_scope 1 object, 40 bytes
+ ---- star_invention 1 object, 48 bytes
+ ---- kind_template_definition 1 object, 40 bytes
---- I6_generation_data 1 object, 40 bytes
---- by_function_bp_data 1 object, 40 bytes
- ---- kind_template_definition 1 object, 40 bytes
+ ---- loop_over_scope 1 object, 40 bytes
100.0% was used for memory not allocated for objects:
- 56.8% text stream storage 70447848 bytes in 479132 claims
+ 56.8% text stream storage 70455588 bytes in 479200 claims
4.2% dictionary storage 5263872 bytes in 7588 claims
---- sorting 1520 bytes in 159 claims
5.8% source text 7200000 bytes in 3 claims
@@ -265,5 +265,5 @@ Total memory consumption was 120981K = 118 MB
---- code generation workspace for objects 1336 bytes in 4 claims
0.2% emitter array storage 280288 bytes in 1999 claims
--150.0% was overhead - -185923840 bytes = -181566K = -177 MB
+-150.0% was overhead - -185924032 bytes = -181566K = -177 MB
diff --git a/inform7/Figures/timings-diagnostics.txt b/inform7/Figures/timings-diagnostics.txt
index 02e59fec0..7b4506d37 100644
--- a/inform7/Figures/timings-diagnostics.txt
+++ b/inform7/Figures/timings-diagnostics.txt
@@ -1,7 +1,7 @@
100.0% in inform7 run
70.4% in compilation to Inter
- 50.5% in //Sequence::undertake_queued_tasks//
- 4.4% in //MajorNodes::pre_pass//
+ 50.0% in //Sequence::undertake_queued_tasks//
+ 4.6% in //MajorNodes::pre_pass//
3.4% in //MajorNodes::pass_1//
1.8% in //ImperativeDefinitions::assess_all//
1.4% in //RTKindConstructors::compile//
@@ -17,17 +17,17 @@
0.2% in //RTKindConstructors::compile_permissions//
0.2% in //Task::make_built_in_kind_constructors//
0.2% in //World::stages_II_and_III//
- 2.6% not specifically accounted for
- 26.6% in running Inter pipeline
+ 3.0% not specifically accounted for
+ 26.3% in running Inter pipeline
10.3% in step 14/15: generate inform6 -> auto.inf
- 5.9% in step 5/15: load-binary-kits
- 5.4% in step 6/15: make-synoptic-module
- 1.4% in step 9/15: make-identifiers-unique
+ 5.6% in step 5/15: load-binary-kits
+ 5.6% in step 6/15: make-synoptic-module
+ 1.6% in step 9/15: make-identifiers-unique
0.4% in step 12/15: eliminate-redundant-operations
0.4% in step 4/15: compile-splats
0.4% in step 7/15: shorten-wiring
0.4% in step 8/15: detect-indirect-calls
0.2% in step 11/15: eliminate-redundant-labels
- 1.6% not specifically accounted for
+ 1.2% not specifically accounted for
2.6% in supervisor
- 0.3% not specifically accounted for
+ 0.7% not specifically accounted for
diff --git a/inform7/Internal/Miscellany/registry.jsonr b/inform7/Internal/Miscellany/registry.jsonr
new file mode 100644
index 000000000..70523a265
--- /dev/null
+++ b/inform7/Internal/Miscellany/registry.jsonr
@@ -0,0 +1,25 @@
+ ::= {
+ "author": string,
+ "title": string,
+ ?"standard-installation": boolean,
+ ?"visible": boolean,
+ ?"forum-thread": number,
+ "version": string,
+ "summary": string,
+ "time": string
+}
+
+ ::= {
+ "title": string,
+ "holdings": [ * ]
+}
+
+ ::= {
+ "title": string,
+ "leafname": string,
+ "subsections": [ * ]
+}
+
+ ::= {
+ "sections": [ * ]
+}
diff --git a/inform7/Internal/Miscellany/metadata.jsonr b/inform7/Internal/Miscellany/resource.jsonr
similarity index 100%
rename from inform7/Internal/Miscellany/metadata.jsonr
rename to inform7/Internal/Miscellany/resource.jsonr
diff --git a/services/html-module/Chapter 2/Installed Files.w b/services/html-module/Chapter 2/Installed Files.w
index 0608f8e62..fcb7cf836 100644
--- a/services/html-module/Chapter 2/Installed Files.w
+++ b/services/html-module/Chapter 2/Installed Files.w
@@ -21,7 +21,8 @@ but they're just plain old files, and are not managed by Inbuild as "copies".
@e CSS_SET_BY_PLATFORM_IRES
@e CSS_FOR_STANDARD_PAGES_IRES
@e EXTENSION_DOCUMENTATION_MODEL_IRES
-@e JSON_REQUIREMENTS_IRES
+@e RESOURCE_JSON_REQS_IRES
+@e REGISTRY_JSON_REQS_IRES
=
filename *InstalledFiles::filename(int ires) {
@@ -39,8 +40,10 @@ filename *InstalledFiles::filename(int ires) {
return Filenames::in(misc, I"DefaultCover.jpg");
case SMALL_DEFAULT_COVER_ART_IRES:
return Filenames::in(misc, I"Small Cover.jpg");
- case JSON_REQUIREMENTS_IRES:
- return Filenames::in(misc, I"metadata.jsonr");
+ case RESOURCE_JSON_REQS_IRES:
+ return Filenames::in(misc, I"resource.jsonr");
+ case REGISTRY_JSON_REQS_IRES:
+ return Filenames::in(misc, I"registry.jsonr");
case CBLORB_REPORT_MODEL_IRES:
return InstalledFiles::varied_by_platform(models, I"CblorbModel.html");