$search
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