mirror of
https://github.com/ganelson/inform.git
synced 2024-06-29 05:24:57 +03:00
Improved project dependency graph
This commit is contained in:
parent
de0965a93e
commit
5a16b16e12
|
@ -20,7 +20,7 @@ pathname *path_to_inbuild = NULL;
|
|||
pathname *path_to_tools = NULL;
|
||||
|
||||
int inbuild_task = INSPECT_TTASK;
|
||||
int dry_run_mode = FALSE;
|
||||
int dry_run_mode = FALSE, build_trace_mode = FALSE;
|
||||
linked_list *targets = NULL; /* of |inbuild_copy| */
|
||||
inbuild_nest *destination_nest = NULL;
|
||||
text_stream *filter_text = NULL;
|
||||
|
@ -43,6 +43,7 @@ int main(int argc, char **argv) {
|
|||
build_methodology *BM;
|
||||
if (path_to_tools) BM = BuildMethodology::new(path_to_tools, FALSE, use);
|
||||
else BM = BuildMethodology::new(Pathnames::up(path_to_inbuild), TRUE, use);
|
||||
if (build_trace_mode) trace_ibg = TRUE;
|
||||
if (Str::len(unit_test) > 0) {
|
||||
if (Str::eq(unit_test, I"compatibility")) Compatibility::test(STDOUT);
|
||||
else if (Str::eq(unit_test, I"semver")) VersionNumbers::test(STDOUT);
|
||||
|
@ -93,6 +94,7 @@ int main(int argc, char **argv) {
|
|||
@e NEEDS_CLSW
|
||||
@e INSPECT_CLSW
|
||||
@e DRY_CLSW
|
||||
@e BUILD_TRACE_CLSW
|
||||
@e TOOLS_CLSW
|
||||
@e CONTENTS_OF_CLSW
|
||||
@e MATCHING_CLSW
|
||||
|
@ -122,6 +124,8 @@ int main(int argc, char **argv) {
|
|||
L"make X the directory of intools executables, and exit developer mode");
|
||||
CommandLine::declare_boolean_switch(DRY_CLSW, L"dry", 1,
|
||||
L"make this a dry run (print but do not execute shell commands)", FALSE);
|
||||
CommandLine::declare_boolean_switch(BUILD_TRACE_CLSW, L"build-trace", 1,
|
||||
L"show verbose reasoning during -build", FALSE);
|
||||
CommandLine::declare_switch(MATCHING_CLSW, L"matching", 2,
|
||||
L"apply to all works in nest(s) matching requirement X");
|
||||
CommandLine::declare_switch(CONTENTS_OF_CLSW, L"contents-of", 2,
|
||||
|
@ -175,6 +179,7 @@ void Main::option(int id, int val, text_stream *arg, void *state) {
|
|||
case MATCHING_CLSW: filter_text = Str::duplicate(arg); break;
|
||||
case CONTENTS_OF_CLSW: Main::load_many(Pathnames::from_text(arg)); break;
|
||||
case DRY_CLSW: dry_run_mode = val; break;
|
||||
case BUILD_TRACE_CLSW: build_trace_mode = val; break;
|
||||
case COPY_TO_CLSW: inbuild_task = COPY_TO_TTASK;
|
||||
destination_nest = Nests::new(Pathnames::from_text(arg));
|
||||
break;
|
||||
|
|
|
@ -542,7 +542,7 @@ void Inbuild::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::add_kit_dependency(shared_project, kit_name, NULL, NULL);
|
||||
Projects::not_necessarily_parser_IF(shared_project);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ Setting up the use of this module.
|
|||
@e known_extension_clash_MT
|
||||
@e build_skill_MT
|
||||
@e control_structure_phrase_MT
|
||||
@e kit_dependency_MT
|
||||
|
||||
=
|
||||
ALLOCATE_INDIVIDUALLY(heading)
|
||||
|
@ -65,6 +66,7 @@ ALLOCATE_INDIVIDUALLY(extension_dictionary_entry)
|
|||
ALLOCATE_INDIVIDUALLY(known_extension_clash)
|
||||
ALLOCATE_INDIVIDUALLY(build_skill)
|
||||
ALLOCATE_INDIVIDUALLY(control_structure_phrase)
|
||||
ALLOCATE_INDIVIDUALLY(kit_dependency)
|
||||
|
||||
ALLOCATE_IN_ARRAYS(inbuild_work_database_entry, 100)
|
||||
|
||||
|
@ -122,6 +124,8 @@ void InbuildModule::end(void) {
|
|||
@ =
|
||||
DECLARE_ANNOTATION_FUNCTIONS(embodying_heading, heading)
|
||||
MAKE_ANNOTATION_FUNCTIONS(embodying_heading, heading)
|
||||
DECLARE_ANNOTATION_FUNCTIONS(inclusion_of_extension, inform_extension)
|
||||
MAKE_ANNOTATION_FUNCTIONS(inclusion_of_extension, inform_extension)
|
||||
|
||||
heading *InbuildModule::heading(parse_node *PN) {
|
||||
return ParseTree::get_embodying_heading(PN);
|
||||
|
|
|
@ -9,7 +9,6 @@ with a given title, and/or version number.
|
|||
typedef struct inbuild_requirement {
|
||||
struct inbuild_work *work;
|
||||
struct semver_range *version_range;
|
||||
int allow_malformed;
|
||||
MEMORY_MANAGEMENT
|
||||
} inbuild_requirement;
|
||||
|
||||
|
@ -17,7 +16,6 @@ inbuild_requirement *Requirements::new(inbuild_work *work, semver_range *R) {
|
|||
inbuild_requirement *req = CREATE(inbuild_requirement);
|
||||
req->work = work;
|
||||
req->version_range = R;
|
||||
req->allow_malformed = FALSE;
|
||||
return req;
|
||||
}
|
||||
|
||||
|
@ -57,11 +55,6 @@ inbuild_requirement *Requirements::from_text(text_stream *T, text_stream *errors
|
|||
|
||||
void Requirements::impose_clause(inbuild_requirement *req, text_stream *T, text_stream *errors) {
|
||||
Str::trim_white_space(T);
|
||||
if (Str::get_last_char(T) == '*') {
|
||||
req->allow_malformed = TRUE;
|
||||
Str::delete_last_character(T);
|
||||
Str::trim_white_space(T);
|
||||
}
|
||||
if (Str::eq(T, I"all")) return;
|
||||
|
||||
TEMPORARY_TEXT(clause);
|
||||
|
@ -145,7 +138,6 @@ void Requirements::write(OUTPUT_STREAM, inbuild_requirement *req) {
|
|||
WRITE("range="); VersionNumbers::write_range(OUT, req->version_range);
|
||||
}
|
||||
if (claused == FALSE) WRITE("all");
|
||||
if (req->allow_malformed) WRITE("*");
|
||||
}
|
||||
|
||||
int Requirements::meets(inbuild_edition *edition, inbuild_requirement *req) {
|
||||
|
@ -155,7 +147,6 @@ int Requirements::meets(inbuild_edition *edition, inbuild_requirement *req) {
|
|||
if (req->work->genre != edition->work->genre)
|
||||
return FALSE;
|
||||
}
|
||||
if ((req->allow_malformed) && (Str::len(edition->work->title) == 0)) return TRUE;
|
||||
if (Str::len(req->work->title) > 0) {
|
||||
if (Str::ne_insensitive(req->work->title, edition->work->title))
|
||||
return FALSE;
|
||||
|
|
|
@ -153,12 +153,21 @@ void Graphs::show_needs(OUTPUT_STREAM, build_vertex *V) {
|
|||
void Graphs::show_needs_r(OUTPUT_STREAM, build_vertex *V, int depth, int true_depth) {
|
||||
if (V->type == COPY_VERTEX) {
|
||||
for (int i=0; i<depth; i++) WRITE(" ");
|
||||
Copies::write_copy(OUT, V->buildable_if_copy); WRITE("\n");
|
||||
inbuild_copy *C = V->buildable_if_copy;
|
||||
WRITE("%S: ", C->edition->work->genre->genre_name);
|
||||
Copies::write_copy(OUT, C); WRITE("\n");
|
||||
depth++;
|
||||
}
|
||||
if (V->type == REQUIREMENT_VERTEX) {
|
||||
for (int i=0; i<depth; i++) WRITE(" ");
|
||||
Requirements::write(OUT, V->findable); WRITE("\n");
|
||||
WRITE("missing %S: ", V->findable->work->genre->genre_name);
|
||||
Works::write(OUT, V->findable->work);
|
||||
if (VersionNumbers::is_any_range(V->findable->version_range) == FALSE) {
|
||||
WRITE(", need version in range "); VersionNumbers::write_range(OUT, V->findable->version_range);
|
||||
} else {
|
||||
WRITE(", any version will do");
|
||||
}
|
||||
WRITE("\n");
|
||||
depth++;
|
||||
}
|
||||
build_vertex *W;
|
||||
|
@ -223,36 +232,43 @@ time_t Graphs::time_of_most_recent_used_resource(build_vertex *V) {
|
|||
|
||||
=
|
||||
int Graphs::build(OUTPUT_STREAM, build_vertex *V, build_methodology *meth) {
|
||||
return Graphs::build_r(OUT, BUILD_GB, V, meth);
|
||||
int changes = 0;
|
||||
return Graphs::build_r(OUT, BUILD_GB, V, meth, &changes);
|
||||
}
|
||||
int Graphs::rebuild(OUTPUT_STREAM, build_vertex *V, build_methodology *meth) {
|
||||
return Graphs::build_r(OUT, BUILD_GB + FORCE_GB, V, meth);
|
||||
int changes = 0;
|
||||
return Graphs::build_r(OUT, BUILD_GB + FORCE_GB, V, meth, &changes);
|
||||
}
|
||||
int trace_ibg = FALSE;
|
||||
int Graphs::build_r(OUTPUT_STREAM, int gb, build_vertex *V, build_methodology *meth) {
|
||||
if (trace_ibg) { WRITE_TO(STDOUT, "Build: "); Graphs::describe(STDOUT, V, FALSE); }
|
||||
int Graphs::build_r(OUTPUT_STREAM, int gb, build_vertex *V, build_methodology *meth, int *changes) {
|
||||
if (trace_ibg) { WRITE_TO(STDOUT, "Visit: "); Graphs::describe(STDOUT, V, FALSE); }
|
||||
|
||||
if (V->built) return TRUE;
|
||||
|
||||
int changes_so_far = *changes;
|
||||
STREAM_INDENT(STDOUT);
|
||||
int rv = TRUE;
|
||||
build_vertex *W;
|
||||
LOOP_OVER_LINKED_LIST(W, build_vertex, V->build_edges)
|
||||
if (rv)
|
||||
rv = Graphs::build_r(OUT, gb | USE_GB, W, meth);
|
||||
rv = Graphs::build_r(OUT, gb | USE_GB, W, meth, changes);
|
||||
if (gb & USE_GB)
|
||||
LOOP_OVER_LINKED_LIST(W, build_vertex, V->use_edges)
|
||||
if (rv)
|
||||
rv = Graphs::build_r(OUT, gb & (BUILD_GB + FORCE_GB), W, meth);
|
||||
rv = Graphs::build_r(OUT, gb & (BUILD_GB + FORCE_GB), W, meth, changes);
|
||||
STREAM_OUTDENT(STDOUT);
|
||||
if (rv) {
|
||||
int needs_building = FALSE;
|
||||
if ((gb & FORCE_GB) || (V->force_this)) needs_building = TRUE;
|
||||
else if ((V->type == GHOST_VERTEX) && (*changes > changes_so_far)) needs_building = TRUE;
|
||||
else @<Decide based on timestamps@>;
|
||||
|
||||
if (needs_building) {
|
||||
if (trace_ibg) { WRITE_TO(STDOUT, "Exec\n"); }
|
||||
if (trace_ibg) { WRITE_TO(STDOUT, "Build: "); Graphs::describe(STDOUT, V, FALSE); }
|
||||
(*changes)++;
|
||||
rv = BuildScripts::execute(V, V->script, meth);
|
||||
} else {
|
||||
if (trace_ibg) { WRITE_TO(STDOUT, "No Build\n"); }
|
||||
}
|
||||
}
|
||||
V->built = rv;
|
||||
|
|
|
@ -18,10 +18,10 @@ int Inform7Skill::inform7_via_shell(build_skill *skill, build_step *S, text_stre
|
|||
|
||||
Shell::quote_file(command, meth->to_inform7);
|
||||
|
||||
inform_kit *K;
|
||||
LOOP_OVER_LINKED_LIST(K, inform_kit, project->kits_to_include) {
|
||||
WRITE_TO(command, "-kit %S ", K->as_copy->edition->work->title);
|
||||
}
|
||||
kit_dependency *kd;
|
||||
LOOP_OVER_LINKED_LIST(kd, kit_dependency, project->kits_to_include)
|
||||
WRITE_TO(command, "-kit %S ", kd->kit->as_copy->edition->work->title);
|
||||
|
||||
WRITE_TO(command, "-format=%S ", TargetVMs::get_unblorbed_extension(S->for_vm));
|
||||
|
||||
inbuild_nest *N;
|
||||
|
|
|
@ -61,12 +61,11 @@ void PipelineManager::claim_as_copy(inbuild_genre *gen, inbuild_copy **C,
|
|||
if (directory_status == TRUE) return;
|
||||
if (Str::eq_insensitive(ext, I"interpipeline")) {
|
||||
filename *F = Filenames::from_text(arg);
|
||||
*C = PipelineManager::claim_file_as_copy(F, NULL, FALSE);
|
||||
*C = PipelineManager::claim_file_as_copy(F, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
inbuild_copy *PipelineManager::claim_file_as_copy(filename *F, text_stream *error_text,
|
||||
int allow_malformed) {
|
||||
inbuild_copy *PipelineManager::claim_file_as_copy(filename *F, text_stream *error_text) {
|
||||
if (TextFiles::exists(F) == FALSE) return NULL;
|
||||
semantic_version_number V = VersionNumbers::null();
|
||||
TEMPORARY_TEXT(unext);
|
||||
|
@ -94,8 +93,7 @@ void PipelineManager::search_nest_for(inbuild_genre *gen, inbuild_nest *N,
|
|||
while (Directories::next(D, LEAFNAME)) {
|
||||
if (Str::get_last_char(LEAFNAME) != FOLDER_SEPARATOR) {
|
||||
filename *F = Filenames::in_folder(P, LEAFNAME);
|
||||
inbuild_copy *C = PipelineManager::claim_file_as_copy(F, NULL,
|
||||
req->allow_malformed);
|
||||
inbuild_copy *C = PipelineManager::claim_file_as_copy(F, NULL);
|
||||
if ((C) && (Requirements::meets(C->edition, req))) {
|
||||
Nests::add_search_result(search_results, N, C, req);
|
||||
}
|
||||
|
|
|
@ -248,7 +248,6 @@ easily be scrolled down off screen when the user first visits the page.
|
|||
=
|
||||
inform_extension *Extensions::Documentation::load(inbuild_work *work) {
|
||||
inbuild_requirement *req = Requirements::any_version_of(work);
|
||||
req->allow_malformed = TRUE;
|
||||
|
||||
inform_extension *E;
|
||||
LOOP_OVER(E, inform_extension)
|
||||
|
|
|
@ -296,10 +296,8 @@ void Extensions::read_source_text_for(inform_extension *E) {
|
|||
E->read_into_file->your_ref = STORE_POINTER_inbuild_copy(E->as_copy);
|
||||
wording EXW = E->read_into_file->text_read;
|
||||
if (Wordings::nonempty(EXW)) @<Break the extension's text into body and documentation@>;
|
||||
#ifdef CORE_MODULE
|
||||
inform_project *project = Inbuild::project();
|
||||
if (project) E->syntax_tree = project->syntax_tree;
|
||||
#endif
|
||||
Sentences::break(E->syntax_tree, E->body_text, TRUE, E->as_copy, -1);
|
||||
E->body_text_unbroken = FALSE;
|
||||
}
|
||||
|
|
|
@ -153,7 +153,7 @@ int Kits::perform_ittt(inform_kit *K, inform_project *project, int parity) {
|
|||
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);
|
||||
Projects::add_kit_dependency(project, ITTT->then_name, NULL, K);
|
||||
changes_made = TRUE;
|
||||
}
|
||||
return changes_made;
|
||||
|
@ -248,7 +248,17 @@ void Kits::construct_graph(inform_kit *K) {
|
|||
|
||||
inbuild_requirement *req;
|
||||
LOOP_OVER_LINKED_LIST(req, inbuild_requirement, K->extensions) {
|
||||
build_vertex *EV = Graphs::req_vertex(req);
|
||||
Graphs::need_this_to_use(KV, EV);
|
||||
int found = FALSE;
|
||||
inform_extension *E;
|
||||
LOOP_OVER(E, inform_extension)
|
||||
if (Requirements::meets(E->as_copy->edition, req)) {
|
||||
Graphs::need_this_to_use(KV, E->as_copy->vertex);
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
if (found == FALSE) {
|
||||
build_vertex *RV = Graphs::req_vertex(req);
|
||||
Graphs::need_this_to_use(KV, RV);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,12 +3,19 @@
|
|||
An Inform 7 project.
|
||||
|
||||
@ =
|
||||
typedef struct kit_dependency {
|
||||
struct inform_kit *kit;
|
||||
struct inform_language *because_of_language;
|
||||
struct inform_kit *because_of_kit;
|
||||
MEMORY_MANAGEMENT
|
||||
} kit_dependency;
|
||||
|
||||
typedef struct inform_project {
|
||||
struct inbuild_copy *as_copy;
|
||||
struct semantic_version_number version;
|
||||
struct linked_list *source_vertices; /* of |build_vertex| */
|
||||
int assumed_to_be_parser_IF;
|
||||
struct linked_list *kits_to_include; /* of |inform_kit| */
|
||||
struct linked_list *kits_to_include; /* of |kit_dependency| */
|
||||
struct inform_language *language_of_play;
|
||||
struct inform_language *language_of_syntax;
|
||||
struct inform_language *language_of_index;
|
||||
|
@ -25,7 +32,7 @@ inform_project *Projects::new_ip(text_stream *name, filename *F, pathname *P) {
|
|||
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->kits_to_include = NEW_LINKED_LIST(kit_dependency);
|
||||
project->assumed_to_be_parser_IF = TRUE;
|
||||
project->language_of_play = NULL;
|
||||
project->language_of_syntax = NULL;
|
||||
|
@ -129,67 +136,70 @@ linked_list *Projects::source(inform_project *project) {
|
|||
return project->source_vertices;
|
||||
}
|
||||
|
||||
void Projects::add_kit_dependency(inform_project *project, text_stream *kit_name) {
|
||||
void Projects::add_kit_dependency(inform_project *project, text_stream *kit_name,
|
||||
inform_language *because_of_language, inform_kit *because_of_kit) {
|
||||
RUN_ONLY_BEFORE_PHASE(OPERATIONAL_INBUILD_PHASE)
|
||||
if (Projects::uses_kit(project, kit_name)) return;
|
||||
linked_list *nest_list = Inbuild::nest_list();
|
||||
inform_kit *kit = Kits::load(kit_name, nest_list);
|
||||
ADD_TO_LINKED_LIST(kit, inform_kit, project->kits_to_include);
|
||||
kit_dependency *kd = CREATE(kit_dependency);
|
||||
kd->kit = Kits::load(kit_name, Inbuild::nest_list());
|
||||
kd->because_of_language = because_of_language;
|
||||
kd->because_of_kit = because_of_kit;
|
||||
ADD_TO_LINKED_LIST(kd, kit_dependency, 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->as_copy->edition->work->title, name))
|
||||
kit_dependency *kd;
|
||||
LOOP_OVER_LINKED_LIST(kd, kit_dependency, project->kits_to_include)
|
||||
if (Str::eq(kd->kit->as_copy->edition->work->title, name))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void Projects::finalise_kit_dependencies(inform_project *project) {
|
||||
Projects::add_kit_dependency(project, I"BasicInformKit");
|
||||
Projects::add_kit_dependency(project, I"BasicInformKit", NULL, NULL);
|
||||
inform_language *L = project->language_of_play;
|
||||
if (L) {
|
||||
text_stream *kit_name = Languages::kit_name(L);
|
||||
Projects::add_kit_dependency(project, kit_name);
|
||||
Projects::add_kit_dependency(project, kit_name, L, NULL);
|
||||
}
|
||||
if (project->assumed_to_be_parser_IF)
|
||||
Projects::add_kit_dependency(project, I"CommandParserKit");
|
||||
Projects::add_kit_dependency(project, I"CommandParserKit", NULL, NULL);
|
||||
|
||||
int parity = TRUE;
|
||||
@<Perform if-this-then-that@>;
|
||||
parity = FALSE;
|
||||
@<Perform if-this-then-that@>;
|
||||
|
||||
linked_list *sorted = NEW_LINKED_LIST(inform_kit);
|
||||
linked_list *sorted = NEW_LINKED_LIST(kit_dependency);
|
||||
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);
|
||||
kit_dependency *kd;
|
||||
LOOP_OVER_LINKED_LIST(kd, kit_dependency, project->kits_to_include)
|
||||
if (kd->kit->priority == p)
|
||||
ADD_TO_LINKED_LIST(kd, kit_dependency, 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->as_copy->edition->work->title, K->priority);
|
||||
|
||||
kit_dependency *kd;
|
||||
LOOP_OVER_LINKED_LIST(kd, kit_dependency, project->kits_to_include)
|
||||
LOG("Using Inform kit '%S' (priority %d).\n", kd->kit->as_copy->edition->work->title, kd->kit->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))
|
||||
kit_dependency *kd;
|
||||
LOOP_OVER_LINKED_LIST(kd, kit_dependency, project->kits_to_include)
|
||||
if (Kits::perform_ittt(kd->kit, 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);
|
||||
kit_dependency *kd;
|
||||
LOOP_OVER_LINKED_LIST(kd, kit_dependency, project->kits_to_include)
|
||||
Kits::load_types(kd->kit);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -197,28 +207,28 @@ void Projects::load_types(inform_project *project) {
|
|||
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);
|
||||
kit_dependency *kd;
|
||||
LOOP_OVER_LINKED_LIST(kd, kit_dependency, project->kits_to_include)
|
||||
Kits::activate_plugins(kd->kit);
|
||||
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)
|
||||
kit_dependency *kd;
|
||||
LOOP_OVER_LINKED_LIST(kd, kit_dependency, project->kits_to_include)
|
||||
if (kd->kit->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;
|
||||
kit_dependency *kd;
|
||||
LOOP_OVER_LINKED_LIST(kd, kit_dependency, project->kits_to_include)
|
||||
if (kd->kit->index_template)
|
||||
I = kd->kit->index_template;
|
||||
return I;
|
||||
}
|
||||
|
||||
|
@ -230,17 +240,17 @@ 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);
|
||||
kit_dependency *kd;
|
||||
LOOP_OVER_LINKED_LIST(kd, kit_dependency, project->kits_to_include)
|
||||
Kits::early_source_text(OUT, kd->kit);
|
||||
}
|
||||
|
||||
#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) {
|
||||
LOG("Okay so K is %S\n", K->as_copy->edition->work->title);
|
||||
kit_dependency *kd;
|
||||
LOOP_OVER_LINKED_LIST(kd, kit_dependency, project->kits_to_include) {
|
||||
inform_kit *K = kd->kit;
|
||||
link_instruction *link = CodeGen::LinkInstructions::new(
|
||||
K->as_copy->location_if_path, K->attachment_point);
|
||||
ADD_TO_LINKED_LIST(link, link_instruction, requirements_list);
|
||||
|
@ -289,41 +299,53 @@ void Projects::construct_build_target(inform_project *project, target_vm *VM,
|
|||
BuildSteps::attach(project->blorbed_vertex, package_using_inblorb_skill,
|
||||
Inbuild::nest_list(), releasing, VM, NULL, project->as_copy);
|
||||
|
||||
// inter_V->force_this = TRUE;
|
||||
|
||||
if (compile_only) {
|
||||
project->chosen_build_target = inf_V;
|
||||
inf_V->force_this = TRUE;
|
||||
inter_V->force_this = TRUE;
|
||||
} else if (releasing) project->chosen_build_target = project->blorbed_vertex;
|
||||
else project->chosen_build_target = project->unblorbed_vertex;
|
||||
}
|
||||
|
||||
void Projects::graph_dependent_kit(inform_project *project, build_vertex *V, kit_dependency *kd, int use) {
|
||||
build_vertex *KV = kd->kit->as_copy->vertex;
|
||||
if (use) Graphs::need_this_to_use(V, KV);
|
||||
else Graphs::need_this_to_build(V, KV);
|
||||
kit_dependency *kd2;
|
||||
LOOP_OVER_LINKED_LIST(kd2, kit_dependency, project->kits_to_include)
|
||||
if ((kd2->because_of_kit == kd->kit) && (kd2->because_of_language == NULL))
|
||||
Projects::graph_dependent_kit(project, KV, kd2, TRUE);
|
||||
}
|
||||
|
||||
void Projects::graph_dependent_language(inform_project *project, build_vertex *V, inform_language *L, int use) {
|
||||
build_vertex *LV = L->as_copy->vertex;
|
||||
if (use) Graphs::need_this_to_use(V, LV);
|
||||
else Graphs::need_this_to_build(V, LV);
|
||||
kit_dependency *kd2;
|
||||
LOOP_OVER_LINKED_LIST(kd2, kit_dependency, project->kits_to_include)
|
||||
if ((kd2->because_of_kit == NULL) && (kd2->because_of_language == L))
|
||||
Projects::graph_dependent_kit(project, LV, kd2, TRUE);
|
||||
}
|
||||
|
||||
void Projects::construct_graph(inform_project *project) {
|
||||
RUN_ONLY_IN_PHASE(GOING_OPERATIONAL_INBUILD_PHASE)
|
||||
if (project == NULL) return;
|
||||
build_vertex *V = project->as_copy->vertex;
|
||||
inform_kit *K;
|
||||
LOOP_OVER_LINKED_LIST(K, inform_kit, project->kits_to_include) {
|
||||
Graphs::need_this_to_build(V, K->as_copy->vertex);
|
||||
}
|
||||
build_vertex *S;
|
||||
LOOP_OVER_LINKED_LIST(S, build_vertex, project->source_vertices) {
|
||||
Graphs::need_this_to_build(V, S);
|
||||
}
|
||||
kit_dependency *kd;
|
||||
LOOP_OVER_LINKED_LIST(kd, kit_dependency, project->kits_to_include)
|
||||
if ((kd->because_of_kit == NULL) && (kd->because_of_language == NULL))
|
||||
Projects::graph_dependent_kit(project, V, kd, FALSE);
|
||||
inform_language *L = project->language_of_play;
|
||||
if (L) {
|
||||
build_vertex *LV = L->as_copy->vertex;
|
||||
Graphs::need_this_to_build(V, LV);
|
||||
}
|
||||
if (L) Projects::graph_dependent_language(project, V, L, FALSE);
|
||||
L = project->language_of_syntax;
|
||||
if (L) {
|
||||
build_vertex *LV = L->as_copy->vertex;
|
||||
Graphs::need_this_to_build(V, LV);
|
||||
}
|
||||
if (L) Projects::graph_dependent_language(project, V, L, FALSE);
|
||||
L = project->language_of_index;
|
||||
if (L) {
|
||||
build_vertex *LV = L->as_copy->vertex;
|
||||
Graphs::need_this_to_build(V, LV);
|
||||
}
|
||||
if (L) Projects::graph_dependent_language(project, V, L, FALSE);
|
||||
}
|
||||
|
||||
@
|
||||
|
@ -335,13 +357,13 @@ void Projects::read_source_text_for(inform_project *project) {
|
|||
Projects::finalise_kit_dependencies(project);
|
||||
|
||||
parse_node *inclusions_heading = ParseTree::new(HEADING_NT);
|
||||
ParseTree::set_text(inclusions_heading, Feeds::feed_text_expanding_strings(L"Implied inclusions"));
|
||||
ParseTree::set_text(inclusions_heading,
|
||||
Feeds::feed_text_expanding_strings(L"Implied inclusions"));
|
||||
ParseTree::insert_sentence(project->syntax_tree, inclusions_heading);
|
||||
#ifdef CORE_MODULE
|
||||
ParseTree::annotate_int(inclusions_heading, sentence_unparsed_ANNOT, FALSE);
|
||||
ParseTree::annotate_int(inclusions_heading, heading_level_ANNOT, 0);
|
||||
ParseTree::annotate_int(inclusions_heading, implied_heading_ANNOT, TRUE);
|
||||
Headings::declare(project->syntax_tree, inclusions_heading);
|
||||
#endif
|
||||
|
||||
int wc = lexer_wordcount, bwc = -1;
|
||||
TEMPORARY_TEXT(early);
|
||||
|
@ -376,11 +398,9 @@ void Projects::read_source_text_for(inform_project *project) {
|
|||
parse_node *implicit_heading = ParseTree::new(HEADING_NT);
|
||||
ParseTree::set_text(implicit_heading, Feeds::feed_text_expanding_strings(L"Invented sentences"));
|
||||
ParseTree::insert_sentence(project->syntax_tree, implicit_heading);
|
||||
#ifdef CORE_MODULE
|
||||
ParseTree::annotate_int(implicit_heading, sentence_unparsed_ANNOT, FALSE);
|
||||
ParseTree::annotate_int(implicit_heading, heading_level_ANNOT, 0);
|
||||
Headings::declare(project->syntax_tree, implicit_heading);
|
||||
#endif
|
||||
ParseTree::pop_attachment_point(project->syntax_tree, l);
|
||||
|
||||
ParseTree::push_attachment_point(project->syntax_tree, implicit_heading);
|
||||
|
@ -390,6 +410,10 @@ void Projects::read_source_text_for(inform_project *project) {
|
|||
#endif
|
||||
Inclusions::traverse(project->as_copy, project->syntax_tree);
|
||||
Headings::satisfy_dependencies(project->syntax_tree, project->as_copy);
|
||||
|
||||
#ifndef CORE_MODULE
|
||||
Copies::list_problems_arising(STDERR, project->as_copy);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ It might seem sensible to parse the opening sentence of the source text,
|
||||
|
|
|
@ -29,18 +29,24 @@ void Inclusions::traverse(inbuild_copy *C, parse_node_tree *T) {
|
|||
do {
|
||||
includes_cleared = TRUE;
|
||||
if (problem_count > 0) break;
|
||||
parse_node *elder = NULL;
|
||||
ParseTree::traverse_ppni(T, Inclusions::visit, &elder, &includes_cleared);
|
||||
ParseTree::traverse_ppni(T, Inclusions::visit, &includes_cleared);
|
||||
} while (includes_cleared == FALSE);
|
||||
inclusions_errors_to = NULL;
|
||||
}
|
||||
|
||||
void Inclusions::visit(parse_node_tree *T, parse_node *pn, parse_node **elder, int *includes_cleared) {
|
||||
build_vertex *Inclusions::spawned_from_vertex(parse_node *H0) {
|
||||
if (H0) {
|
||||
inform_extension *ext = ParseTree::get_inclusion_of_extension(H0);
|
||||
if (ext) return ext->as_copy->vertex;
|
||||
}
|
||||
if (inclusions_errors_to == NULL) internal_error("no H0 ext or inclusion");
|
||||
return inclusions_errors_to->vertex;
|
||||
}
|
||||
|
||||
void Inclusions::visit(parse_node_tree *T, parse_node *pn, parse_node *last_H0, int *includes_cleared) {
|
||||
if (ParseTree::get_type(pn) == INCLUDE_NT) {
|
||||
@<Replace INCLUDE node with sentence nodes for any extensions required@>;
|
||||
*includes_cleared = FALSE;
|
||||
} else if (ParseTree::get_type(pn) != ROOT_NT) {
|
||||
*elder = pn;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,14 +57,20 @@ void Inclusions::visit(parse_node_tree *T, parse_node *pn, parse_node **elder, i
|
|||
internal_error("malformed INCLUDE");
|
||||
wording title = GET_RW(<structural-sentence>, 1);
|
||||
wording author = GET_RW(<structural-sentence>, 2);
|
||||
int l = ParseTree::begin_inclusion(T, pn);
|
||||
inform_extension *E = Inclusions::fulfill_request_to_include_extension(title, author);
|
||||
ParseTree::end_inclusion(T, l);
|
||||
ParseTree::set_type(pn, INCLUSION_NT); pn->down = NULL;
|
||||
int l = ParseTree::push_attachment_point(T, pn);
|
||||
inform_extension *E = Inclusions::fulfill_request_to_include_extension(last_H0, title, author);
|
||||
ParseTree::pop_attachment_point(T, l);
|
||||
if (E) {
|
||||
build_vertex *V = inclusions_errors_to->vertex;
|
||||
for (parse_node *c = pn->down; c; c = c->next)
|
||||
if (ParseTree::get_type(c) == HEADING_NT)
|
||||
ParseTree::set_inclusion_of_extension(c, E);
|
||||
if ((last_H0) && (ParseTree::int_annotation(last_H0, implied_heading_ANNOT) != TRUE)) {
|
||||
build_vertex *V = Inclusions::spawned_from_vertex(last_H0);
|
||||
build_vertex *EV = E->as_copy->vertex;
|
||||
Graphs::need_this_to_build(V, EV);
|
||||
}
|
||||
}
|
||||
|
||||
@
|
||||
|
||||
|
@ -94,7 +106,6 @@ void Inclusions::visit(parse_node_tree *T, parse_node *pn, parse_node **elder, i
|
|||
CE->error_subcategory = IncludeExtQuoted_SYNERROR;
|
||||
CE->details_node = current_sentence;
|
||||
Copies::attach(inclusions_errors_to, CE);
|
||||
WRITE_TO(STDERR, "Listen %X!\n", inclusions_errors_to->edition->work);
|
||||
|
||||
@ This internal parses version text such as "12/110410".
|
||||
|
||||
|
@ -105,7 +116,7 @@ void Inclusions::visit(parse_node_tree *T, parse_node *pn, parse_node **elder, i
|
|||
}
|
||||
|
||||
@ =
|
||||
inform_extension *Inclusions::fulfill_request_to_include_extension(wording TW, wording AW) {
|
||||
inform_extension *Inclusions::fulfill_request_to_include_extension(parse_node *last_H0, wording TW, wording AW) {
|
||||
inform_extension *E = NULL;
|
||||
<<t1>> = -1; <<t2>> = -1;
|
||||
<extension-title-and-version>(TW);
|
||||
|
@ -143,13 +154,13 @@ parse tree.
|
|||
DISCARD_TEXT(exft);
|
||||
DISCARD_TEXT(exfa);
|
||||
|
||||
E = Inclusions::load(current_sentence, req);
|
||||
E = Inclusions::load(last_H0, current_sentence, req);
|
||||
|
||||
@h Extension loading.
|
||||
Extensions are loaded here.
|
||||
|
||||
=
|
||||
inform_extension *Inclusions::load(parse_node *at, inbuild_requirement *req) {
|
||||
inform_extension *Inclusions::load(parse_node *last_H0, parse_node *at, inbuild_requirement *req) {
|
||||
@<Do not load the same extension work twice@>;
|
||||
|
||||
inform_extension *E = NULL;
|
||||
|
@ -178,7 +189,6 @@ can't know at load time what we will ultimately require.)
|
|||
}
|
||||
|
||||
@<Read the extension file into the lexer, and break it into body and documentation@> =
|
||||
req->allow_malformed = TRUE;
|
||||
inbuild_search_result *search_result = Nests::first_found(req, Inbuild::nest_list());
|
||||
if (search_result) {
|
||||
E = ExtensionManager::from_copy(search_result->copy);
|
||||
|
@ -194,13 +204,17 @@ can't know at load time what we will ultimately require.)
|
|||
} else {
|
||||
Copies::read_source_text_for(search_result->copy);
|
||||
}
|
||||
#ifdef CORE_MODULE
|
||||
SourceProblems::issue_problems_arising(search_result->copy);
|
||||
#endif
|
||||
#ifndef CORE_MODULE
|
||||
Copies::list_problems_arising(STDERR, search_result->copy);
|
||||
#endif
|
||||
} else @<Issue a cannot-find problem@>;
|
||||
} else {
|
||||
#ifdef CORE_MODULE
|
||||
@<Issue a cannot-find problem@>;
|
||||
#endif
|
||||
build_vertex *RV = Graphs::req_vertex(req);
|
||||
build_vertex *V = Inclusions::spawned_from_vertex(last_H0);
|
||||
Graphs::need_this_to_build(V, RV);
|
||||
}
|
||||
|
||||
@ Here the problem is not that the extension is broken in some way: it's
|
||||
just not what we can currently use. Therefore the correction should be a
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
Inform 7.10.1 build 6Q21 has started.
|
||||
I've now read your source text, which is 40 words long.
|
||||
I've also read Basic Inform by Graham Nelson, which is 7645 words long.
|
||||
I've also read Standard Rules by Graham Nelson, which is 32123 words long.
|
||||
I've also read English Language by Graham Nelson, which is 2328 words long.
|
||||
I've also read Standard Rules by Graham Nelson, which is 32123 words long.
|
||||
Problem__ PM_HeadingInPlaceOfSubordinate
|
||||
In Part 1 - The Discussing Action:
|
||||
In Part Six - Grammar in the extension Standard Rules by Graham Nelson:
|
||||
>--> In the sentence 'Section 1 - Greeting definitions (in place of Part Six
|
||||
- Grammar in Standard Rules by Graham Nelson)' (source text, line 5), it
|
||||
looks as if you intend to replace a section of source text from the
|
||||
|
@ -13,4 +13,4 @@ In Part 1 - The Discussing Action:
|
|||
(''Part 1 - The Discussing Action (in place of Part Six - Grammar in
|
||||
Standard Rules by Graham Nelson)' (source text, line 3)') which is already
|
||||
being replaced spliced into 'Standard Rules by Graham Nelson'.
|
||||
Inform 7 has finished: 10 centiseconds used.
|
||||
Inform 7 has finished.
|
||||
|
|
|
@ -48,6 +48,10 @@ int Task::carry_out(build_step *S) {
|
|||
latest_syntax_tree = project->syntax_tree;
|
||||
|
||||
SourceProblems::issue_problems_arising(project->as_copy);
|
||||
inform_extension *E;
|
||||
LOOP_OVER(E, inform_extension)
|
||||
SourceProblems::issue_problems_arising(E->as_copy);
|
||||
|
||||
if (problem_count > 0) return FALSE;
|
||||
|
||||
if (inform7_task) internal_error("cannot re-enter with new task");
|
||||
|
@ -62,10 +66,10 @@ int Task::carry_out(build_step *S) {
|
|||
inform7_task->stage_of_compilation = -1;
|
||||
inform7_task->next_resource_number = 3;
|
||||
|
||||
inform_language *E = NaturalLanguages::English();
|
||||
Projects::set_language_of_syntax(project, E);
|
||||
Projects::set_language_of_index(project, E);
|
||||
Projects::set_language_of_play(project, E);
|
||||
inform_language *En = NaturalLanguages::English();
|
||||
Projects::set_language_of_syntax(project, En);
|
||||
Projects::set_language_of_index(project, En);
|
||||
Projects::set_language_of_play(project, En);
|
||||
|
||||
int rv = Sequence::carry_out(TargetVMs::debug_enabled(inform7_task->task->for_vm));
|
||||
inform7_task = NULL;
|
||||
|
|
|
@ -405,8 +405,10 @@ void ParseTreeUsage::write_permissions(void) {
|
|||
|
||||
ParseTree::allow_annotation_to_category(L1_NCAT, clears_pronouns_ANNOT);
|
||||
ParseTree::allow_annotation(HEADING_NT, embodying_heading_ANNOT);
|
||||
ParseTree::allow_annotation(HEADING_NT, inclusion_of_extension_ANNOT);
|
||||
ParseTree::allow_annotation(HEADING_NT, interpretation_of_subject_ANNOT);
|
||||
ParseTree::allow_annotation(HEADING_NT, suppress_heading_dependencies_ANNOT);
|
||||
ParseTree::allow_annotation(HEADING_NT, implied_heading_ANNOT);
|
||||
ParseTree::allow_annotation_to_category(L1_NCAT, module_ANNOT);
|
||||
|
||||
ParseTree::allow_annotation_to_category(L2_NCAT, clears_pronouns_ANNOT);
|
||||
|
|
|
@ -185,6 +185,8 @@ typedef struct parse_node_annotation {
|
|||
@e sentence_unparsed_ANNOT /* int: set if verbs haven't been sought yet here */
|
||||
@e suppress_heading_dependencies_ANNOT /* int: ignore extension dependencies on this heading node */
|
||||
@e embodying_heading_ANNOT /* |heading|: for parse nodes of headings */
|
||||
@e inclusion_of_extension_ANNOT /* |inform_extension|: for parse nodes of headings */
|
||||
@e implied_heading_ANNOT /* int: set only for the heading of implied inclusions */
|
||||
|
||||
@d MAX_ANNOT_NUMBER (NO_DEFINED_ANNOT_VALUES+1)
|
||||
|
||||
|
@ -995,16 +997,21 @@ void ParseTree::traverse_from_ppn(parse_node *pn, void (*visitor)(parse_node *,
|
|||
}
|
||||
current_sentence = SCS;
|
||||
}
|
||||
void ParseTree::traverse_ppni(parse_node_tree *T, void (*visitor)(parse_node_tree *, parse_node *, parse_node **, int *), parse_node **X, int *N) {
|
||||
ParseTree::traverse_from_ppni(T, T->root_node, visitor, X, N);
|
||||
void ParseTree::traverse_ppni(parse_node_tree *T, void (*visitor)(parse_node_tree *, parse_node *, parse_node *, int *), int *N) {
|
||||
ParseTree::traverse_from_ppni(T, T->root_node, visitor, NULL, N);
|
||||
}
|
||||
void ParseTree::traverse_from_ppni(parse_node_tree *T, parse_node *pn, void (*visitor)(parse_node_tree *, parse_node *, parse_node **, int *), parse_node **X, int *N) {
|
||||
void ParseTree::traverse_from_ppni(parse_node_tree *T, parse_node *pn, void (*visitor)(parse_node_tree *, parse_node *, parse_node *, int *), parse_node *last_h0, int *N) {
|
||||
parse_node *SCS = current_sentence;
|
||||
for (; pn; pn = pn->next) {
|
||||
if (ParseTree::top_level(pn->node_type)) ParseTree::traverse_from_ppni(T, pn->down, visitor, X, N);
|
||||
if (ParseTree::top_level(pn->node_type)) {
|
||||
parse_node *H0 = last_h0;
|
||||
if ((ParseTree::is(pn, HEADING_NT)) && (ParseTree::int_annotation(pn, heading_level_ANNOT) == 0))
|
||||
H0 = pn;
|
||||
ParseTree::traverse_from_ppni(T, pn->down, visitor, H0, N);
|
||||
}
|
||||
if (ParseTree::visitable(pn->node_type)) {
|
||||
if (SENTENCE_NODE(pn->node_type)) current_sentence = pn;
|
||||
(*visitor)(T, pn, X, N);
|
||||
(*visitor)(T, pn, last_h0, N);
|
||||
}
|
||||
}
|
||||
current_sentence = SCS;
|
||||
|
@ -1364,15 +1371,3 @@ void ParseTree::add_single_pr_inv(parse_node *E, parse_node *N) {
|
|||
E->next_alternative = N; N->next_alternative = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
@h Handling an inclusion.
|
||||
|
||||
=
|
||||
int ParseTree::begin_inclusion(parse_node_tree *T, parse_node *pn) {
|
||||
ParseTree::set_type(pn, INCLUSION_NT); pn->down = NULL;
|
||||
return ParseTree::push_attachment_point(T, pn);
|
||||
}
|
||||
|
||||
void ParseTree::end_inclusion(parse_node_tree *T, int l) {
|
||||
ParseTree::pop_attachment_point(T, l);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue