~ubuntu-branches/ubuntu/lucid/cmake/lucid

« back to all changes in this revision

Viewing changes to Source/cmSystemTools.cxx

  • Committer: Bazaar Package Importer
  • Author(s): Artur Rona
  • Date: 2009-12-16 11:11:54 UTC
  • mfrom: (3.1.9 sid)
  • Revision ID: james.westby@ubuntu.com-20091216111154-6accvv6yq86h2hkc
Tags: 2.8.0-5ubuntu1
* Merge from debian testing (LP: #497349). Remaining changes:
  - Keep the Replaces: on cmake-data to cover the Kubuntu version from
    Jaunty in case someone decides to do an (unsupported) Jaunty->Lucid
    upgrade.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*=========================================================================
2
 
 
3
 
  Program:   CMake - Cross-Platform Makefile Generator
4
 
  Module:    $RCSfile: cmSystemTools.cxx,v $
5
 
  Language:  C++
6
 
  Date:      $Date: 2009-02-10 22:28:08 $
7
 
  Version:   $Revision: 1.368.2.8 $
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.
11
 
 
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.
15
 
 
16
 
=========================================================================*/
 
1
/*============================================================================
 
2
  CMake - Cross Platform Makefile Generator
 
3
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
 
4
 
 
5
  Distributed under the OSI-approved BSD License (the "License");
 
6
  see accompanying file Copyright.txt for details.
 
7
 
 
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"   
18
13
#include <ctype.h>
19
14
#include <errno.h>
20
15
#include <time.h>
21
16
#include <string.h>
 
17
#include <stdlib.h>
 
18
#ifdef __QNX__
 
19
# include <malloc.h> /* for malloc/free on QNX */
 
20
#endif
22
21
 
23
22
#include <cmsys/RegularExpression.hxx>
24
23
#include <cmsys/Directory.hxx>
47
46
 
48
47
#if defined(CMAKE_BUILD_WITH_CMAKE)
49
48
#  include <libtar/libtar.h>
50
 
#  include <memory> // auto_ptr
51
49
#  include <fcntl.h>
52
50
#  include <cm_zlib.h>
53
51
#  include <cmsys/MD5.h>
235
233
    }
236
234
}
237
235
 
238
 
 
239
 
std::string cmSystemTools::RemoveEscapes(const char* s)
240
 
{
241
 
  std::string result = "";
242
 
  for(const char* ch = s; *ch; ++ch)
243
 
    {
244
 
    if(*ch == '\\' && *(ch+1) != ';')
245
 
      {
246
 
      ++ch;
247
 
      switch (*ch)
248
 
        {
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;
259
 
        case '\0':
260
 
          {
261
 
          cmSystemTools::Error("Trailing backslash in argument:\n", s);
262
 
          return result;
263
 
          }
264
 
        default:
265
 
          {
266
 
          std::string chStr(1, *ch);
267
 
          cmSystemTools::Error("Invalid escape sequence \\", chStr.c_str(),
268
 
                               "\nin argument ", s);
269
 
          }
270
 
        }
271
 
      }
272
 
    else
273
 
      {
274
 
      result.insert(result.end(), *ch);
275
 
      }
276
 
    }
277
 
  return result;
278
 
}
279
 
 
280
236
void cmSystemTools::Error(const char* m1, const char* m2,
281
237
                          const char* m3, const char* m4)
282
238
{
381
337
  for(std::basic_string<char>::iterator c = v.begin();
382
338
      c != v.end(); c++)
383
339
    {
384
 
    *c = toupper(*c);
 
340
    *c = static_cast<char>(toupper(*c));
385
341
    }
386
342
  return (v == "ON" || v == "1" || v == "YES" || v == "TRUE" || v == "Y");
387
343
}
414
370
  for(std::basic_string<char>::iterator c = v.begin();
415
371
      c != v.end(); c++)
416
372
    {
417
 
    *c = toupper(*c);
 
373
    *c = static_cast<char>(toupper(*c));
418
374
    }
419
375
  return (v == "OFF" || v == "0" || v == "NO" || v == "FALSE" || 
420
376
          v == "N" || cmSystemTools::IsNOTFOUND(v.c_str()) || v == "IGNORE");
490
446
    }
491
447
}
492
448
 
 
449
//----------------------------------------------------------------------------
 
450
class cmSystemToolsArgV
 
451
{
 
452
  char** ArgV;
 
453
public:
 
454
  cmSystemToolsArgV(char** argv): ArgV(argv) {}
 
455
  ~cmSystemToolsArgV()
 
456
    {
 
457
    for(char** arg = this->ArgV; arg && *arg; ++arg)
 
458
      {
 
459
      free(*arg);
 
460
      }
 
461
    free(this->ArgV);
 
462
    }
 
463
  void Store(std::vector<std::string>& args) const
 
464
    {
 
465
    for(char** arg = this->ArgV; arg && *arg; ++arg)
 
466
      {
 
467
      args.push_back(*arg);
 
468
      }
 
469
    }
 
470
};
 
471
 
 
472
//----------------------------------------------------------------------------
 
473
void cmSystemTools::ParseUnixCommandLine(const char* command,
 
474
                                         std::vector<std::string>& args)
 
475
{
 
476
  // Invoke the underlying parser.
 
477
  cmSystemToolsArgV argv = cmsysSystem_Parse_CommandForUnix(command, 0);
 
478
  argv.Store(args);
 
479
}
 
480
 
493
481
std::string cmSystemTools::EscapeWindowsShellArgument(const char* arg,
494
482
                                                      int shell_flags)
495
483
{
516
504
 
517
505
  bool win_path = false;
518
506
 
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] == '\\'))
525
513
    {
526
514
    win_path = true;
527
515
    }
898
886
    {
899
887
    commandInDir = command;
900
888
    }
 
889
#ifndef __VMS
901
890
  commandInDir += " 2>&1";
 
891
#endif
902
892
  command = commandInDir.c_str();
903
893
  const int BUFFER_SIZE = 4096;
904
894
  char buffer[BUFFER_SIZE];
924
914
#endif
925
915
    return false;
926
916
    }
927
 
  fgets(buffer, BUFFER_SIZE, cpipe);
 
917
  if (!fgets(buffer, BUFFER_SIZE, cpipe))
 
918
    {
 
919
    buffer[0] = 0;
 
920
    }
928
921
  while(!feof(cpipe))
929
922
    {
930
923
    if(verbose)
932
925
      cmSystemTools::Stdout(buffer);
933
926
      }
934
927
    output += buffer;
935
 
    buffer[0] = 0;
936
 
    fgets(buffer, BUFFER_SIZE, cpipe);
 
928
    if(!fgets(buffer, BUFFER_SIZE, cpipe))
 
929
      {
 
930
      buffer[0] = 0;
 
931
      }
937
932
    }
938
933
 
939
934
  retVal = pclose(cpipe);
1097
1092
  return false;
1098
1093
}
1099
1094
 
 
1095
std::string cmSystemTools::FileExistsInParentDirectories(const char* fname,
 
1096
  const char* directory, const char* toplevel)
 
1097
{
 
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)
 
1104
    {
 
1105
    std::string path = dir + "/" + file;
 
1106
    if ( cmSystemTools::FileExists(path.c_str()) )
 
1107
      {
 
1108
      return path;
 
1109
      }
 
1110
    if ( dir.size() < strlen(toplevel) )
 
1111
      {
 
1112
      break;
 
1113
      }
 
1114
    prevDir = dir;
 
1115
    dir = cmSystemTools::GetParentDirectory(dir.c_str());
 
1116
    }
 
1117
  return "";
 
1118
}
 
1119
 
1100
1120
bool cmSystemTools::cmCopyFile(const char* source, const char* destination)
1101
1121
{
1102
1122
  return Superclass::CopyFileAlways(source, destination);
1108
1128
  return Superclass::CopyFileIfDifferent(source, destination);
1109
1129
}
1110
1130
 
 
1131
//----------------------------------------------------------------------------
 
1132
bool cmSystemTools::RenameFile(const char* oldname, const char* newname)
 
1133
{
 
1134
#ifdef _WIN32
 
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)
 
1139
    {
 
1140
    /* The destination exists.  We have to replace it carefully.  The
 
1141
       MoveFileEx function does what we need but is not available on
 
1142
       Win9x.  */
 
1143
    OSVERSIONINFO osv;
 
1144
    DWORD attrs;
 
1145
 
 
1146
    /* Make sure the destination is not read only.  */
 
1147
    attrs = GetFileAttributes(newname);
 
1148
    if(attrs & FILE_ATTRIBUTE_READONLY)
 
1149
      {
 
1150
      SetFileAttributes(newname, attrs & ~FILE_ATTRIBUTE_READONLY);
 
1151
      }
 
1152
 
 
1153
    /* Check the windows version number.  */
 
1154
    osv.dwOSVersionInfoSize = sizeof(osv);
 
1155
    GetVersionEx(&osv);
 
1156
    if(osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
 
1157
      {
 
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;
 
1163
      }
 
1164
    else
 
1165
      {
 
1166
      /* This is not Win9x.  Use the MoveFileEx implementation.  */
 
1167
      return MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING) != 0;
 
1168
      }
 
1169
    }
 
1170
  else
 
1171
    {
 
1172
    /* The destination does not exist.  Just move the file.  */
 
1173
    return MoveFile(oldname, newname) != 0;
 
1174
    }
 
1175
#else
 
1176
  /* On UNIX we have an OS-provided call to do this atomically.  */
 
1177
  return rename(oldname, newname) == 0;
 
1178
#endif
 
1179
}
 
1180
 
1111
1181
bool cmSystemTools::ComputeFileMD5(const char* source, char* md5out)
1112
1182
{
1113
1183
#if defined(CMAKE_BUILD_WITH_CMAKE)
1529
1599
  return cmsys::SystemTools::RelativePath(local, remote);
1530
1600
}
1531
1601
 
1532
 
class cmDeletingCharVector : public std::vector<char*>
1533
 
{
1534
 
public:
1535
 
  ~cmDeletingCharVector()
1536
 
    {
1537
 
      for(std::vector<char*>::iterator i = this->begin();
1538
 
          i != this->end(); ++i)
1539
 
        {
1540
 
        delete []*i;
1541
 
        }
1542
 
    }
1543
 
};
1544
 
 
1545
 
        
1546
 
bool cmSystemTools::PutEnv(const char* value)
1547
 
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);
1555
 
  return ret == 0;
1556
 
}
1557
 
 
1558
1602
#ifdef CMAKE_BUILD_WITH_CMAKE
 
1603
//----------------------------------------------------------------------
1559
1604
bool cmSystemTools::UnsetEnv(const char* value)
1560
1605
{
1561
1606
#if !defined(HAVE_UNSETENV)
1568
1613
#endif
1569
1614
}
1570
1615
 
 
1616
//----------------------------------------------------------------------
1571
1617
std::vector<std::string> cmSystemTools::GetEnvironmentVariables()
1572
1618
{
1573
1619
  std::vector<std::string> env;
1578
1624
    }
1579
1625
  return env;
1580
1626
}
 
1627
 
 
1628
//----------------------------------------------------------------------
 
1629
std::vector<std::string> cmSystemTools::AppendEnv(
 
1630
  std::vector<std::string>* env)
 
1631
{
 
1632
  std::vector<std::string> origEnv = GetEnvironmentVariables();
 
1633
 
 
1634
  if (env && env->size()>0)
 
1635
    {
 
1636
    std::vector<std::string>::const_iterator eit;
 
1637
 
 
1638
    for (eit = env->begin(); eit!= env->end(); ++eit)
 
1639
      {
 
1640
      PutEnv(eit->c_str());
 
1641
      }
 
1642
    }
 
1643
 
 
1644
  return origEnv;
 
1645
}
 
1646
 
 
1647
//----------------------------------------------------------------------
 
1648
void cmSystemTools::RestoreEnv(const std::vector<std::string>& env)
 
1649
{
 
1650
  std::vector<std::string>::const_iterator eit;
 
1651
 
 
1652
  // First clear everything in the current environment:
 
1653
  //
 
1654
  std::vector<std::string> currentEnv = GetEnvironmentVariables();
 
1655
  for (eit = currentEnv.begin(); eit!= currentEnv.end(); ++eit)
 
1656
    {
 
1657
    std::string var(*eit);
 
1658
 
 
1659
    std::string::size_type pos = var.find("=");
 
1660
    if (pos != std::string::npos)
 
1661
      {
 
1662
      var = var.substr(0, pos);
 
1663
      }
 
1664
 
 
1665
    UnsetEnv(var.c_str());
 
1666
    }
 
1667
 
 
1668
  // Then put back each entry from the original environment:
 
1669
  //
 
1670
  for (eit = env.begin(); eit!= env.end(); ++eit)
 
1671
    {
 
1672
    PutEnv(eit->c_str());
 
1673
    }
 
1674
}
1581
1675
#endif
1582
1676
 
1583
1677
void cmSystemTools::EnableVSConsoleOutput()
1594
1688
#endif
1595
1689
}
1596
1690
 
1597
 
std::string cmSystemTools::MakeXMLSafe(const char* str)
1598
 
{
1599
 
  std::vector<char> result;
1600
 
  result.reserve(500);
1601
 
  const char* pos = str;
1602
 
  for ( ;*pos; ++pos)
1603
 
    {
1604
 
    char ch = *pos;
1605
 
    if ( (ch > 126 || ch < 32) && ch != 9  && ch != 10 && ch != 13 
1606
 
         && ch != '\r' )
1607
 
      {
1608
 
      char buffer[33];
1609
 
      sprintf(buffer, "&lt;%d&gt;", static_cast<int>(ch));
1610
 
      //sprintf(buffer, "&#x%0x;", (unsigned int)ch);
1611
 
      result.insert(result.end(), buffer, buffer+strlen(buffer));
1612
 
      }
1613
 
    else
1614
 
      {
1615
 
      const char* const encodedChars[] = {
1616
 
        "&amp;",
1617
 
        "&lt;",
1618
 
        "&gt;"
1619
 
      };
1620
 
      switch ( ch )
1621
 
        {
1622
 
        case '&':
1623
 
          result.insert(result.end(), encodedChars[0], encodedChars[0]+5);
1624
 
          break;
1625
 
        case '<':
1626
 
          result.insert(result.end(), encodedChars[1], encodedChars[1]+4);
1627
 
          break;
1628
 
        case '>':
1629
 
          result.insert(result.end(), encodedChars[2], encodedChars[2]+4);
1630
 
          break;
1631
 
        case '\n':
1632
 
          result.push_back('\n');
1633
 
          break;
1634
 
        case '\r': break; // Ignore \r
1635
 
        default:
1636
 
          result.push_back(ch);
1637
 
        }
1638
 
      }
1639
 
    }
1640
 
  if ( result.size() == 0 )
1641
 
    {
1642
 
    return "";
1643
 
    }
1644
 
  return std::string(&*result.begin(), result.size());
1645
 
}
1646
 
 
1647
1691
bool cmSystemTools::IsPathToFramework(const char* path)
1648
1692
{
1649
1693
  if(cmSystemTools::FileIsFullPath(path))
1762
1806
    &gzs
1763
1807
  };
1764
1808
 
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;
1770
1813
  if(verbose)
1780
1823
      options) == -1)
1781
1824
    {
1782
1825
    cmSystemTools::Error("Problem with tar_open(): ", strerror(errno));
 
1826
    delete [] realName;
1783
1827
    return false;
1784
1828
    }
1785
1829
 
 
1830
  delete [] realName;
 
1831
 
1786
1832
  std::vector<cmStdString>::const_iterator it;
1787
1833
  for (it = files.begin(); it != files.end(); ++ it )
1788
1834
    {
1814
1860
    cmSystemTools::Error("Problem with tar_close(): ", strerror(errno));
1815
1861
    return false;
1816
1862
    }
 
1863
 
1817
1864
  return true;
1818
1865
#else
1819
1866
  (void)outFileName;
1841
1888
    &gzs
1842
1889
  };
1843
1890
 
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),
1856
1902
      | 0) == -1)
1857
1903
    {
1858
1904
    cmSystemTools::Error("Problem with tar_open(): ", strerror(errno));
 
1905
    delete [] realName;
1859
1906
    return false;
1860
1907
    }
1861
1908
 
 
1909
  delete [] realName;
 
1910
 
1862
1911
  if (tar_extract_all(t, 0) != 0)
1863
1912
  {
1864
1913
    cmSystemTools::Error("Problem with tar_extract_all(): ", strerror(errno));
1895
1944
    &gzs
1896
1945
  };
1897
1946
 
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),
1910
1958
      | 0) == -1)
1911
1959
    {
1912
1960
    cmSystemTools::Error("Problem with tar_open(): ", strerror(errno));
 
1961
    delete [] realName;
1913
1962
    return false;
1914
1963
    }
1915
1964
 
 
1965
  delete [] realName;
 
1966
 
1916
1967
  while ((th_read(t)) == 0)
1917
1968
  {
1918
1969
    const char* filename = th_get_pathname(t);