0.5.4
C++ to UML diagram generator based on Clang
Loading...
Searching...
No Matches
Classes | Functions | Variables
clanguml::util Namespace Reference

Classes

class  query_driver_output_extractor
 Executed compiler frontend and extract default system paths. More...
 
class  thread_pool_executor
 Simple thread pool executor for parallelizing diagram generation. More...
 

Functions

std::string get_process_output (const std::string &command)
 Execute a shell command and return console output as string.
 
void check_process_output (const std::string &command)
 Execute command shell and throw exception if command fails.
 
std::string get_env (const std::string &name)
 Get value of an environment variable.
 
bool is_git_repository ()
 Check if $PWD is in a Git repository.
 
std::string run_git_command (const std::string &cmd, const std::string &env_override)
 
std::string get_git_branch ()
 Get current Git branch.
 
std::string get_git_revision ()
 Get current Git revision.
 
std::string get_git_commit ()
 Get current Git commit.
 
std::string get_git_toplevel_dir ()
 Get path to the top level Git directory.
 
std::string get_os_name ()
 Get descriptive name of the current operating system.
 
std::string ltrim (const std::string &s)
 Left trim a string.
 
std::string rtrim (const std::string &s)
 Right trim a string.
 
std::string trim_typename (const std::string &s)
 Remove typename prefix from a string if exists.
 
std::string trim (const std::string &s)
 Trim a string.
 
std::vector< std::string > split (std::string str, std::string_view delimiter, bool skip_empty=true)
 Split a string using delimiter.
 
std::vector< std::string > split_isspace (std::string str)
 
std::string join (const std::vector< std::string > &toks, std::string_view delimiter)
 Join toks into string using delimiter as separator.
 
std::string abbreviate (const std::string &s, unsigned int max_length)
 Abbreviate string to max_length, and replace last 3 characters with ellipsis.
 
bool find_element_alias (const std::string &input, std::tuple< std::string, size_t, size_t > &result)
 Find element alias in Puml note.
 
bool replace_all (std::string &input, const std::string &pattern, const std::string &replace_with)
 Find and replace in string.
 
template<>
bool starts_with (const std::filesystem::path &path, const std::filesystem::path &prefix)
 
template<>
bool starts_with (const std::string &s, const std::string &prefix)
 
template<>
bool ends_with (const std::string &value, const std::string &suffix)
 
std::size_t hash_seed (std::size_t seed)
 Generate a hash seed.
 
std::string path_to_url (const std::filesystem::path &p)
 Convert filesystem path to url path.
 
std::filesystem::path ensure_path_is_absolute (const std::filesystem::path &p, const std::filesystem::path &root=std::filesystem::current_path())
 Ensure path is absolute.
 
bool is_relative_to (const std::filesystem::path &parent, const std::filesystem::path &child)
 Check if a given path is relative to another path.
 
std::string format_message_comment (const std::string &comment, unsigned width)
 
std::filesystem::path normalize_relative_path (const std::filesystem::path &path)
 
bool is_subpath (const std::filesystem::path &path, const std::filesystem::path &base)
 
std::optional< std::pair< std::string, std::string > > find_entry_by_path_prefix (const std::map< std::string, std::string > &m, const std::string &path)
 
template<typename T , typename S >
std::unique_ptr< T > unique_pointer_cast (std::unique_ptr< S > &&p) noexcept
 
template<typename T , typename F >
void erase_if (std::vector< T > &v, F &&f)
 Remove and erase elements from a vector.
 
template<typename... Args>
std::string join (std::string_view delimiter, Args... args)
 Join args into string using delimiter as separator.
 
template<typename T >
void append (std::vector< T > &l, const std::vector< T > &r)
 Appends a vector to a vector.
 
template<typename T >
bool starts_with (const T &col, const T &prefix)
 Checks if collection starts with a prefix.
 
template<>
bool starts_with (const std::filesystem::path &path, const std::filesystem::path &prefix)
 
template<>
bool starts_with (const std::string &s, const std::string &prefix)
 
template<typename T >
bool ends_with (const T &value, const T &suffix)
 
template<>
bool ends_with (const std::string &value, const std::string &suffix)
 
template<typename T >
bool ends_with (const std::vector< T > &col, const std::vector< T > &suffix)
 
template<typename T >
void remove_prefix (std::vector< T > &col, const std::vector< T > &prefix)
 Removes prefix sequence of elements from the beginning of col.
 
template<typename T , typename E >
bool contains (const T &container, const E &element)
 
template<typename T , typename F >
void for_each (const T &collection, F &&func)
 
template<typename T , typename C , typename F >
void for_each_if (const T &collection, C &&cond, F &&func)
 
template<typename R , typename T , typename F >
std::vector< R > map (const std::vector< T > &in, F &&f)
 
template<typename T , typename F , typename FElse >
void if_not_null (const T *pointer, F &&func, FElse &&func_else)
 
template<typename T , typename F >
void if_not_null (const T *pointer, F &&func)
 
template<typename F , typename FElse >
void _if (const bool condition, F &&func, FElse &&func_else)
 
template<typename F >
void _if (const bool condition, F &&func)
 

Variables

static const auto WHITESPACE = " \n\r\t\f\v"
 
constexpr unsigned kDefaultMessageCommentWidth {25U}
 

Function Documentation

◆ _if() [1/2]

template<typename F >
void clanguml::util::_if ( const bool  condition,
F &&  func 
)

Definition at line 414 of file util.h.

415{
416 _if(condition, std::forward<F>(func), []() {});
417}

◆ _if() [2/2]

template<typename F , typename FElse >
void clanguml::util::_if ( const bool  condition,
F &&  func,
FElse &&  func_else 
)

Definition at line 404 of file util.h.

405{
406 if (condition) {
407 std::forward<F>(func)();
408 }
409 else {
410 std::forward<FElse>(func_else)();
411 }
412}

◆ abbreviate()

std::string clanguml::util::abbreviate ( const std::string &  s,
unsigned int  max_length 
)

Abbreviate string to max_length, and replace last 3 characters with ellipsis.

Parameters
sInput string
max_lengthMaximum length
Returns
Abbreviated string

Definition at line 315 of file util.cc.

316{
317 if (s.size() <= max_length)
318 return s;
319
320 auto res = s;
321
322 res.resize(max_length);
323
324 if (res.size() > 3) {
325 res.replace(res.size() - 3, 3, 3, '.');
326 }
327
328 return res;
329}

◆ append()

template<typename T >
void clanguml::util::append ( std::vector< T > &  l,
const std::vector< T > &  r 
)

Appends a vector to a vector.

Template Parameters
T
Parameters
l
r

Definition at line 277 of file util.h.

278{
279 l.insert(l.end(), r.begin(), r.end());
280}

◆ check_process_output()

void clanguml::util::check_process_output ( const std::string &  command)

Execute command shell and throw exception if command fails.

Parameters
commandCommand to execute

Definition at line 97 of file util.cc.

98{
99 constexpr size_t kBufferSize{1024};
100 std::array<char, kBufferSize> buffer{};
101 int result{EXIT_FAILURE};
102 std::string output;
103 pipe_t pipe{command, result};
104
105 if (!pipe) {
106 throw std::runtime_error("popen() failed!");
107 }
108
109 while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
110 output += buffer.data();
111 }
112
113 pipe.reset();
114
115 if (result != EXIT_SUCCESS) {
116 throw std::runtime_error(
117 fmt::format("External command '{}' failed: {}", command, output));
118 }
119}

◆ contains()

template<typename T , typename E >
bool clanguml::util::contains ( const T &  container,
const E &  element 
)

Returns true if element exists in container.

Template Parameters
T
E
Parameters
container
element
Returns

Definition at line 345 of file util.h.

346{
347 if constexpr (std::is_pointer_v<E>) {
348 return std::find_if(container.begin(), container.end(),
349 [&element](const auto &e) { return *e == *element; }) !=
350 container.end();
351 }
352 else if constexpr (std::is_same_v<std::remove_cv_t<T>, std::string>) {
353 return container.find(element) != std::string::npos;
354 }
355 else {
356 return std::find(container.begin(), container.end(), element) !=
357 container.end();
358 }
359}

◆ ends_with() [1/4]

template<>
bool clanguml::util::ends_with ( const std::string &  value,
const std::string &  suffix 
)

Definition at line 397 of file util.cc.

398{
399 if (suffix.size() > value.size())
400 return false;
401 return std::equal(suffix.rbegin(), suffix.rend(), value.rbegin());
402}

◆ ends_with() [2/4]

template<>
bool clanguml::util::ends_with ( const std::string &  value,
const std::string &  suffix 
)

Definition at line 397 of file util.cc.

398{
399 if (suffix.size() > value.size())
400 return false;
401 return std::equal(suffix.rbegin(), suffix.rend(), value.rbegin());
402}

◆ ends_with() [3/4]

template<typename T >
bool clanguml::util::ends_with ( const std::vector< T > &  col,
const std::vector< T > &  suffix 
)

Definition at line 310 of file util.h.

311{
312 if (suffix.size() > col.size())
313 return false;
314
315 return std::vector<std::string>(suffix.rbegin(), suffix.rend()) ==
316 std::vector<std::string>(col.rbegin(), col.rbegin() + suffix.size());
317}

◆ ends_with() [4/4]

template<typename T >
bool clanguml::util::ends_with ( const T &  value,
const T &  suffix 
)

◆ ensure_path_is_absolute()

std::filesystem::path clanguml::util::ensure_path_is_absolute ( const std::filesystem::path &  p,
const std::filesystem::path &  root = std::filesystem::current_path() 
)

Ensure path is absolute.

If path is absolute, return the p. If path is not absolute, make it absolute with respect to root directory.

Parameters
pPath to modify
rootRoot against which the path should be made absolute
Returns
Absolute path

Definition at line 441 of file util.cc.

443{
444 if (p.is_absolute())
445 return p;
446
447 auto result = root / p;
448 result = result.lexically_normal();
449 result.make_preferred();
450
451 return result;
452}

◆ erase_if()

template<typename T , typename F >
void clanguml::util::erase_if ( std::vector< T > &  v,
F &&  f 
)

Remove and erase elements from a vector.

Template Parameters
TElement type
FFunctor type
Parameters
vVector to remove elements from
fFunctor to decide which elements to remove

Definition at line 202 of file util.h.

203{
204 v.erase(std::remove_if(v.begin(), v.end(), std::forward<F>(f)), v.end());
205}

◆ find_element_alias()

bool clanguml::util::find_element_alias ( const std::string &  input,
std::tuple< std::string, size_t, size_t > &  result 
)

Find element alias in Puml note.

Finds aliases of the form (entity_name) in the Puml notes or directives. The match, if any, is returned in the result tuple: (entity_name, offset, length)

Returns
True if match was found

Definition at line 331 of file util.cc.

333{
334 const std::regex alias_regex(R"((@A\‍([^\).]+\)))");
335
336 auto alias_it =
337 std::sregex_iterator(input.begin(), input.end(), alias_regex);
338 auto end_it = std::sregex_iterator();
339
340 if (alias_it == end_it)
341 return false;
342
343 const std::smatch &match = *alias_it;
344 const std::string alias = match.str().substr(3, match.str().size() - 4);
345
346 std::get<0>(result) = alias;
347 std::get<1>(result) = match.position();
348 std::get<2>(result) = match.length();
349
350 return true;
351}

◆ find_entry_by_path_prefix()

std::optional< std::pair< std::string, std::string > > clanguml::util::find_entry_by_path_prefix ( const std::map< std::string, std::string > &  m,
const std::string &  path 
)

Definition at line 534 of file util.cc.

536{
537 if (m.empty())
538 return {};
539
540 // Extract keys and sort them by length in descending order
541 std::vector<std::string> keys;
542 keys.reserve(m.size());
543 for (const auto &[key, pattern] : m) {
544 keys.push_back(key);
545 }
546
547 std::sort(keys.begin(), keys.end(),
548 [](const std::string &a, const std::string &b) {
549 return a.size() > b.size();
550 });
551
552 std::filesystem::path file_path{path};
553
554 for (const auto &key : keys) {
555 const auto &pattern = m.at(key);
556 std::filesystem::path key_path{key};
557
558 if (is_subpath(file_path, key_path)) {
559 return {{key, pattern}};
560 }
561 }
562
563 if ((path.empty() || file_path.is_relative() || path == ".") &&
564 m.count(".") > 0) {
565 return {{".", m.at(".")}};
566 }
567
568 return {};
569}

◆ for_each()

template<typename T , typename F >
void clanguml::util::for_each ( const T &  collection,
F &&  func 
)

Definition at line 361 of file util.h.

362{
363 std::for_each(std::begin(collection), std::end(collection),
364 std::forward<decltype(func)>(func));
365}

◆ for_each_if()

template<typename T , typename C , typename F >
void clanguml::util::for_each_if ( const T &  collection,
C &&  cond,
F &&  func 
)

Definition at line 368 of file util.h.

369{
370 std::for_each(std::begin(collection), std::end(collection),
371 [cond = std::forward<decltype(cond)>(cond),
372 func = std::forward<decltype(func)>(func)](const auto &e) {
373 if (cond(e))
374 func(e);
375 });
376}

◆ format_message_comment()

std::string clanguml::util::format_message_comment ( const std::string &  comment,
unsigned  width 
)

Definition at line 463 of file util.cc.

464{
465 if (width == 0)
466 return comment;
467
468 std::string result;
469
470 if (comment.empty())
471 return result;
472
473 auto tokens = split_isspace(comment);
474
475 if (tokens.empty())
476 return result;
477
478 unsigned current_line_length{0};
479 for (const auto &token : tokens) {
480 if (current_line_length < width) {
481 result += token;
482 result += ' ';
483 }
484 else {
485 result.back() = '\n';
486 current_line_length = 0;
487 result += token;
488 result += ' ';
489 }
490
491 current_line_length += token.size() + 1;
492 }
493
494 result.pop_back();
495
496 return result;
497}

◆ get_env()

std::string clanguml::util::get_env ( const std::string &  name)

Get value of an environment variable.

Parameters
nameName of the environment variable
Returns
Value of the environment variable, or empty if it doesn't exist

Definition at line 121 of file util.cc.

122{
123#if defined(__linux) || defined(__unix)
124 const char *value = std::getenv(name.c_str()); // NOLINT
125
126 if (value == nullptr)
127 return {};
128
129 return std::string{value};
130#elif defined(WINDOWS) || defined(_WIN32) || defined(WIN32)
131 static constexpr auto kMaxEnvLength = 2096U;
132 static char value[kMaxEnvLength];
133 const DWORD ret =
134 GetEnvironmentVariableA(name.c_str(), value, kMaxEnvLength);
135 if (ret == 0 || ret > kMaxEnvLength)
136 return {};
137 else
138 return value;
139#else
140 return {};
141#endif
142}

◆ get_git_branch()

std::string clanguml::util::get_git_branch ( )

Get current Git branch.

Returns
Name of the current Git branch

Definition at line 183 of file util.cc.

184{
185 return run_git_command(
186 "git rev-parse --abbrev-ref HEAD", "CLANGUML_GIT_BRANCH");
187}

◆ get_git_commit()

std::string clanguml::util::get_git_commit ( )

Get current Git commit.

Returns
Latest Git commit hash

Definition at line 195 of file util.cc.

196{
197 return run_git_command("git rev-parse HEAD", "CLANGUML_GIT_COMMIT");
198}

◆ get_git_revision()

std::string clanguml::util::get_git_revision ( )

Get current Git revision.

Generates a Git revision tag using git describe --tags --always command

Returns
Current repository Git revision

Definition at line 189 of file util.cc.

190{
191 return run_git_command(
192 "git describe --tags --always", "CLANGUML_GIT_REVISION");
193}

◆ get_git_toplevel_dir()

std::string clanguml::util::get_git_toplevel_dir ( )

Get path to the top level Git directory.

Returns
Absolut path to the nearest directory containing .git folder

Definition at line 200 of file util.cc.

201{
202 return run_git_command(
203 "git rev-parse --show-toplevel", "CLANGUML_GIT_TOPLEVEL_DIR");
204}

◆ get_os_name()

std::string clanguml::util::get_os_name ( )

Get descriptive name of the current operating system.

Returns
Name of the operating system

Definition at line 206 of file util.cc.

207{
208#ifdef _WIN32
209 return "Windows, 32-bit";
210#elif _WIN64
211 return "Windows, 64-bit";
212#elif __has_include(<sys/utsname.h>)
213 struct utsname utsn; // NOLINT
214 uname(&utsn);
215 return fmt::format("{} {} {}", utsn.sysname, utsn.machine, utsn.release);
216#elif __linux__
217 return "Linux";
218#elif __APPLE__ || __MACH__
219 return "macOS";
220#elif __FreeBSD__
221 return "FreeBSD";
222#elif __unix__ || __unix
223 return "Unix";
224#else
225 return "Unknown";
226#endif
227}

◆ get_process_output()

std::string clanguml::util::get_process_output ( const std::string &  command)

Execute a shell command and return console output as string.

Parameters
commandShell command to execute
Returns
Console output of the command

Definition at line 70 of file util.cc.

71{
72 constexpr size_t kBufferSize{1024};
73 std::array<char, kBufferSize> buffer{};
74 std::string output;
75 int result{EXIT_FAILURE};
76
77 pipe_t pipe{command, result};
78
79 if (!pipe) {
80 throw std::runtime_error("popen() failed!");
81 }
82
83 while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
84 output += buffer.data();
85 }
86
87 pipe.reset();
88
89 if (result != EXIT_SUCCESS) {
90 throw std::runtime_error(
91 fmt::format("External command '{}' failed: {}", command, output));
92 }
93
94 return output;
95}

◆ hash_seed()

std::size_t clanguml::util::hash_seed ( std::size_t  seed)

Generate a hash seed.

Parameters
seedInitial seed.
Returns
Hash seed.

Definition at line 404 of file util.cc.

405{
406 constexpr auto kSeedStart{0x6a3712b5};
407 constexpr auto kSeedShiftFirst{6};
408 constexpr auto kSeedShiftSecond{2};
409
410 return kSeedStart + (seed << kSeedShiftFirst) + (seed >> kSeedShiftSecond);
411}

◆ if_not_null() [1/2]

template<typename T , typename F >
void clanguml::util::if_not_null ( const T *  pointer,
F &&  func 
)

Definition at line 398 of file util.h.

399{
400 if_not_null(pointer, std::forward<F>(func), []() {});
401}

◆ if_not_null() [2/2]

template<typename T , typename F , typename FElse >
void clanguml::util::if_not_null ( const T *  pointer,
F &&  func,
FElse &&  func_else 
)

Definition at line 388 of file util.h.

389{
390 if (pointer != nullptr) {
391 std::forward<F>(func)(pointer);
392 }
393 else {
394 std::forward<FElse>(func_else)();
395 }
396}

◆ is_git_repository()

bool clanguml::util::is_git_repository ( )

Check if $PWD is in a Git repository.

This can be overridden by exporting CLANGUML_GIT_COMMIT environment variable.

Returns
True, if the current directory is in a Git repository

Definition at line 144 of file util.cc.

145{
146 const auto env = get_env("CLANGUML_GIT_COMMIT");
147
148 if (!env.empty())
149 return true;
150
151 std::string output;
152
153 try {
154 output = get_process_output("git rev-parse --git-dir");
155 }
156 catch (std::runtime_error &e) {
157 return false;
158 }
159
160 return contains(trim(output), ".git");
161}

◆ is_relative_to()

bool clanguml::util::is_relative_to ( const std::filesystem::path &  parent,
const std::filesystem::path &  child 
)

Check if a given path is relative to another path.

Parameters
parentThe path to be checked for relativity.
rightThe base path against which the relativity is checked.
Returns
True if the child path is relative to the parent path, false otherwise.

Definition at line 454 of file util.cc.

456{
457 if (child.has_root_directory() != parent.has_root_directory())
458 return false;
459
460 return starts_with(weakly_canonical(child), weakly_canonical(parent));
461}

◆ is_subpath()

bool clanguml::util::is_subpath ( const std::filesystem::path &  path,
const std::filesystem::path &  base 
)

Definition at line 516 of file util.cc.

518{
519 if (path.empty())
520 return false;
521
522 auto normalized_path = normalize_relative_path(path);
523 auto normalized_base = normalize_relative_path(base);
524
525 if (normalized_path == normalized_base)
526 return true;
527
528 auto rel = std::filesystem::relative(normalized_path, normalized_base);
529
530 std::string rel_str = rel.string();
531 return !rel_str.empty() && rel.native()[0] != '.';
532}

◆ join() [1/2]

std::string clanguml::util::join ( const std::vector< std::string > &  toks,
std::string_view  delimiter 
)

Join toks into string using delimiter as separator.

Parameters
toksElements to join into string
delimiterSeparator to use to join elements
Returns
Concatenated elements into one string

Definition at line 309 of file util.cc.

311{
312 return fmt::format("{}", fmt::join(toks, delimiter));
313}

◆ join() [2/2]

template<typename... Args>
std::string clanguml::util::join ( std::string_view  delimiter,
Args...  args 
)

Join args into string using delimiter as separator.

Template Parameters
ArgsElement type
Parameters
delimiterSeparator to use to join elements
argsElements to join into string
Returns
Arguments concatenated into one string

Definition at line 226 of file util.h.

227{
228 std::vector<std::string> coll{args...};
229
230 erase_if(coll, [](const auto &s) {
231 return s.find_first_not_of(" \t") == std::string::npos;
232 });
233
234 return fmt::format("{}", fmt::join(coll, delimiter));
235}

◆ ltrim()

std::string clanguml::util::ltrim ( const std::string &  s)

Left trim a string.

Parameters
sInput string
Returns
Left trimmed string

Definition at line 229 of file util.cc.

230{
231 const size_t start = s.find_first_not_of(WHITESPACE);
232 return (start == std::string::npos) ? "" : s.substr(start);
233}

◆ map()

template<typename R , typename T , typename F >
std::vector< R > clanguml::util::map ( const std::vector< T > &  in,
F &&  f 
)

Definition at line 379 of file util.h.

380{
381 std::vector<R> out;
382 std::transform(
383 in.cbegin(), in.cend(), std::back_inserter(out), std::forward<F>(f));
384 return out;
385}

◆ normalize_relative_path()

std::filesystem::path clanguml::util::normalize_relative_path ( const std::filesystem::path &  path)

Definition at line 499 of file util.cc.

500{
501 if (path.is_absolute())
502 return path;
503
504 std::filesystem::path result;
505
506 for (const auto &part : path) {
507 if (part == ".") {
508 continue;
509 }
510 result /= part;
511 }
512
513 return result;
514}

◆ path_to_url()

std::string clanguml::util::path_to_url ( const std::filesystem::path &  p)

Convert filesystem path to url path.

The purpose of this function is to make sure that a path can be used in a URL, e.g. it's separators are POSIX-style.

Parameters
pPath to convert
Returns
String representation of the path in URL format

Definition at line 413 of file util.cc.

414{
415 std::vector<std::string> path_tokens;
416 auto it = p.begin();
417 if (p.has_root_directory()) {
418#ifdef _MSC_VER
419 // On Windows convert the root path using its drive letter, e.g.:
420 // C:\A\B\include.h -> /c/A/B/include.h
421 if (p.root_name().string().size() > 1) {
422 if (p.is_absolute()) {
423 path_tokens.push_back(std::string{
424 std::tolower(p.root_name().string().at(0), std::locale())});
425 }
426 it++;
427 }
428#endif
429 it++;
430 }
431
432 for (; it != p.end(); it++)
433 path_tokens.push_back(it->string());
434
435 if (p.has_root_directory())
436 return fmt::format("/{}", fmt::join(path_tokens, "/"));
437
438 return fmt::format("{}", fmt::join(path_tokens, "/"));
439}

◆ remove_prefix()

template<typename T >
void clanguml::util::remove_prefix ( std::vector< T > &  col,
const std::vector< T > &  prefix 
)

Removes prefix sequence of elements from the beginning of col.

Template Parameters
T
Parameters
col
prefix

Definition at line 327 of file util.h.

328{
329 if (!starts_with(col, prefix))
330 return;
331
332 col = std::vector<T>(col.begin() + prefix.size(), col.end());
333}

◆ replace_all()

bool clanguml::util::replace_all ( std::string &  input,
const std::string &  pattern,
const std::string &  replace_with 
)

Find and replace in string.

Replaces all occurences of pattern with replace_with in input string.

Returns
True if at least on replacement was made

Definition at line 353 of file util.cc.

355{
356 bool replaced{false};
357
358 auto pos = input.find(pattern);
359 while (pos < input.size()) {
360 input.replace(pos, pattern.size(), replace_with);
361 pos = input.find(pattern, pos + replace_with.size());
362 replaced = true;
363 }
364
365 return replaced;
366}

◆ rtrim()

std::string clanguml::util::rtrim ( const std::string &  s)

Right trim a string.

Parameters
sInput string
Returns
Right trimmed string

Definition at line 235 of file util.cc.

236{
237 const size_t end = s.find_last_not_of(WHITESPACE);
238 return (end == std::string::npos) ? "" : s.substr(0, end + 1);
239}

◆ run_git_command()

std::string clanguml::util::run_git_command ( const std::string &  cmd,
const std::string &  env_override 
)

Definition at line 163 of file util.cc.

165{
166 auto env = get_env(env_override);
167
168 if (!env.empty())
169 return env;
170
171 std::string output;
172
173 try {
174 output = get_process_output(cmd);
175 }
176 catch (std::runtime_error &e) {
177 return {};
178 }
179
180 return trim(output);
181}

◆ split()

std::vector< std::string > clanguml::util::split ( std::string  str,
std::string_view  delimiter,
bool  skip_empty = true 
)

Split a string using delimiter.

Basic string split function, because C++ stdlib does not have one. In case the string does not contain the delimiter, the original string is returned as the only element of the vector.

Parameters
strString to split
delimiterDelimiter string
skip_emptySkip empty toks between delimiters if true
Returns
Vector of string tokens.

Definition at line 252 of file util.cc.

254{
255 std::vector<std::string> result;
256
257 if (!contains(str, delimiter)) {
258 if (!str.empty())
259 result.push_back(std::move(str));
260 else if (!skip_empty)
261 result.push_back(std::move(str));
262 }
263 else
264 while (static_cast<unsigned int>(!str.empty()) != 0U) {
265 auto index = str.find(delimiter);
266 if (index != std::string::npos) {
267 auto tok = str.substr(0, index);
268 if (!tok.empty())
269 result.push_back(std::move(tok));
270 else if (!skip_empty)
271 result.push_back(std::move(tok));
272
273 str = str.substr(index + delimiter.size());
274 }
275 else {
276 if (!str.empty())
277 result.push_back(std::move(str));
278 else if (!skip_empty)
279 result.push_back(std::move(str));
280 str = "";
281 }
282 }
283
284 return result;
285}

◆ split_isspace()

std::vector< std::string > clanguml::util::split_isspace ( std::string  str)

Definition at line 287 of file util.cc.

288{
289 std::vector<std::string> result;
290
291 while (static_cast<unsigned int>(!str.empty()) != 0U) {
292 auto index = std::find_if(
293 str.begin(), str.end(), [](auto c) { return std::isspace(c); });
294 if (index != str.end()) {
295 auto tok = str.substr(0, std::distance(str.begin(), index));
296 if (!tok.empty())
297 result.push_back(std::move(tok));
298 str = str.substr(std::distance(str.begin(), index) + 1);
299 }
300 else {
301 if (!str.empty())
302 result.push_back(str);
303 str = "";
304 }
305 }
306 return result;
307}

◆ starts_with() [1/5]

template<>
bool clanguml::util::starts_with ( const std::filesystem::path &  path,
const std::filesystem::path &  prefix 
)

Definition at line 369 of file util.cc.

371{
372 auto normal_path = std::filesystem::path();
373 auto normal_prefix = std::filesystem::path();
374
375 for (const auto &element : path.lexically_normal()) {
376 if (!element.empty())
377 normal_path /= element;
378 }
379
380 for (const auto &element : prefix.lexically_normal()) {
381 if (!element.empty())
382 normal_prefix /= element;
383 }
384
385 auto normal_path_str = normal_path.string();
386 auto normal_prefix_str = normal_prefix.string();
387 return std::search(normal_path_str.begin(), normal_path_str.end(),
388 normal_prefix_str.begin(),
389 normal_prefix_str.end()) == normal_path_str.begin();
390}

◆ starts_with() [2/5]

template<>
bool clanguml::util::starts_with ( const std::filesystem::path &  path,
const std::filesystem::path &  prefix 
)

Definition at line 369 of file util.cc.

371{
372 auto normal_path = std::filesystem::path();
373 auto normal_prefix = std::filesystem::path();
374
375 for (const auto &element : path.lexically_normal()) {
376 if (!element.empty())
377 normal_path /= element;
378 }
379
380 for (const auto &element : prefix.lexically_normal()) {
381 if (!element.empty())
382 normal_prefix /= element;
383 }
384
385 auto normal_path_str = normal_path.string();
386 auto normal_prefix_str = normal_prefix.string();
387 return std::search(normal_path_str.begin(), normal_path_str.end(),
388 normal_prefix_str.begin(),
389 normal_prefix_str.end()) == normal_path_str.begin();
390}

◆ starts_with() [3/5]

template<>
bool clanguml::util::starts_with ( const std::string &  s,
const std::string &  prefix 
)

Definition at line 392 of file util.cc.

393{
394 return s.rfind(prefix, 0) == 0;
395}

◆ starts_with() [4/5]

template<>
bool clanguml::util::starts_with ( const std::string &  s,
const std::string &  prefix 
)

Definition at line 392 of file util.cc.

393{
394 return s.rfind(prefix, 0) == 0;
395}

◆ starts_with() [5/5]

template<typename T >
bool clanguml::util::starts_with ( const T &  col,
const T &  prefix 
)

Checks if collection starts with a prefix.

Template Parameters
Te.g. std::vector<std::string>
Parameters
colCollection to be checked against prefix
prefixContainer, which specifies the prefix
Returns
true if first prefix.size() elements of col are equal to prefix

Definition at line 290 of file util.h.

291{
292 if (prefix.size() > col.size())
293 return false;
294
295 return std::search(col.begin(), col.end(), prefix.begin(), prefix.end()) ==
296 col.begin();
297}

◆ trim()

std::string clanguml::util::trim ( const std::string &  s)

Trim a string.

Parameters
sInput string
Returns
Trimmed string

Definition at line 250 of file util.cc.

250{ return rtrim(ltrim(s)); }

◆ trim_typename()

std::string clanguml::util::trim_typename ( const std::string &  s)

Remove typename prefix from a string if exists.

Parameters
sInput string
Returns
String without typename prefix

Definition at line 241 of file util.cc.

242{
243 auto res = trim(s);
244 if (res.find("typename ") == 0)
245 return res.substr(strlen("typename "));
246
247 return res;
248}

◆ unique_pointer_cast()

template<typename T , typename S >
std::unique_ptr< T > clanguml::util::unique_pointer_cast ( std::unique_ptr< S > &&  p)
noexcept

Definition at line 166 of file util.h.

167{
168 if (T *const converted = dynamic_cast<T *>(p.get())) {
169 std::move(p).release(); // NOLINT
170 return std::unique_ptr<T>{converted};
171 }
172
173 return {};
174}

Variable Documentation

◆ kDefaultMessageCommentWidth

constexpr unsigned clanguml::util::kDefaultMessageCommentWidth {25U}
constexpr

Definition at line 62 of file util.h.

◆ WHITESPACE

const auto clanguml::util::WHITESPACE = " \n\r\t\f\v"
static

Definition at line 29 of file util.cc.