1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-06-26 04:00:43 +03:00

Convoluted refactor of projects, adding Source to materials

This commit is contained in:
Graham Nelson 2020-02-11 23:20:14 +00:00
parent 62aa1026ae
commit 67c3f1a121
19 changed files with 319 additions and 215 deletions

View file

@ -66,9 +66,9 @@ int main(int argc, char **argv) {
}
WRITE_TO(STDOUT, "\n");
break;
case GRAPH_TTASK: Graphs::describe(STDOUT, C->graph, TRUE); break;
case BUILD_TTASK: Graphs::build(C->graph, BM); break;
case REBUILD_TTASK: Graphs::rebuild(C->graph, BM); break;
case GRAPH_TTASK: Graphs::describe(STDOUT, C->vertex, TRUE); break;
case BUILD_TTASK: Graphs::build(C->vertex, BM); break;
case REBUILD_TTASK: Graphs::rebuild(C->vertex, BM); break;
case COPY_TO_TTASK: if (destination_nest) Nests::copy_to(C, destination_nest, FALSE, BM); break;
case SYNC_TO_TTASK: if (destination_nest) Nests::copy_to(C, destination_nest, TRUE, BM); break;
}

View file

@ -17,7 +17,7 @@ Setting up the use of this module.
@e inbuild_edition_MT
@e inbuild_requirement_MT
@e inbuild_copy_MT
@e build_graph_MT
@e build_vertex_MT
@e build_methodology_MT
@e build_script_MT
@e build_step_MT
@ -41,7 +41,7 @@ ALLOCATE_INDIVIDUALLY(inbuild_work)
ALLOCATE_INDIVIDUALLY(inbuild_edition)
ALLOCATE_INDIVIDUALLY(inbuild_requirement)
ALLOCATE_INDIVIDUALLY(inbuild_copy)
ALLOCATE_INDIVIDUALLY(build_graph)
ALLOCATE_INDIVIDUALLY(build_vertex)
ALLOCATE_INDIVIDUALLY(build_methodology)
ALLOCATE_INDIVIDUALLY(build_script)
ALLOCATE_INDIVIDUALLY(build_step)

View file

@ -163,8 +163,12 @@ void SharedCLI::create_shared_project(void) {
shared_project = ProjectFileManager::from_copy(C);
}
@<Create the materials nest@>;
if (shared_project)
Projects::set_source_filename(shared_project, filename_of_i7_source);
if (shared_project) {
pathname *P = (shared_materials_nest)?(shared_materials_nest->location):NULL;
if (P) P = Pathnames::subfolder(P, I"Source");
if (Str::len(project_file_request) > 0) P = NULL;
Projects::set_source_filename(shared_project, P, filename_of_i7_source);
}
}
@<Create the materials nest@> =
@ -204,6 +208,30 @@ pathname *SharedCLI::pathname_of_materials(pathname *pathname_of_bundle) {
return materials;
}
@h Kit requests.
=
linked_list *kits_requested_at_command_line = NULL;
void SharedCLI::request_kit(text_stream *name) {
if (kits_requested_at_command_line == NULL)
kits_requested_at_command_line = NEW_LINKED_LIST(text_stream);
text_stream *kit_name;
LOOP_OVER_LINKED_LIST(kit_name, text_stream, kits_requested_at_command_line)
if (Str::eq(kit_name, name))
return;
ADD_TO_LINKED_LIST(Str::duplicate(name), text_stream, kits_requested_at_command_line);
}
void SharedCLI::pass_kit_requests(void) {
if ((shared_project) && (kits_requested_at_command_line)) {
text_stream *kit_name;
LOOP_OVER_LINKED_LIST(kit_name, text_stream, kits_requested_at_command_line) {
Projects::add_kit_dependency(shared_project, kit_name);
Projects::not_necessarily_parser_IF(shared_project);
}
}
}
@h Command line.
We add the following switches:
@ -243,7 +271,7 @@ void SharedCLI::option(int id, int val, text_stream *arg, void *state) {
case INTERNAL_CLSW: SharedCLI::add_nest(Pathnames::from_text(arg), INTERNAL_NEST_TAG); break;
case EXTERNAL_CLSW: SharedCLI::add_nest(Pathnames::from_text(arg), EXTERNAL_NEST_TAG); break;
case TRANSIENT_CLSW: shared_transient_resources = Pathnames::from_text(arg); break;
case KIT_CLSW: Kits::request(arg); break;
case KIT_CLSW: SharedCLI::request_kit(arg); break;
case PROJECT_CLSW:
if (SharedCLI::set_I7_bundle(arg) == FALSE)
Errors::fatal_with_text("can't specify the project twice: '%S'", arg);
@ -262,4 +290,5 @@ options remain to be processed.
void SharedCLI::optioneering_complete(void) {
SharedCLI::create_shared_project();
SharedCLI::sort_nest_list();
SharedCLI::pass_kit_requests();
}

View file

@ -13,48 +13,50 @@ belongs to a single copy, and internal vertices, each of which represents
a different file inside the copy.
=
typedef struct build_graph {
typedef struct build_vertex {
struct inbuild_copy *buildable_if_copy;
struct filename *buildable_if_internal_file;
struct linked_list *arrows; /* of pointers to other |build_graph| nodes */
struct text_stream *annotation;
struct linked_list *arrows; /* of pointers to other |build_vertex| nodes */
struct build_script *script;
time_t timestamp;
MEMORY_MANAGEMENT
} build_graph;
} build_vertex;
build_graph *Graphs::internal_vertex(filename *F) {
build_graph *G = CREATE(build_graph);
build_vertex *Graphs::internal_vertex(filename *F) {
build_vertex *G = CREATE(build_vertex);
G->buildable_if_copy = NULL;
G->buildable_if_internal_file = F;
G->arrows = NEW_LINKED_LIST(build_graph);
G->arrows = NEW_LINKED_LIST(build_vertex);
G->timestamp = (time_t) 0;
G->script = BuildSteps::new_script();
G->annotation = NULL;
return G;
}
build_graph *Graphs::copy_vertex(inbuild_copy *C) {
build_vertex *Graphs::copy_vertex(inbuild_copy *C) {
if (C == NULL) internal_error("no copy");
if (C->graph == NULL) {
C->graph = Graphs::internal_vertex(NULL);
C->graph->buildable_if_copy = C;
if (C->vertex == NULL) {
C->vertex = Graphs::internal_vertex(NULL);
C->vertex->buildable_if_copy = C;
}
return C->graph;
return C->vertex;
}
void Graphs::arrow(build_graph *from, build_graph *to) {
void Graphs::arrow(build_vertex *from, build_vertex *to) {
if (from == NULL) internal_error("no from");
if (to == NULL) internal_error("no to");
if (from == to) internal_error("graph node depends on itself");
build_graph *G;
LOOP_OVER_LINKED_LIST(G, build_graph, from->arrows)
build_vertex *G;
LOOP_OVER_LINKED_LIST(G, build_vertex, from->arrows)
if (G == to) return;
ADD_TO_LINKED_LIST(to, build_graph, from->arrows);
ADD_TO_LINKED_LIST(to, build_vertex, from->arrows);
}
void Graphs::describe(OUTPUT_STREAM, build_graph *G, int recurse) {
void Graphs::describe(OUTPUT_STREAM, build_vertex *G, int recurse) {
Graphs::describe_r(OUT, 0, G, recurse);
}
void Graphs::describe_r(OUTPUT_STREAM, int depth, build_graph *V, int recurse) {
void Graphs::describe_r(OUTPUT_STREAM, int depth, build_vertex *V, int recurse) {
for (int i=0; i<depth; i++) WRITE(" ");
if (V->buildable_if_copy) {
WRITE("[copy%d] ", V->allocation_id);
@ -67,13 +69,13 @@ void Graphs::describe_r(OUTPUT_STREAM, int depth, build_graph *V, int recurse) {
else WRITE("\n");
}
if (recurse) {
build_graph *W;
LOOP_OVER_LINKED_LIST(W, build_graph, V->arrows)
build_vertex *W;
LOOP_OVER_LINKED_LIST(W, build_vertex, V->arrows)
Graphs::describe_r(OUT, depth+1, W, TRUE);
}
}
void Graphs::update_timestamp(build_graph *V) {
void Graphs::update_timestamp(build_vertex *V) {
if (V == NULL) return;
if (V->buildable_if_internal_file == NULL) return;
char transcoded_pathname[4*MAX_FILENAME_LENGTH];
@ -86,23 +88,23 @@ void Graphs::update_timestamp(build_graph *V) {
V->timestamp = filestat.st_mtime;
}
void Graphs::build(build_graph *G, build_methodology *meth) {
void Graphs::build(build_vertex *G, build_methodology *meth) {
Graphs::build_r(FALSE, G, meth);
}
void Graphs::rebuild(build_graph *G, build_methodology *meth) {
void Graphs::rebuild(build_vertex *G, build_methodology *meth) {
Graphs::build_r(TRUE, G, meth);
}
void Graphs::build_r(int forcing_build, build_graph *V, build_methodology *meth) {
void Graphs::build_r(int forcing_build, build_vertex *V, build_methodology *meth) {
int needs_building = forcing_build;
if (V->buildable_if_internal_file)
if (TextFiles::exists(V->buildable_if_internal_file) == FALSE)
needs_building = TRUE;
build_graph *W;
LOOP_OVER_LINKED_LIST(W, build_graph, V->arrows)
build_vertex *W;
LOOP_OVER_LINKED_LIST(W, build_vertex, V->arrows)
Graphs::build_r(forcing_build, W, meth);
if (needs_building == FALSE) {
Graphs::update_timestamp(V);
LOOP_OVER_LINKED_LIST(W, build_graph, V->arrows) {
LOOP_OVER_LINKED_LIST(W, build_vertex, V->arrows) {
Graphs::update_timestamp(W);
double since = difftime(V->timestamp, W->timestamp);
if (since < 0) { needs_building = TRUE; break; }

View file

@ -69,7 +69,7 @@ typedef struct inbuild_copy {
struct pathname *location_if_path;
struct filename *location_if_file;
general_pointer content; /* the type of which depends on the work's genre */
struct build_graph *graph;
struct build_vertex *vertex;
MEMORY_MANAGEMENT
} inbuild_copy;
@ -79,7 +79,7 @@ inbuild_copy *Model::copy_in_file(inbuild_edition *edition, filename *F, general
copy->location_if_path = NULL;
copy->location_if_file = F;
copy->content = C;
copy->graph = NULL;
copy->vertex = NULL;
return copy;
}
@ -89,7 +89,7 @@ inbuild_copy *Model::copy_in_directory(inbuild_edition *edition, pathname *P, ge
copy->location_if_path = P;
copy->location_if_file = NULL;
copy->content = C;
copy->graph = NULL;
copy->vertex = NULL;
return copy;
}

View file

@ -86,7 +86,7 @@ inbuild_copy *ExtensionManager::claim_file_as_copy(filename *F, text_stream *err
Model::edition(Works::new(extension_genre, title, author), V), F);
if ((allow_malformed) || (Str::len(error_text) == 0)) {
Works::add_to_database(C->edition->work, CLAIMED_WDBC);
ExtensionManager::build_graph(C);
ExtensionManager::build_vertex(C);
} else {
C = NULL;
}
@ -348,6 +348,6 @@ The build graph for an extension is just a single node: you don't need to
build an extension at all.
=
void ExtensionManager::build_graph(inbuild_copy *C) {
void ExtensionManager::build_vertex(inbuild_copy *C) {
Graphs::copy_vertex(C);
}

View file

@ -85,7 +85,7 @@ inbuild_copy *KitManager::claim_folder_as_copy(pathname *P) {
filename *canary = Filenames::in_folder(P, I"kit_metadata.txt");
if (TextFiles::exists(canary)) {
inbuild_copy *C = KitManager::new_copy(Pathnames::directory_name(P), P);
KitManager::build_graph(C);
KitManager::build_vertex(C);
Works::add_to_database(C->edition->work, CLAIMED_WDBC);
return C;
}
@ -166,12 +166,12 @@ dependency on every section file of the web of Inform 6 source for the kit.
If there are $S$ sections then the graph has $S+5$ vertices and $4(S+1)$ edges.
=
void KitManager::build_graph(inbuild_copy *C) {
void KitManager::build_vertex(inbuild_copy *C) {
pathname *P = C->location_if_path;
build_graph *KV = Graphs::copy_vertex(C);
build_vertex *KV = Graphs::copy_vertex(C);
text_stream *archs[4] = { I"16", I"32", I"16d", I"32d" };
text_stream *binaries[4] = { I"arch-16.interb", I"arch-32.interb", I"arch-16d.interb", I"arch-32d.interb" };
build_graph *BV[4];
build_vertex *BV[4];
for (int i=0; i<4; i++) {
filename *FV = Filenames::in_folder(P, binaries[i]);
BV[i] = Graphs::internal_vertex(FV);
@ -181,7 +181,7 @@ void KitManager::build_graph(inbuild_copy *C) {
}
filename *contents_page = Filenames::in_folder(C->location_if_path, I"Contents.w");
build_graph *CV = Graphs::internal_vertex(contents_page);
build_vertex *CV = Graphs::internal_vertex(contents_page);
for (int i=0; i<4; i++) Graphs::arrow(BV[i], CV);
kit_contents_section_state CSS;
@ -192,7 +192,7 @@ void KitManager::build_graph(inbuild_copy *C) {
LOOP_OVER_LINKED_LIST(segment, text_stream, CSS.sects) {
filename *SF = Filenames::in_folder(
Pathnames::subfolder(C->location_if_path, I"Sections"), segment);
build_graph *SV = Graphs::internal_vertex(SF);
build_vertex *SV = Graphs::internal_vertex(SF);
for (int i=0; i<4; i++) Graphs::arrow(BV[i], SV);
}
}

View file

@ -92,7 +92,7 @@ inbuild_copy *LanguageManager::claim_folder_as_copy(pathname *P) {
filename *canary = Filenames::in_folder(P, I"about.txt");
if (TextFiles::exists(canary)) {
inbuild_copy *C = LanguageManager::new_copy(Pathnames::directory_name(P), P);
LanguageManager::build_graph(C);
LanguageManager::build_vertex(C);
Works::add_to_database(C->edition->work, CLAIMED_WDBC);
return C;
}
@ -170,6 +170,6 @@ The build graph for a language bundle is just a single node: you don't need to
build it at all.
=
void LanguageManager::build_graph(inbuild_copy *C) {
void LanguageManager::build_vertex(inbuild_copy *C) {
Graphs::copy_vertex(C);
}

View file

@ -75,7 +75,7 @@ inbuild_copy *PipelineManager::claim_file_as_copy(filename *F, text_stream *erro
Model::edition(Works::new_raw(pipeline_genre, unext, NULL), V), F);
DISCARD_TEXT(unext);
Works::add_to_database(C->edition->work, CLAIMED_WDBC);
PipelineManager::build_graph(C);
PipelineManager::build_vertex(C);
return C;
}
@ -152,6 +152,6 @@ The build graph for a pipeline is just a single node: you don't need to
build a pipeline at all.
=
void PipelineManager::build_graph(inbuild_copy *C) {
void PipelineManager::build_vertex(inbuild_copy *C) {
Graphs::copy_vertex(C);
}

View file

@ -58,7 +58,7 @@ void ProjectBundleManager::claim_as_copy(inbuild_genre *gen, inbuild_copy **C,
inbuild_copy *ProjectBundleManager::claim_folder_as_copy(pathname *P) {
inbuild_copy *C = ProjectBundleManager::new_copy(Pathnames::directory_name(P), P);
ProjectBundleManager::build_graph(C);
ProjectBundleManager::build_vertex(C);
Works::add_to_database(C->edition->work, CLAIMED_WDBC);
return C;
}
@ -87,6 +87,6 @@ void ProjectBundleManager::copy_to_nest(inbuild_genre *gen, inbuild_copy *C, inb
The build graph for a project will need further thought.
=
void ProjectBundleManager::build_graph(inbuild_copy *C) {
void ProjectBundleManager::build_vertex(inbuild_copy *C) {
Graphs::copy_vertex(C);
}

View file

@ -61,7 +61,7 @@ void ProjectFileManager::claim_as_copy(inbuild_genre *gen, inbuild_copy **C,
inbuild_copy *ProjectFileManager::claim_file_as_copy(filename *F) {
inbuild_copy *C = ProjectFileManager::new_copy(Filenames::get_leafname(F), F);
ProjectFileManager::build_graph(C);
ProjectFileManager::build_vertex(C);
Works::add_to_database(C->edition->work, CLAIMED_WDBC);
return C;
}
@ -90,6 +90,6 @@ void ProjectFileManager::copy_to_nest(inbuild_genre *gen, inbuild_copy *C, inbui
The build graph for a project will need further thought.
=
void ProjectFileManager::build_graph(inbuild_copy *C) {
void ProjectFileManager::build_vertex(inbuild_copy *C) {
Graphs::copy_vertex(C);
}

View file

@ -68,7 +68,7 @@ inbuild_copy *TemplateManager::claim_folder_as_copy(pathname *P) {
filename *canary2 = Filenames::in_folder(P, I"index.html");
if ((TextFiles::exists(canary1)) || (TextFiles::exists(canary2))) {
inbuild_copy *C = TemplateManager::new_copy(Pathnames::directory_name(P), P);
TemplateManager::build_graph(C);
TemplateManager::build_vertex(C);
Works::add_to_database(C->edition->work, CLAIMED_WDBC);
return C;
}
@ -148,6 +148,6 @@ The build graph for a template is just a single node: you don't need to
build a template at all.
=
void TemplateManager::build_graph(inbuild_copy *C) {
void TemplateManager::build_vertex(inbuild_copy *C) {
Graphs::copy_vertex(C);
}

View file

@ -73,7 +73,7 @@ inform_kit *Kits::load(text_stream *name, linked_list *nest_list) {
pathname *P = Kits::find(name, nest_list);
if (P == NULL) Errors::fatal_with_text("cannot find kit", name);
inbuild_copy *C = KitManager::new_copy(name, P);
KitManager::build_graph(C);
if (C->vertex == NULL) KitManager::build_vertex(C);
return KitManager::from_copy(C);
}
@ -133,165 +133,63 @@ void Kits::read_metadata(text_stream *text, text_file_position *tfp, void *state
Regexp::dispose_of(&mr);
}
int Kits::loaded(text_stream *name) {
inform_kit *K;
LOOP_OVER(K, inform_kit)
if (Str::eq(K->name, name))
return TRUE;
return FALSE;
}
void Kits::perform_ittt(linked_list *nest_list) {
int changes_made = TRUE;
while (changes_made) {
changes_made = FALSE;
inform_kit *K;
LOOP_OVER(K, inform_kit) {
inform_kit_ittt *ITTT;
LOOP_OVER_LINKED_LIST(ITTT, inform_kit_ittt, K->ittt)
if ((Kits::loaded(ITTT->then_name) == FALSE) &&
(Kits::loaded(ITTT->if_name) == ITTT->if_included)) {
Kits::load(ITTT->then_name, nest_list);
changes_made = TRUE;
}
int Kits::perform_ittt(inform_kit *K, inform_project *project, int parity) {
int changes_made = FALSE;
inform_kit_ittt *ITTT;
LOOP_OVER_LINKED_LIST(ITTT, inform_kit_ittt, K->ittt)
if ((ITTT->if_included == parity) &&
(Projects::uses_kit(project, ITTT->then_name) == FALSE) &&
(Projects::uses_kit(project, ITTT->if_name) == ITTT->if_included)) {
Projects::add_kit_dependency(project, ITTT->then_name);
changes_made = TRUE;
}
}
}
linked_list *kits_requested = NULL;
linked_list *kits_to_include = NULL;
void Kits::request(text_stream *name) {
if (kits_requested == NULL) kits_requested = NEW_LINKED_LIST(text_stream);
text_stream *kit_name;
LOOP_OVER_LINKED_LIST(kit_name, text_stream, kits_requested)
if (Str::eq(kit_name, name))
return;
ADD_TO_LINKED_LIST(Str::duplicate(name), text_stream, kits_requested);
return changes_made;
}
#ifdef CORE_MODULE
void Kits::determine(void) {
linked_list *nest_list = SharedCLI::nest_list();
if (kits_requested == NULL) Kits::request(I"CommandParserKit");
Kits::request(I"BasicInformKit");
Languages::request_required_kits();
text_stream *kit_name;
LOOP_OVER_LINKED_LIST(kit_name, text_stream, kits_requested)
Kits::load(kit_name, nest_list);
Kits::perform_ittt(nest_list);
kits_to_include = NEW_LINKED_LIST(inform_kit);
for (int p=0; p<100; p++) {
inform_kit *K;
LOOP_OVER(K, inform_kit)
if (K->priority == p)
ADD_TO_LINKED_LIST(K, inform_kit, kits_to_include);
}
inform_kit *K;
LOOP_OVER_LINKED_LIST(K, inform_kit, kits_to_include)
LOG("Using Inform kit '%S' (priority %d).\n", K->name, K->priority);
}
#endif
#ifdef CORE_MODULE
void Kits::load_types(void) {
inform_kit *K;
LOOP_OVER_LINKED_LIST(K, inform_kit, kits_to_include) {
text_stream *segment;
LOOP_OVER_LINKED_LIST(segment, text_stream, K->kind_definitions) {
pathname *P = Pathnames::subfolder(K->as_copy->location_if_path, I"kinds");
filename *F = Filenames::in_folder(P, segment);
LOG("Loading kinds definitions from %f\n", F);
I6T::interpret_kindt(F);
}
void Kits::load_types(inform_kit *K) {
text_stream *segment;
LOOP_OVER_LINKED_LIST(segment, text_stream, K->kind_definitions) {
pathname *P = Pathnames::subfolder(K->as_copy->location_if_path, I"kinds");
filename *F = Filenames::in_folder(P, segment);
LOG("Loading kinds definitions from %f\n", F);
I6T::interpret_kindt(F);
}
}
#endif
#ifdef CORE_MODULE
void Kits::activate_plugins(void) {
LOG("Activate plugins...\n");
Plugins::Manage::activate(CORE_PLUGIN_NAME);
inform_kit *K;
LOOP_OVER_LINKED_LIST(K, inform_kit, kits_to_include) {
element_activation *EA;
LOOP_OVER_LINKED_LIST(EA, element_activation, K->activations) {
int S = Plugins::Manage::parse(EA->element_name);
if (S == -1)
Problems::Issue::sentence_problem(_p_(Untestable),
"one of the Inform kits made reference to a language segment which does not exist",
"which strongly suggests that Inform is not properly installed.");
if (S >= 0) {
if (EA->activate) Plugins::Manage::activate(S);
else Plugins::Manage::deactivate(S);
}
void Kits::activate_plugins(inform_kit *K) {
element_activation *EA;
LOOP_OVER_LINKED_LIST(EA, element_activation, K->activations) {
int S = Plugins::Manage::parse(EA->element_name);
if (S == -1)
Problems::Issue::sentence_problem(_p_(Untestable),
"one of the Inform kits made reference to a language segment which does not exist",
"which strongly suggests that Inform is not properly installed.");
if (S >= 0) {
if (EA->activate) Plugins::Manage::activate(S);
else Plugins::Manage::deactivate(S);
}
}
Plugins::Manage::show(DL, "Included", TRUE);
Plugins::Manage::show(DL, "Excluded", FALSE);
}
#endif
int Kits::Main_defined(void) {
inform_kit *K;
LOOP_OVER_LINKED_LIST(K, inform_kit, kits_to_include)
if (K->defines_Main)
return TRUE;
return FALSE;
void Kits::early_source_text(OUTPUT_STREAM, inform_kit *K) {
text_stream *X;
LOOP_OVER_LINKED_LIST(X, text_stream, K->extensions)
WRITE("Include %S.\n\n", X);
if (K->early_source) WRITE("%S\n\n", K->early_source);
}
text_stream *Kits::index_template(void) {
text_stream *I = NULL;
inform_kit *K;
LOOP_OVER_LINKED_LIST(K, inform_kit, kits_to_include)
if (K->index_template)
I = K->index_template;
return I;
}
@ Every source text read into Inform is automatically prefixed by a few words
loading the fundamental "extensions" -- text such as "Include Basic Inform by
Graham Nelson." If Inform were a computer, this would be the BIOS which boots
up its operating system. Each kit can contribute such extensions, so there
may be multiple sentences, which we need to count up.
=
void Kits::feed_early_source_text(OUTPUT_STREAM) {
inform_kit *K;
LOOP_OVER_LINKED_LIST(K, inform_kit, kits_to_include) {
text_stream *X;
LOOP_OVER_LINKED_LIST(X, text_stream, K->extensions)
WRITE("Include %S.\n\n", X);
if (K->early_source) WRITE("%S\n\n", K->early_source);
}
}
int Kits::number_of_early_fed_sentences(void) {
int Kits::number_of_early_fed_sentences(inform_kit *K) {
int N = 0;
inform_kit *K;
LOOP_OVER_LINKED_LIST(K, inform_kit, kits_to_include) {
text_stream *X;
LOOP_OVER_LINKED_LIST(X, text_stream, K->extensions) N++;
if (K->early_source) N++;
}
text_stream *X;
LOOP_OVER_LINKED_LIST(X, text_stream, K->extensions) N++;
if (K->early_source) N++;
return N;
}
#ifdef CODEGEN_MODULE
linked_list *requirements_list = NULL;
linked_list *Kits::list_of_inter_libraries(void) {
requirements_list = NEW_LINKED_LIST(link_instruction);
inform_kit *K;
LOOP_OVER_LINKED_LIST(K, inform_kit, kits_to_include) {
link_instruction *link = CodeGen::LinkInstructions::new(
K->as_copy->location_if_path, K->attachment_point);
ADD_TO_LINKED_LIST(link, link_instruction, requirements_list);
}
return requirements_list;
}
#endif
linked_list *Kits::inter_paths(void) {
linked_list *inter_paths = NEW_LINKED_LIST(pathname);
inbuild_nest *N;

View file

@ -125,7 +125,7 @@ that's the language in which the SR are written, and French Language, because
that's the language of play.
=
void Languages::request_required_kits(void) {
void Languages::request_required_kits(inform_project *project) {
inform_language *L;
LOOP_OVER(L, inform_language)
if (L->kit_required) {
@ -134,7 +134,7 @@ void Languages::request_required_kits(void) {
WRITE_TO(TEMP, "%+W", L->language_field[KIT_LFIELD]);
else
WRITE_TO(TEMP, "%+WLanguageKit", L->language_field[NAME_IN_ENGLISH_LFIELD]);
Kits::request(TEMP);
Projects::add_kit_dependency(project, TEMP);
DISCARD_TEXT(TEMP);
}
}

View file

@ -6,19 +6,54 @@ An Inform 7 project.
typedef struct inform_project {
struct inbuild_copy *as_copy;
struct inbuild_version_number version;
struct filename *source_text;
struct linked_list *source_vertices; /* of |build_vertex| */
int assumed_to_be_parser_IF;
struct linked_list *kits_to_include; /* of |inform_kit| */
MEMORY_MANAGEMENT
} inform_project;
inform_project *Projects::new_ip(text_stream *name, filename *F, pathname *P) {
inform_project *T = CREATE(inform_project);
T->as_copy = NULL;
T->version = VersionNumbers::null();
return T;
inform_project *project = CREATE(inform_project);
project->as_copy = NULL;
project->version = VersionNumbers::null();
project->source_vertices = NEW_LINKED_LIST(build_vertex);
project->kits_to_include = NEW_LINKED_LIST(inform_kit);
project->assumed_to_be_parser_IF = TRUE;
return project;
}
void Projects::set_source_filename(inform_project *project, filename *F) {
project->source_text = F;
void Projects::not_necessarily_parser_IF(inform_project *project) {
project->assumed_to_be_parser_IF = FALSE;
}
void Projects::set_source_filename(inform_project *project, pathname *P, filename *F) {
if (P) {
filename *manifest = Filenames::in_folder(P, I"Contents.txt");
linked_list *L = NEW_LINKED_LIST(text_stream);
TextFiles::read(manifest, FALSE,
NULL, FALSE, Projects::manifest_helper, NULL, (void *) L);
text_stream *leafname;
LOOP_OVER_LINKED_LIST(leafname, text_stream, L) {
build_vertex *S = Graphs::internal_vertex(Filenames::in_folder(P, leafname));
S->annotation = leafname;
ADD_TO_LINKED_LIST(S, build_vertex, project->source_vertices);
}
}
if ((LinkedLists::len(project->source_vertices) == 0) && (F)) {
build_vertex *S = Graphs::internal_vertex(F);
S->annotation = I"your source text";
ADD_TO_LINKED_LIST(S, build_vertex, project->source_vertices);
}
}
// Graphs::arrow(project->as_copy->vertex, S);
void Projects::manifest_helper(text_stream *text, text_file_position *tfp, void *state) {
linked_list *L = (linked_list *) state;
Str::trim_white_space(text);
wchar_t c = Str::get_first_char(text);
if ((c == 0) || (c == '#')) return;
ADD_TO_LINKED_LIST(Str::duplicate(text), text_stream, L);
}
pathname *Projects::path(inform_project *project) {
@ -26,7 +61,129 @@ pathname *Projects::path(inform_project *project) {
return project->as_copy->location_if_path;
}
filename *Projects::source(inform_project *project) {
linked_list *Projects::source(inform_project *project) {
if (project == NULL) return NULL;
return project->source_text;
return project->source_vertices;
}
void Projects::add_kit_dependency(inform_project *project, text_stream *kit_name) {
if (Projects::uses_kit(project, kit_name)) return;
linked_list *nest_list = SharedCLI::nest_list();
inform_kit *kit = Kits::load(kit_name, nest_list);
ADD_TO_LINKED_LIST(kit, inform_kit, project->kits_to_include);
}
int Projects::uses_kit(inform_project *project, text_stream *name) {
inform_kit *K;
LOOP_OVER_LINKED_LIST(K, inform_kit, project->kits_to_include)
if (Str::eq(K->name, name))
return TRUE;
return FALSE;
}
void Projects::finalise_kit_dependencies(inform_project *project) {
Projects::add_kit_dependency(project, I"BasicInformKit");
Languages::request_required_kits(project);
if (project->assumed_to_be_parser_IF)
Projects::add_kit_dependency(project, I"CommandParserKit");
int parity = TRUE;
@<Perform if-this-then-that@>;
parity = FALSE;
@<Perform if-this-then-that@>;
linked_list *sorted = NEW_LINKED_LIST(inform_kit);
for (int p=0; p<100; p++) {
inform_kit *K;
LOOP_OVER_LINKED_LIST(K, inform_kit, project->kits_to_include)
if (K->priority == p)
ADD_TO_LINKED_LIST(K, inform_kit, sorted);
}
project->kits_to_include = sorted;
inform_kit *K;
LOOP_OVER_LINKED_LIST(K, inform_kit, project->kits_to_include)
LOG("Using Inform kit '%S' (priority %d).\n", K->name, K->priority);
}
@<Perform if-this-then-that@> =
int changes_made = TRUE;
while (changes_made) {
changes_made = FALSE;
inform_kit *K;
LOOP_OVER_LINKED_LIST(K, inform_kit, project->kits_to_include)
if (Kits::perform_ittt(K, project, parity))
changes_made = TRUE;
}
@ =
#ifdef CORE_MODULE
void Projects::load_types(inform_project *project) {
inform_kit *K;
LOOP_OVER_LINKED_LIST(K, inform_kit, project->kits_to_include)
Kits::load_types(K);
}
#endif
#ifdef CORE_MODULE
void Projects::activate_plugins(inform_project *project) {
LOG("Activate plugins...\n");
Plugins::Manage::activate(CORE_PLUGIN_NAME);
inform_kit *K;
LOOP_OVER_LINKED_LIST(K, inform_kit, project->kits_to_include)
Kits::activate_plugins(K);
Plugins::Manage::show(DL, "Included", TRUE);
Plugins::Manage::show(DL, "Excluded", FALSE);
}
#endif
int Projects::Main_defined(inform_project *project) {
inform_kit *K;
LOOP_OVER_LINKED_LIST(K, inform_kit, project->kits_to_include)
if (K->defines_Main)
return TRUE;
return FALSE;
}
text_stream *Projects::index_template(inform_project *project) {
text_stream *I = NULL;
inform_kit *K;
LOOP_OVER_LINKED_LIST(K, inform_kit, project->kits_to_include)
if (K->index_template)
I = K->index_template;
return I;
}
@ Every source text read into Inform is automatically prefixed by a few words
loading the fundamental "extensions" -- text such as "Include Basic Inform by
Graham Nelson." If Inform were a computer, this would be the BIOS which boots
up its operating system. Each kit can contribute such extensions, so there
may be multiple sentences, which we need to count up.
=
void Projects::early_source_text(OUTPUT_STREAM, inform_project *project) {
inform_kit *K;
LOOP_OVER_LINKED_LIST(K, inform_kit, project->kits_to_include)
Kits::early_source_text(OUT, K);
}
int Projects::number_of_early_fed_sentences(inform_project *project) {
int N = 0;
inform_kit *K;
LOOP_OVER_LINKED_LIST(K, inform_kit, project->kits_to_include)
N += Kits::number_of_early_fed_sentences(K);
return N;
}
#ifdef CODEGEN_MODULE
linked_list *Projects::list_of_inter_libraries(inform_project *project) {
linked_list *requirements_list = NEW_LINKED_LIST(link_instruction);
inform_kit *K;
LOOP_OVER_LINKED_LIST(K, inform_kit, project->kits_to_include) {
link_instruction *link = CodeGen::LinkInstructions::new(
K->as_copy->location_if_path, K->attachment_point);
ADD_TO_LINKED_LIST(link, link_instruction, requirements_list);
}
return requirements_list;
}
#endif

View file

@ -212,7 +212,7 @@ list is not exhaustive.
doc_references_top = lexer_wordcount - 1;
@<Work out our kit requirements@> =
Kits::determine();
Projects::finalise_kit_dependencies(SharedCLI::project());
@<Perform lexical analysis@> =
ProgressBar::update_progress_bar(0, 0);
@ -223,7 +223,7 @@ list is not exhaustive.
@<Perform semantic analysis@> =
ProgressBar::update_progress_bar(1, 0);
if (problem_count == 0) CoreMain::go_to_log_phase(I"Semantic analysis Ia");
COMPILATION_STEP(Kits::activate_plugins, I"Kits::activate_plugins");
Projects::activate_plugins(SharedCLI::project());
COMPILATION_STEP(ParseTreeUsage::plant_parse_tree, I"ParseTreeUsage::plant_parse_tree")
COMPILATION_STEP(StructuralSentences::break_source, I"StructuralSentences::break_source")
COMPILATION_STEP(Extensions::Inclusion::traverse, I"Extensions::Inclusion::traverse")
@ -231,7 +231,7 @@ list is not exhaustive.
if (problem_count == 0) CoreMain::go_to_log_phase(I"Initialise language semantics");
COMPILATION_STEP(Plugins::Manage::start_plugins, I"Plugins::Manage::start_plugins");
COMPILATION_STEP(Kits::load_types, I"Kits::load_types");
Projects::load_types(SharedCLI::project());
COMPILATION_STEP(BinaryPredicates::make_built_in, I"BinaryPredicates::make_built_in")
COMPILATION_STEP(NewVerbs::add_inequalities, I"NewVerbs::add_inequalities")
@ -368,7 +368,7 @@ with "Output.i6t".
COMPILATION_STEP(Lists::check, I"Lists::check")
COMPILATION_STEP(Lists::compile, I"Lists::compile")
if (Kits::Main_defined() == FALSE)
if (Projects::Main_defined(SharedCLI::project()) == FALSE)
COMPILATION_STEP(Phrases::invoke_to_begin, I"Phrases::invoke_to_begin")
COMPILATION_STEP(Phrases::Manager::compile_as_needed, I"Phrases::Manager::compile_as_needed")
COMPILATION_STEP(Strings::compile_responses, I"Strings::compile_responses")
@ -450,7 +450,7 @@ with "Output.i6t".
}
CodeGen::Pipeline::set_repository(SS, Emit::tree());
CodeGen::Pipeline::run(Filenames::get_path_to(filename_of_compiled_i6_code),
SS, Kits::inter_paths(), Kits::list_of_inter_libraries());
SS, Kits::inter_paths(), Projects::list_of_inter_libraries(SharedCLI::project()));
}
LOG("Back end elapsed time: %dcs\n", ((int) (clock() - front_end)) / (CLOCKS_PER_SEC/100));
}

View file

@ -69,7 +69,7 @@ inform_language *NaturalLanguages::English(void) {
void NaturalLanguages::produce_index(void) {
I6T::interpret_indext(
Filenames::in_folder(
Languages::path_to_bundle(language_of_index), Kits::index_template()));
Languages::path_to_bundle(language_of_index), Projects::index_template(SharedCLI::project())));
}
@

View file

@ -30,11 +30,29 @@ int SourceFiles::read_extension_source_text(extension_file *EF,
void SourceFiles::read_primary_source_text(void) {
TEMPORARY_TEXT(early);
Kits::feed_early_source_text(early);
Projects::early_source_text(early, SharedCLI::project());
if (Str::len(early) > 0) Feeds::feed_stream(early);
DISCARD_TEXT(early);
SourceFiles::read_further_mandatory_text();
SourceFiles::read_file(Projects::source(SharedCLI::project()), I"your source text", NULL, FALSE);
linked_list *L = Projects::source(SharedCLI::project());
if (L) {
build_vertex *N;
LOOP_OVER_LINKED_LIST(N, build_vertex, L) {
filename *F = N->buildable_if_internal_file;
if (TextFiles::exists(F) == FALSE) {
Problems::quote_stream(1, Filenames::get_leafname(F));
Problems::Issue::handmade_problem(_p_(Untestable));
Problems::issue_problem_segment(
"I can't open the file '%1' of source text. %P"
"If you are using the 'Source' subfolder of Materials to "
"hold your source text, maybe your 'Contents.txt' has a "
"typo in it?");
Problems::issue_problem_end();
} else {
SourceFiles::read_file(F, N->annotation, NULL, FALSE);
}
}
}
}
@ The following reads in the text of the optional file of use options, if

View file

@ -453,7 +453,7 @@ source texts implicitly begin with an inclusion of the Standard Rules.)
<if-start-of-source-text> internal 0 {
int w1 = Wordings::first_wn(W);
#ifdef CORE_MODULE
int N = 1 + Kits::number_of_early_fed_sentences();
int N = 1 + Projects::number_of_early_fed_sentences(SharedCLI::project());
#endif
#ifndef CORE_MODULE
int N = 3;