X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=tools%2Fsetupgen%2Fsetupgen.cpp;h=204045fbd364a90c5da1199cdb10176e07de633e;hb=548f5db5fb32e84c4b1128ac98a79403885ddadd;hp=950667794e818082487348ca69bc16655e620710;hpb=3b551a2caabdfebaac592b5fcbbeb6cbfe2fd43f;p=libs%2Fgame.git diff --git a/tools/setupgen/setupgen.cpp b/tools/setupgen/setupgen.cpp index 9506677..204045f 100644 --- a/tools/setupgen/setupgen.cpp +++ b/tools/setupgen/setupgen.cpp @@ -1,6 +1,8 @@ #include "setupgen.h" +#include #include #include +#include #include #include #include @@ -11,23 +13,29 @@ using namespace Msp; SetupGen::SetupGen(int argc, char **argv) { + vector import_dirs; + GetOpt getopt; + getopt.add_option('I', "importdir", import_dirs, GetOpt::REQUIRED_ARG); getopt.add_option('o', "output", out_fn, GetOpt::REQUIRED_ARG); getopt.add_argument("input_file", in_fn, GetOpt::REQUIRED_ARG); getopt(argc, argv); + + import_path.insert(import_path.end(), import_dirs.begin(), import_dirs.end()); } int SetupGen::main() { create_standard_types(); - load(); + load(in_fn); - collect_headers(); + const Module &main_mod = modules.front(); + collect_headers(main_mod); if(out_fn.empty()) { - generate_header(IO::cout); - generate_code(IO::cout); + generate_header(main_mod, IO::cout); + generate_code(main_mod, IO::cout); } else { @@ -38,19 +46,19 @@ int SetupGen::main() FS::Path out_dir = FS::dirname(out_fn); out_base = FS::basepart(out_base); IO::BufferedFile header_out((out_dir/(out_base+".h")).str(), IO::M_WRITE); - generate_header(header_out); + generate_header(main_mod, header_out); IO::BufferedFile code_out((out_dir/(out_base+".cpp")).str(), IO::M_WRITE); IO::print(code_out, "#include \"%s.h\"\n", out_base); - if(!enums.empty()) + if(!main_mod.enums.empty()) IO::print(code_out, "#include \n"); - generate_code(code_out); + generate_code(main_mod, code_out); } else { IO::BufferedFile out(out_fn, IO::M_WRITE); - generate_header(out); + generate_header(main_mod, out); out.put('\n'); - generate_code(out); + generate_code(main_mod, out); } } @@ -85,30 +93,33 @@ const Type &SetupGen::get_type(const string &n) const return get_item(types, n); } -void SetupGen::load() +void SetupGen::load(const FS::Path &fn) { - IO::BufferedFile in_file(in_fn); - DataFile::Parser parser(in_file, in_fn); - Loader ldr(*this); + Module &mod = modules.emplace_back(); + IO::BufferedFile in_file(fn.str()); + DataFile::Parser parser(in_file, fn.str()); + Loader ldr(*this, mod); ldr.load(parser); } -void SetupGen::collect_headers() +void SetupGen::collect_headers(const Module &mod) { headers.insert("msp/datafile/objectloader.h"); headers.insert("msp/strings/lexicalcast.h"); - for(const unique_ptr &s: structs) + if(!mod.api_header.empty()) + headers.insert(mod.api_header); + for(const unique_ptr &s: mod.structs) for(const Struct::Field &f: s->get_fields()) if(const string &h = f.type->get_header(); !h.empty()) headers.insert(h); } -void SetupGen::generate_header(IO::Base &out) const +void SetupGen::generate_header(const Module &mod, IO::Base &out) const { string guard = toupper(FS::basepart(FS::basename(out_fn.empty() ? in_fn : out_fn)))+"_H_"; - if(!name_space.empty()) + if(!mod.name_space.empty()) { - vector parts = split(name_space, "::"); + vector parts = split(mod.name_space, "::"); parts.emplace_back(move(guard)); guard = join(parts.begin(), parts.end(), "_"); } @@ -122,63 +133,66 @@ void SetupGen::generate_header(IO::Base &out) const IO::print(out, "#include <%s>\n", h); } - if(!name_space.empty()) - IO::print(out, "\nnamespace %s {\n", name_space); + IO::print(out, "\n#define API %s\n", mod.api); - for(const unique_ptr &e: enums) + if(!mod.name_space.empty()) + IO::print(out, "\nnamespace %s {\n", mod.name_space); + + for(const unique_ptr &e: mod.enums) { out.put('\n'); e->define_type(out); } - for(const unique_ptr &s: structs) + for(const unique_ptr &s: mod.structs) { out.put('\n'); s->define_type(out); } - for(const unique_ptr &s: structs) + for(const unique_ptr &s: mod.structs) { out.put('\n'); s->define_loader(out); } - for(const unique_ptr &e: enums) + for(const unique_ptr &e: mod.enums) { out.put('\n'); e->declare_conversions(out); } - if(!name_space.empty()) - IO::print(out, "\n} // namespace %s\n", name_space); + if(!mod.name_space.empty()) + IO::print(out, "\n} // namespace %s\n", mod.name_space); IO::print(out, "\n#endif\n"); } -void SetupGen::generate_code(IO::Base &out) const +void SetupGen::generate_code(const Module &mod, IO::Base &out) const { - if(!name_space.empty()) - IO::print(out, "\nnamespace %s {\n", name_space); + if(!mod.name_space.empty()) + IO::print(out, "\nnamespace %s {\n", mod.name_space); - for(const unique_ptr &s: structs) + for(const unique_ptr &s: mod.structs) { out.put('\n'); s->define_functions(out); } - for(const unique_ptr &e: enums) + for(const unique_ptr &e: mod.enums) { out.put('\n'); e->define_conversions(out); } - if(!name_space.empty()) - IO::print(out, "\n} // namespace %s\n", name_space); + if(!mod.name_space.empty()) + IO::print(out, "\n} // namespace %s\n", mod.name_space); } -SetupGen::Loader::Loader(SetupGen &s): - ObjectLoader(s) +SetupGen::Loader::Loader(SetupGen &s, Module &m): + ObjectLoader(s), + mod(m) { static ActionMap shared_actions; set_actions(shared_actions); @@ -186,23 +200,52 @@ SetupGen::Loader::Loader(SetupGen &s): void SetupGen::Loader::init_actions() { + add("api", &Loader::api); + add("api", &Loader::api_with_header); add("component", &Loader::struct_def, Struct::COMPONENT); add("entity", &Loader::struct_def, Struct::ENTITY); add("enum", &Loader::enum_def); + add("import", &Loader::import); add("namespace", &Loader::name_space); } +void SetupGen::Loader::api(const string &a) +{ + api_with_header(a, string()); +} + +void SetupGen::Loader::api_with_header(const string &a, const string &h) +{ + mod.api = a; + mod.api_header = h; +} + void SetupGen::Loader::enum_def(const DataFile::Symbol &n) { Enum en(n.name); load_sub(en); Type &type = obj.add_type(n.name, Type::ENUM); - type.set_enum(*obj.enums.emplace_back(make_unique(move(en)))); + type.set_cpp_type(join(mod.name_space, "::", type.get_cpp_type())); + type.set_enum(*mod.enums.emplace_back(make_unique(move(en)))); +} + +void SetupGen::Loader::import(const string &n) +{ + string fn = n+".mgs"; + FS::Path full_path; + if(!ranges::any_of(obj.import_path, [&full_path, &fn](const FS::Path &p){ + full_path = p/fn; + return FS::exists(full_path); + })) + throw IO::file_not_found(fn); + + obj.load(full_path); + obj.headers.insert(n+".h"); } void SetupGen::Loader::name_space(const string &ns) { - obj.name_space = ns; + mod.name_space = ns; } void SetupGen::Loader::struct_def(Struct::Kind kind, const DataFile::Symbol &n) @@ -210,5 +253,6 @@ void SetupGen::Loader::struct_def(Struct::Kind kind, const DataFile::Symbol &n) Struct sct(n.name+"Setup", kind); load_sub(sct, obj); Type &type = obj.add_type(n.name, Type::STRUCT); - type.set_struct(*obj.structs.emplace_back(make_unique(move(sct)))); + type.set_cpp_type(join(mod.name_space, "::", type.get_cpp_type())); + type.set_struct(*mod.structs.emplace_back(make_unique(move(sct)))); }