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
{
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 <msp/strings/format.h>\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);
}
}
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<Struct> &s: structs)
+ for(const unique_ptr<Struct> &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<string> parts = split(name_space, "::");
+ vector<string> parts = split(mod.name_space, "::");
parts.emplace_back(move(guard));
guard = join(parts.begin(), parts.end(), "_");
}
IO::print(out, "#include <%s>\n", h);
}
- 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<Enum> &e: enums)
+ for(const unique_ptr<Enum> &e: mod.enums)
{
out.put('\n');
e->define_type(out);
}
- for(const unique_ptr<Struct> &s: structs)
+ for(const unique_ptr<Struct> &s: mod.structs)
{
out.put('\n');
s->define_type(out);
}
- for(const unique_ptr<Struct> &s: structs)
+ for(const unique_ptr<Struct> &s: mod.structs)
{
out.put('\n');
s->define_loader(out);
}
- for(const unique_ptr<Enum> &e: enums)
+ for(const unique_ptr<Enum> &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<Struct> &s: structs)
+ for(const unique_ptr<Struct> &s: mod.structs)
{
out.put('\n');
s->define_functions(out);
}
- for(const unique_ptr<Enum> &e: enums)
+ for(const unique_ptr<Enum> &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<SetupGen>(s)
+SetupGen::Loader::Loader(SetupGen &s, Module &m):
+ ObjectLoader<SetupGen>(s),
+ mod(m)
{
static ActionMap shared_actions;
set_actions(shared_actions);
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<Enum>(move(en))));
+ type.set_enum(*mod.enums.emplace_back(make_unique<Enum>(move(en))));
}
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)
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<Struct>(move(sct))));
+ type.set_struct(*mod.structs.emplace_back(make_unique<Struct>(move(sct))));
}
#ifndef SETUPGEN_H_
#define SETUPGEN_H_
+#include <list>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <msp/core/application.h>
#include <msp/datafile/objectloader.h>
+#include <msp/fs/path.h>
#include "enum.h"
#include "struct.h"
#include "type.h"
class SetupGen: public Msp::RegisteredApplication<SetupGen>
{
private:
+ struct Module
+ {
+ std::string name_space;
+ std::vector<std::unique_ptr<Enum>> enums;
+ std::vector<std::unique_ptr<Struct>> structs;
+ };
+
class Loader: public Msp::DataFile::ObjectLoader<SetupGen>
{
+ private:
+ Module &mod;
+
public:
- Loader(SetupGen &);
+ Loader(SetupGen &, Module &);
private:
void init_actions() override;
std::string in_fn;
std::string out_fn;
- std::string name_space;
+ std::list<Module> modules;
std::map<std::string, Type> types;
std::vector<std::unique_ptr<Enum>> enums;
std::vector<std::unique_ptr<Struct>> structs;
const Type &get_type(const std::string &) const;
private:
- void load();
- void collect_headers();
- void generate_header(Msp::IO::Base &) const;
- void generate_code(Msp::IO::Base &) const;
+ void load(const Msp::FS::Path &);
+ void collect_headers(const Module &);
+ void generate_header(const Module &, Msp::IO::Base &) const;
+ void generate_code(const Module &, Msp::IO::Base &) const;
};
#endif