mirror of
https://github.com/ganelson/inform.git
synced 2024-06-26 04:00:43 +03:00
Improved requirements and searching
This commit is contained in:
parent
ace0230321
commit
bee49ecc3d
|
@ -18,12 +18,12 @@ this plan out.
|
|||
pathname *path_to_inbuild = NULL;
|
||||
pathname *path_to_tools = NULL;
|
||||
linked_list *nest_list = NULL;
|
||||
linked_list *find_list = NULL;
|
||||
|
||||
int inbuild_task = INSPECT_TTASK;
|
||||
int dry_run_mode = FALSE;
|
||||
linked_list *targets = NULL; /* of |inbuild_copy| */
|
||||
inbuild_nest *destination_nest = NULL;
|
||||
text_stream *filter_text = NULL;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
Foundation::start();
|
||||
|
@ -31,7 +31,6 @@ int main(int argc, char **argv) {
|
|||
InbuildModule::start();
|
||||
targets = NEW_LINKED_LIST(inbuild_copy);
|
||||
nest_list = NEW_LINKED_LIST(inbuild_nest);
|
||||
find_list = NEW_LINKED_LIST(text_stream);
|
||||
@<Read the command line@>;
|
||||
if (FIRST_IN_LINKED_LIST(inbuild_nest, nest_list) == NULL)
|
||||
Nests::add_to_search_sequence(nest_list,
|
||||
|
@ -41,26 +40,39 @@ int main(int argc, char **argv) {
|
|||
if (path_to_tools) BM = BuildSteps::methodology(path_to_tools, FALSE);
|
||||
else BM = BuildSteps::methodology(Pathnames::up(path_to_inbuild), TRUE);
|
||||
if (dry_run_mode == FALSE) BM->methodology = SHELL_METHODOLOGY;
|
||||
text_stream *T;
|
||||
LOOP_OVER_LINKED_LIST(T, text_stream, find_list) {
|
||||
linked_list *L = NEW_LINKED_LIST(inbuild_search_result);
|
||||
inbuild_work *work = Works::new(kit_genre, T, I"");
|
||||
inbuild_requirement *req = Model::requirement(work,
|
||||
VersionNumbers::null(), VersionNumbers::null());
|
||||
Nests::locate(req, nest_list, L);
|
||||
int n = 0;
|
||||
inbuild_search_result *R;
|
||||
LOOP_OVER_LINKED_LIST(R, inbuild_search_result, L) {
|
||||
Model::write_copy(STDOUT, R->copy);
|
||||
WRITE_TO(STDOUT, " (in nest %p)\n", R->nest->location);
|
||||
n++;
|
||||
if (Str::len(filter_text) > 0) {
|
||||
if (LinkedLists::len(nest_list) == 0) {
|
||||
Errors::with_text("can't apply this, since no nests have been given: '%S'", filter_text);
|
||||
} else {
|
||||
TEMPORARY_TEXT(errors);
|
||||
inbuild_requirement *req = Requirements::from_text(filter_text, errors);
|
||||
if (Str::len(errors) > 0) {
|
||||
Errors::with_text("requirement malformed: %S", errors);
|
||||
} else {
|
||||
linked_list *L = NEW_LINKED_LIST(inbuild_search_result);
|
||||
Nests::locate(req, nest_list, L);
|
||||
inbuild_search_result *R;
|
||||
LOOP_OVER_LINKED_LIST(R, inbuild_search_result, L) {
|
||||
ADD_TO_LINKED_LIST(R->copy, inbuild_copy, targets);
|
||||
}
|
||||
}
|
||||
DISCARD_TEXT(errors);
|
||||
}
|
||||
if (n == 0) WRITE_TO(STDOUT, "%S not found\n", T);
|
||||
}
|
||||
inbuild_copy *C;
|
||||
LOOP_OVER_LINKED_LIST(C, inbuild_copy, targets) {
|
||||
switch (inbuild_task) {
|
||||
case INSPECT_TTASK: Graphs::describe(STDOUT, C->graph, FALSE); break;
|
||||
case INSPECT_TTASK:
|
||||
WRITE_TO(STDOUT, "%S: ", Model::genre_name(C->edition->work->genre));
|
||||
Model::write_copy(STDOUT, C);
|
||||
if (C->location_if_path) {
|
||||
WRITE_TO(STDOUT, " at path %p", C->location_if_path);
|
||||
}
|
||||
if (C->location_if_file) {
|
||||
WRITE_TO(STDOUT, " in directory %p", Filenames::get_path_to(C->location_if_file));
|
||||
}
|
||||
WRITE_TO(STDOUT, "\n");
|
||||
break;
|
||||
case GRAPH_TTASK: Graphs::describe(STDOUT, C->graph, TRUE); break;
|
||||
case BUILD_TTASK: Graphs::build(C->graph, BM); break;
|
||||
case REBUILD_TTASK: Graphs::rebuild(C->graph, BM); break;
|
||||
|
@ -83,8 +95,8 @@ int main(int argc, char **argv) {
|
|||
@e DRY_CLSW
|
||||
@e TOOLS_CLSW
|
||||
@e CONTENTS_OF_CLSW
|
||||
@e MATCHING_CLSW
|
||||
@e NEST_CLSW
|
||||
@e FIND_CLSW
|
||||
@e COPY_TO_CLSW
|
||||
@e SYNC_TO_CLSW
|
||||
|
||||
|
@ -108,12 +120,12 @@ int main(int argc, char **argv) {
|
|||
L"make X the directory of intools executables, and exit developer mode");
|
||||
CommandLine::declare_boolean_switch(DRY_CLSW, L"dry", 1,
|
||||
L"make this a dry run (print but do not execute shell commands)");
|
||||
CommandLine::declare_boolean_switch(CONTENTS_OF_CLSW, L"contents-of", 2,
|
||||
CommandLine::declare_switch(MATCHING_CLSW, L"matching", 2,
|
||||
L"apply to all works in nest(s) matching requirement X");
|
||||
CommandLine::declare_switch(CONTENTS_OF_CLSW, L"contents-of", 2,
|
||||
L"apply to all targets in the directory X");
|
||||
CommandLine::declare_switch(NEST_CLSW, L"nest", 2,
|
||||
L"add the nest at pathname X to the search list");
|
||||
CommandLine::declare_switch(FIND_CLSW, L"find", 2,
|
||||
L"find copies in nests in the search list");
|
||||
|
||||
CommandLine::read(argc, argv, NULL, &Main::option, &Main::bareword);
|
||||
|
||||
|
@ -125,11 +137,11 @@ void Main::option(int id, int val, text_stream *arg, void *state) {
|
|||
case INSPECT_CLSW: inbuild_task = INSPECT_TTASK; break;
|
||||
case GRAPH_CLSW: inbuild_task = GRAPH_TTASK; break;
|
||||
case TOOLS_CLSW: path_to_tools = Pathnames::from_text(arg); break;
|
||||
case MATCHING_CLSW: filter_text = Str::duplicate(arg); break;
|
||||
case CONTENTS_OF_CLSW: Main::load_many(Pathnames::from_text(arg)); break;
|
||||
case DRY_CLSW: dry_run_mode = val; break;
|
||||
case NEST_CLSW: Nests::add_to_search_sequence(nest_list,
|
||||
Nests::new(Pathnames::from_text(arg))); break;
|
||||
case FIND_CLSW: ADD_TO_LINKED_LIST(Str::duplicate(arg), text_stream, find_list); break;
|
||||
case COPY_TO_CLSW: inbuild_task = COPY_TO_TTASK;
|
||||
destination_nest = Nests::new(Pathnames::from_text(arg));
|
||||
break;
|
||||
|
|
|
@ -33,6 +33,11 @@ inbuild_genre *Model::genre(text_stream *name) {
|
|||
return gen;
|
||||
}
|
||||
|
||||
text_stream *Model::genre_name(inbuild_genre *G) {
|
||||
if (G == NULL) return I"(none)";
|
||||
return G->genre_name;
|
||||
}
|
||||
|
||||
@h Editions.
|
||||
An "edition" of a work is a particular version numbered form of it. For
|
||||
example, release 7 of Bronze by Emily Short would be an edition of Bronze.
|
||||
|
@ -51,52 +56,6 @@ inbuild_edition *Model::edition(inbuild_work *work, inbuild_version_number versi
|
|||
return edition;
|
||||
}
|
||||
|
||||
@h Requirements.
|
||||
A "requirement" is when we want to get hold of a work in some edition which
|
||||
meets a range of possible versions. A null minimum version means "no minimum",
|
||||
a null maximum means "no maximum".
|
||||
|
||||
=
|
||||
typedef struct inbuild_requirement {
|
||||
struct inbuild_work *work;
|
||||
struct inbuild_version_number min_version;
|
||||
struct inbuild_version_number max_version;
|
||||
MEMORY_MANAGEMENT
|
||||
} inbuild_requirement;
|
||||
|
||||
inbuild_requirement *Model::requirement(inbuild_work *work,
|
||||
inbuild_version_number min, inbuild_version_number max) {
|
||||
inbuild_requirement *req = CREATE(inbuild_requirement);
|
||||
req->work = work;
|
||||
req->min_version = min;
|
||||
req->max_version = max;
|
||||
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,
|
||||
|
|
|
@ -67,7 +67,9 @@ void Nests::add_to_search_sequence(linked_list *search_list, inbuild_nest *N) {
|
|||
void Nests::locate(inbuild_requirement *req, linked_list *search_list, linked_list *results) {
|
||||
inbuild_nest *N;
|
||||
LOOP_OVER_LINKED_LIST(N, inbuild_nest, search_list) {
|
||||
VMETHOD_CALL(req->work->genre, GENRE_LOCATION_IN_NEST_MTID, N, req, results);
|
||||
inbuild_genre *G;
|
||||
LOOP_OVER(G, inbuild_genre)
|
||||
VMETHOD_CALL(G, GENRE_LOCATION_IN_NEST_MTID, N, req, results);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
150
inbuild/inbuild-module/Chapter 2/Requirements.w
Normal file
150
inbuild/inbuild-module/Chapter 2/Requirements.w
Normal file
|
@ -0,0 +1,150 @@
|
|||
[Requirements::] Requirements.
|
||||
|
||||
A requirement is a way to specify some subset of works: for example, those
|
||||
with a given title, and/or version number.
|
||||
|
||||
@ A null minimum version means "no minimum", a null maximum means "no maximum".
|
||||
|
||||
=
|
||||
typedef struct inbuild_requirement {
|
||||
struct inbuild_work *work;
|
||||
struct inbuild_version_number min_version;
|
||||
struct inbuild_version_number max_version;
|
||||
MEMORY_MANAGEMENT
|
||||
} inbuild_requirement;
|
||||
|
||||
inbuild_requirement *Requirements::new(inbuild_work *work,
|
||||
inbuild_version_number min, inbuild_version_number max) {
|
||||
inbuild_requirement *req = CREATE(inbuild_requirement);
|
||||
req->work = work;
|
||||
req->min_version = min;
|
||||
req->max_version = max;
|
||||
return req;
|
||||
}
|
||||
|
||||
inbuild_requirement *Requirements::any_version_of(inbuild_work *work) {
|
||||
return Requirements::new(work, VersionNumbers::null(), VersionNumbers::null());
|
||||
}
|
||||
|
||||
inbuild_requirement *Requirements::anything_of_genre(inbuild_genre *G) {
|
||||
return Requirements::any_version_of(Works::new(G, I"", I""));
|
||||
}
|
||||
|
||||
inbuild_requirement *Requirements::anything(void) {
|
||||
return Requirements::anything_of_genre(NULL);
|
||||
}
|
||||
|
||||
inbuild_requirement *Requirements::from_text(text_stream *T, text_stream *errors) {
|
||||
inbuild_requirement *req = Requirements::anything();
|
||||
int from = 0;
|
||||
for (int at = 0; at < Str::len(T); at++) {
|
||||
wchar_t c = Str::get_at(T, at);
|
||||
if (c == ',') {
|
||||
TEMPORARY_TEXT(initial);
|
||||
Str::substr(initial, Str::at(T, from), Str::at(T, at));
|
||||
Requirements::impose_clause(req, initial, errors);
|
||||
DISCARD_TEXT(initial);
|
||||
from = at + 1;
|
||||
}
|
||||
}
|
||||
if (from < Str::len(T)) {
|
||||
TEMPORARY_TEXT(final);
|
||||
Str::substr(final, Str::at(T, from), Str::end(T));
|
||||
Requirements::impose_clause(req, final, errors);
|
||||
DISCARD_TEXT(final);
|
||||
}
|
||||
return req;
|
||||
}
|
||||
|
||||
void Requirements::impose_clause(inbuild_requirement *req, text_stream *T, text_stream *errors) {
|
||||
Str::trim_white_space(T);
|
||||
if (Str::eq(T, I"all")) return;
|
||||
|
||||
TEMPORARY_TEXT(clause);
|
||||
TEMPORARY_TEXT(value);
|
||||
for (int at = 0; at < Str::len(T); at++) {
|
||||
wchar_t c = Str::get_at(T, at);
|
||||
if (c == '=') {
|
||||
Str::substr(clause, Str::start(T), Str::at(T, at));
|
||||
Str::substr(value, Str::at(T, at+1), Str::end(T));
|
||||
break;
|
||||
}
|
||||
}
|
||||
Str::trim_white_space(clause);
|
||||
Str::trim_white_space(value);
|
||||
|
||||
if ((Str::len(clause) > 0) && (Str::len(value) > 0)) {
|
||||
if (Str::eq(clause, I"title")) Str::copy(req->work->title, value);
|
||||
else if (Str::eq(clause, I"author")) Str::copy(req->work->author_name, value);
|
||||
else if (Str::eq(clause, I"version")) {
|
||||
inbuild_version_number V = VersionNumbers::from_text(value);
|
||||
if (VersionNumbers::is_null(V)) {
|
||||
if (Str::len(errors) == 0)
|
||||
WRITE_TO(errors, "not a valid version number: '%S'", value);
|
||||
}
|
||||
req->min_version = V;
|
||||
req->max_version = V;
|
||||
} else if (Str::eq(clause, I"min")) {
|
||||
inbuild_version_number V = VersionNumbers::from_text(value);
|
||||
if (VersionNumbers::is_null(V)) {
|
||||
if (Str::len(errors) == 0)
|
||||
WRITE_TO(errors, "not a valid version number: '%S'", value);
|
||||
}
|
||||
req->min_version = V;
|
||||
} else if (Str::eq(clause, I"max")) {
|
||||
inbuild_version_number V = VersionNumbers::from_text(value);
|
||||
if (VersionNumbers::is_null(V)) {
|
||||
if (Str::len(errors) == 0)
|
||||
WRITE_TO(errors, "not a valid version number: '%S'", value);
|
||||
}
|
||||
req->max_version = V;
|
||||
} else {
|
||||
if (Str::len(errors) == 0)
|
||||
WRITE_TO(errors, "no such term as '%S'", clause);
|
||||
}
|
||||
} else {
|
||||
if (Str::len(errors) == 0)
|
||||
WRITE_TO(errors, "clause not in the form 'term=value': '%S'", T);
|
||||
}
|
||||
|
||||
DISCARD_TEXT(clause);
|
||||
DISCARD_TEXT(value);
|
||||
}
|
||||
|
||||
int Requirements::meets(inbuild_edition *edition, inbuild_requirement *req) {
|
||||
if (req == NULL) return TRUE;
|
||||
if (req->work) {
|
||||
if (req->work->genre) {
|
||||
if (req->work->genre != edition->work->genre)
|
||||
return FALSE;
|
||||
}
|
||||
if (Str::len(req->work->title) > 0) {
|
||||
if (Str::ne_insensitive(req->work->title, edition->work->title))
|
||||
return FALSE;
|
||||
}
|
||||
if (Str::len(req->work->author_name) > 0) {
|
||||
if (Str::ne_insensitive(req->work->author_name, edition->work->author_name))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if (VersionNumbers::is_null(req->min_version) == FALSE) {
|
||||
if (VersionNumbers::is_null(edition->version)) return FALSE;
|
||||
if (VersionNumbers::lt(edition->version, req->min_version)) return FALSE;
|
||||
}
|
||||
if (VersionNumbers::is_null(req->max_version) == FALSE) {
|
||||
if (VersionNumbers::is_null(edition->version)) return TRUE;
|
||||
if (VersionNumbers::gt(edition->version, req->max_version)) return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int Requirements::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;
|
||||
}
|
|
@ -26,26 +26,30 @@ inbuild_copy *Extensions::claim(text_stream *arg, text_stream *ext, int director
|
|||
if (directory_status == TRUE) return NULL;
|
||||
if (Str::eq_insensitive(ext, I"i7x")) {
|
||||
filename *F = Filenames::from_text(arg);
|
||||
TEMPORARY_TEXT(author);
|
||||
TEMPORARY_TEXT(title);
|
||||
TEMPORARY_TEXT(error_text);
|
||||
TEMPORARY_TEXT(rubric_text);
|
||||
TEMPORARY_TEXT(requirement_text);
|
||||
inbuild_version_number V = Extensions::scan_file(F, title, author, rubric_text, requirement_text, error_text);
|
||||
inform_extension *E = Extensions::load_at(title, author, F);
|
||||
if (Str::len(error_text) > 0) return NULL;
|
||||
Works::add_to_database(E->as_copy->edition->work, CLAIMED_WDBC);
|
||||
E->version_loaded = V; E->as_copy->edition->version = V;
|
||||
DISCARD_TEXT(author);
|
||||
DISCARD_TEXT(title);
|
||||
DISCARD_TEXT(error_text);
|
||||
DISCARD_TEXT(rubric_text);
|
||||
DISCARD_TEXT(requirement_text);
|
||||
return E->as_copy;
|
||||
return Extensions::claim_file(F);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inbuild_copy *Extensions::claim_file(filename *F) {
|
||||
TEMPORARY_TEXT(author);
|
||||
TEMPORARY_TEXT(title);
|
||||
TEMPORARY_TEXT(error_text);
|
||||
TEMPORARY_TEXT(rubric_text);
|
||||
TEMPORARY_TEXT(requirement_text);
|
||||
inbuild_version_number V = Extensions::scan_file(F, title, author, rubric_text, requirement_text, error_text);
|
||||
inform_extension *E = Extensions::load_at(title, author, F);
|
||||
if (Str::len(error_text) > 0) return NULL;
|
||||
Works::add_to_database(E->as_copy->edition->work, CLAIMED_WDBC);
|
||||
E->version_loaded = V; E->as_copy->edition->version = V;
|
||||
DISCARD_TEXT(author);
|
||||
DISCARD_TEXT(title);
|
||||
DISCARD_TEXT(error_text);
|
||||
DISCARD_TEXT(rubric_text);
|
||||
DISCARD_TEXT(requirement_text);
|
||||
return E->as_copy;
|
||||
}
|
||||
|
||||
void Extensions::write_work(inbuild_genre *gen, OUTPUT_STREAM, inbuild_work *work) {
|
||||
WRITE("%X", work);
|
||||
}
|
||||
|
@ -200,18 +204,45 @@ this is unambiguous.
|
|||
=
|
||||
void Extensions::location_in_nest(inbuild_genre *gen, inbuild_nest *N, inbuild_requirement *req, linked_list *search_results) {
|
||||
pathname *P = Extensions::path_within_nest(N);
|
||||
for (int i7x_flag = 1; i7x_flag >= 0; i7x_flag--) {
|
||||
TEMPORARY_TEXT(leaf);
|
||||
if (i7x_flag) WRITE_TO(leaf, "%S.i7x", req->work->title);
|
||||
else WRITE_TO(leaf, "%S", req->work->title);
|
||||
filename *F = Filenames::in_folder(Pathnames::subfolder(P, req->work->author_name), leaf);
|
||||
if (TextFiles::exists(F)) {
|
||||
inform_extension *E = Extensions::load_at(req->work->title, req->work->author_name, F);
|
||||
if (Model::meets(E->version_loaded, req)) {
|
||||
Nests::add_search_result(search_results, N, E->as_copy);
|
||||
if ((Str::len(req->work->title) > 0) && (Str::len(req->work->author_name) > 0)) {
|
||||
for (int i7x_flag = 1; i7x_flag >= 0; i7x_flag--) {
|
||||
TEMPORARY_TEXT(leaf);
|
||||
if (i7x_flag) WRITE_TO(leaf, "%S.i7x", req->work->title);
|
||||
else WRITE_TO(leaf, "%S", req->work->title);
|
||||
filename *F = Filenames::in_folder(Pathnames::subfolder(P, req->work->author_name), leaf);
|
||||
if (TextFiles::exists(F)) {
|
||||
inform_extension *E = Extensions::load_at(req->work->title, req->work->author_name, F);
|
||||
if (Requirements::meets(E->as_copy->edition, req)) {
|
||||
Nests::add_search_result(search_results, N, E->as_copy);
|
||||
}
|
||||
}
|
||||
DISCARD_TEXT(leaf);
|
||||
}
|
||||
} else {
|
||||
Extensions::location_recursively(P, N, req, search_results);
|
||||
}
|
||||
}
|
||||
|
||||
void Extensions::location_recursively(pathname *P, inbuild_nest *N, inbuild_requirement *req, linked_list *search_results) {
|
||||
scan_directory *D = Directories::open(P);
|
||||
if (D) {
|
||||
TEMPORARY_TEXT(LEAFNAME);
|
||||
while (Directories::next(D, LEAFNAME)) {
|
||||
if (Str::get_last_char(LEAFNAME) == FOLDER_SEPARATOR) {
|
||||
pathname *Q = Pathnames::subfolder(P, LEAFNAME);
|
||||
Extensions::location_recursively(Q, N, req, search_results);
|
||||
} else {
|
||||
if (Str::suffix_eq(LEAFNAME, I".i7x", 4)) {
|
||||
filename *F = Filenames::in_folder(P, LEAFNAME);
|
||||
inbuild_copy *C = Extensions::claim_file(F);
|
||||
if (Requirements::meets(C->edition, req)) {
|
||||
Nests::add_search_result(search_results, N, C);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DISCARD_TEXT(leaf);
|
||||
DISCARD_TEXT(LEAFNAME);
|
||||
Directories::close(D);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,18 +28,29 @@ inbuild_copy *Kits::claim(text_stream *arg, text_stream *ext, int directory_stat
|
|||
}
|
||||
|
||||
void Kits::write_copy(inbuild_genre *gen, OUTPUT_STREAM, inbuild_work *work) {
|
||||
WRITE("Kit %S", work->title);
|
||||
WRITE("%S", work->title);
|
||||
}
|
||||
|
||||
void Kits::location_in_nest(inbuild_genre *gen, inbuild_nest *N, inbuild_requirement *req, linked_list *search_results) {
|
||||
pathname *P = Pathnames::subfolder(N->location, I"Inter");
|
||||
P = Pathnames::subfolder(P, req->work->title);
|
||||
filename *canary = Filenames::in_folder(P, I"kit_metadata.txt");
|
||||
if (TextFiles::exists(canary)) {
|
||||
inform_kit *K = Kits::load_at(Pathnames::directory_name(P), P);
|
||||
if (Model::meets(K->version, req)) {
|
||||
Nests::add_search_result(search_results, N, K->as_copy);
|
||||
scan_directory *D = Directories::open(P);
|
||||
if (D) {
|
||||
TEMPORARY_TEXT(LEAFNAME);
|
||||
while (Directories::next(D, LEAFNAME)) {
|
||||
if (Str::get_last_char(LEAFNAME) == FOLDER_SEPARATOR) {
|
||||
Str::delete_last_character(LEAFNAME);
|
||||
pathname *Q = Pathnames::subfolder(P, LEAFNAME);
|
||||
filename *canary = Filenames::in_folder(Q, I"kit_metadata.txt");
|
||||
if (TextFiles::exists(canary)) {
|
||||
inform_kit *K = Kits::load_at(Pathnames::directory_name(Q), Q);
|
||||
if (Requirements::meets(K->as_copy->edition, req)) {
|
||||
Nests::add_search_result(search_results, N, K->as_copy);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DISCARD_TEXT(LEAFNAME);
|
||||
Directories::close(D);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,6 +136,7 @@ inform_kit *Kits::load_at(text_stream *name, pathname *P) {
|
|||
NULL, FALSE, Kits::read_metadata, NULL, (void *) K);
|
||||
|
||||
inbuild_work *work = Works::new(kit_genre, name, NULL);
|
||||
work->title = Str::duplicate(name);
|
||||
inbuild_edition *edition = Model::edition(work, K->version);
|
||||
K->as_copy = Model::copy_in_directory(edition, P, STORE_POINTER_inform_kit(K));
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ Chapter 2: Conceptual Framework
|
|||
Conceptual Model
|
||||
Works
|
||||
Version Numbers
|
||||
Requirements
|
||||
Build Graphs
|
||||
Build Steps
|
||||
Nests
|
||||
|
|
|
@ -169,7 +169,7 @@ application to communicate the problem badly.
|
|||
text_stream *author_name = EF->ef_req->work->author_name;
|
||||
text_stream *title = EF->ef_req->work->title;
|
||||
inbuild_work *work = Works::new(extension_genre, title, author_name);
|
||||
inbuild_requirement *req = Model::requirement(work, VersionNumbers::null(), VersionNumbers::null());
|
||||
inbuild_requirement *req = Requirements::any_version_of(work);
|
||||
linked_list *L = NEW_LINKED_LIST(inbuild_search_result);
|
||||
Nests::locate(req, search_list, L);
|
||||
inbuild_search_result *search_result;
|
||||
|
|
|
@ -206,7 +206,7 @@ matter to the census errors system elsewhere.
|
|||
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());
|
||||
ef->ef_req = Requirements::new(work, min, VersionNumbers::null());
|
||||
if (Works::is_standard_rules(work)) standard_rules_extension = ef;
|
||||
DISCARD_TEXT(exft);
|
||||
DISCARD_TEXT(exfa);
|
||||
|
@ -271,6 +271,12 @@ inbuild_version_number Extensions::Files::get_version(extension_file *ef) {
|
|||
return E->version_loaded;
|
||||
}
|
||||
|
||||
inbuild_edition *Extensions::Files::get_edition(extension_file *ef) {
|
||||
inform_extension *E = Extensions::Files::find(ef);
|
||||
if (E == NULL) return NULL;
|
||||
return E->as_copy->edition;
|
||||
}
|
||||
|
||||
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");
|
||||
|
@ -349,7 +355,7 @@ check that they have been met.
|
|||
void Extensions::Files::check_versions(void) {
|
||||
extension_file *ef;
|
||||
LOOP_OVER(ef, extension_file) {
|
||||
if (Model::meets(Extensions::Files::get_version(ef), ef->ef_req) == FALSE) {
|
||||
if (Requirements::meets(Extensions::Files::get_edition(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;
|
||||
|
|
|
@ -166,7 +166,7 @@ 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 (version_word >= 0) {
|
||||
inbuild_version_number V = Extensions::Inclusion::parse_version(version_word);
|
||||
if (Model::ratchet_minimum(V, ef->ef_req))
|
||||
if (Requirements::ratchet_minimum(V, ef->ef_req))
|
||||
ef->inclusion_sentence = current_sentence;
|
||||
}
|
||||
return ef;
|
||||
|
|
Loading…
Reference in a new issue