| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737 |
- /*=========================================================================
- Program: Insight Segmentation & Registration Toolkit
- Module: $RCSfile$
- Language: C++
- Date: $Date$
- Version: $Revision$
- Copyright (c) 2001 Insight Consortium
- All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
- * The name of the Insight Consortium, nor the names of any consortium members,
- nor of any contributors, may be used to endorse or promote products derived
- from this software without specific prior written permission.
- * Modified source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- =========================================================================*/
- #include "cmSystemTools.h"
- #include "errno.h"
- #include "stdio.h"
- #include <sys/stat.h>
- #include "cmRegularExpression.h"
- #include <ctype.h>
- #if defined(_MSC_VER) || defined(__BORLANDC__)
- #include <windows.h>
- #include <direct.h>
- #define _unlink unlink
- inline int Mkdir(const char* dir)
- {
- return _mkdir(dir);
- }
- inline const char* Getcwd(char* buf, unsigned int len)
- {
- return _getcwd(buf, len);
- }
- inline int Chdir(const char* dir)
- {
- return _chdir(dir);
- }
- #else
- #include <sys/types.h>
- #include <fcntl.h>
- #include <unistd.h>
- inline int Mkdir(const char* dir)
- {
- return mkdir(dir, 00777);
- }
- inline const char* Getcwd(char* buf, unsigned int len)
- {
- return getcwd(buf, len);
- }
- inline int Chdir(const char* dir)
- {
- return chdir(dir);
- }
- #endif
- bool cmSystemTools::s_ErrorOccured = false;
- // adds the elements of the env variable path to the arg passed in
- void cmSystemTools::GetPath(std::vector<std::string>& path)
- {
- #if defined(_WIN32) && !defined(__CYGWIN__)
- const char* pathSep = ";";
- #else
- const 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;
- }
- }
- for(std::vector<std::string>::iterator i = path.begin();
- i != path.end(); ++i)
- {
- cmSystemTools::ConvertToUnixSlashes(*i);
- }
- }
- 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)
- {
- #if defined(_WIN32) && !defined(__CYGWIN__)
- std::string result = str;
- return "\""+result+"\"";
- #else
- std::string result = "";
- for(const char* ch = str; *ch != '\0'; ++ch)
- {
- if(*ch == ' ')
- {
- result += '\\';
- }
- result += *ch;
- }
- return result;
- #endif
- }
- // 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<std::string>& arguments)
- {
- name = "";
- arguments = std::vector<std::string>();
- 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]*$");
- // 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<std::string>& 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);
- }
- bool cmSystemTools::IsOn(const char* val)
- {
- if (!val)
- {
- return false;
- }
- std::basic_string<char> v = val;
-
- for(std::basic_string<char>::iterator c = v.begin();
- c != v.end(); c++)
- {
- *c = toupper(*c);
- }
- return (v == "ON" || v == "1" || v == "YES" || v == "TRUE" || v == "Y");
- }
- bool cmSystemTools::IsOff(const char* val)
- {
- if (!val)
- {
- return true;
- }
- std::basic_string<char> v = val;
-
- for(std::basic_string<char>::iterator c = v.begin();
- c != v.end(); c++)
- {
- *c = toupper(*c);
- }
- return (v == "OFF" || v == "0" || v == "NO" || v == "FALSE" ||
- v == "N" || v == "NOTFOUND");
- }
- bool cmSystemTools::RunCommand(const char* command,
- std::string& output)
- {
- std::string commandToFile = command;
- commandToFile += " > ";
- std::string tempFile;
- tempFile += cmSystemTools::TemporaryFileName();
- commandToFile += tempFile;
- system(commandToFile.c_str());
- std::ifstream fin(tempFile.c_str());
- if(!fin)
- {
- cmSystemTools::Error(command, " from RunCommand Faild to create output file",
- tempFile.c_str());
- return false;
- }
- const int BUFFER_SIZE = 4096;
- char buffer[BUFFER_SIZE];
- while(fin)
- {
- fin.getline(buffer, BUFFER_SIZE);
- output += buffer;
- }
- cmSystemTools::RemoveFile(tempFile.c_str());
- return true;
- }
- #ifdef _MSC_VER
- #define tempnam _tempnam
- #endif
- std::string cmSystemTools::TemporaryFileName()
- {
- return tempnam(0, "cmake");
- }
-
-
- /**
- * Find the executable with the given name. Searches the given path and then
- * the system search path. Returns the full path to the executable if it is
- * found. Otherwise, the empty string is returned.
- */
- std::string cmSystemTools::FindProgram(const char* name,
- const std::vector<std::string>& userPaths)
- {
- // See if the executable exists as written.
- if(cmSystemTools::FileExists(name))
- {
- return cmSystemTools::CollapseFullPath(name);
- }
-
- // Add the system search path to our path.
- std::vector<std::string> path = userPaths;
- cmSystemTools::GetPath(path);
-
- for(std::vector<std::string>::const_iterator p = path.begin();
- p != path.end(); ++p)
- {
- std::string tryPath = *p;
- tryPath += "/";
- tryPath += name;
- if(cmSystemTools::FileExists(tryPath.c_str()))
- {
- return cmSystemTools::CollapseFullPath(tryPath.c_str());
- }
- tryPath += cmSystemTools::GetExecutableExtension();
- if(cmSystemTools::FileExists(tryPath.c_str()))
- {
- return cmSystemTools::CollapseFullPath(tryPath.c_str());
- }
- }
-
- // Couldn't find the program.
- return "";
- }
- bool cmSystemTools::FileIsDirectory(const char* name)
- {
- struct stat fs;
- if(stat(name, &fs) == 0)
- {
- #if _WIN32
- return ((fs.st_mode & _S_IFDIR) != 0);
- #else
- return S_ISDIR(fs.st_mode);
- #endif
- }
- else
- {
- return false;
- }
- }
- std::string cmSystemTools::GetCurrentWorkingDirectory()
- {
- char buf[2048];
- std::string path = Getcwd(buf, 2048);
- return path;
- }
- /**
- * Given the path to a program executable, get the directory part of the path with the
- * file stripped off. If there is no directory part, the empty string is returned.
- */
- std::string cmSystemTools::GetProgramPath(const char* in_name)
- {
- std::string dir, file;
- cmSystemTools::SplitProgramPath(in_name, dir, file);
- return dir;
- }
- /**
- * Given the path to a program executable, get the directory part of the path with the
- * file stripped off. If there is no directory part, the empty string is returned.
- */
- void cmSystemTools::SplitProgramPath(const char* in_name,
- std::string& dir,
- std::string& file)
- {
- dir = in_name;
- file = "";
- cmSystemTools::ConvertToUnixSlashes(dir);
-
- if(!cmSystemTools::FileIsDirectory(dir.c_str()))
- {
- std::string::size_type slashPos = dir.rfind("/");
- if(slashPos != std::string::npos)
- {
- file = dir.substr(slashPos+1) + file;
- dir = dir.substr(0, slashPos);
- }
- else
- {
- file = dir;
- dir = "";
- }
- }
-
- if((dir != "") && !cmSystemTools::FileIsDirectory(dir.c_str()))
- {
- std::string oldDir = in_name;
- cmSystemTools::ConvertToUnixSlashes(oldDir);
- cmSystemTools::Error("Error splitting file name off end of path:\n",
- oldDir.c_str());
- dir = in_name;
- return;
- }
- }
- /**
- * Given a path to a file or directory, convert it to a full path.
- * This collapses away relative paths. The full path is returned.
- */
- std::string cmSystemTools::CollapseFullPath(const char* in_name)
- {
- std::string dir, file;
- cmSystemTools::SplitProgramPath(in_name, dir, file);
- // Ultra-hack warning:
- // This changes to the target directory, saves the working directory,
- // and then changes back to the original working directory.
- std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
- if(dir != "") { Chdir(dir.c_str()); }
- std::string newDir = cmSystemTools::GetCurrentWorkingDirectory();
- Chdir(cwd.c_str());
- cmSystemTools::ConvertToUnixSlashes(newDir);
- std::string newPath = newDir+"/"+file;
-
- return newPath;
- }
|