1/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying 2 file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ 3#ifndef @KWSYS_NAMESPACE@_SystemTools_hxx 4#define @KWSYS_NAMESPACE@_SystemTools_hxx 5 6#include <@KWSYS_NAMESPACE@/Configure.hxx> 7#include <@KWSYS_NAMESPACE@/Status.hxx> 8 9#include <iosfwd> 10#include <map> 11#include <string> 12#include <vector> 13 14#include <sys/types.h> 15// include sys/stat.h after sys/types.h 16#include <sys/stat.h> 17 18#if !defined(_WIN32) || defined(__CYGWIN__) 19# include <unistd.h> // For access permissions for use with access() 20#endif 21 22// Required for va_list 23#include <stdarg.h> 24// Required for FILE* 25#include <stdio.h> 26#if !defined(va_list) 27// Some compilers move va_list into the std namespace and there is no way to 28// tell that this has been done. Playing with things being included before or 29// after stdarg.h does not solve things because we do not have control over 30// what the user does. This hack solves this problem by moving va_list to our 31// own namespace that is local for kwsys. 32namespace std { 33} // Required for platforms that do not have std namespace 34namespace @KWSYS_NAMESPACE@_VA_LIST { 35using namespace std; 36typedef va_list hack_va_list; 37} 38namespace @KWSYS_NAMESPACE@ { 39typedef @KWSYS_NAMESPACE@_VA_LIST::hack_va_list va_list; 40} 41#endif // va_list 42 43namespace @KWSYS_NAMESPACE@ { 44 45class SystemToolsStatic; 46 47/** \class SystemToolsManager 48 * \brief Use to make sure SystemTools is initialized before it is used 49 * and is the last static object destroyed 50 */ 51class @KWSYS_NAMESPACE@_EXPORT SystemToolsManager 52{ 53public: 54 SystemToolsManager(); 55 ~SystemToolsManager(); 56 57 SystemToolsManager(const SystemToolsManager&) = delete; 58 SystemToolsManager& operator=(const SystemToolsManager&) = delete; 59}; 60 61// This instance will show up in any translation unit that uses 62// SystemTools. It will make sure SystemTools is initialized 63// before it is used and is the last static object destroyed. 64static SystemToolsManager SystemToolsManagerInstance; 65 66// Flags for use with TestFileAccess. Use a typedef in case any operating 67// system in the future needs a special type. These are flags that may be 68// combined using the | operator. 69typedef int TestFilePermissions; 70#if defined(_WIN32) && !defined(__CYGWIN__) 71// On Windows (VC), no system header defines these constants... 72static const TestFilePermissions TEST_FILE_OK = 0; 73static const TestFilePermissions TEST_FILE_READ = 4; 74static const TestFilePermissions TEST_FILE_WRITE = 2; 75static const TestFilePermissions TEST_FILE_EXECUTE = 1; 76#else 77// Standard POSIX constants 78static const TestFilePermissions TEST_FILE_OK = F_OK; 79static const TestFilePermissions TEST_FILE_READ = R_OK; 80static const TestFilePermissions TEST_FILE_WRITE = W_OK; 81static const TestFilePermissions TEST_FILE_EXECUTE = X_OK; 82#endif 83 84/** \class SystemTools 85 * \brief A collection of useful platform-independent system functions. 86 */ 87class @KWSYS_NAMESPACE@_EXPORT SystemTools 88{ 89public: 90 /** ----------------------------------------------------------------- 91 * String Manipulation Routines 92 * ----------------------------------------------------------------- 93 */ 94 95 /** 96 * Replace symbols in str that are not valid in C identifiers as 97 * defined by the 1999 standard, ie. anything except [A-Za-z0-9_]. 98 * They are replaced with `_' and if the first character is a digit 99 * then an underscore is prepended. Note that this can produce 100 * identifiers that the standard reserves (_[A-Z].* and __.*). 101 */ 102 static std::string MakeCidentifier(const std::string& s); 103 104 static std::string MakeCindentifier(const std::string& s) 105 { 106 return MakeCidentifier(s); 107 } 108 109 /** 110 * Replace replace all occurrences of the string in the source string. 111 */ 112 static void ReplaceString(std::string& source, const char* replace, 113 const char* with); 114 static void ReplaceString(std::string& source, const std::string& replace, 115 const std::string& with); 116 117 /** 118 * Return a capitalized string (i.e the first letter is uppercased, 119 * all other are lowercased). 120 */ 121 static std::string Capitalized(const std::string&); 122 123 /** 124 * Return a 'capitalized words' string (i.e the first letter of each word 125 * is uppercased all other are left untouched though). 126 */ 127 static std::string CapitalizedWords(const std::string&); 128 129 /** 130 * Return a 'uncapitalized words' string (i.e the first letter of each word 131 * is lowercased all other are left untouched though). 132 */ 133 static std::string UnCapitalizedWords(const std::string&); 134 135 /** 136 * Return a lower case string 137 */ 138 static std::string LowerCase(const std::string&); 139 140 /** 141 * Return a lower case string 142 */ 143 static std::string UpperCase(const std::string&); 144 145 /** 146 * Count char in string 147 */ 148 static size_t CountChar(const char* str, char c); 149 150 /** 151 * Remove some characters from a string. 152 * Return a pointer to the new resulting string (allocated with 'new') 153 */ 154 static char* RemoveChars(const char* str, const char* toremove); 155 156 /** 157 * Remove remove all but 0->9, A->F characters from a string. 158 * Return a pointer to the new resulting string (allocated with 'new') 159 */ 160 static char* RemoveCharsButUpperHex(const char* str); 161 162 /** 163 * Replace some characters by another character in a string (in-place) 164 * Return a pointer to string 165 */ 166 static char* ReplaceChars(char* str, const char* toreplace, 167 char replacement); 168 169 /** 170 * Returns true if str1 starts (respectively ends) with str2 171 */ 172 static bool StringStartsWith(const char* str1, const char* str2); 173 static bool StringStartsWith(const std::string& str1, const char* str2); 174 static bool StringEndsWith(const char* str1, const char* str2); 175 static bool StringEndsWith(const std::string& str1, const char* str2); 176 177 /** 178 * Returns a pointer to the last occurrence of str2 in str1 179 */ 180 static const char* FindLastString(const char* str1, const char* str2); 181 182 /** 183 * Make a duplicate of the string similar to the strdup C function 184 * but use new to create the 'new' string, so one can use 185 * 'delete' to remove it. Returns 0 if the input is empty. 186 */ 187 static char* DuplicateString(const char* str); 188 189 /** 190 * Return the string cropped to a given length by removing chars in the 191 * center of the string and replacing them with an ellipsis (...) 192 */ 193 static std::string CropString(const std::string&, size_t max_len); 194 195 /** split a path by separator into an array of strings, default is /. 196 If isPath is true then the string is treated like a path and if 197 s starts with a / then the first element of the returned array will 198 be /, so /foo/bar will be [/, foo, bar] 199 */ 200 static std::vector<std::string> SplitString(const std::string& s, 201 char separator = '/', 202 bool isPath = false); 203 /** 204 * Perform a case-independent string comparison 205 */ 206 static int Strucmp(const char* s1, const char* s2); 207 208 /** 209 * Split a string on its newlines into multiple lines 210 * Return false only if the last line stored had no newline 211 */ 212 static bool Split(const std::string& s, std::vector<std::string>& l); 213 static bool Split(const std::string& s, std::vector<std::string>& l, 214 char separator); 215 216 /** 217 * Return string with space added between capitalized words 218 * (i.e. EatMyShorts becomes Eat My Shorts ) 219 * (note that IEatShorts becomes IEat Shorts) 220 */ 221 static std::string AddSpaceBetweenCapitalizedWords(const std::string&); 222 223 /** 224 * Append two or more strings and produce new one. 225 * Programmer must 'delete []' the resulting string, which was allocated 226 * with 'new'. 227 * Return 0 if inputs are empty or there was an error 228 */ 229 static char* AppendStrings(const char* str1, const char* str2); 230 static char* AppendStrings(const char* str1, const char* str2, 231 const char* str3); 232 233 /** 234 * Estimate the length of the string that will be produced 235 * from printing the given format string and arguments. The 236 * returned length will always be at least as large as the string 237 * that will result from printing. 238 * WARNING: since va_arg is called to iterate of the argument list, 239 * you will not be able to use this 'ap' anymore from the beginning. 240 * It's up to you to call va_end though. 241 */ 242 static int EstimateFormatLength(const char* format, va_list ap); 243 244 /** 245 * Escape specific characters in 'str'. 246 */ 247 static std::string EscapeChars(const char* str, const char* chars_to_escape, 248 char escape_char = '\\'); 249 250 /** ----------------------------------------------------------------- 251 * Filename Manipulation Routines 252 * ----------------------------------------------------------------- 253 */ 254 255 /** 256 * Replace Windows file system slashes with Unix-style slashes. 257 */ 258 static void ConvertToUnixSlashes(std::string& path); 259 260#ifdef _WIN32 261 /** Calls Encoding::ToWindowsExtendedPath. */ 262 static std::wstring ConvertToWindowsExtendedPath(const std::string&); 263#endif 264 265 /** 266 * For windows this calls ConvertToWindowsOutputPath and for unix 267 * it calls ConvertToUnixOutputPath 268 */ 269 static std::string ConvertToOutputPath(const std::string&); 270 271 /** 272 * Convert the path to a string that can be used in a unix makefile. 273 * double slashes are removed, and spaces are escaped. 274 */ 275 static std::string ConvertToUnixOutputPath(const std::string&); 276 277 /** 278 * Convert the path to string that can be used in a windows project or 279 * makefile. Double slashes are removed if they are not at the start of 280 * the string, the slashes are converted to windows style backslashes, and 281 * if there are spaces in the string it is double quoted. 282 */ 283 static std::string ConvertToWindowsOutputPath(const std::string&); 284 285 /** 286 * Return true if a path with the given name exists in the current directory. 287 */ 288 static bool PathExists(const std::string& path); 289 290 /** 291 * Return true if a file exists in the current directory. 292 * If isFile = true, then make sure the file is a file and 293 * not a directory. If isFile = false, then return true 294 * if it is a file or a directory. Note that the file will 295 * also be checked for read access. (Currently, this check 296 * for read access is only done on POSIX systems.) 297 */ 298 static bool FileExists(const char* filename, bool isFile); 299 static bool FileExists(const std::string& filename, bool isFile); 300 static bool FileExists(const char* filename); 301 static bool FileExists(const std::string& filename); 302 303 /** 304 * Test if a file exists and can be accessed with the requested 305 * permissions. Symbolic links are followed. Returns true if 306 * the access test was successful. 307 * 308 * On POSIX systems (including Cygwin), this maps to the access 309 * function. On Windows systems, all existing files are 310 * considered readable, and writable files are considered to 311 * have the read-only file attribute cleared. 312 */ 313 static bool TestFileAccess(const char* filename, 314 TestFilePermissions permissions); 315 static bool TestFileAccess(const std::string& filename, 316 TestFilePermissions permissions); 317/** 318 * Cross platform wrapper for stat struct 319 */ 320#if defined(_WIN32) && !defined(__CYGWIN__) 321 typedef struct _stat64 Stat_t; 322#else 323 typedef struct stat Stat_t; 324#endif 325 326 /** 327 * Cross platform wrapper for stat system call 328 * 329 * On Windows this may not work for paths longer than 250 characters 330 * due to limitations of the underlying '_wstat64' call. 331 */ 332 static int Stat(const char* path, Stat_t* buf); 333 static int Stat(const std::string& path, Stat_t* buf); 334 335 /** 336 * Return file length 337 */ 338 static unsigned long FileLength(const std::string& filename); 339 340 /** 341 Change the modification time or create a file 342 */ 343 static Status Touch(std::string const& filename, bool create); 344 345 /** 346 * Compare file modification times. 347 * Return true for successful comparison and false for error. 348 * When true is returned, result has -1, 0, +1 for 349 * f1 older, same, or newer than f2. 350 */ 351 static Status FileTimeCompare(std::string const& f1, std::string const& f2, 352 int* result); 353 354 /** 355 * Get the file extension (including ".") needed for an executable 356 * on the current platform ("" for unix, ".exe" for Windows). 357 */ 358 static const char* GetExecutableExtension(); 359 360 /** 361 * Given a path on a Windows machine, return the actual case of 362 * the path as it exists on disk. Path components that do not 363 * exist on disk are returned unchanged. Relative paths are always 364 * returned unchanged. Drive letters are always made upper case. 365 * This does nothing on non-Windows systems but return the path. 366 */ 367 static std::string GetActualCaseForPath(const std::string& path); 368 369 /** 370 * Given the path to a program executable, get the directory part of 371 * the path with the file stripped off. If there is no directory 372 * part, the empty string is returned. 373 */ 374 static std::string GetProgramPath(const std::string&); 375 static bool SplitProgramPath(const std::string& in_name, std::string& dir, 376 std::string& file, bool errorReport = true); 377 378 /** 379 * Given argv[0] for a unix program find the full path to a running 380 * executable. argv0 can be null for windows WinMain programs 381 * in this case GetModuleFileName will be used to find the path 382 * to the running executable. If argv0 is not a full path, 383 * then this will try to find the full path. If the path is not 384 * found false is returned, if found true is returned. An error 385 * message of the attempted paths is stored in errorMsg. 386 * exeName is the name of the executable. 387 * buildDir is a possibly null path to the build directory. 388 * installPrefix is a possibly null pointer to the install directory. 389 */ 390 static bool FindProgramPath(const char* argv0, std::string& pathOut, 391 std::string& errorMsg, 392 const char* exeName = nullptr, 393 const char* buildDir = nullptr, 394 const char* installPrefix = nullptr); 395 396 /** 397 * Given a path to a file or directory, convert it to a full path. 398 * This collapses away relative paths relative to the cwd argument 399 * (which defaults to the current working directory). The full path 400 * is returned. 401 */ 402 static std::string CollapseFullPath(std::string const& in_path); 403 static std::string CollapseFullPath(std::string const& in_path, 404 const char* in_base); 405 static std::string CollapseFullPath(std::string const& in_path, 406 std::string const& in_base); 407 408 /** 409 * Get the real path for a given path, removing all symlinks. In 410 * the event of an error (non-existent path, permissions issue, 411 * etc.) the original path is returned if errorMessage pointer is 412 * nullptr. Otherwise empty string is returned and errorMessage 413 * contains error description. 414 */ 415 static std::string GetRealPath(const std::string& path, 416 std::string* errorMessage = nullptr); 417 418 /** 419 * Split a path name into its root component and the rest of the 420 * path. The root component is one of the following: 421 * "/" = UNIX full path 422 * "c:/" = Windows full path (can be any drive letter) 423 * "c:" = Windows drive-letter relative path (can be any drive letter) 424 * "//" = Network path 425 * "~/" = Home path for current user 426 * "~u/" = Home path for user 'u' 427 * "" = Relative path 428 * 429 * A pointer to the rest of the path after the root component is 430 * returned. The root component is stored in the "root" string if 431 * given. 432 */ 433 static const char* SplitPathRootComponent(const std::string& p, 434 std::string* root = nullptr); 435 436 /** 437 * Split a path name into its basic components. The first component 438 * always exists and is the root returned by SplitPathRootComponent. 439 * The remaining components form the path. If there is a trailing 440 * slash then the last component is the empty string. The 441 * components can be recombined as "c[0]c[1]/c[2]/.../c[n]" to 442 * produce the original path. Home directory references are 443 * automatically expanded if expand_home_dir is true and this 444 * platform supports them. 445 * 446 * This does *not* normalize the input path. All components are 447 * preserved, including empty ones. Typically callers should use 448 * this only on paths that have already been normalized. 449 */ 450 static void SplitPath(const std::string& p, 451 std::vector<std::string>& components, 452 bool expand_home_dir = true); 453 454 /** 455 * Join components of a path name into a single string. See 456 * SplitPath for the format of the components. 457 * 458 * This does *not* normalize the input path. All components are 459 * preserved, including empty ones. Typically callers should use 460 * this only on paths that have already been normalized. 461 */ 462 static std::string JoinPath(const std::vector<std::string>& components); 463 static std::string JoinPath(std::vector<std::string>::const_iterator first, 464 std::vector<std::string>::const_iterator last); 465 466 /** 467 * Compare a path or components of a path. 468 */ 469 static bool ComparePath(const std::string& c1, const std::string& c2); 470 471 /** 472 * Return path of a full filename (no trailing slashes) 473 */ 474 static std::string GetFilenamePath(const std::string&); 475 476 /** 477 * Return file name of a full filename (i.e. file name without path) 478 */ 479 static std::string GetFilenameName(const std::string&); 480 481 /** 482 * Return longest file extension of a full filename (dot included) 483 */ 484 static std::string GetFilenameExtension(const std::string&); 485 486 /** 487 * Return shortest file extension of a full filename (dot included) 488 */ 489 static std::string GetFilenameLastExtension(const std::string& filename); 490 491 /** 492 * Return file name without extension of a full filename 493 */ 494 static std::string GetFilenameWithoutExtension(const std::string&); 495 496 /** 497 * Return file name without its last (shortest) extension 498 */ 499 static std::string GetFilenameWithoutLastExtension(const std::string&); 500 501 /** 502 * Return whether the path represents a full path (not relative) 503 */ 504 static bool FileIsFullPath(const std::string&); 505 static bool FileIsFullPath(const char*); 506 507 /** 508 * For windows return the short path for the given path, 509 * Unix just a pass through 510 */ 511 static Status GetShortPath(std::string const& path, std::string& result); 512 513 /** 514 * Read line from file. Make sure to read a full line and truncates it if 515 * requested via sizeLimit. Returns true if any data were read before the 516 * end-of-file was reached. If the has_newline argument is specified, it will 517 * be true when the line read had a newline character. 518 */ 519 static bool GetLineFromStream(std::istream& istr, std::string& line, 520 bool* has_newline = nullptr, 521 long sizeLimit = -1); 522 523 /** 524 * Get the parent directory of the directory or file 525 */ 526 static std::string GetParentDirectory(const std::string& fileOrDir); 527 528 /** 529 * Check if the given file or directory is in subdirectory of dir 530 */ 531 static bool IsSubDirectory(const std::string& fileOrDir, 532 const std::string& dir); 533 534 /** ----------------------------------------------------------------- 535 * File Manipulation Routines 536 * ----------------------------------------------------------------- 537 */ 538 539 /** 540 * Open a file considering unicode. On Windows, if 'e' is present in 541 * mode it is first discarded. 542 */ 543 static FILE* Fopen(const std::string& file, const char* mode); 544 545/** 546 * Visual C++ does not define mode_t. 547 */ 548#if defined(_MSC_VER) 549 typedef unsigned short mode_t; 550#endif 551 552 /** 553 * Make a new directory if it is not there. This function 554 * can make a full path even if none of the directories existed 555 * prior to calling this function. 556 */ 557 static Status MakeDirectory(const char* path, const mode_t* mode = nullptr); 558 static Status MakeDirectory(std::string const& path, 559 const mode_t* mode = nullptr); 560 561 /** 562 * Copy the source file to the destination file only 563 * if the two files differ. 564 */ 565 static Status CopyFileIfDifferent(std::string const& source, 566 std::string const& destination); 567 568 /** 569 * Compare the contents of two files. Return true if different 570 */ 571 static bool FilesDiffer(const std::string& source, 572 const std::string& destination); 573 574 /** 575 * Compare the contents of two files, ignoring line ending differences. 576 * Return true if different 577 */ 578 static bool TextFilesDiffer(const std::string& path1, 579 const std::string& path2); 580 581 /** 582 * Blockwise copy source to destination file 583 */ 584 static Status CopyFileContentBlockwise(std::string const& source, 585 std::string const& destination); 586 /** 587 * Clone the source file to the destination file 588 */ 589 static Status CloneFileContent(std::string const& source, 590 std::string const& destination); 591 592 /** 593 * Return true if the two files are the same file 594 */ 595 static bool SameFile(const std::string& file1, const std::string& file2); 596 597 /** 598 * Copy a file. 599 */ 600 static Status CopyFileAlways(std::string const& source, 601 std::string const& destination); 602 603 /** 604 * Copy a file. If the "always" argument is true the file is always 605 * copied. If it is false, the file is copied only if it is new or 606 * has changed. 607 */ 608 static Status CopyAFile(std::string const& source, 609 std::string const& destination, bool always = true); 610 611 /** 612 * Copy content directory to another directory with all files and 613 * subdirectories. If the "always" argument is true all files are 614 * always copied. If it is false, only files that have changed or 615 * are new are copied. 616 */ 617 static Status CopyADirectory(std::string const& source, 618 std::string const& destination, 619 bool always = true); 620 621 /** 622 * Remove a file 623 */ 624 static Status RemoveFile(std::string const& source); 625 626 /** 627 * Remove a directory 628 */ 629 static Status RemoveADirectory(std::string const& source); 630 631 /** 632 * Get the maximum full file path length 633 */ 634 static size_t GetMaximumFilePathLength(); 635 636 /** 637 * Find a file in the system PATH, with optional extra paths 638 */ 639 static std::string FindFile( 640 const std::string& name, 641 const std::vector<std::string>& path = std::vector<std::string>(), 642 bool no_system_path = false); 643 644 /** 645 * Find a directory in the system PATH, with optional extra paths 646 */ 647 static std::string FindDirectory( 648 const std::string& name, 649 const std::vector<std::string>& path = std::vector<std::string>(), 650 bool no_system_path = false); 651 652 /** 653 * Find an executable in the system PATH, with optional extra paths 654 */ 655 static std::string FindProgram( 656 const char* name, 657 const std::vector<std::string>& path = std::vector<std::string>(), 658 bool no_system_path = false); 659 static std::string FindProgram( 660 const std::string& name, 661 const std::vector<std::string>& path = std::vector<std::string>(), 662 bool no_system_path = false); 663 static std::string FindProgram( 664 const std::vector<std::string>& names, 665 const std::vector<std::string>& path = std::vector<std::string>(), 666 bool no_system_path = false); 667 668 /** 669 * Find a library in the system PATH, with optional extra paths 670 */ 671 static std::string FindLibrary(const std::string& name, 672 const std::vector<std::string>& path); 673 674 /** 675 * Return true if the file is a directory 676 */ 677 static bool FileIsDirectory(const std::string& name); 678 679 /** 680 * Return true if the file is an executable 681 */ 682 static bool FileIsExecutable(const std::string& name); 683 684 /** 685 * Return true if the file is a symlink 686 */ 687 static bool FileIsSymlink(const std::string& name); 688 689 /** 690 * Return true if the file is a FIFO 691 */ 692 static bool FileIsFIFO(const std::string& name); 693 694 /** 695 * Return true if the file has a given signature (first set of bytes) 696 */ 697 static bool FileHasSignature(const char* filename, const char* signature, 698 long offset = 0); 699 700 /** 701 * Attempt to detect and return the type of a file. 702 * Up to 'length' bytes are read from the file, if more than 'percent_bin' % 703 * of the bytes are non-textual elements, the file is considered binary, 704 * otherwise textual. Textual elements are bytes in the ASCII [0x20, 0x7E] 705 * range, but also \\n, \\r, \\t. 706 * The algorithm is simplistic, and should probably check for usual file 707 * extensions, 'magic' signature, unicode, etc. 708 */ 709 enum FileTypeEnum 710 { 711 FileTypeUnknown, 712 FileTypeBinary, 713 FileTypeText 714 }; 715 static SystemTools::FileTypeEnum DetectFileType(const char* filename, 716 unsigned long length = 256, 717 double percent_bin = 0.05); 718 719 /** 720 * Create a symbolic link if the platform supports it. Returns whether 721 * creation succeeded. 722 */ 723 static Status CreateSymlink(std::string const& origName, 724 std::string const& newName); 725 726 /** 727 * Read the contents of a symbolic link. Returns whether reading 728 * succeeded. 729 */ 730 static Status ReadSymlink(std::string const& newName, std::string& origName); 731 732 /** 733 * Try to locate the file 'filename' in the directory 'dir'. 734 * If 'filename' is a fully qualified filename, the basename of the file is 735 * used to check for its existence in 'dir'. 736 * If 'dir' is not a directory, GetFilenamePath() is called on 'dir' to 737 * get its directory first (thus, you can pass a filename as 'dir', as 738 * a convenience). 739 * 'filename_found' is assigned the fully qualified name/path of the file 740 * if it is found (not touched otherwise). 741 * If 'try_filename_dirs' is true, try to find the file using the 742 * components of its path, i.e. if we are looking for c:/foo/bar/bill.txt, 743 * first look for bill.txt in 'dir', then in 'dir'/bar, then in 'dir'/foo/bar 744 * etc. 745 * Return true if the file was found, false otherwise. 746 */ 747 static bool LocateFileInDir(const char* filename, const char* dir, 748 std::string& filename_found, 749 int try_filename_dirs = 0); 750 751 /** compute the relative path from local to remote. local must 752 be a directory. remote can be a file or a directory. 753 Both remote and local must be full paths. Basically, if 754 you are in directory local and you want to access the file in remote 755 what is the relative path to do that. For example: 756 /a/b/c/d to /a/b/c1/d1 -> ../../c1/d1 757 from /usr/src to /usr/src/test/blah/foo.cpp -> test/blah/foo.cpp 758 */ 759 static std::string RelativePath(const std::string& local, 760 const std::string& remote); 761 762 /** 763 * Return file's modified time 764 */ 765 static long int ModifiedTime(const std::string& filename); 766 767 /** 768 * Return file's creation time (Win32: works only for NTFS, not FAT) 769 */ 770 static long int CreationTime(const std::string& filename); 771 772 /** 773 * Get and set permissions of the file. If honor_umask is set, the umask 774 * is queried and applied to the given permissions. Returns false if 775 * failure. 776 * 777 * WARNING: A non-thread-safe method is currently used to get the umask 778 * if a honor_umask parameter is set to true. 779 */ 780 static Status GetPermissions(const char* file, mode_t& mode); 781 static Status GetPermissions(std::string const& file, mode_t& mode); 782 static Status SetPermissions(const char* file, mode_t mode, 783 bool honor_umask = false); 784 static Status SetPermissions(std::string const& file, mode_t mode, 785 bool honor_umask = false); 786 787 /** ----------------------------------------------------------------- 788 * Time Manipulation Routines 789 * ----------------------------------------------------------------- 790 */ 791 792 /** Get current time in seconds since Posix Epoch (Jan 1, 1970). */ 793 static double GetTime(); 794 795 /** 796 * Get current date/time 797 */ 798 static std::string GetCurrentDateTime(const char* format); 799 800 /** ----------------------------------------------------------------- 801 * Registry Manipulation Routines 802 * ----------------------------------------------------------------- 803 */ 804 805 /** 806 * Specify access to the 32-bit or 64-bit application view of 807 * registry values. The default is to match the currently running 808 * binary type. 809 */ 810 enum KeyWOW64 811 { 812 KeyWOW64_Default, 813 KeyWOW64_32, 814 KeyWOW64_64 815 }; 816 817 /** 818 * Get a list of subkeys. 819 */ 820 static bool GetRegistrySubKeys(const std::string& key, 821 std::vector<std::string>& subkeys, 822 KeyWOW64 view = KeyWOW64_Default); 823 824 /** 825 * Read a registry value 826 */ 827 static bool ReadRegistryValue(const std::string& key, std::string& value, 828 KeyWOW64 view = KeyWOW64_Default); 829 830 /** 831 * Write a registry value 832 */ 833 static bool WriteRegistryValue(const std::string& key, 834 const std::string& value, 835 KeyWOW64 view = KeyWOW64_Default); 836 837 /** 838 * Delete a registry value 839 */ 840 static bool DeleteRegistryValue(const std::string& key, 841 KeyWOW64 view = KeyWOW64_Default); 842 843 /** ----------------------------------------------------------------- 844 * Environment Manipulation Routines 845 * ----------------------------------------------------------------- 846 */ 847 848 /** 849 * Add the paths from the environment variable PATH to the 850 * string vector passed in. If env is set then the value 851 * of env will be used instead of PATH. 852 */ 853 static void GetPath(std::vector<std::string>& path, 854 const char* env = nullptr); 855 856 /** 857 * Read an environment variable 858 */ 859 static const char* GetEnv(const char* key); 860 static const char* GetEnv(const std::string& key); 861 static bool GetEnv(const char* key, std::string& result); 862 static bool GetEnv(const std::string& key, std::string& result); 863 static bool HasEnv(const char* key); 864 static bool HasEnv(const std::string& key); 865 866 /** Put a string into the environment 867 of the form var=value */ 868 static bool PutEnv(const std::string& env); 869 870 /** Remove a string from the environment. 871 Input is of the form "var" or "var=value" (value is ignored). */ 872 static bool UnPutEnv(const std::string& env); 873 874 /** 875 * Get current working directory CWD 876 */ 877 static std::string GetCurrentWorkingDirectory(); 878 879 /** 880 * Change directory to the directory specified 881 */ 882 static Status ChangeDirectory(std::string const& dir); 883 884 /** 885 * Get the result of strerror(errno) 886 */ 887 static std::string GetLastSystemError(); 888 889 /** 890 * When building DEBUG with MSVC, this enables a hook that prevents 891 * error dialogs from popping up if the program is being run from 892 * DART. 893 */ 894 static void EnableMSVCDebugHook(); 895 896 /** 897 * Get the width of the terminal window. The code may or may not work, so 898 * make sure you have some reasonable defaults prepared if the code returns 899 * some bogus size. 900 */ 901 static int GetTerminalWidth(); 902 903#if @KWSYS_NAMESPACE@_SYSTEMTOOLS_USE_TRANSLATION_MAP 904 /** 905 * Add an entry in the path translation table. 906 */ 907 static void AddTranslationPath(const std::string& dir, 908 const std::string& refdir); 909 910 /** 911 * If dir is different after CollapseFullPath is called, 912 * Then insert it into the path translation table 913 */ 914 static void AddKeepPath(const std::string& dir); 915 916 /** 917 * Update path by going through the Path Translation table; 918 */ 919 static void CheckTranslationPath(std::string& path); 920#endif 921 922 /** 923 * Delay the execution for a specified amount of time specified 924 * in milliseconds 925 */ 926 static void Delay(unsigned int msec); 927 928 /** 929 * Get the operating system name and version 930 * This is implemented for Win32 only for the moment 931 */ 932 static std::string GetOperatingSystemNameAndVersion(); 933 934 /** ----------------------------------------------------------------- 935 * URL Manipulation Routines 936 * ----------------------------------------------------------------- 937 */ 938 939 /** 940 * Parse a character string : 941 * protocol://dataglom 942 * and fill protocol as appropriate. 943 * decode the dataglom using DecodeURL if set to true. 944 * Return false if the URL does not have the required form, true otherwise. 945 */ 946 static bool ParseURLProtocol(const std::string& URL, std::string& protocol, 947 std::string& dataglom, bool decode = false); 948 949 /** 950 * Parse a string (a URL without protocol prefix) with the form: 951 * protocol://[[username[':'password]'@']hostname[':'dataport]]'/'[datapath] 952 * and fill protocol, username, password, hostname, dataport, and datapath 953 * when values are found. 954 * decode all string except the protocol using DecodeUrl if set to true. 955 * Return true if the string matches the format; false otherwise. 956 */ 957 static bool ParseURL(const std::string& URL, std::string& protocol, 958 std::string& username, std::string& password, 959 std::string& hostname, std::string& dataport, 960 std::string& datapath, bool decode = false); 961 962 /** 963 * Decode the percent-encoded string from an URL or an URI 964 * into their correct char values. 965 * Does not perform any other sort of validation. 966 * Return the decoded string 967 */ 968 static std::string DecodeURL(const std::string& url); 969 970private: 971 /** 972 * Allocate the stl map that serve as the Path Translation table. 973 */ 974 static void ClassInitialize(); 975 976 /** 977 * Deallocate the stl map that serve as the Path Translation table. 978 */ 979 static void ClassFinalize(); 980 981 /** 982 * This method prevents warning on SGI 983 */ 984 SystemToolsManager* GetSystemToolsManager() 985 { 986 return &SystemToolsManagerInstance; 987 } 988 989 friend class SystemToolsStatic; 990 friend class SystemToolsManager; 991}; 992 993} // namespace @KWSYS_NAMESPACE@ 994 995#endif 996