1 #include <msp/core/getopt.h>
2 #include <msp/fs/utils.h>
3 #include <msp/io/buffered.h>
4 #include <msp/io/console.h>
5 #include <msp/io/file.h>
6 #include <msp/datafile/packsource.h>
7 #include <msp/datafile/parser.h>
8 #include <msp/datafile/statement.h>
9 #include "builtingenerator.h"
17 DataTool::DataTool(int argc, char **argv):
28 getopt.add_option('b', "binary", binary, GetOpt::NO_ARG).set_help("Produce a binary datafile");
29 getopt.add_option('c', "compile", compile, GetOpt::NO_ARG).set_help("Create a collection based on a template file");
30 getopt.add_option('f', "float-size", float_size, GetOpt::REQUIRED_ARG).set_help("Floating-point precision", "BITS");
31 getopt.add_option('g', "debug", debug, GetOpt::NO_ARG).set_help("Display control statements");
32 getopt.add_option('i', "builtin", builtin, GetOpt::NO_ARG).set_help("Generate a source file for a BuiltinSource");
33 getopt.add_option('m', "module", builtin_module, GetOpt::REQUIRED_ARG).set_help("Name of the builtin source module");
34 getopt.add_option('n', "namespace", builtin_ns, GetOpt::REQUIRED_ARG).set_help("Namespace for the builtin source");
35 getopt.add_option('o', "output", out_fn, GetOpt::REQUIRED_ARG).set_help("Output to a file instead of stdout", "FILE");
36 getopt.add_option('p', "pack", pack, GetOpt::NO_ARG).set_help("Create a pack from multiple files");
37 getopt.add_option('u', "unpack", unpack, GetOpt::NO_ARG).set_help("Unpacks files from packs into the current directory");
38 getopt.add_option('z', "compress", compress, GetOpt::NO_ARG).set_help("Produce a compressed datafile");
39 getopt.add_argument("infile", in_fns, GetOpt::OPTIONAL_ARG).set_help("Files to process");
42 if(compile+pack+unpack+builtin>1)
43 throw usage_error("Only one of -c, -p, -u and -i may be specified");
45 if(pack && out_fn=="-")
46 throw usage_error("Can't write pack to stdout");
49 in_fns.push_back("-");
53 for(list<string>::const_iterator i=in_fns.begin(); i!=in_fns.end(); ++i)
55 throw usage_error("Can't unpack from stdout");
58 if(builtin && builtin_module.empty())
61 throw usage_error("Can't determine builtin module name");
63 builtin_module = FS::basepart(FS::basename(out_fn));
76 do_generate_builtin();
83 void DataTool::do_transfer()
85 IO::Base *out = open_output(out_fn);
86 DataFile::Writer *writer = create_writer(*out);
88 for(list<string>::const_iterator i=in_fns.begin(); i!=in_fns.end(); ++i)
90 IO::Base *in = open_input(*i);
91 DataFile::Parser parser(*in, *i);
95 DataFile::Statement st = parser.parse(true);
96 if(st.valid && (!st.control || st.keyword=="__src" || debug))
107 void DataTool::do_compile()
109 IO::Base *out = open_output(out_fn);
110 DataFile::Writer *writer = create_writer(*out);
112 Compiler compiler(*writer);
113 for(list<string>::const_iterator i=in_fns.begin(); i!=in_fns.end(); ++i)
115 IO::Base *in = open_input(*i);
116 DataFile::Parser parser(*in, *i);
117 compiler.load(parser);
125 void DataTool::do_pack()
127 Packer packer(*this);
128 for(list<string>::const_iterator i=in_fns.begin(); i!=in_fns.end(); ++i)
129 packer.pack_file(*i);
130 packer.create_pack(out_fn);
133 void DataTool::do_unpack()
135 DataFile::PackSource source;
136 for(list<string>::const_iterator i=in_fns.begin(); i!=in_fns.end(); ++i)
137 source.add_pack_file(*i);
139 list<DataFile::PackSource::FileInfo> files = source.list_files();
140 for(list<DataFile::PackSource::FileInfo>::const_iterator i=files.begin(); i!=files.end(); ++i)
142 IO::Seekable *in = source.open(i->name);
143 IO::Base *out = open_output(i->name);
147 unsigned len = in->read(buf, sizeof(buf));
148 out->write(buf, len);
157 void DataTool::do_generate_builtin()
159 IO::Base *out = open_output(out_fn);
160 BuiltinGenerator generator(*out);
161 generator.begin(builtin_ns);
162 for(list<string>::const_iterator i=in_fns.begin(); i!=in_fns.end(); ++i)
163 generator.add_file(*i);
164 generator.end(builtin_module);
168 IO::Base *DataTool::open_output(const string &fn)
171 return new IO::Buffered(IO::cout);
173 return new IO::BufferedFile(fn, IO::M_WRITE);
176 IO::Base *DataTool::open_input(const string &fn)
179 return new IO::Buffered(IO::cin);
181 return new IO::BufferedFile(fn, IO::M_READ);
184 DataFile::Writer *DataTool::create_writer(IO::Base &out)
186 DataFile::Writer *writer = new DataFile::Writer(out);
188 writer->set_compressed();
190 writer->set_binary(true);
192 writer->set_float_precision(float_size);