1
0

testSystemTools.cxx 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
  3. #include "kwsysPrivate.h"
  4. #if defined(_MSC_VER)
  5. #pragma warning(disable : 4786)
  6. #endif
  7. #include KWSYS_HEADER(FStream.hxx)
  8. #include KWSYS_HEADER(SystemTools.hxx)
  9. // Work-around CMake dependency scanning limitation. This must
  10. // duplicate the above list of headers.
  11. #if 0
  12. #include "FStream.hxx.in"
  13. #include "SystemTools.hxx.in"
  14. #endif
  15. // Include with <> instead of "" to avoid getting any in-source copy
  16. // left on disk.
  17. #include <testSystemTools.h>
  18. #include <iostream>
  19. #include <sstream>
  20. #include <string.h> /* strcmp */
  21. #if defined(_WIN32) && !defined(__CYGWIN__)
  22. #include <io.h> /* _umask (MSVC) / umask (Borland) */
  23. #ifdef _MSC_VER
  24. #define umask _umask // Note this is still umask on Borland
  25. #endif
  26. #endif
  27. #include <sys/stat.h> /* umask (POSIX), _S_I* constants (Windows) */
  28. // Visual C++ does not define mode_t (note that Borland does, however).
  29. #if defined(_MSC_VER)
  30. typedef unsigned short mode_t;
  31. #endif
  32. static const char* toUnixPaths[][2] = {
  33. { "/usr/local/bin/passwd", "/usr/local/bin/passwd" },
  34. { "/usr/lo cal/bin/pa sswd", "/usr/lo cal/bin/pa sswd" },
  35. { "/usr/lo\\ cal/bin/pa\\ sswd", "/usr/lo\\ cal/bin/pa\\ sswd" },
  36. { "c:/usr/local/bin/passwd", "c:/usr/local/bin/passwd" },
  37. { "c:/usr/lo cal/bin/pa sswd", "c:/usr/lo cal/bin/pa sswd" },
  38. { "c:/usr/lo\\ cal/bin/pa\\ sswd", "c:/usr/lo\\ cal/bin/pa\\ sswd" },
  39. { "\\usr\\local\\bin\\passwd", "/usr/local/bin/passwd" },
  40. { "\\usr\\lo cal\\bin\\pa sswd", "/usr/lo cal/bin/pa sswd" },
  41. { "\\usr\\lo\\ cal\\bin\\pa\\ sswd", "/usr/lo\\ cal/bin/pa\\ sswd" },
  42. { "c:\\usr\\local\\bin\\passwd", "c:/usr/local/bin/passwd" },
  43. { "c:\\usr\\lo cal\\bin\\pa sswd", "c:/usr/lo cal/bin/pa sswd" },
  44. { "c:\\usr\\lo\\ cal\\bin\\pa\\ sswd", "c:/usr/lo\\ cal/bin/pa\\ sswd" },
  45. { "\\\\usr\\local\\bin\\passwd", "//usr/local/bin/passwd" },
  46. { "\\\\usr\\lo cal\\bin\\pa sswd", "//usr/lo cal/bin/pa sswd" },
  47. { "\\\\usr\\lo\\ cal\\bin\\pa\\ sswd", "//usr/lo\\ cal/bin/pa\\ sswd" },
  48. { 0, 0 }
  49. };
  50. static bool CheckConvertToUnixSlashes(std::string input, std::string output)
  51. {
  52. std::string result = input;
  53. kwsys::SystemTools::ConvertToUnixSlashes(result);
  54. if (result != output) {
  55. std::cerr << "Problem with ConvertToUnixSlashes - input: " << input
  56. << " output: " << result << " expected: " << output << std::endl;
  57. return false;
  58. }
  59. return true;
  60. }
  61. static const char* checkEscapeChars[][4] = { { "1 foo 2 bar 2", "12", "\\",
  62. "\\1 foo \\2 bar \\2" },
  63. { " {} ", "{}", "#", " #{#} " },
  64. { 0, 0, 0, 0 } };
  65. static bool CheckEscapeChars(std::string input, const char* chars_to_escape,
  66. char escape_char, std::string output)
  67. {
  68. std::string result = kwsys::SystemTools::EscapeChars(
  69. input.c_str(), chars_to_escape, escape_char);
  70. if (result != output) {
  71. std::cerr << "Problem with CheckEscapeChars - input: " << input
  72. << " output: " << result << " expected: " << output << std::endl;
  73. return false;
  74. }
  75. return true;
  76. }
  77. static bool CheckFileOperations()
  78. {
  79. bool res = true;
  80. const std::string testNonExistingFile(TEST_SYSTEMTOOLS_SOURCE_DIR
  81. "/testSystemToolsNonExistingFile");
  82. const std::string testDotFile(TEST_SYSTEMTOOLS_SOURCE_DIR "/.");
  83. const std::string testBinFile(TEST_SYSTEMTOOLS_SOURCE_DIR
  84. "/testSystemTools.bin");
  85. const std::string testTxtFile(TEST_SYSTEMTOOLS_SOURCE_DIR
  86. "/testSystemTools.cxx");
  87. const std::string testNewDir(TEST_SYSTEMTOOLS_BINARY_DIR
  88. "/testSystemToolsNewDir");
  89. const std::string testNewFile(testNewDir + "/testNewFile.txt");
  90. if (kwsys::SystemTools::DetectFileType(testNonExistingFile.c_str()) !=
  91. kwsys::SystemTools::FileTypeUnknown) {
  92. std::cerr << "Problem with DetectFileType - failed to detect type of: "
  93. << testNonExistingFile << std::endl;
  94. res = false;
  95. }
  96. if (kwsys::SystemTools::DetectFileType(testDotFile.c_str()) !=
  97. kwsys::SystemTools::FileTypeUnknown) {
  98. std::cerr << "Problem with DetectFileType - failed to detect type of: "
  99. << testDotFile << std::endl;
  100. res = false;
  101. }
  102. if (kwsys::SystemTools::DetectFileType(testBinFile.c_str()) !=
  103. kwsys::SystemTools::FileTypeBinary) {
  104. std::cerr << "Problem with DetectFileType - failed to detect type of: "
  105. << testBinFile << std::endl;
  106. res = false;
  107. }
  108. if (kwsys::SystemTools::DetectFileType(testTxtFile.c_str()) !=
  109. kwsys::SystemTools::FileTypeText) {
  110. std::cerr << "Problem with DetectFileType - failed to detect type of: "
  111. << testTxtFile << std::endl;
  112. res = false;
  113. }
  114. if (kwsys::SystemTools::FileLength(testBinFile) != 766) {
  115. std::cerr << "Problem with FileLength - incorrect length for: "
  116. << testBinFile << std::endl;
  117. res = false;
  118. }
  119. kwsys::SystemTools::Stat_t buf;
  120. if (kwsys::SystemTools::Stat(testTxtFile.c_str(), &buf) != 0) {
  121. std::cerr << "Problem with Stat - unable to stat text file: "
  122. << testTxtFile << std::endl;
  123. res = false;
  124. }
  125. if (kwsys::SystemTools::Stat(testBinFile, &buf) != 0) {
  126. std::cerr << "Problem with Stat - unable to stat bin file: " << testBinFile
  127. << std::endl;
  128. res = false;
  129. }
  130. if (!kwsys::SystemTools::MakeDirectory(testNewDir)) {
  131. std::cerr << "Problem with MakeDirectory for: " << testNewDir << std::endl;
  132. res = false;
  133. }
  134. // calling it again should just return true
  135. if (!kwsys::SystemTools::MakeDirectory(testNewDir)) {
  136. std::cerr << "Problem with second call to MakeDirectory for: "
  137. << testNewDir << std::endl;
  138. res = false;
  139. }
  140. // calling with 0 pointer should return false
  141. if (kwsys::SystemTools::MakeDirectory(0)) {
  142. std::cerr << "Problem with MakeDirectory(0)" << std::endl;
  143. res = false;
  144. }
  145. // calling with an empty string should return false
  146. if (kwsys::SystemTools::MakeDirectory(std::string())) {
  147. std::cerr << "Problem with MakeDirectory(std::string())" << std::endl;
  148. res = false;
  149. }
  150. // check existence
  151. if (!kwsys::SystemTools::FileExists(testNewDir.c_str(), false)) {
  152. std::cerr << "Problem with FileExists as C string and not file for: "
  153. << testNewDir << std::endl;
  154. res = false;
  155. }
  156. // check existence
  157. if (!kwsys::SystemTools::PathExists(testNewDir)) {
  158. std::cerr << "Problem with PathExists for: " << testNewDir << std::endl;
  159. res = false;
  160. }
  161. // remove it
  162. if (!kwsys::SystemTools::RemoveADirectory(testNewDir)) {
  163. std::cerr << "Problem with RemoveADirectory for: " << testNewDir
  164. << std::endl;
  165. res = false;
  166. }
  167. // check existence
  168. if (kwsys::SystemTools::FileExists(testNewDir.c_str(), false)) {
  169. std::cerr << "After RemoveADirectory: "
  170. << "Problem with FileExists as C string and not file for: "
  171. << testNewDir << std::endl;
  172. res = false;
  173. }
  174. // check existence
  175. if (kwsys::SystemTools::PathExists(testNewDir)) {
  176. std::cerr << "After RemoveADirectory: "
  177. << "Problem with PathExists for: " << testNewDir << std::endl;
  178. res = false;
  179. }
  180. // create it using the char* version
  181. if (!kwsys::SystemTools::MakeDirectory(testNewDir.c_str())) {
  182. std::cerr << "Problem with second call to MakeDirectory as C string for: "
  183. << testNewDir << std::endl;
  184. res = false;
  185. }
  186. if (!kwsys::SystemTools::Touch(testNewFile.c_str(), true)) {
  187. std::cerr << "Problem with Touch for: " << testNewFile << std::endl;
  188. res = false;
  189. }
  190. // calling MakeDirectory with something that is no file should fail
  191. if (kwsys::SystemTools::MakeDirectory(testNewFile)) {
  192. std::cerr << "Problem with to MakeDirectory for: " << testNewFile
  193. << std::endl;
  194. res = false;
  195. }
  196. // calling with 0 pointer should return false
  197. if (kwsys::SystemTools::FileExists(0)) {
  198. std::cerr << "Problem with FileExists(0)" << std::endl;
  199. res = false;
  200. }
  201. if (kwsys::SystemTools::FileExists(0, true)) {
  202. std::cerr << "Problem with FileExists(0) as file" << std::endl;
  203. res = false;
  204. }
  205. // calling with an empty string should return false
  206. if (kwsys::SystemTools::FileExists(std::string())) {
  207. std::cerr << "Problem with FileExists(std::string())" << std::endl;
  208. res = false;
  209. }
  210. // FileExists(x, true) should return false on a directory
  211. if (kwsys::SystemTools::FileExists(testNewDir, true)) {
  212. std::cerr << "Problem with FileExists as file for: " << testNewDir
  213. << std::endl;
  214. res = false;
  215. }
  216. if (kwsys::SystemTools::FileExists(testNewDir.c_str(), true)) {
  217. std::cerr << "Problem with FileExists as C string and file for: "
  218. << testNewDir << std::endl;
  219. res = false;
  220. }
  221. // FileExists(x, false) should return true even on a directory
  222. if (!kwsys::SystemTools::FileExists(testNewDir, false)) {
  223. std::cerr << "Problem with FileExists as not file for: " << testNewDir
  224. << std::endl;
  225. res = false;
  226. }
  227. if (!kwsys::SystemTools::FileExists(testNewDir.c_str(), false)) {
  228. std::cerr << "Problem with FileExists as C string and not file for: "
  229. << testNewDir << std::endl;
  230. res = false;
  231. }
  232. // should work, was created as new file before
  233. if (!kwsys::SystemTools::FileExists(testNewFile)) {
  234. std::cerr << "Problem with FileExists for: " << testNewDir << std::endl;
  235. res = false;
  236. }
  237. if (!kwsys::SystemTools::FileExists(testNewFile.c_str())) {
  238. std::cerr << "Problem with FileExists as C string for: " << testNewDir
  239. << std::endl;
  240. res = false;
  241. }
  242. if (!kwsys::SystemTools::FileExists(testNewFile, true)) {
  243. std::cerr << "Problem with FileExists as file for: " << testNewDir
  244. << std::endl;
  245. res = false;
  246. }
  247. if (!kwsys::SystemTools::FileExists(testNewFile.c_str(), true)) {
  248. std::cerr << "Problem with FileExists as C string and file for: "
  249. << testNewDir << std::endl;
  250. res = false;
  251. }
  252. // calling with an empty string should return false
  253. if (kwsys::SystemTools::PathExists(std::string())) {
  254. std::cerr << "Problem with PathExists(std::string())" << std::endl;
  255. res = false;
  256. }
  257. // PathExists(x) should return true on a directory
  258. if (!kwsys::SystemTools::PathExists(testNewDir)) {
  259. std::cerr << "Problem with PathExists for: " << testNewDir << std::endl;
  260. res = false;
  261. }
  262. // should work, was created as new file before
  263. if (!kwsys::SystemTools::PathExists(testNewFile)) {
  264. std::cerr << "Problem with PathExists for: " << testNewDir << std::endl;
  265. res = false;
  266. }
  267. // Reset umask
  268. #if defined(_WIN32) && !defined(__CYGWIN__)
  269. // NOTE: Windows doesn't support toggling _S_IREAD.
  270. mode_t fullMask = _S_IWRITE;
  271. #else
  272. // On a normal POSIX platform, we can toggle all permissions.
  273. mode_t fullMask = S_IRWXU | S_IRWXG | S_IRWXO;
  274. #endif
  275. mode_t orig_umask = umask(fullMask);
  276. // Test file permissions without umask
  277. mode_t origPerm, thisPerm;
  278. if (!kwsys::SystemTools::GetPermissions(testNewFile, origPerm)) {
  279. std::cerr << "Problem with GetPermissions (1) for: " << testNewFile
  280. << std::endl;
  281. res = false;
  282. }
  283. if (!kwsys::SystemTools::SetPermissions(testNewFile, 0)) {
  284. std::cerr << "Problem with SetPermissions (1) for: " << testNewFile
  285. << std::endl;
  286. res = false;
  287. }
  288. if (!kwsys::SystemTools::GetPermissions(testNewFile, thisPerm)) {
  289. std::cerr << "Problem with GetPermissions (2) for: " << testNewFile
  290. << std::endl;
  291. res = false;
  292. }
  293. if ((thisPerm & fullMask) != 0) {
  294. std::cerr << "SetPermissions failed to set permissions (1) for: "
  295. << testNewFile << ": actual = " << thisPerm
  296. << "; expected = " << 0 << std::endl;
  297. res = false;
  298. }
  299. // While we're at it, check proper TestFileAccess functionality.
  300. if (kwsys::SystemTools::TestFileAccess(testNewFile,
  301. kwsys::TEST_FILE_WRITE)) {
  302. std::cerr
  303. << "TestFileAccess incorrectly indicated that this is a writable file:"
  304. << testNewFile << std::endl;
  305. res = false;
  306. }
  307. if (!kwsys::SystemTools::TestFileAccess(testNewFile, kwsys::TEST_FILE_OK)) {
  308. std::cerr
  309. << "TestFileAccess incorrectly indicated that this file does not exist:"
  310. << testNewFile << std::endl;
  311. res = false;
  312. }
  313. // Test restoring/setting full permissions.
  314. if (!kwsys::SystemTools::SetPermissions(testNewFile, fullMask)) {
  315. std::cerr << "Problem with SetPermissions (2) for: " << testNewFile
  316. << std::endl;
  317. res = false;
  318. }
  319. if (!kwsys::SystemTools::GetPermissions(testNewFile, thisPerm)) {
  320. std::cerr << "Problem with GetPermissions (3) for: " << testNewFile
  321. << std::endl;
  322. res = false;
  323. }
  324. if ((thisPerm & fullMask) != fullMask) {
  325. std::cerr << "SetPermissions failed to set permissions (2) for: "
  326. << testNewFile << ": actual = " << thisPerm
  327. << "; expected = " << fullMask << std::endl;
  328. res = false;
  329. }
  330. // Test setting file permissions while honoring umask
  331. if (!kwsys::SystemTools::SetPermissions(testNewFile, fullMask, true)) {
  332. std::cerr << "Problem with SetPermissions (3) for: " << testNewFile
  333. << std::endl;
  334. res = false;
  335. }
  336. if (!kwsys::SystemTools::GetPermissions(testNewFile, thisPerm)) {
  337. std::cerr << "Problem with GetPermissions (4) for: " << testNewFile
  338. << std::endl;
  339. res = false;
  340. }
  341. if ((thisPerm & fullMask) != 0) {
  342. std::cerr << "SetPermissions failed to honor umask for: " << testNewFile
  343. << ": actual = " << thisPerm << "; expected = " << 0
  344. << std::endl;
  345. res = false;
  346. }
  347. // Restore umask
  348. umask(orig_umask);
  349. // Restore file permissions
  350. if (!kwsys::SystemTools::SetPermissions(testNewFile, origPerm)) {
  351. std::cerr << "Problem with SetPermissions (4) for: " << testNewFile
  352. << std::endl;
  353. res = false;
  354. }
  355. // Remove the test file
  356. if (!kwsys::SystemTools::RemoveFile(testNewFile)) {
  357. std::cerr << "Problem with RemoveFile: " << testNewFile << std::endl;
  358. res = false;
  359. }
  360. std::string const testFileMissing(testNewDir + "/testMissingFile.txt");
  361. if (!kwsys::SystemTools::RemoveFile(testFileMissing)) {
  362. std::string const& msg = kwsys::SystemTools::GetLastSystemError();
  363. std::cerr << "RemoveFile(\"" << testFileMissing << "\") failed: " << msg
  364. << "\n";
  365. res = false;
  366. }
  367. std::string const testFileMissingDir(testNewDir + "/missing/file.txt");
  368. if (!kwsys::SystemTools::RemoveFile(testFileMissingDir)) {
  369. std::string const& msg = kwsys::SystemTools::GetLastSystemError();
  370. std::cerr << "RemoveFile(\"" << testFileMissingDir << "\") failed: " << msg
  371. << "\n";
  372. res = false;
  373. }
  374. kwsys::SystemTools::Touch(testNewFile.c_str(), true);
  375. if (!kwsys::SystemTools::RemoveADirectory(testNewDir)) {
  376. std::cerr << "Problem with RemoveADirectory for: " << testNewDir
  377. << std::endl;
  378. res = false;
  379. }
  380. #ifdef KWSYS_TEST_SYSTEMTOOLS_LONG_PATHS
  381. // Perform the same file and directory creation and deletion tests but
  382. // with paths > 256 characters in length.
  383. const std::string testNewLongDir(
  384. TEST_SYSTEMTOOLS_BINARY_DIR
  385. "/"
  386. "012345678901234567890123456789012345678901234567890123456789"
  387. "012345678901234567890123456789012345678901234567890123456789"
  388. "012345678901234567890123456789012345678901234567890123456789"
  389. "012345678901234567890123456789012345678901234567890123456789"
  390. "01234567890123");
  391. const std::string testNewLongFile(
  392. testNewLongDir +
  393. "/"
  394. "012345678901234567890123456789012345678901234567890123456789"
  395. "012345678901234567890123456789012345678901234567890123456789"
  396. "012345678901234567890123456789012345678901234567890123456789"
  397. "012345678901234567890123456789012345678901234567890123456789"
  398. "0123456789.txt");
  399. if (!kwsys::SystemTools::MakeDirectory(testNewLongDir)) {
  400. std::cerr << "Problem with MakeDirectory for: " << testNewLongDir
  401. << std::endl;
  402. res = false;
  403. }
  404. if (!kwsys::SystemTools::Touch(testNewLongFile.c_str(), true)) {
  405. std::cerr << "Problem with Touch for: " << testNewLongFile << std::endl;
  406. res = false;
  407. }
  408. if (!kwsys::SystemTools::RemoveFile(testNewLongFile)) {
  409. std::cerr << "Problem with RemoveFile: " << testNewLongFile << std::endl;
  410. res = false;
  411. }
  412. kwsys::SystemTools::Touch(testNewLongFile.c_str(), true);
  413. if (!kwsys::SystemTools::RemoveADirectory(testNewLongDir)) {
  414. std::cerr << "Problem with RemoveADirectory for: " << testNewLongDir
  415. << std::endl;
  416. res = false;
  417. }
  418. #endif
  419. return res;
  420. }
  421. static bool CheckStringOperations()
  422. {
  423. bool res = true;
  424. std::string test = "mary had a little lamb.";
  425. if (kwsys::SystemTools::CapitalizedWords(test) !=
  426. "Mary Had A Little Lamb.") {
  427. std::cerr << "Problem with CapitalizedWords " << '"' << test << '"'
  428. << std::endl;
  429. res = false;
  430. }
  431. test = "Mary Had A Little Lamb.";
  432. if (kwsys::SystemTools::UnCapitalizedWords(test) !=
  433. "mary had a little lamb.") {
  434. std::cerr << "Problem with UnCapitalizedWords " << '"' << test << '"'
  435. << std::endl;
  436. res = false;
  437. }
  438. test = "MaryHadTheLittleLamb.";
  439. if (kwsys::SystemTools::AddSpaceBetweenCapitalizedWords(test) !=
  440. "Mary Had The Little Lamb.") {
  441. std::cerr << "Problem with AddSpaceBetweenCapitalizedWords " << '"' << test
  442. << '"' << std::endl;
  443. res = false;
  444. }
  445. char* cres =
  446. kwsys::SystemTools::AppendStrings("Mary Had A", " Little Lamb.");
  447. if (strcmp(cres, "Mary Had A Little Lamb.")) {
  448. std::cerr << "Problem with AppendStrings "
  449. << "\"Mary Had A\" \" Little Lamb.\"" << std::endl;
  450. res = false;
  451. }
  452. delete[] cres;
  453. cres = kwsys::SystemTools::AppendStrings("Mary Had", " A ", "Little Lamb.");
  454. if (strcmp(cres, "Mary Had A Little Lamb.")) {
  455. std::cerr << "Problem with AppendStrings "
  456. << "\"Mary Had\" \" A \" \"Little Lamb.\"" << std::endl;
  457. res = false;
  458. }
  459. delete[] cres;
  460. if (kwsys::SystemTools::CountChar("Mary Had A Little Lamb.", 'a') != 3) {
  461. std::cerr << "Problem with CountChar "
  462. << "\"Mary Had A Little Lamb.\"" << std::endl;
  463. res = false;
  464. }
  465. cres = kwsys::SystemTools::RemoveChars("Mary Had A Little Lamb.", "aeiou");
  466. if (strcmp(cres, "Mry Hd A Lttl Lmb.")) {
  467. std::cerr << "Problem with RemoveChars "
  468. << "\"Mary Had A Little Lamb.\"" << std::endl;
  469. res = false;
  470. }
  471. delete[] cres;
  472. cres = kwsys::SystemTools::RemoveCharsButUpperHex("Mary Had A Little Lamb.");
  473. if (strcmp(cres, "A")) {
  474. std::cerr << "Problem with RemoveCharsButUpperHex "
  475. << "\"Mary Had A Little Lamb.\"" << std::endl;
  476. res = false;
  477. }
  478. delete[] cres;
  479. char* cres2 = new char[strlen("Mary Had A Little Lamb.") + 1];
  480. strcpy(cres2, "Mary Had A Little Lamb.");
  481. kwsys::SystemTools::ReplaceChars(cres2, "aeiou", 'X');
  482. if (strcmp(cres2, "MXry HXd A LXttlX LXmb.")) {
  483. std::cerr << "Problem with ReplaceChars "
  484. << "\"Mary Had A Little Lamb.\"" << std::endl;
  485. res = false;
  486. }
  487. delete[] cres2;
  488. if (!kwsys::SystemTools::StringStartsWith("Mary Had A Little Lamb.",
  489. "Mary ")) {
  490. std::cerr << "Problem with StringStartsWith "
  491. << "\"Mary Had A Little Lamb.\"" << std::endl;
  492. res = false;
  493. }
  494. if (!kwsys::SystemTools::StringEndsWith("Mary Had A Little Lamb.",
  495. " Lamb.")) {
  496. std::cerr << "Problem with StringEndsWith "
  497. << "\"Mary Had A Little Lamb.\"" << std::endl;
  498. res = false;
  499. }
  500. cres = kwsys::SystemTools::DuplicateString("Mary Had A Little Lamb.");
  501. if (strcmp(cres, "Mary Had A Little Lamb.")) {
  502. std::cerr << "Problem with DuplicateString "
  503. << "\"Mary Had A Little Lamb.\"" << std::endl;
  504. res = false;
  505. }
  506. delete[] cres;
  507. test = "Mary Had A Little Lamb.";
  508. if (kwsys::SystemTools::CropString(test, 13) != "Mary ...Lamb.") {
  509. std::cerr << "Problem with CropString "
  510. << "\"Mary Had A Little Lamb.\"" << std::endl;
  511. res = false;
  512. }
  513. std::vector<std::string> lines;
  514. kwsys::SystemTools::Split("Mary Had A Little Lamb.", lines, ' ');
  515. if (lines[0] != "Mary" || lines[1] != "Had" || lines[2] != "A" ||
  516. lines[3] != "Little" || lines[4] != "Lamb.") {
  517. std::cerr << "Problem with Split "
  518. << "\"Mary Had A Little Lamb.\"" << std::endl;
  519. res = false;
  520. }
  521. if (kwsys::SystemTools::ConvertToWindowsOutputPath(
  522. "L://Local Mojo/Hex Power Pack/Iffy Voodoo") !=
  523. "\"L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\"") {
  524. std::cerr << "Problem with ConvertToWindowsOutputPath "
  525. << "\"L://Local Mojo/Hex Power Pack/Iffy Voodoo\"" << std::endl;
  526. res = false;
  527. }
  528. if (kwsys::SystemTools::ConvertToWindowsOutputPath(
  529. "//grayson/Local Mojo/Hex Power Pack/Iffy Voodoo") !=
  530. "\"\\\\grayson\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\"") {
  531. std::cerr << "Problem with ConvertToWindowsOutputPath "
  532. << "\"//grayson/Local Mojo/Hex Power Pack/Iffy Voodoo\""
  533. << std::endl;
  534. res = false;
  535. }
  536. if (kwsys::SystemTools::ConvertToUnixOutputPath(
  537. "//Local Mojo/Hex Power Pack/Iffy Voodoo") !=
  538. "//Local\\ Mojo/Hex\\ Power\\ Pack/Iffy\\ Voodoo") {
  539. std::cerr << "Problem with ConvertToUnixOutputPath "
  540. << "\"//Local Mojo/Hex Power Pack/Iffy Voodoo\"" << std::endl;
  541. res = false;
  542. }
  543. return res;
  544. }
  545. static bool CheckPutEnv(const std::string& env, const char* name,
  546. const char* value)
  547. {
  548. if (!kwsys::SystemTools::PutEnv(env)) {
  549. std::cerr << "PutEnv(\"" << env << "\") failed!" << std::endl;
  550. return false;
  551. }
  552. std::string v = "(null)";
  553. kwsys::SystemTools::GetEnv(name, v);
  554. if (v != value) {
  555. std::cerr << "GetEnv(\"" << name << "\") returned \"" << v << "\", not \""
  556. << value << "\"!" << std::endl;
  557. return false;
  558. }
  559. return true;
  560. }
  561. static bool CheckUnPutEnv(const char* env, const char* name)
  562. {
  563. if (!kwsys::SystemTools::UnPutEnv(env)) {
  564. std::cerr << "UnPutEnv(\"" << env << "\") failed!" << std::endl;
  565. return false;
  566. }
  567. std::string v;
  568. if (kwsys::SystemTools::GetEnv(name, v)) {
  569. std::cerr << "GetEnv(\"" << name << "\") returned \"" << v
  570. << "\", not (null)!" << std::endl;
  571. return false;
  572. }
  573. return true;
  574. }
  575. static bool CheckEnvironmentOperations()
  576. {
  577. bool res = true;
  578. res &= CheckPutEnv("A=B", "A", "B");
  579. res &= CheckPutEnv("B=C", "B", "C");
  580. res &= CheckPutEnv("C=D", "C", "D");
  581. res &= CheckPutEnv("D=E", "D", "E");
  582. res &= CheckUnPutEnv("A", "A");
  583. res &= CheckUnPutEnv("B=", "B");
  584. res &= CheckUnPutEnv("C=D", "C");
  585. /* Leave "D=E" in environment so a memory checker can test for leaks. */
  586. return res;
  587. }
  588. static bool CheckRelativePath(const std::string& local,
  589. const std::string& remote,
  590. const std::string& expected)
  591. {
  592. std::string result = kwsys::SystemTools::RelativePath(local, remote);
  593. if (!kwsys::SystemTools::ComparePath(expected, result)) {
  594. std::cerr << "RelativePath(" << local << ", " << remote << ") yielded "
  595. << result << " instead of " << expected << std::endl;
  596. return false;
  597. }
  598. return true;
  599. }
  600. static bool CheckRelativePaths()
  601. {
  602. bool res = true;
  603. res &= CheckRelativePath("/usr/share", "/bin/bash", "../../bin/bash");
  604. res &= CheckRelativePath("/usr/./share/", "/bin/bash", "../../bin/bash");
  605. res &= CheckRelativePath("/usr//share/", "/bin/bash", "../../bin/bash");
  606. res &=
  607. CheckRelativePath("/usr/share/../bin/", "/bin/bash", "../../bin/bash");
  608. res &= CheckRelativePath("/usr/share", "/usr/share//bin", "bin");
  609. return res;
  610. }
  611. static bool CheckCollapsePath(const std::string& path,
  612. const std::string& expected)
  613. {
  614. std::string result = kwsys::SystemTools::CollapseFullPath(path);
  615. if (!kwsys::SystemTools::ComparePath(expected, result)) {
  616. std::cerr << "CollapseFullPath(" << path << ") yielded " << result
  617. << " instead of " << expected << std::endl;
  618. return false;
  619. }
  620. return true;
  621. }
  622. static bool CheckCollapsePath()
  623. {
  624. bool res = true;
  625. res &= CheckCollapsePath("/usr/share/*", "/usr/share/*");
  626. res &= CheckCollapsePath("C:/Windows/*", "C:/Windows/*");
  627. return res;
  628. }
  629. static std::string StringVectorToString(const std::vector<std::string>& vec)
  630. {
  631. std::stringstream ss;
  632. ss << "vector(";
  633. for (std::vector<std::string>::const_iterator i = vec.begin();
  634. i != vec.end(); ++i) {
  635. if (i != vec.begin()) {
  636. ss << ", ";
  637. }
  638. ss << *i;
  639. }
  640. ss << ")";
  641. return ss.str();
  642. }
  643. static bool CheckGetPath()
  644. {
  645. const char* envName = "S";
  646. #ifdef _WIN32
  647. const char* envValue = "C:\\Somewhere\\something;D:\\Temp";
  648. #else
  649. const char* envValue = "/Somewhere/something:/tmp";
  650. #endif
  651. const char* registryPath = "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MyApp; MyKey]";
  652. std::vector<std::string> originalPathes;
  653. originalPathes.push_back(registryPath);
  654. std::vector<std::string> expectedPathes;
  655. expectedPathes.push_back(registryPath);
  656. #ifdef _WIN32
  657. expectedPathes.push_back("C:/Somewhere/something");
  658. expectedPathes.push_back("D:/Temp");
  659. #else
  660. expectedPathes.push_back("/Somewhere/something");
  661. expectedPathes.push_back("/tmp");
  662. #endif
  663. bool res = true;
  664. res &= CheckPutEnv(std::string(envName) + "=" + envValue, envName, envValue);
  665. std::vector<std::string> pathes = originalPathes;
  666. kwsys::SystemTools::GetPath(pathes, envName);
  667. if (pathes != expectedPathes) {
  668. std::cerr << "GetPath(" << StringVectorToString(originalPathes) << ", "
  669. << envName << ") yielded " << StringVectorToString(pathes)
  670. << " instead of " << StringVectorToString(expectedPathes)
  671. << std::endl;
  672. res = false;
  673. }
  674. res &= CheckUnPutEnv(envName, envName);
  675. return res;
  676. }
  677. static bool CheckFind()
  678. {
  679. bool res = true;
  680. const std::string testFindFileName("testFindFile.txt");
  681. const std::string testFindFile(TEST_SYSTEMTOOLS_BINARY_DIR "/" +
  682. testFindFileName);
  683. if (!kwsys::SystemTools::Touch(testFindFile.c_str(), true)) {
  684. std::cerr << "Problem with Touch for: " << testFindFile << std::endl;
  685. // abort here as the existence of the file only makes the test meaningful
  686. return false;
  687. }
  688. std::vector<std::string> searchPaths;
  689. searchPaths.push_back(TEST_SYSTEMTOOLS_BINARY_DIR);
  690. if (kwsys::SystemTools::FindFile(testFindFileName, searchPaths, true)
  691. .empty()) {
  692. std::cerr << "Problem with FindFile without system paths for: "
  693. << testFindFileName << std::endl;
  694. res = false;
  695. }
  696. if (kwsys::SystemTools::FindFile(testFindFileName, searchPaths, false)
  697. .empty()) {
  698. std::cerr << "Problem with FindFile with system paths for: "
  699. << testFindFileName << std::endl;
  700. res = false;
  701. }
  702. return res;
  703. }
  704. static bool CheckGetLineFromStream()
  705. {
  706. const std::string fileWithFiveCharsOnFirstLine(TEST_SYSTEMTOOLS_SOURCE_DIR
  707. "/README.rst");
  708. kwsys::ifstream file(fileWithFiveCharsOnFirstLine.c_str(), std::ios::in);
  709. if (!file) {
  710. std::cerr << "Problem opening: " << fileWithFiveCharsOnFirstLine
  711. << std::endl;
  712. return false;
  713. }
  714. std::string line;
  715. bool has_newline = false;
  716. bool result;
  717. file.seekg(0, std::ios::beg);
  718. result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline, -1);
  719. if (!result || line.size() != 5) {
  720. std::cerr << "First line does not have five characters: " << line.size()
  721. << std::endl;
  722. return false;
  723. }
  724. file.seekg(0, std::ios::beg);
  725. result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline, -1);
  726. if (!result || line.size() != 5) {
  727. std::cerr << "First line does not have five characters after rewind: "
  728. << line.size() << std::endl;
  729. return false;
  730. }
  731. bool ret = true;
  732. for (size_t size = 1; size <= 5; ++size) {
  733. file.seekg(0, std::ios::beg);
  734. result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline,
  735. static_cast<long>(size));
  736. if (!result || line.size() != size) {
  737. std::cerr << "Should have read " << size << " characters but got "
  738. << line.size() << std::endl;
  739. ret = false;
  740. }
  741. }
  742. return ret;
  743. }
  744. int testSystemTools(int, char* [])
  745. {
  746. bool res = true;
  747. int cc;
  748. for (cc = 0; toUnixPaths[cc][0]; cc++) {
  749. res &= CheckConvertToUnixSlashes(toUnixPaths[cc][0], toUnixPaths[cc][1]);
  750. }
  751. // Special check for ~
  752. std::string output;
  753. if (kwsys::SystemTools::GetEnv("HOME", output)) {
  754. output += "/foo bar/lala";
  755. res &= CheckConvertToUnixSlashes("~/foo bar/lala", output);
  756. }
  757. for (cc = 0; checkEscapeChars[cc][0]; cc++) {
  758. res &= CheckEscapeChars(checkEscapeChars[cc][0], checkEscapeChars[cc][1],
  759. *checkEscapeChars[cc][2], checkEscapeChars[cc][3]);
  760. }
  761. res &= CheckFileOperations();
  762. res &= CheckStringOperations();
  763. res &= CheckEnvironmentOperations();
  764. res &= CheckRelativePaths();
  765. res &= CheckCollapsePath();
  766. res &= CheckGetPath();
  767. res &= CheckFind();
  768. res &= CheckGetLineFromStream();
  769. return res ? 0 : 1;
  770. }