$search
00001 #include <utilmm/system/system.hh> 00002 #include <utilmm/system/process.hh> 00003 #include <utilmm/configfile/pkgconfig.hh> 00004 #include <utilmm/configfile/exceptions.hh> 00005 #include <utilmm/stringtools.hh> 00006 00007 using namespace utilmm; 00008 using std::string; 00009 using std::list; 00010 00011 pkgconfig::pkgconfig(string const& name_) 00012 : m_name(name_) 00013 { 00014 if(!exists(name_)) 00015 throw not_found(name_); 00016 } 00017 00018 pkgconfig::~pkgconfig() {} 00019 00020 std::list<string> pkgconfig::packages() 00021 { 00022 process prs; 00023 prs << "pkg-config" << "--list-all"; 00024 string output = run(prs); 00025 // strip output 00026 string::size_type first = output.find_first_not_of(" \t\n"); 00027 if (first == string::npos) output = string(); 00028 string::size_type last = output.find_last_not_of(" \t\n"); 00029 if (last == string::npos) output = string(output, first); 00030 00031 string out = string(output, first, last - first + 1); 00032 std::list<string> lines = split(out, "\n"); 00033 // remove the package descriptions 00034 for (list<string>::iterator it = lines.begin(); it != lines.end(); ++it) 00035 { 00036 list<string> fields = split(*it, " "); 00037 *it = fields.front(); 00038 } 00039 00040 return lines; 00041 } 00042 00043 string pkgconfig::name() const { return m_name; } 00044 string pkgconfig::version() const { return run("--modversion"); } 00045 00046 bool pkgconfig::exists(string const& name) 00047 { 00048 process prs; 00049 prs << "pkg-config" << "--exists" << name; 00050 00051 try { run(prs); return true; } 00052 catch(not_found) { return false; } 00053 } 00054 00055 string pkgconfig::get(string const& varname, string const& defval) const 00056 { 00057 try { return run("--variable=" + varname); } 00058 catch(pkgconfig_error) { return defval; } // pkg-config 0.19 crashes when varname does not exist ... 00059 catch(not_found) { return defval; } 00060 } 00061 00062 static const char* const compiler_flags[] = { "--cflags", "--cflags-only-I", "--cflags-only-other" }; 00063 string pkgconfig::compiler(Modes mode) const 00064 { return run(compiler_flags[mode]); } 00065 00066 static const char* const linker_flags[] = { "--libs", "--libs-only-L", "--libs-only-other", "--static", "--libs-only-l", }; 00067 string pkgconfig::linker(Modes mode) const 00068 { return run(linker_flags[mode]); } 00069 00070 00071 00072 00073 #include <iostream> 00074 string pkgconfig::run(string const& argument) const 00075 { 00076 process prs; 00077 prs << "pkg-config" << argument << m_name; 00078 string output = run(prs); 00079 // strip output 00080 string::size_type first = output.find_first_not_of(" \t\n"); 00081 if (first == string::npos) return string(); 00082 string::size_type last = output.find_last_not_of(" \t\n"); 00083 if (last == string::npos) return string(output, first); 00084 return string(output, first, last - first + 1); 00085 } 00086 00087 string pkgconfig::run(process& prs) 00088 { 00089 int pipeno[2]; 00090 pipe(pipeno); 00091 00092 prs.redirect_to(process::Stdout, pipeno[1]); 00093 prs.redirect_to(process::Stderr, "/dev/null"); 00094 prs.start(); 00095 00096 string output; 00097 while(true) 00098 { 00099 char buffer[256]; 00100 int read_count = read(pipeno[0], buffer, 256); 00101 if (read_count == -1) 00102 throw unix_error(); 00103 if (read_count == 0) break; 00104 output += string(buffer, read_count); 00105 } 00106 prs.wait(); 00107 00108 if (!prs.exit_normal()) 00109 throw pkgconfig_error(); 00110 if (prs.exit_status()) 00111 throw not_found(prs.cmdline().front()); 00112 00113 return output; 00114 } 00115 00116