/*========================================================================= 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 #include "cmRegularExpression.h" #if defined(_MSC_VER) || defined(__BORLANDC__) #include #include inline int Mkdir(const char* dir) { return _mkdir(dir); } #else #include #include #include inline int Mkdir(const char* dir) { return mkdir(dir, 00700); } #endif // 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; } } } 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 ); } } // 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("^$"); cmRegularExpression comment("^#.*"); cmRegularExpression oneLiner("[ \t]*([A-Za-z_0-9]*).*\\((.*)\\)"); cmRegularExpression multiLine("[ \t]*([A-Za-z_0-9]*).*\\((.*)"); cmRegularExpression lastLine("(.*)\\)"); // 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 ) ) { 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) { cmRegularExpression argument("[\t ]*([-/\\.\\\\{}\\$A-Za-z_0-9]+)[\t ]*"); cmRegularExpression argumentWithSpaces("[\t ]*\"([-\\. /\\\\{}\\$A-Za-z_0-9]+)\"[\t ]*"); std::string arg(" "); while(arg.length() ) { arg = ""; long endpos; if (argumentWithSpaces.find(line.c_str())) { arg = argumentWithSpaces.match(1); endpos = argumentWithSpaces.end(1); } else if(argument.find(line.c_str())) { arg = argument.match(1); endpos = argument.end(1); } if(arg.length()) { arguments.push_back(arg); line = line.substr(endpos, line.length() - endpos); } } } void cmSystemTools::Error(const char* m1, const char* m2) { std::string message = "CMake Error: "; if(m1) { message += m1; } if(m2) { message += m2; } #ifdef _WIN32 ::MessageBox(0, message.c_str(), 0, MB_OK); std::cerr << message.c_str() << std::endl; #else std::cerr << message.c_str() << std::endl; #endif }