HAL  v4.5.0-83-g30c8f0afc
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_set>
41 #include <vector>
42 
43 namespace hal
44 {
50  namespace utils
51  {
59  template<typename T>
60  CORE_API inline bool unordered_vector_erase(std::vector<T>& vec, T element)
61  {
62  auto it = std::find(vec.begin(), vec.end(), element);
63  if (it == vec.end())
64  {
65  return false;
66  }
67  *it = vec.back();
68  vec.pop_back();
69  return true;
70  }
71 
79  template<typename T>
80  bool vectors_have_same_content(std::vector<T> vec_1, std::vector<T> vec_2)
81  {
82  if (vec_1.size() != vec_2.size())
83  {
84  return false;
85  }
86 
87  std::sort(vec_1.begin(), vec_1.end());
88  std::sort(vec_2.begin(), vec_2.end());
89 
90  return vec_1 == vec_2;
91  }
92 
100  CORE_API inline u64 get_bit(const u64 value, const u64 index)
101  {
102  return (value >> index) & 1;
103  }
104 
112  CORE_API inline u64 set_bit(const u64 value, const u64 index)
113  {
114  return value | ((u64)1 << index);
115  }
116 
124  CORE_API inline u64 clear_bit(const u64 value, const u64 index)
125  {
126  return value & ~((u64)1 << index);
127  }
128 
136  CORE_API inline u64 toggle_bit(const u64 value, const u64 index)
137  {
138  return value ^ ((u64)1 << index);
139  }
140 
148  template<typename T>
149  CORE_API bool ends_with(const T& s, const T& end)
150  {
151  if (s.length() >= end.length())
152  {
153  return (0 == s.compare(s.length() - end.length(), end.length(), end));
154  }
155  else
156  {
157  return false;
158  }
159  }
160 
168  template<typename T>
169  CORE_API bool starts_with(const T& s, const T& start)
170  {
171  if (s.length() >= start.length())
172  {
173  return (0 == s.compare(0, start.length(), start));
174  }
175  else
176  {
177  return false;
178  }
179  }
180 
187  template<typename T>
188  CORE_API bool is_digits(const T& s)
189  {
190  return std::all_of(s.begin(), s.end(), ::isdigit);
191  }
192 
199  template<typename T>
200  CORE_API bool is_integer(const T& s)
201  {
202  if (s.empty() || ((!isdigit(s[0])) && (s[0] != '-') && (s[0] != '+')))
203  {
204  return false;
205  }
206 
207  char* p;
208  strtol(s.c_str(), &p, 10);
209 
210  return (*p == 0);
211  }
212 
219  template<typename T>
220  CORE_API bool is_floating_point(const T& s)
221  {
222  std::stringstream ss(s.c_str());
223  float f;
224  ss >> f;
225  return (ss.eof() && !ss.fail());
226  }
227 
238  template<typename T>
239  CORE_API std::vector<T> split(const T& s, const char delim, bool obey_brackets = false)
240  {
241  std::vector<T> result;
242  T item = "";
243 
244  if (obey_brackets)
245  {
246  int bracket_level = 0;
247 
248  for (size_t i = 0; i < s.length(); ++i)
249  {
250  char c = s.at(i);
251  switch (c)
252  {
253  case '(':
254  case '{':
255  case '[':
256  ++bracket_level;
257  break;
258  case ')':
259  case '}':
260  case ']':
261  --bracket_level;
262  break;
263  default:
264  break;
265  }
266  if (bracket_level < 0)
267  {
268  bracket_level = 0;
269  }
270  if (c == delim)
271  {
272  // No constant expression, therefore not usable in switch case
273  if (bracket_level == 0)
274  {
275  result.push_back(item);
276  item = "";
277  }
278  else
279  {
280  item.push_back(c);
281  }
282  }
283  else
284  {
285  item.push_back(c);
286  }
287  }
288  if (!item.empty())
289  {
290  result.push_back(item);
291  }
292  }
293  else
294  {
295  std::stringstream ss(s);
296  while (std::getline(ss, item, delim))
297  {
298  result.push_back(item);
299  }
300  }
301  if (s.back() == delim)
302  {
303  result.push_back("");
304  }
305  return result;
306  }
307 
315  template<typename T>
316  CORE_API T ltrim(const T& s, const char* to_remove = " \t\r\n")
317  {
318  size_t start = s.find_first_not_of(to_remove);
319 
320  if (start != std::string::npos)
321  {
322  return s.substr(start, s.size() - start);
323  }
324  else
325  {
326  return "";
327  }
328  }
329 
337  template<typename T>
338  CORE_API T rtrim(const T& s, const char* to_remove = " \t\r\n")
339  {
340  size_t end = s.find_last_not_of(to_remove);
341 
342  if (end != std::string::npos)
343  {
344  return s.substr(0, end + 1);
345  }
346  else
347  {
348  return "";
349  }
350  }
351 
359  template<typename T>
360  CORE_API T trim(const T& s, const char* to_remove = " \t\r\n")
361  {
362  size_t start = s.find_first_not_of(to_remove);
363  size_t end = s.find_last_not_of(to_remove);
364 
365  if (start != T::npos)
366  {
367  return s.substr(start, end - start + 1);
368  }
369  else
370  {
371  return "";
372  }
373  }
374 
383  template<typename T>
384  CORE_API T replace(const T& str, const T& search, const T& replace)
385  {
386  auto s = str;
387  size_t pos = 0;
388 
389  if (search.empty())
390  {
391  return str;
392  }
393 
394  while ((pos = s.find(search, pos)) != T::npos)
395  {
396  s.replace(pos, search.length(), replace);
397  pos += replace.length();
398  }
399 
400  return s;
401  }
402 
413  template<typename Iterator, class Transform>
414  CORE_API std::string join(const std::string& joiner, const Iterator& begin, const Iterator& end, const Transform& transform)
415  {
416  std::stringstream ss;
417  bool first = true;
418  for (auto it = begin; it != end; ++it)
419  {
420  if (!first)
421  {
422  ss << joiner;
423  }
424  first = false;
425  ss << transform(*it);
426  }
427  return ss.str();
428  }
429 
439  template<typename T, class Transform>
440  CORE_API std::string join(const std::string& joiner, const T& items, const Transform& transform)
441  {
442  return join(joiner, items.begin(), items.end(), transform);
443  }
444 
452  template<typename T>
453  CORE_API std::string join(const std::string& joiner, const T& items)
454  {
455  return join(joiner, items.begin(), items.end(), [](const auto& v) { return v; });
456  }
457 
464  template<typename T>
465  CORE_API T to_upper(const T& s)
466  {
467  T result = s;
468  std::transform(result.begin(), result.end(), result.begin(), [](char c) { return std::toupper(c); });
469  return result;
470  }
471 
478  template<typename T>
479  CORE_API T to_lower(const T& s)
480  {
481  T result = s;
482  std::transform(result.begin(), result.end(), result.begin(), [](char c) { return std::tolower(c); });
483  return result;
484  }
485 
493  template<typename T>
494  CORE_API u32 num_of_occurrences(const T& s, const T& substr)
495  {
497  auto position = s.find(substr, 0);
498 
499  while (position != std::string::npos)
500  {
502  position = s.find(substr, position + 1);
503  }
504 
505  return num_of_occurrences;
506  }
507 
514  template<typename T, template<typename, typename...> class Container, typename... Args>
515  CORE_API inline std::vector<T> to_vector(const Container<T, Args...>& container)
516  {
517  return std::vector<T>(container.begin(), container.end());
518  }
519 
526  template<typename T, template<typename, typename...> class Container, typename... Args>
527  CORE_API inline std::set<T> to_set(const Container<T, Args...>& container)
528  {
529  return std::set<T>(container.begin(), container.end());
530  }
531 
540  template<typename T1, typename T2>
541  CORE_API bool is_subset(const T1& subset, const T2& superset)
542  {
543  for (const auto& element : subset)
544  {
545  if (std::find(std::begin(superset), std::end(superset), element) == std::end(superset))
546  {
547  return false; // Element not found in superset
548  }
549  }
550  return true; // All elements found; subset is indeed a subset of superset
551  }
552 
559  CORE_API bool file_exists(const std::string& filename);
560 
567  CORE_API bool folder_exists_and_is_accessible(const std::filesystem::path& path);
568 
576  CORE_API std::filesystem::path which(const std::string& name, const std::string& path = "");
577 
583  CORE_API std::filesystem::path get_binary_directory();
584 
593  CORE_API std::filesystem::path get_base_directory();
594 
601  CORE_API std::filesystem::path get_library_directory();
602 
609  CORE_API std::filesystem::path get_share_directory();
610 
617  CORE_API std::filesystem::path get_user_share_directory();
618 
625  CORE_API std::filesystem::path get_config_directory();
626 
633  CORE_API std::filesystem::path get_user_config_directory();
634 
642  CORE_API std::filesystem::path get_default_log_directory(std::filesystem::path source_file = "");
643 
650  CORE_API std::vector<std::filesystem::path> get_gate_library_directories();
651 
658  CORE_API std::vector<std::filesystem::path> get_plugin_directories();
659 
666  CORE_API std::filesystem::path get_first_directory_exists(std::vector<std::filesystem::path> path_hints);
667 
675  CORE_API std::filesystem::path get_file(std::string file_name, std::vector<std::filesystem::path> path_hints);
676 
684  CORE_API Result<std::filesystem::path> get_unique_temp_directory(const std::string& prefix = "", const u32 max_attempts = 5);
685 
691  CORE_API std::string get_open_source_licenses();
692 
697  {
698  public:
699  using iterator = std::filesystem::recursive_directory_iterator;
700 
706  RecursiveDirectoryRange(std::filesystem::path path) : p_(path)
707  {
708  }
709 
717  {
718  return std::filesystem::recursive_directory_iterator(p_);
719  }
720 
727  {
728  return std::filesystem::recursive_directory_iterator();
729  }
730 
731  private:
732  std::filesystem::path p_;
733  };
734 
739  {
740  public:
741  using iterator = std::filesystem::directory_iterator;
742 
748  DirectoryRange(std::filesystem::path path) : p_(path)
749  {
750  }
751 
760  {
761  return std::filesystem::directory_iterator(p_);
762  }
763 
770  {
771  return std::filesystem::directory_iterator();
772  }
773 
774  private:
775  std::filesystem::path p_;
776  };
777 
783  {
784  int h;
785  int s;
786  int v;
787 
788  Color(int _h = 0, int _s = 0, int _v = 0) : h(_h), s(_s), v(_v)
789  {
790  }
791 
792  std::string toString()
793  {
794  return "h=" + std::to_string(h) + " s=" + std::to_string(s) + " v=" + std::to_string(v);
795  }
796  };
797 
806  CORE_API Result<u64> wrapped_stoull(const std::string& s, const u32 base = 10);
807 
816  CORE_API Result<u32> wrapped_stoul(const std::string& s, const u32 base = 10);
817  } // namespace utils
818 } // namespace hal
#define CORE_API
Definition: arch_linux.h:28
DirectoryRange(std::filesystem::path path)
Definition: utils.h:748
std::filesystem::directory_iterator iterator
Definition: utils.h:741
std::filesystem::recursive_directory_iterator iterator
Definition: utils.h:699
RecursiveDirectoryRange(std::filesystem::path path)
Definition: utils.h:706
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:100
std::filesystem::path get_share_directory()
Definition: utils.cpp:149
T replace(const T &str, const T &search, const T &replace)
Definition: utils.h:384
T rtrim(const T &s, const char *to_remove=" \t\r\n")
Definition: utils.h:338
u64 clear_bit(const u64 value, const u64 index)
Definition: utils.h:124
bool is_digits(const T &s)
Definition: utils.h:188
std::filesystem::path get_library_directory()
Definition: utils.cpp:129
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:494
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:527
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:80
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:541
std::string join(const std::string &joiner, const Iterator &begin, const Iterator &end, const Transform &transform)
Definition: utils.h:414
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:169
std::string get_open_source_licenses()
Definition: utils.cpp:299
u64 set_bit(const u64 value, const u64 index)
Definition: utils.h:112
bool is_floating_point(const T &s)
Definition: utils.h:220
T ltrim(const T &s, const char *to_remove=" \t\r\n")
Definition: utils.h:316
bool ends_with(const T &s, const T &end)
Definition: utils.h:149
T to_upper(const T &s)
Definition: utils.h:465
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:515
T to_lower(const T &s)
Definition: utils.h:479
bool file_exists(const std::string &filename)
Definition: utils.cpp:31
bool unordered_vector_erase(std::vector< T > &vec, T element)
Definition: utils.h:60
std::filesystem::path get_user_share_directory()
Definition: utils.cpp:157
bool is_integer(const T &s)
Definition: utils.h:200
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:239
u64 toggle_bit(const u64 value, const u64 index)
Definition: utils.h:136
T trim(const T &s, const char *to_remove=" \t\r\n")
Definition: utils.h:360
Definition: defines.h:45
std::string name
Color(int _h=0, int _s=0, int _v=0)
Definition: utils.h:788
std::string toString()
Definition: utils.h:792