HAL  v4.5.0-133-g64838ea8d
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
utils.h
Go to the documentation of this file.
1 // MIT License
2 //
3 // Copyright (c) 2019 Ruhr University Bochum, Chair for Embedded Security. All Rights reserved.
4 // Copyright (c) 2019 Marc Fyrbiak, Sebastian Wallat, Max Hoffmann ("ORIGINAL AUTHORS"). All rights reserved.
5 // Copyright (c) 2021 Max Planck Institute for Security and Privacy. All Rights reserved.
6 // Copyright (c) 2021 Jörn Langheinrich, Julian Speith, Nils Albartus, René Walendy, Simon Klix ("ORIGINAL AUTHORS"). All Rights reserved.
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
14 //
15 // The above copyright notice and this permission notice shall be included in all
16 // copies or substantial portions of the Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 // SOFTWARE.
25 
30 #pragma once
31 
32 #include "hal_core/defines.h"
34 
35 #include <algorithm>
36 #include <functional>
37 #include <set>
38 #include <sstream>
39 #include <string>
40 #include <unordered_map>
41 #include <unordered_set>
42 #include <vector>
43 
44 namespace hal
45 {
51  namespace utils
52  {
60  template<typename T>
61  CORE_API inline bool unordered_vector_erase(std::vector<T>& vec, T element)
62  {
63  auto it = std::find(vec.begin(), vec.end(), element);
64  if (it == vec.end())
65  {
66  return false;
67  }
68  *it = vec.back();
69  vec.pop_back();
70  return true;
71  }
72 
80  template<typename T>
81  CORE_API inline void indexed_vector_push_back(std::vector<T>& vec, std::unordered_map<T, u32>& positions, T element)
82  {
83  positions[element] = static_cast<u32>(vec.size());
84  vec.push_back(element);
85  }
86 
96  template<typename T>
97  CORE_API inline bool indexed_vector_erase(std::vector<T>& vec, std::unordered_map<T, u32>& positions, T element)
98  {
99  const auto it = positions.find(element);
100  if (it == positions.end())
101  {
102  return false;
103  }
104  const u32 index = it->second;
105  positions.erase(it);
106  T last = vec.back();
107  vec.pop_back();
108  if (last != element)
109  {
110  vec[index] = last;
111  positions[last] = index;
112  }
113  return true;
114  }
115 
123  template<typename T>
124  bool vectors_have_same_content(std::vector<T> vec_1, std::vector<T> vec_2)
125  {
126  if (vec_1.size() != vec_2.size())
127  {
128  return false;
129  }
130 
131  std::sort(vec_1.begin(), vec_1.end());
132  std::sort(vec_2.begin(), vec_2.end());
133 
134  return vec_1 == vec_2;
135  }
136 
144  CORE_API inline u64 get_bit(const u64 value, const u64 index)
145  {
146  return (value >> index) & 1;
147  }
148 
156  CORE_API inline u64 set_bit(const u64 value, const u64 index)
157  {
158  return value | ((u64)1 << index);
159  }
160 
168  CORE_API inline u64 clear_bit(const u64 value, const u64 index)
169  {
170  return value & ~((u64)1 << index);
171  }
172 
180  CORE_API inline u64 toggle_bit(const u64 value, const u64 index)
181  {
182  return value ^ ((u64)1 << index);
183  }
184 
192  template<typename T>
193  CORE_API bool ends_with(const T& s, const T& end)
194  {
195  if (s.length() >= end.length())
196  {
197  return (0 == s.compare(s.length() - end.length(), end.length(), end));
198  }
199  else
200  {
201  return false;
202  }
203  }
204 
212  template<typename T>
213  CORE_API bool starts_with(const T& s, const T& start)
214  {
215  if (s.length() >= start.length())
216  {
217  return (0 == s.compare(0, start.length(), start));
218  }
219  else
220  {
221  return false;
222  }
223  }
224 
231  template<typename T>
232  CORE_API bool is_digits(const T& s)
233  {
234  return std::all_of(s.begin(), s.end(), ::isdigit);
235  }
236 
243  template<typename T>
244  CORE_API bool is_integer(const T& s)
245  {
246  if (s.empty() || ((!isdigit(s[0])) && (s[0] != '-') && (s[0] != '+')))
247  {
248  return false;
249  }
250 
251  char* p;
252  strtol(s.c_str(), &p, 10);
253 
254  return (*p == 0);
255  }
256 
263  template<typename T>
264  CORE_API bool is_floating_point(const T& s)
265  {
266  std::stringstream ss(s.c_str());
267  float f;
268  ss >> f;
269  return (ss.eof() && !ss.fail());
270  }
271 
282  template<typename T>
283  CORE_API std::vector<T> split(const T& s, const char delim, bool obey_brackets = false)
284  {
285  std::vector<T> result;
286  T item = "";
287 
288  if (obey_brackets)
289  {
290  int bracket_level = 0;
291 
292  for (size_t i = 0; i < s.length(); ++i)
293  {
294  char c = s.at(i);
295  switch (c)
296  {
297  case '(':
298  case '{':
299  case '[':
300  ++bracket_level;
301  break;
302  case ')':
303  case '}':
304  case ']':
305  --bracket_level;
306  break;
307  default:
308  break;
309  }
310  if (bracket_level < 0)
311  {
312  bracket_level = 0;
313  }
314  if (c == delim)
315  {
316  // No constant expression, therefore not usable in switch case
317  if (bracket_level == 0)
318  {
319  result.push_back(item);
320  item = "";
321  }
322  else
323  {
324  item.push_back(c);
325  }
326  }
327  else
328  {
329  item.push_back(c);
330  }
331  }
332  if (!item.empty())
333  {
334  result.push_back(item);
335  }
336  }
337  else
338  {
339  std::stringstream ss(s);
340  while (std::getline(ss, item, delim))
341  {
342  result.push_back(item);
343  }
344  }
345  if (!s.empty() && s.back() == delim)
346  {
347  result.push_back("");
348  }
349  return result;
350  }
351 
359  template<typename T>
360  CORE_API T ltrim(const T& s, const char* to_remove = " \t\r\n")
361  {
362  size_t start = s.find_first_not_of(to_remove);
363 
364  if (start != std::string::npos)
365  {
366  return s.substr(start, s.size() - start);
367  }
368  else
369  {
370  return "";
371  }
372  }
373 
381  template<typename T>
382  CORE_API T rtrim(const T& s, const char* to_remove = " \t\r\n")
383  {
384  size_t end = s.find_last_not_of(to_remove);
385 
386  if (end != std::string::npos)
387  {
388  return s.substr(0, end + 1);
389  }
390  else
391  {
392  return "";
393  }
394  }
395 
403  template<typename T>
404  CORE_API T trim(const T& s, const char* to_remove = " \t\r\n")
405  {
406  size_t start = s.find_first_not_of(to_remove);
407  size_t end = s.find_last_not_of(to_remove);
408 
409  if (start != T::npos)
410  {
411  return s.substr(start, end - start + 1);
412  }
413  else
414  {
415  return "";
416  }
417  }
418 
427  template<typename T>
428  CORE_API T replace(const T& str, const T& search, const T& replace)
429  {
430  auto s = str;
431  size_t pos = 0;
432 
433  if (search.empty())
434  {
435  return str;
436  }
437 
438  while ((pos = s.find(search, pos)) != T::npos)
439  {
440  s.replace(pos, search.length(), replace);
441  pos += replace.length();
442  }
443 
444  return s;
445  }
446 
457  template<typename Iterator, class Transform>
458  CORE_API std::string join(const std::string& joiner, const Iterator& begin, const Iterator& end, const Transform& transform)
459  {
460  std::stringstream ss;
461  bool first = true;
462  for (auto it = begin; it != end; ++it)
463  {
464  if (!first)
465  {
466  ss << joiner;
467  }
468  first = false;
469  ss << transform(*it);
470  }
471  return ss.str();
472  }
473 
483  template<typename T, class Transform>
484  CORE_API std::string join(const std::string& joiner, const T& items, const Transform& transform)
485  {
486  return join(joiner, items.begin(), items.end(), transform);
487  }
488 
496  template<typename T>
497  CORE_API std::string join(const std::string& joiner, const T& items)
498  {
499  return join(joiner, items.begin(), items.end(), [](const auto& v) { return v; });
500  }
501 
508  template<typename T>
509  CORE_API T to_upper(const T& s)
510  {
511  T result = s;
512  std::transform(result.begin(), result.end(), result.begin(), [](char c) { return std::toupper(c); });
513  return result;
514  }
515 
522  template<typename T>
523  CORE_API T to_lower(const T& s)
524  {
525  T result = s;
526  std::transform(result.begin(), result.end(), result.begin(), [](char c) { return std::tolower(c); });
527  return result;
528  }
529 
537  template<typename T>
538  CORE_API u32 num_of_occurrences(const T& s, const T& substr)
539  {
541  auto position = s.find(substr, 0);
542 
543  while (position != std::string::npos)
544  {
546  position = s.find(substr, position + 1);
547  }
548 
549  return num_of_occurrences;
550  }
551 
558  template<typename T, template<typename, typename...> class Container, typename... Args>
559  CORE_API inline std::vector<T> to_vector(const Container<T, Args...>& container)
560  {
561  return std::vector<T>(container.begin(), container.end());
562  }
563 
570  template<typename T, template<typename, typename...> class Container, typename... Args>
571  CORE_API inline std::set<T> to_set(const Container<T, Args...>& container)
572  {
573  return std::set<T>(container.begin(), container.end());
574  }
575 
584  template<typename T1, typename T2>
585  CORE_API bool is_subset(const T1& subset, const T2& superset)
586  {
587  for (const auto& element : subset)
588  {
589  if (std::find(std::begin(superset), std::end(superset), element) == std::end(superset))
590  {
591  return false; // Element not found in superset
592  }
593  }
594  return true; // All elements found; subset is indeed a subset of superset
595  }
596 
603  CORE_API bool file_exists(const std::string& filename);
604 
611  CORE_API bool folder_exists_and_is_accessible(const std::filesystem::path& path);
612 
620  CORE_API std::filesystem::path which(const std::string& name, const std::string& path = "");
621 
627  CORE_API std::filesystem::path get_binary_directory();
628 
637  CORE_API std::filesystem::path get_base_directory();
638 
645  CORE_API std::filesystem::path get_library_directory();
646 
653  CORE_API std::filesystem::path get_share_directory();
654 
661  CORE_API std::filesystem::path get_user_share_directory();
662 
669  CORE_API std::filesystem::path get_config_directory();
670 
677  CORE_API std::filesystem::path get_user_config_directory();
678 
686  CORE_API std::filesystem::path get_default_log_directory(std::filesystem::path source_file = "");
687 
694  CORE_API std::vector<std::filesystem::path> get_gate_library_directories();
695 
702  CORE_API std::vector<std::filesystem::path> get_plugin_directories();
703 
710  CORE_API std::filesystem::path get_first_directory_exists(std::vector<std::filesystem::path> path_hints);
711 
719  CORE_API std::filesystem::path get_file(std::string file_name, std::vector<std::filesystem::path> path_hints);
720 
728  CORE_API Result<std::filesystem::path> get_unique_temp_directory(const std::string& prefix = "", const u32 max_attempts = 5);
729 
735  CORE_API std::string get_open_source_licenses();
736 
741  {
742  public:
743  using iterator = std::filesystem::recursive_directory_iterator;
744 
750  RecursiveDirectoryRange(std::filesystem::path path) : p_(path)
751  {
752  }
753 
761  {
762  return std::filesystem::recursive_directory_iterator(p_);
763  }
764 
771  {
772  return std::filesystem::recursive_directory_iterator();
773  }
774 
775  private:
776  std::filesystem::path p_;
777  };
778 
783  {
784  public:
785  using iterator = std::filesystem::directory_iterator;
786 
792  DirectoryRange(std::filesystem::path path) : p_(path)
793  {
794  }
795 
804  {
805  return std::filesystem::directory_iterator(p_);
806  }
807 
814  {
815  return std::filesystem::directory_iterator();
816  }
817 
818  private:
819  std::filesystem::path p_;
820  };
821 
827  {
828  int h;
829  int s;
830  int v;
831 
832  Color(int _h = 0, int _s = 0, int _v = 0) : h(_h), s(_s), v(_v)
833  {
834  }
835 
836  std::string toString()
837  {
838  return "h=" + std::to_string(h) + " s=" + std::to_string(s) + " v=" + std::to_string(v);
839  }
840  };
841 
850  CORE_API Result<u64> wrapped_stoull(const std::string& s, const u32 base = 10);
851 
860  CORE_API Result<u32> wrapped_stoul(const std::string& s, const u32 base = 10);
861  } // namespace utils
862 } // namespace hal
#define CORE_API
Definition: arch_linux.h:28
DirectoryRange(std::filesystem::path path)
Definition: utils.h:792
std::filesystem::directory_iterator iterator
Definition: utils.h:785
std::filesystem::recursive_directory_iterator iterator
Definition: utils.h:743
RecursiveDirectoryRange(std::filesystem::path path)
Definition: utils.h:750
uint64_t u64
Definition: defines.h:42
uint32_t u32
Definition: defines.h:41
std::filesystem::path get_config_directory()
Definition: utils.cpp:164
bool folder_exists_and_is_accessible(const std::filesystem::path &path)
Definition: utils.cpp:37
u64 get_bit(const u64 value, const u64 index)
Definition: utils.h:144
std::filesystem::path get_share_directory()
Definition: utils.cpp:149
T replace(const T &str, const T &search, const T &replace)
Definition: utils.h:428
T rtrim(const T &s, const char *to_remove=" \t\r\n")
Definition: utils.h:382
u64 clear_bit(const u64 value, const u64 index)
Definition: utils.h:168
bool is_digits(const T &s)
Definition: utils.h:232
std::filesystem::path get_library_directory()
Definition: utils.cpp:129
void indexed_vector_push_back(std::vector< T > &vec, std::unordered_map< T, u32 > &positions, T element)
Definition: utils.h:81
Result< u64 > wrapped_stoull(const std::string &s, const u32 base=10)
Definition: utils.cpp:696
Result< u32 > wrapped_stoul(const std::string &s, const u32 base=10)
Definition: utils.cpp:714
u32 num_of_occurrences(const T &s, const T &substr)
Definition: utils.h:538
std::filesystem::path which(const std::string &name, const std::string &path="")
Definition: utils.cpp:243
std::set< T > to_set(const Container< T, Args... > &container)
Definition: utils.h:571
std::filesystem::path get_default_log_directory(std::filesystem::path source_file="")
Definition: utils.cpp:179
bool vectors_have_same_content(std::vector< T > vec_1, std::vector< T > vec_2)
Definition: utils.h:124
std::filesystem::path get_first_directory_exists(std::vector< std::filesystem::path > path_hints)
Definition: utils.cpp:207
std::filesystem::path get_file(std::string file_name, std::vector< std::filesystem::path > path_hints)
Definition: utils.cpp:220
bool is_subset(const T1 &subset, const T2 &superset)
Definition: utils.h:585
std::string join(const std::string &joiner, const Iterator &begin, const Iterator &end, const Transform &transform)
Definition: utils.h:458
Result< std::filesystem::path > get_unique_temp_directory(const std::string &prefix="", const u32 max_attempts=5)
Definition: utils.cpp:276
std::filesystem::path get_base_directory()
Definition: utils.cpp:100
bool starts_with(const T &s, const T &start)
Definition: utils.h:213
std::string get_open_source_licenses()
Definition: utils.cpp:299
u64 set_bit(const u64 value, const u64 index)
Definition: utils.h:156
bool is_floating_point(const T &s)
Definition: utils.h:264
T ltrim(const T &s, const char *to_remove=" \t\r\n")
Definition: utils.h:360
bool indexed_vector_erase(std::vector< T > &vec, std::unordered_map< T, u32 > &positions, T element)
Definition: utils.h:97
bool ends_with(const T &s, const T &end)
Definition: utils.h:193
T to_upper(const T &s)
Definition: utils.h:509
std::filesystem::path get_binary_directory()
Definition: utils.cpp:70
std::vector< std::filesystem::path > get_plugin_directories()
Definition: utils.cpp:195
std::vector< std::filesystem::path > get_gate_library_directories()
Definition: utils.cpp:186
std::vector< T > to_vector(const Container< T, Args... > &container)
Definition: utils.h:559
T to_lower(const T &s)
Definition: utils.h:523
bool file_exists(const std::string &filename)
Definition: utils.cpp:31
bool unordered_vector_erase(std::vector< T > &vec, T element)
Definition: utils.h:61
std::filesystem::path get_user_share_directory()
Definition: utils.cpp:157
bool is_integer(const T &s)
Definition: utils.h:244
std::filesystem::path get_user_config_directory()
Definition: utils.cpp:172
std::vector< T > split(const T &s, const char delim, bool obey_brackets=false)
Definition: utils.h:283
u64 toggle_bit(const u64 value, const u64 index)
Definition: utils.h:180
T trim(const T &s, const char *to_remove=" \t\r\n")
Definition: utils.h:404
Definition: defines.h:45
std::string name
Color(int _h=0, int _s=0, int _v=0)
Definition: utils.h:832
std::string toString()
Definition: utils.h:836