//---------------------------------------------------------------------------
/*
ProFile, Qt Creator project file class
Copyright (C) 2010 Richel Bilderbeek
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program.If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/CppProFile.htm
//---------------------------------------------------------------------------
#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
//---------------------------------------------------------------------------
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
//---------------------------------------------------------------------------
#include "profile.h"
//---------------------------------------------------------------------------
ProFile::ProFile(const std::string& filename)
: m_pro_filename(filename)
{
std::ifstream file(filename.c_str());
std::vector<std::string> * p = 0;
bool has_prefix_minus = false;
while (!file.eof())
{
std::string s;
file >> s;
if (s.empty()) continue;
//std::clog << "Read: '" << s << "\tState: " << has_prefix_minus << "'\n";
if (s == "CONFIG" ) { p = &m_config; continue; }
if (s == "HEADERS" ) { p = &m_headers; continue; }
if (s == "LIBS" )
{
p = &m_libs; continue;
}
if (s == "QT" ) { p = &m_qt; continue; }
if (s == "TARGET" ) { p = &m_target; continue; }
if (s == "TEMPLATE" ) { p = &m_template; continue; }
if (s == "SOURCES" ) { p = &m_sources; continue; }
//Determine prefix
if (s == "+=" || s == "-=" || s[0] == '=' || s[0] == '\\')
{
if (s[0] != '\\') has_prefix_minus = (s[0] == '-');
continue;
}
if (p)
{
p->push_back(
(has_prefix_minus ? std::string("-") : std::string()) + s);
}
}
}
//---------------------------------------------------------------------------
const std::string ProFile::GetBuildDir() const
{
return GetCurDir() + std::string("-build-desktop");
}
//---------------------------------------------------------------------------
const std::string ProFile::GetBuildDirFull() const
{
return GetCurDirFull() + std::string("-build-desktop");
}
//---------------------------------------------------------------------------
///GetCommonRoot returns the common root of all ProFile's file.
///For example:
/// ../../Classes/CppProFile/profile.cpp
/// ../../Tools/ToolZipQtProject/zipqtproject.cpp
///results in
/// /home/richel/qtsdk-2010.04/bin/Projects
const std::string ProFile::GetCommonRoot() const
{
const int max_depth = GetCommonRootDepth();
std::clog << max_depth << '\n';
//Eat away folders from path
std::string path = this->GetCurDirFull();
for (int i=0; i!=max_depth; )
{
std::clog << path << '\n';
const char c = path[path.size()-1];
path.resize(path.size() - 1);
if (c == '/') ++i;
}
return path;
}
//---------------------------------------------------------------------------
///GetCommonRootDepth returns the number of folders
///there needs to traveled up to get to the common root folder.
///For example:
/// ../../Classes/CppProFile/profile.cpp
/// ../../Tools/ToolZipQtProject/zipqtproject.cpp
///results in 2
int ProFile::GetCommonRootDepth() const
{
std::vector<std::string> v;
//Append header file filenames to v
std::copy(m_headers.begin(),m_headers.end(),std::back_inserter(v));
//Append source file filenames to v
std::copy(m_sources.begin(),m_sources.end(),std::back_inserter(v));
//More?
int max_depth = 0;
BOOST_FOREACH(const std::string& s, v)
{
const int depth = std::count(s.begin(),s.end(),'.') / 2;
if (depth > max_depth) max_depth = depth;
}
return max_depth;
}
//---------------------------------------------------------------------------
const std::string ProFile::GetCurDir() const
{
const std::string full_path = GetPath(m_pro_filename);
const unsigned int i = full_path.rfind('/');
if (i==std::string::npos) return full_path;
const std::string path
= full_path.substr(i+1,full_path.size()-(i+1));
return path;
}
//---------------------------------------------------------------------------
const std::string ProFile::GetCurDirFull() const
{
return GetPath(m_pro_filename);
}
//---------------------------------------------------------------------------
const std::vector<std::string> ProFile::GetHeadersFull() const
{
const std::string path = GetPath(GetProFilename());
std::vector<std::string> v = GetHeaders();
std::for_each(v.begin(),v.end(),
[path](std::string& s)
{
s = path + "/" + s;
}
);
return v;
}
//---------------------------------------------------------------------------
const std::string ProFile::GetPath(const std::string& f)
{
const int i = f.rfind("/",f.size());
assert(i < static_cast<int>(f.size()));
return f.substr(0,i);
}
//---------------------------------------------------------------------------
const std::vector<std::string> ProFile::GetSourcesFull() const
{
const std::string path = GetPath(GetProFilename());
std::vector<std::string> v = GetSources();
std::for_each(v.begin(),v.end(),
[path](std::string& s)
{
s = path + "/" + s;
}
);
return v;
}
//---------------------------------------------------------------------------
const std::string ProFile::GetTarget() const
{
assert(m_target.size() == 1);
return m_target[0];
}
//---------------------------------------------------------------------------
const std::string ProFile::GetVersion()
{
return "1.2";
}
//---------------------------------------------------------------------------
const std::vector<std::string> ProFile::GetVersionHistory()
{
std::vector<std::string> v;
v.push_back("YYYY-MM-DD: version X.Y: [description]");
v.push_back("2010-12-19: version 1.0: initial version");
v.push_back("2011-01-06: version 1.1: added GetCommonRoot and GetLibs methods, added operator<<");
v.push_back("2011-09-11: version 1.2: fixed bug");
return v;
}
//---------------------------------------------------------------------------
std::ostream& operator<<(std::ostream& os, const ProFile& p)
{
os << "* CONFIG flags: \n";
BOOST_FOREACH(const std::string&s, p.GetConfig())
os << s << '\n';
os << "* HEADERS: \n";
BOOST_FOREACH(const std::string&s, p.GetHeaders())
os << s << '\n';
os << "* LIBS flags: \n";
BOOST_FOREACH(const std::string&s, p.GetLibs())
os << s << '\n';
os << "* QT flags: \n";
BOOST_FOREACH(const std::string&s, p.GetQt())
os << s << '\n';
os << "* TARGET: " << p.GetTarget() << '\n';
os << "* TEMPLATE: \n";
BOOST_FOREACH(const std::string&s, p.GetTemplate())
os << s << '\n';
os << "* SOURCES: \n";
BOOST_FOREACH(const std::string&s, p.GetSources())
os << s << '\n';
os << "Project filename: " << p.GetProFilename() << '\n';
os << "Common root: " << p.GetCommonRoot();
return os;
}
//---------------------------------------------------------------------------
|