gambit is hosted by Hepforge, IPPP Durham
GAMBIT  v1.5.0-2191-ga4742ac
a Global And Modular Bsm Inference Tool
plugin_details.cpp
Go to the documentation of this file.
1 // GAMBIT: Global and Modular BSM Inference Tool
2 // *********************************************
11 //
22 
23 #include <string>
24 #include <ostream>
25 #include <sstream>
26 #include <iomanip>
27 
30 #include "gambit/cmake/cmake_variables.hpp"
32 
33 namespace Gambit
34 {
35 
36  namespace Scanner
37  {
38 
39  namespace Plugins
40  {
41  Plugin_Details::Plugin_Details(const std::string &str) : full_string(str)
42  {
43  status= "ok";
44 
45  std::string::size_type posMid = str.rfind("__v__");
46  version = str.substr(posMid + 5);
47 
48  std::string::size_type posLast = str.rfind("__t__", posMid - 1);
49  type = str.substr(posLast + 5, posMid - posLast - 5);
50  plugin = str.substr(0, posLast);
51  posLast = version.find("_");
52  major_version = StringToInt(version.substr(0, posLast));
53  posMid = version.find("_", posLast + 1);
54  minor_version = StringToInt(version.substr(posLast + 1, posMid - posLast - 1));
55  posLast = version.find("_", posMid + 1);
56  patch_version = StringToInt(version.substr(posMid + 1, posLast - posMid - 1));
57  release_version = version.substr(posLast + 1);
59  if (release_version != "")
60  version += "-" + release_version;
61  }
62 
63  void Plugin_Details::get_status(const YAML::Node &libNode, const YAML::Node &plugNode, const YAML::Node &flagNode)
64  {
65  std::vector<std::string> linked_libs_plug, found_incs_plug;
66 
67  if (plugNode.IsMap())
68  {
69  if (plugNode[type] && plugNode[type][plugin] && plugNode[type][plugin][version] && plugNode[type][plugin][version].IsMap())
70  {
71  if (plugNode[type][plugin][version]["reqd_inifile_entries"].IsSequence())
72  reqd_inifile_entries = plugNode[type][plugin][version]["reqd_inifile_entries"].as<std::vector<std::string>>();
73  if (plugNode[type][plugin][version]["reqd_libraries"].IsSequence())
74  reqd_not_linked_libs = plugNode[type][plugin][version]["reqd_libraries"].as<std::vector<std::string>>();
75  if (plugNode[type][plugin][version]["not_linked_libraries"].IsSequence())
76  ini_libs_not_found = plugNode[type][plugin][version]["not_linked_libraries"].as<std::vector<std::string>>();
77  if (plugNode[type][plugin][version]["reqd_include_paths"].IsSequence())
78  reqd_incs_not_found = plugNode[type][plugin][version]["reqd_include_paths"].as<std::vector<std::string>>();
79  if (plugNode[type][plugin][version]["not_found_include_paths"].IsSequence())
80  ini_incs_not_found = plugNode[type][plugin][version]["not_found_include_paths"].as<std::vector<std::string>>();
81 
82  if (plugNode[type][plugin][version]["linked_libraries"].IsSequence())
83  linked_libs_plug = plugNode[type][plugin][version]["linked_libraries"].as<std::vector<std::string>>();
84  if (plugNode[type][plugin][version]["found_include_paths"].IsSequence())
85  found_incs_plug = plugNode[type][plugin][version]["found_include_paths"].as<std::vector<std::string>>();
86  }
87  }
88 
89  std::string lib = path.substr(path.rfind("/") + 1);
90  if (libNode.IsMap())
91  {
92  if (libNode[lib] and libNode[lib].IsMap())
93  {
94  std::multimap<std::string, std::string> linked_libs_temp;
95  if (libNode[lib]["linked_libs"] and libNode[lib]["linked_libs"].IsMap())
96  {
97  for (auto it = libNode[lib]["linked_libs"].begin(), end = libNode[lib]["linked_libs"].end(); it != end; ++it)
98  {
99  linked_libs_temp.insert(std::pair<std::string, std::string>(it->first.as<std::string>(), it->second.as<std::string>()));
100  }
101  }
102 
103  for (auto it = linked_libs_plug.begin(), end = linked_libs_plug.end(); it != end; ++it)
104  {
105  auto range = linked_libs_temp.equal_range(*it);
106  if (range.first != range.second)
107  linked_libs.insert(range.first, range.second);
108  }
109 
110  std::vector<std::string> linked_temp;
111  for (auto it = reqd_not_linked_libs.begin(), end = reqd_not_linked_libs.end(); it != end; ++it)
112  {
113  auto range = linked_libs_temp.equal_range(*it);
114  auto range2 = linked_libs.equal_range(*it);
115  if (range.first == range.second)
116  {
117  linked_temp.push_back(*it);
118  }
119  else if (range2.first == range2.second)
120  {
121  linked_libs.insert(range.first, range.second);
122  }
123  }
124 
125  reqd_not_linked_libs = linked_temp;
126 
127  std::multimap<std::string, std::string> found_incs_temp;
128  if (libNode[lib]["found_incs"] and libNode[lib]["found_incs"].IsMap())
129  {
130  for (auto it = libNode[lib]["found_incs"].begin(), end = libNode[lib]["found_incs"].end(); it != end; ++it)
131  found_incs_temp.insert(std::pair<std::string, std::string>(it->first.as<std::string>(), it->second.as<std::string>()));
132  }
133 
134  for (auto it = found_incs_plug.begin(), end = found_incs_plug.end(); it != end; it++)
135  {
136  //cout << *it << endl;
137  found_incs.insert(std::pair<std::string, std::string>(type + "_locations.yaml", *it));
138  }
139  std::vector<std::string> found_temp;
140  for (auto it = reqd_incs_not_found.begin(), end = reqd_incs_not_found.end(); it != end; ++it)
141  {
142  auto range = found_incs_temp.equal_range(*it);
143  if (range.first == range.second)
144  {
145  found_temp.push_back(*it);
146  }
147  else
148  {
149  found_incs.insert(range.first, range.second);
150  }
151  }
152 
153  reqd_incs_not_found = found_temp;
154  }
155  }
156 
157  if (flagNode.IsMap())
158  {
159  if (flagNode[type] && flagNode[type][plugin] && flagNode[type][plugin][version] && flagNode[type][plugin][version].IsMap())
160  {
161  flags = flagNode[type][plugin][version];
162  }
163  }
164 
165  if (status != "excluded")
166  {
167  if (reqd_incs_not_found.size() > 0)
168  {
169  status = "reqd header file(s) not found";
170  }
171  else if (reqd_not_linked_libs.size() > 0)
172  {
173  status = "reqd lib(s) not found";
174  }
175  else if (ini_libs_not_found.size() > 0)
176  {
177  status = "invalid lib path(s) in locations file";
178  }
179  else if (ini_incs_not_found.size() > 0)
180  {
181  status = "invalid include dir(s) in locations file";
182  }
183  }
184  }
185 
186  std::string Plugin_Details::printMin() const
187  {
188  std::stringstream out;
189  out << "plugin: " << plugin << std::endl;
190  out << "version: " << version << std::endl;
191  out << "type: " << type << std::endl;
192 
193  return out.str();
194  }
195 
196  std::string Plugin_Details::print() const
197  {
198  std::stringstream out;
199  out << "plugin: " << plugin << std::endl;
200  out << "\tversion: " << version << std::endl;
201  out << "\tmajor version: " << major_version << std::endl;
202  out << "\tminor version: " << minor_version << std::endl;
203  out << "\tpatch version: " << patch_version << std::endl;
204  out << "\tplugin path: " << path << std::endl;
205  out << "\ttype: " << type << std::endl;
206 
207  return out.str();
208  }
209 
210  std::string Plugin_Details::printFull() const
211  {
212  std::stringstream out;
213 
214  /*table_formatter table(type + " PLUGIN", "VERSION", "STATUS");
215  table.capitalize_title();
216  table.padding(1);
217  table << plugin << version;
218  if (status == "ok")
219  table.green() << status;
220  else
221  table.red() << status;
222 
223  out << table.str();*/
224 
225  out << "\n\x1b[01m\x1b[04mGENERAL PLUGIN INFO\x1b[0m" << std::endl;
226  out << "\nname: " << plugin;
227  out << "\ntype: " << type;
228  out << "\nversion: " << version;
229  out << "\nstatus: ";
230  if (status == "ok")
231  out << "\x1b[32;01m" << status << "\x1b[0m" << std::endl;
232  else
233  out << "\x1b[31;01m" << status << "\x1b[0m" << std::endl;
234 
235  if (reason.size() > 0)
236  {
237  out << "\nreason for exclusion:\n";
238  for (auto it = reason.begin(), end = reason.end(); it != end; ++it)
239  out << " " << *it << std::endl;
240  }
241 
242  out << std::endl;
243 
244  out << "\n\x1b[01m\x1b[04mHEADER & LINK INFO\x1b[0m" << std::endl;
245  out << "\nrequired inifile entries: ";
246  if (reqd_inifile_entries.empty())
247  out << "none" << std::endl;
248  else
249  out << reqd_inifile_entries << std::endl;
250  out << "\n\x1b[04mlink status\x1b[0m:" << std::endl;
251  //out << "-----------" << std::endl;
252  if (not reqd_not_linked_libs.empty())
253  out << " could not find libraries requested by plugin: " << reqd_not_linked_libs << std::endl;
254  if (not ini_libs_not_found.empty())
255  out << " could not find libraries specified in *locations.yaml: " << ini_libs_not_found << std::endl;
256  out << " linked libraries:";
257  if (linked_libs.empty())
258  {
259  out << " none" << std::endl;
260  }
261  else
262  {
263  out << std::endl;
264  for (auto it = linked_libs.begin(), end = linked_libs.end(); it != end; ++it)
265  out << " " << it->first << ": " << it->second << std::endl;
266  }
267 
268  out << "\n\x1b[04minclude header status\x1b[0m:" << std::endl;
269  //out << "---------------------" << std::endl;
270  if (not reqd_incs_not_found.empty())
271  out << " could not find headers requested by plugin: " << reqd_incs_not_found << std::endl;
272  if (not ini_incs_not_found.empty())
273  out << " could not find include paths specified in *locations.yaml: " << ini_incs_not_found << std::endl;
274  out << " headers found:";
275  if (found_incs.empty())
276  {
277  out << " none" << std::endl;
278  }
279  else
280  {
281  out << std::endl;
282  for (auto it = found_incs.begin(), end = found_incs.end(); it != end; ++it)
283  out << " " << it->first << ": " << it->second << std::endl;
284  }
285 
286  out << std::endl;
287 
288  out << "\n\x1b[01m\x1b[04mDESCRIPTION\x1b[0m\n" << std::endl;
289 
290  std::string p_str, description;
291  std::string path = GAMBIT_DIR "/config/";
292  if (FILE* p_f = popen((std::string("ls ") + path + std::string(" | grep \".dat\" | grep \""+ type + "\"")).c_str(), "r"))
293  {
294  char path_buffer[1024];
295  int p_n;
296  while ((p_n = fread(path_buffer, 1, sizeof path_buffer, p_f)) > 0)
297  {
298  std::stringstream p_ss(std::string(path_buffer, p_n));
299  while (p_ss >> p_str)
300  {
301  YAML::Node node = YAML::LoadFile(path + p_str);
302  if (node[plugin])
303  {
304  description = node[plugin].as<std::string>();
305  break;
306  }
307  }
308  }
309 
310  pclose(p_f);
311  }
312 
313  out << description << std::endl;
314 
315  return out.str();
316  }
317 
318  std::string Plugin_Details::printMultiPlugins(const std::vector<const Plugin_Details *> &plugins)
319  {
320  std::stringstream out;
321 
322  if (plugins.empty())
323  return "";
324  else if (plugins.size() == 1)
325  return plugins[0]->printFull();
326 
327  out << "\n\x1b[01m\x1b[04mGENERAL PLUGIN INFO\x1b[0m" << std::endl;
328  out << "\nname: " << plugins[0]->plugin;
329  out << "\ntype: " << plugins[0]->type;
330  out << "\nversions: ";
331  out << plugins[0]->version;
332  for (int i = 1, end = plugins.size(); i < end; ++i)
333  {
334  out << ", " << plugins[i]->version;
335  }
336  out << "\nstatus: ";
337  for (auto &&plug : plugins)
338  {
339  out << "\n " << plug->version << ": ";
340  if (plug->status == "ok")
341  out << "\x1b[32;01m" << plug->status << "\x1b[0m";
342  else
343  out << "\x1b[31;01m" << plug->status << "\x1b[0m";
344  }
345  out << std::endl;
346 
347  bool exclude{false};
348  for (auto&& plug : plugins)
349  {
350  if (not plug->reason.empty())
351  {
352  exclude = true;
353  break;
354  }
355  }
356 
357  if (exclude)
358  {
359  out << "\nreason for exclusion:";
360  for (auto &&plug : plugins)
361  {
362  out << "\n " << plug->version << ":\n";
363  for (auto it = plug->reason.begin(), end = plug->reason.end(); it != end; ++it)
364  out << " " << *it << std::endl;
365  }
366  }
367 
368  out << std::endl;
369 
370  out << "\n\x1b[01m\x1b[04mHEADER & LINK INFO\x1b[0m" << std::endl;
371  out << "\n\x1b[04mrequired inifile entries\x1b[0m:";
372  for (auto &&plug : plugins)
373  {
374  out << "\n " << plug->version << ": ";
375  if (plug->reqd_inifile_entries.empty())
376  out << "none";
377  else
378  out << plug->reqd_inifile_entries;
379  }
380  out << std::endl;
381  out << "\n\x1b[04mlink status\x1b[0m:" << std::endl;
382  for (auto &&plug : plugins)
383  {
384  out << " " << plug->version << ":\n";
385  if (not plug->reqd_not_linked_libs.empty())
386  {
387  out << " could not find libraries requested by plugin: " << plug->reqd_not_linked_libs << std::endl;
388  }
389  if (not plug->ini_libs_not_found.empty())
390  {
391  out << " could not find libraries specified in *locations.yaml: " << plug->ini_libs_not_found << std::endl;
392  }
393 
394  out << " linked libraries:";
395  if (plug->linked_libs.empty())
396  {
397  out << " none" << std::endl;
398  }
399  else
400  {
401  out << std::endl;
402  for (auto it = plug->linked_libs.begin(), end = plug->linked_libs.end(); it != end; ++it)
403  out << " " << it->first << ": " << it->second << std::endl;
404  }
405  out << std::endl;
406  }
407 
408  out << "\x1b[04minclude header status\x1b[0m:" << std::endl;
409  for (auto &&plug : plugins)
410  {
411  out << " " << plug->version << ":\n";
412  if (not plug->reqd_incs_not_found.empty())
413  out << " could not find headers requested by plugin: " << plug->reqd_incs_not_found << std::endl;
414  if (not plug->ini_incs_not_found.empty())
415  out << " could not find include paths specified in *locations.yaml: " << plug->ini_incs_not_found << std::endl;
416  out << " headers found:";
417  if (plug->found_incs.empty())
418  {
419  out << " none" << std::endl;
420  }
421  else
422  {
423  out << std::endl;
424  for (auto it = plug->found_incs.begin(), end = plug->found_incs.end(); it != end; ++it)
425  out << " " << it->first << ": " << it->second << std::endl;
426  }
427  out << std::endl;
428  }
429  out << std::endl;
430 
431  out << "\x1b[01m\x1b[04mDESCRIPTION\x1b[0m\n" << std::endl;
432 
433  out << get_description(plugins) << std::endl;
434 
435  return out.str();
436  }
437 
438  std::string Plugin_Details::get_description(const std::vector<const Plugin_Details *> &plugins) {
439  std::string description;
440  std::string p_str;
441  const std::string path = GAMBIT_DIR "/config/";
442  if (FILE* p_f = popen((std::string("ls ") + path + std::string(" | grep \".dat\" | grep \""+ plugins[0]->type + "\"")).c_str(), "r"))
443  {
444  char path_buffer[1024];
445  int p_n;
446  while ((p_n = fread(path_buffer, 1, sizeof path_buffer, p_f)) > 0)
447  {
448  std::stringstream p_ss(std::string(path_buffer, p_n));
449  while (p_ss >> p_str)
450  {
451  YAML::Node node = YAML::LoadFile(path + p_str);
452  if (node[plugins[0]->plugin])
453  {
454  description = node[plugins[0]->plugin].as<std::string>();
455  break;
456  }
457  }
458  }
459 
460  pclose(p_f);
461  }
462  return description;
463  }
464 
465  bool Plugin_Version_Supersedes(const Plugin_Details &plug1, const Plugin_Details &plug2)
466  {
467  if (plug1.major_version > plug2.major_version)
468  {
469  return true;
470  }
471  else if (plug1.major_version == plug2.major_version)
472  {
473  if (plug1.minor_version > plug2.minor_version)
474  {
475  return true;
476  }
477  else if (plug1.minor_version == plug2.minor_version)
478  {
479  if (plug1.patch_version > plug2.patch_version)
480  {
481  return true;
482  }
483  else if (plug1.patch_version == plug2.patch_version)
484  {
485  if (plug1.release_version == "" && plug2.release_version != "")
486  {
487  return true;
488  }
489  }
490  }
491  }
492 
493  return false;
494  }
495 
496  }
497 
498  }
499 
500 }
std::vector< std::string > ini_incs_not_found
paths specified in the "locations.yaml" file but where not found
int StringToInt(const std::string &str)
Converts a string to an int.
std::multimap< std::string, std::string > linked_libs
list of all libraries that are linked: {lib_name: path_to_lib}
container info for a specific plugin
std::vector< std::string > ini_libs_not_found
libraries specified in the "locations.yaml" file but not found
std::vector< std::string > reason
reason is excluded
bool Plugin_Version_Supersedes(const Plugin_Details &plug1, const Plugin_Details &plug2)
compares the user defined plugin version to the actual plugin version.
std::string path
full path to library containing plugin
std::multimap< std::string, std::string > found_incs
list of all files that were found: {file_name: include_path_to_file}
std::string release_version
release version
std::vector< std::string > reqd_inifile_entries
inifile entries requested my plugin in the "reqd_inifile_entries(...)" function
std::vector< std::string > reqd_not_linked_libs
libraries that were not linked but requested by the "reqd_libraries(...)" function ...
static std::string printMultiPlugins(const std::vector< const Plugin_Details *> &)
Class to hold details of scanner plugins and define simple comparison operations on them...
void get_status(const YAML::Node &, const YAML::Node &, const YAML::Node &)
Utility Functions for the Gambit Scanner.
std::string str
Shorthand for a standard string.
Definition: Analysis.hpp:35
std::vector< std::string > reqd_incs_not_found
requested include files that were not found
Utility Functions for the Gambit Scanner.
std::string version
version string: maj.min.patch-release
std::string status
status, not set right now
TODO: see if we can use this one:
Definition: Analysis.hpp:33
std::string IntToString(const int &in)
Converts a int into a string.
static std::string get_description(const std::vector< const Plugin_Details *> &plugins)