Go to the documentation of this file.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
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
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; }
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
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