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

Moved extension version checking into inbuild

This commit is contained in:
Graham Nelson 2020-02-20 00:39:36 +00:00
parent 926de356f2
commit 44fffd7bb8
19 changed files with 79 additions and 255 deletions

View file

@ -1,5 +1,5 @@
kit: CastrovalvaKit v2.7.1 (not for 32 or 32d) at path inbuild/Tests/Zoo/Inter/CastrovalvaKit
extension: New Standard Tuning by Robert Fripp v3 (for 32 or 32d) in directory inbuild/Tests/Zoo/Extensions/Robert Fripp
kit: CastrovalvaKit v2.7.1 (not for Glulx version 3.1.2 or Glulx version 3.1.2 with debugging) at path inbuild/Tests/Zoo/Inter/CastrovalvaKit
extension: New Standard Tuning by Robert Fripp v3 (for Glulx version 3.1.2 or Glulx version 3.1.2 with debugging) in directory inbuild/Tests/Zoo/Extensions/Robert Fripp
extension: Damaged by Anonymous in directory inbuild/Tests/Zoo/Extensions/Robert Fripp - 4 errors
1. extension misworded: the opening line does not end 'begin(s) here'
2. extension misworded: the titling line does not give both author and title

View file

@ -1,3 +1,3 @@
version: 2.7.1
compatibility: not for 32 or 32d
compatibility: not for 32-bit
priority: 1

View file

@ -21,7 +21,8 @@ typedef struct target_vm {
} target_vm;
target_vm *TargetVMs::new(text_stream *code, text_stream *nick, semantic_version_number V,
text_stream *image, text_stream *interpreter, text_stream *blorbed, text_stream *arch, int debug) {
text_stream *image, text_stream *interpreter, text_stream *blorbed, text_stream *arch,
int debug, int max_locals) {
target_vm *VM = CREATE(target_vm);
VM->family_name = Str::duplicate(code);
VM->version = V;
@ -29,7 +30,7 @@ target_vm *TargetVMs::new(text_stream *code, text_stream *nick, semantic_version
VM->VM_unblorbed_extension = Str::duplicate(nick);
VM->VM_blorbed_extension = Str::duplicate(blorbed);
VM->VM_image = Str::duplicate(image);
VM->max_locals = 15;
VM->max_locals = max_locals;
VM->default_browser_interpreter = Str::duplicate(interpreter);
VM->architecture = Architectures::from_codename(arch);
if (VM->architecture == NULL) internal_error("no such architecture");
@ -52,20 +53,20 @@ void TargetVMs::write(OUTPUT_STREAM, target_vm *VM) {
void TargetVMs::create(void) {
/* hat tip: Joel Berez and Marc Blank, 1979, and later hands */
TargetVMs::new(I"Z-Machine", I"z5", VersionNumbers::from_text(I"5"),
I"vm_z5.png", I"Parchment", I"zblorb", I"16", FALSE);
I"vm_z5.png", I"Parchment", I"zblorb", I"16", FALSE, 15);
TargetVMs::new(I"Z-Machine", I"z5", VersionNumbers::from_text(I"5"),
I"vm_z5.png", I"Parchment", I"zblorb", I"16d", TRUE);
I"vm_z5.png", I"Parchment", I"zblorb", I"16d", TRUE, 15);
TargetVMs::new(I"Z-Machine", I"z8", VersionNumbers::from_text(I"8"),
I"vm_z8.png", I"Parchment", I"zblorb", I"16", FALSE);
I"vm_z8.png", I"Parchment", I"zblorb", I"16", FALSE, 15);
TargetVMs::new(I"Z-Machine", I"z8", VersionNumbers::from_text(I"8"),
I"vm_z8.png", I"Parchment", I"zblorb", I"16d", TRUE);
I"vm_z8.png", I"Parchment", I"zblorb", I"16d", TRUE, 15);
/* hat tip: Andrew Plotkin, 2000 */
TargetVMs::new(I"Glulx", I"ulx", VersionNumbers::from_text(I"3.1.2"),
I"vm_glulx.png", I"Quixe", I"gblorb", I"32", FALSE);
I"vm_glulx.png", I"Quixe", I"gblorb", I"32", FALSE, 256);
TargetVMs::new(I"Glulx", I"ulx", VersionNumbers::from_text(I"3.1.2"),
I"vm_glulx.png", I"Quixe", I"gblorb", I"32d", TRUE);
I"vm_glulx.png", I"Quixe", I"gblorb", I"32d", TRUE, 256);
}
target_vm *TargetVMs::find(text_stream *ext, int debug) {

View file

@ -55,6 +55,10 @@ void Copies::write_copy(OUTPUT_STREAM, inbuild_copy *C) {
Editions::write(OUT, C->edition);
}
void Copies::inspect_copy(OUTPUT_STREAM, inbuild_copy *C) {
Editions::inspect(OUT, C->edition);
}
void Copies::go_operational(inbuild_copy *C) {
VMETHOD_CALL(C->edition->work->genre, GENRE_GO_OPERATIONAL_MTID, C);
}
@ -101,7 +105,7 @@ inbuild_copy *Copies::claim(text_stream *arg) {
void Copies::inspect(OUTPUT_STREAM, inbuild_copy *C) {
WRITE("%S: ", Genres::name(C->edition->work->genre));
Copies::write_copy(STDOUT, C);
Copies::inspect_copy(STDOUT, C);
if (C->location_if_path) {
WRITE(" at path %p", C->location_if_path);
}

View file

@ -28,6 +28,10 @@ void Editions::write(OUTPUT_STREAM, inbuild_edition *E) {
if (VersionNumbers::is_null(V) == FALSE) {
WRITE(" v%v", &V);
}
}
void Editions::inspect(OUTPUT_STREAM, inbuild_edition *E) {
Editions::write(OUT, E);
if (Compatibility::universal(E->compatibility) == FALSE) {
WRITE(" (");
Compatibility::write(OUT, E->compatibility);

View file

@ -563,8 +563,8 @@ where all is optional except the title part.
}
Works::end_extension_link(OUT, ecd->found_as->copy->edition->work);
text_stream *VMR = ExtensionManager::from_copy(ecd->found_as->copy)->reqs_as_lexed;
if (Str::len(VMR)) {
compatibility_specification *C = ecd->found_as->copy->edition->compatibility;
if (Str::len(C->parsed_from) > 0) {
@<Append icons which signify the VM requirements of the extension@>;
key_vms = TRUE;
}
@ -576,13 +576,9 @@ brackets, which the lexer will split off as distinct words, we can ignore
the first and last word and just look at what is in between:
@<Append icons which signify the VM requirements of the extension@> =
WRITE("&nbsp;");
WRITE("&nbsp;%S", C->parsed_from);
#ifdef CORE_MODULE
wording W = Feeds::feed_stream(VMR);
VirtualMachines::write_icons(OUT, Wordings::trim_last_word(Wordings::trim_last_word(W)));
#endif
#ifndef CORE_MODULE
WRITE("%S", VMR);
VirtualMachines::write_icons(OUT, C);
#endif
@<Print column 2 of the census line@> =

View file

@ -16,7 +16,6 @@ typedef struct inform_extension {
int standard; /* the (or perhaps just a) Standard Rules extension */
int authorial_modesty; /* Do not credit in the compiled game */
struct text_stream *rubric_as_lexed; /* brief description found in opening lines */
struct text_stream *reqs_as_lexed; /* such as "(for Z-machine only)" */
struct text_stream *extra_credit_as_lexed;
struct source_file *read_into_file; /* Which source file loaded this */
struct inbuild_requirement *must_satisfy;
@ -39,7 +38,6 @@ void Extensions::scan(inbuild_genre *G, inbuild_copy *C) {
E->authorial_modesty = FALSE;
E->read_into_file = NULL;
E->rubric_as_lexed = Str::new();
E->reqs_as_lexed = Str::new();
E->extra_credit_as_lexed = NULL;
E->must_satisfy = NULL;
#ifdef CORE_MODULE
@ -49,6 +47,7 @@ void Extensions::scan(inbuild_genre *G, inbuild_copy *C) {
TEMPORARY_TEXT(claimed_author_name);
TEMPORARY_TEXT(claimed_title);
TEMPORARY_TEXT(reqs);
filename *F = C->location_if_file;
semantic_version_number V = VersionNumbers::null();
@<Scan the file@>;
@ -61,12 +60,12 @@ void Extensions::scan(inbuild_genre *G, inbuild_copy *C) {
Copies::attach(C, Copies::new_error_N(EXT_AUTHOR_TOO_LONG_CE, Str::len(claimed_author_name)));
}
C->edition = Editions::new(Works::new(extension_genre, claimed_title, claimed_author_name), V);
if (Str::len(E->reqs_as_lexed) > 0) {
compatibility_specification *CS = Compatibility::from_text(E->reqs_as_lexed);
if (Str::len(reqs) > 0) {
compatibility_specification *CS = Compatibility::from_text(reqs);
if (CS) C->edition->compatibility = CS;
else {
TEMPORARY_TEXT(err);
WRITE_TO(err, "cannot read compatibility '%S'", E->reqs_as_lexed);
WRITE_TO(err, "cannot read compatibility '%S'", reqs);
Copies::attach(C, Copies::new_error(EXT_MISWORDED_CE, err));
DISCARD_TEXT(err);
}
@ -74,6 +73,7 @@ void Extensions::scan(inbuild_genre *G, inbuild_copy *C) {
Works::add_to_database(C->edition->work, CLAIMED_WDBC);
DISCARD_TEXT(claimed_author_name);
DISCARD_TEXT(claimed_title);
DISCARD_TEXT(reqs);
}
@ The following scans a potential extension file. If it seems malformed, a
@ -197,7 +197,7 @@ this is unambiguous.
@<Extract the VM requirements text, if any, from the claimed title@> =
if (Regexp::match(&mr, claimed_title, L"(%c*?) *(%(%c*%))")) {
Str::copy(claimed_title, mr.exp[0]);
Str::copy(E->reqs_as_lexed, mr.exp[1]);
Str::copy(reqs, mr.exp[1]);
}
@ =

View file

@ -8,7 +8,7 @@ arch module: for example, it matches |2.7.6| or |3/990505|.
=
<version-number> internal 1 {
TEMPORARY_TEXT(vtext);
WRITE_TO(vtext, "%W", Wordings::first_wn(W));
WRITE_TO(vtext, "%W", W);
semantic_version_number V = VersionNumbers::from_text(vtext);
int result = FALSE;
if (VersionNumbers::is_null(V) == FALSE) {
@ -21,14 +21,6 @@ arch module: for example, it matches |2.7.6| or |3/990505|.
return result;
}
@
=
int VM_matching_error_thrown = FALSE; /* an error occurred during parsing */
text_stream *most_recent_VM_family_name = NULL; /* most recent major VM which matched, or null */
int version_can_be_inferred; /* from earlier in the word range parsed */
linked_list *VM_match_list = NULL;
@ The following nonterminal matches any valid description of a virtual machine,
with result |TRUE| if the current target VM matches that description and
|FALSE| if not.
@ -39,127 +31,4 @@ with result |TRUE| if the current target VM matches that description and
compatibility_specification *C = Compatibility::from_text(vtext);
if (C) { *XP = C; return TRUE; }
*XP = NULL; return FALSE;
/* VM_matching_error_thrown = FALSE;
most_recent_VM_family_name = NULL;
version_can_be_inferred = FALSE;
VM_match_list = NEW_LINKED_LIST(format_vm);
<vm-description-list>(W);
if (VM_matching_error_thrown) { *XP = NULL; *X = FALSE; }
else { *XP = (void *) VM_match_list; *X = TRUE; }
return TRUE;
*/
}
@h Parsing VM restrictions.
Given a word range, we see what set of virtual machines it specifies. For example,
the result of calling
>> for Z-machine version 5 or 8 only
is a list of the v5 and v8 target VMs. The same result is produced by
>> for Z-machine versions 5 and 8 only
English being quirky that way.
The words "Z-machine" and "Glulx" are hard-wired so that they can't be
altered using Preform. (The Spanish for "Glulx", say, is "Glulx".) Preform
grammar is used first to split the list:
=
<vm-description-list> ::=
... | ==> 0; return preform_lookahead_mode; /* match only when looking ahead */
<vm-description-entry> <vm-description-tail> | ==> 0
<vm-description-entry> ==> 0
<vm-description-tail> ::=
, _and/or <vm-description-list> |
_,/and/or <vm-description-list>
<vm-description-entry> ::=
... ==> @<Parse latest term in word range list@>
@ Preform doesn't parse the VM names themselves, but it does pick up the
optional part about version numbering:
=
<version-identification> ::=
version/versions <version-number> ==> 0; *XP = RP[1]
@<Parse latest term in word range list@> =
semantic_version_number V = VersionNumbers::null();
TEMPORARY_TEXT(name);
WRITE_TO(name, "%W", Wordings::first_word(W));
target_vm *VM;
LOOP_OVER(VM, target_vm)
if (Str::eq_insensitive(name, VM->family_name)) {
most_recent_VM_family_name = Str::duplicate(VM->family_name);
W = Wordings::trim_first_word(W);
}
@<Give up if no family name found in any term of the list so far@>;
if (Wordings::nonempty(W)) {
if (<version-identification>(W)) {
semantic_version_number_holder *H = (semantic_version_number_holder *) <<rp>>;
V = H->version;
version_can_be_inferred = TRUE;
} else if ((version_can_be_inferred) && (<version-number>(W))) {
semantic_version_number_holder *H = (semantic_version_number_holder *) <<rp>>;
V = H->version;
} else {
VM_matching_error_thrown = TRUE; return TRUE;
}
@<Score a match for this specific version of the family, if we know about it@>;
} else {
@<Score a match for every known version of the family@>;
}
DISCARD_TEXT(name);
@ The word "version" is sometimes implicit, but not after a family name.
Thus "Glulx 3" is not allowed: it has to be "Glulx version 3".
@<Detect family name, if given, and advance one word@> =
TEMPORARY_TEXT(name);
WRITE_TO(name, "%W", Wordings::first_wn(W));
target_vm *VM;
LOOP_OVER(VM, target_vm) {
most_recent_VM_family_name =
if (Str::eq_insensitive(name, VM->family_name)) {
most_recent_VM_family_name = VM->family_name;
version_can_be_inferred = FALSE;
break;
}
}
@ The variable |VM_matching_error_thrown| may have been set either on
this term or a previous one: for instance, if we are reading "Squirrel
versions 4 and 7" then at the second term, "7", no family is named
but the variable remains set from "Squirrel" having been parsed at the
first term.
@<Give up if no family name found in any term of the list so far@> =
if (most_recent_VM_family_name == NULL) {
VM_matching_error_thrown = TRUE; return TRUE;
}
@ We either make a run of matches:
@<Score a match for every known version of the family@> =
target_vm *VM;
LOOP_OVER(VM, target_vm)
if (Str::eq_insensitive(VM->family_name, most_recent_VM_family_name))
ADD_TO_LINKED_LIST(VM, target_VM, VM_match_list);
@ ...or else we make a single match, or even none at all. This would not be
an error: if the request was for "version 71 of Chipmunk", and we were
unable to compile to this VM (so that no such minor VM record appeared in
the table) then the situation might be that we are reading the requirements
of some extension used by other people, who have a later version of Inform
than us, and which does compile to that VM.
@<Score a match for this specific version of the family, if we know about it@> =
target_vm *VM;
LOOP_OVER(VM, target_vm)
if ((Str::eq_insensitive(VM->family_name, most_recent_VM_family_name)) &&
(VersionNumbers::eq(VM->version, V)))
ADD_TO_LINKED_LIST(VM, target_VM, VM_match_list);

View file

@ -1,5 +0,0 @@
Extmiswordedbeginshere Extension [by Araminta Intest] begins here.
Polynesia is a room.
Extmiswordedbeginshere Extension ends here.

View file

@ -1,3 +0,0 @@
Include ExtMalformedVM Extension by Araminta Intest.
Clifftop is a room.

View file

@ -1,3 +0,0 @@
Include Extmiswordedbeginshere Extension by Araminta Intest.
Xenon is a room.

View file

@ -1,13 +1,14 @@
Inform 7 build 6L26 has started.
Inform 7.10.1 build 6Q21 has started.
I've now read your source text, which is 10 words long.
I've also read Standard Rules by Graham Nelson, which is 42597 words long.
I've also read English Language by Graham Nelson, which is 2288 words long.
I've also read Basic Inform by Graham Nelson, which is 7645 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.
I've also read Extinadequatevm Extension by Araminta Intest, which is 14 words long.
Problem__ PM_ExtInadequateVM
>--> You wrote 'Include Extinadequatevm Extension by Araminta Intest' (source
text, line 1): but my copy of Extinadequatevm Extension by Araminta Intest
stipulates that it is 'for Glulx only'. That means it can only be used with
certain of the possible compiled story file formats, and at the moment, we
don't fit the requirements. (You can change the format used for this
project on the Settings panel.)
Inform 7 has finished: 8 centiseconds used.
stipulates that it is '(For Glulx Only)'. That means it can only be used
with certain of the possible compiled story file formats, and at the
moment, we don't fit the requirements. (You can change the format used for
this project on the Settings panel.)
Inform 7 has finished: 12 centiseconds used.

View file

@ -1,13 +0,0 @@
Inform 7.10.1 build 6Q21 has started.
I've now read your source text, which is 10 words long.
I've also read Basic Inform by Graham Nelson, which is 7645 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.
I've also read Extmalformedvm Extension by Araminta Intest, which is 15 words long.
Problem__ PM_ExtMalformedVM
>--> Your source text makes use of the extension Extmalformedvm Extension by
Araminta Intest: but my copy stipulates that it is 'for clockwork train
sets', which is a description of the required story file format which I
can't understand, and should be something like '(for Z-machine version 5 or
8 only)'.
Inform 7 has finished: 12 centiseconds used.

View file

@ -1,11 +0,0 @@
Inform 7.10.1 build 6Q21 has started.
I've now read your source text, which is 10 words long.
I've also read Basic Inform by Graham Nelson, which is 7645 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_ExtMiswordedBeginsHere
>--> The extension Extmiswordedbeginshere Extension by Araminta Intest, which
your source text makes use of, seems to be damaged or incorrect: its
identifying opening line is wrong. Specifically, the titling line does not
give both author and title.
Inform 7 has finished: 12 centiseconds used.

View file

@ -402,7 +402,7 @@ divided up by the extensions containing the rules which produce them.
@<Start a possible run of matches@> =
if (contiguous_match == FALSE) {
contiguous_match = TRUE;
if (no_cms++ == 0) {
if ((no_cms++ == 0) && (E)) {
TEMPORARY_TEXT(QT);
WRITE_TO(QT, "%<X", E->as_copy->edition->work);
Emit::array_text_entry(QT);

View file

@ -30,11 +30,13 @@ void VirtualMachines::set_identifier(text_stream *text, int debugging) {
current_target_VM = TargetVMs::find(text, debugging);
}
int VirtualMachines::compatible_with(compatibility_specification *C) {
return Compatibility::with(C, current_target_VM);
}
<current-virtual-machine> internal {
if (<virtual-machine>(W)) {
*X = FALSE;
compatibility_specification *C = (compatibility_specification *) <<rp>>;
*X = Compatibility::with(C, current_target_VM);
*X = VirtualMachines::compatible_with((compatibility_specification *) <<rp>>);
return TRUE;
} else {
*X = FALSE;
@ -311,22 +313,19 @@ row of icons (but do not bother for the common case where some extension
has no restriction on its use).
=
void VirtualMachines::write_icons(OUTPUT_STREAM, wording W) {
if (<virtual-machine>(W)) {
compatibility_specification *C = (compatibility_specification *) <<rp>>;
int something = FALSE, everything = TRUE;
target_vm *VM;
void VirtualMachines::write_icons(OUTPUT_STREAM, compatibility_specification *C) {
int something = FALSE, everything = TRUE;
target_vm *VM;
LOOP_OVER(VM, target_vm)
if (Compatibility::with(C, VM))
something = TRUE;
else
everything = FALSE;
if (something == FALSE) WRITE("none");
if (everything == FALSE)
LOOP_OVER(VM, target_vm)
if (Compatibility::with(C, VM))
something = TRUE;
else
everything = FALSE;
if (something == FALSE) WRITE("none");
if (everything == FALSE)
LOOP_OVER(VM, target_vm)
if (Compatibility::with(C, VM))
VirtualMachines::plot_icon(OUT, VM);
}
VirtualMachines::plot_icon(OUT, VM);
}
@ The following table in the index (on the Contents page) may be useful to a

View file

@ -182,10 +182,10 @@ different template:
WRITE("&nbsp;");
@<Write up any restrictions on VM usage@> =
if (Wordings::nonempty(Extensions::get_VM_text(E))) {
WRITE("%+W", Extensions::get_VM_text(E));
WRITE("&nbsp;");
VirtualMachines::write_icons(OUT, Extensions::get_VM_text(E));
compatibility_specification *C = E->as_copy->edition->compatibility;
if (Str::len(C->parsed_from) > 0) {
WRITE("%S&nbsp;", C->parsed_from);
VirtualMachines::write_icons(OUT, C);
}
@<Write up the version number, if any, and location@> =

View file

@ -251,8 +251,9 @@ trap-door into Read Source Text, to seek and open the file.
}
@ =
int last_PM_ExtVersionMalformed_at = -1;
semantic_version_number Extensions::Inclusion::parse_version(int vwn) {
semantic_version_number V = VersionNumbers::from_pair(1, 0); /* which equates to |1/000000| */
semantic_version_number V = VersionNumbers::null();
wording W = Wordings::one_word(vwn);
if (<version-number>(W)) {
semantic_version_number_holder *H = (semantic_version_number_holder *) <<rp>>;
@ -269,13 +270,15 @@ over and over. We do this by altering the text to |1|, the lowest well-formed
version number text.
@<Issue a problem message for a malformed version number@> =
LOG("Offending word number %d <%N>\n", vwn, vwn);
Problems::Issue::sentence_problem(_p_(PM_ExtVersionMalformed),
"a version number must have the form N/DDDDDD",
"as in the example '2/040426' for release 2 made on 26 April 2004. "
"(The DDDDDD part is optional, so '3' is a legal version number too. "
"N must be between 1 and 999: in particular, there is no version 0.)");
Vocabulary::change_text_of_word(vwn, L"1");
if (last_PM_ExtVersionMalformed_at != vwn) {
last_PM_ExtVersionMalformed_at = vwn;
LOG("Offending word number %d <%N>\n", vwn, vwn);
Problems::Issue::sentence_problem(_p_(PM_ExtVersionMalformed),
"a version number must have the form N/DDDDDD",
"as in the example '2/040426' for release 2 made on 26 April 2004. "
"(The DDDDDD part is optional, so '3' is a legal version number too. "
"N must be between 1 and 999: in particular, there is no version 0.)");
}
@h Checking the begins here and ends here sentences.
When a newly loaded extension is being sentence-broken, problem messages
@ -325,8 +328,7 @@ void Extensions::Inclusion::check_begins_here(parse_node *PN, inform_extension *
<begins-here-sentence-subject>(ParseTree::get_text(PN));
Extensions::set_VM_text(E, Wordings::new(<<rest1>>, <<rest2>>));
if (Wordings::nonempty(Extensions::get_VM_text(E)))
@<Check that the extension's stipulation about the virtual machine can be met@>;
@<Check that the extension's stipulation about the virtual machine can be met@>;
}
@ On the other hand, we do already know what virtual machine we are compiling
@ -334,26 +336,9 @@ for, so we can immediately object if the loaded extension cannot be used
with our VM de jour.
@<Check that the extension's stipulation about the virtual machine can be met@> =
if (<platform-qualifier>(Extensions::get_VM_text(E))) {
if (<<r>> == PLATFORM_UNMET_HQ)
@<Issue a problem message saying that the VM does not meet requirements@>;
} else {
@<Issue a problem message saying that the VM requirements are malformed@>;
}
@ See Virtual Machines for the grammar of what can be given as a VM
requirement.
@<Issue a problem message saying that the VM requirements are malformed@> =
Problems::quote_extension(1, E);
Problems::quote_wording(2, Extensions::get_VM_text(E));
Problems::Issue::handmade_problem(_p_(PM_ExtMalformedVM));
Problems::issue_problem_segment(
"Your source text makes use of the extension %1: but my copy "
"stipulates that it is '%2', which is a description of the required "
"story file format which I can't understand, and should be "
"something like '(for Z-machine version 5 or 8 only)'.");
Problems::issue_problem_end();
compatibility_specification *C = E->as_copy->edition->compatibility;
if (VirtualMachines::compatible_with(C) == FALSE)
@<Issue a problem message saying that the VM does not meet requirements@>;
@ 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
@ -364,7 +349,7 @@ report this problem at the inclusion line.
current_sentence = Extensions::get_inclusion_sentence(E);
Problems::quote_source(1, current_sentence);
Problems::quote_copy(2, E->as_copy);
Problems::quote_wording(3, Extensions::get_VM_text(E));
Problems::quote_stream(3, C->parsed_from);
Problems::Issue::handmade_problem(_p_(PM_ExtInadequateVM));
Problems::issue_problem_segment(
"You wrote %1: but my copy of %2 stipulates that it "

View file

@ -582,7 +582,7 @@ To provide an example, ^{@Emily Short}'s useful extension "Locksmith" is one of
Each time that Inform translates any source text, it performs a quick check of the extensions available, and updates its own internal records. A directory of the extensions currently installed can be found by clicking on "Installed Extensions" from the Extensions panel. This is also worth visiting in order to browse the Public Library, a selection of extensions contributed by Inform users.
[x] Including extensions {PM_IncludeExtQuoted} {PM_ExtVersionMalformed} {PM_ExtMiswordedBeginsHere} {PM_ExtMalformedVM} {PM_ExtInadequateVM} {PM_ExtMisidentifiedEnds}
[x] Including extensions {PM_IncludeExtQuoted} {PM_ExtVersionMalformed} {PM_ExtMiswordedBeginsHere} {PM_ExtInadequateVM} {PM_ExtMisidentifiedEnds}
^^{extensions: using}
^^{include (extension) by (extension author)+assert+}