00001 #include "import.hh"
00002
00003 #include "plugin.hh"
00004
00005 #include "typelib/registry.hh"
00006 #include "typelib/registryiterator.hh"
00007 #include "typelib/pluginmanager.hh"
00008 #include "typelib/exporter.hh"
00009 #include "typelib/importer.hh"
00010
00011 #include "utilmm/configfile/commandline.hh"
00012 using utilmm::command_line;
00013 #include "utilmm/configfile/configset.hh"
00014 using utilmm::config_set;
00015
00016 #include "cimportplugin.hh"
00017 #include "tlbimportplugin.hh"
00018
00019 #include <algorithm>
00020 #include <iterator>
00021 #include <iostream>
00022 #include <fstream>
00023 #include <list>
00024
00025 #include <boost/filesystem/operations.hpp>
00026
00027 using namespace std;
00028 using namespace Typelib;
00029
00030 Import::Import()
00031 : Mode("import")
00032 {
00033 addPlugin( new CImportPlugin );
00034 addPlugin( new TlbImportPlugin );
00035 }
00036
00037 bool Import::apply(int argc, char* const argv[])
00038 {
00039 if (argc < 2)
00040 {
00041 help(cerr);
00042 return false;
00043 }
00044 string type = argv[0];
00045
00046 Plugin* plugin = getPlugin(type);
00047 if (! plugin)
00048 {
00049 cerr << "Cannot handle input type " << type << endl;
00050 return false;
00051 }
00052
00053 Registry registry;
00054 config_set config;
00055
00056 std::list<string> options = plugin->getOptions();
00057 options.push_back(":nspace=string,/:Namespace to import types into");
00058 options.push_back(":output=string:Output file");
00059 command_line commandline(options);
00060 try { commandline.parse(argc - 1, argv + 1, config); }
00061 catch(utilmm::commandline_error e)
00062 {
00063 cerr << "error: " << e.error << "\n";
00064 help(cerr);
00065 return false;
00066 }
00067
00068 std::string nspace = config.get<string>("nspace");
00069 if (!registry.setDefaultNamespace( nspace ))
00070 {
00071 cerr << "Invalid namespace option " << nspace << endl;
00072 return false;
00073 }
00074
00075 list<string> remaining = commandline.remaining();
00076 if (remaining.size() > 2)
00077 {
00078 cerr << "More than one file specified on command line" << endl;
00079 help(cerr);
00080 return false;
00081 }
00082
00083 string base_tlb;
00084 if (remaining.size() == 2)
00085 base_tlb = remaining.back();
00086
00087 string output_tlb = config.get<string>("output", base_tlb);
00088 if (output_tlb.empty())
00089 output_tlb = "-";
00090
00091
00092 if (! base_tlb.empty() && boost::filesystem::exists(base_tlb))
00093 {
00094 auto_ptr<Importer> read_db(PluginManager::self()->importer("tlb"));
00095 try { read_db->load(base_tlb, config, registry); }
00096 catch(ImportError e)
00097 {
00098 cerr << "error base registry " << base_tlb << ": " << e.toString() << endl;
00099 return false;
00100 }
00101 }
00102
00103 if (! plugin->apply(remaining, config, registry))
00104 return false;
00105
00106
00107
00108 std::auto_ptr<ofstream> filestream;
00109 ostream* outstream = 0;
00110 if (output_tlb == "-")
00111 outstream = &cout;
00112 else
00113 {
00114 filestream.reset( new ofstream(output_tlb.c_str()) );
00115 if (! filestream->is_open())
00116 {
00117 cerr << "cannot open " << output_tlb << " for writing" << endl;
00118 return false;
00119 }
00120 outstream = filestream.get();
00121 }
00122
00123 try
00124 {
00125 auto_ptr<Exporter> exporter(PluginManager::self()->exporter("tlb"));
00126 exporter->save(*outstream, registry);
00127 }
00128 catch(...)
00129 {
00130 cerr << "error when writing the type data base " << output_tlb << endl;
00131 return false;
00132 }
00133
00134 return true;
00135 }
00136
00137 void Import::help(std::ostream& out) const
00138 {
00139 out <<
00140 "Usage: typelib import <input-type> [options] input-file [base]\n"
00141 "\n"
00142 "Imports the input-file contents, of type <input-type>, into base (if provided)\n"
00143 "and saves it back into either base or the file specified by --output\n"
00144 "If neither base nor --output is provided, print on standard output\n"
00145 "\tSupported input types are: ";
00146
00147 list<string> plugins = getPluginNames();
00148 copy(plugins.begin(), plugins.end(), ostream_iterator<string>(out, " "));
00149 out << endl;
00150
00151 out <<
00152 "and allowed options are :\n"
00153 "\t--nspace=NAME namespace to import new types into\n"
00154 "\t--output=FILE save the resulting database in FILE instead of using base\n"
00155 "\t use --output=- to get the result on standard output" << endl;
00156 }
00157