Imported Upstream version 2.8.9
[platform/upstream/cmake.git] / Source / cmSystemTools.cxx
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 ============================================================================*/
12 #if defined(_MSC_VER) && _MSC_VER < 1300
13 # define _WIN32_WINNT 0x0400 /* for wincrypt.h */
14 #endif
15 #include "cmSystemTools.h"
16 #include <ctype.h>
17 #include <errno.h>
18 #include <time.h>
19 #include <string.h>
20 #include <stdlib.h>
21 #ifdef __QNX__
22 # include <malloc.h> /* for malloc/free on QNX */
23 #endif
24 #include <cmsys/Glob.hxx>
25 #include <cmsys/RegularExpression.hxx>
26 #include <cmsys/Directory.hxx>
27 #include <cmsys/System.h>
28 #if defined(CMAKE_BUILD_WITH_CMAKE)
29 # include "cmArchiveWrite.h"
30 # include <cm_libarchive.h>
31 # include <cmsys/Terminal.h>
32 #endif
33 #include <cmsys/stl/algorithm>
34
35 #if defined(_WIN32)
36 # include <windows.h>
37 # include <wincrypt.h>
38 #else
39 # include <sys/time.h>
40 # include <sys/types.h>
41 # include <unistd.h>
42 # include <utime.h>
43 # include <sys/wait.h>
44 #endif
45
46 #include <sys/stat.h>
47
48 #if defined(_WIN32) && \
49    (defined(_MSC_VER) || defined(__WATCOMC__) || \
50     defined(__BORLANDC__) || defined(__MINGW32__))
51 # include <io.h>
52 #endif
53
54 #if defined(CMAKE_BUILD_WITH_CMAKE)
55 #  include <memory> // auto_ptr
56 #  include <fcntl.h>
57 #  include "cmCryptoHash.h"
58 #endif
59
60 #if defined(CMAKE_USE_ELF_PARSER)
61 # include "cmELF.h"
62 #endif
63
64 class cmSystemToolsFileTime
65 {
66 public:
67 #if defined(_WIN32) && !defined(__CYGWIN__)
68   FILETIME timeCreation;
69   FILETIME timeLastAccess;
70   FILETIME timeLastWrite;
71 #else
72   struct utimbuf timeBuf;
73 #endif
74 };
75
76 #if defined(__sgi) && !defined(__GNUC__)
77 # pragma set woff 1375 /* base class destructor not virtual */
78 #endif
79
80 #if !defined(HAVE_ENVIRON_NOT_REQUIRE_PROTOTYPE)
81 // For GetEnvironmentVariables
82 # if defined(_WIN32)
83 extern __declspec( dllimport ) char** environ;
84 # else
85 extern char** environ;
86 # endif
87 #endif
88
89 #ifdef _WIN32
90 class cmSystemToolsWindowsHandle
91 {
92 public:
93   cmSystemToolsWindowsHandle(HANDLE h): handle_(h) {}
94   ~cmSystemToolsWindowsHandle()
95     {
96     if(this->handle_ != INVALID_HANDLE_VALUE)
97       {
98       CloseHandle(this->handle_);
99       }
100     }
101   operator bool() const { return this->handle_ != INVALID_HANDLE_VALUE; }
102   bool operator !() const { return this->handle_ == INVALID_HANDLE_VALUE; }
103   operator HANDLE() const { return this->handle_; }
104 private:
105   HANDLE handle_;
106 };
107 #elif defined(__APPLE__)
108 #include <crt_externs.h>
109 #define environ (*_NSGetEnviron())
110 #endif
111
112 bool cmSystemTools::s_RunCommandHideConsole = false;
113 bool cmSystemTools::s_DisableRunCommandOutput = false;
114 bool cmSystemTools::s_ErrorOccured = false;
115 bool cmSystemTools::s_FatalErrorOccured = false;
116 bool cmSystemTools::s_DisableMessages = false;
117 bool cmSystemTools::s_ForceUnixPaths = false;
118
119 std::string cmSystemTools::s_Windows9xComspecSubstitute = "command.com";
120 void cmSystemTools::SetWindows9xComspecSubstitute(const char* str)
121 {
122   if ( str )
123     {
124     cmSystemTools::s_Windows9xComspecSubstitute = str;
125     }
126 }
127 const char* cmSystemTools::GetWindows9xComspecSubstitute()
128 {
129   return cmSystemTools::s_Windows9xComspecSubstitute.c_str();
130 }
131
132 void (*cmSystemTools::s_ErrorCallback)(const char*, const char*,
133                                        bool&, void*);
134 void (*cmSystemTools::s_StdoutCallback)(const char*, int len, void*);
135 void* cmSystemTools::s_ErrorCallbackClientData = 0;
136 void* cmSystemTools::s_StdoutCallbackClientData = 0;
137 bool (*cmSystemTools::s_InterruptCallback)(void*);
138 void* cmSystemTools::s_InterruptCallbackClientData = 0;
139
140 // replace replace with with as many times as it shows up in source.
141 // write the result into source.
142 #if defined(_WIN32) && !defined(__CYGWIN__)
143 void cmSystemTools::ExpandRegistryValues(std::string& source, KeyWOW64 view)
144 {
145   // Regular expression to match anything inside [...] that begins in HKEY.
146   // Note that there is a special rule for regular expressions to match a
147   // close square-bracket inside a list delimited by square brackets.
148   // The "[^]]" part of this expression will match any character except
149   // a close square-bracket.  The ']' character must be the first in the
150   // list of characters inside the [^...] block of the expression.
151   cmsys::RegularExpression regEntry("\\[(HKEY[^]]*)\\]");
152
153   // check for black line or comment
154   while (regEntry.find(source))
155     {
156     // the arguments are the second match
157     std::string key = regEntry.match(1);
158     std::string val;
159     if (ReadRegistryValue(key.c_str(), val, view))
160       {
161       std::string reg = "[";
162       reg += key + "]";
163       cmSystemTools::ReplaceString(source, reg.c_str(), val.c_str());
164       }
165     else
166       {
167       std::string reg = "[";
168       reg += key + "]";
169       cmSystemTools::ReplaceString(source, reg.c_str(), "/registry");
170       }
171     }
172 }
173 #else
174 void cmSystemTools::ExpandRegistryValues(std::string& source, KeyWOW64)
175 {
176   cmsys::RegularExpression regEntry("\\[(HKEY[^]]*)\\]");
177   while (regEntry.find(source))
178     {
179     // the arguments are the second match
180     std::string key = regEntry.match(1);
181     std::string val;
182     std::string reg = "[";
183     reg += key + "]";
184     cmSystemTools::ReplaceString(source, reg.c_str(), "/registry");
185     }
186
187 }
188 #endif
189
190 std::string cmSystemTools::EscapeQuotes(const char* str)
191 {
192   std::string result = "";
193   for(const char* ch = str; *ch != '\0'; ++ch)
194     {
195     if(*ch == '"')
196       {
197       result += '\\';
198       }
199     result += *ch;
200     }
201   return result;
202 }
203
204 std::string cmSystemTools::TrimWhitespace(const std::string& s)
205 {
206   std::string::const_iterator start = s.begin();
207   while(start != s.end() && *start == ' ')
208     ++start;
209   if (start == s.end())
210     return "";
211
212   std::string::const_iterator stop = s.end()-1;
213   while(*stop == ' ')
214     --stop;
215   return std::string(start, stop+1);
216 }
217
218 void cmSystemTools::Error(const char* m1, const char* m2,
219                           const char* m3, const char* m4)
220 {
221   std::string message = "CMake Error: ";
222   if(m1)
223     {
224     message += m1;
225     }
226   if(m2)
227     {
228     message += m2;
229     }
230   if(m3)
231     {
232     message += m3;
233     }
234   if(m4)
235     {
236     message += m4;
237     }
238   cmSystemTools::s_ErrorOccured = true;
239   cmSystemTools::Message(message.c_str(),"Error");
240 }
241
242 void cmSystemTools::SetInterruptCallback(InterruptCallback f, void* clientData)
243 {
244   s_InterruptCallback = f;
245   s_InterruptCallbackClientData = clientData;
246 }
247
248 bool cmSystemTools::GetInterruptFlag()
249 {
250   if(s_InterruptCallback)
251     {
252     return (*s_InterruptCallback)(s_InterruptCallbackClientData);
253     }
254   return false;
255 }
256
257 void cmSystemTools::SetErrorCallback(ErrorCallback f, void* clientData)
258 {
259   s_ErrorCallback = f;
260   s_ErrorCallbackClientData = clientData;
261 }
262
263 void cmSystemTools::SetStdoutCallback(StdoutCallback f, void* clientData)
264 {
265   s_StdoutCallback = f;
266   s_StdoutCallbackClientData = clientData;
267 }
268
269 void cmSystemTools::Stdout(const char* s)
270 {
271   if(s_StdoutCallback)
272     {
273     (*s_StdoutCallback)(s, static_cast<int>(strlen(s)),
274                         s_StdoutCallbackClientData);
275     }
276   else
277     {
278     std::cout << s;
279     std::cout.flush();
280     }
281 }
282
283 void cmSystemTools::Stderr(const char* s, int length)
284 {
285     std::cerr.write(s, length);
286     std::cerr.flush();
287 }
288
289 void cmSystemTools::Stdout(const char* s, int length)
290 {
291   if(s_StdoutCallback)
292     {
293     (*s_StdoutCallback)(s, length, s_StdoutCallbackClientData);
294     }
295   else
296     {
297     std::cout.write(s, length);
298     std::cout.flush();
299     }
300 }
301
302 void cmSystemTools::Message(const char* m1, const char *title)
303 {
304   if(s_DisableMessages)
305     {
306     return;
307     }
308   if(s_ErrorCallback)
309     {
310     (*s_ErrorCallback)(m1, title, s_DisableMessages,
311                        s_ErrorCallbackClientData);
312     return;
313     }
314   else
315     {
316     std::cerr << m1 << std::endl << std::flush;
317     }
318
319 }
320
321
322 void cmSystemTools::ReportLastSystemError(const char* msg)
323 {
324   std::string m = msg;
325   m += ": System Error: ";
326   m += Superclass::GetLastSystemError();
327   cmSystemTools::Error(m.c_str());
328 }
329
330 bool cmSystemTools::IsInternallyOn(const char* val)
331 {
332   if (!val)
333     {
334     return false;
335     }
336   std::basic_string<char> v = val;
337
338   for(std::basic_string<char>::iterator c = v.begin();
339       c != v.end(); c++)
340     {
341     *c = static_cast<char>(toupper(*c));
342     }
343   return (v == "I_ON" || v == "i_on");
344 }
345
346 bool cmSystemTools::IsOn(const char* val)
347 {
348   if (!val)
349     {
350     return false;
351     }
352   std::basic_string<char> v = val;
353
354   for(std::basic_string<char>::iterator c = v.begin();
355       c != v.end(); c++)
356     {
357     *c = static_cast<char>(toupper(*c));
358     }
359   return (v == "ON" || v == "1" || v == "YES" || v == "TRUE" || v == "Y");
360 }
361
362 bool cmSystemTools::IsNOTFOUND(const char* val)
363 {
364   size_t len = strlen(val);
365   const char* notfound = "-NOTFOUND";
366   const size_t lenNotFound = 9;
367   if(len < lenNotFound-1)
368     {
369     return false;
370     }
371   if(len == lenNotFound-1)
372     {
373     return ( strcmp(val, "NOTFOUND") == 0);
374     }
375   return ((strncmp((val + (len - lenNotFound)), notfound, lenNotFound) == 0));
376 }
377
378
379 bool cmSystemTools::IsOff(const char* val)
380 {
381   if (!val || strlen(val) == 0)
382     {
383     return true;
384     }
385   std::basic_string<char> v = val;
386
387   for(std::basic_string<char>::iterator c = v.begin();
388       c != v.end(); c++)
389     {
390     *c = static_cast<char>(toupper(*c));
391     }
392   return (v == "OFF" || v == "0" || v == "NO" || v == "FALSE" ||
393           v == "N" || cmSystemTools::IsNOTFOUND(v.c_str()) || v == "IGNORE");
394 }
395
396 //----------------------------------------------------------------------------
397 void cmSystemTools::ParseWindowsCommandLine(const char* command,
398                                             std::vector<std::string>& args)
399 {
400   // See the MSDN document "Parsing C Command-Line Arguments" at
401   // http://msdn2.microsoft.com/en-us/library/a1y7w461.aspx for rules
402   // of parsing the windows command line.
403
404   bool in_argument = false;
405   bool in_quotes = false;
406   int backslashes = 0;
407   std::string arg;
408   for(const char* c = command;*c; ++c)
409     {
410     if(*c == '\\')
411       {
412       ++backslashes;
413       in_argument = true;
414       }
415     else if(*c == '"')
416       {
417       int backslash_pairs  = backslashes >> 1;
418       int backslash_escaped = backslashes & 1;
419       arg.append(backslash_pairs, '\\');
420       backslashes = 0;
421       if(backslash_escaped)
422         {
423         /* An odd number of backslashes precede this quote.
424            It is escaped.  */
425         arg.append(1, '"');
426         }
427       else
428         {
429         /* An even number of backslashes precede this quote.
430            It is not escaped.  */
431         in_quotes = !in_quotes;
432         }
433       in_argument = true;
434       }
435     else
436       {
437       arg.append(backslashes, '\\');
438       backslashes = 0;
439       if(isspace(*c))
440         {
441         if(in_quotes)
442           {
443           arg.append(1, *c);
444           }
445         else if(in_argument)
446           {
447           args.push_back(arg);
448           arg = "";
449           in_argument = false;
450           }
451         }
452       else
453         {
454         in_argument = true;
455         arg.append(1, *c);
456         }
457       }
458     }
459   arg.append(backslashes, '\\');
460   if(in_argument)
461     {
462     args.push_back(arg);
463     }
464 }
465
466 //----------------------------------------------------------------------------
467 class cmSystemToolsArgV
468 {
469   char** ArgV;
470 public:
471   cmSystemToolsArgV(char** argv): ArgV(argv) {}
472   ~cmSystemToolsArgV()
473     {
474     for(char** arg = this->ArgV; arg && *arg; ++arg)
475       {
476       free(*arg);
477       }
478     free(this->ArgV);
479     }
480   void Store(std::vector<std::string>& args) const
481     {
482     for(char** arg = this->ArgV; arg && *arg; ++arg)
483       {
484       args.push_back(*arg);
485       }
486     }
487   void Store(std::vector<cmStdString>& args) const
488     {
489     for(char** arg = this->ArgV; arg && *arg; ++arg)
490       {
491       args.push_back(*arg);
492       }
493     }
494 };
495
496 //----------------------------------------------------------------------------
497 void cmSystemTools::ParseUnixCommandLine(const char* command,
498                                          std::vector<std::string>& args)
499 {
500   // Invoke the underlying parser.
501   cmSystemToolsArgV argv = cmsysSystem_Parse_CommandForUnix(command, 0);
502   argv.Store(args);
503 }
504
505 //----------------------------------------------------------------------------
506 void cmSystemTools::ParseUnixCommandLine(const char* command,
507                                          std::vector<cmStdString>& args)
508 {
509   // Invoke the underlying parser.
510   cmSystemToolsArgV argv = cmsysSystem_Parse_CommandForUnix(command, 0);
511   argv.Store(args);
512 }
513
514 std::string cmSystemTools::EscapeWindowsShellArgument(const char* arg,
515                                                       int shell_flags)
516 {
517   char local_buffer[1024];
518   char* buffer = local_buffer;
519   int size = cmsysSystem_Shell_GetArgumentSizeForWindows(arg, shell_flags);
520   if(size > 1024)
521     {
522     buffer = new char[size];
523     }
524   cmsysSystem_Shell_GetArgumentForWindows(arg, buffer, shell_flags);
525   std::string result(buffer);
526   if(buffer != local_buffer)
527     {
528     delete [] buffer;
529     }
530   return result;
531 }
532
533 std::vector<cmStdString> cmSystemTools::ParseArguments(const char* command)
534 {
535   std::vector<cmStdString> args;
536   std::string arg;
537
538   bool win_path = false;
539
540   if ((command[0] != '/' && command[1] == ':' && command[2] == '\\') ||
541       (command[0] == '\"' && command[1] != '/' && command[2] == ':'
542        && command[3] == '\\') ||
543       (command[0] == '\'' && command[1] != '/' && command[2] == ':'
544        && command[3] == '\\') ||
545       (command[0] == '\\' && command[1] == '\\'))
546     {
547     win_path = true;
548     }
549   // Split the command into an argv array.
550   for(const char* c = command; *c;)
551     {
552     // Skip over whitespace.
553     while(*c == ' ' || *c == '\t')
554       {
555       ++c;
556       }
557     arg = "";
558     if(*c == '"')
559       {
560       // Parse a quoted argument.
561       ++c;
562       while(*c && *c != '"')
563         {
564         arg.append(1, *c);
565         ++c;
566         }
567       if(*c)
568         {
569         ++c;
570         }
571       args.push_back(arg);
572       }
573     else if(*c == '\'')
574       {
575       // Parse a quoted argument.
576       ++c;
577       while(*c && *c != '\'')
578         {
579         arg.append(1, *c);
580         ++c;
581         }
582       if(*c)
583         {
584         ++c;
585         }
586       args.push_back(arg);
587       }
588     else if(*c)
589       {
590       // Parse an unquoted argument.
591       while(*c && *c != ' ' && *c != '\t')
592         {
593         if(*c == '\\' && !win_path)
594           {
595           ++c;
596           if(*c)
597             {
598             arg.append(1, *c);
599             ++c;
600             }
601           }
602         else
603           {
604           arg.append(1, *c);
605           ++c;
606           }
607         }
608       args.push_back(arg);
609       }
610     }
611
612   return args;
613 }
614
615
616 bool cmSystemTools::RunSingleCommand(std::vector<cmStdString>const& command,
617                                      std::string* output ,
618                                      int* retVal , const char* dir ,
619                                      OutputOption outputflag ,
620                                      double timeout )
621 {
622   std::vector<const char*> argv;
623   for(std::vector<cmStdString>::const_iterator a = command.begin();
624       a != command.end(); ++a)
625     {
626     argv.push_back(a->c_str());
627     }
628   argv.push_back(0);
629   if ( output )
630     {
631     *output = "";
632     }
633
634   cmsysProcess* cp = cmsysProcess_New();
635   cmsysProcess_SetCommand(cp, &*argv.begin());
636   cmsysProcess_SetWorkingDirectory(cp, dir);
637   if(cmSystemTools::GetRunCommandHideConsole())
638     {
639     cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
640     }
641
642   cmsysProcess_SetTimeout(cp, timeout);
643   cmsysProcess_Execute(cp);
644
645   std::vector<char> tempOutput;
646   char* data;
647   int length;
648   int pipe;
649   if ( output || outputflag != OUTPUT_NONE )
650     {
651     while((pipe = cmsysProcess_WaitForData(cp, &data, &length, 0)) > 0)
652       {
653       if(output || outputflag != OUTPUT_NONE)
654         {
655         // Translate NULL characters in the output into valid text.
656         // Visual Studio 7 puts these characters in the output of its
657         // build process.
658         for(int i=0; i < length; ++i)
659           {
660           if(data[i] == '\0')
661             {
662             data[i] = ' ';
663             }
664           }
665         }
666       if ( output )
667         {
668         tempOutput.insert(tempOutput.end(), data, data+length);
669         }
670       if(outputflag != OUTPUT_NONE)
671         {
672         if(outputflag == OUTPUT_MERGE)
673           {
674           cmSystemTools::Stdout(data, length);
675           }
676         else
677           {
678           if(pipe == cmsysProcess_Pipe_STDERR)
679             {
680             cmSystemTools::Stderr(data, length);
681             }
682           else if(pipe == cmsysProcess_Pipe_STDOUT)
683             {
684             cmSystemTools::Stdout(data, length);
685             }
686           }
687         }
688       }
689     }
690
691   cmsysProcess_WaitForExit(cp, 0);
692   if ( output && tempOutput.begin() != tempOutput.end())
693     {
694     output->append(&*tempOutput.begin(), tempOutput.size());
695     }
696
697   bool result = true;
698   if(cmsysProcess_GetState(cp) == cmsysProcess_State_Exited)
699     {
700     if ( retVal )
701       {
702       *retVal = cmsysProcess_GetExitValue(cp);
703       }
704     else
705       {
706       if ( cmsysProcess_GetExitValue(cp) !=  0 )
707         {
708         result = false;
709         }
710       }
711     }
712   else if(cmsysProcess_GetState(cp) == cmsysProcess_State_Exception)
713     {
714     const char* exception_str = cmsysProcess_GetExceptionString(cp);
715     if ( outputflag != OUTPUT_NONE )
716       {
717       std::cerr << exception_str << std::endl;
718       }
719     if ( output )
720       {
721       output->append(exception_str, strlen(exception_str));
722       }
723     result = false;
724     }
725   else if(cmsysProcess_GetState(cp) == cmsysProcess_State_Error)
726     {
727     const char* error_str = cmsysProcess_GetErrorString(cp);
728     if ( outputflag != OUTPUT_NONE )
729       {
730       std::cerr << error_str << std::endl;
731       }
732     if ( output )
733       {
734       output->append(error_str, strlen(error_str));
735       }
736     result = false;
737     }
738   else if(cmsysProcess_GetState(cp) == cmsysProcess_State_Expired)
739     {
740     const char* error_str = "Process terminated due to timeout\n";
741     if ( outputflag != OUTPUT_NONE )
742       {
743       std::cerr << error_str << std::endl;
744       }
745     if ( output )
746       {
747       output->append(error_str, strlen(error_str));
748       }
749     result = false;
750     }
751
752   cmsysProcess_Delete(cp);
753   return result;
754 }
755
756 bool cmSystemTools::RunSingleCommand(
757   const char* command,
758   std::string* output,
759   int *retVal,
760   const char* dir,
761   OutputOption outputflag,
762   double timeout)
763 {
764   if(s_DisableRunCommandOutput)
765     {
766     outputflag = OUTPUT_NONE;
767     }
768
769   std::vector<cmStdString> args = cmSystemTools::ParseArguments(command);
770
771   if(args.size() < 1)
772     {
773     return false;
774     }
775   return cmSystemTools::RunSingleCommand(args, output,retVal,
776                                          dir, outputflag, timeout);
777 }
778 bool cmSystemTools::RunCommand(const char* command,
779                                std::string& output,
780                                const char* dir,
781                                bool verbose,
782                                int timeout)
783 {
784   int dummy;
785   return cmSystemTools::RunCommand(command, output, dummy,
786                                    dir, verbose, timeout);
787 }
788
789 #if defined(WIN32) && !defined(__CYGWIN__)
790 #include "cmWin32ProcessExecution.h"
791 // use this for shell commands like echo and dir
792 bool RunCommandViaWin32(const char* command,
793                         const char* dir,
794                         std::string& output,
795                         int& retVal,
796                         bool verbose,
797                         int timeout)
798 {
799 #if defined(__BORLANDC__)
800   return
801     cmWin32ProcessExecution::
802     BorlandRunCommand(command, dir, output,
803                       retVal,
804                       verbose, timeout,
805                       cmSystemTools::GetRunCommandHideConsole());
806 #else // Visual studio
807   ::SetLastError(ERROR_SUCCESS);
808   if ( ! command )
809     {
810     cmSystemTools::Error("No command specified");
811     return false;
812     }
813   cmWin32ProcessExecution resProc;
814   if(cmSystemTools::GetRunCommandHideConsole())
815     {
816     resProc.SetHideWindows(true);
817     }
818
819   if ( cmSystemTools::GetWindows9xComspecSubstitute() )
820     {
821     resProc.SetConsoleSpawn(cmSystemTools::GetWindows9xComspecSubstitute() );
822     }
823   if ( !resProc.StartProcess(command, dir, verbose) )
824     {
825     output = resProc.GetOutput();
826     if(verbose)
827       {
828       cmSystemTools::Stdout(output.c_str());
829       }
830     return false;
831     }
832   resProc.Wait(timeout);
833   output = resProc.GetOutput();
834   retVal = resProc.GetExitValue();
835   return true;
836 #endif
837 }
838
839 // use this for shell commands like echo and dir
840 bool RunCommandViaSystem(const char* command,
841                          const char* dir,
842                          std::string& output,
843                          int& retVal,
844                          bool verbose)
845 {
846   std::cout << "@@ " << command << std::endl;
847
848   std::string commandInDir;
849   if(dir)
850     {
851     commandInDir = "cd ";
852     commandInDir += cmSystemTools::ConvertToOutputPath(dir);
853     commandInDir += " && ";
854     commandInDir += command;
855     }
856   else
857     {
858     commandInDir = command;
859     }
860   command = commandInDir.c_str();
861   std::string commandToFile = command;
862   commandToFile += " > ";
863   std::string tempFile;
864   tempFile += _tempnam(0, "cmake");
865
866   commandToFile += tempFile;
867   retVal = system(commandToFile.c_str());
868   std::ifstream fin(tempFile.c_str());
869   if(!fin)
870     {
871     if(verbose)
872       {
873       std::string errormsg = "RunCommand produced no output: command: \"";
874       errormsg += command;
875       errormsg += "\"";
876       errormsg += "\nOutput file: ";
877       errormsg += tempFile;
878       cmSystemTools::Error(errormsg.c_str());
879       }
880     fin.close();
881     cmSystemTools::RemoveFile(tempFile.c_str());
882     return false;
883     }
884   bool multiLine = false;
885   std::string line;
886   while(cmSystemTools::GetLineFromStream(fin, line))
887     {
888     output += line;
889     if(multiLine)
890       {
891       output += "\n";
892       }
893     multiLine = true;
894     }
895   fin.close();
896   cmSystemTools::RemoveFile(tempFile.c_str());
897   return true;
898 }
899
900 #else // We have popen
901
902 // BeOS seems to return from a successful pclose() before the process has
903 //  legitimately exited, or at least before SIGCHLD is thrown...the signal may
904 //  come quite some time after pclose returns! This causes havoc with later
905 //  parts of CMake that expect to catch the signal from other child processes,
906 //  so we explicitly wait to catch it here. This should be safe to do with
907 //  popen() so long as we don't actually collect the zombie process ourselves.
908 #ifdef __BEOS__
909 #include <signal.h>
910 #undef SIGBUS  // this is the same as SIGSEGV on BeOS and causes issues below.
911 static volatile bool beos_seen_signal = false;
912 static void beos_popen_workaround(int sig)
913 {
914   beos_seen_signal = true;
915 }
916 #endif
917
918 bool RunCommandViaPopen(const char* command,
919                         const char* dir,
920                         std::string& output,
921                         int& retVal,
922                         bool verbose,
923                         int /*timeout*/)
924 {
925   // if only popen worked on windows.....
926   std::string commandInDir;
927   if(dir)
928     {
929     commandInDir = "cd \"";
930     commandInDir += dir;
931     commandInDir += "\" && ";
932     commandInDir += command;
933     }
934   else
935     {
936     commandInDir = command;
937     }
938 #ifndef __VMS
939   commandInDir += " 2>&1";
940 #endif
941   command = commandInDir.c_str();
942   const int BUFFER_SIZE = 4096;
943   char buffer[BUFFER_SIZE];
944   if(verbose)
945     {
946     cmSystemTools::Stdout("running ");
947     cmSystemTools::Stdout(command);
948     cmSystemTools::Stdout("\n");
949     }
950   fflush(stdout);
951   fflush(stderr);
952
953 #ifdef __BEOS__
954   beos_seen_signal = false;
955   signal(SIGCHLD, beos_popen_workaround);
956 #endif
957
958   FILE* cpipe = popen(command, "r");
959   if(!cpipe)
960     {
961 #ifdef __BEOS__
962     signal(SIGCHLD, SIG_DFL);
963 #endif
964     return false;
965     }
966   if (!fgets(buffer, BUFFER_SIZE, cpipe))
967     {
968     buffer[0] = 0;
969     }
970   while(!feof(cpipe))
971     {
972     if(verbose)
973       {
974       cmSystemTools::Stdout(buffer);
975       }
976     output += buffer;
977     if(!fgets(buffer, BUFFER_SIZE, cpipe))
978       {
979       buffer[0] = 0;
980       }
981     }
982
983   retVal = pclose(cpipe);
984
985 #ifdef __BEOS__
986   for (int i = 0; (!beos_seen_signal) && (i < 3); i++)
987     {
988     ::sleep(1);   // signals should interrupt this...
989     }
990
991   if (!beos_seen_signal)
992     {
993     signal(SIGCHLD, SIG_DFL);  // oh well, didn't happen. Go on anyhow.
994     }
995 #endif
996
997   if (WIFEXITED(retVal))
998     {
999     retVal = WEXITSTATUS(retVal);
1000     return true;
1001     }
1002   if (WIFSIGNALED(retVal))
1003     {
1004     retVal = WTERMSIG(retVal);
1005     cmOStringStream error;
1006     error << "\nProcess terminated due to ";
1007     switch (retVal)
1008       {
1009 #ifdef SIGKILL
1010       case SIGKILL:
1011         error << "SIGKILL";
1012         break;
1013 #endif
1014 #ifdef SIGFPE
1015       case SIGFPE:
1016         error << "SIGFPE";
1017         break;
1018 #endif
1019 #ifndef __HAIKU__
1020 #ifdef SIGBUS
1021       case SIGBUS:
1022         error << "SIGBUS";
1023         break;
1024 #endif
1025 #endif
1026 #ifdef SIGSEGV
1027       case SIGSEGV:
1028         error << "SIGSEGV";
1029         break;
1030 #endif
1031       default:
1032         error << "signal " << retVal;
1033         break;
1034       }
1035     output += error.str();
1036     }
1037   return false;
1038 }
1039
1040 #endif  // endif WIN32 not CYGWIN
1041
1042
1043 // run a command unix uses popen (easy)
1044 // windows uses system and ShortPath
1045 bool cmSystemTools::RunCommand(const char* command,
1046                                std::string& output,
1047                                int &retVal,
1048                                const char* dir,
1049                                bool verbose,
1050                                int timeout)
1051 {
1052   if(s_DisableRunCommandOutput)
1053     {
1054     verbose = false;
1055     }
1056
1057 #if defined(WIN32) && !defined(__CYGWIN__)
1058   // if the command does not start with a quote, then
1059   // try to find the program, and if the program can not be
1060   // found use system to run the command as it must be a built in
1061   // shell command like echo or dir
1062   int count = 0;
1063   if(command[0] == '\"')
1064     {
1065     // count the number of quotes
1066     for(const char* s = command; *s != 0; ++s)
1067       {
1068       if(*s == '\"')
1069         {
1070         count++;
1071         if(count > 2)
1072           {
1073           break;
1074           }
1075         }
1076       }
1077     // if there are more than two double quotes use
1078     // GetShortPathName, the cmd.exe program in windows which
1079     // is used by system fails to execute if there are more than
1080     // one set of quotes in the arguments
1081     if(count > 2)
1082       {
1083       cmsys::RegularExpression quoted("^\"([^\"]*)\"[ \t](.*)");
1084       if(quoted.find(command))
1085         {
1086         std::string shortCmd;
1087         std::string cmd = quoted.match(1);
1088         std::string args = quoted.match(2);
1089         if(! cmSystemTools::FileExists(cmd.c_str()) )
1090           {
1091           shortCmd = cmd;
1092           }
1093         else if(!cmSystemTools::GetShortPath(cmd.c_str(), shortCmd))
1094           {
1095          cmSystemTools::Error("GetShortPath failed for " , cmd.c_str());
1096           return false;
1097           }
1098         shortCmd += " ";
1099         shortCmd += args;
1100
1101         //return RunCommandViaSystem(shortCmd.c_str(), dir,
1102         //                           output, retVal, verbose);
1103         //return WindowsRunCommand(shortCmd.c_str(), dir,
1104         //output, retVal, verbose);
1105         return RunCommandViaWin32(shortCmd.c_str(), dir,
1106                                   output, retVal, verbose, timeout);
1107         }
1108       else
1109         {
1110         cmSystemTools::Error("Could not parse command line with quotes ",
1111                              command);
1112         }
1113       }
1114     }
1115   // if there is only one set of quotes or no quotes then just run the command
1116   //return RunCommandViaSystem(command, dir, output, retVal, verbose);
1117   //return WindowsRunCommand(command, dir, output, retVal, verbose);
1118   return ::RunCommandViaWin32(command, dir, output, retVal, verbose, timeout);
1119 #else
1120   return ::RunCommandViaPopen(command, dir, output, retVal, verbose, timeout);
1121 #endif
1122 }
1123
1124 bool cmSystemTools::DoesFileExistWithExtensions(
1125   const char* name,
1126   const std::vector<std::string>& headerExts)
1127 {
1128   std::string hname;
1129
1130   for( std::vector<std::string>::const_iterator ext = headerExts.begin();
1131        ext != headerExts.end(); ++ext )
1132     {
1133     hname = name;
1134     hname += ".";
1135     hname += *ext;
1136     if(cmSystemTools::FileExists(hname.c_str()))
1137       {
1138       return true;
1139       }
1140     }
1141   return false;
1142 }
1143
1144 std::string cmSystemTools::FileExistsInParentDirectories(const char* fname,
1145   const char* directory, const char* toplevel)
1146 {
1147   std::string file = fname;
1148   cmSystemTools::ConvertToUnixSlashes(file);
1149   std::string dir = directory;
1150   cmSystemTools::ConvertToUnixSlashes(dir);
1151   std::string prevDir;
1152   while(dir != prevDir)
1153     {
1154     std::string path = dir + "/" + file;
1155     if ( cmSystemTools::FileExists(path.c_str()) )
1156       {
1157       return path;
1158       }
1159     if ( dir.size() < strlen(toplevel) )
1160       {
1161       break;
1162       }
1163     prevDir = dir;
1164     dir = cmSystemTools::GetParentDirectory(dir.c_str());
1165     }
1166   return "";
1167 }
1168
1169 bool cmSystemTools::cmCopyFile(const char* source, const char* destination)
1170 {
1171   return Superclass::CopyFileAlways(source, destination);
1172 }
1173
1174 bool cmSystemTools::CopyFileIfDifferent(const char* source,
1175   const char* destination)
1176 {
1177   return Superclass::CopyFileIfDifferent(source, destination);
1178 }
1179
1180 //----------------------------------------------------------------------------
1181 bool cmSystemTools::RenameFile(const char* oldname, const char* newname)
1182 {
1183 #ifdef _WIN32
1184   /* On Windows the move functions will not replace existing files.
1185      Check if the destination exists.  */
1186   struct stat newFile;
1187   if(stat(newname, &newFile) == 0)
1188     {
1189     /* The destination exists.  We have to replace it carefully.  The
1190        MoveFileEx function does what we need but is not available on
1191        Win9x.  */
1192     OSVERSIONINFO osv;
1193     DWORD attrs;
1194
1195     /* Make sure the destination is not read only.  */
1196     attrs = GetFileAttributes(newname);
1197     if(attrs & FILE_ATTRIBUTE_READONLY)
1198       {
1199       SetFileAttributes(newname, attrs & ~FILE_ATTRIBUTE_READONLY);
1200       }
1201
1202     /* Check the windows version number.  */
1203     osv.dwOSVersionInfoSize = sizeof(osv);
1204     GetVersionEx(&osv);
1205     if(osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
1206       {
1207       /* This is Win9x.  There is no MoveFileEx implementation.  We
1208          cannot quite rename the file atomically.  Just delete the
1209          destination and then move the file.  */
1210       DeleteFile(newname);
1211       return MoveFile(oldname, newname) != 0;
1212       }
1213     else
1214       {
1215       /* This is not Win9x.  Use the MoveFileEx implementation.  */
1216       return MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING) != 0;
1217       }
1218     }
1219   else
1220     {
1221     /* The destination does not exist.  Just move the file.  */
1222     return MoveFile(oldname, newname) != 0;
1223     }
1224 #else
1225   /* On UNIX we have an OS-provided call to do this atomically.  */
1226   return rename(oldname, newname) == 0;
1227 #endif
1228 }
1229
1230 bool cmSystemTools::ComputeFileMD5(const char* source, char* md5out)
1231 {
1232 #if defined(CMAKE_BUILD_WITH_CMAKE)
1233   cmCryptoHashMD5 md5;
1234   std::string str = md5.HashFile(source);
1235   strncpy(md5out, str.c_str(), 32);
1236   return !str.empty();
1237 #else
1238   (void)source;
1239   (void)md5out;
1240   cmSystemTools::Message("md5sum not supported in bootstrapping mode","Error");
1241   return false;
1242 #endif
1243 }
1244
1245 std::string cmSystemTools::ComputeStringMD5(const char* input)
1246 {
1247 #if defined(CMAKE_BUILD_WITH_CMAKE)
1248   cmCryptoHashMD5 md5;
1249   return md5.HashString(input);
1250 #else
1251   (void)input;
1252   cmSystemTools::Message("md5sum not supported in bootstrapping mode","Error");
1253   return "";
1254 #endif
1255 }
1256
1257 void cmSystemTools::Glob(const char *directory, const char *regexp,
1258                          std::vector<std::string>& files)
1259 {
1260   cmsys::Directory d;
1261   cmsys::RegularExpression reg(regexp);
1262
1263   if (d.Load(directory))
1264     {
1265     size_t numf;
1266         unsigned int i;
1267     numf = d.GetNumberOfFiles();
1268     for (i = 0; i < numf; i++)
1269       {
1270       std::string fname = d.GetFile(i);
1271       if (reg.find(fname))
1272         {
1273         files.push_back(fname);
1274         }
1275       }
1276     }
1277 }
1278
1279
1280 void cmSystemTools::GlobDirs(const char *fullPath,
1281                              std::vector<std::string>& files)
1282 {
1283   std::string path = fullPath;
1284   std::string::size_type pos = path.find("/*");
1285   if(pos == std::string::npos)
1286     {
1287     files.push_back(fullPath);
1288     return;
1289     }
1290   std::string startPath = path.substr(0, pos);
1291   std::string finishPath = path.substr(pos+2);
1292
1293   cmsys::Directory d;
1294   if (d.Load(startPath.c_str()))
1295     {
1296     for (unsigned int i = 0; i < d.GetNumberOfFiles(); ++i)
1297       {
1298       if((std::string(d.GetFile(i)) != ".")
1299          && (std::string(d.GetFile(i)) != ".."))
1300         {
1301         std::string fname = startPath;
1302         fname +="/";
1303         fname += d.GetFile(i);
1304         if(cmSystemTools::FileIsDirectory(fname.c_str()))
1305           {
1306           fname += finishPath;
1307           cmSystemTools::GlobDirs(fname.c_str(), files);
1308           }
1309         }
1310       }
1311     }
1312 }
1313
1314
1315 void cmSystemTools::ExpandList(std::vector<std::string> const& arguments,
1316                                std::vector<std::string>& newargs)
1317 {
1318   std::vector<std::string>::const_iterator i;
1319   for(i = arguments.begin();i != arguments.end(); ++i)
1320     {
1321     cmSystemTools::ExpandListArgument(*i, newargs);
1322     }
1323 }
1324
1325 void cmSystemTools::ExpandListArgument(const std::string& arg,
1326                                        std::vector<std::string>& newargs,
1327                                        bool emptyArgs)
1328 {
1329   // If argument is empty, it is an empty list.
1330   if(arg.length() == 0 && !emptyArgs)
1331     {
1332     return;
1333     }
1334   // if there are no ; in the name then just copy the current string
1335   if(arg.find(';') == std::string::npos)
1336     {
1337     newargs.push_back(arg);
1338     return;
1339     }
1340   std::vector<char> newArgVec;
1341   // Break the string at non-escaped semicolons not nested in [].
1342   int squareNesting = 0;
1343   for(const char* c = arg.c_str(); *c; ++c)
1344     {
1345     switch(*c)
1346       {
1347       case '\\':
1348         {
1349         // We only want to allow escaping of semicolons.  Other
1350         // escapes should not be processed here.
1351         ++c;
1352         if(*c == ';')
1353           {
1354           newArgVec.push_back(*c);
1355           }
1356         else
1357           {
1358           newArgVec.push_back('\\');
1359           if(*c)
1360             {
1361             newArgVec.push_back(*c);
1362             }
1363           else
1364             {
1365             // Terminate the loop properly.
1366             --c;
1367             }
1368           }
1369         } break;
1370       case '[':
1371         {
1372         ++squareNesting;
1373         newArgVec.push_back(*c);
1374         } break;
1375       case ']':
1376         {
1377         --squareNesting;
1378         newArgVec.push_back(*c);
1379         } break;
1380       case ';':
1381         {
1382         // Break the string here if we are not nested inside square
1383         // brackets.
1384         if(squareNesting == 0)
1385           {
1386           if ( newArgVec.size() || emptyArgs )
1387             {
1388             // Add the last argument if the string is not empty.
1389             newArgVec.push_back(0);
1390             newargs.push_back(&*newArgVec.begin());
1391             newArgVec.clear();
1392             }
1393           }
1394         else
1395           {
1396           newArgVec.push_back(*c);
1397           }
1398         } break;
1399       default:
1400         {
1401         // Just append this character.
1402         newArgVec.push_back(*c);
1403         } break;
1404       }
1405     }
1406   if ( newArgVec.size() || emptyArgs )
1407     {
1408     // Add the last argument if the string is not empty.
1409     newArgVec.push_back(0);
1410     newargs.push_back(&*newArgVec.begin());
1411     }
1412 }
1413
1414 bool cmSystemTools::SimpleGlob(const cmStdString& glob,
1415                                std::vector<cmStdString>& files,
1416                                int type /* = 0 */)
1417 {
1418   files.clear();
1419   if ( glob[glob.size()-1] != '*' )
1420     {
1421     return false;
1422     }
1423   std::string path = cmSystemTools::GetFilenamePath(glob);
1424   std::string ppath = cmSystemTools::GetFilenameName(glob);
1425   ppath = ppath.substr(0, ppath.size()-1);
1426   if ( path.size() == 0 )
1427     {
1428     path = "/";
1429     }
1430
1431   bool res = false;
1432   cmsys::Directory d;
1433   if (d.Load(path.c_str()))
1434     {
1435     for (unsigned int i = 0; i < d.GetNumberOfFiles(); ++i)
1436       {
1437       if((std::string(d.GetFile(i)) != ".")
1438          && (std::string(d.GetFile(i)) != ".."))
1439         {
1440         std::string fname = path;
1441         if ( path[path.size()-1] != '/' )
1442           {
1443           fname +="/";
1444           }
1445         fname += d.GetFile(i);
1446         std::string sfname = d.GetFile(i);
1447         if ( type > 0 && cmSystemTools::FileIsDirectory(fname.c_str()) )
1448           {
1449           continue;
1450           }
1451         if ( type < 0 && !cmSystemTools::FileIsDirectory(fname.c_str()) )
1452           {
1453           continue;
1454           }
1455         if ( sfname.size() >= ppath.size() &&
1456              sfname.substr(0, ppath.size()) ==
1457              ppath )
1458           {
1459           files.push_back(fname);
1460           res = true;
1461           }
1462         }
1463       }
1464     }
1465   return res;
1466 }
1467
1468 cmSystemTools::FileFormat cmSystemTools::GetFileFormat(const char* cext)
1469 {
1470   if ( ! cext || *cext == 0 )
1471     {
1472     return cmSystemTools::NO_FILE_FORMAT;
1473     }
1474   //std::string ext = cmSystemTools::LowerCase(cext);
1475   std::string ext = cext;
1476   if ( ext == "c" || ext == ".c" ||
1477        ext == "m" || ext == ".m"
1478     ) { return cmSystemTools::C_FILE_FORMAT; }
1479   if (
1480     ext == "C" || ext == ".C" ||
1481     ext == "M" || ext == ".M" ||
1482     ext == "c++" || ext == ".c++" ||
1483     ext == "cc" || ext == ".cc" ||
1484     ext == "cpp" || ext == ".cpp" ||
1485     ext == "cxx" || ext == ".cxx" ||
1486     ext == "mm" || ext == ".mm"
1487     ) { return cmSystemTools::CXX_FILE_FORMAT; }
1488   if (
1489     ext == "f" || ext == ".f" ||
1490     ext == "F" || ext == ".F" ||
1491     ext == "f77" || ext == ".f77" ||
1492     ext == "f90" || ext == ".f90" ||
1493     ext == "for" || ext == ".for" ||
1494     ext == "f95" || ext == ".f95"
1495     ) { return cmSystemTools::FORTRAN_FILE_FORMAT; }
1496   if ( ext == "java" || ext == ".java" )
1497     { return cmSystemTools::JAVA_FILE_FORMAT; }
1498   if (
1499     ext == "H" || ext == ".H" ||
1500     ext == "h" || ext == ".h" ||
1501     ext == "h++" || ext == ".h++" ||
1502     ext == "hm" || ext == ".hm" ||
1503     ext == "hpp" || ext == ".hpp" ||
1504     ext == "hxx" || ext == ".hxx" ||
1505     ext == "in" || ext == ".in" ||
1506     ext == "txx" || ext == ".txx"
1507     ) { return cmSystemTools::HEADER_FILE_FORMAT; }
1508   if ( ext == "rc" || ext == ".rc" )
1509     { return cmSystemTools::RESOURCE_FILE_FORMAT; }
1510   if ( ext == "def" || ext == ".def" )
1511     { return cmSystemTools::DEFINITION_FILE_FORMAT; }
1512   if ( ext == "lib" || ext == ".lib" ||
1513        ext == "a" || ext == ".a")
1514     { return cmSystemTools::STATIC_LIBRARY_FILE_FORMAT; }
1515   if ( ext == "o" || ext == ".o" ||
1516        ext == "obj" || ext == ".obj")
1517     { return cmSystemTools::OBJECT_FILE_FORMAT; }
1518 #ifdef __APPLE__
1519   if ( ext == "dylib" || ext == ".dylib" )
1520     { return cmSystemTools::SHARED_LIBRARY_FILE_FORMAT; }
1521   if ( ext == "so" || ext == ".so" ||
1522        ext == "bundle" || ext == ".bundle" )
1523     { return cmSystemTools::MODULE_FILE_FORMAT; }
1524 #else // __APPLE__
1525   if ( ext == "so" || ext == ".so" ||
1526        ext == "sl" || ext == ".sl" ||
1527        ext == "dll" || ext == ".dll" )
1528     { return cmSystemTools::SHARED_LIBRARY_FILE_FORMAT; }
1529 #endif // __APPLE__
1530   return cmSystemTools::UNKNOWN_FILE_FORMAT;
1531 }
1532
1533 bool cmSystemTools::Split(const char* s, std::vector<cmStdString>& l)
1534 {
1535   std::vector<std::string> temp;
1536   bool res = Superclass::Split(s, temp);
1537   for(std::vector<std::string>::const_iterator i = temp.begin();
1538       i != temp.end(); ++i)
1539     {
1540     l.push_back(*i);
1541     }
1542   return res;
1543 }
1544
1545 std::string cmSystemTools::ConvertToOutputPath(const char* path)
1546 {
1547 #if defined(_WIN32) && !defined(__CYGWIN__)
1548   if(s_ForceUnixPaths)
1549     {
1550     return cmSystemTools::ConvertToUnixOutputPath(path);
1551     }
1552   return cmSystemTools::ConvertToWindowsOutputPath(path);
1553 #else
1554   return cmSystemTools::ConvertToUnixOutputPath(path);
1555 #endif
1556 }
1557
1558 void cmSystemTools::ConvertToOutputSlashes(std::string& path)
1559 {
1560 #if defined(_WIN32) && !defined(__CYGWIN__)
1561   if(!s_ForceUnixPaths)
1562     {
1563     // Convert to windows slashes.
1564     std::string::size_type pos = 0;
1565     while((pos = path.find('/', pos)) != std::string::npos)
1566       {
1567       path[pos++] = '\\';
1568       }
1569     }
1570 #else
1571   static_cast<void>(path);
1572 #endif
1573 }
1574
1575 std::string cmSystemTools::ConvertToRunCommandPath(const char* path)
1576 {
1577 #if defined(_WIN32) && !defined(__CYGWIN__)
1578   return cmSystemTools::ConvertToWindowsOutputPath(path);
1579 #else
1580   return cmSystemTools::ConvertToUnixOutputPath(path);
1581 #endif
1582 }
1583
1584 bool cmSystemTools::StringEndsWith(const char* str1, const char* str2)
1585 {
1586   if ( !str1 || !str2 || strlen(str1) < strlen(str2) )
1587     {
1588     return 0;
1589     }
1590   return !strncmp(str1 + (strlen(str1)-strlen(str2)), str2, strlen(str2));
1591 }
1592
1593 // compute the relative path from here to there
1594 std::string cmSystemTools::RelativePath(const char* local, const char* remote)
1595 {
1596   if(!cmSystemTools::FileIsFullPath(local))
1597     {
1598     cmSystemTools::Error("RelativePath must be passed a full path to local: ",
1599                          local);
1600     }
1601   if(!cmSystemTools::FileIsFullPath(remote))
1602     {
1603     cmSystemTools::Error
1604       ("RelativePath must be passed a full path to remote: ", remote);
1605     }
1606   return cmsys::SystemTools::RelativePath(local, remote);
1607 }
1608
1609 #ifdef CMAKE_BUILD_WITH_CMAKE
1610 //----------------------------------------------------------------------
1611 bool cmSystemTools::UnsetEnv(const char* value)
1612 {
1613 #if !defined(HAVE_UNSETENV)
1614   std::string var = value;
1615   var += "=";
1616   return cmSystemTools::PutEnv(var.c_str());
1617 #else
1618   unsetenv(value);
1619   return true;
1620 #endif
1621 }
1622
1623 //----------------------------------------------------------------------
1624 std::vector<std::string> cmSystemTools::GetEnvironmentVariables()
1625 {
1626   std::vector<std::string> env;
1627   int cc;
1628   for ( cc = 0; environ[cc]; ++ cc )
1629     {
1630     env.push_back(environ[cc]);
1631     }
1632   return env;
1633 }
1634
1635 //----------------------------------------------------------------------
1636 void cmSystemTools::AppendEnv(std::vector<std::string> const& env)
1637 {
1638   for(std::vector<std::string>::const_iterator eit = env.begin();
1639       eit != env.end(); ++eit)
1640     {
1641     cmSystemTools::PutEnv(eit->c_str());
1642     }
1643 }
1644
1645 //----------------------------------------------------------------------
1646 cmSystemTools::SaveRestoreEnvironment::SaveRestoreEnvironment()
1647 {
1648   this->Env = cmSystemTools::GetEnvironmentVariables();
1649 }
1650
1651 //----------------------------------------------------------------------
1652 cmSystemTools::SaveRestoreEnvironment::~SaveRestoreEnvironment()
1653 {
1654   // First clear everything in the current environment:
1655   std::vector<std::string> currentEnv = GetEnvironmentVariables();
1656   for(std::vector<std::string>::const_iterator
1657         eit = currentEnv.begin(); eit != currentEnv.end(); ++eit)
1658     {
1659     std::string var(*eit);
1660
1661     std::string::size_type pos = var.find("=");
1662     if (pos != std::string::npos)
1663       {
1664       var = var.substr(0, pos);
1665       }
1666
1667     cmSystemTools::UnsetEnv(var.c_str());
1668     }
1669
1670   // Then put back each entry from the original environment:
1671   cmSystemTools::AppendEnv(this->Env);
1672 }
1673 #endif
1674
1675 void cmSystemTools::EnableVSConsoleOutput()
1676 {
1677   // Visual Studio 8 2005 (devenv.exe or VCExpress.exe) will not
1678   // display output to the console unless this environment variable is
1679   // set.  We need it to capture the output of these build tools.
1680   // Note for future work that one could pass "/out \\.\pipe\NAME" to
1681   // either of these executables where NAME is created with
1682   // CreateNamedPipe.  This would bypass the internal buffering of the
1683   // output and allow it to be captured on the fly.
1684 #ifdef _WIN32
1685   cmSystemTools::PutEnv("vsconsoleoutput=1");
1686 #endif
1687 }
1688
1689 bool cmSystemTools::IsPathToFramework(const char* path)
1690 {
1691   if(cmSystemTools::FileIsFullPath(path))
1692     {
1693     std::string libname = path;
1694     if(libname.find(".framework") == libname.size()+1-sizeof(".framework"))
1695       {
1696       return true;
1697       }
1698     }
1699   return false;
1700 }
1701
1702 bool cmSystemTools::CreateTar(const char* outFileName,
1703                               const std::vector<cmStdString>& files,
1704                               bool gzip, bool bzip2, bool verbose)
1705 {
1706 #if defined(CMAKE_BUILD_WITH_CMAKE)
1707   std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
1708   std::ofstream fout(outFileName, std::ios::out | cmsys_ios_binary);
1709   if(!fout)
1710     {
1711     std::string e = "Cannot open output file \"";
1712     e += outFileName;
1713     e += "\": ";
1714     e += cmSystemTools::GetLastSystemError();
1715     cmSystemTools::Error(e.c_str());
1716     return false;
1717     }
1718   cmArchiveWrite a(fout, (gzip? cmArchiveWrite::CompressGZip :
1719                           (bzip2? cmArchiveWrite::CompressBZip2 :
1720                            cmArchiveWrite::CompressNone)),
1721                            cmArchiveWrite::TypeTAR);
1722   a.SetVerbose(verbose);
1723   for(std::vector<cmStdString>::const_iterator i = files.begin();
1724       i != files.end(); ++i)
1725     {
1726     std::string path = *i;
1727     if(cmSystemTools::FileIsFullPath(path.c_str()))
1728       {
1729       // Get the relative path to the file.
1730       path = cmSystemTools::RelativePath(cwd.c_str(), path.c_str());
1731       }
1732     if(!a.Add(path))
1733       {
1734       break;
1735       }
1736     }
1737   if(!a)
1738     {
1739     cmSystemTools::Error(a.GetError().c_str());
1740     return false;
1741     }
1742   return true;
1743 #else
1744   (void)outFileName;
1745   (void)files;
1746   (void)gzip;
1747   (void)verbose;
1748   return false;
1749 #endif
1750 }
1751
1752 #if defined(CMAKE_BUILD_WITH_CMAKE)
1753 namespace{
1754 #define BSDTAR_FILESIZE_PRINTF  "%lu"
1755 #define BSDTAR_FILESIZE_TYPE    unsigned long
1756   void
1757     list_item_verbose(FILE *out, struct archive_entry *entry)
1758 {
1759   char                   tmp[100];
1760   size_t                         w;
1761   const char            *p;
1762   const char            *fmt;
1763   time_t                         tim;
1764   static time_t          now;
1765   size_t u_width = 6;
1766   size_t gs_width = 13;
1767
1768   /*
1769    * We avoid collecting the entire list in memory at once by
1770    * listing things as we see them.  However, that also means we can't
1771    * just pre-compute the field widths.  Instead, we start with guesses
1772    * and just widen them as necessary.  These numbers are completely
1773    * arbitrary.
1774    */
1775   if (!now)
1776     {
1777     time(&now);
1778     }
1779   fprintf(out, "%s %d ",
1780           archive_entry_strmode(entry),
1781           archive_entry_nlink(entry));
1782
1783   /* Use uname if it's present, else uid. */
1784   p = archive_entry_uname(entry);
1785   if ((p == NULL) || (*p == '\0'))
1786     {
1787     sprintf(tmp, "%lu ",
1788             (unsigned long)archive_entry_uid(entry));
1789     p = tmp;
1790     }
1791   w = strlen(p);
1792   if (w > u_width)
1793     {
1794     u_width = w;
1795     }
1796   fprintf(out, "%-*s ", (int)u_width, p);
1797   /* Use gname if it's present, else gid. */
1798   p = archive_entry_gname(entry);
1799   if (p != NULL && p[0] != '\0')
1800     {
1801     fprintf(out, "%s", p);
1802     w = strlen(p);
1803     }
1804   else
1805     {
1806     sprintf(tmp, "%lu",
1807             (unsigned long)archive_entry_gid(entry));
1808     w = strlen(tmp);
1809     fprintf(out, "%s", tmp);
1810     }
1811
1812   /*
1813    * Print device number or file size, right-aligned so as to make
1814    * total width of group and devnum/filesize fields be gs_width.
1815    * If gs_width is too small, grow it.
1816    */
1817   if (archive_entry_filetype(entry) == AE_IFCHR
1818       || archive_entry_filetype(entry) == AE_IFBLK)
1819     {
1820     sprintf(tmp, "%lu,%lu",
1821             (unsigned long)archive_entry_rdevmajor(entry),
1822             (unsigned long)archive_entry_rdevminor(entry));
1823     }
1824   else
1825     {
1826     /*
1827      * Note the use of platform-dependent macros to format
1828      * the filesize here.  We need the format string and the
1829      * corresponding type for the cast.
1830      */
1831     sprintf(tmp, BSDTAR_FILESIZE_PRINTF,
1832             (BSDTAR_FILESIZE_TYPE)archive_entry_size(entry));
1833     }
1834   if (w + strlen(tmp) >= gs_width)
1835     {
1836     gs_width = w+strlen(tmp)+1;
1837     }
1838   fprintf(out, "%*s", (int)(gs_width - w), tmp);
1839
1840   /* Format the time using 'ls -l' conventions. */
1841   tim = archive_entry_mtime(entry);
1842 #define HALF_YEAR (time_t)365 * 86400 / 2
1843 #if defined(_WIN32) && !defined(__CYGWIN__)
1844   /* Windows' strftime function does not support %e format. */
1845 #define DAY_FMT  "%d"
1846 #else
1847 #define DAY_FMT  "%e"  /* Day number without leading zeros */
1848 #endif
1849   if (tim < now - HALF_YEAR || tim > now + HALF_YEAR)
1850     {
1851     fmt = DAY_FMT " %b  %Y";
1852     }
1853   else
1854     {
1855     fmt = DAY_FMT " %b %H:%M";
1856     }
1857   strftime(tmp, sizeof(tmp), fmt, localtime(&tim));
1858   fprintf(out, " %s ", tmp);
1859   fprintf(out, "%s", archive_entry_pathname(entry));
1860
1861   /* Extra information for links. */
1862   if (archive_entry_hardlink(entry)) /* Hard link */
1863     {
1864     fprintf(out, " link to %s",
1865             archive_entry_hardlink(entry));
1866     }
1867   else if (archive_entry_symlink(entry)) /* Symbolic link */
1868     {
1869     fprintf(out, " -> %s", archive_entry_symlink(entry));
1870     }
1871 }
1872 #ifdef __BORLANDC__
1873 # pragma warn -8066 /* unreachable code */
1874 #endif
1875
1876 long copy_data(struct archive *ar, struct archive *aw)
1877 {
1878   long r;
1879   const void *buff;
1880   size_t size;
1881 #if defined(ARCHIVE_VERSION_NUMBER) && ARCHIVE_VERSION_NUMBER >= 3000000
1882   __LA_INT64_T offset;
1883 #else
1884   off_t offset;
1885 #endif
1886
1887   for (;;)
1888     {
1889     r = archive_read_data_block(ar, &buff, &size, &offset);
1890     if (r == ARCHIVE_EOF)
1891       {
1892       return (ARCHIVE_OK);
1893       }
1894     if (r != ARCHIVE_OK)
1895       {
1896       return (r);
1897       }
1898     r = archive_write_data_block(aw, buff, size, offset);
1899     if (r != ARCHIVE_OK)
1900       {
1901       cmSystemTools::Message("archive_write_data_block()",
1902                              archive_error_string(aw));
1903       return (r);
1904       }
1905     }
1906   return r;
1907 }
1908
1909 bool extract_tar(const char* outFileName, bool verbose,
1910                  bool extract)
1911 {
1912   struct archive* a = archive_read_new();
1913   struct archive *ext = archive_write_disk_new();
1914   archive_read_support_compression_all(a);
1915   archive_read_support_format_all(a);
1916   struct archive_entry *entry;
1917   int r = archive_read_open_file(a, outFileName, 10240);
1918   if(r)
1919     {
1920     cmSystemTools::Error("Problem with archive_read_open_file(): ",
1921                          archive_error_string(a));
1922     return false;
1923     }
1924   for (;;)
1925     {
1926     r = archive_read_next_header(a, &entry);
1927     if (r == ARCHIVE_EOF)
1928       {
1929       break;
1930       }
1931     if (r != ARCHIVE_OK)
1932       {
1933       cmSystemTools::Error("Problem with archive_read_next_header(): ",
1934                            archive_error_string(a));
1935       }
1936     if (verbose && extract)
1937       {
1938       cmSystemTools::Stdout("x ");
1939       cmSystemTools::Stdout(archive_entry_pathname(entry));
1940       }
1941     if(verbose && !extract)
1942       {
1943       list_item_verbose(stdout, entry);
1944       }
1945     else if(!extract)
1946       {
1947       cmSystemTools::Stdout(archive_entry_pathname(entry));
1948       }
1949     if(extract)
1950       {
1951       r = archive_write_disk_set_options(ext, ARCHIVE_EXTRACT_TIME);
1952       if (r != ARCHIVE_OK)
1953         {
1954         cmSystemTools::Error(
1955           "Problem with archive_write_disk_set_options(): ",
1956           archive_error_string(ext));
1957         }
1958
1959       r = archive_write_header(ext, entry);
1960       if (r != ARCHIVE_OK)
1961         {
1962         cmSystemTools::Error("Problem with archive_write_header(): ",
1963                              archive_error_string(ext));
1964         cmSystemTools::Error("Current file:",
1965                              archive_entry_pathname(entry));
1966         }
1967       else
1968         {
1969         copy_data(a, ext);
1970         r = archive_write_finish_entry(ext);
1971         if (r != ARCHIVE_OK)
1972           {
1973           cmSystemTools::Error("Problem with archive_write_finish_entry(): ",
1974                                archive_error_string(ext));
1975           }
1976         }
1977       }
1978     if (verbose || !extract)
1979       {
1980       cmSystemTools::Stdout("\n");
1981       }
1982     }
1983   archive_read_close(a);
1984   archive_read_finish(a);
1985   return true;
1986
1987 }
1988 }
1989 #endif
1990
1991 bool cmSystemTools::ExtractTar(const char* outFileName,
1992                                bool , bool verbose)
1993 {
1994 #if defined(CMAKE_BUILD_WITH_CMAKE)
1995   return extract_tar(outFileName, verbose, true);
1996 #else
1997   (void)outFileName;
1998   (void)verbose;
1999   return false;
2000 #endif
2001 }
2002
2003 bool cmSystemTools::ListTar(const char* outFileName,
2004                             bool ,
2005                             bool verbose)
2006 {
2007 #if defined(CMAKE_BUILD_WITH_CMAKE)
2008   return extract_tar(outFileName, verbose, false);
2009 #else
2010   (void)outFileName;
2011   (void)verbose;
2012   return false;
2013 #endif
2014 }
2015
2016 int cmSystemTools::WaitForLine(cmsysProcess* process, std::string& line,
2017                                double timeout,
2018                                std::vector<char>& out,
2019                                std::vector<char>& err)
2020 {
2021   line = "";
2022   std::vector<char>::iterator outiter = out.begin();
2023   std::vector<char>::iterator erriter = err.begin();
2024   while(1)
2025     {
2026     // Check for a newline in stdout.
2027     for(;outiter != out.end(); ++outiter)
2028       {
2029       if((*outiter == '\r') && ((outiter+1) == out.end()))
2030         {
2031         break;
2032         }
2033       else if(*outiter == '\n' || *outiter == '\0')
2034         {
2035         std::vector<char>::size_type length = outiter-out.begin();
2036         if(length > 1 && *(outiter-1) == '\r')
2037           {
2038           --length;
2039           }
2040         if(length > 0)
2041           {
2042           line.append(&out[0], length);
2043           }
2044         out.erase(out.begin(), outiter+1);
2045         return cmsysProcess_Pipe_STDOUT;
2046         }
2047       }
2048
2049     // Check for a newline in stderr.
2050     for(;erriter != err.end(); ++erriter)
2051       {
2052       if((*erriter == '\r') && ((erriter+1) == err.end()))
2053         {
2054         break;
2055         }
2056       else if(*erriter == '\n' || *erriter == '\0')
2057         {
2058         std::vector<char>::size_type length = erriter-err.begin();
2059         if(length > 1 && *(erriter-1) == '\r')
2060           {
2061           --length;
2062           }
2063         if(length > 0)
2064           {
2065           line.append(&err[0], length);
2066           }
2067         err.erase(err.begin(), erriter+1);
2068         return cmsysProcess_Pipe_STDERR;
2069         }
2070       }
2071
2072     // No newlines found.  Wait for more data from the process.
2073     int length;
2074     char* data;
2075     int pipe = cmsysProcess_WaitForData(process, &data, &length, &timeout);
2076     if(pipe == cmsysProcess_Pipe_Timeout)
2077       {
2078       // Timeout has been exceeded.
2079       return pipe;
2080       }
2081     else if(pipe == cmsysProcess_Pipe_STDOUT)
2082       {
2083       // Append to the stdout buffer.
2084       std::vector<char>::size_type size = out.size();
2085       out.insert(out.end(), data, data+length);
2086       outiter = out.begin()+size;
2087       }
2088     else if(pipe == cmsysProcess_Pipe_STDERR)
2089       {
2090       // Append to the stderr buffer.
2091       std::vector<char>::size_type size = err.size();
2092       err.insert(err.end(), data, data+length);
2093       erriter = err.begin()+size;
2094       }
2095     else if(pipe == cmsysProcess_Pipe_None)
2096       {
2097       // Both stdout and stderr pipes have broken.  Return leftover data.
2098       if(!out.empty())
2099         {
2100         line.append(&out[0], outiter-out.begin());
2101         out.erase(out.begin(), out.end());
2102         return cmsysProcess_Pipe_STDOUT;
2103         }
2104       else if(!err.empty())
2105         {
2106         line.append(&err[0], erriter-err.begin());
2107         err.erase(err.begin(), err.end());
2108         return cmsysProcess_Pipe_STDERR;
2109         }
2110       else
2111         {
2112         return cmsysProcess_Pipe_None;
2113         }
2114       }
2115     }
2116 }
2117
2118 void cmSystemTools::DoNotInheritStdPipes()
2119 {
2120 #ifdef _WIN32
2121   // Check to see if we are attached to a console
2122   // if so, then do not stop the inherited pipes
2123   // or stdout and stderr will not show up in dos
2124   // shell windows
2125   CONSOLE_SCREEN_BUFFER_INFO hOutInfo;
2126   HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
2127   if(GetConsoleScreenBufferInfo(hOut, &hOutInfo))
2128     {
2129     return;
2130     }
2131   {
2132   HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
2133   DuplicateHandle(GetCurrentProcess(), out,
2134                   GetCurrentProcess(), &out, 0, FALSE,
2135                   DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
2136   SetStdHandle(STD_OUTPUT_HANDLE, out);
2137   }
2138   {
2139   HANDLE out = GetStdHandle(STD_ERROR_HANDLE);
2140   DuplicateHandle(GetCurrentProcess(), out,
2141                   GetCurrentProcess(), &out, 0, FALSE,
2142                   DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
2143   SetStdHandle(STD_ERROR_HANDLE, out);
2144   }
2145 #endif
2146 }
2147
2148 //----------------------------------------------------------------------------
2149 bool cmSystemTools::CopyFileTime(const char* fromFile, const char* toFile)
2150 {
2151 #if defined(_WIN32) && !defined(__CYGWIN__)
2152   cmSystemToolsWindowsHandle hFrom =
2153     CreateFile(fromFile, GENERIC_READ, FILE_SHARE_READ, 0,
2154                OPEN_EXISTING, 0, 0);
2155   cmSystemToolsWindowsHandle hTo =
2156     CreateFile(toFile, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
2157   if(!hFrom || !hTo)
2158     {
2159     return false;
2160     }
2161   FILETIME timeCreation;
2162   FILETIME timeLastAccess;
2163   FILETIME timeLastWrite;
2164   if(!GetFileTime(hFrom, &timeCreation, &timeLastAccess, &timeLastWrite))
2165     {
2166     return false;
2167     }
2168   if(!SetFileTime(hTo, &timeCreation, &timeLastAccess, &timeLastWrite))
2169     {
2170     return false;
2171     }
2172 #else
2173   struct stat fromStat;
2174   if(stat(fromFile, &fromStat) < 0)
2175     {
2176     return false;
2177     }
2178
2179   struct utimbuf buf;
2180   buf.actime = fromStat.st_atime;
2181   buf.modtime = fromStat.st_mtime;
2182   if(utime(toFile, &buf) < 0)
2183     {
2184     return false;
2185     }
2186 #endif
2187   return true;
2188 }
2189
2190 //----------------------------------------------------------------------------
2191 cmSystemToolsFileTime* cmSystemTools::FileTimeNew()
2192 {
2193   return new cmSystemToolsFileTime;
2194 }
2195
2196 //----------------------------------------------------------------------------
2197 void cmSystemTools::FileTimeDelete(cmSystemToolsFileTime* t)
2198 {
2199   delete t;
2200 }
2201
2202 //----------------------------------------------------------------------------
2203 bool cmSystemTools::FileTimeGet(const char* fname, cmSystemToolsFileTime* t)
2204 {
2205 #if defined(_WIN32) && !defined(__CYGWIN__)
2206   cmSystemToolsWindowsHandle h =
2207     CreateFile(fname, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
2208   if(!h)
2209     {
2210     return false;
2211     }
2212   if(!GetFileTime(h, &t->timeCreation, &t->timeLastAccess, &t->timeLastWrite))
2213     {
2214     return false;
2215     }
2216 #else
2217   struct stat st;
2218   if(stat(fname, &st) < 0)
2219     {
2220     return false;
2221     }
2222   t->timeBuf.actime = st.st_atime;
2223   t->timeBuf.modtime = st.st_mtime;
2224 #endif
2225   return true;
2226 }
2227
2228 //----------------------------------------------------------------------------
2229 bool cmSystemTools::FileTimeSet(const char* fname, cmSystemToolsFileTime* t)
2230 {
2231 #if defined(_WIN32) && !defined(__CYGWIN__)
2232   cmSystemToolsWindowsHandle h =
2233     CreateFile(fname, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
2234   if(!h)
2235     {
2236     return false;
2237     }
2238   if(!SetFileTime(h, &t->timeCreation, &t->timeLastAccess, &t->timeLastWrite))
2239     {
2240     return false;
2241     }
2242 #else
2243   if(utime(fname, &t->timeBuf) < 0)
2244     {
2245     return false;
2246     }
2247 #endif
2248   return true;
2249 }
2250
2251 //----------------------------------------------------------------------------
2252 #ifdef _WIN32
2253 # ifndef CRYPT_SILENT
2254 #  define CRYPT_SILENT 0x40 /* Not defined by VS 6 version of header.  */
2255 # endif
2256 static int WinCryptRandom(void* data, size_t size)
2257 {
2258   int result = 0;
2259   HCRYPTPROV hProvider = 0;
2260   if(CryptAcquireContextW(&hProvider, 0, 0, PROV_RSA_FULL,
2261                           CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
2262     {
2263     result = CryptGenRandom(hProvider, (DWORD)size, (BYTE*)data)? 1:0;
2264     CryptReleaseContext(hProvider, 0);
2265     }
2266   return result;
2267 }
2268 #endif
2269
2270 //----------------------------------------------------------------------------
2271 unsigned int cmSystemTools::RandomSeed()
2272 {
2273 #if defined(_WIN32) && !defined(__CYGWIN__)
2274   unsigned int seed = 0;
2275
2276   // Try using a real random source.
2277   if(WinCryptRandom(&seed, sizeof(seed)))
2278     {
2279     return seed;
2280     }
2281
2282   // Fall back to the time and pid.
2283   FILETIME ft;
2284   GetSystemTimeAsFileTime(&ft);
2285   unsigned int t1 = static_cast<unsigned int>(ft.dwHighDateTime);
2286   unsigned int t2 = static_cast<unsigned int>(ft.dwLowDateTime);
2287   unsigned int pid = static_cast<unsigned int>(GetCurrentProcessId());
2288   return t1 ^ t2 ^ pid;
2289 #else
2290   union
2291   {
2292     unsigned int integer;
2293     char bytes[sizeof(unsigned int)];
2294   } seed;
2295
2296   // Try using a real random source.
2297   std::ifstream fin("/dev/urandom");
2298   if(fin && fin.read(seed.bytes, sizeof(seed)) &&
2299      fin.gcount() == sizeof(seed))
2300     {
2301     return seed.integer;
2302     }
2303
2304   // Fall back to the time and pid.
2305   struct timeval t;
2306   gettimeofday(&t, 0);
2307   unsigned int pid = static_cast<unsigned int>(getpid());
2308   unsigned int tv_sec = static_cast<unsigned int>(t.tv_sec);
2309   unsigned int tv_usec = static_cast<unsigned int>(t.tv_usec);
2310   // Since tv_usec never fills more than 11 bits we shift it to fill
2311   // in the slow-changing high-order bits of tv_sec.
2312   return tv_sec ^ (tv_usec << 21) ^ pid;
2313 #endif
2314 }
2315
2316 //----------------------------------------------------------------------------
2317 static std::string cmSystemToolsExecutableDirectory;
2318 void cmSystemTools::FindExecutableDirectory(const char* argv0)
2319 {
2320 #if defined(_WIN32) && !defined(__CYGWIN__)
2321   (void)argv0; // ignore this on windows
2322   char modulepath[_MAX_PATH];
2323   ::GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2324   cmSystemToolsExecutableDirectory =
2325     cmSystemTools::GetFilenamePath(modulepath);
2326   return;
2327 #else
2328   std::string errorMsg;
2329   std::string exe;
2330   if(cmSystemTools::FindProgramPath(argv0, exe, errorMsg))
2331     {
2332     // remove symlinks
2333     exe = cmSystemTools::GetRealPath(exe.c_str());
2334     cmSystemToolsExecutableDirectory =
2335       cmSystemTools::GetFilenamePath(exe.c_str());
2336     }
2337   else
2338     {
2339     // ???
2340     }
2341 #endif
2342 }
2343
2344 //----------------------------------------------------------------------------
2345 const char* cmSystemTools::GetExecutableDirectory()
2346 {
2347   return cmSystemToolsExecutableDirectory.c_str();
2348 }
2349
2350 //----------------------------------------------------------------------------
2351 #if defined(CMAKE_BUILD_WITH_CMAKE)
2352 void cmSystemTools::MakefileColorEcho(int color, const char* message,
2353                                       bool newline, bool enabled)
2354 {
2355   // On some platforms (an MSYS prompt) cmsysTerminal may not be able
2356   // to determine whether the stream is displayed on a tty.  In this
2357   // case it assumes no unless we tell it otherwise.  Since we want
2358   // color messages to be displayed for users we will assume yes.
2359   // However, we can test for some situations when the answer is most
2360   // likely no.
2361   int assumeTTY = cmsysTerminal_Color_AssumeTTY;
2362   if(cmSystemTools::GetEnv("DART_TEST_FROM_DART") ||
2363      cmSystemTools::GetEnv("DASHBOARD_TEST_FROM_CTEST") ||
2364      cmSystemTools::GetEnv("CTEST_INTERACTIVE_DEBUG_MODE"))
2365     {
2366     // Avoid printing color escapes during dashboard builds.
2367     assumeTTY = 0;
2368     }
2369
2370   if(enabled)
2371     {
2372     cmsysTerminal_cfprintf(color | assumeTTY, stdout, "%s%s",
2373                            message, newline? "\n" : "");
2374     }
2375   else
2376     {
2377     // Color is disabled.  Print without color.
2378     fprintf(stdout, "%s%s", message, newline? "\n" : "");
2379     }
2380 }
2381 #endif
2382
2383 //----------------------------------------------------------------------------
2384 bool cmSystemTools::GuessLibrarySOName(std::string const& fullPath,
2385                                        std::string& soname)
2386 {
2387   // For ELF shared libraries use a real parser to get the correct
2388   // soname.
2389 #if defined(CMAKE_USE_ELF_PARSER)
2390   cmELF elf(fullPath.c_str());
2391   if(elf)
2392     {
2393     return elf.GetSOName(soname);
2394     }
2395 #endif
2396
2397   // If the file is not a symlink we have no guess for its soname.
2398   if(!cmSystemTools::FileIsSymlink(fullPath.c_str()))
2399     {
2400     return false;
2401     }
2402   if(!cmSystemTools::ReadSymlink(fullPath.c_str(), soname))
2403     {
2404     return false;
2405     }
2406
2407   // If the symlink has a path component we have no guess for the soname.
2408   if(!cmSystemTools::GetFilenamePath(soname).empty())
2409     {
2410     return false;
2411     }
2412
2413   // If the symlink points at an extended version of the same name
2414   // assume it is the soname.
2415   std::string name = cmSystemTools::GetFilenameName(fullPath);
2416   if(soname.length() > name.length() &&
2417      soname.substr(0, name.length()) == name)
2418     {
2419     return true;
2420     }
2421   return false;
2422 }
2423
2424 //----------------------------------------------------------------------------
2425 #if defined(CMAKE_USE_ELF_PARSER)
2426 std::string::size_type cmSystemToolsFindRPath(std::string const& have,
2427                                               std::string const& want)
2428 {
2429   // Search for the desired rpath.
2430   std::string::size_type pos = have.find(want);
2431
2432   // If the path is not present we are done.
2433   if(pos == std::string::npos)
2434     {
2435     return pos;
2436     }
2437
2438   // Build a regex to match a properly separated path instance.
2439   std::string regex_str = "(^|:)(";
2440   for(std::string::const_iterator i = want.begin(); i != want.end(); ++i)
2441     {
2442     int ch = *i;
2443     if(!(('a' <= ch && ch <= 'z') ||
2444          ('A' <= ch && ch <= 'Z') ||
2445          ('0' <= ch && ch <= '9')))
2446       {
2447       // Escape the non-alphanumeric character.
2448       regex_str += "\\";
2449       }
2450     // Store the character.
2451     regex_str.append(1, static_cast<char>(ch));
2452     }
2453   regex_str += ")(:|$)";
2454
2455   // Look for the separated path.
2456   cmsys::RegularExpression regex(regex_str.c_str());
2457   if(regex.find(have))
2458     {
2459     // Return the position of the path portion.
2460     return regex.start(2);
2461     }
2462   else
2463     {
2464     // The desired rpath was not found.
2465     return std::string::npos;
2466     }
2467 }
2468 #endif
2469
2470 #if defined(CMAKE_USE_ELF_PARSER)
2471 struct cmSystemToolsRPathInfo
2472 {
2473   unsigned long Position;
2474   unsigned long Size;
2475   std::string Name;
2476   std::string Value;
2477 };
2478 #endif
2479
2480 //----------------------------------------------------------------------------
2481 bool cmSystemTools::ChangeRPath(std::string const& file,
2482                                 std::string const& oldRPath,
2483                                 std::string const& newRPath,
2484                                 std::string* emsg,
2485                                 bool* changed)
2486 {
2487 #if defined(CMAKE_USE_ELF_PARSER)
2488   if(changed)
2489     {
2490     *changed = false;
2491     }
2492   int rp_count = 0;
2493   cmSystemToolsRPathInfo rp[2];
2494   {
2495   // Parse the ELF binary.
2496   cmELF elf(file.c_str());
2497
2498   // Get the RPATH and RUNPATH entries from it.
2499   int se_count = 0;
2500   cmELF::StringEntry const* se[2] = {0, 0};
2501   const char* se_name[2] = {0, 0};
2502   if(cmELF::StringEntry const* se_rpath = elf.GetRPath())
2503     {
2504     se[se_count] = se_rpath;
2505     se_name[se_count] = "RPATH";
2506     ++se_count;
2507     }
2508   if(cmELF::StringEntry const* se_runpath = elf.GetRunPath())
2509     {
2510     se[se_count] = se_runpath;
2511     se_name[se_count] = "RUNPATH";
2512     ++se_count;
2513     }
2514   if(se_count == 0)
2515     {
2516     if(newRPath.empty())
2517       {
2518       // The new rpath is empty and there is no rpath anyway so it is
2519       // okay.
2520       return true;
2521       }
2522     else
2523       {
2524       if(emsg)
2525         {
2526         *emsg = "No valid ELF RPATH or RUNPATH entry exists in the file; ";
2527         *emsg += elf.GetErrorMessage();
2528         }
2529       return false;
2530       }
2531     }
2532
2533   for(int i=0; i < se_count; ++i)
2534     {
2535     // If both RPATH and RUNPATH refer to the same string literal it
2536     // needs to be changed only once.
2537     if(rp_count && rp[0].Position == se[i]->Position)
2538       {
2539       continue;
2540       }
2541
2542     // Make sure the current rpath contains the old rpath.
2543     std::string::size_type pos =
2544       cmSystemToolsFindRPath(se[i]->Value, oldRPath);
2545     if(pos == std::string::npos)
2546       {
2547       // If it contains the new rpath instead then it is okay.
2548       if(cmSystemToolsFindRPath(se[i]->Value, newRPath) != std::string::npos)
2549         {
2550         continue;
2551         }
2552       if(emsg)
2553         {
2554         cmOStringStream e;
2555         e << "The current " << se_name[i] << " is:\n"
2556           << "  " << se[i]->Value << "\n"
2557           << "which does not contain:\n"
2558           << "  " << oldRPath << "\n"
2559           << "as was expected.";
2560         *emsg = e.str();
2561         }
2562       return false;
2563       }
2564
2565     // Store information about the entry in the file.
2566     rp[rp_count].Position = se[i]->Position;
2567     rp[rp_count].Size = se[i]->Size;
2568     rp[rp_count].Name = se_name[i];
2569
2570     // Construct the new value which preserves the part of the path
2571     // not being changed.
2572     rp[rp_count].Value = se[i]->Value.substr(0, pos);
2573     rp[rp_count].Value += newRPath;
2574     rp[rp_count].Value += se[i]->Value.substr(pos+oldRPath.length(),
2575                                               oldRPath.npos);
2576
2577     // Make sure there is enough room to store the new rpath and at
2578     // least one null terminator.
2579     if(rp[rp_count].Size < rp[rp_count].Value.length()+1)
2580       {
2581       if(emsg)
2582         {
2583         *emsg = "The replacement path is too long for the ";
2584         *emsg += se_name[i];
2585         *emsg += " entry.";
2586         }
2587       return false;
2588       }
2589
2590     // This entry is ready for update.
2591     ++rp_count;
2592     }
2593   }
2594
2595   // If no runtime path needs to be changed, we are done.
2596   if(rp_count == 0)
2597     {
2598     return true;
2599     }
2600
2601   {
2602   // Open the file for update.
2603   std::ofstream f(file.c_str(),
2604                   std::ios::in | std::ios::out | std::ios::binary);
2605   if(!f)
2606     {
2607     if(emsg)
2608       {
2609       *emsg = "Error opening file for update.";
2610       }
2611     return false;
2612     }
2613
2614   // Store the new RPATH and RUNPATH strings.
2615   for(int i=0; i < rp_count; ++i)
2616     {
2617     // Seek to the RPATH position.
2618     if(!f.seekp(rp[i].Position))
2619       {
2620       if(emsg)
2621         {
2622         *emsg = "Error seeking to ";
2623         *emsg += rp[i].Name;
2624         *emsg += " position.";
2625         }
2626       return false;
2627       }
2628
2629     // Write the new rpath.  Follow it with enough null terminators to
2630     // fill the string table entry.
2631     f << rp[i].Value;
2632     for(unsigned long j=rp[i].Value.length(); j < rp[i].Size; ++j)
2633       {
2634       f << '\0';
2635       }
2636
2637     // Make sure it wrote correctly.
2638     if(!f)
2639       {
2640       if(emsg)
2641         {
2642         *emsg = "Error writing the new ";
2643         *emsg += rp[i].Name;
2644         *emsg += " string to the file.";
2645         }
2646       return false;
2647       }
2648     }
2649   }
2650
2651   // Everything was updated successfully.
2652   if(changed)
2653     {
2654     *changed = true;
2655     }
2656   return true;
2657 #else
2658   (void)file;
2659   (void)oldRPath;
2660   (void)newRPath;
2661   (void)emsg;
2662   (void)changed;
2663   return false;
2664 #endif
2665 }
2666
2667 //----------------------------------------------------------------------------
2668 bool cmSystemTools::VersionCompare(cmSystemTools::CompareOp op,
2669                                    const char* lhss, const char* rhss)
2670 {
2671   unsigned int lhs[4] = {0,0,0,0};
2672   unsigned int rhs[4] = {0,0,0,0};
2673   sscanf(lhss, "%u.%u.%u.%u", &lhs[0], &lhs[1], &lhs[2], &lhs[3]);
2674   sscanf(rhss, "%u.%u.%u.%u", &rhs[0], &rhs[1], &rhs[2], &rhs[3]);
2675
2676   // Do component-wise comparison.
2677   for(unsigned int i=0; i < 4; ++i)
2678     {
2679     if(lhs[i] < rhs[i])
2680       {
2681       // lhs < rhs, so true if operation is LESS
2682       return op == cmSystemTools::OP_LESS;
2683       }
2684     else if(lhs[i] > rhs[i])
2685       {
2686       // lhs > rhs, so true if operation is GREATER
2687       return op == cmSystemTools::OP_GREATER;
2688       }
2689     }
2690   // lhs == rhs, so true if operation is EQUAL
2691   return op == cmSystemTools::OP_EQUAL;
2692 }
2693
2694 //----------------------------------------------------------------------------
2695 bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
2696                                 bool* removed)
2697 {
2698 #if defined(CMAKE_USE_ELF_PARSER)
2699   if(removed)
2700     {
2701     *removed = false;
2702     }
2703   int zeroCount = 0;
2704   unsigned long zeroPosition[2] = {0,0};
2705   unsigned long zeroSize[2] = {0,0};
2706   unsigned long bytesBegin = 0;
2707   std::vector<char> bytes;
2708   {
2709   // Parse the ELF binary.
2710   cmELF elf(file.c_str());
2711
2712   // Get the RPATH and RUNPATH entries from it and sort them by index
2713   // in the dynamic section header.
2714   int se_count = 0;
2715   cmELF::StringEntry const* se[2] = {0, 0};
2716   if(cmELF::StringEntry const* se_rpath = elf.GetRPath())
2717     {
2718     se[se_count++] = se_rpath;
2719     }
2720   if(cmELF::StringEntry const* se_runpath = elf.GetRunPath())
2721     {
2722     se[se_count++] = se_runpath;
2723     }
2724   if(se_count == 0)
2725     {
2726     // There is no RPATH or RUNPATH anyway.
2727     return true;
2728     }
2729   if(se_count == 2 && se[1]->IndexInSection < se[0]->IndexInSection)
2730     {
2731     cmsys_stl::swap(se[0], se[1]);
2732     }
2733
2734   // Get the size of the dynamic section header.
2735   unsigned int count = elf.GetDynamicEntryCount();
2736   if(count == 0)
2737     {
2738     // This should happen only for invalid ELF files where a DT_NULL
2739     // appears before the end of the table.
2740     if(emsg)
2741       {
2742       *emsg = "DYNAMIC section contains a DT_NULL before the end.";
2743       }
2744     return false;
2745     }
2746
2747   // Save information about the string entries to be zeroed.
2748   zeroCount = se_count;
2749   for(int i=0; i < se_count; ++i)
2750     {
2751     zeroPosition[i] = se[i]->Position;
2752     zeroSize[i] = se[i]->Size;
2753     }
2754
2755   // Get the range of file positions corresponding to each entry and
2756   // the rest of the table after them.
2757   unsigned long entryBegin[3] = {0,0,0};
2758   unsigned long entryEnd[2] = {0,0};
2759   for(int i=0; i < se_count; ++i)
2760     {
2761     entryBegin[i] = elf.GetDynamicEntryPosition(se[i]->IndexInSection);
2762     entryEnd[i] = elf.GetDynamicEntryPosition(se[i]->IndexInSection+1);
2763     }
2764   entryBegin[se_count] = elf.GetDynamicEntryPosition(count);
2765
2766   // The data are to be written over the old table entries starting at
2767   // the first one being removed.
2768   bytesBegin = entryBegin[0];
2769   unsigned long bytesEnd = entryBegin[se_count];
2770
2771   // Allocate a buffer to hold the part of the file to be written.
2772   // Initialize it with zeros.
2773   bytes.resize(bytesEnd - bytesBegin, 0);
2774
2775   // Read the part of the DYNAMIC section header that will move.
2776   // The remainder of the buffer will be left with zeros which
2777   // represent a DT_NULL entry.
2778   char* data = &bytes[0];
2779   for(int i=0; i < se_count; ++i)
2780     {
2781     // Read data between the entries being removed.
2782     unsigned long sz = entryBegin[i+1] - entryEnd[i];
2783     if(sz > 0 && !elf.ReadBytes(entryEnd[i], sz, data))
2784       {
2785       if(emsg)
2786         {
2787         *emsg = "Failed to read DYNAMIC section header.";
2788         }
2789       return false;
2790       }
2791     data += sz;
2792     }
2793   }
2794
2795   // Open the file for update.
2796   std::ofstream f(file.c_str(),
2797                   std::ios::in | std::ios::out | std::ios::binary);
2798   if(!f)
2799     {
2800     if(emsg)
2801       {
2802       *emsg = "Error opening file for update.";
2803       }
2804     return false;
2805     }
2806
2807   // Write the new DYNAMIC table header.
2808   if(!f.seekp(bytesBegin))
2809     {
2810     if(emsg)
2811       {
2812       *emsg = "Error seeking to DYNAMIC table header for RPATH.";
2813       }
2814     return false;
2815     }
2816   if(!f.write(&bytes[0], bytes.size()))
2817     {
2818     if(emsg)
2819       {
2820       *emsg = "Error replacing DYNAMIC table header.";
2821       }
2822     return false;
2823     }
2824
2825   // Fill the RPATH and RUNPATH strings with zero bytes.
2826   for(int i=0; i < zeroCount; ++i)
2827     {
2828     if(!f.seekp(zeroPosition[i]))
2829       {
2830       if(emsg)
2831         {
2832         *emsg = "Error seeking to RPATH position.";
2833         }
2834       return false;
2835       }
2836     for(unsigned long j=0; j < zeroSize[i]; ++j)
2837       {
2838       f << '\0';
2839       }
2840     if(!f)
2841       {
2842       if(emsg)
2843         {
2844         *emsg = "Error writing the empty rpath string to the file.";
2845         }
2846       return false;
2847       }
2848     }
2849
2850   // Everything was updated successfully.
2851   if(removed)
2852     {
2853     *removed = true;
2854     }
2855   return true;
2856 #else
2857   (void)file;
2858   (void)emsg;
2859   (void)removed;
2860   return false;
2861 #endif
2862 }
2863
2864 //----------------------------------------------------------------------------
2865 bool cmSystemTools::CheckRPath(std::string const& file,
2866                                std::string const& newRPath)
2867 {
2868 #if defined(CMAKE_USE_ELF_PARSER)
2869   // Parse the ELF binary.
2870   cmELF elf(file.c_str());
2871
2872   // Get the RPATH or RUNPATH entry from it.
2873   cmELF::StringEntry const* se = elf.GetRPath();
2874   if(!se)
2875     {
2876     se = elf.GetRunPath();
2877     }
2878
2879   // Make sure the current rpath contains the new rpath.
2880   if(newRPath.empty())
2881     {
2882     if(!se)
2883       {
2884       return true;
2885       }
2886     }
2887   else
2888     {
2889     if(se &&
2890        cmSystemToolsFindRPath(se->Value, newRPath) != std::string::npos)
2891       {
2892       return true;
2893       }
2894     }
2895   return false;
2896 #else
2897   (void)file;
2898   (void)newRPath;
2899   return false;
2900 #endif
2901 }
2902
2903 //----------------------------------------------------------------------------
2904 bool cmSystemTools::RepeatedRemoveDirectory(const char* dir)
2905 {
2906   // Windows sometimes locks files temporarily so try a few times.
2907   for(int i = 0; i < 10; ++i)
2908     {
2909     if(cmSystemTools::RemoveADirectory(dir))
2910       {
2911       return true;
2912       }
2913     cmSystemTools::Delay(100);
2914     }
2915   return false;
2916 }
2917
2918 //----------------------------------------------------------------------------
2919 std::vector<std::string> cmSystemTools::tokenize(const std::string& str,
2920                                   const std::string& sep)
2921 {
2922   std::vector<std::string> tokens;
2923   std::string::size_type tokend = 0;
2924
2925   do
2926     {
2927     std::string::size_type tokstart=str.find_first_not_of(sep, tokend);
2928     if (tokstart==std::string::npos)
2929       {
2930       break;    // no more tokens
2931       }
2932     tokend=str.find_first_of(sep,tokstart);
2933     if (tokend==std::string::npos)
2934       {
2935       tokens.push_back(str.substr(tokstart));
2936       }
2937     else
2938       {
2939       tokens.push_back(str.substr(tokstart,tokend-tokstart));
2940       }
2941     } while (tokend!=std::string::npos);
2942
2943   if (tokens.empty())
2944     {
2945     tokens.push_back("");
2946     }
2947   return tokens;
2948 }