1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-05 16:44:21 +03:00
inform7/inter/Chapter 1/Main.w

179 lines
6.2 KiB
OpenEdge ABL
Raw Normal View History

2019-02-05 02:44:07 +02:00
[Main::] Main.
The top level, which decides what is to be done and then carries
this plan out.
@h Main routine.
@e TEXTUAL_CLSW
@e BINARY_CLSW
2019-07-20 14:40:27 +03:00
@e PIPELINE_CLSW
@e PIPELINE_FILE_CLSW
@e PIPELINE_VARIABLE_CLSW
2019-02-05 02:44:07 +02:00
@e DOMAIN_CLSW
@e TEMPLATE_CLSW
@e TEST_CLSW
@e ARCHITECTURE_CLSW
2019-09-17 14:55:51 +03:00
@e ASSIMILATE_CLSW
2019-02-05 02:44:07 +02:00
=
2019-09-17 14:55:51 +03:00
pathname *path_to_inter = NULL;
pathname *path_to_pipelines = NULL;
2019-07-20 14:40:27 +03:00
pathname *template_path = NULL;
2019-09-17 14:55:51 +03:00
int template_action = -1;
2019-07-20 14:40:27 +03:00
pathname *domain_path = NULL;
filename *output_textually = NULL;
filename *output_binarily = NULL;
filename *unit_test_file = NULL;
dictionary *pipeline_vars = NULL;
filename *pipeline_as_file = NULL;
text_stream *pipeline_as_text = NULL;
2019-09-17 14:55:51 +03:00
linked_list *requirements_list = NULL;
2019-07-20 14:40:27 +03:00
2019-02-05 02:44:07 +02:00
int main(int argc, char **argv) {
Foundation::start();
ArchModule::start();
2019-02-05 02:44:07 +02:00
InterModule::start();
2019-08-28 12:35:44 +03:00
BuildingModule::start();
2019-02-05 02:44:07 +02:00
CodegenModule::start();
2019-09-17 14:55:51 +03:00
path_to_inter = Pathnames::installation_path("INTER_PATH", I"inter");
path_to_pipelines = Pathnames::subfolder(path_to_inter, I"Pipelines");
requirements_list = NEW_LINKED_LIST(inter_library);
2019-09-17 14:55:51 +03:00
2019-02-05 02:44:07 +02:00
CommandLine::declare_heading(
L"[[Purpose]]\n\n"
L"usage: inter file1 file2 ... [options]\n");
CommandLine::declare_switch(TEXTUAL_CLSW, L"textual", 2,
L"write to file X in textual format");
CommandLine::declare_switch(BINARY_CLSW, L"binary", 2,
L"write to file X in binary format");
2019-07-20 14:40:27 +03:00
CommandLine::declare_switch(PIPELINE_CLSW, L"pipeline", 2,
L"specify pipeline textually");
CommandLine::declare_switch(PIPELINE_FILE_CLSW, L"pipeline-file", 2,
L"specify pipeline from file X");
CommandLine::declare_switch(PIPELINE_VARIABLE_CLSW, L"variable", 2,
L"set pipeline variable X (in form name=value)");
2019-02-05 02:44:07 +02:00
CommandLine::declare_switch(TEMPLATE_CLSW, L"template", 2,
L"specify folder holding i6t template files");
CommandLine::declare_switch(TEST_CLSW, L"test", 2,
L"perform unit tests from file X");
2019-02-05 02:44:07 +02:00
CommandLine::declare_switch(DOMAIN_CLSW, L"domain", 2,
L"specify folder to read/write inter files from/to");
CommandLine::declare_switch(ARCHITECTURE_CLSW, L"architecture", 2,
L"generate inter with architecture X");
2019-09-17 14:55:51 +03:00
CommandLine::declare_switch(ASSIMILATE_CLSW, L"assimilate", 2,
L"assimilate I6T code into inter inside template X");
2019-02-05 02:44:07 +02:00
2019-07-20 14:40:27 +03:00
pipeline_vars = CodeGen::Pipeline::basic_dictionary(I"output.i6");
2019-02-05 02:44:07 +02:00
CommandLine::read(argc, argv, NULL, &Main::respond, &Main::add_file);
2019-09-17 14:55:51 +03:00
if (template_action == ASSIMILATE_CLSW) {
inter_architecture *A = CodeGen::Architecture::current();
if (A == NULL) Errors::fatal("no -architecture given");
filename *assim = Architectures::canonical_binary(template_path, A);
filename *assim_t = Architectures::canonical_textual(template_path, A);
2019-09-17 14:55:51 +03:00
pipeline_as_file = Filenames::in_folder(path_to_pipelines, I"assimilate.interpipeline");
TEMPORARY_TEXT(fullname);
WRITE_TO(fullname, "%f", assim);
Str::copy(Dictionaries::create_text(pipeline_vars, I"*out"), fullname);
Str::clear(fullname);
WRITE_TO(fullname, "%f", assim_t);
Str::copy(Dictionaries::create_text(pipeline_vars, I"*outt"), fullname);
DISCARD_TEXT(fullname);
Str::copy(Dictionaries::create_text(pipeline_vars, I"*attach"), Pathnames::directory_name(template_path));
2019-09-17 14:55:51 +03:00
}
2019-02-05 02:44:07 +02:00
Main::act();
InterModule::end();
2019-08-28 12:35:44 +03:00
BuildingModule::end();
2019-02-05 02:44:07 +02:00
CodegenModule::end();
ArchModule::end();
2019-02-05 02:44:07 +02:00
Foundation::end();
if (Errors::have_occurred()) return 1;
return 0;
}
@ =
void Main::respond(int id, int val, text_stream *arg, void *state) {
switch (id) {
case TEXTUAL_CLSW: output_textually = Filenames::from_text(arg); break;
2019-07-20 14:40:27 +03:00
case BINARY_CLSW: output_binarily = Filenames::from_text(arg); pipeline_as_text = NULL; break;
case PIPELINE_CLSW: pipeline_as_text = Str::duplicate(arg); break;
case PIPELINE_FILE_CLSW: pipeline_as_file = Filenames::from_text(arg); break;
case PIPELINE_VARIABLE_CLSW: {
match_results mr = Regexp::create_mr();
if (Regexp::match(&mr, arg, L"(%c+)=(%c+)")) {
if (Str::get_first_char(arg) != '*') {
Errors::fatal("-variable names must begin with '*'");
} else {
Str::copy(Dictionaries::create_text(pipeline_vars, mr.exp[0]), mr.exp[1]);
}
} else {
Errors::fatal("-variable should take the form 'name=value'");
}
Regexp::dispose_of(&mr);
break;
}
case DOMAIN_CLSW: domain_path = Pathnames::from_text(arg); pipeline_as_text = NULL; break;
case TEMPLATE_CLSW: template_path = Pathnames::from_text(arg); pipeline_as_text = NULL; break;
2019-09-17 14:55:51 +03:00
case ASSIMILATE_CLSW: template_path = Pathnames::from_text(arg);
pipeline_as_text = NULL; template_action = id; break;
case TEST_CLSW: unit_test_file = Filenames::from_text(arg); break;
case ARCHITECTURE_CLSW:
2019-09-17 14:55:51 +03:00
if (CodeGen::Architecture::set(arg) == FALSE)
Errors::fatal("no such -architecture");
break;
2019-02-05 02:44:07 +02:00
}
}
@ =
typedef struct inter_file {
struct filename *inter_filename;
MEMORY_MANAGEMENT
} inter_file;
void Main::add_file(int id, text_stream *arg, void *state) {
inter_file *IF = CREATE(inter_file);
IF->inter_filename = Filenames::from_text(arg);
}
@ =
void Main::act(void) {
2019-07-20 14:40:27 +03:00
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");
2020-02-10 02:10:58 +02:00
linked_list *inter_paths = NEW_LINKED_LIST(pathname);
ADD_TO_LINKED_LIST(template_path, pathname, inter_paths);
2019-07-20 14:40:27 +03:00
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);
2020-02-10 02:10:58 +02:00
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);
2019-02-05 02:44:07 +02:00
} else {
2019-07-24 22:29:29 +03:00
inter_tree *I = Inter::Tree::new();
2019-07-20 14:40:27 +03:00
inter_file *IF;
LOOP_OVER(IF, inter_file) {
if (Inter::Binary::test_file(IF->inter_filename))
Inter::Binary::read(I, IF->inter_filename);
else
Inter::Textual::read(I, IF->inter_filename);
}
2019-02-05 02:44:07 +02:00
if (output_textually) {
text_stream C_struct; text_stream *OUT = &C_struct;
if (STREAM_OPEN_TO_FILE(OUT, output_textually, UTF8_ENC) == FALSE)
Errors::fatal_with_file("unable to open textual inter file for output: %f",
output_textually);
Inter::Textual::write(OUT, I, NULL, 1);
STREAM_CLOSE(OUT);
}
if (output_binarily) Inter::Binary::write(output_binarily, I);
}
}