Updates will be applied on October 27th between 12pm - 12:45pm EDT (UTC-0400). Gitlab may be slow during the maintenance window.

SystemTools.hxx.in 21.4 KB
Newer Older
1
2
3
4
5
/*=========================================================================

  Program:   KWSys - Kitware System Library
  Module:    $RCSfile$

Brad King's avatar
Brad King committed
6
7
  Copyright (c) Kitware, Inc., Insight Consortium.  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
8

Brad King's avatar
Brad King committed
9
10
     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11
12
13
14
15
16
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#ifndef @KWSYS_NAMESPACE@_SystemTools_hxx
#define @KWSYS_NAMESPACE@_SystemTools_hxx

17
18
19
#include <@KWSYS_NAMESPACE@/ios/iosfwd>
#include <@KWSYS_NAMESPACE@/stl/string>
#include <@KWSYS_NAMESPACE@/stl/vector>
20
#include <@KWSYS_NAMESPACE@/stl/map>
21

Brad King's avatar
Brad King committed
22
23
#include <@KWSYS_NAMESPACE@/Configure.h>

24
#include <sys/types.h>
25
#include <stdarg.h>
26

Andy Cedilnik's avatar
Andy Cedilnik committed
27
28
29
30
#if defined( _MSC_VER )
typedef unsigned short mode_t;
#endif

31
32
33
34
/* Define these macros temporarily to keep the code readable.  */
#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
# define kwsys_stl @KWSYS_NAMESPACE@_stl
# define kwsys_ios @KWSYS_NAMESPACE@_ios
35
36
#endif

37
38
39
namespace @KWSYS_NAMESPACE@
{

40
class SystemToolsTranslationMap;
41
42
43
44
45
46
47
48
49
50
51
class @KWSYS_NAMESPACE@_EXPORT SystemToolsManager
{
public:
  SystemToolsManager();
  ~SystemToolsManager();
};

// This instance will show up in any translation unit that uses
// SystemTools. It will make sure SystemTools is initialized 
// before it is used and is the last static object destroyed.
static SystemToolsManager SystemToolsManagerInstance;
52

53
54
55
/** \class SystemTools
 * \brief A collection of useful platform-independent system functions.
 */
Brad King's avatar
Brad King committed
56
class @KWSYS_NAMESPACE@_EXPORT SystemTools
57
58
{
public:
59
60
61
62
63
64

  /** -----------------------------------------------------------------
   *               String Manipulation Routines
   *  -----------------------------------------------------------------
   */

65
66
67
68
69
70
71
  /**
   * Replace symbols in str that are not valid in C identifiers as
   * defined by the 1999 standard, ie. anything except [A-Za-z0-9_].
   * They are replaced with `_' and if the first character is a digit
   * then an underscore is prepended.  Note that this can produce
   * identifiers that the standard reserves (_[A-Z].* and __.*).
   */
72
  static kwsys_stl::string MakeCindentifier(const char* s);
73
74
  
  /**
75
   * Replace replace all occurences of the string in the source string.
76
   */
77
  static void ReplaceString(kwsys_stl::string& source,
78
79
80
81
82
83
84
                            const char* replace,
                            const char* with);

  /**
   * Return a capitalized string (i.e the first letter is uppercased,
   * all other are lowercased).
   */
85
  static kwsys_stl::string Capitalized(const kwsys_stl::string&);
86
  
87
  /**
88
89
   * Return a 'capitalized words' string (i.e the first letter of each word
   * is uppercased all other are left untouched though).
90
91
92
93
   */
  static kwsys_stl::string CapitalizedWords(const kwsys_stl::string&);
  
  /**
94
95
   * Return a 'uncapitalized words' string (i.e the first letter of each word
   * is lowercased all other are left untouched though).
96
97
98
   */
  static kwsys_stl::string UnCapitalizedWords(const kwsys_stl::string&);
  
99
100
101
  /**
   * Return a lower case string
   */
102
  static kwsys_stl::string LowerCase(const kwsys_stl::string&);
103
104
105
106
  
  /**
   * Return a lower case string
   */
107
  static kwsys_stl::string UpperCase(const kwsys_stl::string&);
108
  
109
110
111
112
113
114
115
116
117
118
119
120
  /**
   * Count char in string
   */
  static size_t CountChar(const char* str, char c);
  
  /**
   * Remove some characters from a string.
   * Return a pointer to the new resulting string (allocated with 'new')
   */
  static char* RemoveChars(const char* str, const char *toremove);

  /**
121
   * Remove remove all but 0->9, A->F characters from a string.
122
123
124
125
126
127
128
129
130
131
   * Return a pointer to the new resulting string (allocated with 'new')
   */
  static char* RemoveCharsButUpperHex(const char* str);
  
  /**
   * Replace some characters by another character in a string (in-place)
   * Return a pointer to string
   */
  static char* ReplaceChars(char* str, const char *toreplace,char replacement);
  
132
  /**
133
   * Returns true if str1 starts (respectively ends) with str2
134
135
136
137
   */
  static bool StringStartsWith(const char* str1, const char* str2);
  static bool StringEndsWith(const char* str1, const char* str2);

138
139
140
141
142
143
144
145
146
147
148
149
  /**
   * Returns a pointer to the last occurence of str2 in str1
   */
  static const char* FindLastString(const char* str1, const char* str2);
  
  /**
   * Make a duplicate of the string similar to the strdup C function
   * but use new to create the 'new' string, so one can use
   * 'delete' to remove it. Returns 0 if the input is empty.
   */
  static char* DuplicateString(const char* str);
  
150
151
152
153
  /**
   * Return the string cropped to a given length by removing chars in the
   * center of the string and replacing them with an ellipsis (...)
   */
154
  static kwsys_stl::string CropString(const kwsys_stl::string&,size_t max_len);
155
  
156
  /**
157
   * Perform a case-independent string comparison
158
159
160
   */
  static int Strucmp(const char *s1, const char *s2);

161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
  /** 
   * Convert a string in __DATE__ or __TIMESTAMP__ format into a time_t.
   * Return false on error, true on success
   */
  static bool ConvertDateMacroString(const char *str, time_t *tmt);
  static bool ConvertTimeStampMacroString(const char *str, time_t *tmt);

  /**
   * Split a string on its newlines into multiple lines
   * Return false only if the last line stored had no newline
   */
  static bool Split(const char* s, kwsys_stl::vector<kwsys_stl::string>& l);
  
  /** 
   * Return string with space added between capitalized words
   * (i.e. EatMyShorts becomes Eat My Shorts 
   */
  static kwsys_stl::string AddSpaceBetweenCapitalizedWords(
    const kwsys_stl::string&);

181
182
183
184
185
186
187
188
189
190
191
  /** 
   * Append two or more strings and produce new one.
   * Programmer must 'delete []' the resulting string, which was allocated 
   * with 'new'. 
   * Return 0 if inputs are empty or there was an error
   */
  static char* AppendStrings(
    const char* str1, const char* str2);
  static char* AppendStrings(
    const char* str1, const char* str2, const char* str3);

192
193
194
195
196
197
198
199
200
201
202
  /** 
   * Estimate the length of the string that will be produced
   * from printing the given format string and arguments.  The
   * returned length will always be at least as large as the string
   * that will result from printing.
   * WARNING: since va_arg is called to iterate of the argument list,
   * you will not be able to use this 'ap' anymore from the beginning.
   * It's up to you to call va_end though.
   */
  static int EstimateFormatLength(const char *format, va_list ap);

203
204
205
206
207
  /** -----------------------------------------------------------------
   *               Filename Manipulation Routines
   *  -----------------------------------------------------------------
   */

208
209
210
  /**
   * Replace Windows file system slashes with Unix-style slashes.
   */
211
  static void ConvertToUnixSlashes(kwsys_stl::string& path);
212
213
  
  /**
214
   * For windows this calls ConvertToWindowsOutputPath and for unix
215
216
   * it calls ConvertToUnixOutputPath
   */
217
  static kwsys_stl::string ConvertToOutputPath(const char*);
218
  
219
220
221
  /**
   * Return true if a file exists in the current directory
   */
222
223
  static bool FileExists(const char* filename);
  
224
225
226
  /**
   * Return file length
   */
227
  static unsigned long FileLength(const char *filename);
228

229
  /**
230
231
232
233
   *  Compare file modification times.
   *  Return true for successful comparison and false for error.
   *  When true is returned, result has -1, 0, +1 for
   *  f1 older, same, or newer than f2.  
234
   */
235
236
  static bool FileTimeCompare(const char* f1, const char* f2,
                              int* result);
Brad King's avatar
Brad King committed
237

238
239
240
241
242
243
244
245
246
247
248
  /**
   *  Get the file extension (including ".") needed for an executable
   *  on the current platform ("" for unix, ".exe" for Windows).
   */
  static const char* GetExecutableExtension();

  /**
   * 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.
   */
249
  static kwsys_stl::string GetProgramPath(const char*);
250
  static bool SplitProgramPath(const char* in_name, 
251
252
                               kwsys_stl::string& dir, 
                               kwsys_stl::string& file,
253
254
                               bool errorReport = true);
  
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
  /** 
   *  Given argv[0] for a unix program find the full path to a running
   *  executable.  argv0 can be null for windows WinMain programs
   *  in this case GetModuleFileName will be used to find the path
   *  to the running executable.  If argv0 is not a full path,
   *  then this will try to find the full path.  If the path is not
   *  found false is returned, if found true is returned.  An error
   *  message of the attempted paths is stored in errorMsg.  
   *  exeName is the name of the executable.
   *  buildDir is a possibly null path to the build directory.
   *  installPrefix is a possibly null pointer to the install directory.
   */
  static bool FindProgramPath(const char* argv0, 
                              kwsys_stl::string& pathOut,
                              kwsys_stl::string& errorMsg,
                              const char* exeName = 0,
                              const char* buildDir = 0,         
                              const char* installPrefix = 0);
  
274
275
276
277
278
279
  /**
   * Given a path to a file or directory, convert it to a full path.
   * This collapses away relative paths relative to the cwd argument
   * (which defaults to the current working directory).  The full path
   * is returned.
   */
280
281
  static kwsys_stl::string CollapseFullPath(const char* in_relative);
  static kwsys_stl::string CollapseFullPath(const char* in_relative,
282
                                            const char* in_base);
283
284
285
286
287
288
289
290
291
292
293
294

  /**
   * Split a path name into its basic components.  The first component
   * is one of the following roots:
   *    "/"   = UNIX
   *    "c:/" = Windows full path (can be any drive letter)
   *    "c:"  = Windows drive-letter relative path (can be any drive letter)
   *    "//"  = Network path
   *    ""    = Relative path
   * The remaining components form the path.  If there is a trailing
   * slash then the last component is the empty string.  The
   * components can be recombined as "c[0]c[1]/c[2]/.../c[n]" to
295
   * produce the original path.
296
297
298
   */
  static void SplitPath(const char* p,
                        kwsys_stl::vector<kwsys_stl::string>& components);
299
300
301
302
303

  /**
   * Join components of a path name into a single string.  See
   * SplitPath for the format of the components.
   */
304
305
  static kwsys_stl::string JoinPath(
    const kwsys_stl::vector<kwsys_stl::string>& components);
306

Brad King's avatar
Brad King committed
307
308
309
310
311
  /**
   * Compare a path or components of a path.
   */
  static bool ComparePath(const char* c1, const char* c2);

312
313
314
315

  /**
   * Return path of a full filename (no trailing slashes)
   */
316
  static kwsys_stl::string GetFilenamePath(const kwsys_stl::string&);
317

318
319
320
  /**
   * Return file name of a full filename (i.e. file name without path)
   */
321
  static kwsys_stl::string GetFilenameName(const kwsys_stl::string&);
322
  
323
324
325
326
327
328
  /**
   * Split a program from its arguments and handle spaces in the paths
   */
  static void SplitProgramFromArgs(
    const char* path, 
    kwsys_stl::string& program, kwsys_stl::string& args);
329
  
330
331
332
  /**
   * Return longest file extension of a full filename (dot included)
   */
333
  static kwsys_stl::string GetFilenameExtension(const kwsys_stl::string&);
334
  
335
336
337
338
339
  /**
   * Return shortest file extension of a full filename (dot included)
   */
  static kwsys_stl::string GetFilenameLastExtension(
    const kwsys_stl::string& filename);
340
  
341
342
343
344
345
  /**
   * Return file name without extension of a full filename
   */
  static kwsys_stl::string GetFilenameWithoutExtension(
    const kwsys_stl::string&);
346
  
347
348
349
350
351
  /**
   * Return file name without its last (shortest) extension
   */
  static kwsys_stl::string GetFilenameWithoutLastExtension(
    const kwsys_stl::string&);
352
  
353
354
355
  /**
   * Return whether the path represents a full path (not relative)
   */
356
357
  static bool FileIsFullPath(const char*);
  
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
  /**
   * For windows return the short path for the given path,
   * Unix just a pass through
   */
  static bool GetShortPath(const char* path, kwsys_stl::string& result);
  
  /**
   * Read line from file. Make sure to get everything. Due to a buggy stream
   * library on the HP and another on Mac OSX, we need this very carefully
   * written version of getline. Returns true if any data were read before the
   * end-of-file was reached. If the has_newline argument is specified, it will
   * be true when the line read had a newline character.
   */
  static bool GetLineFromStream(kwsys_ios::istream& istr, 
                                kwsys_stl::string& line,
                                bool* has_newline=0);
374

375
376
377
378
  /**
   * Get the parent directory of the directory or file
   */
  static kwsys_stl::string GetParentDirectory(const char* fileOrDir);
379

380
381
  /**
   * Check if the given file or directory is in subdirectory of dir
382
   */
383
  static bool IsSubDirectory(const char* fileOrDir, const char* dir);
384

385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
  /** -----------------------------------------------------------------
   *               File Manipulation Routines
   *  -----------------------------------------------------------------
   */

  /**
   * Make a new directory if it is not there.  This function
   * can make a full path even if none of the directories existed
   * prior to calling this function.  
   */
  static bool MakeDirectory(const char* path);

  /**
   * Copy the source file to the destination file only
   * if the two files differ.  
   */
  static bool CopyFileIfDifferent(const char* source,
                                  const char* destination);
403
  
404
405
406
407
408
409
410
411
412
  /**
   * Compare the contents of two files.  Return true if different
   */
  static bool FilesDiffer(const char* source, const char* destination);
  
  /**
   * Return true if the two files are the same file
   */
  static bool SameFile(const char* file1, const char* file2);
413

414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
  /**
   * Copy a file
   */
  static bool CopyFileAlways(const char* source, const char* destination);

  /**
   * Copy content directory to another directory with all files and 
   * subdirectories
   */
  static bool CopyADirectory(const char* source, const char* destination);
  
  /**
   * Remove a file
   */
  static bool RemoveFile(const char* source);
  
  /**
   * Remove a directory
   */
  static bool RemoveADirectory(const char* source);

  /**
   * Find a file in the system PATH, with optional extra paths
   */
  static kwsys_stl::string FindFile(
    const char* name,
    const kwsys_stl::vector<kwsys_stl::string>& path = 
    kwsys_stl::vector<kwsys_stl::string>());

  /**
   * Find an executable in the system PATH, with optional extra paths
   */
  static kwsys_stl::string FindProgram(
    const char* name,
    const kwsys_stl::vector<kwsys_stl::string>& path = 
    kwsys_stl::vector<kwsys_stl::string>(),
    bool no_system_path = false);

  /**
   * Find a library in the system PATH, with optional extra paths
   */
  static kwsys_stl::string FindLibrary(
    const char* name,
    const kwsys_stl::vector<kwsys_stl::string>& path);
458
  
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
  /**
   * Return true if the file is a directory
   */
  static bool FileIsDirectory(const char* name);
  
  /**
   * return true if the file has a given signature (first set of bytes)
   */
  static bool FileHasSignature(
    const char* filename, const char *signature, long offset = 0);

  /**
   * Try to locate the file 'filename' in the directory 'dir'.
   * If 'filename' is a fully qualified filename, the basename of the file is
   * used to check for its existence in 'dir'.
   * If 'dir' is not a directory, GetFilenamePath() is called on 'dir' to
   * get its directory first (thus, you can pass a filename as 'dir', as
   * a convenience).
   * 'filename_found' is assigned the fully qualified name/path of the file
   * if it is found (not touched otherwise).
   * If 'try_filename_dirs' is true, try to find the file using the
   * components of its path, i.e. if we are looking for c:/foo/bar/bill.txt, 
   * first look for bill.txt in 'dir', then in 'dir'/bar, then in 'dir'/foo/bar
   * etc.
   * Return true if the file was found, false otherwise.
   */
  static bool LocateFileInDir(const char *filename, 
                              const char *dir, 
                              kwsys_stl::string& filename_found,
                              int try_filename_dirs = 0);
  
  /** 
   * Check if the given file exists in one of the parent directory of the
   * given file or directory and if it does, return the name of the file.
   * Toplevel specifies the top-most directory to where it will look.
   */
  static kwsys_stl::string FileExistsInParentDirectories(const char* fname,
    const char* directory, const char* toplevel);

  /**
   * Return file's modified time
   */
  static long int ModifiedTime(const char* filename);

  /**
   * Return file's creation time (Win32: works only for NTFS, not FAT)
   */
  static long int CreationTime(const char* filename);

  /**
   * Get and set permissions of the file.
   */
  static bool GetPermissions(const char* file, mode_t& mode);
  static bool SetPermissions(const char* file, mode_t mode);

  /** -----------------------------------------------------------------
   *               Time Manipulation Routines
   *  -----------------------------------------------------------------
   */

  /**
   * Get current time as a double. On certain platforms this will
   * return higher resolution than seconds:
   * (1) gettimeofday() -- resolution in microseconds
   * (2) ftime() -- resolution in milliseconds
   * (3) time() -- resolution in seconds
   */
  static double GetTime();

  /**
   * Get current date/time
   */
531
  static kwsys_stl::string GetCurrentDateTime(const char* format);
532

533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
  /** -----------------------------------------------------------------
   *               Registry Manipulation Routines
   *  -----------------------------------------------------------------
   */

  /**
   * Read a registry value
   */
  static bool ReadRegistryValue(const char *key, kwsys_stl::string &value);

  /**
   * Write a registry value
   */
  static bool WriteRegistryValue(const char *key, const char *value);

  /**
   * Delete a registry value
   */
  static bool DeleteRegistryValue(const char *key);

  /** -----------------------------------------------------------------
   *               Environment Manipulation Routines
   *  -----------------------------------------------------------------
   */

  /**
   *  Add the paths from the environment variable PATH to the 
   *  string vector passed in.  If env is set then the value
   *  of env will be used instead of PATH.
   */
  static void GetPath(kwsys_stl::vector<kwsys_stl::string>& path, 
                      const char* env=0);

  /**
   * Read an environment variable
   */
  static const char* GetEnv(const char* key);
  static bool GetEnv(const char* key, kwsys_stl::string& result);

  /**
   * Get current working directory CWD
   */
  static kwsys_stl::string GetCurrentWorkingDirectory();

  /**
   * Change directory the the directory specified
   */
  static int ChangeDirectory(const char* dir);

  /**
   * Get the result of strerror(errno)
   */
585
  static kwsys_stl::string GetLastSystemError();
586
  
587
588
  /** 
   * When building DEBUG with MSVC, this enables a hook that prevents
589
590
591
592
593
   * error dialogs from popping up if the program is being run from
   * DART.
   */
  static void EnableMSVCDebugHook();

594
595
596
597
598
599
  /**
   * Get the width of the terminal window. The code may or may not work, so
   * make sure you have some resonable defaults prepared if the code returns
   * some bogus size.
   */
  static int GetTerminalWidth();
600
  
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
  /**
   * Add an entry in the path translation table.
   */
  static void AddTranslationPath(const char * dir, const char * refdir);

  /**
   * If dir is different after CollapseFullPath is called,
   * Then insert it into the path translation table
   */
  static void AddKeepPath(const char* dir);

  /**
   * Update path by going through the Path Translation table;
   */
  static void CheckTranslationPath(kwsys_stl::string & path);

617
618
619
  /** 
   * Delay the execution for a specified amount of time specified 
   * in miliseconds 
620
   */
Andy Cedilnik's avatar
Andy Cedilnik committed
621
622
  static void Delay(unsigned int msec);

623
624
625
626
627
628
protected:
  // these two functions can be called from ConvertToOutputPath
  /**
   * Convert the path to a string that can be used in a unix makefile.
   * double slashes are removed, and spaces are escaped.
   */
629
  static kwsys_stl::string ConvertToUnixOutputPath(const char*);
630
631
632
633
634
635
636
  
  /**
   * Convert the path to string that can be used in a windows project or
   * makefile.   Double slashes are removed if they are not at the start of
   * the string, the slashes are converted to windows style backslashes, and
   * if there are spaces in the string it is double quoted.
   */
637
  static kwsys_stl::string ConvertToWindowsOutputPath(const char*);
638

639
private:
640
641
642
643
644
645
646
647
648
649
  /**
   * Allocate the std::map that serve as the Path Translation table.
   */
  static void ClassInitialize();

  /**
   * Deallocate the std::map that serve as the Path Translation table.
   */
  static void ClassFinalize();

650
651
652
653
654
655
656
657
  /**
   * This method prevents warning on SGI
   */
  SystemToolsManager* GetSystemToolsManager()
    {
    return &SystemToolsManagerInstance;
    }

658
659
660
661
  /**
   * Path translation table from dir to refdir
   * Each time 'dir' will be found it will be replace by 'refdir'
   */
662
663
664
665
666
  static SystemToolsTranslationMap *TranslationMap;
  
  friend class SystemToolsManager;
};

667
668
} // namespace @KWSYS_NAMESPACE@

669
670
671
672
/* Undefine temporary macros.  */
#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
# undef kwsys_stl
# undef kwsys_ios
673
674
#endif

675
#endif