1
/*=========================================================================
3
Program: CMake - Cross-Platform Makefile Generator
4
Module: $RCSfile: cmSystemTools.cxx,v $
6
Date: $Date: 2009-02-10 22:28:08 $
7
Version: $Revision: 1.368.2.8 $
9
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
10
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
12
This software is distributed WITHOUT ANY WARRANTY; without even
13
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14
PURPOSE. See the above copyright notices for more information.
16
=========================================================================*/
1
/*============================================================================
2
CMake - Cross Platform Makefile Generator
3
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
5
Distributed under the OSI-approved BSD License (the "License");
6
see accompanying file Copyright.txt for details.
8
This software is distributed WITHOUT ANY WARRANTY; without even the
9
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10
See the License for more information.
11
============================================================================*/
17
12
#include "cmSystemTools.h"
21
16
#include <string.h>
19
# include <malloc.h> /* for malloc/free on QNX */
23
22
#include <cmsys/RegularExpression.hxx>
24
23
#include <cmsys/Directory.hxx>
239
std::string cmSystemTools::RemoveEscapes(const char* s)
241
std::string result = "";
242
for(const char* ch = s; *ch; ++ch)
244
if(*ch == '\\' && *(ch+1) != ';')
249
case '\\': result.insert(result.end(), '\\'); break;
250
case '"': result.insert(result.end(), '"'); break;
251
case ' ': result.insert(result.end(), ' '); break;
252
case 't': result.insert(result.end(), '\t'); break;
253
case 'n': result.insert(result.end(), '\n'); break;
254
case 'r': result.insert(result.end(), '\r'); break;
255
case '#': result.insert(result.end(), '#'); break;
256
case '(': result.insert(result.end(), '('); break;
257
case ')': result.insert(result.end(), ')'); break;
258
case '0': result.insert(result.end(), '\0'); break;
261
cmSystemTools::Error("Trailing backslash in argument:\n", s);
266
std::string chStr(1, *ch);
267
cmSystemTools::Error("Invalid escape sequence \\", chStr.c_str(),
268
"\nin argument ", s);
274
result.insert(result.end(), *ch);
280
236
void cmSystemTools::Error(const char* m1, const char* m2,
281
237
const char* m3, const char* m4)
414
370
for(std::basic_string<char>::iterator c = v.begin();
415
371
c != v.end(); c++)
373
*c = static_cast<char>(toupper(*c));
419
375
return (v == "OFF" || v == "0" || v == "NO" || v == "FALSE" ||
420
376
v == "N" || cmSystemTools::IsNOTFOUND(v.c_str()) || v == "IGNORE");
449
//----------------------------------------------------------------------------
450
class cmSystemToolsArgV
454
cmSystemToolsArgV(char** argv): ArgV(argv) {}
457
for(char** arg = this->ArgV; arg && *arg; ++arg)
463
void Store(std::vector<std::string>& args) const
465
for(char** arg = this->ArgV; arg && *arg; ++arg)
467
args.push_back(*arg);
472
//----------------------------------------------------------------------------
473
void cmSystemTools::ParseUnixCommandLine(const char* command,
474
std::vector<std::string>& args)
476
// Invoke the underlying parser.
477
cmSystemToolsArgV argv = cmsysSystem_Parse_CommandForUnix(command, 0);
493
481
std::string cmSystemTools::EscapeWindowsShellArgument(const char* arg,
517
505
bool win_path = false;
519
if ( command[0] != '/' && command[1] == ':' && command[2] == '\\' ||
520
command[0] == '\"' && command[1] != '/' && command[2] == ':'
521
&& command[3] == '\\' ||
522
command[0] == '\'' && command[1] != '/' && command[2] == ':'
523
&& command[3] == '\\' ||
524
command[0] == '\\' && command[1] == '\\')
507
if ((command[0] != '/' && command[1] == ':' && command[2] == '\\') ||
508
(command[0] == '\"' && command[1] != '/' && command[2] == ':'
509
&& command[3] == '\\') ||
510
(command[0] == '\'' && command[1] != '/' && command[2] == ':'
511
&& command[3] == '\\') ||
512
(command[0] == '\\' && command[1] == '\\'))
932
925
cmSystemTools::Stdout(buffer);
934
927
output += buffer;
936
fgets(buffer, BUFFER_SIZE, cpipe);
928
if(!fgets(buffer, BUFFER_SIZE, cpipe))
939
934
retVal = pclose(cpipe);
1095
std::string cmSystemTools::FileExistsInParentDirectories(const char* fname,
1096
const char* directory, const char* toplevel)
1098
std::string file = fname;
1099
cmSystemTools::ConvertToUnixSlashes(file);
1100
std::string dir = directory;
1101
cmSystemTools::ConvertToUnixSlashes(dir);
1102
std::string prevDir;
1103
while(dir != prevDir)
1105
std::string path = dir + "/" + file;
1106
if ( cmSystemTools::FileExists(path.c_str()) )
1110
if ( dir.size() < strlen(toplevel) )
1115
dir = cmSystemTools::GetParentDirectory(dir.c_str());
1100
1120
bool cmSystemTools::cmCopyFile(const char* source, const char* destination)
1102
1122
return Superclass::CopyFileAlways(source, destination);
1108
1128
return Superclass::CopyFileIfDifferent(source, destination);
1131
//----------------------------------------------------------------------------
1132
bool cmSystemTools::RenameFile(const char* oldname, const char* newname)
1135
/* On Windows the move functions will not replace existing files.
1136
Check if the destination exists. */
1137
struct stat newFile;
1138
if(stat(newname, &newFile) == 0)
1140
/* The destination exists. We have to replace it carefully. The
1141
MoveFileEx function does what we need but is not available on
1146
/* Make sure the destination is not read only. */
1147
attrs = GetFileAttributes(newname);
1148
if(attrs & FILE_ATTRIBUTE_READONLY)
1150
SetFileAttributes(newname, attrs & ~FILE_ATTRIBUTE_READONLY);
1153
/* Check the windows version number. */
1154
osv.dwOSVersionInfoSize = sizeof(osv);
1156
if(osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
1158
/* This is Win9x. There is no MoveFileEx implementation. We
1159
cannot quite rename the file atomically. Just delete the
1160
destination and then move the file. */
1161
DeleteFile(newname);
1162
return MoveFile(oldname, newname) != 0;
1166
/* This is not Win9x. Use the MoveFileEx implementation. */
1167
return MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING) != 0;
1172
/* The destination does not exist. Just move the file. */
1173
return MoveFile(oldname, newname) != 0;
1176
/* On UNIX we have an OS-provided call to do this atomically. */
1177
return rename(oldname, newname) == 0;
1111
1181
bool cmSystemTools::ComputeFileMD5(const char* source, char* md5out)
1113
1183
#if defined(CMAKE_BUILD_WITH_CMAKE)
1529
1599
return cmsys::SystemTools::RelativePath(local, remote);
1532
class cmDeletingCharVector : public std::vector<char*>
1535
~cmDeletingCharVector()
1537
for(std::vector<char*>::iterator i = this->begin();
1538
i != this->end(); ++i)
1546
bool cmSystemTools::PutEnv(const char* value)
1548
static cmDeletingCharVector localEnvironment;
1549
char* envVar = new char[strlen(value)+1];
1550
strcpy(envVar, value);
1551
int ret = putenv(envVar);
1552
// save the pointer in the static vector so that it can
1553
// be deleted on exit
1554
localEnvironment.push_back(envVar);
1558
1602
#ifdef CMAKE_BUILD_WITH_CMAKE
1603
//----------------------------------------------------------------------
1559
1604
bool cmSystemTools::UnsetEnv(const char* value)
1561
1606
#if !defined(HAVE_UNSETENV)
1628
//----------------------------------------------------------------------
1629
std::vector<std::string> cmSystemTools::AppendEnv(
1630
std::vector<std::string>* env)
1632
std::vector<std::string> origEnv = GetEnvironmentVariables();
1634
if (env && env->size()>0)
1636
std::vector<std::string>::const_iterator eit;
1638
for (eit = env->begin(); eit!= env->end(); ++eit)
1640
PutEnv(eit->c_str());
1647
//----------------------------------------------------------------------
1648
void cmSystemTools::RestoreEnv(const std::vector<std::string>& env)
1650
std::vector<std::string>::const_iterator eit;
1652
// First clear everything in the current environment:
1654
std::vector<std::string> currentEnv = GetEnvironmentVariables();
1655
for (eit = currentEnv.begin(); eit!= currentEnv.end(); ++eit)
1657
std::string var(*eit);
1659
std::string::size_type pos = var.find("=");
1660
if (pos != std::string::npos)
1662
var = var.substr(0, pos);
1665
UnsetEnv(var.c_str());
1668
// Then put back each entry from the original environment:
1670
for (eit = env.begin(); eit!= env.end(); ++eit)
1672
PutEnv(eit->c_str());
1583
1677
void cmSystemTools::EnableVSConsoleOutput()
1597
std::string cmSystemTools::MakeXMLSafe(const char* str)
1599
std::vector<char> result;
1600
result.reserve(500);
1601
const char* pos = str;
1605
if ( (ch > 126 || ch < 32) && ch != 9 && ch != 10 && ch != 13
1609
sprintf(buffer, "<%d>", static_cast<int>(ch));
1610
//sprintf(buffer, "&#x%0x;", (unsigned int)ch);
1611
result.insert(result.end(), buffer, buffer+strlen(buffer));
1615
const char* const encodedChars[] = {
1623
result.insert(result.end(), encodedChars[0], encodedChars[0]+5);
1626
result.insert(result.end(), encodedChars[1], encodedChars[1]+4);
1629
result.insert(result.end(), encodedChars[2], encodedChars[2]+4);
1632
result.push_back('\n');
1634
case '\r': break; // Ignore \r
1636
result.push_back(ch);
1640
if ( result.size() == 0 )
1644
return std::string(&*result.begin(), result.size());
1647
1691
bool cmSystemTools::IsPathToFramework(const char* path)
1649
1693
if(cmSystemTools::FileIsFullPath(path))
1765
// Ok, this libtar is not const safe. for now use auto_ptr hack
1809
// This libtar is not const safe. Make a non-const copy of outFileName
1766
1810
char* realName = new char[ strlen(outFileName) + 1 ];
1767
std::auto_ptr<char> realNamePtr(realName);
1768
1811
strcpy(realName, outFileName);
1769
1812
int options = 0;
1844
// Ok, this libtar is not const safe. for now use auto_ptr hack
1891
// This libtar is not const safe. Make a non-const copy of outFileName
1845
1892
char* realName = new char[ strlen(outFileName) + 1 ];
1846
std::auto_ptr<char> realNamePtr(realName);
1847
1893
strcpy(realName, outFileName);
1848
1894
if (tar_open(&t, realName,
1849
1895
(gzip? &gztype : NULL),
1858
1904
cmSystemTools::Error("Problem with tar_open(): ", strerror(errno));
1862
1911
if (tar_extract_all(t, 0) != 0)
1864
1913
cmSystemTools::Error("Problem with tar_extract_all(): ", strerror(errno));
1898
// Ok, this libtar is not const safe. for now use auto_ptr hack
1947
// This libtar is not const safe. Make a non-const copy of outFileName
1899
1948
char* realName = new char[ strlen(outFileName) + 1 ];
1900
std::auto_ptr<char> realNamePtr(realName);
1901
1949
strcpy(realName, outFileName);
1902
1950
if (tar_open(&t, realName,
1903
1951
(gzip? &gztype : NULL),