2 # ---------------------------------------------------------------------
4 # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
6 # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
7 # Previous Authors : Laurent Guigues, Jean-Pierre Roux
8 # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
10 # This software is governed by the CeCILL-B license under French law and
11 # abiding by the rules of distribution of free software. You can use,
12 # modify and/ or redistribute the software under the terms of the CeCILL-B
13 # license as circulated by CEA, CNRS and INRIA at the following URL
14 # http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
15 # or in the file LICENSE.txt.
17 # As a counterpart to the access to the source code and rights to copy,
18 # modify and redistribute granted by the license, users are provided only
19 # with a limited warranty and the software's author, the holder of the
20 # economic rights, and the successive licensors have only limited
23 # The fact that you are presently reading this means that you have had
24 # knowledge of the CeCILL-B license and that you accept its terms.
25 # ------------------------------------------------------------------------ */
34 #include "boost/filesystem.hpp"
35 //#include "boost/filesystem/operations.hpp"
36 //#include "boost/filesystem/path.hpp"
37 #include "bbtkBBPInterpreter.h"
39 namespace bf = boost::filesystem;
40 typedef std::vector<std::vector<int> > Graph;
42 typedef std::set<std::string> Dependency;
43 typedef std::vector<Dependency> Dependencies;
44 typedef std::vector<std::string> Boxes;
46 bool isCycle(const Graph& g);
47 bool checkCycle(const Graph& g, const int& i, std::vector<bool>& v);
49 void setPriorities(const Graph& g, std::vector<int>& p);
50 void setPriority(const Graph& g, const int i, std::vector<int>& p);
52 int main(int argc, char **argv)
57 std::cout << "usage : bbConfigurator <path_to_bbs> <package_name> <output_path>" << std::endl;
61 std::string path_bbs(argv[1]);
62 std::string package_name(argv[2]);
63 std::string path_out(argv[3]);
65 // Get bbs files in path_bbs
66 std::vector<bf::path> files;
68 bf::path pth(path_bbs.c_str());
69 if(bf::exists(pth) && bf::is_directory(pth))
71 bf::directory_iterator end_itr;
72 for(bf::directory_iterator itr(pth); itr != end_itr; ++itr)
74 if(!is_directory(itr->status()))
76 std::string nm(itr->path().filename().string());
77 if(nm.substr(nm.size()-4) == ".bbs")
79 //std::cout << itr->path().filename().string() << std::endl;
80 files.push_back(itr->path());
87 std::cout<< "the path to the bbs's should be a folder and not a file.";
91 // Order files by name
92 for (int i = 0; i < (int)files.size()-1; ++i) {
93 for (int j = i+1; j < (int)files.size(); ++j) {
94 if(files[j].filename().string() < files[i].filename().string())
96 bf::path tmp = files[i];
103 // Order files by dependencies
104 // Get Dependencies and Box Names
109 for (int i = 0; i < (int)files.size(); ++i) {
110 bbtk::BBPInterpreter::Pointer I = bbtk::BBPInterpreter::New();
111 I->InterpretFile(files[i].string());
112 bs.push_back( ((bbtk::BBPInterpreter*)(I.get()))->boxName );
113 ds.push_back( ((bbtk::BBPInterpreter*)(I.get()))->dependencies );
115 //print box name and dependencies
116 /* std::cout << ((bbtk::BBPInterpreter*)(I.get()))->boxName << ": ";
118 dep::iterator it = ((bbtk::BBPInterpreter*)(I.get()))->dependencies.begin();
119 it != ((bbtk::BBPInterpreter*)(I.get()))->dependencies.end();
121 std::cout << *it << ", ";
123 std::cout << std::endl;
126 // Only keep dependencies from package
127 Dependency boxesNamesSet(bs.begin(), bs.end());
129 //std::cout << "after: " << std::endl;
130 for (Dependencies::iterator it = ds.begin(); it != ds.end(); it++) {
132 std::set_intersection(it->begin(), it->end(), boxesNamesSet.begin(), boxesNamesSet.end(),std::back_inserter(tmp));
133 Dependency tmp1(tmp.begin(),tmp.end());
135 //print clean dependencies
137 dep::iterator it1 = it->begin();
140 std::cout << *it1 << ", ";
142 std::cout << std::endl;
146 // Check there are no cycles in graph
147 std::vector<std::vector<int> > g(bs.size(), std::vector<int>());
148 std::map<std::string, int> idxs;
151 for (int i = 0; i < (int)bs.size(); ++i)
157 for (Dependencies::iterator dit = ds.begin(); dit != ds.end(); dit++, boxit++)
159 for (Dependency::iterator ddit = dit->begin(); ddit != dit->end(); ddit++)
161 g[boxit].push_back(idxs[*ddit]);
167 std::cout << "there are dependency cycles, please check your scripts." << std::endl;
172 std::cout << "no cycles, we keep going." << std::endl;
173 std::vector<int> dep_priority(bs.size(), -1);
174 setPriorities(g, dep_priority);
175 // for (int i = 0; i < (int)dep_priority.size(); i++)
177 // std::cout << dep_priority[i] << " ";
179 // std::cout << std::endl;
181 // Write results to bbp file
183 std::string fname = path_out + "\\" + package_name + ".bbp";
185 std::string fname = path_out + "/" + package_name + ".bbp";
188 std::ofstream out(fname.c_str());
189 out << "#-----------------------------------------" << std::endl;
190 out << "# Include script for bbtk package '" << package_name << "'" << std::endl;
191 out << "# Automatically generated by bbpConfigurator" << std::endl;
192 out << "#-----------------------------------------" << std::endl;
193 out << "load "<< package_name << std::endl;
194 out << "#-----------------------------------------" << std::endl;
195 out << "package "<< package_name << std::endl;
196 out << "#-----------------------------------------" << std::endl;
198 //each bbs file ordered.
199 //include [package_name]/boxes/[file_bbs]
200 //#-----------------------------------------
202 // for (int i = 0; i < (int)files.size(); ++i) {
203 // out << "include " << package_name << "/boxes/" << files[i].filename().string() << std::endl;
204 // out << "#-----------------------------------------" << std::endl;
207 // for each priority level print scripts in that level.
209 for (int i = 0; i < (int)dep_priority.size(); i++)
210 m_priority = std::max(m_priority, dep_priority[i]);
212 for (int i = 0; i <= m_priority; i++)
214 for (int j = 0; j < (int)dep_priority.size(); j++)
216 if(dep_priority[j] == i)
218 out << "include " << package_name << "/boxes/" << files[j].filename().string() << std::endl;
219 out << "#-----------------------------------------" << std::endl;
223 out << "endpackage" << std::endl;
224 out << "#-- EOF ----------------------------------" << std::endl;
230 //==========================================================================
232 // extract of the tarjan's algorithm for strongly connected components
233 bool isCycle(const Graph& g)
235 for (int it = 0; it < (int)g.size(); ++it) {
236 std::vector<bool> visited (g.size(), false);
237 if (checkCycle(g, it, visited))
239 //std::cout << "At " << it << std::endl;
246 //==========================================================================
248 bool checkCycle(const Graph& g, const int& i, std::vector<bool>& v)
252 for(int dit = 0; dit < (int)g[i].size(); dit++)
255 if(d < 0 || d >= (int)g[i].size() || v[d])
257 //std::cout << "Checking " << i << " dependency " << dit << "=" << d << std::endl;
260 if(checkCycle(g,d,v))
266 //==========================================================================
268 // find precedence in graph. 0 are the boxes that have no deps, 1 boxes that have deps from 0 or less, 2 boxes that have deps from 1 or less, etc.
269 void setPriorities(const Graph& g, std::vector<int>& p)
271 for(int i = 0; i < (int)g.size(); i++)
274 setPriority(g, i, p);
278 //==========================================================================
279 void setPriority(const Graph& g, const int i, std::vector<int>& p)
282 for(int j = 0; j < (int)g[i].size(); j++)
284 setPriority(g, g[i][j], p);
285 pi = std::max(pi, p[g[i][j]]);