/*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile$ Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) 2000 National Library of Medicine All rights reserved. See COPYRIGHT.txt for copyright details. =========================================================================*/ #include "cmSystemTools.h" #include "errno.h" #include "stdio.h" #include #include "cmRegularExpression.h" #if defined(_MSC_VER) || defined(__BORLANDC__) #include #include #define _unlink unlink inline int Mkdir(const char* dir) { return _mkdir(dir); } #else #include #include #include inline int Mkdir(const char* dir) { return mkdir(dir, 00777); } #endif bool cmSystemTools::s_ErrorOccured = false; // adds the elements of the env variable path to the arg passed in void cmSystemTools::GetPath(std::vector& path) { #if defined(_WIN32) && !defined(__CYGWIN__) char* pathSep = ";"; #else char* pathSep = ":"; #endif std::string pathEnv = getenv("PATH"); std::string::size_type start =0; bool done = false; while(!done) { std::string::size_type endpos = pathEnv.find(pathSep, start); if(endpos != std::string::npos) { path.push_back(pathEnv.substr(start, endpos-start)); start = endpos+1; } else { done = true; } } } const char* cmSystemTools::GetExecutableExtension() { #if defined(_WIN32) return ".exe"; #else return ""; #endif } bool cmSystemTools::MakeDirectory(const char* path) { std::string dir = path; // replace all of the \ with / size_t pos = 0; while((pos = dir.find('\\', pos)) != std::string::npos) { dir[pos] = '/'; pos++; } pos = dir.find(':'); if(pos == std::string::npos) { pos = 0; } while((pos = dir.find('/', pos)) != std::string::npos) { std::string topdir = dir.substr(0, pos); Mkdir(topdir.c_str()); pos++; } if(Mkdir(path) != 0) { // if it is some other error besides directory exists // then return false if(errno != EEXIST) { return false; } } return true; } // replace replace with with as many times as it shows up in source. // write the result into source. void cmSystemTools::ReplaceString(std::string& source, const char* replace, const char* with) { int lengthReplace = strlen(replace); std::string rest; size_t start = source.find(replace); while(start != std::string::npos) { rest = source.substr(start+lengthReplace); source = source.substr(0, start); source += with; source += rest; start = source.find(replace, start + lengthReplace ); } } std::string cmSystemTools::EscapeSpaces(const char* str) { std::string result = ""; for(const char* ch = str; *ch != '\0'; ++ch) { if(*ch == ' ') { result += '\\'; } result += *ch; } return result; } // return true if the file exists bool cmSystemTools::FileExists(const char* filename) { struct stat fs; if (stat(filename, &fs) != 0) { return false; } else { return true; } } // convert windows slashes to unix slashes \ with / void cmSystemTools::ConvertToUnixSlashes(std::string& path) { std::string::size_type pos = path.find('\\'); while(pos != std::string::npos) { path[pos] = '/'; pos = path.find('\\'); } // remove any trailing slash if(path[path.size()-1] == '/') { path = path.substr(0, path.size()-1); } } int cmSystemTools::Grep(const char* dir, const char* file, const char* expression) { std::string path = dir; path += "/"; path += file; std::ifstream fin(path.c_str()); char buffer[2056]; int count = 0; cmRegularExpression reg(expression); while(fin) { fin.getline(buffer, sizeof(buffer)); count += reg.find(buffer); } return count; } void cmSystemTools::ConvertCygwinPath(std::string& pathname) { if(pathname.find("/cygdrive/") != std::string::npos) { std::string cygStuff = pathname.substr(0, 11); std::string replace; replace += cygStuff.at(10); replace += ":"; cmSystemTools::ReplaceString(pathname, cygStuff.c_str(), replace.c_str()); } } bool cmSystemTools::ParseFunction(std::ifstream& fin, std::string& name, std::vector& arguments) { name = ""; arguments = std::vector(); const int BUFFER_SIZE = 4096; char inbuffer[BUFFER_SIZE]; if(!fin) { return false; } if(fin.getline(inbuffer, BUFFER_SIZE ) ) { cmRegularExpression blankLine("^[ \t]*$"); cmRegularExpression comment("^[ \t]*#.*$"); cmRegularExpression oneLiner("^[ \t]*([A-Za-z_0-9]*)[ \t]*\\((.*)\\)[ \t]*$"); cmRegularExpression multiLine("^[ \t]*([A-Za-z_0-9]*)[ \t]*\\((.*)$"); cmRegularExpression lastLine("^(.*)\\)[ \t]*$"); // BEGIN VERBATIM JUNK SHOULD BE REMOVED cmRegularExpression verbatim("BEGIN MAKE VERBATIM"); if(verbatim.find(inbuffer)) { cmRegularExpression endVerbatim("END MAKE VERBATIM"); name = "VERBATIM"; bool done = false; while(!done) { if(fin.getline(inbuffer, BUFFER_SIZE)) { if(endVerbatim.find(inbuffer)) { done = true; } else { arguments.push_back(inbuffer); } } else { done = true; } } return true; } // END VERBATIM JUNK SHOULD BE REMOVED // check for black line or comment if(blankLine.find(inbuffer) || comment.find(inbuffer)) { return false; } // look for a oneline fun(arg arg2) else if(oneLiner.find(inbuffer)) { // the arguments are the second match std::string args = oneLiner.match(2); name = oneLiner.match(1); // break up the arguments cmSystemTools::GetArguments(args, arguments); return true; } // look for a start of a multiline with no trailing ")" fun(arg arg2 else if(multiLine.find(inbuffer)) { name = multiLine.match(1); std::string args = multiLine.match(2); cmSystemTools::GetArguments(args, arguments); // Read lines until the closing paren is hit bool done = false; while(!done) { // read lines until the end paren is found if(fin.getline(inbuffer, BUFFER_SIZE ) ) { // Check for comment lines and ignore them. if(blankLine.find(inbuffer) || comment.find(inbuffer)) { continue; } // Is this the last line? if(lastLine.find(inbuffer)) { done = true; std::string args = lastLine.match(1); cmSystemTools::GetArguments(args, arguments); } else { std::string line = inbuffer; cmSystemTools::GetArguments(line, arguments); } } else { cmSystemTools::Error("Parse error in read function missing end )", inbuffer); return false; } } return true; } else { cmSystemTools::Error("Parse error in read function ", inbuffer); return false; } } return false; } void cmSystemTools::GetArguments(std::string& line, std::vector& arguments) { // Match a normal argument (not quoted, no spaces). cmRegularExpression normalArgument("[\t ]*([^\" \t]+)[\t ]*"); // Match a quoted argument (surrounded by double quotes, spaces allowed). cmRegularExpression quotedArgument("[\t ]*(\"[^\"]*\")[\t ]*"); bool done = false; while(!done) { std::string arg; long endpos; bool foundQuoted = quotedArgument.find(line.c_str()); bool foundNormal = normalArgument.find(line.c_str()); if(foundQuoted && foundNormal) { // Both matches were found. Take the earlier one. if(normalArgument.start(1) < quotedArgument.start(1)) { arg = normalArgument.match(1); endpos = normalArgument.end(1); } else { arg = quotedArgument.match(1); endpos = quotedArgument.end(1); // Strip off the double quotes on the ends. arg = arg.substr(1, arg.length()-2); } } else if (foundQuoted) { arg = quotedArgument.match(1); endpos = quotedArgument.end(1); // Strip off the double quotes on the ends. arg = arg.substr(1, arg.length()-2); } else if(foundNormal) { arg = normalArgument.match(1); endpos = normalArgument.end(1); } else { done = true; } if(!done) { arguments.push_back(arg); line = line.substr(endpos, line.length() - endpos); } } } void cmSystemTools::Error(const char* m1, const char* m2, const char* m3, const char* m4) { std::string message = "CMake Error: "; if(m1) { message += m1; } if(m2) { message += m2; } if(m3) { message += m3; } if(m4) { message += m4; } cmSystemTools::s_ErrorOccured = true; #if defined(_WIN32) && !defined(__CYGWIN__) ::MessageBox(0, message.c_str(), 0, MB_OK); std::cerr << message.c_str() << std::endl; #else std::cerr << message.c_str() << std::endl; #endif } void cmSystemTools::CopyFileIfDifferent(const char* source, const char* destination) { if(cmSystemTools::FilesDiffer(source, destination)) { cmSystemTools::cmCopyFile(source, destination); } } bool cmSystemTools::FilesDiffer(const char* source, const char* destination) { struct stat statSource; if (stat(source, &statSource) != 0) { return true; } struct stat statDestination; if (stat(destination, &statDestination) != 0) { return true; } if(statSource.st_size != statDestination.st_size) { return true; } std::ifstream finSource(source); std::ifstream finDestination(destination); if(!finSource || !finDestination) { return true; } while(finSource && finDestination) { char s, d; finSource >> s; finDestination >> d; if(s != d) { return true; } } return false; } void cmSystemTools::cmCopyFile(const char* source, const char* destination) { std::ifstream fin(source); char buff[4096]; std::ofstream fout(destination); if(!fout ) { cmSystemTools::Error("CopyFile failed to open input file", source); } if(!fin) { cmSystemTools::Error("CopyFile failed to open output file", destination); } while(fin) { fin.getline(buff, 4096); if(fin) { fout << buff << "\n"; } } } // return true if the file exists long int cmSystemTools::ModifiedTime(const char* filename) { struct stat fs; if (stat(filename, &fs) != 0) { return 0; } else { return (long int)fs.st_mtime; } } void cmSystemTools::RemoveFile(const char* source) { unlink(source); }