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

Divided old extension_file structure into requirement plus copy

This commit is contained in:
Graham Nelson 2020-02-03 09:25:57 +00:00
parent 5b5e6ccf47
commit accbe7e16c
11 changed files with 230 additions and 122 deletions

View file

@ -9,6 +9,7 @@ Setting up the use of this module.
@ To begin with, this module needs to allocate memory:
@e inform_kit_MT
@e inform_extension_MT
@e inform_kit_ittt_MT
@e element_activation_MT
@e inbuild_genre_MT
@ -26,6 +27,7 @@ Setting up the use of this module.
=
ALLOCATE_INDIVIDUALLY(inform_kit)
ALLOCATE_INDIVIDUALLY(inform_extension)
ALLOCATE_INDIVIDUALLY(inform_kit_ittt)
ALLOCATE_INDIVIDUALLY(element_activation)
ALLOCATE_INDIVIDUALLY(inbuild_genre)

View file

@ -73,6 +73,30 @@ inbuild_requirement *Model::requirement(inbuild_work *work,
return req;
}
int Model::meets(inbuild_version_number V, inbuild_requirement *req) {
if (req == NULL) return TRUE;
if (VersionNumbers::is_null(req->min_version) == FALSE) {
if (VersionNumbers::is_null(V)) return FALSE;
if (VersionNumbers::lt(V, req->min_version)) return FALSE;
}
if (VersionNumbers::is_null(req->max_version) == FALSE) {
if (VersionNumbers::is_null(V)) return TRUE;
if (VersionNumbers::gt(V, req->max_version)) return FALSE;
}
return TRUE;
}
int Model::ratchet_minimum(inbuild_version_number V, inbuild_requirement *req) {
if (req == NULL) internal_error("no requirement");
if (VersionNumbers::is_null(V)) return FALSE;
if ((VersionNumbers::is_null(req->min_version)) ||
(VersionNumbers::gt(V, req->min_version))) {
req->min_version = V;
return TRUE;
}
return FALSE;
}
@h Copies.
A "copy" of a work exists in the file system when we've actually got hold of
some edition of it. For some genres, copies will be files; for others,

View file

@ -37,3 +37,47 @@ void Extensions::location_in_nest(inbuild_genre *gen, inbuild_nest *N, inbuild_r
void Extensions::copy_to_nest(inbuild_genre *gen, inbuild_copy *C, inbuild_nest *N, int syncing) {
internal_error("unimplemented");
}
typedef struct inform_extension {
struct inbuild_copy *as_copy;
struct inbuild_version_number version_loaded; /* As actually loaded */
#ifdef CORE_MODULE
struct wording body_text; /* Body of source text supplied in extension, if any */
int body_text_unbroken; /* Does this contain text waiting to be sentence-broken? */
struct wording documentation_text; /* Documentation supplied in extension, if any */
int loaded_from_built_in_area; /* Located within Inform application */
int authorial_modesty; /* Do not credit in the compiled game */
struct source_file *read_into_file; /* Which source file loaded this */
struct text_stream *rubric_as_lexed;
struct text_stream *extra_credit_as_lexed;
#endif
MEMORY_MANAGEMENT
} inform_extension;
inform_extension *Extensions::load_at(text_stream *title, text_stream *author, filename *F) {
inform_extension *E = CREATE(inform_extension);
inbuild_work *work = Works::new(extension_genre, title, author);
inbuild_edition *edition = Model::edition(work, VersionNumbers::null());
E->as_copy = Model::copy_in_file(edition, F, STORE_POINTER_inform_extension(E));
E->version_loaded = VersionNumbers::null();
#ifdef CORE_MODULE
E->body_text = EMPTY_WORDING;
E->body_text_unbroken = FALSE;
E->documentation_text = EMPTY_WORDING;
E->loaded_from_built_in_area = FALSE;
E->authorial_modesty = FALSE;
E->rubric_as_lexed = NULL;
E->extra_credit_as_lexed = NULL;
#endif
return E;
}
inform_extension *Extensions::from_copy(inbuild_copy *C) {
if ((C) && (C->edition->work->genre == extension_genre)) {
return RETRIEVE_POINTER_inform_extension(C->content);
}
return NULL;
}

View file

@ -58,10 +58,11 @@ compilation_module *Modules::new(parse_node *from) {
DISCARD_TEXT(pname);
if (owner) {
Hierarchy::markup(C->inter_presence->the_package, EXT_AUTHOR_HMD, owner->ef_work->raw_author_name);
Hierarchy::markup(C->inter_presence->the_package, EXT_TITLE_HMD, owner->ef_work->raw_title);
Hierarchy::markup(C->inter_presence->the_package, EXT_AUTHOR_HMD, owner->ef_req->work->raw_author_name);
Hierarchy::markup(C->inter_presence->the_package, EXT_TITLE_HMD, owner->ef_req->work->raw_title);
TEMPORARY_TEXT(V);
WRITE_TO(V, "%+W", Wordings::one_word(owner->version_loaded));
inbuild_version_number N = Extensions::Files::get_version(owner);
WRITE_TO(V, "%v", &N);
Hierarchy::markup(C->inter_presence->the_package, EXT_VERSION_HMD, V);
DISCARD_TEXT(V);
}

View file

@ -677,6 +677,7 @@ void Sentences::Headings::suppress_dependencies(parse_node *pn) {
Problems::issue_problem_end();
@<Can't find heading in the given extension@> =
TEMPORARY_TEXT(vt);
current_sentence = h->sentence_declaring;
Problems::quote_source(1, current_sentence);
Problems::quote_extension_id(2, h->for_use_with);
@ -685,9 +686,10 @@ void Sentences::Headings::suppress_dependencies(parse_node *pn) {
"unspecified, that is, the extension didn't have a version number");
extension_file *ef;
LOOP_OVER(ef, extension_file)
if (Works::match(h->for_use_with, Extensions::Files::get_work(ef)))
Problems::quote_wording(4,
Wordings::one_word(Extensions::Files::get_version_wn(ef)));
if (Works::match(h->for_use_with, Extensions::Files::get_work(ef))) {
VersionNumbers::to_text(vt, Extensions::Files::get_version(ef));
Problems::quote_stream(4, vt);
}
Problems::Issue::handmade_problem(_p_(PM_HeadingInPlaceOfUnknown));
Problems::issue_problem_segment(
"In the sentence %1, it looks as if you intend to replace a section "
@ -695,6 +697,7 @@ void Sentences::Headings::suppress_dependencies(parse_node *pn) {
"not seem to have any heading called '%3'. (The version I loaded "
"was %4.)");
Problems::issue_problem_end();
DISCARD_TEXT(vt);
@<Can't replace heading unless level matches@> =
current_sentence = h->sentence_declaring;

View file

@ -148,7 +148,7 @@ void Extensions::Dictionary::erase_entries(extension_file *ef) {
LOGIF(EXTENSIONS_CENSUS, "Erasure of dictionary entries for $x\n", ef);
LOOP_OVER(ede, extension_dictionary_entry)
if ((ede->erased == FALSE) &&
(Works::match(ede->ede_work, ef->ef_work))) {
(Works::match(ede->ede_work, ef->ef_req->work))) {
ede->erased = TRUE;
LOGIF(EXTENSIONS_CENSUS, "Erased $d", ede);
}
@ -162,13 +162,13 @@ void Extensions::Dictionary::new_entry(text_stream *category, extension_file *ef
if (Wordings::nonempty(W)) { /* a safety precaution: never index the empty text */
TEMPORARY_TEXT(headword);
WRITE_TO(headword, "%+W", W);
Extensions::Dictionary::new_dictionary_entry_raw(category, ef->ef_work->author_name, ef->ef_work->title, headword);
Extensions::Dictionary::new_dictionary_entry_raw(category, ef->ef_req->work->author_name, ef->ef_req->work->title, headword);
DISCARD_TEXT(headword);
}
}
void Extensions::Dictionary::new_entry_from_stream(text_stream *category, extension_file *ef, text_stream *headword) {
Extensions::Dictionary::new_dictionary_entry_raw(category, ef->ef_work->author_name, ef->ef_work->title, headword);
Extensions::Dictionary::new_dictionary_entry_raw(category, ef->ef_req->work->author_name, ef->ef_req->work->title, headword);
}
void Extensions::Dictionary::new_dictionary_entry_raw(text_stream *category,
@ -289,7 +289,7 @@ void Extensions::Dictionary::time_stamp(extension_file *ef) {
the_present->tm_year+1900, the_present->tm_mon + 1, the_present->tm_mday,
the_present->tm_hour, the_present->tm_min, the_present->tm_sec,
TextFromFiles::total_word_count(
Extensions::Files::get_corresponding_source_file(ef)),
Extensions::Files::source(ef)),
ascday[the_present->tm_wday], the_present->tm_mday,
ascmon[the_present->tm_mon], the_present->tm_year+1900,
the_present->tm_hour, the_present->tm_min);

View file

@ -64,7 +64,7 @@ int Extensions::Documentation::write_extension_documentation_page(extension_cens
FILE *TEST_DOCF;
int page_exists_already, no_egs = 0;
if (ecd) work = ecd->ecd_work; else if (ef) work = ef->ef_work;
if (ecd) work = ecd->ecd_work; else if (ef) work = ef->ef_req->work;
else internal_error("WEDP incorrectly called");
LOGIF(EXTENSIONS_CENSUS, "WEDP %s (%X)/%d\n", (ecd)?"ecd":" ef", work, eg_number);
@ -188,20 +188,25 @@ different template:
}
@<Write up the version number, if any, and location@> =
if (ef->version_loaded >= 0) {
WRITE("Version %+W", Wordings::one_word(ef->version_loaded));
}
if (ef->loaded_from_built_in_area) {
if (ef->version_loaded < 0) { WRITE("Extension"); }
WRITE(" built in to Inform");
inform_extension *E = Extensions::Files::find(ef);
if (E) {
inbuild_version_number V = Extensions::Files::get_version(ef);
if (VersionNumbers::is_null(V) == FALSE) WRITE("Version %v", &V);
if (E->loaded_from_built_in_area) {
if (VersionNumbers::is_null(V)) { WRITE("Extension"); }
WRITE(" built in to Inform");
}
}
@<Write up the rubric, if any@> =
if (Str::len(ef->rubric_as_lexed) > 0) {
HTML_OPEN("p"); WRITE("%S", ef->rubric_as_lexed); HTML_CLOSE("p");
}
if (Str::len(ef->extra_credit_as_lexed) > 0) {
HTML_OPEN("p"); WRITE("<i>%S</i>", ef->extra_credit_as_lexed); HTML_CLOSE("p");
inform_extension *E = Extensions::Files::find(ef);
if (E) {
if (Str::len(E->rubric_as_lexed) > 0) {
HTML_OPEN("p"); WRITE("%S", E->rubric_as_lexed); HTML_CLOSE("p");
}
if (Str::len(E->extra_credit_as_lexed) > 0) {
HTML_OPEN("p"); WRITE("<i>%S</i>", E->extra_credit_as_lexed); HTML_CLOSE("p");
}
}
@ This appears above the definition paragraphs because it tends to be only
@ -210,19 +215,25 @@ If the TOC were directly at the top of the supplied documentation, it might
easily be scrolled down off screen when the user first visits the page.
@<Write up the table of contents for the extension author's supplied documentation, if any@> =
if (Wordings::nonempty(ef->documentation_text)) {
HTML_OPEN("p");
HTML::Documentation::set_table_of_contents(ef->documentation_text, OUT, leaf);
HTML_CLOSE("p");
inform_extension *E = Extensions::Files::find(ef);
if (E) {
if (Wordings::nonempty(E->documentation_text)) {
HTML_OPEN("p");
HTML::Documentation::set_table_of_contents(E->documentation_text, OUT, leaf);
HTML_CLOSE("p");
}
}
@<Write up the extension author's supplied documentation, if any@> =
if (Wordings::nonempty(ef->documentation_text))
no_egs = HTML::Documentation::set_body_text(ef->documentation_text, OUT, eg_number, leaf);
else {
HTML_OPEN("p");
WRITE("The extension provides no documentation.");
HTML_CLOSE("p");
inform_extension *E = Extensions::Files::find(ef);
if (E) {
if (Wordings::nonempty(E->documentation_text))
no_egs = HTML::Documentation::set_body_text(E->documentation_text, OUT, eg_number, leaf);
else {
HTML_OPEN("p");
WRITE("The extension provides no documentation.");
HTML_CLOSE("p");
}
}
@ Nothing can prevent a certain repetitiousness intruding here, but there is
@ -259,7 +270,7 @@ documentation page could be forgiven for thinking it a miscellany.
LOOP_OVER_BASE_KINDS(K) {
parse_node *S = Kinds::Behaviour::get_creating_sentence(K);
if (S) {
if (Lexer::file_of_origin(Wordings::first_wn(ParseTree::get_text(S))) == ef->read_into_file) {
if (Lexer::file_of_origin(Wordings::first_wn(ParseTree::get_text(S))) == Extensions::Files::source(ef)) {
wording W = Kinds::Behaviour::get_name(K, FALSE);
kc = Extensions::Documentation::document_headword(OUT, kc, ef, "Kinds", I"kind", W);
kind *S = Kinds::Compare::super(K);
@ -282,7 +293,7 @@ documentation page could be forgiven for thinking it a miscellany.
if ((Instances::get_creating_sentence(I)) && (Wordings::nonempty(OW))) {
if (Lexer::file_of_origin(
Wordings::first_wn(ParseTree::get_text(Instances::get_creating_sentence(I))))
== ef->read_into_file) {
== Extensions::Files::source(ef)) {
TEMPORARY_TEXT(name_of_its_kind);
kind *k = Instances::to_kind(I);
wording W = Kinds::Behaviour::get_name(k, FALSE);
@ -304,7 +315,7 @@ documentation page could be forgiven for thinking it a miscellany.
LOOP_OVER(q, nonlocal_variable)
if ((Wordings::first_wn(q->name) >= 0) &&
(NonlocalVariables::is_global(q)) &&
(Lexer::file_of_origin(Wordings::first_wn(q->name)) == ef->read_into_file) &&
(Lexer::file_of_origin(Wordings::first_wn(q->name)) == Extensions::Files::source(ef)) &&
(Sentences::Headings::indexed(Sentences::Headings::of_wording(q->name)))) {
if (<value-understood-variable-name>(q->name) == FALSE)
kc = Extensions::Documentation::document_headword(OUT,
@ -319,7 +330,7 @@ documentation page could be forgiven for thinking it a miscellany.
int kc = 0;
LOOP_OVER_ENUMERATION_INSTANCES(q) {
wording NW = Instances::get_name(q, FALSE);
if ((Wordings::nonempty(NW)) && (Lexer::file_of_origin(Wordings::first_wn(NW)) == ef->read_into_file))
if ((Wordings::nonempty(NW)) && (Lexer::file_of_origin(Wordings::first_wn(NW)) == Extensions::Files::source(ef)))
kc = Extensions::Documentation::document_headword(OUT, kc, ef, "Values", I"value", NW);
}
if (kc != 0) HTML_CLOSE("p");
@ -328,20 +339,20 @@ documentation page could be forgiven for thinking it a miscellany.
@<Document and dictionary the kinds of action made in extension@> =
#ifdef IF_MODULE
PL::Actions::Patterns::Named::index_for_extension(OUT, ef->read_into_file, ef);
PL::Actions::Patterns::Named::index_for_extension(OUT, Extensions::Files::source(ef), ef);
#endif
@ Actions:
@<Document and dictionary the actions made in extension@> =
#ifdef IF_MODULE
PL::Actions::Index::index_for_extension(OUT, ef->read_into_file, ef);
PL::Actions::Index::index_for_extension(OUT, Extensions::Files::source(ef), ef);
#endif
@ Verbs (this one we delegate):
@<Document and dictionary the verbs made in extension@> =
Index::Lexicon::list_verbs_in_file(OUT, ef->read_into_file, ef);
Index::Lexicon::list_verbs_in_file(OUT, Extensions::Files::source(ef), ef);
@ Adjectival phrases:
@ -351,7 +362,7 @@ documentation page could be forgiven for thinking it a miscellany.
LOOP_OVER(adj, adjectival_phrase) {
wording W = Adjectives::get_text(adj, FALSE);
if ((Wordings::nonempty(W)) &&
(Lexer::file_of_origin(Wordings::first_wn(W)) == ef->read_into_file))
(Lexer::file_of_origin(Wordings::first_wn(W)) == Extensions::Files::source(ef)))
kc = Extensions::Documentation::document_headword(OUT, kc, ef, "Adjectives", I"adjective", W);
}
if (kc != 0) HTML_CLOSE("p");
@ -364,7 +375,7 @@ documentation page could be forgiven for thinking it a miscellany.
LOOP_OVER(prn, property)
if ((Wordings::nonempty(prn->name)) &&
(Properties::is_shown_in_index(prn)) &&
(Lexer::file_of_origin(Wordings::first_wn(prn->name)) == ef->read_into_file))
(Lexer::file_of_origin(Wordings::first_wn(prn->name)) == Extensions::Files::source(ef)))
kc = Extensions::Documentation::document_headword(OUT, kc, ef, "Properties", I"property",
prn->name);
if (kc != 0) HTML_CLOSE("p");
@ -376,7 +387,7 @@ documentation page could be forgiven for thinking it a miscellany.
int kc = 0;
LOOP_OVER(uo, use_option)
if ((Wordings::first_wn(uo->name) >= 0) &&
(Lexer::file_of_origin(Wordings::first_wn(uo->name)) == ef->read_into_file))
(Lexer::file_of_origin(Wordings::first_wn(uo->name)) == Extensions::Files::source(ef)))
kc = Extensions::Documentation::document_headword(OUT, kc, ef, "Use options", I"use option",
uo->name);
if (kc != 0) HTML_CLOSE("p");

View file

@ -142,21 +142,12 @@ its purpose.
=
typedef struct extension_file {
struct inbuild_work *ef_work; /* Texts of title and author with hash code */
struct inbuild_requirement *ef_req; /* Work and version needed */
struct wording author_text; /* Author's name */
struct wording title_text; /* Extension name */
struct wording body_text; /* Body of source text supplied in extension, if any */
int body_text_unbroken; /* Does this contain text waiting to be sentence-broken? */
struct wording documentation_text; /* Documentation supplied in extension, if any */
struct wording VM_restriction_text; /* Restricting use to certain VMs */
int min_version_needed; /* As stipulated by source */
int version_loaded; /* As actually loaded */
int loaded_from_built_in_area; /* Located within Inform application */
int authorial_modesty; /* Do not credit in the compiled game */
struct parse_node *inclusion_sentence; /* Where the source called for this */
struct source_file *read_into_file; /* Which source file loaded this */
struct text_stream *rubric_as_lexed;
struct text_stream *extra_credit_as_lexed;
struct inbuild_copy *found;
MEMORY_MANAGEMENT
} extension_file;
@ -172,17 +163,9 @@ extension_file *Extensions::Files::new(wording AW, wording NW, wording VMW, int
ef->author_text = AW;
ef->title_text = NW;
@<Create work for new extension file@>;
ef->min_version_needed = version_word;
ef->inclusion_sentence = current_sentence;
ef->VM_restriction_text = VMW;
ef->body_text = EMPTY_WORDING;
ef->body_text_unbroken = FALSE;
ef->documentation_text = EMPTY_WORDING;
ef->version_loaded = -1;
ef->loaded_from_built_in_area = FALSE;
ef->authorial_modesty = FALSE;
ef->rubric_as_lexed = NULL;
ef->extra_credit_as_lexed = NULL;
ef->found = NULL;
if (Str::len(violation) > 0) {
LOG("So %S\n", violation);
Problems::Issue::extension_problem_S(_p_(PM_IncludesTooLong), ef, violation); /* see below */
@ -191,6 +174,12 @@ extension_file *Extensions::Files::new(wording AW, wording NW, wording VMW, int
return ef;
}
inform_extension *Extensions::Files::find(extension_file *ef) {
if (ef == NULL) return NULL;
if (ef->found == NULL) return NULL;
return Extensions::from_copy(ef->found);
}
@ We protect ourselves a little against absurdly long requested author or
title names, and then produce problem messages in the event of only longish
ones, unless the census is going on: in which case it's better to leave the
@ -219,9 +208,12 @@ matter to the census errors system elsewhere.
Str::truncate(exft, MAX_EXTENSION_AUTHOR_LENGTH-1);
}
}
ef->ef_work = Works::new(extension_genre, exft, exfa);
Works::add_to_database(ef->ef_work, LOADED_WDBC);
if (Works::is_standard_rules(ef->ef_work)) standard_rules_extension = ef;
inbuild_work *work = Works::new(extension_genre, exft, exfa);
Works::add_to_database(work, LOADED_WDBC);
inbuild_version_number min = VersionNumbers::null();
if (version_word >= 0) min = Extensions::Inclusion::parse_version(version_word);
ef->ef_req = Model::requirement(work, min, VersionNumbers::null());
if (Works::is_standard_rules(work)) standard_rules_extension = ef;
DISCARD_TEXT(exft);
DISCARD_TEXT(exfa);
@ -238,13 +230,17 @@ sources, collaborators, translators and so on.
=
void Extensions::Files::set_rubric(extension_file *ef, text_stream *text) {
ef->rubric_as_lexed = Str::duplicate(text);
LOGIF(EXTENSIONS_CENSUS, "Extension rubric: %S\n", ef->rubric_as_lexed);
inform_extension *E = Extensions::Files::find(ef);
if (E == NULL) internal_error("unfound ef");
E->rubric_as_lexed = Str::duplicate(text);
LOGIF(EXTENSIONS_CENSUS, "Extension rubric: %S\n", E->rubric_as_lexed);
}
void Extensions::Files::set_extra_credit(extension_file *ef, text_stream *text) {
ef->extra_credit_as_lexed = Str::duplicate(text);
LOGIF(EXTENSIONS_CENSUS, "Extension extra credit: %S\n", ef->extra_credit_as_lexed);
inform_extension *E = Extensions::Files::find(ef);
if (E == NULL) internal_error("unfound ef");
E->extra_credit_as_lexed = Str::duplicate(text);
LOGIF(EXTENSIONS_CENSUS, "Extension extra credit: %S\n", E->extra_credit_as_lexed);
}
@ Once we start reading text from the file (if it can successfully be found:
@ -253,25 +249,38 @@ it up with the corresponding source file structure.
=
void Extensions::Files::set_corresponding_source_file(extension_file *ef, source_file *sf) {
ef->read_into_file = sf;
inform_extension *E = Extensions::load_at(
ef->ef_req->work->title, ef->ef_req->work->author_name, sf->name);
ef->found = E->as_copy;
E->read_into_file = sf;
}
source_file *Extensions::Files::get_corresponding_source_file(extension_file *ef) {
return ef->read_into_file;
source_file *Extensions::Files::source(extension_file *ef) {
inform_extension *E = Extensions::Files::find(ef);
if (E) return E->read_into_file;
return NULL;
}
@ When headings cross-refer to extensions, they need to read extension IDs, so:
=
inbuild_work *Extensions::Files::get_work(extension_file *ef) {
return (ef)?(ef->ef_work):NULL;
return (ef)?(ef->ef_req->work):NULL;
}
@ A few problem messages need the version number loaded, so:
=
int Extensions::Files::get_version_wn(extension_file *ef) {
return ef->version_loaded;
inbuild_version_number Extensions::Files::get_version(extension_file *ef) {
inform_extension *E = Extensions::Files::find(ef);
if (E == NULL) return VersionNumbers::null();
return E->version_loaded;
}
void Extensions::Files::set_version(extension_file *ef, inbuild_version_number V) {
inform_extension *E = Extensions::Files::find(ef);
if (E == NULL) internal_error("no E found");
E->version_loaded = V;
}
@ The use option "authorial modesty" is unusual in applying to the extension
@ -281,7 +290,11 @@ the main source text:
=
int general_authorial_modesty = FALSE;
void Extensions::Files::set_authorial_modesty(extension_file *ef) { ef->authorial_modesty = TRUE; }
void Extensions::Files::set_authorial_modesty(extension_file *ef) {
inform_extension *E = Extensions::Files::find(ef);
if (E == NULL) internal_error("unfound ef");
E->authorial_modesty = TRUE;
}
void Extensions::Files::set_general_authorial_modesty(void) { general_authorial_modesty = TRUE; }
@h Printing names of extensions.
@ -342,19 +355,21 @@ check that they have been met.
void Extensions::Files::check_versions(void) {
extension_file *ef;
LOOP_OVER(ef, extension_file) {
inbuild_version_number have = Extensions::Inclusion::parse_version(ef->version_loaded),
need = Extensions::Inclusion::parse_version(ef->min_version_needed);
if (VersionNumbers::gt(need, have)) {
LOG("Need %v, have %v\n", &need, &have);
if (Model::meets(Extensions::Files::get_version(ef), ef->ef_req) == FALSE) {
inbuild_version_number have = Extensions::Files::get_version(ef);
LOG("Need %v, have %v\n", &(ef->ef_req->min_version), &have);
current_sentence = ef->inclusion_sentence;
Problems::quote_source(1, current_sentence);
Problems::quote_extension(2, ef);
if (ef->version_loaded >= 0) {
Problems::quote_wording(3, Wordings::one_word(ef->version_loaded));
if (VersionNumbers::is_null(have) == FALSE) {
TEMPORARY_TEXT(vn);
VersionNumbers::to_text(vn, have);
Problems::quote_stream(3, vn);
Problems::Issue::handmade_problem(_p_(PM_ExtVersionTooLow));
Problems::issue_problem_segment(
"You wrote %1: but my copy of %2 is only version %3.");
Problems::issue_problem_end();
DISCARD_TEXT(vn);
} else {
Problems::Issue::handmade_problem(_p_(PM_ExtNoVersion));
Problems::issue_problem_segment(
@ -398,7 +413,8 @@ void Extensions::Files::ShowExtensionVersions_routine(void) {
#ifdef IF_MODULE
if (PL::Bibliographic::story_author_is(the_author_name)) self_penned = TRUE;
#endif
if ((ef->authorial_modesty == FALSE) && /* if (1) extension doesn't ask to be modest */
inform_extension *E = Extensions::Files::find(ef);
if (((E == NULL) || (E->authorial_modesty == FALSE)) && /* if (1) extension doesn't ask to be modest */
((general_authorial_modesty == FALSE) || /* and (2) author doesn't ask to be modest, or... */
(self_penned == FALSE))) { /* ...didn't write this extension */
TEMPORARY_TEXT(C);
@ -460,11 +476,13 @@ and author. These are printed as I6 strings, hence the ISO encoding.
=
void Extensions::Files::credit_ef(OUTPUT_STREAM, extension_file *ef, int with_newline) {
WRITE("%S", ef->ef_work->raw_title);
if (ef->version_loaded >= 0)
WRITE(" version %+W", Wordings::one_word(ef->version_loaded));
WRITE(" by %S", ef->ef_work->raw_author_name);
if (Str::len(ef->extra_credit_as_lexed) > 0) WRITE(" (%S)", ef->extra_credit_as_lexed);
inform_extension *E = Extensions::Files::find(ef);
if (E == NULL) internal_error("unfound ef");
WRITE("%S", ef->ef_req->work->raw_title);
inbuild_version_number V = Extensions::Files::get_version(ef);
if (VersionNumbers::is_null(V) == FALSE) WRITE(" version %v", &V);
WRITE(" by %S", ef->ef_req->work->raw_author_name);
if (Str::len(E->extra_credit_as_lexed) > 0) WRITE(" (%S)", E->extra_credit_as_lexed);
if (with_newline) WRITE("\n");
}
@ -514,27 +532,29 @@ void Extensions::Files::index_extensions_from(OUTPUT_STREAM, extension_file *fro
HTML_OPEN_WITH("li", "class=\"leaded indent2\"");
HTML_OPEN("span");
WRITE("%+W ", ef->title_text);
Works::begin_extension_link(OUT, ef->ef_work, NULL);
Works::begin_extension_link(OUT, ef->ef_req->work, NULL);
HTML_TAG_WITH("img", "border=0 src=inform:/doc_images/help.png");
Works::end_extension_link(OUT, ef->ef_work);
Works::end_extension_link(OUT, ef->ef_req->work);
if (ef != standard_rules_extension) { /* give author and inclusion links, but not for SR */
WRITE(" by %+W", ef->author_text);
}
if (ef->version_loaded >= 0) {
if (VersionNumbers::is_null(Extensions::Files::get_version(ef)) == FALSE) {
WRITE(" ");
HTML_OPEN_WITH("span", "class=\"smaller\"");
WRITE("version %+W", Wordings::one_word(ef->version_loaded));
inbuild_version_number V = Extensions::Files::get_version(ef);
WRITE("version %v", &V);
HTML_CLOSE("span");
}
if (Str::len(ef->extra_credit_as_lexed) > 0) {
inform_extension *E = Extensions::Files::find(ef);
if ((E) && (Str::len(E->extra_credit_as_lexed) > 0)) {
WRITE(" ");
HTML_OPEN_WITH("span", "class=\"smaller\"");
WRITE("(%S)", ef->extra_credit_as_lexed);
WRITE("(%S)", E->extra_credit_as_lexed);
HTML_CLOSE("span");
}
HTML_CLOSE("span");
HTML_OPEN("span");
WRITE("%d words", TextFromFiles::total_word_count(ef->read_into_file));
WRITE("%d words", TextFromFiles::total_word_count(Extensions::Files::source(ef)));
if (from == NULL) Index::link(OUT, Wordings::first_wn(ParseTree::get_text(ef->inclusion_sentence)));
HTML_CLOSE("span");
HTML_CLOSE("li");

View file

@ -128,9 +128,10 @@ parse tree.
extension_file *requested_extension =
Extensions::Inclusion::load(AW, W, version_word, RW);
if (requested_extension->body_text_unbroken) {
Sentences::break(requested_extension->body_text, requested_extension);
requested_extension->body_text_unbroken = FALSE;
inform_extension *E = Extensions::Files::find(requested_extension);
if ((E) && (E->body_text_unbroken)) {
Sentences::break(E->body_text, requested_extension);
E->body_text_unbroken = FALSE;
}
@h Extension loading.
@ -163,11 +164,10 @@ then we need to note that the version requirement on PS has been raised to 3.
can't know at load time what we will ultimately require.)
@<This is an extension already loaded, so note any version number hike and return@> =
if (VersionNumbers::lt(
Extensions::Inclusion::parse_version(ef->min_version_needed),
Extensions::Inclusion::parse_version(version_word))) {
ef->min_version_needed = version_word;
ef->inclusion_sentence = current_sentence;
if (version_word >= 0) {
inbuild_version_number V = Extensions::Inclusion::parse_version(version_word);
if (Model::ratchet_minimum(V, ef->ef_req))
ef->inclusion_sentence = current_sentence;
}
return ef;
@ -178,17 +178,21 @@ trap-door into Read Source Text, to seek and open the file.
TEMPORARY_TEXT(synopsis);
@<Concoct a synopsis for the extension to be read@>;
feed_t id = Feeds::begin();
switch (SourceFiles::read_extension_source_text(ef, synopsis, census_mode)) {
case ORIGIN_WAS_MATERIALS_EXTENSIONS_AREA:
case ORIGIN_WAS_USER_EXTENSIONS_AREA:
ef->loaded_from_built_in_area = FALSE; break;
case ORIGIN_WAS_BUILT_IN_EXTENSIONS_AREA:
ef->loaded_from_built_in_area = TRUE; break;
default: /* which can happen if the extension file cannot be found */
ef->loaded_from_built_in_area = FALSE; break;
int origin = SourceFiles::read_extension_source_text(ef, synopsis, census_mode);
inform_extension *E = Extensions::Files::find(ef);
if (E) {
switch (origin) {
case ORIGIN_WAS_MATERIALS_EXTENSIONS_AREA:
case ORIGIN_WAS_USER_EXTENSIONS_AREA:
E->loaded_from_built_in_area = FALSE; break;
case ORIGIN_WAS_BUILT_IN_EXTENSIONS_AREA:
E->loaded_from_built_in_area = TRUE; break;
default: /* which can happen if the extension file cannot be found */
E->loaded_from_built_in_area = FALSE; break;
}
wording EXW = Feeds::end(id);
if (Wordings::nonempty(EXW)) @<Break the extension's text into body and documentation@>;
}
wording EXW = Feeds::end(id);
if (Wordings::nonempty(EXW)) @<Break the extension's text into body and documentation@>;
DISCARD_TEXT(synopsis);
@ We concoct a textual synopsis in the form
@ -222,9 +226,9 @@ present then the extension contains only body source and no documentation.
@<Break the extension's text into body and documentation@> =
<extension-body>(EXW);
ef->body_text = GET_RW(<extension-body>, 1);
if (<<r>>) ef->documentation_text = GET_RW(<extension-body>, 2);
ef->body_text_unbroken = TRUE; /* mark this to be sentence-broken */
E->body_text = GET_RW(<extension-body>, 1);
if (<<r>>) E->documentation_text = GET_RW(<extension-body>, 2);
E->body_text_unbroken = TRUE; /* mark this to be sentence-broken */
@h Parsing extension version numbers.
Extensions can have versions in the form N/DDDDDD, a format which was chosen
@ -278,7 +282,7 @@ inbuild_version_number Extensions::Inclusion::parse_version(int vwn) {
if ((p[0] == '0') || (digits == 0)) goto Malformed;
if ((slashes == 0) && (digits <= 3)) /* so that |p| points to 1 to 3 digits, not starting with |0| */
return VersionNumbers::from_pair(Wide::atoi(p), 0);
return VersionNumbers::from_major(Wide::atoi(p));
p[slash_at] = 0; /* temporarily replace the slash with a null, making |p| and |q| distinct C strings */
if (Wide::len(p) > 3) goto Malformed; /* now |p| points to 1 to 3 digits, not starting with |0| */
if (Wide::len(q) != 6) goto Malformed;
@ -355,11 +359,10 @@ void Extensions::Inclusion::check_begins_here(parse_node *PN, extension_file *ef
wording W = Wordings::new(<<t1>>, <<t2>>);
wording AW = Wordings::new(<<auth1>>, <<auth2>>);
if (Wordings::empty(AW)) return;
ef->version_loaded = <<r>>;
if (<<r>> < 0) Extensions::Files::set_version(ef, VersionNumbers::null());
else Extensions::Files::set_version(ef, Extensions::Inclusion::parse_version(<<r>>));
ef->VM_restriction_text = Wordings::new(<<rest1>>, <<rest2>>);
if (ef->version_loaded >= 0) Extensions::Inclusion::parse_version(ef->version_loaded);
if (Wordings::nonempty(ef->VM_restriction_text))
@<Check that the extension's stipulation about the virtual machine can be met@>;

View file

@ -273,7 +273,7 @@ void PL::Actions::Index::index_for_extension(OUTPUT_STREAM, source_file *sf, ext
action_name *acn;
int kc = 0;
LOOP_OVER(acn, action_name)
if (Lexer::file_of_origin(Wordings::first_wn(acn->present_name)) == ef->read_into_file)
if (Lexer::file_of_origin(Wordings::first_wn(acn->present_name)) == Extensions::Files::source(ef))
kc = Extensions::Documentation::document_headword(OUT, kc, ef, "Actions", I"action",
acn->present_name);
if (kc != 0) HTML_CLOSE("p");

View file

@ -116,7 +116,7 @@ void PL::Actions::Patterns::Named::index_for_extension(OUTPUT_STREAM, source_fil
named_action_pattern *nap;
int kc = 0;
LOOP_OVER(nap, named_action_pattern)
if (Lexer::file_of_origin(Wordings::first_wn(nap->text_of_declaration)) == ef->read_into_file)
if (Lexer::file_of_origin(Wordings::first_wn(nap->text_of_declaration)) == Extensions::Files::source(ef))
kc = Extensions::Documentation::document_headword(OUT, kc, ef, "Kinds of action", I"kind of action",
nap->text_of_declaration);
if (kc != 0) HTML_CLOSE("p");