2001-01-11 22:55:47 +03:00
/*=========================================================================
Program : Insight Segmentation & Registration Toolkit
Module : $ RCSfile $
Language : C + +
Date : $ Date $
Version : $ Revision $
2002-01-21 23:30:43 +03:00
Copyright ( c ) 2002 Insight Consortium . All rights reserved .
See ITKCopyright . txt or http : //www.itk.org/HTML/Copyright.htm for details.
2001-01-11 22:55:47 +03:00
2002-01-21 23:30:43 +03:00
This software is distributed WITHOUT ANY WARRANTY ; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE . See the above copyright notices for more information .
2001-01-11 22:55:47 +03:00
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
2001-09-28 00:50:59 +04:00
# include "cmSystemTools.h"
2000-08-29 23:26:29 +04:00
# include "errno.h"
2001-02-23 03:24:43 +03:00
# include "stdio.h"
2000-09-12 13:30:35 +04:00
# include <sys/stat.h>
2000-09-27 23:01:19 +04:00
# include "cmRegularExpression.h"
2001-04-26 18:49:12 +04:00
# include <ctype.h>
2001-06-21 20:01:18 +04:00
# include "cmDirectory.h"
2000-09-12 13:30:35 +04:00
2001-09-28 00:50:59 +04:00
// support for realpath call
# ifndef _WIN32
# include <limits.h>
# include <stdlib.h>
# include <sys/param.h>
2002-03-06 02:25:13 +03:00
# include <sys/wait.h>
2001-09-28 00:50:59 +04:00
# endif
2001-01-05 19:41:20 +03:00
# if defined(_MSC_VER) || defined(__BORLANDC__)
2002-03-14 19:11:39 +03:00
# include <string.h>
2000-08-29 23:26:29 +04:00
# include <windows.h>
2000-09-12 13:30:35 +04:00
# include <direct.h>
2001-02-23 03:24:43 +03:00
# define _unlink unlink
2000-09-12 13:30:35 +04:00
inline int Mkdir ( const char * dir )
{
return _mkdir ( dir ) ;
}
2001-05-04 00:55:18 +04:00
inline const char * Getcwd ( char * buf , unsigned int len )
{
return _getcwd ( buf , len ) ;
}
inline int Chdir ( const char * dir )
{
2001-06-06 01:41:16 +04:00
# if defined(__BORLANDC__)
return chdir ( dir ) ;
# else
2001-05-04 00:55:18 +04:00
return _chdir ( dir ) ;
2001-06-06 01:41:16 +04:00
# endif
2001-05-04 00:55:18 +04:00
}
2000-09-12 13:30:35 +04:00
# else
# include <sys/types.h>
# include <fcntl.h>
# include <unistd.h>
inline int Mkdir ( const char * dir )
{
2001-02-27 20:00:36 +03:00
return mkdir ( dir , 00777 ) ;
2000-09-12 13:30:35 +04:00
}
2001-05-04 00:55:18 +04:00
inline const char * Getcwd ( char * buf , unsigned int len )
{
return getcwd ( buf , len ) ;
}
inline int Chdir ( const char * dir )
{
return chdir ( dir ) ;
}
2000-09-12 13:30:35 +04:00
# endif
2001-11-27 02:28:27 +03:00
bool cmSystemTools : : s_DisableRunCommandOutput = false ;
2001-02-23 03:24:43 +03:00
bool cmSystemTools : : s_ErrorOccured = false ;
2001-11-20 01:52:08 +03:00
bool cmSystemTools : : s_DisableMessages = false ;
2001-02-23 03:24:43 +03:00
2001-10-29 18:19:34 +03:00
void ( * cmSystemTools : : s_ErrorCallback ) ( const char * , const char * , bool & ) ;
2001-02-16 19:34:23 +03:00
// 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__)
2001-04-16 23:40:40 +04:00
const char * pathSep = " ; " ;
2001-02-16 19:34:23 +03:00
# else
2001-04-16 23:40:40 +04:00
const char * pathSep = " : " ;
2001-02-16 19:34:23 +03:00
# endif
std : : string pathEnv = getenv ( " PATH " ) ;
2001-05-25 22:31:35 +04:00
// A hack to make the below algorithm work.
if ( pathEnv [ pathEnv . length ( ) - 1 ] ! = ' : ' )
{
2001-05-25 23:33:22 +04:00
pathEnv + = pathSep ;
2001-05-25 22:31:35 +04:00
}
2001-02-16 19:34:23 +03:00
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 ;
}
}
2001-05-04 19:30:46 +04:00
for ( std : : vector < std : : string > : : iterator i = path . begin ( ) ;
i ! = path . end ( ) ; + + i )
{
cmSystemTools : : ConvertToUnixSlashes ( * i ) ;
}
2001-02-16 19:34:23 +03:00
}
2000-08-29 23:26:29 +04:00
2001-03-08 18:30:18 +03:00
const char * cmSystemTools : : GetExecutableExtension ( )
{
2001-06-27 23:42:27 +04:00
# if defined(_WIN32) || defined(__CYGWIN__)
2001-03-08 18:30:18 +03:00
return " .exe " ;
# else
return " " ;
# endif
}
2000-08-29 23:26:29 +04:00
bool cmSystemTools : : MakeDirectory ( const char * path )
{
2001-08-28 18:57:25 +04:00
if ( cmSystemTools : : FileExists ( path ) )
{
return true ;
}
2000-08-29 23:26:29 +04:00
std : : string dir = path ;
2001-08-29 17:44:27 +04:00
if ( dir . size ( ) = = 0 )
{
return false ;
}
2001-05-25 03:17:47 +04:00
cmSystemTools : : ConvertToUnixSlashes ( dir ) ;
std : : string : : size_type pos = dir . find ( ' : ' ) ;
2000-08-29 23:26:29 +04:00
if ( pos = = std : : string : : npos )
{
pos = 0 ;
}
2001-08-28 18:57:25 +04:00
std : : string topdir ;
2000-08-29 23:26:29 +04:00
while ( ( pos = dir . find ( ' / ' , pos ) ) ! = std : : string : : npos )
{
2001-08-28 18:57:25 +04:00
topdir = dir . substr ( 0 , pos ) ;
2000-09-12 13:30:35 +04:00
Mkdir ( topdir . c_str ( ) ) ;
2000-08-29 23:26:29 +04:00
pos + + ;
}
2001-08-29 17:44:27 +04:00
if ( dir [ dir . size ( ) - 1 ] = = ' / ' )
2001-08-28 18:57:25 +04:00
{
topdir = dir . substr ( 0 , dir . size ( ) ) ;
}
else
{
topdir = dir ;
}
if ( Mkdir ( topdir . c_str ( ) ) ! = 0 )
2000-08-29 23:26:29 +04:00
{
2001-06-06 01:41:16 +04:00
// There is a bug in the Borland Run time library which makes MKDIR
// return EACCES when it should return EEXISTS
2000-08-29 23:26:29 +04:00
// if it is some other error besides directory exists
// then return false
2001-08-28 18:57:25 +04:00
if ( ( errno ! = EEXIST )
# ifdef __BORLANDC__
& & ( errno ! = EACCES )
# endif
)
2000-08-29 23:26:29 +04:00
{
2001-08-28 18:57:25 +04:00
cmSystemTools : : Error ( " Faild to create directory: " , path ) ;
2000-08-29 23:26:29 +04:00
return false ;
}
}
return true ;
}
2000-09-12 13:30:35 +04:00
// replace replace with with as many times as it shows up in source.
// write the result into source.
2000-08-29 23:26:29 +04:00
void cmSystemTools : : ReplaceString ( std : : string & source ,
const char * replace ,
const char * with )
{
2002-02-26 02:14:01 +03:00
std : : string : : size_type lengthReplace = strlen ( replace ) ;
2000-09-01 18:43:10 +04:00
std : : string rest ;
2002-02-26 02:14:01 +03:00
std : : string : : size_type start = source . find ( replace ) ;
2000-08-29 23:26:29 +04:00
while ( start ! = std : : string : : npos )
{
2000-09-01 18:43:10 +04:00
rest = source . substr ( start + lengthReplace ) ;
source = source . substr ( 0 , start ) ;
2000-08-29 23:26:29 +04:00
source + = with ;
2000-09-01 18:43:10 +04:00
source + = rest ;
start = source . find ( replace , start + lengthReplace ) ;
2000-08-29 23:26:29 +04:00
}
}
2000-09-12 13:30:35 +04:00
2001-05-17 23:48:32 +04:00
# if defined(_WIN32) && !defined(__CYGWIN__)
2001-05-12 01:11:06 +04:00
// Get the data of key value.
// Example :
// HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore\2.1\InstallPath
// => will return the data of the "default" value of the key
2001-05-15 00:47:09 +04:00
// HKEY_LOCAL_MACHINE\SOFTWARE\Scriptics\Tcl\8.4;Root
2001-05-12 01:11:06 +04:00
// => will return the data of the "Root" value of the key
2001-05-11 18:53:17 +04:00
bool ReadAValue ( std : : string & res , const char * key )
{
// find the primary key
std : : string primary = key ;
2001-05-12 01:11:06 +04:00
std : : string second ;
std : : string valuename ;
2001-05-11 18:53:17 +04:00
size_t start = primary . find ( " \\ " ) ;
if ( start = = std : : string : : npos )
{
return false ;
}
2001-05-15 00:47:09 +04:00
size_t valuenamepos = primary . find ( " ; " ) ;
2001-05-12 01:11:06 +04:00
if ( valuenamepos ! = std : : string : : npos )
{
valuename = primary . substr ( valuenamepos + 1 ) ;
}
second = primary . substr ( start + 1 , valuenamepos - start - 1 ) ;
primary = primary . substr ( 0 , start ) ;
2001-05-11 18:53:17 +04:00
HKEY primaryKey ;
if ( primary = = " HKEY_CURRENT_USER " )
{
primaryKey = HKEY_CURRENT_USER ;
}
if ( primary = = " HKEY_CURRENT_CONFIG " )
{
primaryKey = HKEY_CURRENT_CONFIG ;
}
if ( primary = = " HKEY_CLASSES_ROOT " )
{
primaryKey = HKEY_CLASSES_ROOT ;
}
if ( primary = = " HKEY_LOCAL_MACHINE " )
{
primaryKey = HKEY_LOCAL_MACHINE ;
}
if ( primary = = " HKEY_USERS " )
{
primaryKey = HKEY_USERS ;
}
HKEY hKey ;
if ( RegOpenKeyEx ( primaryKey , second . c_str ( ) ,
0 , KEY_READ , & hKey ) ! = ERROR_SUCCESS )
{
return false ;
}
else
{
DWORD dwType , dwSize ;
dwSize = 1023 ;
2001-05-12 01:11:06 +04:00
char data [ 1024 ] ;
if ( RegQueryValueEx ( hKey , ( LPTSTR ) valuename . c_str ( ) , NULL , & dwType ,
( BYTE * ) data , & dwSize ) = = ERROR_SUCCESS )
2001-05-11 18:53:17 +04:00
{
if ( dwType = = REG_SZ )
{
2001-05-12 01:11:06 +04:00
res = data ;
2001-05-11 18:53:17 +04:00
return true ;
}
}
}
return false ;
}
# endif
// replace replace with with as many times as it shows up in source.
// write the result into source.
void cmSystemTools : : ExpandRegistryValues ( std : : string & source )
{
2001-05-17 23:48:32 +04:00
# if defined(_WIN32) && !defined(__CYGWIN__)
2001-06-11 18:18:30 +04:00
// Regular expression to match anything inside [...] that begins in HKEY.
// Note that there is a special rule for regular expressions to match a
// close square-bracket inside a list delimited by square brackets.
// The "[^]]" part of this expression will match any character except
// a close square-bracket. The ']' character must be the first in the
// list of characters inside the [^...] block of the expression.
cmRegularExpression regEntry ( " \\ [(HKEY[^]]*) \ \ ] " ) ;
2001-05-11 18:53:17 +04:00
// check for black line or comment
while ( regEntry . find ( source ) )
{
// the arguments are the second match
std : : string key = regEntry . match ( 1 ) ;
std : : string val ;
if ( ReadAValue ( val , key . c_str ( ) ) )
{
std : : string reg = " [ " ;
reg + = key + " ] " ;
cmSystemTools : : ReplaceString ( source , reg . c_str ( ) , val . c_str ( ) ) ;
}
else
{
std : : string reg = " [ " ;
reg + = key + " ] " ;
cmSystemTools : : ReplaceString ( source , reg . c_str ( ) , " /registry " ) ;
}
}
# endif
}
2001-04-09 18:31:36 +04:00
2001-08-28 22:55:14 +04:00
2001-04-09 18:31:36 +04:00
2001-06-22 18:21:08 +04:00
std : : string cmSystemTools : : EscapeQuotes ( const char * str )
{
std : : string result = " " ;
for ( const char * ch = str ; * ch ! = ' \0 ' ; + + ch )
{
if ( * ch = = ' " ' )
{
result + = ' \\ ' ;
}
result + = * ch ;
}
return result ;
}
2001-04-09 18:31:36 +04:00
2001-11-22 01:45:01 +03:00
bool cmSystemTools : : SameFile ( const char * file1 , const char * file2 )
{
struct stat fileStat1 , fileStat2 ;
if ( stat ( file1 , & fileStat1 ) = = 0 & & stat ( file2 , & fileStat2 ) = = 0 )
{
// see if the files are the same file
// check the device inode and size
if ( fileStat2 . st_dev = = fileStat1 . st_dev & &
fileStat2 . st_ino = = fileStat1 . st_ino & &
fileStat2 . st_size = = fileStat1 . st_size
)
{
return true ;
}
}
return false ;
}
2000-09-12 13:30:35 +04:00
// return true if the file exists
bool cmSystemTools : : FileExists ( const char * filename )
{
struct stat fs ;
if ( stat ( filename , & fs ) ! = 0 )
2001-01-11 22:47:38 +03:00
{
2000-09-12 13:30:35 +04:00
return false ;
2001-01-11 22:47:38 +03:00
}
2000-09-12 13:30:35 +04:00
else
2001-01-11 22:47:38 +03:00
{
2000-09-12 13:30:35 +04:00
return true ;
2001-01-11 22:47:38 +03:00
}
2000-09-12 13:30:35 +04:00
}
2001-05-24 21:40:46 +04:00
// Return a capitalized string (i.e the first letter is uppercased, all other
// are lowercased)
2001-05-25 05:17:02 +04:00
std : : string cmSystemTools : : Capitalized ( const std : : string & s )
2001-05-24 21:40:46 +04:00
{
std : : string n ;
n . resize ( s . size ( ) ) ;
n [ 0 ] = toupper ( s [ 0 ] ) ;
for ( size_t i = 1 ; i < s . size ( ) ; i + + )
{
n [ i ] = tolower ( s [ i ] ) ;
}
return n ;
2001-06-06 01:41:16 +04:00
}
2001-05-24 21:40:46 +04:00
2001-09-13 01:09:02 +04:00
// Return a lower case string
std : : string cmSystemTools : : LowerCase ( const std : : string & s )
{
std : : string n ;
n . resize ( s . size ( ) ) ;
for ( size_t i = 0 ; i < s . size ( ) ; i + + )
{
n [ i ] = tolower ( s [ i ] ) ;
}
return n ;
}
2001-11-15 02:12:22 +03:00
// Return a lower case string
std : : string cmSystemTools : : UpperCase ( const std : : string & s )
{
std : : string n ;
n . resize ( s . size ( ) ) ;
for ( size_t i = 0 ; i < s . size ( ) ; i + + )
{
n [ i ] = toupper ( s [ i ] ) ;
}
return n ;
}
2001-09-13 01:09:02 +04:00
2002-02-26 02:14:01 +03:00
// convert windows slashes to unix slashes
2002-02-22 21:38:33 +03:00
void cmSystemTools : : ConvertToUnixSlashes ( std : : string & path )
2000-09-12 13:30:35 +04:00
{
2001-05-25 03:17:47 +04:00
std : : string : : size_type pos = 0 ;
while ( ( pos = path . find ( ' \\ ' , pos ) ) ! = std : : string : : npos )
2000-09-12 13:30:35 +04:00
{
path [ pos ] = ' / ' ;
2001-05-25 03:17:47 +04:00
pos + + ;
2000-09-12 13:30:35 +04:00
}
// remove any trailing slash
2001-06-28 19:40:35 +04:00
if ( path . size ( ) & & path [ path . size ( ) - 1 ] = = ' / ' )
2000-09-12 13:30:35 +04:00
{
path = path . substr ( 0 , path . size ( ) - 1 ) ;
}
2001-12-07 00:50:54 +03:00
// if there is a tilda ~ then replace it with HOME
if ( path . find ( " ~ " ) = = 0 )
{
if ( getenv ( " HOME " ) )
{
path = std : : string ( getenv ( " HOME " ) ) + path . substr ( 1 ) ;
}
}
2001-12-05 01:28:35 +03:00
// if there is a /tmp_mnt in a path get rid of it!
// stupid sgi's
if ( path . find ( " /tmp_mnt " ) = = 0 )
{
path = path . substr ( 8 ) ;
}
2000-09-12 13:30:35 +04:00
}
2000-09-27 23:01:19 +04:00
2002-02-22 21:38:33 +03:00
// change // to /, and escape any spaces in the path
std : : string cmSystemTools : : ConvertToUnixOutputPath ( const char * path )
2001-06-06 01:41:16 +04:00
{
2002-02-22 21:38:33 +03:00
std : : string ret = path ;
2002-02-25 18:47:56 +03:00
// remove // except at the beginning might be a cygwin drive
std : : string : : size_type pos = 1 ;
2002-02-22 21:38:33 +03:00
while ( ( pos = ret . find ( " // " , pos ) ) ! = std : : string : : npos )
2001-06-06 01:41:16 +04:00
{
2002-02-22 21:38:33 +03:00
ret . erase ( pos , 1 ) ;
2001-06-06 01:41:16 +04:00
}
2002-02-22 21:38:33 +03:00
// now escape spaces if there is a space in the path
if ( ret . find ( " " ) ! = std : : string : : npos )
2001-06-06 01:41:16 +04:00
{
2002-02-22 21:38:33 +03:00
std : : string result = " " ;
2002-02-22 23:40:44 +03:00
char lastch = 1 ;
2002-02-22 21:38:33 +03:00
for ( const char * ch = ret . c_str ( ) ; * ch ! = ' \0 ' ; + + ch )
{
2002-02-22 23:40:44 +03:00
// if it is already escaped then don't try to escape it again
if ( * ch = = ' ' & & lastch ! = ' \\ ' )
2002-02-22 21:38:33 +03:00
{
result + = ' \\ ' ;
}
result + = * ch ;
2002-02-22 23:40:44 +03:00
lastch = * ch ;
2002-02-22 21:38:33 +03:00
}
ret = result ;
}
return ret ;
}
std : : string cmSystemTools : : EscapeSpaces ( const char * str )
{
# if defined(_WIN32) && !defined(__CYGWIN__)
std : : string result ;
// if there are spaces
std : : string temp = str ;
if ( temp . find ( " " ) ! = std : : string : : npos & &
temp . find ( " \" " ) = = std : : string : : npos )
{
result = " \" " ;
result + = str ;
result + = " \" " ;
return result ;
}
return str ;
# else
std : : string result = " " ;
for ( const char * ch = str ; * ch ! = ' \0 ' ; + + ch )
{
if ( * ch = = ' ' )
{
result + = ' \\ ' ;
}
result + = * ch ;
2001-06-06 01:41:16 +04:00
}
2002-02-22 21:38:33 +03:00
return result ;
# endif
2001-09-02 00:13:56 +04:00
}
2002-02-22 21:38:33 +03:00
std : : string cmSystemTools : : ConvertToOutputPath ( const char * path )
2001-09-02 00:13:56 +04:00
{
2002-02-22 21:38:33 +03:00
# if defined(_WIN32) && !defined(__CYGWIN__)
return cmSystemTools : : ConvertToWindowsOutputPath ( path ) ;
# else
return cmSystemTools : : ConvertToUnixOutputPath ( path ) ;
# endif
}
// remove double slashes not at the start
std : : string cmSystemTools : : ConvertToWindowsOutputPath ( const char * path )
{
std : : string ret = path ;
2001-09-02 00:13:56 +04:00
std : : string : : size_type pos = 0 ;
2002-02-22 21:38:33 +03:00
// first convert all of the slashes
while ( ( pos = ret . find ( ' / ' , pos ) ) ! = std : : string : : npos )
{
ret [ pos ] = ' \\ ' ;
pos + + ;
}
// check for really small paths
if ( ret . size ( ) < 2 )
{
return ret ;
}
// now clean up a bit and remove double slashes
// Only if it is not the first position in the path which is a network
// path on windows
pos = 1 ; // start at position 1
while ( ( pos = ret . find ( " \\ \\ " , pos ) ) ! = std : : string : : npos )
{
ret . erase ( pos , 1 ) ;
}
// now double quote the path if it has spaces in it
// and is not already double quoted
if ( ret . find ( " " ) ! = std : : string : : npos
& & ret [ 0 ] ! = ' \" ' )
2001-06-06 01:41:16 +04:00
{
2002-02-22 21:38:33 +03:00
std : : string result ;
result = " \" " + ret + " \" " ;
ret = result ;
2001-06-06 01:41:16 +04:00
}
2002-02-22 21:38:33 +03:00
return ret ;
2001-06-06 01:41:16 +04:00
}
2001-01-05 19:41:20 +03:00
bool cmSystemTools : : ParseFunction ( std : : ifstream & fin ,
std : : string & name ,
2001-10-03 01:28:55 +04:00
std : : vector < std : : string > & arguments ,
2001-11-30 00:44:22 +03:00
const char * filename ,
bool & parseError )
2001-01-05 19:41:20 +03:00
{
2001-11-30 00:44:22 +03:00
parseError = false ;
2001-01-05 19:41:20 +03:00
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 ) )
{
2001-10-09 18:25:51 +04:00
cmRegularExpression blankLine ( " ^[ \t \r ]*$ " ) ;
2001-03-15 00:34:24 +03:00
cmRegularExpression comment ( " ^[ \t ]*#.*$ " ) ;
2001-10-09 18:25:51 +04:00
cmRegularExpression oneLiner ( " ^[ \t ]*([A-Za-z_0-9]*) [ \ t ] * \ \ ( ( . * ) \ \ ) [ \ t \ r ] * $ " ) ;
2001-02-27 23:41:21 +03:00
cmRegularExpression multiLine ( " ^[ \t ]*([A-Za-z_0-9]*) [ \ t ] * \ \ ( ( . * ) $ " ) ;
2001-10-09 18:25:51 +04:00
cmRegularExpression lastLine ( " ^(.*) \ \ ) [ \ t \ r ] * $ " ) ;
2001-01-05 19:41:20 +03:00
// 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 ) )
{
2001-03-15 00:34:24 +03:00
// Check for comment lines and ignore them.
if ( blankLine . find ( inbuffer ) | | comment . find ( inbuffer ) )
{ continue ; }
// Is this the last line?
2001-01-05 19:41:20 +03:00
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 ) ;
}
}
2001-01-12 21:48:38 +03:00
else
{
2001-11-30 00:44:22 +03:00
parseError = true ;
2001-10-03 01:28:55 +04:00
cmSystemTools : : Error ( " Parse error in read function missing end ) \n In File: " ,
filename , " \n Current line: " , inbuffer ) ;
2001-01-12 21:48:38 +03:00
return false ;
}
2001-01-05 19:41:20 +03:00
}
return true ;
}
else
{
2001-11-30 00:44:22 +03:00
parseError = true ;
2001-10-03 01:28:55 +04:00
cmSystemTools : : Error ( " Parse error in read function \n In file: " ,
filename , " \n Current line: " , inbuffer ) ;
2001-01-05 19:41:20 +03:00
return false ;
}
}
return false ;
}
void cmSystemTools : : GetArguments ( std : : string & line ,
std : : vector < std : : string > & arguments )
2000-09-27 23:01:19 +04:00
{
2001-02-27 23:41:21 +03:00
// Match a normal argument (not quoted, no spaces).
2001-12-18 01:44:24 +03:00
cmRegularExpression normalArgument ( " [ \t ]*(([^ \t \r \\ ]|[ \\ ].) + ) [ \ t \ r ] * " ) ;
2001-02-27 23:41:21 +03:00
// Match a quoted argument (surrounded by double quotes, spaces allowed).
2001-12-18 01:44:24 +03:00
cmRegularExpression quotedArgument ( " [ \t ]*( \" ([^ \" \\ ]|[ \\ ].) * \ " )[ \t \r ]* " ) ;
2001-02-27 23:41:21 +03:00
bool done = false ;
while ( ! done )
2000-09-27 23:01:19 +04:00
{
2001-02-27 23:41:21 +03:00
std : : string arg ;
2002-03-13 18:25:11 +03:00
std : : string : : size_type endpos ;
2001-02-27 23:41:21 +03:00
bool foundQuoted = quotedArgument . find ( line . c_str ( ) ) ;
bool foundNormal = normalArgument . find ( line . c_str ( ) ) ;
2001-01-05 19:41:20 +03:00
2001-02-27 23:41:21 +03:00
if ( foundQuoted & & foundNormal )
{
// Both matches were found. Take the earlier one.
2001-07-17 17:54:05 +04:00
// Favor double-quoted version if there is a tie.
2001-02-27 23:41:21 +03:00
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 )
2001-01-05 19:41:20 +03:00
{
2001-02-27 23:41:21 +03:00
arg = normalArgument . match ( 1 ) ;
endpos = normalArgument . end ( 1 ) ;
2001-01-05 19:41:20 +03:00
}
2001-02-27 23:41:21 +03:00
else
2000-09-27 23:01:19 +04:00
{
2001-02-27 23:41:21 +03:00
done = true ;
2000-09-27 23:01:19 +04:00
}
2001-02-27 23:41:21 +03:00
if ( ! done )
2000-09-27 23:01:19 +04:00
{
2001-07-17 17:54:05 +04:00
arguments . push_back ( cmSystemTools : : RemoveEscapes ( arg . c_str ( ) ) ) ;
2001-01-05 19:41:20 +03:00
line = line . substr ( endpos , line . length ( ) - endpos ) ;
2000-09-27 23:01:19 +04:00
}
}
}
2001-07-17 17:54:05 +04:00
std : : string cmSystemTools : : RemoveEscapes ( const char * s )
{
std : : string result = " " ;
for ( const char * ch = s ; * ch ; + + ch )
{
if ( * ch = = ' \\ ' )
{
+ + ch ;
switch ( * ch )
{
case ' \\ ' : result . insert ( result . end ( ) , ' \\ ' ) ; break ;
case ' " ' : result . insert ( result . end ( ) , ' " ' ) ; break ;
case ' ' : result . insert ( result . end ( ) , ' ' ) ; break ;
case ' t ' : result . insert ( result . end ( ) , ' \t ' ) ; break ;
case ' n ' : result . insert ( result . end ( ) , ' \n ' ) ; break ;
case ' r ' : result . insert ( result . end ( ) , ' \r ' ) ; break ;
case ' 0 ' : result . insert ( result . end ( ) , ' \0 ' ) ; break ;
case ' \0 ' :
{
cmSystemTools : : Error ( " Trailing backslash in argument: \n " , s ) ;
return result ;
}
default :
{
std : : string chStr ( 1 , * ch ) ;
cmSystemTools : : Error ( " Invalid escape sequence \\ " , chStr . c_str ( ) ,
" \n in argument " , s ) ;
}
}
}
else
{
result . insert ( result . end ( ) , * ch ) ;
}
}
return result ;
}
2001-03-13 02:30:58 +03:00
void cmSystemTools : : Error ( const char * m1 , const char * m2 ,
const char * m3 , const char * m4 )
2001-01-05 19:41:20 +03:00
{
std : : string message = " CMake Error: " ;
if ( m1 )
{
message + = m1 ;
}
if ( m2 )
{
message + = m2 ;
}
2001-03-13 02:30:58 +03:00
if ( m3 )
{
message + = m3 ;
}
if ( m4 )
{
message + = m4 ;
}
2001-02-23 03:24:43 +03:00
cmSystemTools : : s_ErrorOccured = true ;
2001-06-05 00:55:37 +04:00
cmSystemTools : : Message ( message . c_str ( ) , " Error " ) ;
}
2001-10-29 18:19:34 +03:00
void cmSystemTools : : SetErrorCallback ( ErrorCallback f )
{
s_ErrorCallback = f ;
}
2001-06-05 00:55:37 +04:00
void cmSystemTools : : Message ( const char * m1 , const char * title )
{
2001-11-20 01:52:08 +03:00
if ( s_DisableMessages )
2001-08-08 19:54:46 +04:00
{
return ;
}
2001-10-29 18:19:34 +03:00
if ( s_ErrorCallback )
{
2001-11-20 01:52:08 +03:00
( * s_ErrorCallback ) ( m1 , title , s_DisableMessages ) ;
2001-10-29 18:19:34 +03:00
return ;
}
2001-10-29 18:41:31 +03:00
else
2001-08-08 19:54:46 +04:00
{
2001-10-29 18:41:31 +03:00
std : : cerr < < m1 < < std : : endl ;
2001-08-08 19:54:46 +04:00
}
2001-10-29 18:41:31 +03:00
2001-01-05 19:41:20 +03:00
}
2001-02-13 03:49:52 +03:00
2001-02-23 03:24:43 +03:00
2002-02-06 18:50:17 +03:00
bool cmSystemTools : : CopyFileIfDifferent ( const char * source ,
2001-02-23 03:24:43 +03:00
const char * destination )
{
if ( cmSystemTools : : FilesDiffer ( source , destination ) )
{
cmSystemTools : : cmCopyFile ( source , destination ) ;
2002-02-06 18:50:17 +03:00
return true ;
2001-02-23 03:24:43 +03:00
}
2002-02-06 18:50:17 +03:00
return false ;
2001-02-23 03:24:43 +03:00
}
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 ;
}
2002-02-18 22:36:04 +03:00
const int buffer_length = 4096 ;
char bufferSource [ buffer_length ] ;
char bufferDest [ buffer_length ] ;
2001-02-23 03:24:43 +03:00
while ( finSource & & finDestination )
{
2002-02-18 22:36:04 +03:00
if ( finSource . getline ( bufferSource , buffer_length , ' \n ' )
| | finSource . gcount ( ) )
2001-02-23 03:24:43 +03:00
{
2002-02-18 22:36:04 +03:00
if ( finDestination . getline ( bufferDest , buffer_length , ' \n ' )
| | finDestination . gcount ( ) )
{
// both if statements passed
if ( finSource . eof ( ) )
{
if ( ! finDestination . eof ( ) )
{
return true ;
}
if ( finSource . gcount ( ) ! = finDestination . gcount ( ) )
{
return true ;
}
if ( strncmp ( bufferSource , bufferDest , finSource . gcount ( ) ) ! = 0 )
{
return true ;
}
}
else if ( finSource . fail ( ) )
{
if ( ! finDestination . fail ( ) )
{
return true ;
}
if ( strcmp ( bufferSource , bufferDest ) ! = 0 )
{
return true ;
}
finSource . clear ( finSource . rdstate ( ) & ~ std : : ios : : failbit ) ;
finDestination . clear ( finDestination . rdstate ( ) & ~ std : : ios : : failbit ) ;
}
else
{
if ( strcmp ( bufferSource , bufferDest ) ! = 0 )
{
return true ;
}
}
}
else
{
return true ;
}
2001-02-23 03:24:43 +03:00
}
}
return false ;
}
2001-06-22 20:19:34 +04:00
/**
2002-02-22 18:08:04 +03:00
* Copy a file named by " source " to the file named by " destination " .
2001-06-22 20:19:34 +04:00
*/
2001-02-23 03:24:43 +03:00
void cmSystemTools : : cmCopyFile ( const char * source ,
2001-06-22 20:19:34 +04:00
const char * destination )
2001-02-23 03:24:43 +03:00
{
2002-02-22 18:08:04 +03:00
const int bufferSize = 4096 ;
char buffer [ bufferSize ] ;
2002-02-23 18:00:54 +03:00
std : : ifstream fin ( source ,
# ifdef _WIN32
std : : ios : : binary |
# endif
std : : ios : : in ) ;
2001-06-22 20:19:34 +04:00
if ( ! fin )
2001-02-23 03:24:43 +03:00
{
2001-06-22 20:19:34 +04:00
cmSystemTools : : Error ( " CopyFile failed to open input file \" " ,
source , " \" " ) ;
2001-09-21 17:40:07 +04:00
return ;
2001-02-23 03:24:43 +03:00
}
2001-06-22 20:19:34 +04:00
std : : ofstream fout ( destination ,
2002-02-23 18:00:54 +03:00
# ifdef _WIN32
std : : ios : : binary |
# endif
std : : ios : : out | std : : ios : : trunc ) ;
2001-06-22 20:19:34 +04:00
if ( ! fout )
2001-02-23 03:24:43 +03:00
{
2001-06-22 20:19:34 +04:00
cmSystemTools : : Error ( " CopyFile failed to open output file \" " ,
destination , " \" " ) ;
2001-09-21 17:40:07 +04:00
return ;
2001-02-23 03:24:43 +03:00
}
2002-02-22 18:08:04 +03:00
// This copy loop is very sensitive on certain platforms with
// slightly broken stream libraries (like HPUX). Normally, it is
// incorrect to not check the error condition on the fin.read()
// before using the data, but the fin.gcount() will be zero if an
// error occurred. Therefore, the loop should be safe everywhere.
while ( fin )
{
fin . read ( buffer , bufferSize ) ;
if ( fin . gcount ( ) )
2001-02-23 03:24:43 +03:00
{
2002-02-22 18:08:04 +03:00
fout . write ( buffer , fin . gcount ( ) ) ;
2001-02-23 03:24:43 +03:00
}
}
}
// 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 ;
}
}
2002-01-19 03:21:02 +03:00
bool cmSystemTools : : RemoveFile ( const char * source )
2001-02-23 03:24:43 +03:00
{
2002-01-19 03:21:02 +03:00
return unlink ( source ) ! = 0 ? false : true ;
2001-02-23 03:24:43 +03:00
}
2001-04-26 18:49:12 +04:00
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 " ) ;
}
2001-04-30 22:56:06 +04:00
bool cmSystemTools : : IsOff ( const char * val )
{
2001-06-29 01:45:54 +04:00
if ( ! val | | strlen ( val ) = = 0 )
2001-04-30 22:56:06 +04:00
{
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 " | |
2001-08-29 17:26:55 +04:00
v = = " N " | | v = = " NOTFOUND " | | v = = " IGNORE " ) ;
2001-04-30 22:56:06 +04:00
}
2001-05-04 00:55:18 +04:00
2001-05-04 19:30:46 +04:00
bool cmSystemTools : : RunCommand ( const char * command ,
2001-07-23 19:53:52 +04:00
std : : string & output ,
2002-03-14 19:11:39 +03:00
const char * dir ,
2001-07-23 19:53:52 +04:00
bool verbose )
2001-08-23 19:12:19 +04:00
{
int foo ;
2002-03-14 19:11:39 +03:00
return cmSystemTools : : RunCommand ( command , output , foo , dir , verbose ) ;
2001-08-23 19:12:19 +04:00
}
2002-03-14 19:11:39 +03:00
# if defined(WIN32) && !defined(__CYGWIN__)
// Code from a Borland web site with the following explaination :
/* In this article, I will explain how to spawn a console application and redirect its standard input/output using anonymous pipes. An anonymous pipe is a pipe that goes only in one direction (read pipe, write pipe, etc.). Maybe you are asking, "why would I ever need to do this sort of thing?" One example would be a Windows telnet server, where you spawn a shell and listen on a port and send and receive data between the shell and the socket client. (Windows does not really have a built-in remote shell).
First , we should talk about pipes . A pipe in Windows is simply a method of communication , often between process . The SDK defines a pipe as " a communication conduit with two ends; a process with a handle to one end can communicate with a process having a handle to the other end. " In our case , we are using " anonymous " pipes , one - way pipes that " transfer data between a parent process and a child process or between two child processes of the same parent process. " It ' s easiest to imagine a pipe as its namesake . An actual pipe running between processes that can carry data .
We are using anonymous pipes because the console app we are spawning is a child process . We use the CreatePipe function which will create an anonymous pipe and return a read handle and a write handle . We will create two pipes , on for stdin and one for stdout . We will then monitor the read end of the stdout pipe to check for display on our child process . Every time there is something availabe for reading , we will display it in our app . Consequently , we check for input in our app and send it off to the write end of the stdin pipe .
*/
inline bool IsWinNT ( ) //check if we're running NT
{
OSVERSIONINFO osv ;
osv . dwOSVersionInfoSize = sizeof ( osv ) ;
GetVersionEx ( & osv ) ;
return ( osv . dwPlatformId = = VER_PLATFORM_WIN32_NT ) ;
}
//---------------------------------------------------------------------------
bool WindowsRunCommand ( const char * command ,
const char * dir ,
std : : string & output ,
int & retVal ,
bool verbose )
2001-05-04 19:30:46 +04:00
{
2002-03-14 19:11:39 +03:00
const int BUFFER_SIZE = 4096 ;
char buf [ BUFFER_SIZE ] ; //i/o buffer
STARTUPINFO si ;
SECURITY_ATTRIBUTES sa ;
SECURITY_DESCRIPTOR sd ; //security information for pipes
PROCESS_INFORMATION pi ;
HANDLE newstdin , newstdout , read_stdout , write_stdin ; //pipe handles
if ( IsWinNT ( ) ) //initialize security descriptor (Windows NT)
{
InitializeSecurityDescriptor ( & sd , SECURITY_DESCRIPTOR_REVISION ) ;
SetSecurityDescriptorDacl ( & sd , true , NULL , false ) ;
sa . lpSecurityDescriptor = & sd ;
}
else sa . lpSecurityDescriptor = NULL ;
sa . nLength = sizeof ( SECURITY_ATTRIBUTES ) ;
sa . bInheritHandle = true ; //allow inheritable handles
if ( ! CreatePipe ( & newstdin , & write_stdin , & sa , 0 ) ) //create stdin pipe
{
cmSystemTools : : Error ( " CreatePipe " ) ;
return false ;
}
if ( ! CreatePipe ( & read_stdout , & newstdout , & sa , 0 ) ) //create stdout pipe
{
cmSystemTools : : Error ( " CreatePipe " ) ;
CloseHandle ( newstdin ) ;
CloseHandle ( write_stdin ) ;
return false ;
}
GetStartupInfo ( & si ) ; //set startupinfo for the spawned process
/*
The dwFlags member tells CreateProcess how to make the process .
STARTF_USESTDHANDLES validates the hStd * members . STARTF_USESHOWWINDOW
validates the wShowWindow member .
*/
si . dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW ;
si . wShowWindow = SW_HIDE ;
si . hStdOutput = newstdout ;
si . hStdError = newstdout ; //set the new handles for the child process
si . hStdInput = newstdin ;
char * commandAndArgs = strcpy ( new char [ strlen ( command ) + 1 ] , command ) ;
if ( ! CreateProcess ( NULL , commandAndArgs , NULL , NULL , TRUE , CREATE_NEW_CONSOLE ,
NULL , dir , & si , & pi ) )
{
cmSystemTools : : Error ( " CreateProcess failed " , commandAndArgs ) ;
CloseHandle ( newstdin ) ;
CloseHandle ( newstdout ) ;
CloseHandle ( read_stdout ) ;
CloseHandle ( write_stdin ) ;
delete [ ] commandAndArgs ;
return false ;
}
delete [ ] commandAndArgs ;
unsigned long exit = 0 ; //process exit code
unsigned long bread ; //bytes read
unsigned long avail ; //bytes available
memset ( buf , 0 , sizeof ( buf ) ) ;
for ( ; ; ) //main program loop
{
GetExitCodeProcess ( pi . hProcess , & exit ) ; //while the process is running
if ( exit ! = STILL_ACTIVE )
break ;
//check to see if there is any data to read from stdout
PeekNamedPipe ( read_stdout , buf , 1023 , & bread , & avail , NULL ) ;
if ( bread ! = 0 )
{
memset ( buf , 0 , sizeof ( buf ) ) ;
if ( avail > 1023 )
{
while ( bread > = 1023 )
{
ReadFile ( read_stdout , buf , 1023 , & bread , NULL ) ; //read the stdout pipe
printf ( " %s " , buf ) ;
memset ( buf , 0 , sizeof ( buf ) ) ;
}
}
else
{
ReadFile ( read_stdout , buf , 1023 , & bread , NULL ) ;
output + = buf ;
output + = " \n " ;
if ( verbose )
{
std : : cout < < buf < < " \n " < < std : : flush ;
}
}
}
}
CloseHandle ( pi . hThread ) ;
CloseHandle ( pi . hProcess ) ;
CloseHandle ( newstdin ) ; //clean stuff up
CloseHandle ( newstdout ) ;
CloseHandle ( read_stdout ) ;
CloseHandle ( write_stdin ) ;
retVal = exit ;
return true ;
}
// use this for shell commands like echo and dir
bool RunCommandViaSystem ( const char * command ,
const char * dir ,
std : : string & output ,
int & retVal ,
bool verbose )
{
2001-05-08 02:11:16 +04:00
const int BUFFER_SIZE = 4096 ;
char buffer [ BUFFER_SIZE ] ;
2002-03-14 19:11:39 +03:00
std : : string commandInDir ;
if ( dir )
2001-11-27 02:28:27 +03:00
{
2002-03-14 19:11:39 +03:00
commandInDir = " cd " ;
commandInDir + = dir ;
commandInDir + = " && " ;
commandInDir + = command ;
2001-11-27 02:28:27 +03:00
}
2002-03-14 19:11:39 +03:00
else
{
commandInDir = command ;
}
command = commandInDir . c_str ( ) ;
2001-05-04 19:30:46 +04:00
std : : string commandToFile = command ;
commandToFile + = " > " ;
std : : string tempFile ;
2001-11-26 19:32:20 +03:00
tempFile + = _tempnam ( 0 , " cmake " ) ;
2001-05-04 19:30:46 +04:00
commandToFile + = tempFile ;
2001-08-23 19:12:19 +04:00
retVal = system ( commandToFile . c_str ( ) ) ;
2001-05-04 19:30:46 +04:00
std : : ifstream fin ( tempFile . c_str ( ) ) ;
if ( ! fin )
{
2001-07-23 19:53:52 +04:00
if ( verbose )
{
std : : string errormsg = " RunCommand produced no output: command: \" " ;
errormsg + = command ;
errormsg + = " \" " ;
errormsg + = " \n Output file: " ;
errormsg + = tempFile ;
cmSystemTools : : Error ( errormsg . c_str ( ) ) ;
}
2001-07-06 01:52:31 +04:00
fin . close ( ) ;
cmSystemTools : : RemoveFile ( tempFile . c_str ( ) ) ;
2001-05-04 19:30:46 +04:00
return false ;
}
while ( fin )
{
fin . getline ( buffer , BUFFER_SIZE ) ;
output + = buffer ;
}
2001-07-06 01:52:31 +04:00
fin . close ( ) ;
2001-05-04 19:30:46 +04:00
cmSystemTools : : RemoveFile ( tempFile . c_str ( ) ) ;
return true ;
2002-03-14 19:11:39 +03:00
}
# endif // endif WIN32 not CYGWIN
// run a command unix uses popen (easy)
// windows uses CreateProcess (difficult) or system for built in commands
bool cmSystemTools : : RunCommand ( const char * command ,
std : : string & output ,
int & retVal ,
const char * dir ,
bool verbose )
{
if ( s_DisableRunCommandOutput )
{
verbose = false ;
}
# if defined(WIN32) && !defined(__CYGWIN__)
// if the command does not start with a quote, then
// try to find the program, and if the program can not be
// found use system to run the command as it must be a built in
// shell command like echo or dir
if ( command [ 0 ] ! = ' \" ' )
{
cmRegularExpression nonQuoted ( " ^([^ \t ]*) [ \ t ] ( . * ) " ) ;
if ( nonQuoted . find ( command ) )
{
std : : string cmd = nonQuoted . match ( 1 ) ;
if ( cmSystemTools : : FindProgram ( cmd . c_str ( ) ) = = " " )
{
return RunCommandViaSystem ( command , dir , output , retVal , verbose ) ;
}
}
}
// best case is the command is an executable and we run it this way
return WindowsRunCommand ( command , dir , output , retVal , verbose ) ;
2001-05-08 02:11:16 +04:00
# else
2002-03-14 19:11:39 +03:00
std : : string commandInDir ;
if ( dir )
{
commandInDir = " cd " ;
commandInDir + = dir ;
commandInDir + = " && " ;
commandInDir + = command ;
}
else
{
commandInDir = command ;
}
command = commandInDir . c_str ( ) ;
const int BUFFER_SIZE = 4096 ;
char buffer [ BUFFER_SIZE ] ;
2001-07-23 19:53:52 +04:00
if ( verbose )
{
std : : cout < < " running " < < command < < std : : endl ;
}
2002-03-06 02:25:13 +03:00
fflush ( stdout ) ;
fflush ( stderr ) ;
2001-05-08 02:11:16 +04:00
FILE * cpipe = popen ( command , " r " ) ;
if ( ! cpipe )
{
return false ;
}
fgets ( buffer , BUFFER_SIZE , cpipe ) ;
while ( ! feof ( cpipe ) )
{
2001-07-23 19:53:52 +04:00
if ( verbose )
{
std : : cout < < buffer < < std : : flush ;
}
2001-05-08 02:11:16 +04:00
output + = buffer ;
fgets ( buffer , BUFFER_SIZE , cpipe ) ;
}
2002-03-06 02:25:13 +03:00
2001-08-23 19:12:19 +04:00
retVal = pclose ( cpipe ) ;
2002-03-06 02:25:13 +03:00
retVal = WEXITSTATUS ( retVal ) ;
2001-05-10 19:19:15 +04:00
return true ;
2001-05-08 02:11:16 +04:00
# endif
2001-05-04 19:30:46 +04:00
}
2001-09-12 03:58:22 +04:00
/**
* Find the file the given name . Searches the given path and then
* the system search path . Returns the full path to the file if it is
* found . Otherwise , the empty string is returned .
*/
std : : string cmSystemTools : : FindFile ( const char * name ,
const std : : vector < std : : string > & userPaths )
{
// Add the system search path to our path.
std : : vector < std : : string > path = userPaths ;
cmSystemTools : : GetPath ( path ) ;
std : : string tryPath ;
for ( std : : vector < std : : string > : : const_iterator p = path . begin ( ) ;
p ! = path . end ( ) ; + + p )
{
tryPath = * p ;
tryPath + = " / " ;
tryPath + = name ;
if ( cmSystemTools : : FileExists ( tryPath . c_str ( ) ) & &
! cmSystemTools : : FileIsDirectory ( tryPath . c_str ( ) ) )
{
return cmSystemTools : : CollapseFullPath ( tryPath . c_str ( ) ) ;
}
}
// Couldn't find the file.
return " " ;
}
2001-05-04 19:30:46 +04:00
2001-05-04 00:55:18 +04:00
/**
* 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.
2001-07-11 20:12:13 +04:00
if ( cmSystemTools : : FileExists ( name ) & &
! cmSystemTools : : FileIsDirectory ( name ) )
2001-05-04 00:55:18 +04:00
{
return cmSystemTools : : CollapseFullPath ( name ) ;
}
2001-05-24 00:28:34 +04:00
std : : string tryPath = name ;
tryPath + = cmSystemTools : : GetExecutableExtension ( ) ;
2001-07-11 20:12:13 +04:00
if ( cmSystemTools : : FileExists ( tryPath . c_str ( ) ) & &
! cmSystemTools : : FileIsDirectory ( tryPath . c_str ( ) ) )
2001-05-24 00:28:34 +04:00
{
return cmSystemTools : : CollapseFullPath ( tryPath . c_str ( ) ) ;
}
2001-09-12 03:58:22 +04:00
2001-05-04 00:55:18 +04:00
// Add the system search path to our path.
std : : vector < std : : string > path = userPaths ;
cmSystemTools : : GetPath ( path ) ;
2001-09-12 03:58:22 +04:00
2001-05-04 00:55:18 +04:00
for ( std : : vector < std : : string > : : const_iterator p = path . begin ( ) ;
p ! = path . end ( ) ; + + p )
{
2001-05-24 00:28:34 +04:00
tryPath = * p ;
2001-05-04 00:55:18 +04:00
tryPath + = " / " ;
tryPath + = name ;
2001-07-11 20:12:13 +04:00
if ( cmSystemTools : : FileExists ( tryPath . c_str ( ) ) & &
! cmSystemTools : : FileIsDirectory ( tryPath . c_str ( ) ) )
2001-05-04 00:55:18 +04:00
{
return cmSystemTools : : CollapseFullPath ( tryPath . c_str ( ) ) ;
}
2002-02-28 18:41:27 +03:00
# ifdef _WIN32
tryPath + = " .com " ;
if ( cmSystemTools : : FileExists ( tryPath . c_str ( ) ) & &
! cmSystemTools : : FileIsDirectory ( tryPath . c_str ( ) ) )
{
return cmSystemTools : : CollapseFullPath ( tryPath . c_str ( ) ) ;
}
2002-02-28 19:15:10 +03:00
tryPath = * p ;
tryPath + = " / " ;
tryPath + = name ;
2002-02-28 18:41:27 +03:00
# endif
2001-05-04 00:55:18 +04:00
tryPath + = cmSystemTools : : GetExecutableExtension ( ) ;
2001-07-11 20:12:13 +04:00
if ( cmSystemTools : : FileExists ( tryPath . c_str ( ) ) & &
! cmSystemTools : : FileIsDirectory ( tryPath . c_str ( ) ) )
2001-05-04 00:55:18 +04:00
{
return cmSystemTools : : CollapseFullPath ( tryPath . c_str ( ) ) ;
}
}
2001-09-12 03:58:22 +04:00
2001-05-04 00:55:18 +04:00
// Couldn't find the program.
return " " ;
}
2001-05-09 22:53:32 +04:00
/**
* Find the library with the given name . Searches the given path and then
* the system search path . Returns the full path to the library if it is
* found . Otherwise , the empty string is returned .
*/
std : : string cmSystemTools : : FindLibrary ( 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 ) ;
std : : string tryPath ;
for ( std : : vector < std : : string > : : const_iterator p = path . begin ( ) ;
p ! = path . end ( ) ; + + p )
{
2001-07-18 19:40:23 +04:00
# if defined(_WIN32) && !defined(__CYGWIN__)
2001-05-09 22:53:32 +04:00
tryPath = * p ;
tryPath + = " / " ;
tryPath + = name ;
tryPath + = " .lib " ;
if ( cmSystemTools : : FileExists ( tryPath . c_str ( ) ) )
{
return cmSystemTools : : CollapseFullPath ( tryPath . c_str ( ) ) ;
}
2001-07-18 19:40:23 +04:00
# else
2001-05-10 23:50:03 +04:00
tryPath = * p ;
tryPath + = " /lib " ;
tryPath + = name ;
2001-05-12 15:29:23 +04:00
tryPath + = " .so " ;
2001-05-09 22:53:32 +04:00
if ( cmSystemTools : : FileExists ( tryPath . c_str ( ) ) )
{
return cmSystemTools : : CollapseFullPath ( tryPath . c_str ( ) ) ;
}
2001-05-10 23:50:03 +04:00
tryPath = * p ;
2001-05-21 23:16:19 +04:00
tryPath + = " /lib " ;
2001-05-10 23:50:03 +04:00
tryPath + = name ;
2001-05-12 15:29:23 +04:00
tryPath + = " .a " ;
2001-05-09 22:53:32 +04:00
if ( cmSystemTools : : FileExists ( tryPath . c_str ( ) ) )
{
return cmSystemTools : : CollapseFullPath ( tryPath . c_str ( ) ) ;
}
2001-05-10 23:50:03 +04:00
tryPath = * p ;
2001-05-21 23:16:19 +04:00
tryPath + = " /lib " ;
2001-05-10 23:50:03 +04:00
tryPath + = name ;
2001-05-12 15:29:23 +04:00
tryPath + = " .sl " ;
2001-05-09 22:53:32 +04:00
if ( cmSystemTools : : FileExists ( tryPath . c_str ( ) ) )
{
return cmSystemTools : : CollapseFullPath ( tryPath . c_str ( ) ) ;
}
2001-07-18 19:40:23 +04:00
# endif
2001-05-09 22:53:32 +04:00
}
// Couldn't find the library.
return " " ;
}
2001-05-04 00:55:18 +04:00
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 ;
}
}
2001-06-22 01:53:15 +04:00
int cmSystemTools : : ChangeDirectory ( const char * dir )
{
return Chdir ( dir ) ;
}
2001-05-04 00:55:18 +04:00
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 ;
}
/**
2001-05-25 05:17:02 +04:00
* 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 .
2001-05-04 00:55:18 +04:00
*/
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 ( " / " ) ;
2001-05-25 03:17:47 +04:00
if ( slashPos ! = std : : string : : npos )
2001-05-04 00:55:18 +04:00
{
2001-05-25 03:17:47 +04:00
file = dir . substr ( slashPos + 1 ) ;
2001-05-04 00:55:18 +04:00
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 " ,
2001-05-23 22:44:35 +04:00
oldDir . c_str ( ) , " \n Directory not found: " ,
dir . c_str ( ) ) ;
2001-05-04 00:55:18 +04:00
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 ) ;
2001-09-28 20:14:52 +04:00
# ifdef _WIN32
2001-05-04 00:55:18 +04:00
// 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 ) ;
2002-01-07 23:49:07 +03:00
std : : string newPath = newDir + " / " + file ;
return newPath ;
2001-09-28 00:50:59 +04:00
# else
# ifdef MAXPATHLEN
char resolved_name [ MAXPATHLEN ] ;
# else
2001-09-28 18:40:14 +04:00
# ifdef PATH_MAX
2001-09-28 00:50:59 +04:00
char resolved_name [ PATH_MAX ] ;
2001-09-28 18:40:14 +04:00
# else
char resolved_name [ 5024 ] ;
# endif
2001-09-28 00:50:59 +04:00
# endif
2001-09-29 19:12:17 +04:00
if ( dir ! = " " )
{
realpath ( dir . c_str ( ) , resolved_name ) ;
dir = resolved_name ;
}
else
{
dir = cmSystemTools : : GetCurrentWorkingDirectory ( ) ;
}
2002-02-08 23:52:36 +03:00
if ( file = = " " )
{
return dir ;
}
2002-01-07 23:49:07 +03:00
return dir + " / " + file ;
2001-09-28 00:50:59 +04:00
# endif
2001-05-04 00:55:18 +04:00
}
2001-05-04 19:30:46 +04:00
2001-05-25 05:17:02 +04:00
/**
* Return path of a full filename ( no trailing slashes ) .
* Warning : returned path is converted to Unix slashes format .
*/
std : : string cmSystemTools : : GetFilenamePath ( const std : : string & filename )
{
std : : string fn = filename ;
cmSystemTools : : ConvertToUnixSlashes ( fn ) ;
std : : string : : size_type slash_pos = fn . rfind ( " / " ) ;
if ( slash_pos ! = std : : string : : npos )
{
return fn . substr ( 0 , slash_pos ) ;
}
else
{
return " " ;
}
}
/**
* Return file name of a full filename ( i . e . file name without path ) .
*/
std : : string cmSystemTools : : GetFilenameName ( const std : : string & filename )
{
std : : string fn = filename ;
cmSystemTools : : ConvertToUnixSlashes ( fn ) ;
std : : string : : size_type slash_pos = fn . rfind ( " / " ) ;
if ( slash_pos ! = std : : string : : npos )
{
return fn . substr ( slash_pos + 1 ) ;
}
else
{
return filename ;
}
}
/**
* Return file extension of a full filename ( dot included ) .
* Warning : this is the longest extension ( for example : . tar . gz )
*/
std : : string cmSystemTools : : GetFilenameExtension ( const std : : string & filename )
{
std : : string name = cmSystemTools : : GetFilenameName ( filename ) ;
std : : string : : size_type dot_pos = name . find ( " . " ) ;
if ( dot_pos ! = std : : string : : npos )
2001-09-13 19:27:54 +04:00
{
return name . substr ( dot_pos ) ;
}
else
{
return " " ;
}
}
/**
* Return file extension of a full filename ( dot included ) .
*/
std : : string cmSystemTools : : GetFilenameShortestExtension ( const std : : string & filename )
{
std : : string name = cmSystemTools : : GetFilenameName ( filename ) ;
std : : string : : size_type dot_pos = name . rfind ( " . " ) ;
if ( dot_pos ! = std : : string : : npos )
2001-05-25 05:17:02 +04:00
{
return name . substr ( dot_pos ) ;
}
else
{
return " " ;
}
}
/**
* Return file name without extension of a full filename ( i . e . without path ) .
* Warning : it considers the longest extension ( for example : . tar . gz )
*/
std : : string cmSystemTools : : GetFilenameNameWithoutExtension ( const std : : string & filename )
{
std : : string name = cmSystemTools : : GetFilenameName ( filename ) ;
std : : string : : size_type dot_pos = name . find ( " . " ) ;
if ( dot_pos ! = std : : string : : npos )
{
return name . substr ( 0 , dot_pos ) ;
}
else
{
return name ;
}
}
2001-06-21 20:01:18 +04:00
void cmSystemTools : : Glob ( const char * directory , const char * regexp ,
std : : vector < std : : string > & files )
{
cmDirectory d ;
cmRegularExpression reg ( regexp ) ;
if ( d . Load ( directory ) )
{
2002-03-13 18:25:11 +03:00
size_t numf ;
unsigned int i ;
2001-06-21 20:01:18 +04:00
numf = d . GetNumberOfFiles ( ) ;
for ( i = 0 ; i < numf ; i + + )
{
std : : string fname = d . GetFile ( i ) ;
if ( reg . find ( fname ) )
{
files . push_back ( fname ) ;
}
}
}
}
2001-09-20 18:54:29 +04:00
void cmSystemTools : : GlobDirs ( const char * fullPath ,
std : : vector < std : : string > & files )
{
std : : string path = fullPath ;
2001-11-13 20:38:53 +03:00
std : : string : : size_type pos = path . find ( " /* " ) ;
2001-09-20 18:54:29 +04:00
if ( pos = = std : : string : : npos )
{
files . push_back ( fullPath ) ;
return ;
}
std : : string startPath = path . substr ( 0 , pos ) ;
std : : string finishPath = path . substr ( pos + 2 ) ;
cmDirectory d ;
if ( d . Load ( startPath . c_str ( ) ) )
{
2002-02-28 02:11:12 +03:00
for ( unsigned int i = 0 ; i < d . GetNumberOfFiles ( ) ; + + i )
2001-09-20 18:54:29 +04:00
{
if ( ( std : : string ( d . GetFile ( i ) ) ! = " . " )
& & ( std : : string ( d . GetFile ( i ) ) ! = " .. " ) )
{
std : : string fname = startPath ;
fname + = " / " ;
fname + = d . GetFile ( i ) ;
if ( cmSystemTools : : FileIsDirectory ( fname . c_str ( ) ) )
{
fname + = finishPath ;
cmSystemTools : : GlobDirs ( fname . c_str ( ) , files ) ;
}
}
}
}
}
2002-03-06 18:10:46 +03:00
void cmSystemTools : : ExpandListArguments ( std : : vector < std : : string > const & arguments ,
std : : vector < std : : string > & newargs )
{
std : : vector < std : : string > : : const_iterator i ;
for ( i = arguments . begin ( ) ; i ! = arguments . end ( ) ; + + i )
{
if ( i - > find ( ' ; ' ) ! = std : : string : : npos )
{
std : : string : : size_type start = 0 ;
std : : string : : size_type endpos = 0 ;
while ( endpos ! = std : : string : : npos )
{
endpos = i - > find ( ' ; ' , start ) ;
std : : string : : size_type len ;
if ( endpos ! = std : : string : : npos )
{
len = endpos - start ;
}
else
{
len = i - > size ( ) - start ;
}
newargs . push_back ( i - > substr ( start , len ) ) ;
start = endpos + 1 ;
}
}
else
{
newargs . push_back ( * i ) ;
}
}
}