import.cc
Go to the documentation of this file.
00001 #include <typelib/registry.hh>
00002 
00003 #include <CPPLexer.hpp>
00004 #include "typesolver.hh"
00005 #include "import.hh"
00006 
00007 #include <fstream>
00008 #include <iostream>
00009 #include <utilmm/stringtools.hh>
00010 
00011 #include <utilmm/configfile/configset.hh>
00012 #include <utilmm/system/process.hh>
00013 #include <utilmm/system/system.hh>
00014 
00015 #include <boost/filesystem.hpp>
00016 
00017 #include "standard_types.hh"
00018 
00019 using namespace std;
00020 using namespace antlr;
00021 using namespace Typelib;
00022 
00023 using boost::filesystem::path;
00024 
00025 namespace 
00026 {
00027     using namespace std;
00028     using namespace utilmm;
00029     using namespace boost::filesystem;
00030 
00031     path runcpp(path const& file, config_set const& config)
00032     {
00033         utilmm::process cpp;
00034 
00035         try { 
00036             tempfile tmpfile("typelib_cimport");
00037             path tmp_path = tmpfile.path();
00038             FILE* handle = tmpfile.handle();
00039 
00040             bool debug = config.get<bool>("debug");
00041 
00042             if (debug)
00043             {
00044                 std::clog << "cpp output goes to " << tmp_path.native_file_string() << std::endl;
00045                 tmpfile.detach();
00046             }
00047 
00048             cpp.push("cpp");
00049             cpp.push(file.native_file_string());
00050 
00051             // Build the command line for cpp
00052             typedef list<string> strlist;
00053             list<string> defines  = config.get< list<string> >("define");
00054             list<string> includes = config.get< list<string> >("include");
00055             list<string> rawflags = config.get< list<string> >("rawflags");
00056             { // for backward compatibility
00057                 list<string> rawflag = config.get< list<string> >("rawflag");
00058                 rawflags.splice(rawflags.end(), rawflag);
00059             }
00060 
00061             for (strlist::const_iterator it = defines.begin(); it != defines.end(); ++it)
00062                 cpp.push("-D" + *it);
00063             for (strlist::const_iterator it = includes.begin(); it != includes.end(); ++it)
00064                 cpp.push("-I" + *it);
00065             for (strlist::const_iterator it = rawflags.begin(); it != rawflags.end(); ++it)
00066                 cpp.push(*it);
00067 
00068             if (debug)
00069             {
00070                 std::clog << "will run the following command: \n"
00071                     << "  " << utilmm::join(cpp.cmdline(), " ") << std::endl;
00072             }
00073 
00074 
00075             cpp.redirect_to(process::Stdout, handle, false);
00076             cpp.start();
00077             cpp.wait();
00078             if (cpp.exit_normal() && !cpp.exit_status())
00079             {
00080                 if (!debug)
00081                     tmpfile.detach();
00082                 return tmp_path;
00083             }
00084             
00085             return path();
00086         }
00087         catch(utilmm::unix_error) { return path(); }
00088     }
00089 }
00090 
00091 void CImport::load
00092     ( std::istream& stream
00093     , utilmm::config_set const& config
00094     , Registry& registry )
00095 {
00096     try {
00097         CPPLexer cpp_lexer(stream);
00098 
00099         Typelib::CXX::addStandardTypes(registry);
00100 
00101         TypeSolver reader(cpp_lexer, registry, config.get<bool>("cxx", true));
00102         reader.setupOpaqueHandling(config.get<bool>("opaques_forced_alignment", true),
00103                 config.get<bool>("opaques_ignore", false));
00104 
00105         list<config_set const*> opaque_defs = config.children("opaques");
00106         for (list<config_set const*>::const_iterator it = opaque_defs.begin(); it != opaque_defs.end(); ++it)
00107         {
00108             reader.defineOpaqueAlignment((*it)->get<string>("name"),
00109                     (*it)->get<size_t>("alignment"));
00110         }
00111 
00112         reader.init();
00113         reader.translation_unit();
00114     }
00115     catch (ANTLRException const& e) 
00116     { throw ImportError("", "syntax error: " + e.toString()); }
00117 }
00118     
00119 
00120 void CImport::load
00121     ( std::string const& file
00122     , utilmm::config_set const& config
00123     , Registry& registry)
00124 {
00125     path temp;
00126     try
00127     {
00128         temp = runcpp(utilmm::clean_path(file), config);
00129         if (temp.empty())
00130             throw ImportError("", "error running the preprocessor");
00131 
00132         // Check that the input file can be opened
00133         ifstream s(temp.native_file_string().c_str());
00134         if (!s)
00135             throw ImportError("", "cannot open for reading");
00136 
00137         load(s, config, registry);
00138         remove(temp);
00139     }
00140     catch(...) 
00141     { 
00142         if (! temp.empty())
00143             remove(temp); 
00144         throw;
00145     }
00146 }
00147 


typelib
Author(s): Sylvain Joyeux/sylvain.joyeux@m4x.org
autogenerated on Thu Jan 2 2014 11:38:41