#include <map>
#include <algorithm>
#include "boost/filesystem.hpp"
-//#include "boost/filesystem/operations.hpp"
-//#include "boost/filesystem/path.hpp"
#include "bbtkBBPInterpreter.h"
namespace bf = boost::filesystem;
+
typedef std::vector<std::vector<int> > Graph;
-typedef std::set<std::string> Dependency;
-typedef std::vector<Dependency> Dependencies;
-typedef std::vector<std::string> Boxes;
+typedef std::set<std::string> Dependencies;
+typedef std::vector<Dependencies> DependenciesVector;
+typedef std::vector<std::string> BoxesVector;
+
+std::vector<bf::path> getFileList(const std::string& path);
bool isCycle(const Graph& g);
bool checkCycle(const Graph& g, const int& i, std::vector<bool>& v);
std::string path_out(argv[3]);
// Get bbs files in path_bbs
- std::vector<bf::path> files;
-
- bf::path pth(path_bbs.c_str());
- if(bf::exists(pth) && bf::is_directory(pth))
- {
- bf::directory_iterator end_itr;
- for(bf::directory_iterator itr(pth); itr != end_itr; ++itr)
- {
- if(!is_directory(itr->status()))
- {
- std::string nm(itr->path().filename().string());
- if(nm.substr(nm.size()-4) == ".bbs")
- {
- //std::cout << itr->path().filename().string() << std::endl;
- files.push_back(itr->path());
- }
- }
- }
- }
- else
+ std::vector<bf::path> files = getFileList(path_bbs);
+ if(files.size() == 0)
{
- std::cout<< "the path to the bbs's should be a folder and not a file.";
- return 1;
+ std::cout << "No files to check." << std::endl;
+ return 0;
}
- // Order files by name
- for (int i = 0; i < (int)files.size()-1; ++i) {
- for (int j = i+1; j < (int)files.size(); ++j) {
- if(files[j].filename().string() < files[i].filename().string())
- {
- bf::path tmp = files[i];
- files[i] = files[j];
- files[j] = tmp;
- }
- }
- }
// Order files by dependencies
- // Get Dependencies and Box Names
- Dependencies ds;
- Boxes bs;
+ // Get DependenciesVector and Box Names
+ DependenciesVector deps;
+ BoxesVector boxs;
for (int i = 0; i < (int)files.size(); ++i) {
bbtk::BBPInterpreter::Pointer I = bbtk::BBPInterpreter::New();
I->InterpretFile(files[i].string());
- bs.push_back( ((bbtk::BBPInterpreter*)(I.get()))->boxName );
- ds.push_back( ((bbtk::BBPInterpreter*)(I.get()))->dependencies );
+ boxs.push_back( ((bbtk::BBPInterpreter*)(I.get()))->boxName );
+ deps.push_back( ((bbtk::BBPInterpreter*)(I.get()))->dependencies );
//print box name and dependencies
-/* std::cout << ((bbtk::BBPInterpreter*)(I.get()))->boxName << ": ";
- for(
- dep::iterator it = ((bbtk::BBPInterpreter*)(I.get()))->dependencies.begin();
- it != ((bbtk::BBPInterpreter*)(I.get()))->dependencies.end();
- it++) {
- std::cout << *it << ", ";
- }
- std::cout << std::endl;
-*/
+// std::cout << ((bbtk::BBPInterpreter*)(I.get()))->boxName << ": ";
+// for(
+// Dependencies::iterator it = ((bbtk::BBPInterpreter*)(I.get()))->dependencies.begin();
+// it != ((bbtk::BBPInterpreter*)(I.get()))->dependencies.end();
+// it++) {
+// std::cout << *it << ", ";
+// }
+// std::cout << std::endl;
+
}
+
// Only keep dependencies from package
- Dependency boxesNamesSet(bs.begin(), bs.end());
+ Dependencies boxNamesSet(boxs.begin(), boxs.end());
//std::cout << "after: " << std::endl;
- for (Dependencies::iterator it = ds.begin(); it != ds.end(); it++) {
- Boxes tmp;
- std::set_intersection(it->begin(), it->end(), boxesNamesSet.begin(), boxesNamesSet.end(),std::back_inserter(tmp));
- Dependency tmp1(tmp.begin(),tmp.end());
+ for (DependenciesVector::iterator it = deps.begin(); it != deps.end(); it++) {
+ BoxesVector tmp;
+ std::set_intersection(it->begin(), it->end(), boxNamesSet.begin(), boxNamesSet.end(),std::back_inserter(tmp));
+ Dependencies tmp1(tmp.begin(),tmp.end());
it->swap( tmp1 );
//print clean dependencies
-/* for(
- dep::iterator it1 = it->begin();
- it1 != it->end();
- it1++) {
- std::cout << *it1 << ", ";
- }
- std::cout << std::endl;
-*/
+// for(
+// Dependencies::iterator it1 = it->begin();
+// it1 != it->end();
+// it1++) {
+// std::cout << *it1 << ", ";
+// }
+// std::cout << std::endl;
+
}
- // Check there are no cycles in graph
- std::vector<std::vector<int> > g(bs.size(), std::vector<int>());
+ // Create dependencies graph
+ std::vector<std::vector<int> > g(boxs.size(), std::vector<int>());
std::map<std::string, int> idxs;
- for (int i = 0; i < (int)bs.size(); ++i)
+ for (int i = 0; i < (int)boxs.size(); ++i)
{
- idxs[bs[i]] = i;
+ idxs[boxs[i]] = i;
}
int boxit = 0;
- for (Dependencies::iterator dit = ds.begin(); dit != ds.end(); dit++, boxit++)
+ for (DependenciesVector::iterator dit = deps.begin(); dit != deps.end(); dit++, boxit++)
{
- for (Dependency::iterator ddit = dit->begin(); ddit != dit->end(); ddit++)
+ for (Dependencies::iterator ddit = dit->begin(); ddit != dit->end(); ddit++)
{
g[boxit].push_back(idxs[*ddit]);
}
}
+ // Check there are no cycles in graph
if(isCycle(g))
{
std::cout << "there are dependency cycles, please check your scripts." << std::endl;
else
{
std::cout << "no cycles, we keep going." << std::endl;
- std::vector<int> dep_priority(bs.size(), -1);
- setPriorities(g, dep_priority);
-// for (int i = 0; i < (int)dep_priority.size(); i++)
+ std::vector<int> priorities(boxs.size(), -1);
+ setPriorities(g, priorities);
+// for (int i = 0; i < (int)priorities.size(); i++)
// {
-// std::cout << dep_priority[i] << " ";
+// std::cout << priorities[i] << " ";
// }
// std::cout << std::endl;
// out << "#-----------------------------------------" << std::endl;
// }
- // for each priority level print scripts in that level.
- int m_priority = 0;
- for (int i = 0; i < (int)dep_priority.size(); i++)
- m_priority = std::max(m_priority, dep_priority[i]);
+ // find max priority level
+ int mx_priority = 0;
+ for (int i = 0; i < (int)priorities.size(); i++)
+ mx_priority = std::max(mx_priority, priorities[i]);
- for (int i = 0; i <= m_priority; i++)
+ // for each priority level print scripts in that level.
+ for (int i = 0; i <= mx_priority; i++)
{
- for (int j = 0; j < (int)dep_priority.size(); j++)
+ for (int j = 0; j < (int)priorities.size(); j++)
{
- if(dep_priority[j] == i)
+ if(priorities[j] == i)
{
out << "include " << package_name << "/boxes/" << files[j].filename().string() << std::endl;
out << "#-----------------------------------------" << std::endl;
//==========================================================================
+// dfs search to check cycles.
bool checkCycle(const Graph& g, const int& i, std::vector<bool>& v)
{
for(int dit = 0; dit < (int)g[i].size(); dit++)
{
int d = g[i][dit];
- if(d < 0 || d >= (int)g[i].size() || v[d])
+ if(d < 0 || d >= (int)g.size() || v[d])
{
//std::cout << "Checking " << i << " dependency " << dit << "=" << d << std::endl;
return true;
if(checkCycle(g,d,v))
return true;
}
+ v[i] = false;
return false;
}
}
//==========================================================================
+
+// dfs search to find dependencies
void setPriority(const Graph& g, const int i, std::vector<int>& p)
{
int pi = -1;
}
p[i]=pi+1;
}
+
+//==========================================================================
+
+std::vector<bf::path> getFileList(const std::string& path)
+{
+ std::vector<bf::path> files;
+
+ bf::path pth(path.c_str());
+ if(bf::exists(pth) && bf::is_directory(pth))
+ {
+ bf::directory_iterator end_itr;
+ for(bf::directory_iterator itr(pth); itr != end_itr; ++itr)
+ {
+ if(!is_directory(itr->status()))
+ {
+ std::string nm(itr->path().filename().string());
+ if(nm.substr(nm.size()-4) == ".bbs")
+ {
+ //std::cout << itr->path().filename().string() << std::endl;
+ files.push_back(itr->path());
+ }
+ }
+ }
+ }
+ else
+ {
+ std::cout<< "the path to the bbs's should be a folder and not a file.";
+ return files;
+ }
+
+ // Order files by name
+ for (int i = 0; i < (int)files.size()-1; ++i) {
+ for (int j = i+1; j < (int)files.size(); ++j) {
+ if(files[j].filename().string() < files[i].filename().string())
+ {
+ bf::path tmp = files[i];
+ files[i] = files[j];
+ files[j] = tmp;
+ }
+ }
+ }
+
+ return files;
+}