SystemTools.cxx 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797
  1. /*=========================================================================
  2. Program: KWSys - Kitware System Library
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
  8. See http://www.cmake.org/HTML/Copyright.html for details.
  9. This software is distributed WITHOUT ANY WARRANTY; without even
  10. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  11. PURPOSE. See the above copyright notices for more information.
  12. =========================================================================*/
  13. #ifdef _MSC_VER
  14. # pragma warning (disable: 4786)
  15. #endif
  16. #include <SystemTools.hxx>
  17. #include <RegularExpression.hxx>
  18. #include <Directory.hxx>
  19. #include <fstream>
  20. #include <stdio.h>
  21. #include <sys/stat.h>
  22. #include <ctype.h>
  23. #include <errno.h>
  24. #include <time.h>
  25. // support for realpath call
  26. #ifndef _WIN32
  27. #include <limits.h>
  28. #include <stdlib.h>
  29. #include <sys/param.h>
  30. #include <sys/wait.h>
  31. #endif
  32. #if defined(_WIN32) && (defined(_MSC_VER) || defined(__BORLANDC__))
  33. #include <string.h>
  34. #include <windows.h>
  35. #include <direct.h>
  36. #define _unlink unlink
  37. inline int Mkdir(const char* dir)
  38. {
  39. return _mkdir(dir);
  40. }
  41. inline const char* Getcwd(char* buf, unsigned int len)
  42. {
  43. return _getcwd(buf, len);
  44. }
  45. inline int Chdir(const char* dir)
  46. {
  47. #if defined(__BORLANDC__)
  48. return chdir(dir);
  49. #else
  50. return _chdir(dir);
  51. #endif
  52. }
  53. #else
  54. #include <sys/types.h>
  55. #include <fcntl.h>
  56. #include <unistd.h>
  57. inline int Mkdir(const char* dir)
  58. {
  59. return mkdir(dir, 00777);
  60. }
  61. inline const char* Getcwd(char* buf, unsigned int len)
  62. {
  63. return getcwd(buf, len);
  64. }
  65. inline int Chdir(const char* dir)
  66. {
  67. return chdir(dir);
  68. }
  69. #endif
  70. /* Implement floattime() for various platforms */
  71. // Taken from Python 2.1.3
  72. #if defined( _WIN32 ) && !defined( __CYGWIN__ )
  73. # include <sys/timeb.h>
  74. # define HAVE_FTIME
  75. # if defined( __BORLANDC__)
  76. # define FTIME ftime
  77. # define TIMEB timeb
  78. # else // Visual studio?
  79. # define FTIME _ftime
  80. # define TIMEB _timeb
  81. # endif
  82. #elif defined( __CYGWIN__ ) || defined( __linux__ )
  83. # include <sys/time.h>
  84. # include <time.h>
  85. # define HAVE_GETTIMEOFDAY
  86. #endif
  87. namespace KWSYS_NAMESPACE
  88. {
  89. double
  90. SystemTools::GetTime(void)
  91. {
  92. /* There are three ways to get the time:
  93. (1) gettimeofday() -- resolution in microseconds
  94. (2) ftime() -- resolution in milliseconds
  95. (3) time() -- resolution in seconds
  96. In all cases the return value is a float in seconds.
  97. Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may
  98. fail, so we fall back on ftime() or time().
  99. Note: clock resolution does not imply clock accuracy! */
  100. #ifdef HAVE_GETTIMEOFDAY
  101. {
  102. struct timeval t;
  103. #ifdef GETTIMEOFDAY_NO_TZ
  104. if (gettimeofday(&t) == 0)
  105. return (double)t.tv_sec + t.tv_usec*0.000001;
  106. #else /* !GETTIMEOFDAY_NO_TZ */
  107. if (gettimeofday(&t, (struct timezone *)NULL) == 0)
  108. return (double)t.tv_sec + t.tv_usec*0.000001;
  109. #endif /* !GETTIMEOFDAY_NO_TZ */
  110. }
  111. #endif /* !HAVE_GETTIMEOFDAY */
  112. {
  113. #if defined(HAVE_FTIME)
  114. struct TIMEB t;
  115. FTIME(&t);
  116. return (double)t.time + (double)t.millitm * (double)0.001;
  117. #else /* !HAVE_FTIME */
  118. time_t secs;
  119. time(&secs);
  120. return (double)secs;
  121. #endif /* !HAVE_FTIME */
  122. }
  123. }
  124. // adds the elements of the env variable path to the arg passed in
  125. void SystemTools::GetPath(kwsys_std::vector<kwsys_std::string>& path)
  126. {
  127. #if defined(_WIN32) && !defined(__CYGWIN__)
  128. const char* pathSep = ";";
  129. #else
  130. const char* pathSep = ":";
  131. #endif
  132. kwsys_std::string pathEnv = getenv("PATH");
  133. // A hack to make the below algorithm work.
  134. if(pathEnv[pathEnv.length()-1] != ':')
  135. {
  136. pathEnv += pathSep;
  137. }
  138. kwsys_std::string::size_type start =0;
  139. bool done = false;
  140. while(!done)
  141. {
  142. kwsys_std::string::size_type endpos = pathEnv.find(pathSep, start);
  143. if(endpos != kwsys_std::string::npos)
  144. {
  145. path.push_back(pathEnv.substr(start, endpos-start));
  146. start = endpos+1;
  147. }
  148. else
  149. {
  150. done = true;
  151. }
  152. }
  153. for(kwsys_std::vector<kwsys_std::string>::iterator i = path.begin();
  154. i != path.end(); ++i)
  155. {
  156. SystemTools::ConvertToUnixSlashes(*i);
  157. }
  158. }
  159. const char* SystemTools::GetExecutableExtension()
  160. {
  161. #if defined(_WIN32) || defined(__CYGWIN__)
  162. return ".exe";
  163. #else
  164. return "";
  165. #endif
  166. }
  167. bool SystemTools::MakeDirectory(const char* path)
  168. {
  169. if(SystemTools::FileExists(path))
  170. {
  171. return true;
  172. }
  173. kwsys_std::string dir = path;
  174. if(dir.size() == 0)
  175. {
  176. return false;
  177. }
  178. SystemTools::ConvertToUnixSlashes(dir);
  179. kwsys_std::string::size_type pos = dir.find(':');
  180. if(pos == kwsys_std::string::npos)
  181. {
  182. pos = 0;
  183. }
  184. kwsys_std::string topdir;
  185. while((pos = dir.find('/', pos)) != kwsys_std::string::npos)
  186. {
  187. topdir = dir.substr(0, pos);
  188. Mkdir(topdir.c_str());
  189. pos++;
  190. }
  191. if(dir[dir.size()-1] == '/')
  192. {
  193. topdir = dir.substr(0, dir.size());
  194. }
  195. else
  196. {
  197. topdir = dir;
  198. }
  199. if(Mkdir(topdir.c_str()) != 0)
  200. {
  201. // There is a bug in the Borland Run time library which makes MKDIR
  202. // return EACCES when it should return EEXISTS
  203. // if it is some other error besides directory exists
  204. // then return false
  205. if( (errno != EEXIST)
  206. #ifdef __BORLANDC__
  207. && (errno != EACCES)
  208. #endif
  209. )
  210. {
  211. return false;
  212. }
  213. }
  214. return true;
  215. }
  216. // replace replace with with as many times as it shows up in source.
  217. // write the result into source.
  218. void SystemTools::ReplaceString(kwsys_std::string& source,
  219. const char* replace,
  220. const char* with)
  221. {
  222. // get out quick if string is not found
  223. kwsys_std::string::size_type start = source.find(replace);
  224. if(start == kwsys_std::string::npos)
  225. {
  226. return;
  227. }
  228. kwsys_std::string rest;
  229. kwsys_std::string::size_type lengthReplace = strlen(replace);
  230. kwsys_std::string::size_type lengthWith = strlen(with);
  231. while(start != kwsys_std::string::npos)
  232. {
  233. rest = source.substr(start+lengthReplace);
  234. source = source.substr(0, start);
  235. source += with;
  236. source += rest;
  237. start = source.find(replace, start + lengthWith );
  238. }
  239. }
  240. // Read a registry value.
  241. // Example :
  242. // HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore\2.1\InstallPath
  243. // => will return the data of the "default" value of the key
  244. // HKEY_LOCAL_MACHINE\SOFTWARE\Scriptics\Tcl\8.4;Root
  245. // => will return the data of the "Root" value of the key
  246. #if defined(_WIN32) && !defined(__CYGWIN__)
  247. bool SystemTools::ReadRegistryValue(const char *key, kwsys_std::string &value)
  248. {
  249. kwsys_std::string primary = key;
  250. kwsys_std::string second;
  251. kwsys_std::string valuename;
  252. size_t start = primary.find("\\");
  253. if (start == kwsys_std::string::npos)
  254. {
  255. return false;
  256. }
  257. size_t valuenamepos = primary.find(";");
  258. if (valuenamepos != kwsys_std::string::npos)
  259. {
  260. valuename = primary.substr(valuenamepos+1);
  261. }
  262. second = primary.substr(start+1, valuenamepos-start-1);
  263. primary = primary.substr(0, start);
  264. HKEY primaryKey;
  265. if (primary == "HKEY_CURRENT_USER")
  266. {
  267. primaryKey = HKEY_CURRENT_USER;
  268. }
  269. if (primary == "HKEY_CURRENT_CONFIG")
  270. {
  271. primaryKey = HKEY_CURRENT_CONFIG;
  272. }
  273. if (primary == "HKEY_CLASSES_ROOT")
  274. {
  275. primaryKey = HKEY_CLASSES_ROOT;
  276. }
  277. if (primary == "HKEY_LOCAL_MACHINE")
  278. {
  279. primaryKey = HKEY_LOCAL_MACHINE;
  280. }
  281. if (primary == "HKEY_USERS")
  282. {
  283. primaryKey = HKEY_USERS;
  284. }
  285. HKEY hKey;
  286. if(RegOpenKeyEx(primaryKey,
  287. second.c_str(),
  288. 0,
  289. KEY_READ,
  290. &hKey) != ERROR_SUCCESS)
  291. {
  292. return false;
  293. }
  294. else
  295. {
  296. DWORD dwType, dwSize;
  297. dwSize = 1023;
  298. char data[1024];
  299. if(RegQueryValueEx(hKey,
  300. (LPTSTR)valuename.c_str(),
  301. NULL,
  302. &dwType,
  303. (BYTE *)data,
  304. &dwSize) == ERROR_SUCCESS)
  305. {
  306. if (dwType == REG_SZ)
  307. {
  308. value = data;
  309. return true;
  310. }
  311. }
  312. }
  313. return false;
  314. }
  315. #else
  316. bool SystemTools::ReadRegistryValue(const char *, kwsys_std::string &)
  317. {
  318. return false;
  319. }
  320. #endif
  321. // Write a registry value.
  322. // Example :
  323. // HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore\2.1\InstallPath
  324. // => will set the data of the "default" value of the key
  325. // HKEY_LOCAL_MACHINE\SOFTWARE\Scriptics\Tcl\8.4;Root
  326. // => will set the data of the "Root" value of the key
  327. #if defined(_WIN32) && !defined(__CYGWIN__)
  328. bool SystemTools::WriteRegistryValue(const char *key, const char *value)
  329. {
  330. kwsys_std::string primary = key;
  331. kwsys_std::string second;
  332. kwsys_std::string valuename;
  333. size_t start = primary.find("\\");
  334. if (start == kwsys_std::string::npos)
  335. {
  336. return false;
  337. }
  338. size_t valuenamepos = primary.find(";");
  339. if (valuenamepos != kwsys_std::string::npos)
  340. {
  341. valuename = primary.substr(valuenamepos+1);
  342. }
  343. second = primary.substr(start+1, valuenamepos-start-1);
  344. primary = primary.substr(0, start);
  345. HKEY primaryKey;
  346. if (primary == "HKEY_CURRENT_USER")
  347. {
  348. primaryKey = HKEY_CURRENT_USER;
  349. }
  350. if (primary == "HKEY_CURRENT_CONFIG")
  351. {
  352. primaryKey = HKEY_CURRENT_CONFIG;
  353. }
  354. if (primary == "HKEY_CLASSES_ROOT")
  355. {
  356. primaryKey = HKEY_CLASSES_ROOT;
  357. }
  358. if (primary == "HKEY_LOCAL_MACHINE")
  359. {
  360. primaryKey = HKEY_LOCAL_MACHINE;
  361. }
  362. if (primary == "HKEY_USERS")
  363. {
  364. primaryKey = HKEY_USERS;
  365. }
  366. HKEY hKey;
  367. DWORD dwDummy;
  368. if(RegCreateKeyEx(primaryKey,
  369. second.c_str(),
  370. 0,
  371. "",
  372. REG_OPTION_NON_VOLATILE,
  373. KEY_WRITE,
  374. NULL,
  375. &hKey,
  376. &dwDummy) != ERROR_SUCCESS)
  377. {
  378. return false;
  379. }
  380. if(RegSetValueEx(hKey,
  381. (LPTSTR)valuename.c_str(),
  382. 0,
  383. REG_SZ,
  384. (CONST BYTE *)value,
  385. (DWORD)(strlen(value) + 1)) == ERROR_SUCCESS)
  386. {
  387. return true;
  388. }
  389. return false;
  390. }
  391. #else
  392. bool SystemTools::WriteRegistryValue(const char *, const char *)
  393. {
  394. return false;
  395. }
  396. #endif
  397. // Delete a registry value.
  398. // Example :
  399. // HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore\2.1\InstallPath
  400. // => will delete the data of the "default" value of the key
  401. // HKEY_LOCAL_MACHINE\SOFTWARE\Scriptics\Tcl\8.4;Root
  402. // => will delete the data of the "Root" value of the key
  403. #if defined(_WIN32) && !defined(__CYGWIN__)
  404. bool SystemTools::DeleteRegistryValue(const char *key)
  405. {
  406. kwsys_std::string primary = key;
  407. kwsys_std::string second;
  408. kwsys_std::string valuename;
  409. size_t start = primary.find("\\");
  410. if (start == kwsys_std::string::npos)
  411. {
  412. return false;
  413. }
  414. size_t valuenamepos = primary.find(";");
  415. if (valuenamepos != kwsys_std::string::npos)
  416. {
  417. valuename = primary.substr(valuenamepos+1);
  418. }
  419. second = primary.substr(start+1, valuenamepos-start-1);
  420. primary = primary.substr(0, start);
  421. HKEY primaryKey;
  422. if (primary == "HKEY_CURRENT_USER")
  423. {
  424. primaryKey = HKEY_CURRENT_USER;
  425. }
  426. if (primary == "HKEY_CURRENT_CONFIG")
  427. {
  428. primaryKey = HKEY_CURRENT_CONFIG;
  429. }
  430. if (primary == "HKEY_CLASSES_ROOT")
  431. {
  432. primaryKey = HKEY_CLASSES_ROOT;
  433. }
  434. if (primary == "HKEY_LOCAL_MACHINE")
  435. {
  436. primaryKey = HKEY_LOCAL_MACHINE;
  437. }
  438. if (primary == "HKEY_USERS")
  439. {
  440. primaryKey = HKEY_USERS;
  441. }
  442. HKEY hKey;
  443. if(RegOpenKeyEx(primaryKey,
  444. second.c_str(),
  445. 0,
  446. KEY_WRITE,
  447. &hKey) != ERROR_SUCCESS)
  448. {
  449. return false;
  450. }
  451. else
  452. {
  453. if(RegDeleteValue(hKey,
  454. (LPTSTR)valuename.c_str()) == ERROR_SUCCESS)
  455. {
  456. return true;
  457. }
  458. }
  459. return false;
  460. }
  461. #else
  462. bool SystemTools::DeleteRegistryValue(const char *)
  463. {
  464. return false;
  465. }
  466. #endif
  467. // replace replace with with as many times as it shows up in source.
  468. // write the result into source.
  469. #if defined(_WIN32) && !defined(__CYGWIN__)
  470. void SystemTools::ExpandRegistryValues(kwsys_std::string& source)
  471. {
  472. // Regular expression to match anything inside [...] that begins in HKEY.
  473. // Note that there is a special rule for regular expressions to match a
  474. // close square-bracket inside a list delimited by square brackets.
  475. // The "[^]]" part of this expression will match any character except
  476. // a close square-bracket. The ']' character must be the first in the
  477. // list of characters inside the [^...] block of the expression.
  478. RegularExpression regEntry("\\[(HKEY[^]]*)\\]");
  479. // check for black line or comment
  480. while (regEntry.find(source))
  481. {
  482. // the arguments are the second match
  483. kwsys_std::string key = regEntry.match(1);
  484. kwsys_std::string val;
  485. if (ReadRegistryValue(key.c_str(), val))
  486. {
  487. kwsys_std::string reg = "[";
  488. reg += key + "]";
  489. SystemTools::ReplaceString(source, reg.c_str(), val.c_str());
  490. }
  491. else
  492. {
  493. kwsys_std::string reg = "[";
  494. reg += key + "]";
  495. SystemTools::ReplaceString(source, reg.c_str(), "/registry");
  496. }
  497. }
  498. }
  499. #else
  500. void SystemTools::ExpandRegistryValues(kwsys_std::string&)
  501. {
  502. }
  503. #endif
  504. kwsys_std::string SystemTools::EscapeQuotes(const char* str)
  505. {
  506. kwsys_std::string result = "";
  507. for(const char* ch = str; *ch != '\0'; ++ch)
  508. {
  509. if(*ch == '"')
  510. {
  511. result += '\\';
  512. }
  513. result += *ch;
  514. }
  515. return result;
  516. }
  517. bool SystemTools::SameFile(const char* file1, const char* file2)
  518. {
  519. #ifdef _WIN32
  520. HANDLE hFile1, hFile2;
  521. hFile1 = CreateFile( file1,
  522. GENERIC_READ,
  523. FILE_SHARE_READ ,
  524. NULL,
  525. OPEN_EXISTING,
  526. FILE_FLAG_BACKUP_SEMANTICS,
  527. NULL
  528. );
  529. hFile2 = CreateFile( file2,
  530. GENERIC_READ,
  531. FILE_SHARE_READ,
  532. NULL,
  533. OPEN_EXISTING,
  534. FILE_FLAG_BACKUP_SEMANTICS,
  535. NULL
  536. );
  537. if( hFile1 == INVALID_HANDLE_VALUE || hFile2 == INVALID_HANDLE_VALUE)
  538. {
  539. if(hFile1 != INVALID_HANDLE_VALUE)
  540. {
  541. CloseHandle(hFile1);
  542. }
  543. if(hFile2 != INVALID_HANDLE_VALUE)
  544. {
  545. CloseHandle(hFile2);
  546. }
  547. return false;
  548. }
  549. BY_HANDLE_FILE_INFORMATION fiBuf1;
  550. BY_HANDLE_FILE_INFORMATION fiBuf2;
  551. GetFileInformationByHandle( hFile1, &fiBuf1 );
  552. GetFileInformationByHandle( hFile2, &fiBuf2 );
  553. CloseHandle(hFile1);
  554. CloseHandle(hFile2);
  555. return (fiBuf1.nFileIndexHigh == fiBuf2.nFileIndexHigh &&
  556. fiBuf1.nFileIndexLow == fiBuf2.nFileIndexLow);
  557. #else
  558. struct stat fileStat1, fileStat2;
  559. if (stat(file1, &fileStat1) == 0 && stat(file2, &fileStat2) == 0)
  560. {
  561. // see if the files are the same file
  562. // check the device inode and size
  563. if(memcmp(&fileStat2.st_dev, &fileStat1.st_dev, sizeof(fileStat1.st_dev)) == 0 &&
  564. memcmp(&fileStat2.st_ino, &fileStat1.st_ino, sizeof(fileStat1.st_ino)) == 0 &&
  565. fileStat2.st_size == fileStat1.st_size
  566. )
  567. {
  568. return true;
  569. }
  570. }
  571. return false;
  572. #endif
  573. }
  574. // return true if the file exists
  575. bool SystemTools::FileExists(const char* filename)
  576. {
  577. struct stat fs;
  578. if (stat(filename, &fs) != 0)
  579. {
  580. return false;
  581. }
  582. else
  583. {
  584. return true;
  585. }
  586. }
  587. // Return a capitalized string (i.e the first letter is uppercased, all other
  588. // are lowercased)
  589. kwsys_std::string SystemTools::Capitalized(const kwsys_std::string& s)
  590. {
  591. kwsys_std::string n;
  592. n.resize(s.size());
  593. n[0] = toupper(s[0]);
  594. for (size_t i = 1; i < s.size(); i++)
  595. {
  596. n[i] = tolower(s[i]);
  597. }
  598. return n;
  599. }
  600. // Return a lower case string
  601. kwsys_std::string SystemTools::LowerCase(const kwsys_std::string& s)
  602. {
  603. kwsys_std::string n;
  604. n.resize(s.size());
  605. for (size_t i = 0; i < s.size(); i++)
  606. {
  607. n[i] = tolower(s[i]);
  608. }
  609. return n;
  610. }
  611. // Return a lower case string
  612. kwsys_std::string SystemTools::UpperCase(const kwsys_std::string& s)
  613. {
  614. kwsys_std::string n;
  615. n.resize(s.size());
  616. for (size_t i = 0; i < s.size(); i++)
  617. {
  618. n[i] = toupper(s[i]);
  619. }
  620. return n;
  621. }
  622. // convert windows slashes to unix slashes
  623. void SystemTools::ConvertToUnixSlashes(kwsys_std::string& path)
  624. {
  625. kwsys_std::string::size_type pos = 0;
  626. while((pos = path.find('\\', pos)) != kwsys_std::string::npos)
  627. {
  628. path[pos] = '/';
  629. pos++;
  630. }
  631. // Remove all // from the path just like most unix shells
  632. int start_find = 0;
  633. #ifdef _WIN32
  634. // However, on windows if the first characters are both slashes,
  635. // then keep them that way, so that network paths can be handled.
  636. start_find = 1;
  637. #endif
  638. while((pos = path.find("//", start_find)) != kwsys_std::string::npos)
  639. {
  640. SystemTools::ReplaceString(path, "//", "/");
  641. }
  642. // remove any trailing slash
  643. if(path.size() && path[path.size()-1] == '/')
  644. {
  645. path = path.substr(0, path.size()-1);
  646. }
  647. // if there is a tilda ~ then replace it with HOME
  648. if(path.find("~") == 0)
  649. {
  650. if (getenv("HOME"))
  651. {
  652. path = kwsys_std::string(getenv("HOME")) + path.substr(1);
  653. }
  654. }
  655. // if there is a /tmp_mnt in a path get rid of it!
  656. // stupid sgi's
  657. if(path.find("/tmp_mnt") == 0)
  658. {
  659. path = path.substr(8);
  660. }
  661. }
  662. // change // to /, and escape any spaces in the path
  663. kwsys_std::string SystemTools::ConvertToUnixOutputPath(const char* path)
  664. {
  665. kwsys_std::string ret = path;
  666. // remove // except at the beginning might be a cygwin drive
  667. kwsys_std::string::size_type pos = 1;
  668. while((pos = ret.find("//", pos)) != kwsys_std::string::npos)
  669. {
  670. ret.erase(pos, 1);
  671. }
  672. // now escape spaces if there is a space in the path
  673. if(ret.find(" ") != kwsys_std::string::npos)
  674. {
  675. kwsys_std::string result = "";
  676. char lastch = 1;
  677. for(const char* ch = ret.c_str(); *ch != '\0'; ++ch)
  678. {
  679. // if it is already escaped then don't try to escape it again
  680. if(*ch == ' ' && lastch != '\\')
  681. {
  682. result += '\\';
  683. }
  684. result += *ch;
  685. lastch = *ch;
  686. }
  687. ret = result;
  688. }
  689. return ret;
  690. }
  691. kwsys_std::string SystemTools::EscapeSpaces(const char* str)
  692. {
  693. #if defined(_WIN32) && !defined(__CYGWIN__)
  694. kwsys_std::string result;
  695. // if there are spaces
  696. kwsys_std::string temp = str;
  697. if (temp.find(" ") != kwsys_std::string::npos &&
  698. temp.find("\"")==kwsys_std::string::npos)
  699. {
  700. result = "\"";
  701. result += str;
  702. result += "\"";
  703. return result;
  704. }
  705. return str;
  706. #else
  707. kwsys_std::string result = "";
  708. for(const char* ch = str; *ch != '\0'; ++ch)
  709. {
  710. if(*ch == ' ')
  711. {
  712. result += '\\';
  713. }
  714. result += *ch;
  715. }
  716. return result;
  717. #endif
  718. }
  719. kwsys_std::string SystemTools::ConvertToOutputPath(const char* path)
  720. {
  721. #if defined(_WIN32) && !defined(__CYGWIN__)
  722. return SystemTools::ConvertToWindowsOutputPath(path);
  723. #else
  724. return SystemTools::ConvertToUnixOutputPath(path);
  725. #endif
  726. }
  727. // remove double slashes not at the start
  728. kwsys_std::string SystemTools::ConvertToWindowsOutputPath(const char* path)
  729. {
  730. kwsys_std::string ret = path;
  731. kwsys_std::string::size_type pos = 0;
  732. // first convert all of the slashes
  733. while((pos = ret.find('/', pos)) != kwsys_std::string::npos)
  734. {
  735. ret[pos] = '\\';
  736. pos++;
  737. }
  738. // check for really small paths
  739. if(ret.size() < 2)
  740. {
  741. return ret;
  742. }
  743. // now clean up a bit and remove double slashes
  744. // Only if it is not the first position in the path which is a network
  745. // path on windows
  746. pos = 1; // start at position 1
  747. if(ret[0] == '\"')
  748. {
  749. pos = 2; // if the string is already quoted then start at 2
  750. if(ret.size() < 3)
  751. {
  752. return ret;
  753. }
  754. }
  755. while((pos = ret.find("\\\\", pos)) != kwsys_std::string::npos)
  756. {
  757. ret.erase(pos, 1);
  758. }
  759. // now double quote the path if it has spaces in it
  760. // and is not already double quoted
  761. if(ret.find(" ") != kwsys_std::string::npos
  762. && ret[0] != '\"')
  763. {
  764. kwsys_std::string result;
  765. result = "\"" + ret + "\"";
  766. ret = result;
  767. }
  768. return ret;
  769. }
  770. bool SystemTools::CopyFileIfDifferent(const char* source,
  771. const char* destination)
  772. {
  773. if(SystemTools::FilesDiffer(source, destination))
  774. {
  775. SystemTools::CopyFileAlways(source, destination);
  776. return true;
  777. }
  778. return false;
  779. }
  780. bool SystemTools::FilesDiffer(const char* source,
  781. const char* destination)
  782. {
  783. struct stat statSource;
  784. if (stat(source, &statSource) != 0)
  785. {
  786. return true;
  787. }
  788. struct stat statDestination;
  789. if (stat(destination, &statDestination) != 0)
  790. {
  791. return true;
  792. }
  793. if(statSource.st_size != statDestination.st_size)
  794. {
  795. return true;
  796. }
  797. if(statSource.st_size == 0)
  798. {
  799. return false;
  800. }
  801. #if defined(_WIN32) || defined(__CYGWIN__)
  802. kwsys_std::ifstream finSource(source,
  803. kwsys_std::ios::binary | kwsys_std::ios::in);
  804. kwsys_std::ifstream finDestination(destination,
  805. kwsys_std::ios::binary | kwsys_std::ios::in);
  806. #else
  807. kwsys_std::ifstream finSource(source);
  808. kwsys_std::ifstream finDestination(destination);
  809. #endif
  810. if(!finSource || !finDestination)
  811. {
  812. return true;
  813. }
  814. char* source_buf = new char[statSource.st_size];
  815. char* dest_buf = new char[statSource.st_size];
  816. finSource.read(source_buf, statSource.st_size);
  817. finDestination.read(dest_buf, statSource.st_size);
  818. if(statSource.st_size != static_cast<long>(finSource.gcount()) ||
  819. statSource.st_size != static_cast<long>(finDestination.gcount()))
  820. {
  821. // Failed to read files.
  822. delete [] source_buf;
  823. delete [] dest_buf;
  824. return true;
  825. }
  826. int ret = memcmp((const void*)source_buf,
  827. (const void*)dest_buf,
  828. statSource.st_size);
  829. delete [] dest_buf;
  830. delete [] source_buf;
  831. return ret != 0;
  832. }
  833. /**
  834. * Copy a file named by "source" to the file named by "destination".
  835. */
  836. bool SystemTools::CopyFileAlways(const char* source, const char* destination)
  837. {
  838. const int bufferSize = 4096;
  839. char buffer[bufferSize];
  840. // If destination is a directory, try to create a file with the same
  841. // name as the source in that directory.
  842. kwsys_std::string new_destination;
  843. if(SystemTools::FileExists(destination) &&
  844. SystemTools::FileIsDirectory(destination))
  845. {
  846. new_destination = destination;
  847. SystemTools::ConvertToUnixSlashes(new_destination);
  848. new_destination += '/';
  849. kwsys_std::string source_name = source;
  850. new_destination += SystemTools::GetFilenameName(source_name);
  851. destination = new_destination.c_str();
  852. }
  853. // Create destination directory
  854. kwsys_std::string destination_dir = destination;
  855. destination_dir = SystemTools::GetFilenamePath(destination_dir);
  856. SystemTools::MakeDirectory(destination_dir.c_str());
  857. // Open files
  858. #if defined(_WIN32) || defined(__CYGWIN__)
  859. kwsys_std::ifstream fin(source,
  860. kwsys_std::ios::binary | kwsys_std::ios::in);
  861. #else
  862. kwsys_std::ifstream fin(source);
  863. #endif
  864. if(!fin)
  865. {
  866. return false;
  867. }
  868. #if defined(_WIN32) || defined(__CYGWIN__)
  869. kwsys_std::ofstream fout(destination,
  870. kwsys_std::ios::binary | kwsys_std::ios::out | kwsys_std::ios::trunc);
  871. #else
  872. kwsys_std::ofstream fout(destination,
  873. kwsys_std::ios::out | kwsys_std::ios::trunc);
  874. #endif
  875. if(!fout)
  876. {
  877. return false;
  878. }
  879. // This copy loop is very sensitive on certain platforms with
  880. // slightly broken stream libraries (like HPUX). Normally, it is
  881. // incorrect to not check the error condition on the fin.read()
  882. // before using the data, but the fin.gcount() will be zero if an
  883. // error occurred. Therefore, the loop should be safe everywhere.
  884. while(fin)
  885. {
  886. fin.read(buffer, bufferSize);
  887. if(fin.gcount())
  888. {
  889. fout.write(buffer, fin.gcount());
  890. }
  891. }
  892. // Make sure the operating system has finished writing the file
  893. // before closing it. This will ensure the file is finished before
  894. // the check below.
  895. fout.flush();
  896. fin.close();
  897. fout.close();
  898. // More checks.
  899. struct stat statSource, statDestination;
  900. statSource.st_size = 12345;
  901. statDestination.st_size = 12345;
  902. if(stat(source, &statSource) != 0)
  903. {
  904. return false;
  905. }
  906. else if(stat(destination, &statDestination) != 0)
  907. {
  908. return false;
  909. }
  910. else if(statSource.st_size != statDestination.st_size)
  911. {
  912. return false;
  913. }
  914. return true;
  915. }
  916. // return true if the file exists
  917. long int SystemTools::ModifiedTime(const char* filename)
  918. {
  919. struct stat fs;
  920. if (stat(filename, &fs) != 0)
  921. {
  922. return 0;
  923. }
  924. else
  925. {
  926. return (long int)fs.st_mtime;
  927. }
  928. }
  929. kwsys_std::string SystemTools::GetLastSystemError()
  930. {
  931. int e = errno;
  932. return strerror(e);
  933. }
  934. bool SystemTools::RemoveFile(const char* source)
  935. {
  936. return unlink(source) != 0 ? false : true;
  937. }
  938. /**
  939. * Find the file the given name. Searches the given path and then
  940. * the system search path. Returns the full path to the file if it is
  941. * found. Otherwise, the empty string is returned.
  942. */
  943. kwsys_std::string SystemTools::FindFile(const char* name,
  944. const kwsys_std::vector<kwsys_std::string>& userPaths)
  945. {
  946. // Add the system search path to our path.
  947. kwsys_std::vector<kwsys_std::string> path = userPaths;
  948. SystemTools::GetPath(path);
  949. kwsys_std::string tryPath;
  950. for(kwsys_std::vector<kwsys_std::string>::const_iterator p = path.begin();
  951. p != path.end(); ++p)
  952. {
  953. tryPath = *p;
  954. tryPath += "/";
  955. tryPath += name;
  956. if(SystemTools::FileExists(tryPath.c_str()) &&
  957. !SystemTools::FileIsDirectory(tryPath.c_str()))
  958. {
  959. return SystemTools::CollapseFullPath(tryPath.c_str());
  960. }
  961. }
  962. // Couldn't find the file.
  963. return "";
  964. }
  965. /**
  966. * Find the executable with the given name. Searches the given path and then
  967. * the system search path. Returns the full path to the executable if it is
  968. * found. Otherwise, the empty string is returned.
  969. */
  970. kwsys_std::string SystemTools::FindProgram(const char* name,
  971. const kwsys_std::vector<kwsys_std::string>& userPaths,
  972. bool no_system_path)
  973. {
  974. if(!name)
  975. {
  976. return "";
  977. }
  978. // See if the executable exists as written.
  979. if(SystemTools::FileExists(name) &&
  980. !SystemTools::FileIsDirectory(name))
  981. {
  982. return SystemTools::CollapseFullPath(name);
  983. }
  984. kwsys_std::string tryPath = name;
  985. tryPath += SystemTools::GetExecutableExtension();
  986. if(SystemTools::FileExists(tryPath.c_str()) &&
  987. !SystemTools::FileIsDirectory(tryPath.c_str()))
  988. {
  989. return SystemTools::CollapseFullPath(tryPath.c_str());
  990. }
  991. // Add the system search path to our path.
  992. kwsys_std::vector<kwsys_std::string> path = userPaths;
  993. if (!no_system_path)
  994. {
  995. SystemTools::GetPath(path);
  996. }
  997. for(kwsys_std::vector<kwsys_std::string>::const_iterator p = path.begin();
  998. p != path.end(); ++p)
  999. {
  1000. tryPath = *p;
  1001. tryPath += "/";
  1002. tryPath += name;
  1003. if(SystemTools::FileExists(tryPath.c_str()) &&
  1004. !SystemTools::FileIsDirectory(tryPath.c_str()))
  1005. {
  1006. return SystemTools::CollapseFullPath(tryPath.c_str());
  1007. }
  1008. #ifdef _WIN32
  1009. tryPath += ".com";
  1010. if(SystemTools::FileExists(tryPath.c_str()) &&
  1011. !SystemTools::FileIsDirectory(tryPath.c_str()))
  1012. {
  1013. return SystemTools::CollapseFullPath(tryPath.c_str());
  1014. }
  1015. tryPath = *p;
  1016. tryPath += "/";
  1017. tryPath += name;
  1018. #endif
  1019. tryPath += SystemTools::GetExecutableExtension();
  1020. if(SystemTools::FileExists(tryPath.c_str()) &&
  1021. !SystemTools::FileIsDirectory(tryPath.c_str()))
  1022. {
  1023. return SystemTools::CollapseFullPath(tryPath.c_str());
  1024. }
  1025. }
  1026. // Couldn't find the program.
  1027. return "";
  1028. }
  1029. /**
  1030. * Find the library with the given name. Searches the given path and then
  1031. * the system search path. Returns the full path to the library if it is
  1032. * found. Otherwise, the empty string is returned.
  1033. */
  1034. kwsys_std::string SystemTools::FindLibrary(const char* name,
  1035. const kwsys_std::vector<kwsys_std::string>& userPaths)
  1036. {
  1037. // See if the executable exists as written.
  1038. if(SystemTools::FileExists(name) &&
  1039. !SystemTools::FileIsDirectory(name))
  1040. {
  1041. return SystemTools::CollapseFullPath(name);
  1042. }
  1043. // Add the system search path to our path.
  1044. kwsys_std::vector<kwsys_std::string> path = userPaths;
  1045. SystemTools::GetPath(path);
  1046. kwsys_std::string tryPath;
  1047. for(kwsys_std::vector<kwsys_std::string>::const_iterator p = path.begin();
  1048. p != path.end(); ++p)
  1049. {
  1050. #if defined(_WIN32) && !defined(__CYGWIN__)
  1051. tryPath = *p;
  1052. tryPath += "/";
  1053. tryPath += name;
  1054. tryPath += ".lib";
  1055. if(SystemTools::FileExists(tryPath.c_str()))
  1056. {
  1057. return SystemTools::CollapseFullPath(tryPath.c_str());
  1058. }
  1059. #else
  1060. tryPath = *p;
  1061. tryPath += "/lib";
  1062. tryPath += name;
  1063. tryPath += ".so";
  1064. if(SystemTools::FileExists(tryPath.c_str()))
  1065. {
  1066. return SystemTools::CollapseFullPath(tryPath.c_str());
  1067. }
  1068. tryPath = *p;
  1069. tryPath += "/lib";
  1070. tryPath += name;
  1071. tryPath += ".a";
  1072. if(SystemTools::FileExists(tryPath.c_str()))
  1073. {
  1074. return SystemTools::CollapseFullPath(tryPath.c_str());
  1075. }
  1076. tryPath = *p;
  1077. tryPath += "/lib";
  1078. tryPath += name;
  1079. tryPath += ".sl";
  1080. if(SystemTools::FileExists(tryPath.c_str()))
  1081. {
  1082. return SystemTools::CollapseFullPath(tryPath.c_str());
  1083. }
  1084. tryPath = *p;
  1085. tryPath += "/lib";
  1086. tryPath += name;
  1087. tryPath += ".dylib";
  1088. if(SystemTools::FileExists(tryPath.c_str()))
  1089. {
  1090. return SystemTools::CollapseFullPath(tryPath.c_str());
  1091. }
  1092. #endif
  1093. }
  1094. // Couldn't find the library.
  1095. return "";
  1096. }
  1097. bool SystemTools::FileIsDirectory(const char* name)
  1098. {
  1099. struct stat fs;
  1100. if(stat(name, &fs) == 0)
  1101. {
  1102. #if _WIN32
  1103. return ((fs.st_mode & _S_IFDIR) != 0);
  1104. #else
  1105. return S_ISDIR(fs.st_mode);
  1106. #endif
  1107. }
  1108. else
  1109. {
  1110. return false;
  1111. }
  1112. }
  1113. int SystemTools::ChangeDirectory(const char *dir)
  1114. {
  1115. return Chdir(dir);
  1116. }
  1117. kwsys_std::string SystemTools::GetCurrentWorkingDirectory()
  1118. {
  1119. char buf[2048];
  1120. kwsys_std::string path = Getcwd(buf, 2048);
  1121. return path;
  1122. }
  1123. kwsys_std::string SystemTools::GetProgramPath(const char* in_name)
  1124. {
  1125. kwsys_std::string dir, file;
  1126. SystemTools::SplitProgramPath(in_name, dir, file);
  1127. return dir;
  1128. }
  1129. bool SystemTools::SplitProgramPath(const char* in_name,
  1130. kwsys_std::string& dir,
  1131. kwsys_std::string& file,
  1132. bool)
  1133. {
  1134. dir = in_name;
  1135. file = "";
  1136. SystemTools::ConvertToUnixSlashes(dir);
  1137. if(!SystemTools::FileIsDirectory(dir.c_str()))
  1138. {
  1139. kwsys_std::string::size_type slashPos = dir.rfind("/");
  1140. if(slashPos != kwsys_std::string::npos)
  1141. {
  1142. file = dir.substr(slashPos+1);
  1143. dir = dir.substr(0, slashPos);
  1144. }
  1145. else
  1146. {
  1147. file = dir;
  1148. dir = "";
  1149. }
  1150. }
  1151. if((dir != "") && !SystemTools::FileIsDirectory(dir.c_str()))
  1152. {
  1153. kwsys_std::string oldDir = in_name;
  1154. SystemTools::ConvertToUnixSlashes(oldDir);
  1155. dir = in_name;
  1156. return false;
  1157. }
  1158. return true;
  1159. }
  1160. kwsys_std::string SystemTools::CollapseFullPath(const char* in_relative)
  1161. {
  1162. return SystemTools::CollapseFullPath(in_relative, 0);
  1163. }
  1164. kwsys_std::string SystemTools::CollapseFullPath(const char* in_relative,
  1165. const char* in_base)
  1166. {
  1167. kwsys_std::string dir, file;
  1168. SystemTools::SplitProgramPath(in_relative, dir, file, false);
  1169. // Save original working directory.
  1170. kwsys_std::string orig = SystemTools::GetCurrentWorkingDirectory();
  1171. // Change to base of relative path.
  1172. if(in_base)
  1173. {
  1174. Chdir(in_base);
  1175. }
  1176. #ifdef _WIN32
  1177. // Follow relative path.
  1178. if(dir != "")
  1179. {
  1180. Chdir(dir.c_str());
  1181. }
  1182. // Get the resulting directory.
  1183. kwsys_std::string newDir = SystemTools::GetCurrentWorkingDirectory();
  1184. // Add the file back on to the directory.
  1185. SystemTools::ConvertToUnixSlashes(newDir);
  1186. #else
  1187. # ifdef MAXPATHLEN
  1188. char resolved_name[MAXPATHLEN];
  1189. # else
  1190. # ifdef PATH_MAX
  1191. char resolved_name[PATH_MAX];
  1192. # else
  1193. char resolved_name[5024];
  1194. # endif
  1195. # endif
  1196. // Resolve relative path.
  1197. kwsys_std::string newDir;
  1198. if(dir != "")
  1199. {
  1200. realpath(dir.c_str(), resolved_name);
  1201. newDir = resolved_name;
  1202. }
  1203. else
  1204. {
  1205. newDir = SystemTools::GetCurrentWorkingDirectory();
  1206. }
  1207. #endif
  1208. // Restore original working directory.
  1209. Chdir(orig.c_str());
  1210. // Construct and return the full path.
  1211. kwsys_std::string newPath = newDir;
  1212. if(file != "")
  1213. {
  1214. newPath += "/";
  1215. newPath += file;
  1216. }
  1217. return newPath;
  1218. }
  1219. bool SystemTools::Split(const char* str, kwsys_std::vector<kwsys_std::string>& lines)
  1220. {
  1221. kwsys_std::string data(str);
  1222. kwsys_std::string::size_type lpos = 0;
  1223. while(lpos < data.length())
  1224. {
  1225. kwsys_std::string::size_type rpos = data.find_first_of("\n", lpos);
  1226. if(rpos == kwsys_std::string::npos)
  1227. {
  1228. // Line ends at end of string without a newline.
  1229. lines.push_back(data.substr(lpos));
  1230. return false;
  1231. }
  1232. if((rpos > lpos) && (data[rpos-1] == '\r'))
  1233. {
  1234. // Line ends in a "\r\n" pair, remove both characters.
  1235. lines.push_back(data.substr(lpos, (rpos-1)-lpos));
  1236. }
  1237. else
  1238. {
  1239. // Line ends in a "\n", remove the character.
  1240. lines.push_back(data.substr(lpos, rpos-lpos));
  1241. }
  1242. lpos = rpos+1;
  1243. }
  1244. return true;
  1245. }
  1246. /**
  1247. * Return path of a full filename (no trailing slashes).
  1248. * Warning: returned path is converted to Unix slashes format.
  1249. */
  1250. kwsys_std::string SystemTools::GetFilenamePath(const kwsys_std::string& filename)
  1251. {
  1252. kwsys_std::string fn = filename;
  1253. SystemTools::ConvertToUnixSlashes(fn);
  1254. kwsys_std::string::size_type slash_pos = fn.rfind("/");
  1255. if(slash_pos != kwsys_std::string::npos)
  1256. {
  1257. return fn.substr(0, slash_pos);
  1258. }
  1259. else
  1260. {
  1261. return "";
  1262. }
  1263. }
  1264. /**
  1265. * Return file name of a full filename (i.e. file name without path).
  1266. */
  1267. kwsys_std::string SystemTools::GetFilenameName(const kwsys_std::string& filename)
  1268. {
  1269. kwsys_std::string fn = filename;
  1270. SystemTools::ConvertToUnixSlashes(fn);
  1271. kwsys_std::string::size_type slash_pos = fn.rfind("/");
  1272. if(slash_pos != kwsys_std::string::npos)
  1273. {
  1274. return fn.substr(slash_pos + 1);
  1275. }
  1276. else
  1277. {
  1278. return filename;
  1279. }
  1280. }
  1281. /**
  1282. * Return file extension of a full filename (dot included).
  1283. * Warning: this is the longest extension (for example: .tar.gz)
  1284. */
  1285. kwsys_std::string SystemTools::GetFilenameExtension(const kwsys_std::string& filename)
  1286. {
  1287. kwsys_std::string name = SystemTools::GetFilenameName(filename);
  1288. kwsys_std::string::size_type dot_pos = name.find(".");
  1289. if(dot_pos != kwsys_std::string::npos)
  1290. {
  1291. return name.substr(dot_pos);
  1292. }
  1293. else
  1294. {
  1295. return "";
  1296. }
  1297. }
  1298. /**
  1299. * Return file name without extension of a full filename (i.e. without path).
  1300. * Warning: it considers the longest extension (for example: .tar.gz)
  1301. */
  1302. kwsys_std::string SystemTools::GetFilenameWithoutExtension(const kwsys_std::string& filename)
  1303. {
  1304. kwsys_std::string name = SystemTools::GetFilenameName(filename);
  1305. kwsys_std::string::size_type dot_pos = name.find(".");
  1306. if(dot_pos != kwsys_std::string::npos)
  1307. {
  1308. return name.substr(0, dot_pos);
  1309. }
  1310. else
  1311. {
  1312. return name;
  1313. }
  1314. }
  1315. /**
  1316. * Return file name without extension of a full filename (i.e. without path).
  1317. * Warning: it considers the last extension (for example: removes .gz
  1318. * from .tar.gz)
  1319. */
  1320. kwsys_std::string
  1321. SystemTools::GetFilenameWithoutLastExtension(const kwsys_std::string& filename)
  1322. {
  1323. kwsys_std::string name = SystemTools::GetFilenameName(filename);
  1324. kwsys_std::string::size_type dot_pos = name.rfind(".");
  1325. if(dot_pos != kwsys_std::string::npos)
  1326. {
  1327. return name.substr(0, dot_pos);
  1328. }
  1329. else
  1330. {
  1331. return name;
  1332. }
  1333. }
  1334. bool SystemTools::FileIsFullPath(const char* in_name)
  1335. {
  1336. kwsys_std::string name = in_name;
  1337. #if defined(_WIN32)
  1338. // On Windows, the name must be at least two characters long.
  1339. if(name.length() < 2)
  1340. {
  1341. return false;
  1342. }
  1343. if(name[1] == ':')
  1344. {
  1345. return true;
  1346. }
  1347. if(name[0] == '\\')
  1348. {
  1349. return true;
  1350. }
  1351. #else
  1352. // On UNIX, the name must be at least one character long.
  1353. if(name.length() < 1)
  1354. {
  1355. return false;
  1356. }
  1357. #endif
  1358. // On UNIX, the name must begin in a '/'.
  1359. // On Windows, if the name begins in a '/', then it is a full
  1360. // network path.
  1361. if(name[0] == '/')
  1362. {
  1363. return true;
  1364. }
  1365. return false;
  1366. }
  1367. void SystemTools::Glob(const char *directory, const char *regexp,
  1368. kwsys_std::vector<kwsys_std::string>& files)
  1369. {
  1370. Directory d;
  1371. RegularExpression reg(regexp);
  1372. if (d.Load(directory))
  1373. {
  1374. size_t numf;
  1375. unsigned int i;
  1376. numf = d.GetNumberOfFiles();
  1377. for (i = 0; i < numf; i++)
  1378. {
  1379. kwsys_std::string fname = d.GetFile(i);
  1380. if (reg.find(fname))
  1381. {
  1382. files.push_back(fname);
  1383. }
  1384. }
  1385. }
  1386. }
  1387. void SystemTools::GlobDirs(const char *fullPath,
  1388. kwsys_std::vector<kwsys_std::string>& files)
  1389. {
  1390. kwsys_std::string path = fullPath;
  1391. kwsys_std::string::size_type pos = path.find("/*");
  1392. if(pos == kwsys_std::string::npos)
  1393. {
  1394. files.push_back(fullPath);
  1395. return;
  1396. }
  1397. kwsys_std::string startPath = path.substr(0, pos);
  1398. kwsys_std::string finishPath = path.substr(pos+2);
  1399. Directory d;
  1400. if (d.Load(startPath.c_str()))
  1401. {
  1402. for (unsigned int i = 0; i < d.GetNumberOfFiles(); ++i)
  1403. {
  1404. if((kwsys_std::string(d.GetFile(i)) != ".")
  1405. && (kwsys_std::string(d.GetFile(i)) != ".."))
  1406. {
  1407. kwsys_std::string fname = startPath;
  1408. fname +="/";
  1409. fname += d.GetFile(i);
  1410. if(SystemTools::FileIsDirectory(fname.c_str()))
  1411. {
  1412. fname += finishPath;
  1413. SystemTools::GlobDirs(fname.c_str(), files);
  1414. }
  1415. }
  1416. }
  1417. }
  1418. }
  1419. bool SystemTools::GetShortPath(const char* path, kwsys_std::string& shortPath)
  1420. {
  1421. #if defined(WIN32) && !defined(__CYGWIN__)
  1422. const int size = int(strlen(path)) +1; // size of return
  1423. char *buffer = new char[size]; // create a buffer
  1424. char *tempPath = new char[size]; // create a buffer
  1425. int ret;
  1426. // if the path passed in has quotes around it, first remove the quotes
  1427. if (path[0] == '"' && path[strlen(path)-1] == '"')
  1428. {
  1429. strcpy(tempPath,path+1);
  1430. tempPath[strlen(tempPath)-1] = '\0';
  1431. }
  1432. else
  1433. {
  1434. strcpy(tempPath,path);
  1435. }
  1436. buffer[0] = 0;
  1437. ret = GetShortPathName(tempPath, buffer, size);
  1438. if(buffer[0] == 0 || ret > size)
  1439. {
  1440. delete [] buffer;
  1441. delete [] tempPath;
  1442. return false;
  1443. }
  1444. else
  1445. {
  1446. shortPath = buffer;
  1447. delete [] buffer;
  1448. delete [] tempPath;
  1449. return true;
  1450. }
  1451. #else
  1452. shortPath = path;
  1453. return true;
  1454. #endif
  1455. }
  1456. bool SystemTools::SimpleGlob(const kwsys_std::string& glob,
  1457. kwsys_std::vector<kwsys_std::string>& files,
  1458. int type /* = 0 */)
  1459. {
  1460. files.clear();
  1461. if ( glob[glob.size()-1] != '*' )
  1462. {
  1463. return false;
  1464. }
  1465. kwsys_std::string path = SystemTools::GetFilenamePath(glob);
  1466. kwsys_std::string ppath = SystemTools::GetFilenameName(glob);
  1467. ppath = ppath.substr(0, ppath.size()-1);
  1468. if ( path.size() == 0 )
  1469. {
  1470. path = "/";
  1471. }
  1472. bool res = false;
  1473. Directory d;
  1474. if (d.Load(path.c_str()))
  1475. {
  1476. for (unsigned int i = 0; i < d.GetNumberOfFiles(); ++i)
  1477. {
  1478. if((kwsys_std::string(d.GetFile(i)) != ".")
  1479. && (kwsys_std::string(d.GetFile(i)) != ".."))
  1480. {
  1481. kwsys_std::string fname = path;
  1482. if ( path[path.size()-1] != '/' )
  1483. {
  1484. fname +="/";
  1485. }
  1486. fname += d.GetFile(i);
  1487. kwsys_std::string sfname = d.GetFile(i);
  1488. if ( type > 0 && SystemTools::FileIsDirectory(fname.c_str()) )
  1489. {
  1490. continue;
  1491. }
  1492. if ( type < 0 && !SystemTools::FileIsDirectory(fname.c_str()) )
  1493. {
  1494. continue;
  1495. }
  1496. if ( sfname.size() >= ppath.size() &&
  1497. sfname.substr(0, ppath.size()) ==
  1498. ppath )
  1499. {
  1500. files.push_back(fname);
  1501. res = true;
  1502. }
  1503. }
  1504. }
  1505. }
  1506. return res;
  1507. }
  1508. void SystemTools::SplitProgramFromArgs(const char* path,
  1509. kwsys_std::string& program, kwsys_std::string& args)
  1510. {
  1511. if(SystemTools::FileExists(path))
  1512. {
  1513. program = path;
  1514. args = "";
  1515. return;
  1516. }
  1517. kwsys_std::vector<kwsys_std::string> e;
  1518. kwsys_std::string findProg = SystemTools::FindProgram(path, e);
  1519. if(findProg.size())
  1520. {
  1521. program = findProg;
  1522. args = "";
  1523. return;
  1524. }
  1525. kwsys_std::string dir = path;
  1526. kwsys_std::string::size_type spacePos = dir.rfind(' ');
  1527. if(spacePos == kwsys_std::string::npos)
  1528. {
  1529. program = "";
  1530. args = "";
  1531. return;
  1532. }
  1533. while(spacePos != kwsys_std::string::npos)
  1534. {
  1535. kwsys_std::string tryProg = dir.substr(0, spacePos);
  1536. if(SystemTools::FileExists(tryProg.c_str()))
  1537. {
  1538. program = tryProg;
  1539. args = dir.substr(spacePos, dir.size()-spacePos);
  1540. return;
  1541. }
  1542. findProg = SystemTools::FindProgram(tryProg.c_str(), e);
  1543. if(findProg.size())
  1544. {
  1545. program = findProg;
  1546. args = dir.substr(spacePos, dir.size()-spacePos);
  1547. return;
  1548. }
  1549. spacePos = dir.rfind(' ', spacePos--);
  1550. }
  1551. program = "";
  1552. args = "";
  1553. }
  1554. kwsys_std::string SystemTools::GetCurrentDateTime(const char* format)
  1555. {
  1556. char buf[1024];
  1557. time_t t;
  1558. time(&t);
  1559. strftime(buf, sizeof(buf), format, localtime(&t));
  1560. return buf;
  1561. }
  1562. kwsys_std::string SystemTools::MakeCindentifier(const char* s)
  1563. {
  1564. kwsys_std::string str(s);
  1565. if (str.find_first_of("0123456789") == 0)
  1566. {
  1567. str = "_" + str;
  1568. }
  1569. kwsys_std::string permited_chars("_"
  1570. "abcdefghijklmnopqrstuvwxyz"
  1571. "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  1572. "0123456789");
  1573. kwsys_std::string::size_type pos = 0;
  1574. while ((pos = str.find_first_not_of(permited_chars, pos)) != kwsys_std::string::npos)
  1575. {
  1576. str[pos] = '_';
  1577. }
  1578. return str;
  1579. }
  1580. // Due to a buggy stream library on the HP and another on Mac OSX, we
  1581. // need this very carefully written version of getline. Returns true
  1582. // if any data were read before the end-of-file was reached.
  1583. bool SystemTools::GetLineFromStream(kwsys_std::istream& is, kwsys_std::string& line)
  1584. {
  1585. const int bufferSize = 1024;
  1586. char buffer[bufferSize];
  1587. line = "";
  1588. bool haveData = false;
  1589. // If no characters are read from the stream, the end of file has
  1590. // been reached.
  1591. while((is.getline(buffer, bufferSize), is.gcount() > 0))
  1592. {
  1593. haveData = true;
  1594. line.append(buffer);
  1595. // If newline character was read, the gcount includes the
  1596. // character, but the buffer does not. The end of line has been
  1597. // reached.
  1598. if(strlen(buffer) < static_cast<size_t>(is.gcount()))
  1599. {
  1600. break;
  1601. }
  1602. // The fail bit may be set. Clear it.
  1603. is.clear(is.rdstate() & ~kwsys_std::ios::failbit);
  1604. }
  1605. return haveData;
  1606. }
  1607. #if defined(_MSC_VER) && defined(_DEBUG)
  1608. # include <crtdbg.h>
  1609. # include <stdio.h>
  1610. # include <stdlib.h>
  1611. static int SystemToolsDebugReport(int, char* message, int*)
  1612. {
  1613. fprintf(stderr, message);
  1614. exit(1);
  1615. return 0;
  1616. }
  1617. void SystemTools::EnableMSVCDebugHook()
  1618. {
  1619. if(getenv("DART_TEST_FROM_DART"))
  1620. {
  1621. _CrtSetReportHook(SystemToolsDebugReport);
  1622. }
  1623. }
  1624. #else
  1625. void SystemTools::EnableMSVCDebugHook()
  1626. {
  1627. }
  1628. #endif
  1629. } // namespace KWSYS_NAMESPACE