mirror of
https://github.com/ganelson/inform.git
synced 2024-06-26 04:00:43 +03:00
Made pipelines inbuild resources
This commit is contained in:
parent
f2378d5a07
commit
1338ef1cde
|
@ -29,6 +29,7 @@ Setting up the use of this module.
|
|||
@e inform_template_MT
|
||||
@e inform_project_MT
|
||||
@e inform_language_MT
|
||||
@e inform_pipeline_MT
|
||||
|
||||
=
|
||||
ALLOCATE_INDIVIDUALLY(inform_kit)
|
||||
|
@ -51,6 +52,7 @@ ALLOCATE_INDIVIDUALLY(extension_census)
|
|||
ALLOCATE_INDIVIDUALLY(inform_template)
|
||||
ALLOCATE_INDIVIDUALLY(inform_project)
|
||||
ALLOCATE_INDIVIDUALLY(inform_language)
|
||||
ALLOCATE_INDIVIDUALLY(inform_pipeline)
|
||||
|
||||
ALLOCATE_IN_ARRAYS(inbuild_work_database_entry, 100)
|
||||
|
||||
|
@ -68,6 +70,7 @@ void InbuildModule::start(void) {
|
|||
TemplateManager::start();
|
||||
LanguageManager::start();
|
||||
ProjectManager::start();
|
||||
PipelineManager::start();
|
||||
}
|
||||
|
||||
@
|
||||
|
|
|
@ -47,15 +47,23 @@ derived from its title and author name.
|
|||
|
||||
=
|
||||
inbuild_work *Works::new(inbuild_genre *genre, text_stream *ti, text_stream *an) {
|
||||
return Works::new_inner(genre, ti, an, TRUE);
|
||||
}
|
||||
inbuild_work *Works::new_raw(inbuild_genre *genre, text_stream *ti, text_stream *an) {
|
||||
return Works::new_inner(genre, ti, an, FALSE);
|
||||
}
|
||||
|
||||
inbuild_work *Works::new_inner(inbuild_genre *genre, text_stream *ti, text_stream *an, int norm) {
|
||||
inbuild_work *work = CREATE(inbuild_work);
|
||||
work->genre = genre;
|
||||
work->raw_author_name = Str::duplicate(an);
|
||||
work->author_name = Str::duplicate(an);
|
||||
work->raw_title = Str::duplicate(ti);
|
||||
work->title = Str::duplicate(ti);
|
||||
Works::normalise_casing(work->author_name);
|
||||
Works::normalise_casing(work->title);
|
||||
|
||||
if (norm) {
|
||||
Works::normalise_casing(work->author_name);
|
||||
Works::normalise_casing(work->title);
|
||||
}
|
||||
unsigned int hc = 0;
|
||||
LOOP_THROUGH_TEXT(pos, work->author_name)
|
||||
hc = hc*30011 + (unsigned int) Str::get(pos);
|
||||
|
|
|
@ -47,7 +47,7 @@ inbuild_copy *KitManager::new_copy(text_stream *name, pathname *P) {
|
|||
C = Dictionaries::read_value(kit_copy_cache, key);
|
||||
if (C == NULL) {
|
||||
inform_kit *K = Kits::new_ik(name, P);
|
||||
inbuild_work *work = Works::new(kit_genre, Str::duplicate(name), NULL);
|
||||
inbuild_work *work = Works::new_raw(kit_genre, Str::duplicate(name), NULL);
|
||||
inbuild_edition *edition = Model::edition(work, K->version);
|
||||
C = Model::copy_in_directory(edition, P, STORE_POINTER_inform_kit(K));
|
||||
K->as_copy = C;
|
||||
|
|
157
inbuild/inbuild-module/Chapter 3/Pipeline Manager.w
Normal file
157
inbuild/inbuild-module/Chapter 3/Pipeline Manager.w
Normal file
|
@ -0,0 +1,157 @@
|
|||
[PipelineManager::] Pipeline Manager.
|
||||
|
||||
An Inform 7 pipeline.
|
||||
|
||||
@h Genre definition.
|
||||
|
||||
= (early code)
|
||||
inbuild_genre *pipeline_genre = NULL;
|
||||
|
||||
@ =
|
||||
void PipelineManager::start(void) {
|
||||
pipeline_genre = Model::genre(I"pipeline");
|
||||
METHOD_ADD(pipeline_genre, GENRE_WRITE_WORK_MTID, PipelineManager::write_work);
|
||||
METHOD_ADD(pipeline_genre, GENRE_CLAIM_AS_COPY_MTID, PipelineManager::claim_as_copy);
|
||||
METHOD_ADD(pipeline_genre, GENRE_SEARCH_NEST_FOR_MTID, PipelineManager::search_nest_for);
|
||||
METHOD_ADD(pipeline_genre, GENRE_COPY_TO_NEST_MTID, PipelineManager::copy_to_nest);
|
||||
}
|
||||
|
||||
void PipelineManager::write_work(inbuild_genre *gen, OUTPUT_STREAM, inbuild_work *work) {
|
||||
WRITE("%S", work->title);
|
||||
}
|
||||
|
||||
@ Pipelines live in their namesake subdirectory of a nest:
|
||||
|
||||
=
|
||||
pathname *PipelineManager::path_within_nest(inbuild_nest *N) {
|
||||
if (N == NULL) internal_error("no nest");
|
||||
return Pathnames::subfolder(N->location, I"Pipelines");
|
||||
}
|
||||
|
||||
@ Pipeline copies are annotated with a structure called an |inform_pipeline|,
|
||||
which stores data about pipelines used by the Inform compiler.
|
||||
|
||||
=
|
||||
inform_pipeline *PipelineManager::from_copy(inbuild_copy *C) {
|
||||
if ((C) && (C->edition->work->genre == pipeline_genre)) {
|
||||
return RETRIEVE_POINTER_inform_pipeline(C->content);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inbuild_copy *PipelineManager::new_copy(inbuild_edition *edition, filename *F) {
|
||||
inform_pipeline *E = Pipelines::new_ip(edition->work->title, F);
|
||||
inbuild_copy *C = Model::copy_in_file(edition, F, STORE_POINTER_inform_pipeline(E));
|
||||
E->as_copy = C;
|
||||
return C;
|
||||
}
|
||||
|
||||
@h Claiming.
|
||||
Here |arg| is a textual form of a filename or pathname, such as may have been
|
||||
supplied at the command line; |ext| is a substring of it, and is its extension
|
||||
(e.g., |jpg| if |arg| is |Geraniums.jpg|), or is empty if there isn't one;
|
||||
|directory_status| is true if we know for some reason that this is a directory
|
||||
not a file, false if we know the reverse, and otherwise not applicable.
|
||||
|
||||
An pipeline, for us, simply needs to be a file with extension |interpipeline|.
|
||||
|
||||
=
|
||||
void PipelineManager::claim_as_copy(inbuild_genre *gen, inbuild_copy **C,
|
||||
text_stream *arg, text_stream *ext, int directory_status) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
inbuild_copy *PipelineManager::claim_file_as_copy(filename *F, text_stream *error_text,
|
||||
int allow_malformed) {
|
||||
if (TextFiles::exists(F) == FALSE) return NULL;
|
||||
inbuild_version_number V = VersionNumbers::null();
|
||||
TEMPORARY_TEXT(unext);
|
||||
Filenames::write_unextended_leafname(unext, F);
|
||||
inbuild_copy *C = PipelineManager::new_copy(
|
||||
Model::edition(Works::new_raw(pipeline_genre, unext, NULL), V), F);
|
||||
DISCARD_TEXT(unext);
|
||||
Works::add_to_database(C->edition->work, CLAIMED_WDBC);
|
||||
PipelineManager::build_graph(C);
|
||||
return C;
|
||||
}
|
||||
|
||||
@h Searching.
|
||||
Here we look through a nest to find all pipelines matching the supplied
|
||||
requirements.
|
||||
|
||||
=
|
||||
void PipelineManager::search_nest_for(inbuild_genre *gen, inbuild_nest *N,
|
||||
inbuild_requirement *req, linked_list *search_results) {
|
||||
if ((req->work->genre) && (req->work->genre != pipeline_genre)) return;
|
||||
pathname *P = PipelineManager::path_within_nest(N);
|
||||
scan_directory *D = Directories::open(P);
|
||||
if (D) {
|
||||
TEMPORARY_TEXT(LEAFNAME);
|
||||
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);
|
||||
if ((C) && (Requirements::meets(C->edition, req))) {
|
||||
Nests::add_search_result(search_results, N, C);
|
||||
}
|
||||
}
|
||||
}
|
||||
DISCARD_TEXT(LEAFNAME);
|
||||
Directories::close(D);
|
||||
}
|
||||
}
|
||||
|
||||
@h Copying.
|
||||
Now the task is to copy a pipeline into place in a nest. This is easy,
|
||||
since a pipeline is a single file; to sync, we just overwrite.
|
||||
|
||||
=
|
||||
filename *PipelineManager::filename_in_nest(inbuild_nest *N, text_stream *title) {
|
||||
pathname *E = PipelineManager::path_within_nest(N);
|
||||
TEMPORARY_TEXT(leaf);
|
||||
WRITE_TO(leaf, "%S.interpipeline", title);
|
||||
filename *F = Filenames::in_folder(E, leaf);
|
||||
DISCARD_TEXT(leaf);
|
||||
return F;
|
||||
}
|
||||
|
||||
void PipelineManager::copy_to_nest(inbuild_genre *gen, inbuild_copy *C, inbuild_nest *N,
|
||||
int syncing, build_methodology *meth) {
|
||||
filename *F = PipelineManager::filename_in_nest(N, C->edition->work->title);
|
||||
|
||||
if (TextFiles::exists(F)) {
|
||||
if (syncing == FALSE) { Nests::overwrite_error(N, C); return; }
|
||||
} else {
|
||||
if (meth->methodology == DRY_RUN_METHODOLOGY) {
|
||||
TEMPORARY_TEXT(command);
|
||||
WRITE_TO(command, "mkdir -p ");
|
||||
Shell::quote_path(command, Filenames::get_path_to(F));
|
||||
WRITE_TO(STDOUT, "%S\n", command);
|
||||
DISCARD_TEXT(command);
|
||||
} else {
|
||||
Pathnames::create_in_file_system(N->location);
|
||||
Pathnames::create_in_file_system(Filenames::get_path_to(F));
|
||||
}
|
||||
}
|
||||
|
||||
TEMPORARY_TEXT(command);
|
||||
WRITE_TO(command, "cp -f ");
|
||||
Shell::quote_file(command, C->location_if_file);
|
||||
Shell::quote_file(command, F);
|
||||
BuildSteps::shell(command, meth);
|
||||
DISCARD_TEXT(command);
|
||||
}
|
||||
|
||||
@h Build graph.
|
||||
The build graph for a pipeline is just a single node: you don't need to
|
||||
build a pipeline at all.
|
||||
|
||||
=
|
||||
void PipelineManager::build_graph(inbuild_copy *C) {
|
||||
Graphs::copy_vertex(C);
|
||||
}
|
18
inbuild/inbuild-module/Chapter 4/Pipeline Services.w
Normal file
18
inbuild/inbuild-module/Chapter 4/Pipeline Services.w
Normal file
|
@ -0,0 +1,18 @@
|
|||
[Pipelines::] Pipeline Services.
|
||||
|
||||
A pipeline is a list of steps to be followed by the Inter processor forming
|
||||
the back end of the Inform compiler.
|
||||
|
||||
@ =
|
||||
typedef struct inform_pipeline {
|
||||
struct inbuild_copy *as_copy;
|
||||
struct inbuild_version_number version;
|
||||
MEMORY_MANAGEMENT
|
||||
} inform_pipeline;
|
||||
|
||||
inform_pipeline *Pipelines::new_ip(text_stream *name, filename *F) {
|
||||
inform_pipeline *T = CREATE(inform_pipeline);
|
||||
T->as_copy = NULL;
|
||||
T->version = VersionNumbers::null();
|
||||
return T;
|
||||
}
|
|
@ -22,6 +22,7 @@ Chapter 3: Managing Genres of Work
|
|||
Language Manager
|
||||
Project Manager
|
||||
Template Manager
|
||||
Pipeline Manager
|
||||
|
||||
Chapter 4: Services for the Inform Compiler
|
||||
Kit Services
|
||||
|
@ -30,3 +31,4 @@ Chapter 4: Services for the Inform Compiler
|
|||
Template Services
|
||||
Project Services
|
||||
Language Services
|
||||
Pipeline Services
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
else
|
||||
set: $TCACHE = inform7/Internal/I6T/standard_rules/arch-16d.interb
|
||||
endif
|
||||
set: $PIPELINE = inform7/Tests/test.interpipeline
|
||||
set: $PIPELINE = test
|
||||
|
||||
! First, problem message cases, where we require ni to fail and with the
|
||||
! correct output.
|
||||
|
@ -199,7 +199,7 @@
|
|||
else
|
||||
set: $TCACHE = inform7/Internal/I6T/standard_rules/arch-16d.interb
|
||||
endif
|
||||
set: $PIPELINE = inform7/Tests/test_basic.interpipeline
|
||||
set: $PIPELINE = test_basic
|
||||
|
||||
! First, problem message cases, where we require ni to fail and with the
|
||||
! correct output.
|
||||
|
|
|
@ -102,6 +102,7 @@ int CoreMain::main(int argc, char *argv[]) {
|
|||
Errors::set_internal_handler(&Problems::Issue::internal_error_fn);
|
||||
story_filename_extension = I"ulx";
|
||||
inter_processing_pipeline = Str::new();
|
||||
inter_processing_file = I"compile";
|
||||
|
||||
PRINT("%B build %B has started.\n", FALSE, TRUE);
|
||||
STREAM_FLUSH(STDOUT);
|
||||
|
@ -436,33 +437,40 @@ with "Output.i6t".
|
|||
@<Ensure inter pipeline variables dictionary@>;
|
||||
Str::copy(Dictionaries::create_text(pipeline_vars, I"*in"), I"*memory");
|
||||
Str::copy(Dictionaries::create_text(pipeline_vars, I"*out"), Filenames::get_leafname(filename_of_compiled_i6_code));
|
||||
pathname *inter_subnests[NO_FS_AREAS] = { NULL, NULL, NULL };
|
||||
int s = 0;
|
||||
|
||||
linked_list *inter_paths = NEW_LINKED_LIST(pathname);
|
||||
inbuild_nest *N;
|
||||
LOOP_OVER_LINKED_LIST(N, inbuild_nest, I7_nest_list) {
|
||||
if (s >= NO_FS_AREAS) break;
|
||||
inter_subnests[s++] = KitManager::path_within_nest(N);
|
||||
}
|
||||
LOOP_OVER_LINKED_LIST(N, inbuild_nest, I7_nest_list)
|
||||
ADD_TO_LINKED_LIST(KitManager::path_within_nest(N), pathname, inter_paths);
|
||||
|
||||
codegen_pipeline *SS = NULL;
|
||||
if (inter_processing_file)
|
||||
SS = CodeGen::Pipeline::parse_from_file(Filenames::from_text(inter_processing_file), pipeline_vars);
|
||||
else if (Str::len(inter_processing_pipeline) > 0)
|
||||
if (Str::len(inter_processing_pipeline) > 0) {
|
||||
SS = CodeGen::Pipeline::parse(inter_processing_pipeline, pipeline_vars);
|
||||
else {
|
||||
for (int area=0; area<NO_FS_AREAS; area++) {
|
||||
pathname *P = inter_subnests[area];
|
||||
filename *F = Filenames::in_folder(P, I"default.interpipeline");
|
||||
if (TextFiles::exists(F)) {
|
||||
if (SS == NULL)
|
||||
Problems::Fatal::issue("The Inter pipeline description contained errors");
|
||||
} else {
|
||||
inbuild_requirement *req =
|
||||
Requirements::any_version_of(Works::new(pipeline_genre, inter_processing_file, NULL));
|
||||
linked_list *L = NEW_LINKED_LIST(inbuild_search_result);
|
||||
Nests::search_for(req, I7_nest_list, L);
|
||||
if (LinkedLists::len(L) == 0) {
|
||||
WRITE_TO(STDERR, "Sought pipeline '%S'\n", inter_processing_file);
|
||||
Problems::Fatal::issue("The Inter pipeline could not be found");
|
||||
} else {
|
||||
inbuild_search_result *R;
|
||||
LOOP_OVER_LINKED_LIST(R, inbuild_search_result, L) {
|
||||
inbuild_copy *C = R->copy;
|
||||
filename *F = C->location_if_file;
|
||||
SS = CodeGen::Pipeline::parse_from_file(F, pipeline_vars);
|
||||
if (SS == NULL)
|
||||
Problems::Fatal::filename_related("This Inter pipeline contains errors", F);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (SS == NULL)
|
||||
Problems::Fatal::issue("The Inter pipeline description contained errors");
|
||||
CodeGen::Pipeline::set_repository(SS, Emit::tree());
|
||||
CodeGen::Pipeline::run(Filenames::get_path_to(filename_of_compiled_i6_code),
|
||||
SS, NO_FS_AREAS, inter_subnests, Kits::list_of_inter_libraries());
|
||||
SS, inter_paths, Kits::list_of_inter_libraries());
|
||||
}
|
||||
LOG("Back end elapsed time: %dcs\n", ((int) (clock() - front_end)) / (CLOCKS_PER_SEC/100));
|
||||
}
|
||||
|
|
|
@ -8,22 +8,14 @@ To configure the many locations used in the host filing system.
|
|||
of where everything lives in the filing system. Very early in Inform's run,
|
||||
it works out the filenames of everything it will ever need to refer to, and
|
||||
these are stored in the following globals. Explanations are given below,
|
||||
not here. First, some "areas":
|
||||
|
||||
@d NO_FS_AREAS 3
|
||||
@d MATERIALS_FS_AREA 0 /* must match |ORIGIN_WAS_*| constants minus 1 */
|
||||
@d EXTERNAL_FS_AREA 1
|
||||
@d INTERNAL_FS_AREA 2
|
||||
|
||||
=
|
||||
char *AREA_NAME[3] = { "from .materials", "installed", "built in" };
|
||||
|
||||
@ Now for the folders:
|
||||
not here.
|
||||
|
||||
= (early code)
|
||||
linked_list *I7_nest_list = NULL;
|
||||
pathname *pathname_of_area[NO_FS_AREAS] = { NULL, NULL, NULL };
|
||||
pathname *pathname_of_website_templates[NO_FS_AREAS] = { NULL, NULL, NULL };
|
||||
|
||||
pathname *pathname_of_materials = NULL;
|
||||
pathname *pathname_of_external_folder = NULL;
|
||||
pathname *pathname_of_internal_folder = NULL;
|
||||
|
||||
pathname *pathname_of_extension_docs = NULL;
|
||||
pathname *pathname_of_extension_docs_inner = NULL;
|
||||
|
@ -83,16 +75,16 @@ void Locations::set_project(text_stream *loc) {
|
|||
}
|
||||
|
||||
void Locations::set_internal(text_stream *loc) {
|
||||
pathname_of_area[INTERNAL_FS_AREA] = Pathnames::from_text(loc);
|
||||
pathname_of_internal_folder = Pathnames::from_text(loc);
|
||||
}
|
||||
|
||||
void Locations::set_default_internal(pathname *P) {
|
||||
if (pathname_of_area[INTERNAL_FS_AREA] == NULL)
|
||||
pathname_of_area[INTERNAL_FS_AREA] = P;
|
||||
if (pathname_of_internal_folder == NULL)
|
||||
pathname_of_internal_folder = P;
|
||||
}
|
||||
|
||||
void Locations::set_external(text_stream *loc) {
|
||||
pathname_of_area[EXTERNAL_FS_AREA] = Pathnames::from_text(loc);
|
||||
pathname_of_external_folder = Pathnames::from_text(loc);
|
||||
}
|
||||
|
||||
void Locations::set_transient(text_stream *loc) {
|
||||
|
@ -132,18 +124,18 @@ int Locations::set_defaults(int census_mode) {
|
|||
if ((census_mode) && (filename_of_i7_source))
|
||||
Problems::Fatal::issue("In census mode, no source text may be supplied");
|
||||
I7_nest_list = NEW_LINKED_LIST(inbuild_nest);
|
||||
if (pathname_of_area[MATERIALS_FS_AREA]) {
|
||||
inbuild_nest *nest = Nests::new(pathname_of_area[MATERIALS_FS_AREA]);
|
||||
if (pathname_of_materials) {
|
||||
inbuild_nest *nest = Nests::new(pathname_of_materials);
|
||||
Nests::set_tag(nest, ORIGIN_WAS_MATERIALS_EXTENSIONS_AREA);
|
||||
ADD_TO_LINKED_LIST(nest, inbuild_nest, I7_nest_list);
|
||||
}
|
||||
if (pathname_of_area[EXTERNAL_FS_AREA]) {
|
||||
inbuild_nest *nest = Nests::new(pathname_of_area[EXTERNAL_FS_AREA]);
|
||||
if (pathname_of_external_folder) {
|
||||
inbuild_nest *nest = Nests::new(pathname_of_external_folder);
|
||||
Nests::set_tag(nest, ORIGIN_WAS_USER_EXTENSIONS_AREA);
|
||||
ADD_TO_LINKED_LIST(nest, inbuild_nest, I7_nest_list);
|
||||
}
|
||||
if (pathname_of_area[INTERNAL_FS_AREA]) {
|
||||
inbuild_nest *nest = Nests::new(pathname_of_area[INTERNAL_FS_AREA]);
|
||||
if (pathname_of_internal_folder) {
|
||||
inbuild_nest *nest = Nests::new(pathname_of_internal_folder);
|
||||
Nests::set_tag(nest, ORIGIN_WAS_BUILT_IN_EXTENSIONS_AREA);
|
||||
ADD_TO_LINKED_LIST(nest, inbuild_nest, I7_nest_list);
|
||||
}
|
||||
|
@ -169,13 +161,11 @@ language definitions, and website templates. The Standard Rules, for
|
|||
example, live inside the Extensions part of this.
|
||||
|
||||
@<Internal resources@> =
|
||||
if (pathname_of_area[INTERNAL_FS_AREA] == NULL)
|
||||
if (pathname_of_internal_folder == NULL)
|
||||
Problems::Fatal::issue("Did not set -internal when calling");
|
||||
|
||||
Locations::EILT_at(INTERNAL_FS_AREA, pathname_of_area[INTERNAL_FS_AREA]);
|
||||
|
||||
pathname *inter_resources =
|
||||
Pathnames::subfolder(pathname_of_area[INTERNAL_FS_AREA], I"Inter");
|
||||
Pathnames::subfolder(pathname_of_internal_folder, I"Inter");
|
||||
filename_of_default_inter_pipeline =
|
||||
Filenames::in_folder(inter_resources, I"default.interpipeline");
|
||||
|
||||
|
@ -191,14 +181,14 @@ brief specifications of phrases, extracted from the manual "Writing with
|
|||
Inform". This is used to generate the Phrasebook index.
|
||||
|
||||
@<Miscellaneous other stuff@> =
|
||||
pathname *misc = Pathnames::subfolder(pathname_of_area[INTERNAL_FS_AREA], I"Miscellany");
|
||||
pathname *misc = Pathnames::subfolder(pathname_of_internal_folder, I"Miscellany");
|
||||
|
||||
filename_of_large_default_cover_art = Filenames::in_folder(misc, I"Cover.jpg");
|
||||
filename_of_small_default_cover_art = Filenames::in_folder(misc, I"Small Cover.jpg");
|
||||
filename_of_intro_postcard = Filenames::in_folder(misc, I"Postcard.pdf");
|
||||
filename_of_intro_booklet = Filenames::in_folder(misc, I"IntroductionToIF.pdf");
|
||||
|
||||
pathname_of_HTML_models = Pathnames::subfolder(pathname_of_area[INTERNAL_FS_AREA], I"HTML");
|
||||
pathname_of_HTML_models = Pathnames::subfolder(pathname_of_internal_folder, I"HTML");
|
||||
filename_of_cblorb_report_model = Filenames::in_folder(pathname_of_HTML_models, I"CblorbModel.html");
|
||||
|
||||
filename_of_xrefs = Filenames::in_folder(pathname_of_HTML_models, I"xrefs.txt");
|
||||
|
@ -226,24 +216,24 @@ If |-transient| is not specified, it's the same folder, i.e., Inform does
|
|||
not distinguish between permanent and transient external resources.
|
||||
|
||||
@<External resources@> =
|
||||
if (pathname_of_area[EXTERNAL_FS_AREA] == NULL) {
|
||||
pathname_of_area[EXTERNAL_FS_AREA] = home_path;
|
||||
if (pathname_of_external_folder == NULL) {
|
||||
pathname_of_external_folder = home_path;
|
||||
char *subfolder_within = INFORM_FOLDER_RELATIVE_TO_HOME;
|
||||
if (subfolder_within[0]) {
|
||||
TEMPORARY_TEXT(SF);
|
||||
WRITE_TO(SF, "%s", subfolder_within);
|
||||
pathname_of_area[EXTERNAL_FS_AREA] = Pathnames::subfolder(home_path, SF);
|
||||
pathname_of_external_folder = Pathnames::subfolder(home_path, SF);
|
||||
DISCARD_TEXT(SF);
|
||||
}
|
||||
pathname_of_area[EXTERNAL_FS_AREA] =
|
||||
Pathnames::subfolder(pathname_of_area[EXTERNAL_FS_AREA], I"Inform");
|
||||
pathname_of_external_folder =
|
||||
Pathnames::subfolder(pathname_of_external_folder, I"Inform");
|
||||
}
|
||||
if (Pathnames::create_in_file_system(pathname_of_area[EXTERNAL_FS_AREA]) == 0) return FALSE;
|
||||
if (Pathnames::create_in_file_system(pathname_of_external_folder) == 0) return FALSE;
|
||||
@<Permanent external resources@>;
|
||||
|
||||
if (pathname_of_transient_external_resources == NULL)
|
||||
pathname_of_transient_external_resources =
|
||||
pathname_of_area[EXTERNAL_FS_AREA];
|
||||
pathname_of_external_folder;
|
||||
if (Pathnames::create_in_file_system(pathname_of_transient_external_resources) == 0) return FALSE;
|
||||
@<Transient external resources@>;
|
||||
|
||||
|
@ -256,9 +246,8 @@ a useful little file to add source text to everything Inform compiles,
|
|||
generally to set use options.
|
||||
|
||||
@<Permanent external resources@> =
|
||||
Locations::EILT_at(EXTERNAL_FS_AREA, pathname_of_area[EXTERNAL_FS_AREA]);
|
||||
filename_of_options =
|
||||
Filenames::in_folder(pathname_of_area[EXTERNAL_FS_AREA], I"Options.txt");
|
||||
Filenames::in_folder(pathname_of_external_folder, I"Options.txt");
|
||||
|
||||
@ The transient resources are all written by us.
|
||||
|
||||
|
@ -418,16 +407,14 @@ For the third and final time, there are EILT resources.
|
|||
Str::truncate(mf, i);
|
||||
WRITE_TO(mf, ".materials");
|
||||
}
|
||||
pathname_of_area[MATERIALS_FS_AREA] =
|
||||
pathname_of_materials =
|
||||
Pathnames::subfolder(pathname_of_project->pathname_of_parent, mf);
|
||||
DISCARD_TEXT(mf);
|
||||
if (Pathnames::create_in_file_system(pathname_of_area[MATERIALS_FS_AREA]) == 0) return FALSE;
|
||||
if (Pathnames::create_in_file_system(pathname_of_materials) == 0) return FALSE;
|
||||
} else {
|
||||
pathname_of_area[MATERIALS_FS_AREA] = Pathnames::from_text(I"inform.materials");
|
||||
pathname_of_materials = Pathnames::from_text(I"inform.materials");
|
||||
}
|
||||
|
||||
Locations::EILT_at(MATERIALS_FS_AREA, pathname_of_area[MATERIALS_FS_AREA]);
|
||||
|
||||
@<Figures and sounds@>;
|
||||
@<The Release folder@>;
|
||||
@<Existing story file@>;
|
||||
|
@ -442,15 +429,15 @@ This is also where the originals (not the released copies) of the Figures
|
|||
and Sounds, if any, live: in their own subfolders.
|
||||
|
||||
@<Figures and sounds@> =
|
||||
pathname_of_materials_figures = Pathnames::subfolder(pathname_of_area[MATERIALS_FS_AREA], I"Figures");
|
||||
pathname_of_materials_sounds = Pathnames::subfolder(pathname_of_area[MATERIALS_FS_AREA], I"Sounds");
|
||||
pathname_of_materials_figures = Pathnames::subfolder(pathname_of_materials, I"Figures");
|
||||
pathname_of_materials_sounds = Pathnames::subfolder(pathname_of_materials, I"Sounds");
|
||||
|
||||
filename_of_large_cover_art_jpeg = Filenames::in_folder(pathname_of_area[MATERIALS_FS_AREA], I"Cover.jpg");
|
||||
filename_of_large_cover_art_png = Filenames::in_folder(pathname_of_area[MATERIALS_FS_AREA], I"Cover.png");
|
||||
filename_of_small_cover_art_jpeg = Filenames::in_folder(pathname_of_area[MATERIALS_FS_AREA], I"Small Cover.jpg");
|
||||
filename_of_small_cover_art_png = Filenames::in_folder(pathname_of_area[MATERIALS_FS_AREA], I"Small Cover.png");
|
||||
filename_of_large_cover_art_jpeg = Filenames::in_folder(pathname_of_materials, I"Cover.jpg");
|
||||
filename_of_large_cover_art_png = Filenames::in_folder(pathname_of_materials, I"Cover.png");
|
||||
filename_of_small_cover_art_jpeg = Filenames::in_folder(pathname_of_materials, I"Small Cover.jpg");
|
||||
filename_of_small_cover_art_png = Filenames::in_folder(pathname_of_materials, I"Small Cover.png");
|
||||
|
||||
filename_of_epsfile = Filenames::in_folder(pathname_of_area[MATERIALS_FS_AREA], I"Inform Map.eps");
|
||||
filename_of_epsfile = Filenames::in_folder(pathname_of_materials, I"Inform Map.eps");
|
||||
|
||||
@ On a release run, Inblorb will populate the Release subfolder of Materials;
|
||||
figures and sounds will be copied into the relevant subfolders. The principle
|
||||
|
@ -458,7 +445,7 @@ is that everything in Release can always be thrown away without loss, because
|
|||
it can all be generated again.
|
||||
|
||||
@<The Release folder@> =
|
||||
pathname_of_materials_release = Pathnames::subfolder(pathname_of_area[MATERIALS_FS_AREA], I"Release");
|
||||
pathname_of_materials_release = Pathnames::subfolder(pathname_of_materials, I"Release");
|
||||
pathname_of_released_interpreter = Pathnames::subfolder(pathname_of_materials_release, I"interpreter");
|
||||
pathname_of_released_figures = Pathnames::subfolder(pathname_of_materials_release, I"Figures");
|
||||
pathname_of_released_sounds = Pathnames::subfolder(pathname_of_materials_release, I"Sounds");
|
||||
|
@ -472,19 +459,9 @@ have by default, if so.
|
|||
TEMPORARY_TEXT(leaf);
|
||||
WRITE_TO(leaf, "story.%S", story_filename_extension);
|
||||
filename_of_existing_story_file =
|
||||
Filenames::in_folder(pathname_of_area[MATERIALS_FS_AREA], leaf);
|
||||
Filenames::in_folder(pathname_of_materials, leaf);
|
||||
DISCARD_TEXT(leaf);
|
||||
|
||||
@h EILTs.
|
||||
Each of the materials folder, the internal and external areas has a suite
|
||||
of subfolders to hold I7 extensions (in an author tree: see below), I6
|
||||
template files, language definitions and website templates.
|
||||
|
||||
=
|
||||
void Locations::EILT_at(int area, pathname *P) {
|
||||
pathname_of_website_templates[area] = Pathnames::subfolder(P, I"Templates");
|
||||
}
|
||||
|
||||
@h Location of extensions.
|
||||
When Inform needs one of the EILT resources, it now has three places to look:
|
||||
the internal resources folder, the external one, and the materials folder.
|
||||
|
|
|
@ -27,7 +27,7 @@ void NaturalLanguages::scan(void) {
|
|||
}
|
||||
|
||||
@h Language of play.
|
||||
The following is the language read and typed by the player:
|
||||
The followin
|
||||
|
||||
=
|
||||
inform_language *language_of_play = NULL;
|
||||
|
@ -36,8 +36,10 @@ inform_language *language_of_index = NULL;
|
|||
|
||||
@ =
|
||||
void NaturalLanguages::default_to_English(void) {
|
||||
language_of_syntax = NaturalLanguages::English();
|
||||
language_of_index = language_of_syntax;
|
||||
inform_language *E = NaturalLanguages::English();
|
||||
NaturalLanguages::set_language_of_syntax(E);
|
||||
NaturalLanguages::set_language_of_index(E);
|
||||
NaturalLanguages::set_language_of_play(E);
|
||||
}
|
||||
|
||||
void NaturalLanguages::set_language_of_play(inform_language *L) {
|
||||
|
@ -45,12 +47,19 @@ void NaturalLanguages::set_language_of_play(inform_language *L) {
|
|||
if (L) L->kit_required = TRUE;
|
||||
}
|
||||
|
||||
void NaturalLanguages::set_language_of_index(inform_language *L) {
|
||||
language_of_index = L;
|
||||
}
|
||||
|
||||
void NaturalLanguages::set_language_of_syntax(inform_language *L) {
|
||||
language_of_syntax = L;
|
||||
English_language = L;
|
||||
}
|
||||
|
||||
inform_language *NaturalLanguages::English(void) {
|
||||
NaturalLanguages::scan();
|
||||
inform_language *L = Languages::from_name(I"english");
|
||||
if (L == NULL) internal_error("unable to find English language bundle");
|
||||
L->kit_required = TRUE;
|
||||
English_language = L;
|
||||
return L;
|
||||
}
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ but in that event the Extensions.w routines do indeed want to know this.
|
|||
source code is classified.)
|
||||
|
||||
@d ORIGIN_WAS_PRIMARY_SOURCE 0
|
||||
@d ORIGIN_WAS_MATERIALS_EXTENSIONS_AREA 1 /* must match |*_FS_AREA| numbers plus 1 */
|
||||
@d ORIGIN_WAS_MATERIALS_EXTENSIONS_AREA 1
|
||||
@d ORIGIN_WAS_USER_EXTENSIONS_AREA 2
|
||||
@d ORIGIN_WAS_BUILT_IN_EXTENSIONS_AREA 3
|
||||
|
||||
|
|
|
@ -209,7 +209,7 @@ void PL::Bibliographic::Release::handle_release_declaration_inner(parse_node *p)
|
|||
TEMPORARY_TEXT(leaf);
|
||||
WRITE_TO(leaf, "%N", Wordings::first_wn(SW));
|
||||
filename_of_existing_story_file =
|
||||
Filenames::in_folder(pathname_of_area[MATERIALS_FS_AREA], leaf);
|
||||
Filenames::in_folder(pathname_of_materials, leaf);
|
||||
DISCARD_TEXT(leaf);
|
||||
}
|
||||
existing_story_file = TRUE;
|
||||
|
@ -221,7 +221,7 @@ void PL::Bibliographic::Release::handle_release_declaration_inner(parse_node *p)
|
|||
Word::dequote(Wordings::first_wn(DW));
|
||||
TEMPORARY_TEXT(leaf);
|
||||
WRITE_TO(leaf, "%N", Wordings::first_wn(LW));
|
||||
filename *A = Filenames::in_folder(pathname_of_area[MATERIALS_FS_AREA], leaf);
|
||||
filename *A = Filenames::in_folder(pathname_of_materials, leaf);
|
||||
DISCARD_TEXT(leaf);
|
||||
PL::Bibliographic::Release::create_aux_file(A,
|
||||
pathname_of_materials_release,
|
||||
|
@ -234,7 +234,7 @@ void PL::Bibliographic::Release::handle_release_declaration_inner(parse_node *p)
|
|||
Word::dequote(Wordings::first_wn(LW));
|
||||
TEMPORARY_TEXT(leaf);
|
||||
WRITE_TO(leaf, "%N", Wordings::first_wn(LW));
|
||||
filename *A = Filenames::in_folder(pathname_of_area[MATERIALS_FS_AREA], leaf);
|
||||
filename *A = Filenames::in_folder(pathname_of_materials, leaf);
|
||||
DISCARD_TEXT(leaf);
|
||||
PL::Bibliographic::Release::create_aux_file(A,
|
||||
pathname_of_materials_release,
|
||||
|
@ -249,7 +249,7 @@ void PL::Bibliographic::Release::handle_release_declaration_inner(parse_node *p)
|
|||
Word::dequote(Wordings::first_wn(FW));
|
||||
TEMPORARY_TEXT(leaf);
|
||||
WRITE_TO(leaf, "%N", Wordings::first_wn(LW));
|
||||
filename *A = Filenames::in_folder(pathname_of_area[MATERIALS_FS_AREA], leaf);
|
||||
filename *A = Filenames::in_folder(pathname_of_materials, leaf);
|
||||
DISCARD_TEXT(leaf);
|
||||
TEMPORARY_TEXT(folder);
|
||||
WRITE_TO(folder, "%N", Wordings::first_wn(FW));
|
||||
|
@ -352,13 +352,13 @@ application sandboxing in Mac OS X in 2012 may force us to revisit this.
|
|||
}
|
||||
|
||||
@<Create the Materials folder if not already present@> =
|
||||
if (Pathnames::create_in_file_system(pathname_of_area[MATERIALS_FS_AREA]) == FALSE) {
|
||||
if (Pathnames::create_in_file_system(pathname_of_materials) == FALSE) {
|
||||
Problems::Issue::release_problem_path(_p_(Untestable),
|
||||
"In order to release the story file along with other "
|
||||
"resources, I tried to create a folder alongside this "
|
||||
"Inform project, but was unable to do so. The folder "
|
||||
"was to have been called",
|
||||
pathname_of_area[MATERIALS_FS_AREA]);
|
||||
pathname_of_materials);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -614,7 +614,7 @@ void PL::Bibliographic::Release::write_ifiction_record(OUTPUT_STREAM, zbyte *hea
|
|||
WRITE("<auxiliary>\n"); INDENT;
|
||||
WRITE("<leafname>");
|
||||
TEMPORARY_TEXT(rel);
|
||||
Filenames::to_text_relative(rel, af->name_of_original_file, pathname_of_area[MATERIALS_FS_AREA]);
|
||||
Filenames::to_text_relative(rel, af->name_of_original_file, pathname_of_materials);
|
||||
HTMLFiles::write_xml_safe_text(OUT, rel);
|
||||
DISCARD_TEXT(rel);
|
||||
WRITE("</leafname>\n");
|
||||
|
@ -1001,14 +1001,14 @@ file online.
|
|||
LOOP_OVER(af, auxiliary_file)
|
||||
if (af->from_payload == JAVASCRIPT_PAYLOAD) {
|
||||
TEMPORARY_TEXT(rel);
|
||||
Filenames::to_text_relative(rel, af->name_of_original_file, pathname_of_area[MATERIALS_FS_AREA]);
|
||||
Filenames::to_text_relative(rel, af->name_of_original_file, pathname_of_materials);
|
||||
WRITE("<script src='%S'></script>", rel);
|
||||
DISCARD_TEXT(rel);
|
||||
}
|
||||
LOOP_OVER(af, auxiliary_file)
|
||||
if (af->from_payload == CSS_PAYLOAD) {
|
||||
TEMPORARY_TEXT(rel);
|
||||
Filenames::to_text_relative(rel, af->name_of_original_file, pathname_of_area[MATERIALS_FS_AREA]);
|
||||
Filenames::to_text_relative(rel, af->name_of_original_file, pathname_of_materials);
|
||||
WRITE("<link rel='stylesheet' href='%S' type='text/css' media='all'></link>", rel);
|
||||
DISCARD_TEXT(rel);
|
||||
}
|
||||
|
@ -1029,8 +1029,9 @@ file online.
|
|||
with the earliest quoted searched first.
|
||||
|
||||
@<Tell Inblorb where to find the website templates@> =
|
||||
for (int area=0; area<NO_FS_AREAS; area++)
|
||||
WRITE("template path \"%p\"\n", pathname_of_website_templates[area]);
|
||||
inbuild_nest *N;
|
||||
LOOP_OVER_LINKED_LIST(N, inbuild_nest, I7_nest_list)
|
||||
WRITE("template path \"%p\"\n", TemplateManager::path_within_nest(N));
|
||||
|
||||
@ Inblorb reports its progress, or lack of it, with an HTML page, just as we do.
|
||||
This page however includes some hints on what the user might have chosen
|
||||
|
|
|
@ -211,7 +211,7 @@ void PL::Figures::write_picture_manifest(OUTPUT_STREAM, int include_cover,
|
|||
if (bf->figure_number > 1) {
|
||||
WRITE("<key>%d</key>\n", bf->figure_number);
|
||||
TEMPORARY_TEXT(rel);
|
||||
Filenames::to_text_relative(rel, bf->filename_of_image_file, pathname_of_area[MATERIALS_FS_AREA]);
|
||||
Filenames::to_text_relative(rel, bf->filename_of_image_file, pathname_of_materials);
|
||||
WRITE("<string>%S</string>\n", rel);
|
||||
DISCARD_TEXT(rel);
|
||||
}
|
||||
|
@ -335,7 +335,7 @@ void PL::Figures::index_all(OUTPUT_STREAM) {
|
|||
Index::link(OUT, Wordings::first_wn(bf->name));
|
||||
|
||||
TEMPORARY_TEXT(rel);
|
||||
Filenames::to_text_relative(rel, bf->filename_of_image_file, pathname_of_area[MATERIALS_FS_AREA]);
|
||||
Filenames::to_text_relative(rel, bf->filename_of_image_file, pathname_of_materials);
|
||||
HTML_TAG("br");
|
||||
WRITE("%SFilename: \"%S\" - resource number %d", line2, rel, bf->figure_number);
|
||||
DISCARD_TEXT(rel);
|
||||
|
|
|
@ -175,7 +175,7 @@ void PL::Sounds::write_sounds_manifest(OUTPUT_STREAM) {
|
|||
LOOP_OVER(bs, blorb_sound) {
|
||||
WRITE("<key>%d</key>\n", bs->sound_number);
|
||||
TEMPORARY_TEXT(rel);
|
||||
Filenames::to_text_relative(rel, bs->filename_of_sound_file, pathname_of_area[MATERIALS_FS_AREA]);
|
||||
Filenames::to_text_relative(rel, bs->filename_of_sound_file, pathname_of_materials);
|
||||
WRITE("<string>%S</string>\n", rel);
|
||||
DISCARD_TEXT(rel);
|
||||
}
|
||||
|
@ -331,7 +331,7 @@ void PL::Sounds::index_all(OUTPUT_STREAM) {
|
|||
WRITE("%+W", bs->name);
|
||||
Index::link(OUT, Wordings::first_wn(bs->name));
|
||||
TEMPORARY_TEXT(rel);
|
||||
Filenames::to_text_relative(rel, bs->filename_of_sound_file, pathname_of_area[MATERIALS_FS_AREA]);
|
||||
Filenames::to_text_relative(rel, bs->filename_of_sound_file, pathname_of_materials);
|
||||
HTML_TAG("br");
|
||||
WRITE("%SFilename: \"%S\" - resource number %d", line2, rel, bs->sound_number);
|
||||
DISCARD_TEXT(rel);
|
||||
|
|
|
@ -152,13 +152,12 @@ void Main::act(void) {
|
|||
if ((pipeline_as_file) || (pipeline_as_text)) {
|
||||
if (NUMBER_CREATED(inter_file) > 0)
|
||||
Errors::fatal("-pipeline and -pipeline-file cannot be combined with inter file parameters");
|
||||
int no_subnests = 0;
|
||||
pathname *subnests[1];
|
||||
if (template_path) { no_subnests = 1; subnests[0] = template_path; }
|
||||
linked_list *inter_paths = NEW_LINKED_LIST(pathname);
|
||||
ADD_TO_LINKED_LIST(template_path, pathname, inter_paths);
|
||||
codegen_pipeline *SS;
|
||||
if (pipeline_as_file) SS = CodeGen::Pipeline::parse_from_file(pipeline_as_file, pipeline_vars);
|
||||
else SS = CodeGen::Pipeline::parse(pipeline_as_text, pipeline_vars);
|
||||
if (SS) CodeGen::Pipeline::run(domain_path, SS, no_subnests, subnests, requirements_list);
|
||||
if (SS) CodeGen::Pipeline::run(domain_path, SS, inter_paths, requirements_list);
|
||||
else Errors::fatal("pipeline could not be parsed");
|
||||
} else if (unit_test_file) {
|
||||
UnitTests::run(unit_test_file);
|
||||
|
|
|
@ -15,8 +15,7 @@ typedef struct pipeline_step {
|
|||
struct code_generation_target *target_argument;
|
||||
struct text_stream *package_argument;
|
||||
struct filename *parsed_filename;
|
||||
struct pathname **the_PP;
|
||||
int the_N;
|
||||
struct linked_list *the_PP; /* of |pathname| */
|
||||
int to_debugging_log;
|
||||
int from_memory;
|
||||
int repository_argument;
|
||||
|
@ -43,7 +42,6 @@ pipeline_step *CodeGen::Pipeline::new_step(void) {
|
|||
void CodeGen::Pipeline::clean_step(pipeline_step *step) {
|
||||
step->parsed_filename = NULL;
|
||||
step->text_out_file = NULL;
|
||||
step->the_N = -1;
|
||||
step->to_debugging_log = FALSE;
|
||||
step->from_memory = FALSE;
|
||||
step->the_PP = NULL;
|
||||
|
@ -237,7 +235,7 @@ void CodeGen::Pipeline::set_repository(codegen_pipeline *S, inter_tree *I) {
|
|||
S->memory_repository = I;
|
||||
}
|
||||
|
||||
void CodeGen::Pipeline::run(pathname *P, codegen_pipeline *S, int N, pathname **PP,
|
||||
void CodeGen::Pipeline::run(pathname *P, codegen_pipeline *S, linked_list *PP,
|
||||
linked_list *requirements_list) {
|
||||
if (S == NULL) return;
|
||||
clock_t start = clock();
|
||||
|
@ -257,7 +255,6 @@ void CodeGen::Pipeline::run(pathname *P, codegen_pipeline *S, int N, pathname **
|
|||
CodeGen::Pipeline::lint(I);
|
||||
|
||||
CodeGen::Pipeline::clean_step(step);
|
||||
step->the_N = N;
|
||||
step->the_PP = PP;
|
||||
step->repository = I;
|
||||
step->pipeline = S;
|
||||
|
|
|
@ -14,11 +14,11 @@ int CodeGen::MergeTemplate::run_pipeline_stage(pipeline_step *step) {
|
|||
inter_bookmark IBM;
|
||||
if (main_package) IBM = Inter::Bookmarks::at_end_of_this_package(main_package);
|
||||
else IBM = Inter::Bookmarks::at_start_of_this_repository(step->repository);
|
||||
CodeGen::MergeTemplate::link(&IBM, step->step_argument, step->the_N, step->the_PP, NULL);
|
||||
CodeGen::MergeTemplate::link(&IBM, step->step_argument, step->the_PP, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CodeGen::MergeTemplate::link(inter_bookmark *IBM, text_stream *template_file, int N, pathname **PP, inter_package *owner) {
|
||||
void CodeGen::MergeTemplate::link(inter_bookmark *IBM, text_stream *template_file, linked_list *PP, inter_package *owner) {
|
||||
if (IBM == NULL) internal_error("no inter to link with");
|
||||
inter_tree *I = Inter::Bookmarks::tree(IBM);
|
||||
if (Str::eq(template_file, I"none"))
|
||||
|
@ -32,8 +32,11 @@ void CodeGen::MergeTemplate::link(inter_bookmark *IBM, text_stream *template_fil
|
|||
Inter::Bookmarks::at_end_of_this_package(template_package);
|
||||
|
||||
I6T_kit kit = TemplateReader::kit_out(&link_bookmark, &(CodeGen::MergeTemplate::receive_raw), &(CodeGen::MergeTemplate::receive_command), NULL);
|
||||
kit.no_i6t_file_areas = N;
|
||||
for (int i=0; i<N; i++) kit.i6t_files[i] = Pathnames::subfolder(PP[i], I"Sections");
|
||||
kit.no_i6t_file_areas = LinkedLists::len(PP);
|
||||
pathname *P;
|
||||
int i=0;
|
||||
LOOP_OVER_LINKED_LIST(P, pathname, PP)
|
||||
kit.i6t_files[i] = Pathnames::subfolder(P, I"Sections");
|
||||
int stage = EARLY_LINK_STAGE;
|
||||
if (Str::eq(template_file, I"none")) stage = CATCH_ALL_LINK_STAGE;
|
||||
TEMPORARY_TEXT(T);
|
||||
|
|
|
@ -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_ExtMisidentified} {PM_ExtMalformedVM} {PM_ExtInadequateVM} {PM_ExtMisidentifiedEnds}
|
||||
[x] Including extensions {PM_IncludeExtQuoted} {PM_ExtVersionMalformed} {PM_ExtMiswordedBeginsHere} {PM_ExtMalformedVM} {PM_ExtInadequateVM} {PM_ExtMisidentifiedEnds}
|
||||
|
||||
^^{extensions: using}
|
||||
^^{include (extension) by (extension author)+assert+}
|
||||
|
@ -17442,7 +17442,7 @@ Sometimes authorship is complicated. What if Mary Brown finds some Inform 6 code
|
|||
|
||||
But Mary and John deserve their credits too: see the next section for how to give them.
|
||||
|
||||
[x] A simple example extension {PM_ExtMultipleBeginsHere} {PM_ExtBeginsAfterEndsHere} {PM_ExtEndsWithoutBegins} {PM_ExtMultipleEndsHere} {PM_ExtNoBeginsHere} {PM_ExtNoEndsHere}
|
||||
[x] A simple example extension {PM_ExtMultipleBeginsHere} {PM_ExtBeginsAfterEndsHere} {PM_ExtMultipleEndsHere} {PM_ExtNoBeginsHere} {PM_ExtNoEndsHere}
|
||||
|
||||
^^{extensions: writing: example}
|
||||
^^{>VERSION}
|
||||
|
|
|
@ -490,7 +490,6 @@ integration: \
|
|||
$(SRULESINPLACE) \
|
||||
$(BINFORMINPLACE) \
|
||||
kitsintegration \
|
||||
$(INTERNAL)/Inter/default.interpipeline \
|
||||
$(DOCEXEMPLUM) \
|
||||
$(INTERNALEXEMPLUM) \
|
||||
$(IMAGESEXEMPLUM) \
|
||||
|
@ -506,7 +505,6 @@ forceintegration:
|
|||
$(call transfer-preform)
|
||||
$(call transfer-standard-rules)
|
||||
$(call transfer-kits)
|
||||
$(call transfer-inter-resources)
|
||||
$(call transfer-internal-tree)
|
||||
$(call transfer-images)
|
||||
$(call make-inapp-documentation)
|
||||
|
@ -590,19 +588,11 @@ define transfer-xefs
|
|||
cp -f inform7/Internal/HTML/xrefs.txt "$(INTERNAL)/HTML"
|
||||
endef
|
||||
|
||||
# (d) Copying the I6 template into the app
|
||||
# (d) Copying kits and pipelines into the app
|
||||
|
||||
define transfer-kits
|
||||
$(INBUILDX) -sync-to $(INTERNAL) -contents-of inform7/Internal/Inter
|
||||
endef
|
||||
|
||||
$(INTERNAL)/Inter/default.interpipeline: inform7/Internal/Inter/*.interpipeline
|
||||
$(call transfer-inter-resources)
|
||||
|
||||
define transfer-inter-resources
|
||||
mkdir -p "$(INTERNAL)/Inter"
|
||||
rm -f $(INTERNAL)/Inter/*.interpipeline
|
||||
cp -R -f inform7/Internal/Inter/*.interpipeline $(INTERNAL)/Inter
|
||||
$(INBUILDX) -sync-to $(INTERNAL) -contents-of inform7/Internal/Pipelines
|
||||
endef
|
||||
|
||||
# (e) Copying internal resources into the app
|
||||
|
|
Loading…
Reference in a new issue