From a79868206eb59e19fd0ebca72ba435cdbb8c6a89 Mon Sep 17 00:00:00 2001 From: Sebastien Barre Date: Thu, 10 Mar 2005 12:50:17 -0500 Subject: ENH: move function from vtkKWDirectoryUtilities and vtkString to SystemTools --- Source/kwsys/SystemTools.cxx | 177 +++++++++++++++++++++++++++++++++++++++- Source/kwsys/SystemTools.hxx.in | 33 ++++++++ 2 files changed, 209 insertions(+), 1 deletion(-) diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index a5a196c..d15e5ab 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -820,6 +820,38 @@ kwsys_stl::string SystemTools::UpperCase(const kwsys_stl::string& s) return n; } +// Return a cropped string +kwsys_stl::string SystemTools::Crop(const kwsys_stl::string& s, + size_t max_len) +{ + if (!s.size() || max_len == 0 || max_len >= s.size()) + { + return s; + } + + kwsys_stl::string n; + n.reserve(max_len); + + size_t middle = max_len / 2; + + n += s.substr(0, middle); + n += s.substr(s.size() - (max_len - middle), kwsys_stl::string::npos); + + if (max_len > 2) + { + n[middle] = '.'; + if (max_len > 3) + { + n[middle - 1] = '.'; + if (max_len > 4) + { + n[middle + 1] = '.'; + } + } + } + + return n; +} // convert windows slashes to unix slashes void SystemTools::ConvertToUnixSlashes(kwsys_stl::string& path) @@ -1218,7 +1250,7 @@ int SystemTools::Strucmp(const char *s1, const char *s2) } -// return true if the file exists +// return file's modified time long int SystemTools::ModifiedTime(const char* filename) { struct stat fs; @@ -1232,6 +1264,19 @@ long int SystemTools::ModifiedTime(const char* filename) } } +// return file's creation time +long int SystemTools::CreationTime(const char* filename) +{ + struct stat fs; + if (stat(filename, &fs) != 0) + { + return 0; + } + else + { + return fs.st_ctime >= 0 ? (long int)fs.st_ctime : 0; + } +} kwsys_stl::string SystemTools::GetLastSystemError() { @@ -1988,6 +2033,136 @@ SystemTools::GetFilenameWithoutLastExtension(const kwsys_stl::string& filename) } } +bool SystemTools::FileHasSignature(const char *filename, + const char *signature, + unsigned long offset) +{ + if (!filename || !signature) + { + return false; + } + + FILE *fp; + fp = fopen(filename, "rb"); + if (!fp) + { + return false; + } + + fseek(fp, offset, SEEK_SET); + + bool res = false; + size_t signature_len = strlen(signature); + char *buffer = new char [signature_len]; + + if (fread(buffer, 1, signature_len, fp) == signature_len) + { + res = (!strncmp(buffer, signature, signature_len) ? true : false); + } + + delete [] buffer; + + fclose(fp); + return res; +} + +bool SystemTools::LocateFileInDir(const char *filename, + const char *dir, + kwsys_stl::string& filename_found, + int try_filename_dirs) +{ + if (!filename || !dir) + { + return false; + } + + // Get the basename of 'filename' + + kwsys_stl::string filename_base = SystemTools::GetFilenameName(filename); + + // Check if 'dir' is really a directory + // If win32 and matches something like C:, accept it as a dir + + kwsys_stl::string real_dir; + if (!SystemTools::FileIsDirectory(dir)) + { +#if _WIN32 + size_t dir_len = strlen(dir); + if (dir_len < 2 || dir[dir_len - 1] != ':') + { +#endif + real_dir = SystemTools::GetFilenamePath(dir); + dir = real_dir.c_str(); +#if _WIN32 + } +#endif + } + + // Try to find the file in 'dir' + + bool res = false; + if (filename_base.size() && dir) + { + size_t dir_len = strlen(dir); + int need_slash = + (dir_len && dir[dir_len - 1] != '/' && dir[dir_len - 1] != '\\'); + + kwsys_stl::string temp = dir; + if (need_slash) + { + temp += "/"; + } + temp += filename_base; + + if (SystemTools::FileExists(filename_found.c_str())) + { + res = true; + filename_found = temp; + } + + // If not found, we can try harder by appending part of the file to + // to the directory to look inside. + // Example: if we were looking for /foo/bar/yo.txt in /d1/d2, then + // try to find yo.txt in /d1/d2/bar, then /d1/d2/foo/bar, etc. + + else if (try_filename_dirs) + { + kwsys_stl::string filename_dir(filename); + kwsys_stl::string filename_dir_base; + kwsys_stl::string filename_dir_bases; + do + { + filename_dir = SystemTools::GetFilenamePath(filename_dir); + filename_dir_base = SystemTools::GetFilenameName(filename_dir); +#if _WIN32 + if (!filename_dir_base.size() || + filename_dir_base[filename_dir_base.size() - 1] == ':') +#else + if (!filename_dir_base.size()) +#endif + { + break; + } + + filename_dir_bases = filename_dir_base + "/" + filename_dir_bases; + + temp = dir; + if (need_slash) + { + temp += "/"; + } + temp += filename_dir_bases; + + res = SystemTools::LocateFileInDir( + filename_base.c_str(), temp.c_str(), filename_found, 0); + + } while (!res && filename_dir_base.size()); + } + } + + return res; +} + bool SystemTools::FileIsFullPath(const char* in_name) { kwsys_stl::string name = in_name; diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in index a9ebfe7..a546de9 100644 --- a/Source/kwsys/SystemTools.hxx.in +++ b/Source/kwsys/SystemTools.hxx.in @@ -120,6 +120,12 @@ public: static kwsys_stl::string UpperCase(const kwsys_stl::string&); /** + * Return the string cropped to a given length by removing chars in the + * center of the string and replacing them with an ellipsis (...) + */ + static kwsys_stl::string Crop(const kwsys_stl::string&, size_t max_len); + + /** * do a case-independent string comparison */ static int Strucmp(const char *s1, const char *s2); @@ -207,6 +213,29 @@ public: static bool FileIsDirectory(const char* name); static kwsys_stl::string GetCurrentWorkingDirectory(); + + ///! return true if the file has a given signature (first set of bytes) + static bool FileHasSignature(const char* filename, const char *signature, unsigned long offset = 0); + + /** + * Try to locate the file 'filename' in the directory 'dir'. + * If 'filename' is a fully qualified filename, the basename of the file is + * used to check for its existence in 'dir'. + * If 'dir' is not a directory, GetFilenamePath() is called on 'dir' to + * get its directory first (thus, you can pass a filename as 'dir', as + * a convenience). + * 'filename_found' is assigned the fully qualified name/path of the file + * if it is found (not touched otherwise). + * If 'try_filename_dirs' is true, try to find the file using the + * components of its path, i.e. if we are looking for c:/foo/bar/bill.txt, + * first look for bill.txt in 'dir', then in 'dir'/bar, then in 'dir'/foo/bar + * etc. + * Return true if the file was found, false otherwise. + */ + static bool LocateFileInDir(const char *filename, + const char *dir, + kwsys_stl::string& filename_found, + int try_filename_dirs = 0); /** * Given the path to a program executable, get the directory part of @@ -304,8 +333,12 @@ public: /** Return whether the path represents a full path (not relative). */ static bool FileIsFullPath(const char*); + /** Return file's modified time. */ static long int ModifiedTime(const char* filename); + /** Return file's creation time (Win32: works only for NTFS, not FAT). */ + static long int CreationTime(const char* filename); + ///! for windows return the short path for the given path, unix just a pass through static bool GetShortPath(const char* path, kwsys_stl::string& result); -- cgit v0.12