From b4604150d61ba79410d436d0a96875496af48825 Mon Sep 17 00:00:00 2001 From: Graham Nelson Date: Mon, 13 Sep 2021 00:33:30 +0100 Subject: [PATCH] Improved project-free compilation and unified pipelines --- README.md | 2 +- build.txt | 4 +- docs/arch-module/2-tvm.html | 29 +- docs/core-module/1-htc.html | 2 +- docs/core-module/1-pp.html | 6 +- docs/core-module/1-wtc.html | 20 +- docs/core-module/2-up.html | 95 +++-- docs/final-module/2-cg.html | 1 + docs/inform7/1-mn.html | 192 ++++++---- docs/inform7/M-cu.html | 87 ++++- docs/inform7/M-pm.html | 118 +++--- docs/pipeline-module/1-ppl.html | 72 ++-- docs/pipeline-module/1-stg.html | 1 + docs/problems-module/2-pl1.html | 95 +++-- docs/problems-module/2-pl3.html | 11 +- docs/problems-module/P-htitm.html | 13 +- docs/supervisor-module/1-ic.html | 32 +- docs/supervisor-module/2-ce.html | 4 +- docs/supervisor-module/2-cps.html | 6 +- docs/supervisor-module/2-nst.html | 4 +- docs/supervisor-module/3-bg.html | 8 +- docs/supervisor-module/3-bs2.html | 2 +- docs/supervisor-module/3-ib.html | 17 +- docs/supervisor-module/3-is.html | 4 +- docs/supervisor-module/3-is2.html | 4 +- docs/supervisor-module/4-em.html | 2 +- docs/supervisor-module/4-pbm.html | 6 +- docs/supervisor-module/4-pfm.html | 11 +- docs/supervisor-module/5-es.html | 4 +- docs/supervisor-module/5-ks.html | 16 +- docs/supervisor-module/5-ls.html | 6 +- docs/supervisor-module/5-ps2.html | 351 ++++++++++-------- docs/supervisor-module/6-hdn.html | 8 +- docs/supervisor-module/6-inc.html | 6 +- docs/supervisor-module/6-st.html | 5 +- docs/supervisor-module/6-tbs.html | 2 +- docs/supervisor-module/6-tof.html | 2 +- docs/supervisor-module/7-cns.html | 2 +- docs/supervisor-module/7-tm.html | 2 +- docs/supervisor-module/P-wtmd.html | 8 +- .../Chapter 5/Project Services.w | 4 + .../supervisor-module/Chapter 6/Source Text.w | 3 +- inform7/Chapter 1/Main.w | 129 ++++--- inform7/Figures/memory-diagnostics.txt | 74 ++-- inform7/Figures/timings-diagnostics.txt | 44 +-- ...pipeline => compile-reduced.interpipeline} | 1 + .../Internal/Pipelines/compile.interpipeline | 3 +- inform7/Internal/Pipelines/test.interpipeline | 15 - .../Pipelines/test_basic.interpipeline | 14 - .../Pipelines/test_basic_c.interpipeline | 15 - .../Internal/Pipelines/test_c.interpipeline | 16 - .../test_reduced_basic_c.interpipeline | 16 - inform7/Manual/Command-Line Usage.w | 70 +++- .../Tests/Test Externals/_Makefiles/XText.mk | 7 +- inform7/Tests/Test Externals/_Source/XText.c | 2 +- inform7/Tests/Test Externals/_Source/XText.i7 | 1 + inform7/Tests/inform7.intest | 55 ++- .../core-module/Chapter 1/What To Compile.w | 16 +- .../core-module/Chapter 2/Using Problems.w | 40 +- inter/pipeline-module/Chapter 1/Pipelines.w | 1 - .../Chapter 2/Problems, Level 1.w | 50 ++- .../Chapter 2/Problems, Level 3.w | 11 +- .../How To Include This Module.w | 4 + 63 files changed, 1131 insertions(+), 720 deletions(-) rename inform7/Internal/Pipelines/{test_any.interpipeline => compile-reduced.interpipeline} (92%) delete mode 100644 inform7/Internal/Pipelines/test.interpipeline delete mode 100644 inform7/Internal/Pipelines/test_basic.interpipeline delete mode 100644 inform7/Internal/Pipelines/test_basic_c.interpipeline delete mode 100644 inform7/Internal/Pipelines/test_c.interpipeline delete mode 100644 inform7/Internal/Pipelines/test_reduced_basic_c.interpipeline diff --git a/README.md b/README.md index 995817d46..d62b86df6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Inform 7 -v10.1.0-alpha.1+6T23 'Krypton' (12 September 2021) +v10.1.0-alpha.1+6T24 'Krypton' (13 September 2021) ## About Inform 7 diff --git a/build.txt b/build.txt index 1886b6838..a41d92756 100644 --- a/build.txt +++ b/build.txt @@ -1,3 +1,3 @@ Prerelease: alpha.1 -Build Date: 12 September 2021 -Build Number: 6T23 +Build Date: 13 September 2021 +Build Number: 6T24 diff --git a/docs/arch-module/2-tvm.html b/docs/arch-module/2-tvm.html index 449659e68..b55dca3f5 100644 --- a/docs/arch-module/2-tvm.html +++ b/docs/arch-module/2-tvm.html @@ -89,26 +89,26 @@ or, say, "32-bit to be generated to ANSI C code". void TargetVMs::create(void) { hat tip: Joel Berez and Marc Blank, 1979, and later hands TargetVMs::new(Architectures::from_codename(I"16"), I"Inform6", - VersionNumbers::from_text(I"5"), I"z5", I"zblorb", I"Parchment", NULL); + VersionNumbers::from_text(I"5"), I"i6", I"z5", I"zblorb", I"Parchment", NULL); TargetVMs::new(Architectures::from_codename(I"16d"), I"Inform6", - VersionNumbers::from_text(I"5"), I"z5", I"zblorb", I"Parchment", NULL); + VersionNumbers::from_text(I"5"), I"i6", I"z5", I"zblorb", I"Parchment", NULL); TargetVMs::new(Architectures::from_codename(I"16"), I"Inform6", - VersionNumbers::from_text(I"8"), I"z8", I"zblorb", I"Parchment", NULL); + VersionNumbers::from_text(I"8"), I"i6", I"z8", I"zblorb", I"Parchment", NULL); TargetVMs::new(Architectures::from_codename(I"16d"), I"Inform6", - VersionNumbers::from_text(I"8"), I"z8", I"zblorb", I"Parchment", NULL); + VersionNumbers::from_text(I"8"), I"i6", I"z8", I"zblorb", I"Parchment", NULL); hat tip: Andrew Plotkin, 2000 TargetVMs::new(Architectures::from_codename(I"32"), I"Inform6", - VersionNumbers::from_text(I"3.1.2"), I"ulx", I"gblorb", I"Quixe", NULL); + VersionNumbers::from_text(I"3.1.2"), I"i6", I"ulx", I"gblorb", I"Quixe", NULL); TargetVMs::new(Architectures::from_codename(I"32d"), I"Inform6", - VersionNumbers::from_text(I"3.1.2"), I"ulx", I"gblorb", I"Quixe", NULL); + VersionNumbers::from_text(I"3.1.2"), I"i6", I"ulx", I"gblorb", I"Quixe", NULL); C support added September 2021 TargetVMs::new(Architectures::from_codename(I"32"), I"C", - VersionNumbers::from_text(I"1"), I"c", I"", I"", NULL); + VersionNumbers::from_text(I"1"), I"c", I"", I"", I"", NULL); TargetVMs::new(Architectures::from_codename(I"32d"), I"C", - VersionNumbers::from_text(I"1"), I"c", I"", I"", NULL); + VersionNumbers::from_text(I"1"), I"c", I"", I"", I"", NULL); }

§2. The target_vm structure contains two arguably architectural doohickies: @@ -122,6 +122,7 @@ with integer-only arithmetic, say. typedef struct target_vm { struct inter_architecture *architecture; such as 32d struct semantic_version_number version; such as 0.8.7 + struct text_stream *transpiled_extension; such as i6 struct text_stream *VM_unblorbed_extension; such as z8 struct text_stream *VM_blorbed_extension; when blorbed up struct text_stream *VM_image; filename of image for icon used in the index @@ -140,10 +141,11 @@ with integer-only arithmetic, say.

 target_vm *TargetVMs::new(inter_architecture *arch, text_stream *format,
-    semantic_version_number V, text_stream *unblorbed, text_stream *blorbed,
-    text_stream *interpreter, linked_list *opts) {
+    semantic_version_number V, text_stream *trans, text_stream *unblorbed,
+    text_stream *blorbed, text_stream *interpreter, linked_list *opts) {
     target_vm *VM = CREATE(target_vm);
     VM->version = V;
+    VM->transpiled_extension = Str::duplicate(trans);
     VM->VM_unblorbed_extension = Str::duplicate(unblorbed);
     VM->VM_blorbed_extension = Str::duplicate(blorbed);
     VM->default_browser_interpreter = Str::duplicate(interpreter);
@@ -196,7 +198,7 @@ to understand what these mean, if indeed they mean anything.
 
 target_vm *TargetVMs::new_variant(target_vm *existing, linked_list *opts) {
     return TargetVMs::new(existing->architecture, existing->transpiler_family,
-        existing->version, existing->VM_unblorbed_extension,
+        existing->version, existing->transpiled_extension, existing->VM_unblorbed_extension,
         existing->VM_blorbed_extension, existing->default_browser_interpreter, opts);
 }
 
@@ -447,6 +449,11 @@ and then the blorbed extension may be the empty text.

+text_stream *TargetVMs::get_transpiled_extension(target_vm *VM) {
+    if (VM == NULL) internal_error("no VM");
+    return VM->transpiled_extension;
+}
+
 text_stream *TargetVMs::get_unblorbed_extension(target_vm *VM) {
     if (VM == NULL) internal_error("no VM");
     return VM->VM_unblorbed_extension;
diff --git a/docs/core-module/1-htc.html b/docs/core-module/1-htc.html
index 40a48a920..8b84094b4 100644
--- a/docs/core-module/1-htc.html
+++ b/docs/core-module/1-htc.html
@@ -616,7 +616,7 @@ to advance last_task    }
 }
 
-void Sequence::backtrace(void) {
+void Sequence::backtrace(void) {
     compilation_subtask *t = current_task;
     int d = 0;
     while (t) {
diff --git a/docs/core-module/1-pp.html b/docs/core-module/1-pp.html
index 9ec322204..edd0bdc45 100644
--- a/docs/core-module/1-pp.html
+++ b/docs/core-module/1-pp.html
@@ -120,7 +120,7 @@ progress bar with a rubric beneath it.
     last_progress_pc = pc;
 }
 
-void ProgressBar::final_state_of_progress_bar(void) {
+void ProgressBar::final_state_of_progress_bar(void) {
     if (show_progress_indicator) {
         WRITE_TO(STDERR, "++ 100%% (Finishing work)\n");
         STREAM_FLUSH(STDERR);
@@ -132,13 +132,13 @@ a final status indicator.
 

-text_stream *ProgressBar::begin_outcome(void) {
+text_stream *ProgressBar::begin_outcome(void) {
     if (show_progress_indicator == FALSE) return NULL;
     WRITE_TO(STDERR, "++ Ended: ");
     return STDERR;
 }
 
-void ProgressBar::end_outcome(void) {
+void ProgressBar::end_outcome(void) {
     if (show_progress_indicator == FALSE) return;
     WRITE_TO(STDERR, "\n");
     STREAM_FLUSH(STDERR);
diff --git a/docs/core-module/1-wtc.html b/docs/core-module/1-wtc.html
index a04b5477e..48ee69fc3 100644
--- a/docs/core-module/1-wtc.html
+++ b/docs/core-module/1-wtc.html
@@ -153,7 +153,9 @@ thing which is being compiled when it is.
     inform7_task->project = project;
     inform7_task->path = S->associated_copy->location_if_path;
     inform7_task->build = Projects::build_path(project);
-    if (Pathnames::create_in_file_system(inform7_task->build) == 0) return FALSE;
+    if (inform7_task->build) {
+        if (Pathnames::create_in_file_system(inform7_task->build) == 0) return FALSE;
+    }
     inform7_task->materials = Projects::materials_path(project);
     inform7_task->existing_storyfile = NULL;
     inform7_task->stage_of_compilation = -1;
@@ -226,7 +228,7 @@ rough stages. Twenty is plenty.
 

-inform_project *Task::project(void) {
+inform_project *Task::project(void) {
     if (inform7_task == NULL) internal_error("there is no current task");
     return inform7_task->project;
 }
@@ -253,7 +255,7 @@ rough stages. Twenty is plenty.
     return inform7_task->project->as_copy->edition;
 }
 
-parse_node_tree *Task::syntax_tree(void) {
+parse_node_tree *Task::syntax_tree(void) {
     return latest_syntax_tree;
 }
 
@@ -422,7 +424,9 @@ it to, and this is where:
 
 
 void Task::write_XML_headings_file(void) {
-    Headings::write_as_XML(Task::syntax_tree(), IndexLocations::xml_headings_filename());
+    if (inform7_task == NULL) internal_error("there is no current task");
+    if (inform7_task->project->stand_alone == FALSE)
+        Headings::write_as_XML(Task::syntax_tree(), IndexLocations::xml_headings_filename());
 }
 

§15. That's it for the project folder, but other project-related stuff is in @@ -528,10 +532,18 @@ flag stays FALSEvoid Task::disable_or_enable_index(int which) { do_not_generate_index = which; } +int do_not_generate_problems = FALSE; Set by the -no-problems command line option +void Task::disable_or_enable_problems(int which) { + do_not_generate_problems = which; +} int do_not_update_census = FALSE; Set by the -no-update-census command line option void Task::disable_or_enable_census(int which) { do_not_update_census = which; } + +int Task::problems_enabled(void) { + return do_not_generate_problems?FALSE:TRUE; +}

§19. And so, finally, the following triggers the indexing process.

diff --git a/docs/core-module/2-up.html b/docs/core-module/2-up.html index 8ab7e403b..632003663 100644 --- a/docs/core-module/2-up.html +++ b/docs/core-module/2-up.html @@ -73,18 +73,33 @@ function togglePopup(material_id) {

Interface to the Problems module.

-
+

§1.

define PROBLEMS_HTML_EMITTER HTML::put
 
-

§2. Inform tops and tails its output of problem messages, and it also prints +

§2. In "silence-is-goldem" mode, we want our Problem messages to look more like +traditional Unix errors, even if they're long ones: +

+ +
define FORMAT_CONSOLE_PROBLEMS_CALLBACK Problems::Using::console_format
+
+
+void Problems::Using::console_format(int *sig_mode, int *break_width, filename **fallback) {
+    if (Main::silence_is_golden()) {
+        *sig_mode = TRUE;
+        *break_width = 10000000;  i.e., do not word-wrap problem messages at all
+        *fallback = Projects::get_primary_source(Task::project());
+    }
+}
+
+

§3. Inform tops and tails its output of problem messages, and it also prints non-problem messages when everything was fine. That all happens here:

-
define START_PROBLEM_FILE_PROBLEMS_CALLBACK Problems::Using::start_problems_report
-define INFORMATIONAL_ADDENDA_PROBLEMS_CALLBACK Problems::Using::final_report
+
define START_PROBLEM_FILE_PROBLEMS_CALLBACK Problems::Using::start_problems_report
+define INFORMATIONAL_ADDENDA_PROBLEMS_CALLBACK Problems::Using::final_report
 
 void Problems::Using::start_problems_report(filename *F, text_stream *P) {
@@ -99,15 +114,15 @@ non-problem messages when everything was fine. That all happens here:
     int total_words = 0;
 
     if (problem_count > 0) {
-        ProblemBuffer::redirect_problem_stream(problems_file);
+        if (problems_file_active) ProblemBuffer::redirect_problem_stream(problems_file);
         Problems::issue_problem_begin(Task::syntax_tree(), "*");
-        if (disaster_struck) Issue problem summary for an internal error2.1
-        else Issue problem summary for a run with problem messages2.2;
+        if (disaster_struck) Issue problem summary for an internal error3.1
+        else Issue problem summary for a run with problem messages3.2;
         Problems::issue_problem_end();
-        ProblemBuffer::redirect_problem_stream(NULL);
+        if (problems_file_active) ProblemBuffer::redirect_problem_stream(NULL);
     } else {
         int rooms = 0, things = 0;
-        Problems::Using::html_outcome_image(problems_file, "ni_succeeded", "Succeeded");
+        if (problems_file_active) Problems::Using::html_outcome_image(problems_file, "ni_succeeded", "Succeeded");
         #ifdef IF_MODULE
         Spatial::get_world_size(&rooms, &things);
         #endif
@@ -117,17 +132,17 @@ non-problem messages when everything was fine. That all happens here:
         if (things == 1) Problems::quote_text(4, "thing"); else Problems::quote_text(4, "things");
         total_words = TextFromFiles::total_word_count(FIRST_OBJECT(source_file));
         Problems::quote_number(5, &total_words);
-        Issue problem summaries for a run without problems2.3;
+        Issue problem summaries for a run without problems3.3;
     }
 }
 
-

§2.1. One of the slightly annoying things about internal errors is that Inform's +

§3.1. One of the slightly annoying things about internal errors is that Inform's users persistently refer to them as "crashes" on bug report forms. I mean, -the effort we go to! They are entirely clean exits from the program! The +the effort we go to! These are entirely clean exits from the program! The ingratitude of some — oh, all right.

-

Issue problem summary for an internal error2.1 = +

Issue problem summary for an internal error3.1 =

@@ -145,11 +160,11 @@ ingratitude of some — oh, all right.
         "But even if your source text looks correct, there are "
         "probably rephrasings which would achieve the same effect.");
 
-
  • This code is used in §2.
-

§2.2. Singular and plural versions of the same message, really: +

  • This code is used in §3.
+

§3.2. Singular and plural versions of the same message, really:

-

Issue problem summary for a run with problem messages2.2 = +

Issue problem summary for a run with problem messages3.2 =

@@ -163,7 +178,7 @@ ingratitude of some — oh, all right.
             "Problems occurring in translation prevented the game "
             "from being properly created. (Correct the source text to "
             "remove these problems and click on Go once again.)");
-    Problems::Using::outcome_image_tail(problems_file);
+    Problems::Using::outcome_image_tail(problems_file);
 
     text_stream *STATUS = ProgressBar::begin_outcome();
     if (STATUS) {
@@ -172,8 +187,8 @@ ingratitude of some — oh, all right.
         ProgressBar::end_outcome();
     }
 
-
  • This code is used in §2.
-

§2.3. The success message needs to take different forms in stdout and in +

  • This code is used in §3.
+

§3.3. The success message needs to take different forms in stdout and in the Problems log file. In the latter, we write as though the subsequent conversion of Inform's output to a story file via Inform 6 had already been completed successfully — this is because the Problems log is intended @@ -188,7 +203,7 @@ might well not be running in the Inform application, but only on the command line — deserves the truth.

-

Issue problem summaries for a run without problems2.3 = +

Issue problem summaries for a run without problems3.3 =

@@ -201,7 +216,7 @@ command line — deserves the truth.
         "into a world with %1 %2 and %3 %4, and the index has been "
         "brought up to date.");
     Problems::issue_problem_end();
-    Problems::Using::outcome_image_tail(problems_file);
+    Problems::Using::outcome_image_tail(problems_file);
 
     if (telemetry_recording) {
         Telemetry::ensure_telemetry_file();
@@ -218,9 +233,8 @@ command line — deserves the truth.
     WRITE_TO(STDOUT, "\n");
     Problems::issue_problem_begin(Task::syntax_tree(), "**");
     Problems::issue_problem_segment(
-        "The %5-word source text has successfully been translated "
-        "into an intermediate description which can be run through "
-        "Inform 6 to complete compilation. There were %1 %2 and %3 %4.");
+        "The %5-word source text has successfully been translated. "
+        "There were %1 %2 and %3 %4.");
     Problems::issue_problem_end();
     STREAM_FLUSH(STDOUT);
     ProblemBuffer::redirect_problem_stream(NULL);
@@ -234,8 +248,8 @@ command line — deserves the truth.
         ProgressBar::end_outcome();
     }
 
-
  • This code is used in §2.
-

§3. Outcome images. These are the two images used on the Problems page to visually indicate +

  • This code is used in §3.
+

§4. Outcome images. These are the two images used on the Problems page to visually indicate success or failure. We also use special images on special occasions.

@@ -245,21 +259,21 @@ success or failure. We also use special images on special occasions.
 int outcome_image_style = SIDE_OUTCOME_IMAGE_STYLE;
 
-

§4. This callback function is called just as the problems module is about +

§5. This callback function is called just as the problems module is about to issue its first problem of the run:

-
define FIRST_PROBLEMS_CALLBACK Problems::Using::html_outcome_failed
+
define FIRST_PROBLEMS_CALLBACK Problems::Using::html_outcome_failed
 
 void Problems::Using::html_outcome_failed(OUTPUT_STREAM) {
     if (StandardProblems::internal_errors_have_occurred())
-        Problems::Using::html_outcome_image(problems_file, "ni_failed_badly", "Failed");
+        Problems::Using::html_outcome_image(problems_file, "ni_failed_badly", "Failed");
     else
-        Problems::Using::html_outcome_image(problems_file, "ni_failed", "Failed");
+        Problems::Using::html_outcome_image(problems_file, "ni_failed", "Failed");
 }
 
-void Problems::Using::html_outcome_image(OUTPUT_STREAM, char *image, char *verdict) {
+void Problems::Using::html_outcome_image(OUTPUT_STREAM, char *image, char *verdict) {
     char *vn = "";
     int be_festive = TRUE;
     if (StandardProblems::internal_errors_have_occurred() == FALSE) be_festive = FALSE;
@@ -295,16 +309,17 @@ to issue its first problem of the run:
     HTML::comment(OUT, I"PROBLEMS BEGIN");
 }
 
-void Problems::Using::outcome_image_tail(OUTPUT_STREAM) {
-    if (outcome_image_style == SIDE_OUTCOME_IMAGE_STYLE) {
-        HTML::comment(OUT, I"PROBLEMS END");
-        HTML::end_html_row(OUT);
-        HTML::end_html_table(OUT);
-        HTML::comment(OUT, I"FOOTNOTE");
-    }
+void Problems::Using::outcome_image_tail(OUTPUT_STREAM) {
+    if (problems_file_active)
+        if (outcome_image_style == SIDE_OUTCOME_IMAGE_STYLE) {
+            HTML::comment(OUT, I"PROBLEMS END");
+            HTML::end_html_row(OUT);
+            HTML::end_html_table(OUT);
+            HTML::comment(OUT, I"FOOTNOTE");
+        }
 }
 
-

§5. This is a more elaborate form of the standard StandardProblems::sentence_problem, +

§6. This is a more elaborate form of the standard StandardProblems::sentence_problem, used when an assertion sentence has gone wrong. Experience from the early builds of the Public Beta showed that many people tried syntaxes which Inform did not recognise, and which cause Inform to misread the primary @@ -350,7 +365,7 @@ a message which diagnoses the problem rather better. " %P(It may help to know that I am reading the primary verb here " "as '%4', not '%5'.)"); } - Problems::Using::diagnose_further(); + Problems::Using::diagnose_further(); Problems::issue_problem_end(); } diff --git a/docs/final-module/2-cg.html b/docs/final-module/2-cg.html index a5a560be2..41e29796a 100644 --- a/docs/final-module/2-cg.html +++ b/docs/final-module/2-cg.html @@ -80,6 +80,7 @@ function togglePopup(material_id) {

 void CodeGen::create_pipeline_stage(void) {
     CodeGen::Stage::new(I"generate", CodeGen::run_pipeline_stage, TEXT_OUT_STAGE_ARG, FALSE);
+    CodeGen::Stage::new(I"optionally-generate", CodeGen::run_pipeline_stage, OPTIONAL_TEXT_OUT_STAGE_ARG, FALSE);
 }
 
 int CodeGen::run_pipeline_stage(pipeline_step *step) {
diff --git a/docs/inform7/1-mn.html b/docs/inform7/1-mn.html
index b9c60687d..adac17471 100644
--- a/docs/inform7/1-mn.html
+++ b/docs/inform7/1-mn.html
@@ -102,29 +102,47 @@ equivalent of unlocking the doors and turning the lights on in the morning.
 

+int silence_is_golden = FALSE;
+int index_explicitly_set = FALSE, problems_explicitly_set = FALSE;
 pathname *diagnostics_path = NULL;
 
 int Main::deputy(int argc, char *argv[]) {
-    Start up the modules2.1;
-    Banner and startup2.2;
+    Start up2.1;
     int proceed = Main::read_command_line(argc, argv);
     PluginManager::start();
     if (proceed) {
+        if (silence_is_golden == FALSE)
+            PRINT("Inform 7 v[[Version Number]] has started.\n", FALSE, TRUE);
         inform_project *proj = NULL;
-        Find the project identified for us by Inbuild2.3;
-        Open the debugging log and the problems report2.4;
-        Name the telemetry2.5;
-        Build the project2.6;
+        Find the project identified for us by Inbuild2.2;
+        Open the debugging log and the problems report2.3;
+        Name the telemetry2.4;
+        Build the project2.5;
     }
 
-    Post mortem logging2.7;
-    if (proceed) Shutdown and rennab2.8;
+    Post mortem logging2.6;
+    if (proceed) Shutdown and rennab2.7;
     if (problem_count > 0) ProblemSigils::exit(1);
-    Shut down the modules2.9;
+    Shut down the modules2.8;
     return 0;
 }
 
-

§2.1. Start up the modules2.1 = +

§2.1. We need to make sure that internal errors, though they should never happen, +are reported as problem messages (fed to our HTML problems report) rather than +simply causing an abrupt exit with only a plain text error written to stderr. +See the problems module for more. +

+ +

Start up2.1 = +

+ +
+    Start up the modules2.1.1;
+    Errors::set_internal_handler(&StandardProblems::internal_error_fn);
+    Task::start_timers();
+
+
  • This code is used in §2.
+

§2.1.1. Start up the modules2.1.1 =

@@ -154,28 +172,13 @@ equivalent of unlocking the doors and turning the lights on in the morning.
     FinalModule::start();
     SupervisorModule::start();
 
-
  • This code is used in §2.
-

§2.2. The very first thing we do is to make sure internal errors, though they -should never happen, are reported as problem messages (fed to our HTML -problems report) rather than simply causing an abrupt exit with only a -plain text error written to stderr. See the problems module for more. -

- -

Banner and startup2.2 = -

- -
-    Errors::set_internal_handler(&StandardProblems::internal_error_fn);
-    PRINT("Inform 7 v[[Version Number]] has started.\n", FALSE, TRUE);
-    Task::start_timers();
-
-
  • This code is used in §2.
-

§2.3. The supervisor would happily send us instructions to compile multiple +

  • This code is used in §2.1.
+

§2.2. The supervisor would happily send us instructions to compile multiple projects, but we can only accept one; and in fact the inform7 command line isn't set up to allow more, so this error is not easy to generate.

-

Find the project identified for us by Inbuild2.3 = +

Find the project identified for us by Inbuild2.2 =

@@ -184,70 +187,91 @@ isn't set up to allow more, so this error is not easy to generate.
         if (proj) Problems::fatal("Multiple projects given on the command line");
         proj = P;
     }
+    if (proj == NULL) Problems::fatal("Nothing to compile");
+    if (proj->stand_alone) {
+        if (index_explicitly_set == FALSE)
+            Task::disable_or_enable_index(TRUE);  disable it
+        if (problems_explicitly_set == FALSE)
+            Task::disable_or_enable_problems(TRUE);  disable it
+        ProgressBar::enable_or_disable(FALSE);  disable it
+        if (Log::get_debug_log_filename() == NULL)
+            Log::set_aspect_from_command_line(I"nothing", TRUE);
+    }
+    if (silence_is_golden) Task::disable_or_enable_problems(TRUE);  disable it
 
  • This code is used in §2.
-

§2.4. supervisor supplies us with a folder in which to write the debugging log +

§2.3. supervisor supplies us with a folder in which to write the debugging log and the Problems report (the HTML version of our error messages or success message, which is displayed in the Inform app when a compilation has finished). This folder will usually be the Build subfolder of the project folder, but we won't assume that. Remember, supervisor knows best.

-

Open the debugging log and the problems report2.4 = +

Open the debugging log and the problems report2.3 =

-    pathname *build_folder = Projects::build_path(proj);
-    if (Pathnames::create_in_file_system(build_folder) == 0)
-        Problems::fatal(
-            "Unable to create Build folder for project: is it read-only?");
+    if ((proj->stand_alone == FALSE) || (Log::get_debug_log_filename())) {
+        pathname *build_folder = Projects::build_path(proj);
+        if (Pathnames::create_in_file_system(build_folder) == 0)
+            Problems::fatal(
+                "Unable to create Build folder for project: is it read-only?");
 
-    filename *DF = Filenames::in(build_folder, I"Debug log.txt");
-    Log::set_debug_log_filename(DF);
-    Log::open();
-    LOG("inform7 was called as:");
-    for (int i=0; i<argc; i++) LOG(" %s", argv[i]);
-    LOG("\n");
-    CommandLine::play_back_log();
+        filename *DF = Filenames::in(build_folder, I"Debug log.txt");
+        Log::set_debug_log_filename(DF);
+        Log::open();
+        LOG("inform7 was called as:");
+        for (int i=0; i<argc; i++) LOG(" %s", argv[i]);
+        LOG("\n");
+        CommandLine::play_back_log();
+    }
 
-    filename *PF = Filenames::in(build_folder, I"Problems.html");
-    StandardProblems::start_problems_report(PF);
+    if (Task::problems_enabled()) {
+        pathname *build_folder = Projects::build_path(proj);
+        filename *PF = Filenames::in(build_folder, I"Problems.html");
+        StandardProblems::start_problems_report(PF);
+    } else {
+        StandardProblems::start_problems_report(NULL);
+    }
 
-    HTML::set_link_abbreviation_path(Projects::path(proj));
+    HTML::set_link_abbreviation_path(Projects::path(proj));
 
  • This code is used in §2.
-

§2.5. Telemetry is not as sinister as it sounds: the app isn't sending data out +

§2.4. Telemetry is not as sinister as it sounds: the app isn't sending data out on the Internet, only (if requested) logging what it's doing to a local file. This was provided for classroom use, so that teachers can see what their students have been getting stuck on. In any case, it needs to be activated with a use option, so by default this file will never be written.

-

Name the telemetry2.5 = +

Name the telemetry2.4 =

-    pathname *P = Pathnames::down(Supervisor::transient(), I"Telemetry");
-    if (Pathnames::create_in_file_system(P)) {
-        TEMPORARY_TEXT(leafname_of_telemetry)
-        int this_month = the_present->tm_mon + 1;
-        int this_day = the_present->tm_mday;
-        int this_year = the_present->tm_year + 1900;
-        WRITE_TO(leafname_of_telemetry,
-            "Telemetry %04d-%02d-%02d.txt", this_year, this_month, this_day);
-        filename *F = Filenames::in(P, leafname_of_telemetry);
-        Telemetry::locate_telemetry_file(F);
-        DISCARD_TEXT(leafname_of_telemetry)
+    pathname *T = Supervisor::transient();
+    if (T) {
+        pathname *P = Pathnames::down(T, I"Telemetry");
+        if (Pathnames::create_in_file_system(P)) {
+            TEMPORARY_TEXT(leafname_of_telemetry)
+            int this_month = the_present->tm_mon + 1;
+            int this_day = the_present->tm_mday;
+            int this_year = the_present->tm_year + 1900;
+            WRITE_TO(leafname_of_telemetry,
+                "Telemetry %04d-%02d-%02d.txt", this_year, this_month, this_day);
+            filename *F = Filenames::in(P, leafname_of_telemetry);
+            Telemetry::locate_telemetry_file(F);
+            DISCARD_TEXT(leafname_of_telemetry)
+        }
     }
 
  • This code is used in §2.
-

§2.6. The compiler is now ready for use. We ask supervisor to go ahead and +

§2.5. The compiler is now ready for use. We ask supervisor to go ahead and build that project: it will incrementally build some of the resources needed, if any of them are, and then call upon core to perform the actual compilation.

-

Build the project2.6 = +

Build the project2.5 =

@@ -258,11 +282,11 @@ compilation.
     }
 
  • This code is used in §2.
-

§2.7. Diagnostics files fall into the category of "be careful what you wish for"; +

§2.6. Diagnostics files fall into the category of "be careful what you wish for"; they can be rather lengthy.

-

Post mortem logging2.7 = +

Post mortem logging2.6 =

@@ -293,17 +317,19 @@ they can be rather lengthy.
     }
 
  • This code is used in §2.
-

§2.8. Shutdown and rennab2.8 = +

§2.7. Shutdown and rennab2.7 =

-    ProblemBuffer::write_reports(FALSE);
-    LOG("Total of %d files written as streams.\n", total_file_writes);
-    Writers::log_escape_usage();
-    WRITE_TO(STDOUT, "Inform 7 has finished.\n");
+    if (silence_is_golden == FALSE) {
+        ProblemBuffer::write_reports(FALSE);
+        LOG("Total of %d files written as streams.\n", total_file_writes);
+        Writers::log_escape_usage();
+        WRITE_TO(STDOUT, "Inform 7 has finished.\n");
+    }
 
  • This code is used in §2.
-

§2.9. Shut down the modules2.9 = +

§2.8. Shut down the modules2.8 =

@@ -337,7 +363,7 @@ they can be rather lengthy.
 

§3.

-void Main::write_diagnostics(text_stream *leafname, void (*write_fn)(void)) {
+void Main::write_diagnostics(text_stream *leafname, void (*write_fn)(void)) {
     filename *F = Filenames::in(diagnostics_path, leafname);
     text_stream diagnostics_file;
     if (STREAM_OPEN_TO_FILE(&diagnostics_file, F, ISO_ENC) == FALSE)
@@ -350,15 +376,15 @@ they can be rather lengthy.
     STREAM_CLOSE(&diagnostics_file);
 }
 
-void Main::log_task_syntax_tree(void) {
+void Main::log_task_syntax_tree(void) {
     Node::log_tree(DL, Task::syntax_tree()->root_node);
 }
 
-void Main::log_preform_summary(void) {
+void Main::log_preform_summary(void) {
     Instrumentation::log_nt(<s-literal>, TRUE);
 }
 
-void Main::log_task_syntax_summary(void) {
+void Main::log_task_syntax_summary(void) {
     Node::summarise_tree(DL, Task::syntax_tree()->root_node);
 }
 
@@ -376,7 +402,13 @@ Inform UI apps is really a command to Register command-line arguments4.2; Supervisor::declare_options(); int proceed = CommandLine::read(argc, argv, NULL, &Main::switch, &Main::bareword); - if (proceed) Supervisor::optioneering_complete(NULL, TRUE, &CorePreform::load); + if (proceed) { + if (shared_internal_nest == NULL) { + pathname *path_to_inform = Pathnames::installation_path("INFORM7_PATH", I"inform7"); + Supervisor::add_nest(Pathnames::down(path_to_inform, I"Internal"), INTERNAL_NEST_TAG); + } + Supervisor::optioneering_complete(NULL, TRUE, &CorePreform::load); + } return proceed; }
@@ -388,11 +420,13 @@ compiler via Delia scripts in enum CRASHALL_CLSW enum DIAGNOSTICS_CLSW enum INDEX_CLSW +enum PROBLEMS_CLSW enum CENSUS_UPDATE_CLSW enum PROGRESS_CLSW enum REQUIRE_PROBLEM_CLSW enum SIGILS_CLSW enum TEST_OUTPUT_CLSW +enum SILENCE_CLSW

§4.2. Register command-line arguments4.2 =

@@ -403,6 +437,8 @@ compiler via Delia scripts in L"intentionally crash on Problem messages, for backtracing", FALSE); CommandLine::declare_boolean_switch(INDEX_CLSW, L"index", 1, L"produce an Index", TRUE); + CommandLine::declare_boolean_switch(PROBLEMS_CLSW, L"problems", 1, + L"produce (an HTML) Problems report page", TRUE); CommandLine::declare_boolean_switch(CENSUS_UPDATE_CLSW, L"census-update", 1, L"update the extensions census", TRUE); CommandLine::declare_boolean_switch(PROGRESS_CLSW, L"progress", 1, @@ -415,6 +451,8 @@ compiler via Delia scripts in L"return 0 unless exactly this Problem message is generated"); CommandLine::declare_switch(TEST_OUTPUT_CLSW, L"test-output", 2, L"write output of internal tests to file X"); + CommandLine::declare_boolean_switch(SILENCE_CLSW, L"silence", 1, + L"practice 'silence is golden': print only Unix-style errors", FALSE); CommandLine::end_group();
  • This code is used in §4.
@@ -427,13 +465,17 @@ rather than core switch (id) { case CRASHALL_CLSW: debugger_mode = val; ProblemSigils::crash_on_problems(val); break; - case INDEX_CLSW: Task::disable_or_enable_index(val?FALSE:TRUE); break; + case INDEX_CLSW: Task::disable_or_enable_index(val?FALSE:TRUE); + index_explicitly_set = TRUE; break; + case PROBLEMS_CLSW: Task::disable_or_enable_problems(val?FALSE:TRUE); + problems_explicitly_set = TRUE; break; case CENSUS_UPDATE_CLSW: Task::disable_or_enable_census(val?FALSE:TRUE); break; case PROGRESS_CLSW: ProgressBar::enable_or_disable(val); break; case SIGILS_CLSW: ProblemSigils::echo_sigils(val); break; case REQUIRE_PROBLEM_CLSW: ProblemSigils::require(arg); break; case DIAGNOSTICS_CLSW: diagnostics_path = Pathnames::from_text(arg); break; case TEST_OUTPUT_CLSW: InternalTests::set_file(Filenames::from_text(arg)); break; + case SILENCE_CLSW: silence_is_golden = TRUE; break; } Supervisor::option(id, val, arg, state); } @@ -442,6 +484,10 @@ rather than core if (Supervisor::set_I7_source(opt) == FALSE) Errors::fatal_with_text("unknown command line argument: %S (see -help)", opt); } + +int Main::silence_is_golden(void) { + return silence_is_golden; +}