https://mooseframework.inl.gov
MooseUtils.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 // MOOSE includes
11 #include "MooseUtils.h"
12 #include "MooseError.h"
13 #include "MaterialProperty.h"
14 #include "MultiMooseEnum.h"
15 #include "InputParameters.h"
16 #include "ExecFlagEnum.h"
17 #include "InfixIterator.h"
18 #include "Registry.h"
19 #include "MortarConstraintBase.h"
20 #include "MortarNodalAuxKernel.h"
21 #include "ExecFlagRegistry.h"
22 #include "RestartableDataReader.h"
23 
24 #include "libmesh/utility.h"
25 #include "libmesh/elem.h"
26 
27 // External includes
28 #include "pcrecpp.h"
29 #include "tinydir.h"
30 
31 // C++ includes
32 #include <iostream>
33 #include <fstream>
34 #include <istream>
35 #include <iterator>
36 #include <filesystem>
37 #include <ctime>
38 #include <cstdlib>
39 #include <regex>
40 
41 // System includes
42 #include <sys/stat.h>
43 #include <numeric>
44 #include <unistd.h>
45 
46 #include "petscsys.h"
47 
48 #ifdef __WIN32__
49 #include <windows.h>
50 #include <winbase.h>
51 #include <fileapi.h>
52 #else
53 #include <sys/ioctl.h>
54 #endif
55 
56 namespace MooseUtils
57 {
58 std::filesystem::path
59 pathjoin(const std::filesystem::path & p)
60 {
61  return p;
62 }
63 
64 std::string
66 {
67  auto build_loc = pathjoin(Moose::getExecutablePath(), "run_tests");
68  if (pathExists(build_loc) && checkFileReadable(build_loc))
69  return build_loc;
70  // TODO: maybe no path prefix - just moose_test_runner here?
71  return pathjoin(Moose::getExecutablePath(), "moose_test_runner");
72 }
73 
74 std::string
76 {
77  std::string path = ".";
78  for (int i = 0; i < 5; i++)
79  {
80  auto testroot = pathjoin(path, "testroot");
81  if (pathExists(testroot) && checkFileReadable(testroot))
82  return testroot;
83  path += "/..";
84  }
85  return "";
86 }
87 
88 bool
89 parsesToReal(const std::string & input)
90 {
91  std::istringstream ss(input);
92  Real real_value;
93  if (ss >> real_value && ss.eof())
94  return true;
95  return false;
96 }
97 
98 std::string
99 installedInputsDir(const std::string & app_name,
100  const std::string & dir_name,
101  const std::string & extra_error_msg)
102 {
103  // See moose.mk for a detailed explanation of the assumed installed application
104  // layout. Installed inputs are expected to be installed in "share/<app_name>/<folder>".
105  // The binary, which has a defined location will be in "bin", a peer directory to "share".
106  std::string installed_path =
107  pathjoin(Moose::getExecutablePath(), "..", "share", app_name, dir_name);
108 
109  auto test_root = pathjoin(installed_path, "testroot");
110  if (!pathExists(installed_path))
111  mooseError("Couldn't locate any installed inputs to copy in path: ",
112  installed_path,
113  '\n',
114  extra_error_msg);
115 
116  checkFileReadable(test_root);
117  return installed_path;
118 }
119 
120 std::string
121 docsDir(const std::string & app_name)
122 {
123  // See moose.mk for a detailed explanation of the assumed installed application
124  // layout. Installed docs are expected to be installed in "share/<app_name>/doc".
125  // The binary, which has a defined location will be in "bin", a peer directory to "share".
126  std::string installed_path = pathjoin(Moose::getExecutablePath(), "..", "share", app_name, "doc");
127 
128  auto docfile = pathjoin(installed_path, "css", "moose.css");
129  if (pathExists(docfile) && checkFileReadable(docfile))
130  return installed_path;
131  return "";
132 }
133 
134 std::string
135 mooseDocsURL(const std::string & path)
136 {
137  return "https://mooseframework.inl.gov/" + path;
138 }
139 
140 std::string
141 replaceAll(std::string str, const std::string & from, const std::string & to)
142 {
143  size_t start_pos = 0;
144  while ((start_pos = str.find(from, start_pos)) != std::string::npos)
145  {
146  str.replace(start_pos, from.length(), to);
147  start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
148  }
149  return str;
150 }
151 
152 std::string
153 convertLatestCheckpoint(std::string orig)
154 {
155  auto slash_pos = orig.find_last_of("/");
156  auto path = orig.substr(0, slash_pos);
157  auto file = orig.substr(slash_pos + 1);
158  if (file != "LATEST")
159  return orig;
160 
162 
163  if (converted.empty())
164  mooseError("Unable to find suitable recovery file!");
165 
166  return converted;
167 }
168 
169 // this implementation is copied from
170 // https://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#C.2B.2B
171 int
172 levenshteinDist(const std::string & s1, const std::string & s2)
173 {
174  // To change the type this function manipulates and returns, change
175  // the return type and the types of the two variables below.
176  auto s1len = s1.size();
177  auto s2len = s2.size();
178 
179  auto column_start = (decltype(s1len))1;
180 
181  auto column = new decltype(s1len)[s1len + 1];
182  std::iota(column + column_start, column + s1len + 1, column_start);
183 
184  for (auto x = column_start; x <= s2len; x++)
185  {
186  column[0] = x;
187  auto last_diagonal = x - column_start;
188  for (auto y = column_start; y <= s1len; y++)
189  {
190  auto old_diagonal = column[y];
191  auto possibilities = {
192  column[y] + 1, column[y - 1] + 1, last_diagonal + (s1[y - 1] == s2[x - 1] ? 0 : 1)};
193  column[y] = std::min(possibilities);
194  last_diagonal = old_diagonal;
195  }
196  }
197  auto result = column[s1len];
198  delete[] column;
199  return result;
200 }
201 
202 void
203 escape(std::string & str)
204 {
205  std::map<char, std::string> escapes;
206  escapes['\a'] = "\\a";
207  escapes['\b'] = "\\b";
208  escapes['\f'] = "\\f";
209  escapes['\n'] = "\\n";
210  escapes['\t'] = "\\t";
211  escapes['\v'] = "\\v";
212  escapes['\r'] = "\\r";
213 
214  for (const auto & it : escapes)
215  for (size_t pos = 0; (pos = str.find(it.first, pos)) != std::string::npos;
216  pos += it.second.size())
217  str.replace(pos, 1, it.second);
218 }
219 
220 std::string
221 removeExtraWhitespace(const std::string & input)
222 {
223  return std::regex_replace(input, std::regex("^\\s+|\\s+$|\\s+(?=\\s)"), "");
224 }
225 
226 bool
227 pathContains(const std::string & expression,
228  const std::string & string_to_find,
229  const std::string & delims)
230 {
231  std::vector<std::string> elements;
232  tokenize(expression, elements, 0, delims);
233 
234  std::vector<std::string>::iterator found_it =
235  std::find(elements.begin(), elements.end(), string_to_find);
236  if (found_it != elements.end())
237  return true;
238  else
239  return false;
240 }
241 
242 bool
243 pathExists(const std::string & path)
244 {
245  struct stat buffer;
246  return (stat(path.c_str(), &buffer) == 0);
247 }
248 
249 bool
250 checkFileReadable(const std::string & filename,
251  bool check_line_endings,
252  bool throw_on_unreadable,
253  bool check_for_git_lfs_pointer)
254 {
255  std::ifstream in(filename.c_str(), std::ifstream::in);
256  if (in.fail())
257  {
258  if (throw_on_unreadable)
259  mooseError(
260  (std::string("Unable to open file \"") + filename +
261  std::string("\". Check to make sure that it exists and that you have read permission."))
262  .c_str());
263  else
264  return false;
265  }
266 
267  if (check_line_endings)
268  {
269  std::istream_iterator<char> iter(in);
270  std::istream_iterator<char> eos;
271  in >> std::noskipws;
272  while (iter != eos)
273  if (*iter++ == '\r')
274  mooseError(filename + " contains Windows(DOS) line endings which are not supported.");
275  }
276 
277  if (check_for_git_lfs_pointer && checkForGitLFSPointer(in))
278  mooseError(filename + " appears to be a Git-LFS pointer. Make sure you have \"git-lfs\" "
279  "installed so that you may pull this file.");
280  in.close();
281 
282  return true;
283 }
284 
285 bool
286 checkForGitLFSPointer(std::ifstream & file)
287 {
288  mooseAssert(file.is_open(), "Passed in file handle is not open");
289 
290  std::string line;
291 
292  // git-lfs pointer files contain several name value pairs. The specification states that the
293  // first name/value pair must be "version {url}". We'll do a simplified check for that.
294  file.seekg(0);
295  std::getline(file, line);
296  if (line.find("version https://") != std::string::npos)
297  return true;
298  else
299  return false;
300 }
301 
302 bool
303 checkFileWriteable(const std::string & filename, bool throw_on_unwritable)
304 {
305  std::ofstream out(filename.c_str(), std::ios_base::app);
306  if (out.fail())
307  {
308  if (throw_on_unwritable)
309  mooseError(
310  (std::string("Unable to open file \"") + filename +
311  std::string("\". Check to make sure that it exists and that you have write permission."))
312  .c_str());
313  else
314  return false;
315  }
316 
317  out.close();
318 
319  return true;
320 }
321 
322 void
323 parallelBarrierNotify(const Parallel::Communicator & comm, bool messaging)
324 {
325  processor_id_type secondary_processor_id;
326 
327  if (messaging)
328  Moose::out << "Waiting For Other Processors To Finish" << std::endl;
329  if (comm.rank() == 0)
330  {
331  // The primary process is already through, so report it
332  if (messaging)
333  Moose::out << "Jobs complete: 1/" << comm.size() << (1 == comm.size() ? "\n" : "\r")
334  << std::flush;
335  for (unsigned int i = 2; i <= comm.size(); ++i)
336  {
337  comm.receive(MPI_ANY_SOURCE, secondary_processor_id);
338  if (messaging)
339  Moose::out << "Jobs complete: " << i << "/" << comm.size()
340  << (i == comm.size() ? "\n" : "\r") << std::flush;
341  }
342  }
343  else
344  {
345  secondary_processor_id = comm.rank();
346  comm.send(0, secondary_processor_id);
347  }
348 
349  comm.barrier();
350 }
351 
352 void
354 {
355  // unless we are the first processor...
356  if (comm.rank() > 0)
357  {
358  // ...wait for the previous processor to finish
359  int dummy = 0;
360  comm.receive(comm.rank() - 1, dummy);
361  }
362  else if (warn)
363  mooseWarning("Entering serial execution block (use only for debugging)");
364 }
365 
366 void
368 {
369  // unless we are the last processor...
370  if (comm.rank() + 1 < comm.size())
371  {
372  // ...notify the next processor of its turn
373  int dummy = 0;
374  comm.send(comm.rank() + 1, dummy);
375  }
376 
377  comm.barrier();
378  if (comm.rank() == 0 && warn)
379  mooseWarning("Leaving serial execution block (use only for debugging)");
380 }
381 
382 bool
383 hasExtension(const std::string & filename, std::string ext, bool strip_exodus_ext)
384 {
385  // Extract the extension, w/o the '.'
386  std::string file_ext;
387  if (strip_exodus_ext)
388  {
389  pcrecpp::RE re(
390  ".*\\.([^\\.]*?)(?:-s\\d+)?\\s*$"); // capture the complete extension, ignoring -s*
391  re.FullMatch(filename, &file_ext);
392  }
393  else
394  {
395  pcrecpp::RE re(".*\\.([^\\.]*?)\\s*$"); // capture the complete extension
396  re.FullMatch(filename, &file_ext);
397  }
398 
399  // Perform the comparision
400  if (file_ext == ext)
401  return true;
402  else
403  return false;
404 }
405 
406 std::string
407 getExtension(const std::string & filename, const bool rfind)
408 {
409  std::string file_ext = "";
410  if (filename != "")
411  {
412  // The next line splits filename at the last "/" and gives the file name after "/"
413  const std::string stripped_filename = splitFileName<std::string>(filename).second;
414  auto pos = rfind ? stripped_filename.rfind(".") : stripped_filename.find(".");
415  if (pos != std::string::npos)
416  file_ext += stripped_filename.substr(pos + 1, std::string::npos);
417  }
418 
419  return file_ext;
420 }
421 
422 std::string
423 stripExtension(const std::string & s, const bool rfind)
424 {
425  const std::string ext = getExtension(s, rfind);
426  const bool offset = (ext.size() != 0);
427  // -1 offset accounts for the extension's leading dot ("."), if there is an extension
428  return s.substr(0, s.size() - ext.size() - offset);
429 }
430 
431 std::string
433 {
434  // Note: At the time of creating this method, our minimum compiler still
435  // does not support <filesystem>. Additionally, the inclusion of that header
436  // requires an additional library to be linked so for now, we'll just
437  // use the Unix standard library to get us the cwd().
438  constexpr unsigned int BUF_SIZE = 1024;
439  char buffer[BUF_SIZE];
440 
441  return getcwd(buffer, BUF_SIZE) != nullptr ? buffer : "";
442 }
443 
444 void
445 makedirs(const std::string & dir_name, bool throw_on_failure)
446 {
447  // split path into directories with delimiter '/'
448  std::vector<std::string> split_dir_names;
449  MooseUtils::tokenize(dir_name, split_dir_names);
450 
451  auto n = split_dir_names.size();
452 
453  // remove '.' and '..' when possible
454  auto i = n;
455  i = 0;
456  while (i != n)
457  {
458  if (split_dir_names[i] == ".")
459  {
460  for (auto j = i + 1; j < n; ++j)
461  split_dir_names[j - 1] = split_dir_names[j];
462  --n;
463  }
464  else if (i > 0 && split_dir_names[i] == ".." && split_dir_names[i - 1] != "..")
465  {
466  for (auto j = i + 1; j < n; ++j)
467  split_dir_names[j - 2] = split_dir_names[j];
468  n -= 2;
469  --i;
470  }
471  else
472  ++i;
473  }
474  if (n == 0)
475  return;
476 
477  split_dir_names.resize(n);
478 
479  // start creating directories recursively
480  std::string cur_dir = dir_name[0] == '/' ? "" : ".";
481  for (auto & dir : split_dir_names)
482  {
483  cur_dir += "/" + dir;
484 
485  if (!pathExists(cur_dir))
486  {
487  auto code = Utility::mkdir(cur_dir.c_str());
488  if (code != 0)
489  {
490  std::string msg = "Failed creating directory " + dir_name;
491  if (throw_on_failure)
492  throw std::invalid_argument(msg);
493  else
494  mooseError(msg);
495  }
496  }
497  }
498 }
499 
500 void
501 removedirs(const std::string & dir_name, bool throw_on_failure)
502 {
503  // split path into directories with delimiter '/'
504  std::vector<std::string> split_dir_names;
505  MooseUtils::tokenize(dir_name, split_dir_names);
506 
507  auto n = split_dir_names.size();
508 
509  // remove '.' and '..' when possible
510  auto i = n;
511  i = 0;
512  while (i != n)
513  {
514  if (split_dir_names[i] == ".")
515  {
516  for (auto j = i + 1; j < n; ++j)
517  split_dir_names[j - 1] = split_dir_names[j];
518  --n;
519  }
520  else if (i > 0 && split_dir_names[i] == ".." && split_dir_names[i - 1] != "..")
521  {
522  for (auto j = i + 1; j < n; ++j)
523  split_dir_names[j - 2] = split_dir_names[j];
524  n -= 2;
525  --i;
526  }
527  else
528  ++i;
529  }
530  if (n == 0)
531  return;
532 
533  split_dir_names.resize(n);
534 
535  // start removing directories recursively
536  std::string base_dir = dir_name[0] == '/' ? "" : ".";
537  for (i = n; i > 0; --i)
538  {
539  std::string cur_dir = base_dir;
540  auto j = i;
541  for (j = 0; j < i; ++j)
542  cur_dir += "/" + split_dir_names[j];
543 
544  // listDir should return at least '.' and '..'
545  if (pathExists(cur_dir) && listDir(cur_dir).size() == 2)
546  {
547  auto code = rmdir(cur_dir.c_str());
548  if (code != 0)
549  {
550  std::string msg = "Failed removing directory " + dir_name;
551  if (throw_on_failure)
552  throw std::invalid_argument(msg);
553  else
554  mooseError(msg);
555  }
556  }
557  else
558  // stop removing
559  break;
560  }
561 }
562 
563 std::string
564 camelCaseToUnderscore(const std::string & camel_case_name)
565 {
566  std::string replaced = camel_case_name;
567  // Put underscores in front of each contiguous set of capital letters
568  pcrecpp::RE("(?!^)(?<![A-Z_])([A-Z]+)").GlobalReplace("_\\1", &replaced);
569 
570  // Convert all capital letters to lower case
571  std::transform(replaced.begin(), replaced.end(), replaced.begin(), ::tolower);
572  return replaced;
573 }
574 
575 std::string
576 underscoreToCamelCase(const std::string & underscore_name, bool leading_upper_case)
577 {
578  pcrecpp::StringPiece input(underscore_name);
579  pcrecpp::RE re("([^_]*)(_|$)");
580 
581  std::string result;
582  std::string us, not_us;
583  bool make_upper = leading_upper_case;
584  while (re.Consume(&input, &not_us, &us))
585  {
586  if (not_us.length() > 0)
587  {
588  if (make_upper)
589  {
590  result += std::toupper(not_us[0]);
591  if (not_us.length() > 1)
592  result += not_us.substr(1);
593  }
594  else
595  result += not_us;
596  }
597  if (us == "")
598  break;
599 
600  // Toggle flag so next match is upper cased
601  make_upper = true;
602  }
603 
604  return result;
605 }
606 
607 std::string
608 shortName(const std::string & name)
609 {
610  return name.substr(name.find_last_of('/') != std::string::npos ? name.find_last_of('/') + 1 : 0);
611 }
612 
613 std::string
614 baseName(const std::string & name)
615 {
616  return name.substr(0, name.find_last_of('/') != std::string::npos ? name.find_last_of('/') : 0);
617 }
618 
619 std::string
621 {
622  char hostname[1024];
623  hostname[1023] = '\0';
624 #ifndef __WIN32__
625  if (gethostname(hostname, 1023))
626  mooseError("Failed to retrieve hostname!");
627 #else
628  DWORD dwSize = sizeof(hostname);
629  if (!GetComputerNameEx(ComputerNamePhysicalDnsHostname, hostname, &dwSize))
630  mooseError("Failed to retrieve hostname!");
631 #endif
632  return hostname;
633 }
634 
635 unsigned short
636 getTermWidth(bool use_environment)
637 {
638 #ifndef __WIN32__
639  struct winsize w;
640 #else
641  struct
642  {
643  unsigned short ws_col;
644  } w;
645 #endif
646 
651 
652  if (use_environment)
653  {
654  char * pps_width = std::getenv("MOOSE_PPS_WIDTH");
655  if (pps_width != NULL)
656  {
657  std::stringstream ss(pps_width);
658  ss >> w.ws_col;
659  }
660  }
661  // Default to AUTO if no environment variable was set
663  {
664 #ifndef __WIN32__
665  try
666  {
667  ioctl(0, TIOCGWINSZ, &w);
668  }
669  catch (...)
670 #endif
671  {
672  }
673  }
674 
675  // Something bad happened, make sure we have a sane value
676  // 132 seems good for medium sized screens, and is available as a GNOME preset
678  w.ws_col = 132;
679 
680  return w.ws_col;
681 }
682 
683 void
686 {
687  // Loop through the elements
688  for (const auto & elem_it : props)
689  {
690  Moose::out << "Element " << elem_it.first->id() << '\n';
691 
692  // Loop through the sides
693  for (const auto & side_it : elem_it.second)
694  {
695  Moose::out << " Side " << side_it.first << '\n';
696 
697  // Loop over properties
698  unsigned int cnt = 0;
699  for (const auto & mat_prop : side_it.second)
700  {
701  if (auto mp = dynamic_cast<const MaterialProperty<Real> *>(&mat_prop))
702  {
703  Moose::out << " Property " << cnt << '\n';
704  cnt++;
705 
706  // Loop over quadrature points
707  for (unsigned int qp = 0; qp < mp->size(); ++qp)
708  Moose::out << " prop[" << qp << "] = " << (*mp)[qp] << '\n';
709  }
710  }
711  }
712  }
713 
714  Moose::out << std::flush;
715 }
716 
717 std::string &
718 removeColor(std::string & msg)
719 {
720  pcrecpp::RE re("(\\33\\[3[0-7]m))", pcrecpp::DOTALL());
721  re.GlobalReplace(std::string(""), &msg);
722  return msg;
723 }
724 
725 void
726 addLineBreaks(std::string & message,
727  unsigned int line_width /*= ConsoleUtils::console_line_length*/)
728 {
729  for (auto i : make_range(int(message.length() / line_width)))
730  message.insert((i + 1) * (line_width + 2) - 2, "\n");
731 }
732 
733 void
734 indentMessage(const std::string & prefix,
735  std::string & message,
736  const char * color /*= COLOR_CYAN*/,
737  bool indent_first_line,
738  const std::string & post_prefix)
739 {
740  // First we need to see if the message we need to indent (with color) also contains color codes
741  // that span lines.
742  // The code matches all of the XTERM constants (see XTermConstants.h). If it does, then we'll work
743  // on formatting
744  // each colored multiline chunk one at a time with the right codes.
745  std::string colored_message;
746  std::string curr_color = COLOR_DEFAULT; // tracks last color code before newline
747  std::string line, color_code;
748 
749  bool ends_in_newline = message.empty() ? true : message.back() == '\n';
750 
751  bool first = true;
752 
753  std::istringstream iss(message);
754  for (std::string line; std::getline(iss, line);) // loop over each line
755  {
756  const static pcrecpp::RE match_color(".*(\\33\\[3\\dm)((?!\\33\\[3\\d)[^\n])*");
757  pcrecpp::StringPiece line_piece(line);
758  match_color.FindAndConsume(&line_piece, &color_code);
759 
760  if (!first || indent_first_line)
761  colored_message += color + prefix + post_prefix + curr_color;
762 
763  colored_message += line;
764 
765  // Only add a newline to the last line if it had one to begin with!
766  if (!iss.eof() || ends_in_newline)
767  colored_message += "\n";
768 
769  if (!color_code.empty())
770  curr_color = color_code; // remember last color of this line
771 
772  first = false;
773  }
774  message = colored_message;
775 }
776 
777 std::list<std::string>
778 listDir(const std::string path, bool files_only)
779 {
780  std::list<std::string> files;
781 
782  tinydir_dir dir;
783  dir.has_next = 0; // Avoid a garbage value in has_next (clang StaticAnalysis)
784  tinydir_open(&dir, path.c_str());
785 
786  while (dir.has_next)
787  {
788  tinydir_file file;
789  file.is_dir = 0; // Avoid a garbage value in is_dir (clang StaticAnalysis)
790  tinydir_readfile(&dir, &file);
791 
792  if (!files_only || !file.is_dir)
793  files.push_back(path + "/" + file.name);
794 
795  tinydir_next(&dir);
796  }
797 
798  tinydir_close(&dir);
799 
800  return files;
801 }
802 
803 std::list<std::string>
804 getFilesInDirs(const std::list<std::string> & directory_list, const bool files_only /* = true */)
805 {
806  std::list<std::string> files;
807 
808  for (const auto & dir_name : directory_list)
809  files.splice(files.end(), listDir(dir_name, files_only));
810 
811  return files;
812 }
813 
814 std::string
815 getLatestCheckpointFilePrefix(const std::list<std::string> & checkpoint_files)
816 {
817  // Create storage for newest restart files
818  // Note that these might have the same modification time if the simulation was fast.
819  // In that case we're going to save all of the "newest" files and sort it out momentarily
820  std::time_t newest_time = 0;
821  std::list<std::string> newest_restart_files;
822 
823  // Loop through all possible files and store the newest
824  for (const auto & cp_file : checkpoint_files)
825  {
826  if (MooseUtils::hasExtension(cp_file, "rd"))
827  {
828  struct stat stats;
829  stat(cp_file.c_str(), &stats);
830 
831  std::time_t mod_time = stats.st_mtime;
832  if (mod_time > newest_time)
833  {
834  newest_restart_files.clear(); // If the modification time is greater, clear the list
835  newest_time = mod_time;
836  }
837 
838  if (mod_time == newest_time)
839  newest_restart_files.push_back(cp_file);
840  }
841  }
842 
843  // Loop through all of the newest files according the number in the file name
844  int max_file_num = -1;
845  std::string max_file;
846  std::string max_prefix;
847 
848  // Pull out the path including the number and the number itself
849  // This takes something_blah_out_cp/0024-restart-1.rd
850  // and returns "something_blah_out_cp/0024" as the "prefix"
851  // and then "24" as the number itself
852  pcrecpp::RE re_file_num("(.*?(\\d+))-restart-\\d+.rd$");
853 
854  // Now, out of the newest files find the one with the largest number in it
855  for (const auto & res_file : newest_restart_files)
856  {
857  int file_num = 0;
858 
859  // All of the file up to and including the digits
860  std::string file_prefix;
861 
862  re_file_num.FullMatch(res_file, &file_prefix, &file_num);
863 
864  if (file_num > max_file_num)
865  {
866  // Need both the header and the data
867  if (!RestartableDataReader::isAvailable(res_file))
868  continue;
869 
870  max_file_num = file_num;
871  max_file = res_file;
872  max_prefix = file_prefix;
873  }
874  }
875 
876  // Error if nothing was located
877  if (max_file_num == -1)
878  mooseError("No checkpoint file found!");
879 
880  return max_prefix;
881 }
882 
883 bool
884 wildCardMatch(std::string name, std::string search_string)
885 {
886  // Assume that an empty string matches anything
887  if (search_string == "")
888  return true;
889 
890  // transform to lower for case insenstive matching
891  std::transform(name.begin(), name.end(), name.begin(), (int (*)(int))std::toupper);
892  std::transform(search_string.begin(),
893  search_string.end(),
894  search_string.begin(),
895  (int (*)(int))std::toupper);
896 
897  // exact match!
898  if (search_string.find("*") == std::string::npos)
899  return search_string == name;
900 
901  // wildcard
902  std::vector<std::string> tokens;
903  MooseUtils::tokenize(search_string, tokens, 1, "*");
904 
905  size_t pos = 0;
906  for (unsigned int i = 0; i < tokens.size() && pos != std::string::npos; ++i)
907  {
908  pos = name.find(tokens[i], pos);
909  // See if we have a leading wildcard
910  if (search_string[0] != '*' && i == 0 && pos != 0)
911  return false;
912  }
913 
914  if (pos != std::string::npos && tokens.size() > 0)
915  {
916  // Now see if we have a trailing wildcard
917  size_t last_token_length = tokens.back().length();
918  if (*search_string.rbegin() == '*' || pos == name.size() - last_token_length)
919  return true;
920  else
921  return false;
922  }
923  else
924  return false;
925 }
926 
927 bool
928 globCompare(const std::string & candidate,
929  const std::string & pattern,
930  std::size_t c,
931  std::size_t p)
932 {
933  if (p == pattern.size())
934  return c == candidate.size();
935 
936  if (pattern[p] == '*')
937  {
938  for (; c < candidate.size(); ++c)
939  if (globCompare(candidate, pattern, c, p + 1))
940  return true;
941  return globCompare(candidate, pattern, c, p + 1);
942  }
943 
944  if (pattern[p] != '?' && pattern[p] != candidate[c])
945  return false;
946 
947  return globCompare(candidate, pattern, c + 1, p + 1);
948 }
949 
950 template <typename T>
951 T
952 convertStringToInt(const std::string & str, bool throw_on_failure)
953 {
954  T val;
955 
956  // Let's try to read a double and see if we can cast it to an int
957  // This would be the case for scientific notation
958  long double double_val;
959  std::stringstream double_ss(str);
960  double_ss >> double_val;
961 
962  // on arm64 the long double does not have sufficient precission
963  bool use_int = false;
964  std::stringstream int_ss(str);
965  if (!(int_ss >> val).fail() && int_ss.eof())
966  use_int = true;
967 
968  if (double_ss.fail() || !double_ss.eof())
969  {
970  std::string msg =
971  std::string("Unable to convert '") + str + "' to type " + demangle(typeid(T).name());
972 
973  if (throw_on_failure)
974  throw std::invalid_argument(msg);
975  else
976  mooseError(msg);
977  }
978 
979  // Check to see if it's an integer (and within range of an integer)
980  if (double_val == static_cast<long double>(static_cast<T>(double_val)))
981  return use_int ? val : static_cast<T>(double_val);
982 
983  // Still failure
984  std::string msg =
985  std::string("Unable to convert '") + str + "' to type " + demangle(typeid(T).name());
986 
987  if (throw_on_failure)
988  throw std::invalid_argument(msg);
989  else
990  mooseError(msg);
991 }
992 
993 template <>
994 short int
995 convert<short int>(const std::string & str, bool throw_on_failure)
996 {
997  return convertStringToInt<short int>(str, throw_on_failure);
998 }
999 
1000 template <>
1001 unsigned short int
1002 convert<unsigned short int>(const std::string & str, bool throw_on_failure)
1003 {
1004  return convertStringToInt<unsigned short int>(str, throw_on_failure);
1005 }
1006 
1007 template <>
1008 int
1009 convert<int>(const std::string & str, bool throw_on_failure)
1010 {
1011  return convertStringToInt<int>(str, throw_on_failure);
1012 }
1013 
1014 template <>
1015 unsigned int
1016 convert<unsigned int>(const std::string & str, bool throw_on_failure)
1017 {
1018  return convertStringToInt<unsigned int>(str, throw_on_failure);
1019 }
1020 
1021 template <>
1022 long int
1023 convert<long int>(const std::string & str, bool throw_on_failure)
1024 {
1025  return convertStringToInt<long int>(str, throw_on_failure);
1026 }
1027 
1028 template <>
1029 unsigned long int
1030 convert<unsigned long int>(const std::string & str, bool throw_on_failure)
1031 {
1032  return convertStringToInt<unsigned long int>(str, throw_on_failure);
1033 }
1034 
1035 template <>
1036 long long int
1037 convert<long long int>(const std::string & str, bool throw_on_failure)
1038 {
1039  return convertStringToInt<long long int>(str, throw_on_failure);
1040 }
1041 
1042 template <>
1043 unsigned long long int
1044 convert<unsigned long long int>(const std::string & str, bool throw_on_failure)
1045 {
1046  return convertStringToInt<unsigned long long int>(str, throw_on_failure);
1047 }
1048 
1049 std::string
1050 stringJoin(const std::vector<std::string> & values, const std::string & separator)
1051 {
1052  std::string combined;
1053  for (const auto & value : values)
1054  combined += value + separator;
1055  if (values.size())
1056  combined = combined.substr(0, combined.size() - separator.size());
1057  return combined;
1058 }
1059 
1060 bool
1061 beginsWith(const std::string & value, const std::string & begin_value)
1062 {
1063  return value.rfind(begin_value, 0) == 0;
1064 }
1065 
1068 {
1070 }
1071 
1072 int
1073 stringToInteger(const std::string & input, bool throw_on_failure)
1074 {
1075  return convert<int>(input, throw_on_failure);
1076 }
1077 
1078 void
1080  dof_id_type num_chunks,
1081  dof_id_type chunk_id,
1082  dof_id_type & num_local_items,
1083  dof_id_type & local_items_begin,
1084  dof_id_type & local_items_end)
1085 {
1086  auto global_num_local_items = num_items / num_chunks;
1087 
1088  num_local_items = global_num_local_items;
1089 
1090  auto leftovers = num_items % num_chunks;
1091 
1092  if (chunk_id < leftovers)
1093  {
1094  num_local_items++;
1095  local_items_begin = num_local_items * chunk_id;
1096  }
1097  else
1098  local_items_begin =
1099  (global_num_local_items + 1) * leftovers + global_num_local_items * (chunk_id - leftovers);
1100 
1101  local_items_end = local_items_begin + num_local_items;
1102 }
1103 
1106 {
1107  auto global_num_local_items = num_items / num_chunks;
1108 
1109  auto leftovers = num_items % num_chunks;
1110 
1111  auto first_item_past_first_part = leftovers * (global_num_local_items + 1);
1112 
1113  // Is it in the first section (that gets an extra item)
1114  if (item_id < first_item_past_first_part)
1115  return item_id / (global_num_local_items + 1);
1116  else
1117  {
1118  auto new_item_id = item_id - first_item_past_first_part;
1119 
1120  // First chunk after the first section + the number of chunks after that
1121  return leftovers + (new_item_id / global_num_local_items);
1122  }
1123 }
1124 
1125 std::vector<std::string>
1126 split(const std::string & str, const std::string & delimiter, std::size_t max_count)
1127 {
1128  std::vector<std::string> output;
1129  std::size_t count = 0;
1130  size_t prev = 0, pos = 0;
1131  do
1132  {
1133  pos = str.find(delimiter, prev);
1134  output.push_back(str.substr(prev, pos - prev));
1135  prev = pos + delimiter.length();
1136  count += 1;
1137  } while (pos != std::string::npos && count < max_count);
1138 
1139  if (pos != std::string::npos)
1140  output.push_back(str.substr(prev));
1141 
1142  return output;
1143 }
1144 
1145 std::vector<std::string>
1146 rsplit(const std::string & str, const std::string & delimiter, std::size_t max_count)
1147 {
1148  std::vector<std::string> output;
1149  std::size_t count = 0;
1150  size_t prev = str.length(), pos = str.length();
1151  do
1152  {
1153  pos = str.rfind(delimiter, prev);
1154  output.insert(output.begin(), str.substr(pos + delimiter.length(), prev - pos));
1155  prev = pos - delimiter.length();
1156  count += 1;
1157  } while (pos != std::string::npos && pos > 0 && count < max_count);
1158 
1159  if (pos != std::string::npos)
1160  output.insert(output.begin(), str.substr(0, pos));
1161 
1162  return output;
1163 }
1164 
1165 void
1166 createSymlink(const std::string & target, const std::string & link)
1167 {
1168  clearSymlink(link);
1169 #ifndef __WIN32__
1170  auto err = symlink(target.c_str(), link.c_str());
1171 #else
1172  auto err = CreateSymbolicLink(target.c_str(), link.c_str(), 0);
1173 #endif
1174  if (err)
1175  mooseError("Failed to create symbolic link (via 'symlink') from ", target, " to ", link);
1176 }
1177 
1178 void
1179 clearSymlink(const std::string & link)
1180 {
1181 #ifndef __WIN32__
1182  struct stat sbuf;
1183  if (lstat(link.c_str(), &sbuf) == 0)
1184  {
1185  auto err = unlink(link.c_str());
1186  if (err != 0)
1187  mooseError("Failed to remove symbolic link (via 'unlink') to ", link);
1188  }
1189 #else
1190  auto attr = GetFileAttributesA(link.c_str());
1191  if (attr != INVALID_FILE_ATTRIBUTES)
1192  {
1193  auto err = _unlink(link.c_str());
1194  if (err != 0)
1195  mooseError("Failed to remove link/file (via '_unlink') to ", link);
1196  }
1197 #endif
1198 }
1199 
1200 std::size_t
1201 fileSize(const std::string & filename)
1202 {
1203 #ifndef __WIN32__
1204  struct stat buffer;
1205  if (!stat(filename.c_str(), &buffer))
1206  return buffer.st_size;
1207 #else
1208  HANDLE hFile = CreateFile(filename.c_str(),
1209  GENERIC_READ,
1210  FILE_SHARE_READ | FILE_SHARE_WRITE,
1211  NULL,
1212  OPEN_EXISTING,
1213  FILE_ATTRIBUTE_NORMAL,
1214  NULL);
1215  if (hFile == INVALID_HANDLE_VALUE)
1216  return 0;
1217 
1218  LARGE_INTEGER size;
1219  if (GetFileSizeEx(hFile, &size))
1220  {
1221  CloseHandle(hFile);
1222  return size.QuadPart;
1223  }
1224 
1225  CloseHandle(hFile);
1226 #endif
1227  return 0;
1228 }
1229 
1230 std::string
1231 realpath(const std::string & path)
1232 {
1233  return std::filesystem::absolute(path);
1234 }
1235 
1236 BoundingBox
1237 buildBoundingBox(const Point & p1, const Point & p2)
1238 {
1239  BoundingBox bb;
1240  bb.union_with(p1);
1241  bb.union_with(p2);
1242  return bb;
1243 }
1244 
1245 std::string
1246 prettyCppType(const std::string & cpp_type)
1247 {
1248  // On mac many of the std:: classes are inline namespaced with __1
1249  // On linux std::string can be inline namespaced with __cxx11
1250  std::string s = cpp_type;
1251  // Remove all spaces surrounding a >
1252  pcrecpp::RE("\\s(?=>)").GlobalReplace("", &s);
1253  pcrecpp::RE("std::__\\w+::").GlobalReplace("std::", &s);
1254  // It would be nice if std::string actually looked normal
1255  pcrecpp::RE("\\s*std::basic_string<char, std::char_traits<char>, std::allocator<char>>\\s*")
1256  .GlobalReplace("std::string", &s);
1257  // It would be nice if std::vector looked normal
1258  pcrecpp::RE r("std::vector<([[:print:]]+),\\s?std::allocator<\\s?\\1\\s?>\\s?>");
1259  r.GlobalReplace("std::vector<\\1>", &s);
1260  // Do it again for nested vectors
1261  r.GlobalReplace("std::vector<\\1>", &s);
1262  return s;
1263 }
1264 
1265 std::string
1266 canonicalPath(const std::string & path)
1267 {
1268  return std::filesystem::weakly_canonical(path).c_str();
1269 }
1270 
1271 bool
1272 startsWith(const std::string & string1, const std::string & string2)
1273 {
1274  if (string2.size() > string1.size())
1275  return false;
1276  return string1.compare(0, string2.size(), string2) == 0;
1277 }
1278 
1279 void
1280 replaceStart(std::string & string1, const std::string & string2, const std::string & string3)
1281 {
1282  mooseAssert(startsWith(string1, string2),
1283  "Cannot replace the start because it doesn't match the start string");
1284  string1.replace(0, string2.size(), string3);
1285 }
1286 
1287 bool
1288 isAllLowercase(const std::string & str)
1289 {
1290  return std::all_of(
1291  str.begin(), str.end(), [](unsigned char c) { return !std::isalpha(c) || std::islower(c); });
1292 }
1293 } // MooseUtils namespace
1294 
1295 void
1296 removeSubstring(std::string & main, const std::string & sub)
1297 {
1298  std::string::size_type n = sub.length();
1299  for (std::string::size_type i = main.find(sub); i != std::string::npos; i = main.find(sub))
1300  main.erase(i, n);
1301 }
1302 
1303 std::string
1304 removeSubstring(const std::string & main, const std::string & sub)
1305 {
1306  std::string copy_main = main;
1307  std::string::size_type n = sub.length();
1308  for (std::string::size_type i = copy_main.find(sub); i != std::string::npos;
1309  i = copy_main.find(sub))
1310  copy_main.erase(i, n);
1311  return copy_main;
1312 }
std::string name(const ElemQuality q)
OStreamProxy err
bool parsesToReal(const std::string &input)
Check if the input string can be parsed into a Real.
Definition: MooseUtils.C:89
std::string docsDir(const std::string &app_name)
Returns the directory of any installed docs/site.
Definition: MooseUtils.C:121
bool globCompare(const std::string &candidate, const std::string &pattern, std::size_t c=0, std::size_t p=0)
Definition: MooseUtils.C:928
A MultiMooseEnum object to hold "execute_on" flags.
Definition: ExecFlagEnum.h:21
void serialEnd(const libMesh::Parallel::Communicator &comm, bool warn=true)
Closes a section of code that is executed in serial rank by rank, and that was opened with a call to ...
Definition: MooseUtils.C:367
void tokenize(const std::string &str, std::vector< T > &elements, unsigned int min_len=1, const std::string &delims="/")
This function will split the passed in string on a set of delimiters appending the substrings to the ...
bool beginsWith(const std::string &value, const std::string &begin_value)
Definition: MooseUtils.C:1061
HashMap is an abstraction for dictionary data type, we make it thread-safe by locking inserts...
Definition: HashMap.h:18
int stringToInteger(const std::string &input, bool throw_on_failure=false)
Robust string to integer conversion that fails for cases such at "1foo".
Definition: MooseUtils.C:1073
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:302
void MaterialPropertyStorageDump(const HashMap< const libMesh::Elem *, HashMap< unsigned int, MaterialProperties >> &props)
Function to dump the contents of MaterialPropertyStorage for debugging purposes.
Definition: MooseUtils.C:684
std::string installedInputsDir(const std::string &app_name, const std::string &dir_name, const std::string &extra_error_msg="")
Returns the directory of any installed inputs or the empty string if none are found.
Definition: MooseUtils.C:99
std::string getExecutablePath()
This function returns the PATH of the running executable.
bool isAllLowercase(const std::string &str)
Definition: MooseUtils.C:1288
void mooseWarning(Args &&... args)
Emit a warning message with the given stringified, concatenated args.
Definition: MooseError.h:336
bool startsWith(const std::string &string1, const std::string &string2)
Definition: MooseUtils.C:1272
std::list< std::string > getFilesInDirs(const std::list< std::string > &directory_list, const bool files_only=true)
Retrieves the names of all of the files contained within the list of directories passed into the rout...
Definition: MooseUtils.C:804
processor_id_type rank() const
void removedirs(const std::string &dir_name, bool throw_on_failure=false)
Recursively remove directories from inner-most when the directories are empty.
Definition: MooseUtils.C:501
void linearPartitionItems(dof_id_type num_items, dof_id_type num_chunks, dof_id_type chunk_id, dof_id_type &num_local_items, dof_id_type &local_items_begin, dof_id_type &local_items_end)
Linearly partition a number of items.
Definition: MooseUtils.C:1079
bool checkForGitLFSPointer(std::ifstream &file)
Check if the file is a Git-LFS pointer.
Definition: MooseUtils.C:286
std::string realpath(const std::string &path)
Wrapper around PetscGetRealPath, which is a cross-platform replacement for realpath.
Definition: MooseUtils.C:1231
static ExecFlagRegistry & getExecFlagRegistry()
Return Singleton instance.
std::string convertLatestCheckpoint(std::string orig)
Replaces "LATEST" placeholders with the latest checkpoint file name.
Definition: MooseUtils.C:153
std::string mooseDocsURL(const std::string &path)
Returns the URL of a page located on the MOOSE documentation site.
Definition: MooseUtils.C:135
std::string hostname()
Get the hostname the current process is running on.
Definition: MooseUtils.C:620
auto max(const L &left, const R &right)
std::string camelCaseToUnderscore(const std::string &camel_case_name)
Function for converting a camel case name to a name containing underscores.
Definition: MooseUtils.C:564
std::string shortName(const std::string &name)
Function for stripping name after the file / in parser block.
Definition: MooseUtils.C:608
void removeSubstring(std::string &main, const std::string &sub)
find, erase, length algorithm for removing a substring from a string
Definition: MooseUtils.C:1296
std::vector< std::string > split(const std::string &str, const std::string &delimiter, std::size_t max_count=std::numeric_limits< std::size_t >::max())
Python like split functions for strings.
Definition: MooseUtils.C:1126
ExecFlagEnum getDefaultExecFlagEnum()
Return the default ExecFlagEnum for MOOSE.
Definition: MooseUtils.C:1067
T convertStringToInt(const std::string &str, bool throw_on_failure)
Definition: MooseUtils.C:952
std::string getExtension(const std::string &filename, const bool rfind=false)
Gets the extension of the passed file name.
Definition: MooseUtils.C:407
void replaceStart(std::string &string1, const std::string &string2, const std::string &string3)
Replace the starting string string2 of string1 with string3.
Definition: MooseUtils.C:1280
processor_id_type size() const
std::vector< std::string > rsplit(const std::string &str, const std::string &delimiter, std::size_t max_count=std::numeric_limits< std::size_t >::max())
Definition: MooseUtils.C:1146
uint8_t processor_id_type
Status receive(const unsigned int dest_processor_id, T &buf, const MessageTag &tag=any_tag) const
std::string stripExtension(const std::string &s, const bool rfind=false)
Removes any file extension from the given string s (i.e.
Definition: MooseUtils.C:423
int convert< int >(const std::string &str, bool throw_on_failure)
Definition: MooseUtils.C:1009
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
void indentMessage(const std::string &prefix, std::string &message, const char *color=COLOR_CYAN, bool dont_indent_first_line=true, const std::string &post_prefix=": ")
Indents the supplied message given the prefix and color.
Definition: MooseUtils.C:734
void parallelBarrierNotify(const libMesh::Parallel::Communicator &comm, bool messaging=true)
This function implements a parallel barrier function but writes progress to stdout.
Definition: MooseUtils.C:323
std::string getLatestCheckpointFilePrefix(const std::list< std::string > &checkpoint_files)
Returns the most recent checkpoint prefix (the four numbers at the beginning) If a suitable file isn&#39;...
Definition: MooseUtils.C:815
void serialBegin(const libMesh::Parallel::Communicator &comm, bool warn=true)
This function marks the begin of a section of code that is executed in serial rank by rank...
Definition: MooseUtils.C:353
std::string canonicalPath(const std::string &path)
Gets the canonical path of the given path.
Definition: MooseUtils.C:1266
bool checkFileReadable(const std::string &filename, bool check_line_endings=false, bool throw_on_unreadable=true, bool check_for_git_lfs_pointer=true)
Checks to see if a file is readable (exists and permissions)
Definition: MooseUtils.C:250
std::string runTestsExecutable()
Returns the location of either a local repo run_tests script - or an installed test executor script i...
Definition: MooseUtils.C:65
std::size_t fileSize(const std::string &filename)
Check the file size.
Definition: MooseUtils.C:1201
unsigned int convert< unsigned int >(const std::string &str, bool throw_on_failure)
Definition: MooseUtils.C:1016
std::string underscoreToCamelCase(const std::string &underscore_name, bool leading_upper_case)
Function for converting an underscore name to a camel case name.
Definition: MooseUtils.C:576
bool hasExtension(const std::string &filename, std::string ext, bool strip_exodus_ext=false)
Function tests if the supplied filename as the desired extension.
Definition: MooseUtils.C:383
std::string & removeColor(std::string &msg)
remove ANSI escape sequences for terminal color from msg
Definition: MooseUtils.C:718
std::string demangle(const char *name)
bool checkFileWriteable(const std::string &filename, bool throw_on_unwritable=true)
Check if the file is writable (path exists and permissions)
Definition: MooseUtils.C:303
void addLineBreaks(std::string &message, unsigned int line_width)
Definition: MooseUtils.C:726
int main(int argc, char *argv[])
Initialize, create and run a MooseApp.
Definition: MooseMain.h:31
charT const * delimiter
Definition: InfixIterator.h:34
void clearSymlink(const std::string &link)
Remove a symbolic link, if the given filename is a link.
Definition: MooseUtils.C:1179
long long int convert< long long int >(const std::string &str, bool throw_on_failure)
Definition: MooseUtils.C:1037
processor_id_type linearPartitionChunk(dof_id_type num_items, dof_id_type num_chunks, dof_id_type item_id)
Return the chunk_id that is assigned to handle item_id.
Definition: MooseUtils.C:1105
void createSymlink(const std::string &target, const std::string &link)
Create a symbolic link, if the link already exists it is replaced.
Definition: MooseUtils.C:1166
short int convert< short int >(const std::string &str, bool throw_on_failure)
Definition: MooseUtils.C:995
std::filesystem::path pathjoin(const std::filesystem::path &p)
Definition: MooseUtils.C:59
unsigned long int convert< unsigned long int >(const std::string &str, bool throw_on_failure)
Definition: MooseUtils.C:1030
std::string baseName(const std::string &name)
Function for string the information before the final / in a parser block.
Definition: MooseUtils.C:614
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
bool wildCardMatch(std::string name, std::string search_string)
Definition: MooseUtils.C:884
void send(const unsigned int dest_processor_id, const T &buf, const MessageTag &tag=no_tag) const
OStreamProxy out
IntRange< T > make_range(T beg, T end)
const ExecFlagEnum & getDefaultFlags() const
std::list< std::string > listDir(const std::string path, bool files_only=false)
Definition: MooseUtils.C:778
libMesh::BoundingBox buildBoundingBox(const Point &p1, const Point &p2)
Construct a valid bounding box from 2 arbitrary points.
Definition: MooseUtils.C:1237
int levenshteinDist(const std::string &s1, const std::string &s2)
Computes and returns the Levenshtein distance between strings s1 and s2.
Definition: MooseUtils.C:172
std::string getCurrentWorkingDir()
Returns the current working directory as a string.
Definition: MooseUtils.C:432
void makedirs(const std::string &dir_name, bool throw_on_failure=false)
Recursively make directories.
Definition: MooseUtils.C:445
std::string removeExtraWhitespace(const std::string &str)
Removes additional whitespace from a string.
Definition: MooseUtils.C:221
long int convert< long int >(const std::string &str, bool throw_on_failure)
Definition: MooseUtils.C:1023
void union_with(const Point &p)
unsigned short int convert< unsigned short int >(const std::string &str, bool throw_on_failure)
Definition: MooseUtils.C:1002
bool pathContains(const std::string &expression, const std::string &string_to_find, const std::string &delims="/")
This function tokenizes a path and checks to see if it contains the string to look for...
Definition: MooseUtils.C:227
bool pathExists(const std::string &path)
Definition: MooseUtils.C:243
std::string replaceAll(std::string str, const std::string &from, const std::string &to)
Replaces all occurrences of from in str with to and returns the result.
Definition: MooseUtils.C:141
auto min(const L &left, const R &right)
std::string stringJoin(const std::vector< std::string > &values, const std::string &separator=" ")
Concatenates value into a single string separated by separator.
Definition: MooseUtils.C:1050
unsigned long long int convert< unsigned long long int >(const std::string &str, bool throw_on_failure)
Definition: MooseUtils.C:1044
void ErrorVector unsigned int
void escape(std::string &str)
This function will escape all of the standard C++ escape characters so that they can be printed...
Definition: MooseUtils.C:203
std::string prettyCppType(const std::string &cpp_type)
Definition: MooseUtils.C:1246
uint8_t dof_id_type
std::string findTestRoot()
Searches in the current working directory and then recursively up in each parent directory looking fo...
Definition: MooseUtils.C:75
unsigned short getTermWidth(bool use_environment)
Returns the width of the terminal using sys/ioctl.
Definition: MooseUtils.C:636
static bool isAvailable(const std::filesystem::path &folder_base)