cmSystemTools.cxx 58 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354
  1. /*=========================================================================
  2. Program: CMake - Cross-Platform Makefile Generator
  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 Copyright.txt or 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. #include "cmSystemTools.h"
  14. #include <stdio.h>
  15. #include <sys/stat.h>
  16. #include "cmRegularExpression.h"
  17. #include <ctype.h>
  18. #include "cmDirectory.h"
  19. #include <errno.h>
  20. // support for realpath call
  21. #ifndef _WIN32
  22. #include <limits.h>
  23. #include <stdlib.h>
  24. #include <sys/param.h>
  25. #include <sys/wait.h>
  26. #endif
  27. #if defined(_WIN32) && (defined(_MSC_VER) || defined(__BORLANDC__))
  28. #include <string.h>
  29. #include <windows.h>
  30. #include <direct.h>
  31. #define _unlink unlink
  32. inline int Mkdir(const char* dir)
  33. {
  34. return _mkdir(dir);
  35. }
  36. inline const char* Getcwd(char* buf, unsigned int len)
  37. {
  38. return _getcwd(buf, len);
  39. }
  40. inline int Chdir(const char* dir)
  41. {
  42. #if defined(__BORLANDC__)
  43. return chdir(dir);
  44. #else
  45. return _chdir(dir);
  46. #endif
  47. }
  48. #else
  49. #include <sys/types.h>
  50. #include <fcntl.h>
  51. #include <unistd.h>
  52. inline int Mkdir(const char* dir)
  53. {
  54. return mkdir(dir, 00777);
  55. }
  56. inline const char* Getcwd(char* buf, unsigned int len)
  57. {
  58. return getcwd(buf, len);
  59. }
  60. inline int Chdir(const char* dir)
  61. {
  62. return chdir(dir);
  63. }
  64. #endif
  65. /* Implement floattime() for various platforms */
  66. // Taken from Python 2.1.3
  67. #if defined( _WIN32 ) && !defined( __CYGWIN__ )
  68. # include <sys/timeb.h>
  69. # define HAVE_FTIME
  70. # if defined( __BORLANDC__)
  71. # define FTIME ftime
  72. # define TIMEB timeb
  73. # else // Visual studio?
  74. # define FTIME _ftime
  75. # define TIMEB _timeb
  76. # endif
  77. #elif defined( __CYGWIN__ ) || defined( __linux__ )
  78. # include <sys/time.h>
  79. # include <time.h>
  80. # define HAVE_GETTIMEOFDAY
  81. #endif
  82. double
  83. cmSystemTools::GetTime(void)
  84. {
  85. /* There are three ways to get the time:
  86. (1) gettimeofday() -- resolution in microseconds
  87. (2) ftime() -- resolution in milliseconds
  88. (3) time() -- resolution in seconds
  89. In all cases the return value is a float in seconds.
  90. Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may
  91. fail, so we fall back on ftime() or time().
  92. Note: clock resolution does not imply clock accuracy! */
  93. #ifdef HAVE_GETTIMEOFDAY
  94. {
  95. struct timeval t;
  96. #ifdef GETTIMEOFDAY_NO_TZ
  97. if (gettimeofday(&t) == 0)
  98. return (double)t.tv_sec + t.tv_usec*0.000001;
  99. #else /* !GETTIMEOFDAY_NO_TZ */
  100. if (gettimeofday(&t, (struct timezone *)NULL) == 0)
  101. return (double)t.tv_sec + t.tv_usec*0.000001;
  102. #endif /* !GETTIMEOFDAY_NO_TZ */
  103. }
  104. #endif /* !HAVE_GETTIMEOFDAY */
  105. {
  106. #if defined(HAVE_FTIME)
  107. struct TIMEB t;
  108. FTIME(&t);
  109. return (double)t.time + (double)t.millitm * (double)0.001;
  110. #else /* !HAVE_FTIME */
  111. time_t secs;
  112. time(&secs);
  113. return (double)secs;
  114. #endif /* !HAVE_FTIME */
  115. }
  116. }
  117. bool cmSystemTools::s_RunCommandHideConsole = false;
  118. bool cmSystemTools::s_DisableRunCommandOutput = false;
  119. bool cmSystemTools::s_ErrorOccured = false;
  120. bool cmSystemTools::s_FatalErrorOccured = false;
  121. bool cmSystemTools::s_DisableMessages = false;
  122. std::string cmSystemTools::s_Windows9xComspecSubstitute = "command.com";
  123. void cmSystemTools::SetWindows9xComspecSubstitute(const char* str)
  124. {
  125. if ( str )
  126. {
  127. cmSystemTools::s_Windows9xComspecSubstitute = str;
  128. }
  129. }
  130. const char* cmSystemTools::GetWindows9xComspecSubstitute()
  131. {
  132. return cmSystemTools::s_Windows9xComspecSubstitute.c_str();
  133. }
  134. void (*cmSystemTools::s_ErrorCallback)(const char*, const char*, bool&, void*);
  135. void* cmSystemTools::s_ErrorCallbackClientData = 0;
  136. // adds the elements of the env variable path to the arg passed in
  137. void cmSystemTools::GetPath(std::vector<std::string>& path)
  138. {
  139. #if defined(_WIN32) && !defined(__CYGWIN__)
  140. const char* pathSep = ";";
  141. #else
  142. const char* pathSep = ":";
  143. #endif
  144. std::string pathEnv = getenv("PATH");
  145. // A hack to make the below algorithm work.
  146. if(pathEnv[pathEnv.length()-1] != ':')
  147. {
  148. pathEnv += pathSep;
  149. }
  150. std::string::size_type start =0;
  151. bool done = false;
  152. while(!done)
  153. {
  154. std::string::size_type endpos = pathEnv.find(pathSep, start);
  155. if(endpos != std::string::npos)
  156. {
  157. path.push_back(pathEnv.substr(start, endpos-start));
  158. start = endpos+1;
  159. }
  160. else
  161. {
  162. done = true;
  163. }
  164. }
  165. for(std::vector<std::string>::iterator i = path.begin();
  166. i != path.end(); ++i)
  167. {
  168. cmSystemTools::ConvertToUnixSlashes(*i);
  169. }
  170. }
  171. const char* cmSystemTools::GetExecutableExtension()
  172. {
  173. #if defined(_WIN32) || defined(__CYGWIN__)
  174. return ".exe";
  175. #else
  176. return "";
  177. #endif
  178. }
  179. bool cmSystemTools::MakeDirectory(const char* path)
  180. {
  181. if(cmSystemTools::FileExists(path))
  182. {
  183. return true;
  184. }
  185. std::string dir = path;
  186. if(dir.size() == 0)
  187. {
  188. return false;
  189. }
  190. cmSystemTools::ConvertToUnixSlashes(dir);
  191. std::string::size_type pos = dir.find(':');
  192. if(pos == std::string::npos)
  193. {
  194. pos = 0;
  195. }
  196. std::string topdir;
  197. while((pos = dir.find('/', pos)) != std::string::npos)
  198. {
  199. topdir = dir.substr(0, pos);
  200. Mkdir(topdir.c_str());
  201. pos++;
  202. }
  203. if(dir[dir.size()-1] == '/')
  204. {
  205. topdir = dir.substr(0, dir.size());
  206. }
  207. else
  208. {
  209. topdir = dir;
  210. }
  211. if(Mkdir(topdir.c_str()) != 0)
  212. {
  213. // There is a bug in the Borland Run time library which makes MKDIR
  214. // return EACCES when it should return EEXISTS
  215. // if it is some other error besides directory exists
  216. // then return false
  217. if( (errno != EEXIST)
  218. #ifdef __BORLANDC__
  219. && (errno != EACCES)
  220. #endif
  221. )
  222. {
  223. cmSystemTools::Error("Faild to create directory:", path);
  224. return false;
  225. }
  226. }
  227. return true;
  228. }
  229. // replace replace with with as many times as it shows up in source.
  230. // write the result into source.
  231. void cmSystemTools::ReplaceString(std::string& source,
  232. const char* replace,
  233. const char* with)
  234. {
  235. // get out quick if string is not found
  236. std::string::size_type start = source.find(replace);
  237. if(start == std::string::npos)
  238. {
  239. return;
  240. }
  241. std::string rest;
  242. std::string::size_type lengthReplace = strlen(replace);
  243. std::string::size_type lengthWith = strlen(with);
  244. while(start != std::string::npos)
  245. {
  246. rest = source.substr(start+lengthReplace);
  247. source = source.substr(0, start);
  248. source += with;
  249. source += rest;
  250. start = source.find(replace, start + lengthWith );
  251. }
  252. }
  253. // Read a registry value.
  254. // Example :
  255. // HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore\2.1\InstallPath
  256. // => will return the data of the "default" value of the key
  257. // HKEY_LOCAL_MACHINE\SOFTWARE\Scriptics\Tcl\8.4;Root
  258. // => will return the data of the "Root" value of the key
  259. #if defined(_WIN32) && !defined(__CYGWIN__)
  260. bool cmSystemTools::ReadRegistryValue(const char *key, std::string &value)
  261. {
  262. std::string primary = key;
  263. std::string second;
  264. std::string valuename;
  265. size_t start = primary.find("\\");
  266. if (start == std::string::npos)
  267. {
  268. return false;
  269. }
  270. size_t valuenamepos = primary.find(";");
  271. if (valuenamepos != std::string::npos)
  272. {
  273. valuename = primary.substr(valuenamepos+1);
  274. }
  275. second = primary.substr(start+1, valuenamepos-start-1);
  276. primary = primary.substr(0, start);
  277. HKEY primaryKey;
  278. if (primary == "HKEY_CURRENT_USER")
  279. {
  280. primaryKey = HKEY_CURRENT_USER;
  281. }
  282. if (primary == "HKEY_CURRENT_CONFIG")
  283. {
  284. primaryKey = HKEY_CURRENT_CONFIG;
  285. }
  286. if (primary == "HKEY_CLASSES_ROOT")
  287. {
  288. primaryKey = HKEY_CLASSES_ROOT;
  289. }
  290. if (primary == "HKEY_LOCAL_MACHINE")
  291. {
  292. primaryKey = HKEY_LOCAL_MACHINE;
  293. }
  294. if (primary == "HKEY_USERS")
  295. {
  296. primaryKey = HKEY_USERS;
  297. }
  298. HKEY hKey;
  299. if(RegOpenKeyEx(primaryKey,
  300. second.c_str(),
  301. 0,
  302. KEY_READ,
  303. &hKey) != ERROR_SUCCESS)
  304. {
  305. return false;
  306. }
  307. else
  308. {
  309. DWORD dwType, dwSize;
  310. dwSize = 1023;
  311. char data[1024];
  312. if(RegQueryValueEx(hKey,
  313. (LPTSTR)valuename.c_str(),
  314. NULL,
  315. &dwType,
  316. (BYTE *)data,
  317. &dwSize) == ERROR_SUCCESS)
  318. {
  319. if (dwType == REG_SZ)
  320. {
  321. value = data;
  322. return true;
  323. }
  324. }
  325. }
  326. return false;
  327. }
  328. #else
  329. bool cmSystemTools::ReadRegistryValue(const char *, std::string &)
  330. {
  331. return false;
  332. }
  333. #endif
  334. // Write a registry value.
  335. // Example :
  336. // HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore\2.1\InstallPath
  337. // => will set the data of the "default" value of the key
  338. // HKEY_LOCAL_MACHINE\SOFTWARE\Scriptics\Tcl\8.4;Root
  339. // => will set the data of the "Root" value of the key
  340. #if defined(_WIN32) && !defined(__CYGWIN__)
  341. bool cmSystemTools::WriteRegistryValue(const char *key, const char *value)
  342. {
  343. std::string primary = key;
  344. std::string second;
  345. std::string valuename;
  346. size_t start = primary.find("\\");
  347. if (start == std::string::npos)
  348. {
  349. return false;
  350. }
  351. size_t valuenamepos = primary.find(";");
  352. if (valuenamepos != std::string::npos)
  353. {
  354. valuename = primary.substr(valuenamepos+1);
  355. }
  356. second = primary.substr(start+1, valuenamepos-start-1);
  357. primary = primary.substr(0, start);
  358. HKEY primaryKey;
  359. if (primary == "HKEY_CURRENT_USER")
  360. {
  361. primaryKey = HKEY_CURRENT_USER;
  362. }
  363. if (primary == "HKEY_CURRENT_CONFIG")
  364. {
  365. primaryKey = HKEY_CURRENT_CONFIG;
  366. }
  367. if (primary == "HKEY_CLASSES_ROOT")
  368. {
  369. primaryKey = HKEY_CLASSES_ROOT;
  370. }
  371. if (primary == "HKEY_LOCAL_MACHINE")
  372. {
  373. primaryKey = HKEY_LOCAL_MACHINE;
  374. }
  375. if (primary == "HKEY_USERS")
  376. {
  377. primaryKey = HKEY_USERS;
  378. }
  379. HKEY hKey;
  380. DWORD dwDummy;
  381. if(RegCreateKeyEx(primaryKey,
  382. second.c_str(),
  383. 0,
  384. "",
  385. REG_OPTION_NON_VOLATILE,
  386. KEY_WRITE,
  387. NULL,
  388. &hKey,
  389. &dwDummy) != ERROR_SUCCESS)
  390. {
  391. return false;
  392. }
  393. if(RegSetValueEx(hKey,
  394. (LPTSTR)valuename.c_str(),
  395. 0,
  396. REG_SZ,
  397. (CONST BYTE *)value,
  398. (DWORD)(strlen(value) + 1)) == ERROR_SUCCESS)
  399. {
  400. return true;
  401. }
  402. return false;
  403. }
  404. #else
  405. bool cmSystemTools::WriteRegistryValue(const char *, const char *)
  406. {
  407. return false;
  408. }
  409. #endif
  410. // Delete a registry value.
  411. // Example :
  412. // HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore\2.1\InstallPath
  413. // => will delete the data of the "default" value of the key
  414. // HKEY_LOCAL_MACHINE\SOFTWARE\Scriptics\Tcl\8.4;Root
  415. // => will delete the data of the "Root" value of the key
  416. #if defined(_WIN32) && !defined(__CYGWIN__)
  417. bool cmSystemTools::DeleteRegistryValue(const char *key)
  418. {
  419. std::string primary = key;
  420. std::string second;
  421. std::string valuename;
  422. size_t start = primary.find("\\");
  423. if (start == std::string::npos)
  424. {
  425. return false;
  426. }
  427. size_t valuenamepos = primary.find(";");
  428. if (valuenamepos != std::string::npos)
  429. {
  430. valuename = primary.substr(valuenamepos+1);
  431. }
  432. second = primary.substr(start+1, valuenamepos-start-1);
  433. primary = primary.substr(0, start);
  434. HKEY primaryKey;
  435. if (primary == "HKEY_CURRENT_USER")
  436. {
  437. primaryKey = HKEY_CURRENT_USER;
  438. }
  439. if (primary == "HKEY_CURRENT_CONFIG")
  440. {
  441. primaryKey = HKEY_CURRENT_CONFIG;
  442. }
  443. if (primary == "HKEY_CLASSES_ROOT")
  444. {
  445. primaryKey = HKEY_CLASSES_ROOT;
  446. }
  447. if (primary == "HKEY_LOCAL_MACHINE")
  448. {
  449. primaryKey = HKEY_LOCAL_MACHINE;
  450. }
  451. if (primary == "HKEY_USERS")
  452. {
  453. primaryKey = HKEY_USERS;
  454. }
  455. HKEY hKey;
  456. if(RegOpenKeyEx(primaryKey,
  457. second.c_str(),
  458. 0,
  459. KEY_WRITE,
  460. &hKey) != ERROR_SUCCESS)
  461. {
  462. return false;
  463. }
  464. else
  465. {
  466. if(RegDeleteValue(hKey,
  467. (LPTSTR)valuename.c_str()) == ERROR_SUCCESS)
  468. {
  469. return true;
  470. }
  471. }
  472. return false;
  473. }
  474. #else
  475. bool cmSystemTools::DeleteRegistryValue(const char *)
  476. {
  477. return false;
  478. }
  479. #endif
  480. // replace replace with with as many times as it shows up in source.
  481. // write the result into source.
  482. #if defined(_WIN32) && !defined(__CYGWIN__)
  483. void cmSystemTools::ExpandRegistryValues(std::string& source)
  484. {
  485. // Regular expression to match anything inside [...] that begins in HKEY.
  486. // Note that there is a special rule for regular expressions to match a
  487. // close square-bracket inside a list delimited by square brackets.
  488. // The "[^]]" part of this expression will match any character except
  489. // a close square-bracket. The ']' character must be the first in the
  490. // list of characters inside the [^...] block of the expression.
  491. cmRegularExpression regEntry("\\[(HKEY[^]]*)\\]");
  492. // check for black line or comment
  493. while (regEntry.find(source))
  494. {
  495. // the arguments are the second match
  496. std::string key = regEntry.match(1);
  497. std::string val;
  498. if (ReadRegistryValue(key.c_str(), val))
  499. {
  500. std::string reg = "[";
  501. reg += key + "]";
  502. cmSystemTools::ReplaceString(source, reg.c_str(), val.c_str());
  503. }
  504. else
  505. {
  506. std::string reg = "[";
  507. reg += key + "]";
  508. cmSystemTools::ReplaceString(source, reg.c_str(), "/registry");
  509. }
  510. }
  511. }
  512. #else
  513. void cmSystemTools::ExpandRegistryValues(std::string&)
  514. {
  515. }
  516. #endif
  517. std::string cmSystemTools::EscapeQuotes(const char* str)
  518. {
  519. std::string result = "";
  520. for(const char* ch = str; *ch != '\0'; ++ch)
  521. {
  522. if(*ch == '"')
  523. {
  524. result += '\\';
  525. }
  526. result += *ch;
  527. }
  528. return result;
  529. }
  530. bool cmSystemTools::SameFile(const char* file1, const char* file2)
  531. {
  532. #ifdef _WIN32
  533. HANDLE hFile1, hFile2;
  534. hFile1 = CreateFile( file1,
  535. GENERIC_READ,
  536. FILE_SHARE_READ ,
  537. NULL,
  538. OPEN_EXISTING,
  539. FILE_FLAG_BACKUP_SEMANTICS,
  540. NULL
  541. );
  542. hFile2 = CreateFile( file2,
  543. GENERIC_READ,
  544. FILE_SHARE_READ,
  545. NULL,
  546. OPEN_EXISTING,
  547. FILE_FLAG_BACKUP_SEMANTICS,
  548. NULL
  549. );
  550. if( hFile1 == INVALID_HANDLE_VALUE || hFile2 == INVALID_HANDLE_VALUE)
  551. {
  552. if(hFile1 != INVALID_HANDLE_VALUE)
  553. {
  554. CloseHandle(hFile1);
  555. }
  556. if(hFile2 != INVALID_HANDLE_VALUE)
  557. {
  558. CloseHandle(hFile2);
  559. }
  560. return false;
  561. }
  562. BY_HANDLE_FILE_INFORMATION fiBuf1;
  563. BY_HANDLE_FILE_INFORMATION fiBuf2;
  564. GetFileInformationByHandle( hFile1, &fiBuf1 );
  565. GetFileInformationByHandle( hFile2, &fiBuf2 );
  566. CloseHandle(hFile1);
  567. CloseHandle(hFile2);
  568. return (fiBuf1.nFileIndexHigh == fiBuf2.nFileIndexHigh &&
  569. fiBuf1.nFileIndexLow == fiBuf2.nFileIndexLow);
  570. #else
  571. struct stat fileStat1, fileStat2;
  572. if (stat(file1, &fileStat1) == 0 && stat(file2, &fileStat2) == 0)
  573. {
  574. // see if the files are the same file
  575. // check the device inode and size
  576. if(memcmp(&fileStat2.st_dev, &fileStat1.st_dev, sizeof(fileStat1.st_dev)) == 0 &&
  577. memcmp(&fileStat2.st_ino, &fileStat1.st_ino, sizeof(fileStat1.st_ino)) == 0 &&
  578. fileStat2.st_size == fileStat1.st_size
  579. )
  580. {
  581. return true;
  582. }
  583. }
  584. return false;
  585. #endif
  586. }
  587. // return true if the file exists
  588. bool cmSystemTools::FileExists(const char* filename)
  589. {
  590. struct stat fs;
  591. if (stat(filename, &fs) != 0)
  592. {
  593. return false;
  594. }
  595. else
  596. {
  597. return true;
  598. }
  599. }
  600. // Return a capitalized string (i.e the first letter is uppercased, all other
  601. // are lowercased)
  602. std::string cmSystemTools::Capitalized(const std::string& s)
  603. {
  604. std::string n;
  605. n.resize(s.size());
  606. n[0] = toupper(s[0]);
  607. for (size_t i = 1; i < s.size(); i++)
  608. {
  609. n[i] = tolower(s[i]);
  610. }
  611. return n;
  612. }
  613. // Return a lower case string
  614. std::string cmSystemTools::LowerCase(const std::string& s)
  615. {
  616. std::string n;
  617. n.resize(s.size());
  618. for (size_t i = 0; i < s.size(); i++)
  619. {
  620. n[i] = tolower(s[i]);
  621. }
  622. return n;
  623. }
  624. // Return a lower case string
  625. std::string cmSystemTools::UpperCase(const std::string& s)
  626. {
  627. std::string n;
  628. n.resize(s.size());
  629. for (size_t i = 0; i < s.size(); i++)
  630. {
  631. n[i] = toupper(s[i]);
  632. }
  633. return n;
  634. }
  635. // convert windows slashes to unix slashes
  636. void cmSystemTools::ConvertToUnixSlashes(std::string& path)
  637. {
  638. std::string::size_type pos = 0;
  639. while((pos = path.find('\\', pos)) != std::string::npos)
  640. {
  641. path[pos] = '/';
  642. pos++;
  643. }
  644. // Remove all // from the path just like most unix shells
  645. int start_find = 0;
  646. #ifdef _WIN32
  647. // However, on windows if the first characters are both slashes,
  648. // then keep them that way, so that network paths can be handled.
  649. start_find = 1;
  650. #endif
  651. while((pos = path.find("//", start_find)) != std::string::npos)
  652. {
  653. cmSystemTools::ReplaceString(path, "//", "/");
  654. }
  655. // remove any trailing slash
  656. if(path.size() && path[path.size()-1] == '/')
  657. {
  658. path = path.substr(0, path.size()-1);
  659. }
  660. // if there is a tilda ~ then replace it with HOME
  661. if(path.find("~") == 0)
  662. {
  663. if (getenv("HOME"))
  664. {
  665. path = std::string(getenv("HOME")) + path.substr(1);
  666. }
  667. }
  668. // if there is a /tmp_mnt in a path get rid of it!
  669. // stupid sgi's
  670. if(path.find("/tmp_mnt") == 0)
  671. {
  672. path = path.substr(8);
  673. }
  674. }
  675. // change // to /, and escape any spaces in the path
  676. std::string cmSystemTools::ConvertToUnixOutputPath(const char* path)
  677. {
  678. std::string ret = path;
  679. // remove // except at the beginning might be a cygwin drive
  680. std::string::size_type pos = 1;
  681. while((pos = ret.find("//", pos)) != std::string::npos)
  682. {
  683. ret.erase(pos, 1);
  684. }
  685. // now escape spaces if there is a space in the path
  686. if(ret.find(" ") != std::string::npos)
  687. {
  688. std::string result = "";
  689. char lastch = 1;
  690. for(const char* ch = ret.c_str(); *ch != '\0'; ++ch)
  691. {
  692. // if it is already escaped then don't try to escape it again
  693. if(*ch == ' ' && lastch != '\\')
  694. {
  695. result += '\\';
  696. }
  697. result += *ch;
  698. lastch = *ch;
  699. }
  700. ret = result;
  701. }
  702. return ret;
  703. }
  704. std::string cmSystemTools::EscapeSpaces(const char* str)
  705. {
  706. #if defined(_WIN32) && !defined(__CYGWIN__)
  707. std::string result;
  708. // if there are spaces
  709. std::string temp = str;
  710. if (temp.find(" ") != std::string::npos &&
  711. temp.find("\"")==std::string::npos)
  712. {
  713. result = "\"";
  714. result += str;
  715. result += "\"";
  716. return result;
  717. }
  718. return str;
  719. #else
  720. std::string result = "";
  721. for(const char* ch = str; *ch != '\0'; ++ch)
  722. {
  723. if(*ch == ' ')
  724. {
  725. result += '\\';
  726. }
  727. result += *ch;
  728. }
  729. return result;
  730. #endif
  731. }
  732. std::string cmSystemTools::ConvertToOutputPath(const char* path)
  733. {
  734. #if defined(_WIN32) && !defined(__CYGWIN__)
  735. return cmSystemTools::ConvertToWindowsOutputPath(path);
  736. #else
  737. return cmSystemTools::ConvertToUnixOutputPath(path);
  738. #endif
  739. }
  740. // remove double slashes not at the start
  741. std::string cmSystemTools::ConvertToWindowsOutputPath(const char* path)
  742. {
  743. std::string ret = path;
  744. std::string::size_type pos = 0;
  745. // first convert all of the slashes
  746. while((pos = ret.find('/', pos)) != std::string::npos)
  747. {
  748. ret[pos] = '\\';
  749. pos++;
  750. }
  751. // check for really small paths
  752. if(ret.size() < 2)
  753. {
  754. return ret;
  755. }
  756. // now clean up a bit and remove double slashes
  757. // Only if it is not the first position in the path which is a network
  758. // path on windows
  759. pos = 1; // start at position 1
  760. if(ret[0] == '\"')
  761. {
  762. pos = 2; // if the string is already quoted then start at 2
  763. if(ret.size() < 3)
  764. {
  765. return ret;
  766. }
  767. }
  768. while((pos = ret.find("\\\\", pos)) != std::string::npos)
  769. {
  770. ret.erase(pos, 1);
  771. }
  772. // now double quote the path if it has spaces in it
  773. // and is not already double quoted
  774. if(ret.find(" ") != std::string::npos
  775. && ret[0] != '\"')
  776. {
  777. std::string result;
  778. result = "\"" + ret + "\"";
  779. ret = result;
  780. }
  781. return ret;
  782. }
  783. std::string cmSystemTools::RemoveEscapes(const char* s)
  784. {
  785. std::string result = "";
  786. for(const char* ch = s; *ch; ++ch)
  787. {
  788. if(*ch == '\\' && *(ch+1) != ';')
  789. {
  790. ++ch;
  791. switch (*ch)
  792. {
  793. case '\\': result.insert(result.end(), '\\'); break;
  794. case '"': result.insert(result.end(), '"'); break;
  795. case ' ': result.insert(result.end(), ' '); break;
  796. case 't': result.insert(result.end(), '\t'); break;
  797. case 'n': result.insert(result.end(), '\n'); break;
  798. case 'r': result.insert(result.end(), '\r'); break;
  799. case '0': result.insert(result.end(), '\0'); break;
  800. case '\0':
  801. {
  802. cmSystemTools::Error("Trailing backslash in argument:\n", s);
  803. return result;
  804. }
  805. default:
  806. {
  807. std::string chStr(1, *ch);
  808. cmSystemTools::Error("Invalid escape sequence \\", chStr.c_str(),
  809. "\nin argument ", s);
  810. }
  811. }
  812. }
  813. else
  814. {
  815. result.insert(result.end(), *ch);
  816. }
  817. }
  818. return result;
  819. }
  820. void cmSystemTools::Error(const char* m1, const char* m2,
  821. const char* m3, const char* m4)
  822. {
  823. std::string message = "CMake Error: ";
  824. if(m1)
  825. {
  826. message += m1;
  827. }
  828. if(m2)
  829. {
  830. message += m2;
  831. }
  832. if(m3)
  833. {
  834. message += m3;
  835. }
  836. if(m4)
  837. {
  838. message += m4;
  839. }
  840. cmSystemTools::s_ErrorOccured = true;
  841. cmSystemTools::Message(message.c_str(),"Error");
  842. }
  843. void cmSystemTools::SetErrorCallback(ErrorCallback f, void* clientData)
  844. {
  845. s_ErrorCallback = f;
  846. s_ErrorCallbackClientData = clientData;
  847. }
  848. void cmSystemTools::Message(const char* m1, const char *title)
  849. {
  850. if(s_DisableMessages)
  851. {
  852. return;
  853. }
  854. if(s_ErrorCallback)
  855. {
  856. (*s_ErrorCallback)(m1, title, s_DisableMessages, s_ErrorCallbackClientData);
  857. return;
  858. }
  859. else
  860. {
  861. std::cerr << m1 << std::endl << std::flush;
  862. }
  863. }
  864. bool cmSystemTools::CopyFileIfDifferent(const char* source,
  865. const char* destination)
  866. {
  867. if(cmSystemTools::FilesDiffer(source, destination))
  868. {
  869. cmSystemTools::cmCopyFile(source, destination);
  870. return true;
  871. }
  872. return false;
  873. }
  874. bool cmSystemTools::FilesDiffer(const char* source,
  875. const char* destination)
  876. {
  877. struct stat statSource;
  878. if (stat(source, &statSource) != 0)
  879. {
  880. return true;
  881. }
  882. struct stat statDestination;
  883. if (stat(destination, &statDestination) != 0)
  884. {
  885. return true;
  886. }
  887. if(statSource.st_size != statDestination.st_size)
  888. {
  889. return true;
  890. }
  891. if(statSource.st_size == 0)
  892. {
  893. return false;
  894. }
  895. #if defined(_WIN32) || defined(__CYGWIN__)
  896. std::ifstream finSource(source,
  897. std::ios::binary | std::ios::in);
  898. std::ifstream finDestination(destination,
  899. std::ios::binary | std::ios::in);
  900. #else
  901. std::ifstream finSource(source);
  902. std::ifstream finDestination(destination);
  903. #endif
  904. if(!finSource || !finDestination)
  905. {
  906. return true;
  907. }
  908. char* source_buf = new char[statSource.st_size];
  909. char* dest_buf = new char[statSource.st_size];
  910. finSource.read(source_buf, statSource.st_size);
  911. finDestination.read(dest_buf, statSource.st_size);
  912. if(statSource.st_size != static_cast<long>(finSource.gcount()) ||
  913. statSource.st_size != static_cast<long>(finDestination.gcount()))
  914. {
  915. cmOStringStream msg;
  916. msg << "FilesDiffer failed to read files (allocated: "
  917. << statSource.st_size << ", read source: " << finSource.gcount()
  918. << ", read dest: " << finDestination.gcount();
  919. cmSystemTools::Error(msg.str().c_str());
  920. delete [] source_buf;
  921. delete [] dest_buf;
  922. return false;
  923. }
  924. int ret = memcmp((const void*)source_buf,
  925. (const void*)dest_buf,
  926. statSource.st_size);
  927. delete [] dest_buf;
  928. delete [] source_buf;
  929. return ret != 0;
  930. }
  931. /**
  932. * Copy a file named by "source" to the file named by "destination".
  933. */
  934. void cmSystemTools::cmCopyFile(const char* source,
  935. const char* destination)
  936. {
  937. const int bufferSize = 4096;
  938. char buffer[bufferSize];
  939. // If destination is a directory, try to create a file with the same
  940. // name as the source in that directory.
  941. std::string new_destination;
  942. if(cmSystemTools::FileExists(destination) &&
  943. cmSystemTools::FileIsDirectory(destination))
  944. {
  945. new_destination = destination;
  946. cmSystemTools::ConvertToUnixSlashes(new_destination);
  947. new_destination += '/';
  948. std::string source_name = source;
  949. new_destination += cmSystemTools::GetFilenameName(source_name);
  950. destination = new_destination.c_str();
  951. }
  952. // Create destination directory
  953. std::string destination_dir = destination;
  954. destination_dir = cmSystemTools::GetFilenamePath(destination_dir);
  955. cmSystemTools::MakeDirectory(destination_dir.c_str());
  956. // Open files
  957. #if defined(_WIN32) || defined(__CYGWIN__)
  958. std::ifstream fin(source,
  959. std::ios::binary | std::ios::in);
  960. #else
  961. std::ifstream fin(source);
  962. #endif
  963. if(!fin)
  964. {
  965. int e = errno;
  966. std::string m = "CopyFile failed to open source file \"";
  967. m += source;
  968. m += "\"";
  969. m += " System Error: ";
  970. m += strerror(e);
  971. cmSystemTools::Error(m.c_str());
  972. return;
  973. }
  974. #if defined(_WIN32) || defined(__CYGWIN__)
  975. std::ofstream fout(destination,
  976. std::ios::binary | std::ios::out | std::ios::trunc);
  977. #else
  978. std::ofstream fout(destination,
  979. std::ios::out | std::ios::trunc);
  980. #endif
  981. if(!fout)
  982. {
  983. int e = errno;
  984. std::string m = "CopyFile failed to open destination file \"";
  985. m += destination;
  986. m += "\"";
  987. m += " System Error: ";
  988. m += strerror(e);
  989. cmSystemTools::Error(m.c_str());
  990. return;
  991. }
  992. // This copy loop is very sensitive on certain platforms with
  993. // slightly broken stream libraries (like HPUX). Normally, it is
  994. // incorrect to not check the error condition on the fin.read()
  995. // before using the data, but the fin.gcount() will be zero if an
  996. // error occurred. Therefore, the loop should be safe everywhere.
  997. while(fin)
  998. {
  999. fin.read(buffer, bufferSize);
  1000. if(fin.gcount())
  1001. {
  1002. fout.write(buffer, fin.gcount());
  1003. }
  1004. }
  1005. // Make sure the operating system has finished writing the file
  1006. // before closing it. This will ensure the file is finished before
  1007. // the check below.
  1008. fout.flush();
  1009. fin.close();
  1010. fout.close();
  1011. // More checks.
  1012. struct stat statSource, statDestination;
  1013. statSource.st_size = 12345;
  1014. statDestination.st_size = 12345;
  1015. if(stat(source, &statSource) != 0)
  1016. {
  1017. int e = errno;
  1018. std::string m = "CopyFile failed to stat source file \"";
  1019. m += source;
  1020. m += "\"";
  1021. m += " System Error: ";
  1022. m += strerror(e);
  1023. cmSystemTools::Error(m.c_str());
  1024. }
  1025. else if(stat(destination, &statDestination) != 0)
  1026. {
  1027. int e = errno;
  1028. std::string m = "CopyFile failed to stat destination file \"";
  1029. m += source;
  1030. m += "\"";
  1031. m += " System Error: ";
  1032. m += strerror(e);
  1033. cmSystemTools::Error(m.c_str());
  1034. }
  1035. else if(statSource.st_size != statDestination.st_size)
  1036. {
  1037. cmOStringStream msg;
  1038. msg << "CopyFile failed to copy files: source \""
  1039. << source << "\", size " << statSource.st_size << ", destination \""
  1040. << destination << "\", size " << statDestination.st_size;
  1041. cmSystemTools::Error(msg.str().c_str());
  1042. }
  1043. }
  1044. // return true if the file exists
  1045. long int cmSystemTools::ModifiedTime(const char* filename)
  1046. {
  1047. struct stat fs;
  1048. if (stat(filename, &fs) != 0)
  1049. {
  1050. return 0;
  1051. }
  1052. else
  1053. {
  1054. return (long int)fs.st_mtime;
  1055. }
  1056. }
  1057. void cmSystemTools::ReportLastSystemError(const char* msg)
  1058. {
  1059. int e = errno;
  1060. std::string m = msg;
  1061. m += ": System Error: ";
  1062. m += strerror(e);
  1063. cmSystemTools::Error(m.c_str());
  1064. }
  1065. bool cmSystemTools::RemoveFile(const char* source)
  1066. {
  1067. return unlink(source) != 0 ? false : true;
  1068. }
  1069. bool cmSystemTools::IsOn(const char* val)
  1070. {
  1071. if (!val)
  1072. {
  1073. return false;
  1074. }
  1075. std::basic_string<char> v = val;
  1076. for(std::basic_string<char>::iterator c = v.begin();
  1077. c != v.end(); c++)
  1078. {
  1079. *c = toupper(*c);
  1080. }
  1081. return (v == "ON" || v == "1" || v == "YES" || v == "TRUE" || v == "Y");
  1082. }
  1083. bool cmSystemTools::IsNOTFOUND(const char* val)
  1084. {
  1085. cmRegularExpression reg("-NOTFOUND$");
  1086. if(reg.find(val))
  1087. {
  1088. return true;
  1089. }
  1090. return std::string("NOTFOUND") == val;
  1091. }
  1092. bool cmSystemTools::IsOff(const char* val)
  1093. {
  1094. if (!val || strlen(val) == 0)
  1095. {
  1096. return true;
  1097. }
  1098. std::basic_string<char> v = val;
  1099. for(std::basic_string<char>::iterator c = v.begin();
  1100. c != v.end(); c++)
  1101. {
  1102. *c = toupper(*c);
  1103. }
  1104. return (v == "OFF" || v == "0" || v == "NO" || v == "FALSE" ||
  1105. v == "N" || cmSystemTools::IsNOTFOUND(v.c_str()) || v == "IGNORE");
  1106. }
  1107. bool cmSystemTools::RunCommand(const char* command,
  1108. std::string& output,
  1109. const char* dir,
  1110. bool verbose,
  1111. int timeout)
  1112. {
  1113. int dummy;
  1114. return cmSystemTools::RunCommand(command, output, dummy,
  1115. dir, verbose, timeout);
  1116. }
  1117. #if defined(WIN32) && !defined(__CYGWIN__)
  1118. #include "cmWin32ProcessExecution.h"
  1119. // use this for shell commands like echo and dir
  1120. bool RunCommandViaWin32(const char* command,
  1121. const char* dir,
  1122. std::string& output,
  1123. int& retVal,
  1124. bool verbose,
  1125. int timeout)
  1126. {
  1127. #if defined(__BORLANDC__)
  1128. return cmWin32ProcessExecution::BorlandRunCommand(command, dir, output,
  1129. retVal,
  1130. verbose, timeout,
  1131. cmSystemTools::GetRunCommandHideConsole());
  1132. #else // Visual studio
  1133. ::SetLastError(ERROR_SUCCESS);
  1134. if ( ! command )
  1135. {
  1136. cmSystemTools::Error("No command specified");
  1137. return false;
  1138. }
  1139. cmWin32ProcessExecution resProc;
  1140. if(cmSystemTools::GetRunCommandHideConsole())
  1141. {
  1142. resProc.SetHideWindows(true);
  1143. }
  1144. if ( cmSystemTools::GetWindows9xComspecSubstitute() )
  1145. {
  1146. resProc.SetConsoleSpawn(cmSystemTools::GetWindows9xComspecSubstitute() );
  1147. }
  1148. if ( !resProc.StartProcess(command, dir, verbose) )
  1149. {
  1150. std::cout << "Problem starting command" << std::endl;
  1151. return false;
  1152. }
  1153. resProc.Wait(timeout);
  1154. output = resProc.GetOutput();
  1155. retVal = resProc.GetExitValue();
  1156. return true;
  1157. #endif
  1158. }
  1159. // use this for shell commands like echo and dir
  1160. bool RunCommandViaSystem(const char* command,
  1161. const char* dir,
  1162. std::string& output,
  1163. int& retVal,
  1164. bool verbose)
  1165. {
  1166. std::cout << "@@ " << command << std::endl;
  1167. const int BUFFER_SIZE = 4096;
  1168. char buffer[BUFFER_SIZE];
  1169. std::string commandInDir;
  1170. if(dir)
  1171. {
  1172. commandInDir = "cd ";
  1173. commandInDir += cmSystemTools::ConvertToOutputPath(dir);
  1174. commandInDir += " && ";
  1175. commandInDir += command;
  1176. }
  1177. else
  1178. {
  1179. commandInDir = command;
  1180. }
  1181. command = commandInDir.c_str();
  1182. std::string commandToFile = command;
  1183. commandToFile += " > ";
  1184. std::string tempFile;
  1185. tempFile += _tempnam(0, "cmake");
  1186. commandToFile += tempFile;
  1187. retVal = system(commandToFile.c_str());
  1188. std::ifstream fin(tempFile.c_str());
  1189. if(!fin)
  1190. {
  1191. if(verbose)
  1192. {
  1193. std::string errormsg = "RunCommand produced no output: command: \"";
  1194. errormsg += command;
  1195. errormsg += "\"";
  1196. errormsg += "\nOutput file: ";
  1197. errormsg += tempFile;
  1198. cmSystemTools::Error(errormsg.c_str());
  1199. }
  1200. fin.close();
  1201. cmSystemTools::RemoveFile(tempFile.c_str());
  1202. return false;
  1203. }
  1204. bool multiLine = false;
  1205. while(fin)
  1206. {
  1207. fin.getline(buffer, BUFFER_SIZE);
  1208. output += buffer;
  1209. if(multiLine)
  1210. {
  1211. output += "\n";
  1212. }
  1213. multiLine = true;
  1214. }
  1215. fin.close();
  1216. cmSystemTools::RemoveFile(tempFile.c_str());
  1217. return true;
  1218. }
  1219. #else // We have popen
  1220. bool RunCommandViaPopen(const char* command,
  1221. const char* dir,
  1222. std::string& output,
  1223. int& retVal,
  1224. bool verbose,
  1225. int /*timeout*/)
  1226. {
  1227. // if only popen worked on windows.....
  1228. std::string commandInDir;
  1229. if(dir)
  1230. {
  1231. commandInDir = "cd \"";
  1232. commandInDir += dir;
  1233. commandInDir += "\" && ";
  1234. commandInDir += command;
  1235. }
  1236. else
  1237. {
  1238. commandInDir = command;
  1239. }
  1240. commandInDir += " 2>&1";
  1241. command = commandInDir.c_str();
  1242. const int BUFFER_SIZE = 4096;
  1243. char buffer[BUFFER_SIZE];
  1244. if(verbose)
  1245. {
  1246. std::cout << "running " << command << std::endl;
  1247. }
  1248. fflush(stdout);
  1249. fflush(stderr);
  1250. FILE* cpipe = popen(command, "r");
  1251. if(!cpipe)
  1252. {
  1253. return false;
  1254. }
  1255. fgets(buffer, BUFFER_SIZE, cpipe);
  1256. while(!feof(cpipe))
  1257. {
  1258. if(verbose)
  1259. {
  1260. std::cout << buffer << std::flush;
  1261. }
  1262. output += buffer;
  1263. fgets(buffer, BUFFER_SIZE, cpipe);
  1264. }
  1265. retVal = pclose(cpipe);
  1266. if (WIFEXITED(retVal))
  1267. {
  1268. retVal = WEXITSTATUS(retVal);
  1269. return true;
  1270. }
  1271. if (WIFSIGNALED(retVal))
  1272. {
  1273. retVal = WTERMSIG(retVal);
  1274. cmOStringStream error;
  1275. error << "\nProcess terminated due to ";
  1276. switch (retVal)
  1277. {
  1278. #ifdef SIGKILL
  1279. case SIGKILL:
  1280. error << "SIGKILL";
  1281. break;
  1282. #endif
  1283. #ifdef SIGFPE
  1284. case SIGFPE:
  1285. error << "SIGFPE";
  1286. break;
  1287. #endif
  1288. #ifdef SIGBUS
  1289. case SIGBUS:
  1290. error << "SIGBUS";
  1291. break;
  1292. #endif
  1293. #ifdef SIGSEGV
  1294. case SIGSEGV:
  1295. error << "SIGSEGV";
  1296. break;
  1297. #endif
  1298. default:
  1299. error << "signal " << retVal;
  1300. break;
  1301. }
  1302. output += error.str();
  1303. }
  1304. return false;
  1305. }
  1306. #endif // endif WIN32 not CYGWIN
  1307. // run a command unix uses popen (easy)
  1308. // windows uses system and ShortPath
  1309. bool cmSystemTools::RunCommand(const char* command,
  1310. std::string& output,
  1311. int &retVal,
  1312. const char* dir,
  1313. bool verbose,
  1314. int timeout)
  1315. {
  1316. if(s_DisableRunCommandOutput)
  1317. {
  1318. verbose = false;
  1319. }
  1320. #if defined(WIN32) && !defined(__CYGWIN__)
  1321. // if the command does not start with a quote, then
  1322. // try to find the program, and if the program can not be
  1323. // found use system to run the command as it must be a built in
  1324. // shell command like echo or dir
  1325. int count = 0;
  1326. if(command[0] == '\"')
  1327. {
  1328. // count the number of quotes
  1329. for(const char* s = command; *s != 0; ++s)
  1330. {
  1331. if(*s == '\"')
  1332. {
  1333. count++;
  1334. if(count > 2)
  1335. {
  1336. break;
  1337. }
  1338. }
  1339. }
  1340. // if there are more than two double quotes use
  1341. // GetShortPathName, the cmd.exe program in windows which
  1342. // is used by system fails to execute if there are more than
  1343. // one set of quotes in the arguments
  1344. if(count > 2)
  1345. {
  1346. cmRegularExpression quoted("^\"([^\"]*)\"[ \t](.*)");
  1347. if(quoted.find(command))
  1348. {
  1349. std::string shortCmd;
  1350. std::string cmd = quoted.match(1);
  1351. std::string args = quoted.match(2);
  1352. if(! cmSystemTools::FileExists(cmd.c_str()) )
  1353. {
  1354. shortCmd = cmd;
  1355. }
  1356. else if(!cmSystemTools::GetShortPath(cmd.c_str(), shortCmd))
  1357. {
  1358. cmSystemTools::Error("GetShortPath failed for " , cmd.c_str());
  1359. return false;
  1360. }
  1361. shortCmd += " ";
  1362. shortCmd += args;
  1363. //return RunCommandViaSystem(shortCmd.c_str(), dir,
  1364. // output, retVal, verbose);
  1365. //return WindowsRunCommand(shortCmd.c_str(), dir,
  1366. //output, retVal, verbose);
  1367. return RunCommandViaWin32(shortCmd.c_str(), dir,
  1368. output, retVal, verbose, timeout);
  1369. }
  1370. else
  1371. {
  1372. cmSystemTools::Error("Could not parse command line with quotes ",
  1373. command);
  1374. }
  1375. }
  1376. }
  1377. // if there is only one set of quotes or no quotes then just run the command
  1378. //return RunCommandViaSystem(command, dir, output, retVal, verbose);
  1379. //return WindowsRunCommand(command, dir, output, retVal, verbose);
  1380. return ::RunCommandViaWin32(command, dir, output, retVal, verbose, timeout);
  1381. #else
  1382. return ::RunCommandViaPopen(command, dir, output, retVal, verbose, timeout);
  1383. #endif
  1384. }
  1385. /**
  1386. * Find the file the given name. Searches the given path and then
  1387. * the system search path. Returns the full path to the file if it is
  1388. * found. Otherwise, the empty string is returned.
  1389. */
  1390. std::string cmSystemTools::FindFile(const char* name,
  1391. const std::vector<std::string>& userPaths)
  1392. {
  1393. // Add the system search path to our path.
  1394. std::vector<std::string> path = userPaths;
  1395. cmSystemTools::GetPath(path);
  1396. std::string tryPath;
  1397. for(std::vector<std::string>::const_iterator p = path.begin();
  1398. p != path.end(); ++p)
  1399. {
  1400. tryPath = *p;
  1401. tryPath += "/";
  1402. tryPath += name;
  1403. if(cmSystemTools::FileExists(tryPath.c_str()) &&
  1404. !cmSystemTools::FileIsDirectory(tryPath.c_str()))
  1405. {
  1406. return cmSystemTools::CollapseFullPath(tryPath.c_str());
  1407. }
  1408. }
  1409. // Couldn't find the file.
  1410. return "";
  1411. }
  1412. /**
  1413. * Find the executable with the given name. Searches the given path and then
  1414. * the system search path. Returns the full path to the executable if it is
  1415. * found. Otherwise, the empty string is returned.
  1416. */
  1417. std::string cmSystemTools::FindProgram(const char* name,
  1418. const std::vector<std::string>& userPaths,
  1419. bool no_system_path)
  1420. {
  1421. if(!name)
  1422. {
  1423. return "";
  1424. }
  1425. // See if the executable exists as written.
  1426. if(cmSystemTools::FileExists(name) &&
  1427. !cmSystemTools::FileIsDirectory(name))
  1428. {
  1429. return cmSystemTools::CollapseFullPath(name);
  1430. }
  1431. std::string tryPath = name;
  1432. tryPath += cmSystemTools::GetExecutableExtension();
  1433. if(cmSystemTools::FileExists(tryPath.c_str()) &&
  1434. !cmSystemTools::FileIsDirectory(tryPath.c_str()))
  1435. {
  1436. return cmSystemTools::CollapseFullPath(tryPath.c_str());
  1437. }
  1438. // Add the system search path to our path.
  1439. std::vector<std::string> path = userPaths;
  1440. if (!no_system_path)
  1441. {
  1442. cmSystemTools::GetPath(path);
  1443. }
  1444. for(std::vector<std::string>::const_iterator p = path.begin();
  1445. p != path.end(); ++p)
  1446. {
  1447. tryPath = *p;
  1448. tryPath += "/";
  1449. tryPath += name;
  1450. if(cmSystemTools::FileExists(tryPath.c_str()) &&
  1451. !cmSystemTools::FileIsDirectory(tryPath.c_str()))
  1452. {
  1453. return cmSystemTools::CollapseFullPath(tryPath.c_str());
  1454. }
  1455. #ifdef _WIN32
  1456. tryPath += ".com";
  1457. if(cmSystemTools::FileExists(tryPath.c_str()) &&
  1458. !cmSystemTools::FileIsDirectory(tryPath.c_str()))
  1459. {
  1460. return cmSystemTools::CollapseFullPath(tryPath.c_str());
  1461. }
  1462. tryPath = *p;
  1463. tryPath += "/";
  1464. tryPath += name;
  1465. #endif
  1466. tryPath += cmSystemTools::GetExecutableExtension();
  1467. if(cmSystemTools::FileExists(tryPath.c_str()) &&
  1468. !cmSystemTools::FileIsDirectory(tryPath.c_str()))
  1469. {
  1470. return cmSystemTools::CollapseFullPath(tryPath.c_str());
  1471. }
  1472. }
  1473. // Couldn't find the program.
  1474. return "";
  1475. }
  1476. /**
  1477. * Find the library with the given name. Searches the given path and then
  1478. * the system search path. Returns the full path to the library if it is
  1479. * found. Otherwise, the empty string is returned.
  1480. */
  1481. std::string cmSystemTools::FindLibrary(const char* name,
  1482. const std::vector<std::string>& userPaths)
  1483. {
  1484. // See if the executable exists as written.
  1485. if(cmSystemTools::FileExists(name))
  1486. {
  1487. return cmSystemTools::CollapseFullPath(name);
  1488. }
  1489. // Add the system search path to our path.
  1490. std::vector<std::string> path = userPaths;
  1491. cmSystemTools::GetPath(path);
  1492. std::string tryPath;
  1493. for(std::vector<std::string>::const_iterator p = path.begin();
  1494. p != path.end(); ++p)
  1495. {
  1496. #if defined(_WIN32) && !defined(__CYGWIN__)
  1497. tryPath = *p;
  1498. tryPath += "/";
  1499. tryPath += name;
  1500. tryPath += ".lib";
  1501. if(cmSystemTools::FileExists(tryPath.c_str()))
  1502. {
  1503. return cmSystemTools::CollapseFullPath(tryPath.c_str());
  1504. }
  1505. #else
  1506. tryPath = *p;
  1507. tryPath += "/lib";
  1508. tryPath += name;
  1509. tryPath += ".so";
  1510. if(cmSystemTools::FileExists(tryPath.c_str()))
  1511. {
  1512. return cmSystemTools::CollapseFullPath(tryPath.c_str());
  1513. }
  1514. tryPath = *p;
  1515. tryPath += "/lib";
  1516. tryPath += name;
  1517. tryPath += ".a";
  1518. if(cmSystemTools::FileExists(tryPath.c_str()))
  1519. {
  1520. return cmSystemTools::CollapseFullPath(tryPath.c_str());
  1521. }
  1522. tryPath = *p;
  1523. tryPath += "/lib";
  1524. tryPath += name;
  1525. tryPath += ".sl";
  1526. if(cmSystemTools::FileExists(tryPath.c_str()))
  1527. {
  1528. return cmSystemTools::CollapseFullPath(tryPath.c_str());
  1529. }
  1530. tryPath = *p;
  1531. tryPath += "/lib";
  1532. tryPath += name;
  1533. tryPath += ".dylib";
  1534. if(cmSystemTools::FileExists(tryPath.c_str()))
  1535. {
  1536. return cmSystemTools::CollapseFullPath(tryPath.c_str());
  1537. }
  1538. #endif
  1539. }
  1540. // Couldn't find the library.
  1541. return "";
  1542. }
  1543. bool cmSystemTools::FileIsDirectory(const char* name)
  1544. {
  1545. struct stat fs;
  1546. if(stat(name, &fs) == 0)
  1547. {
  1548. #if _WIN32
  1549. return ((fs.st_mode & _S_IFDIR) != 0);
  1550. #else
  1551. return S_ISDIR(fs.st_mode);
  1552. #endif
  1553. }
  1554. else
  1555. {
  1556. return false;
  1557. }
  1558. }
  1559. int cmSystemTools::ChangeDirectory(const char *dir)
  1560. {
  1561. return Chdir(dir);
  1562. }
  1563. std::string cmSystemTools::GetCurrentWorkingDirectory()
  1564. {
  1565. char buf[2048];
  1566. std::string path = Getcwd(buf, 2048);
  1567. return path;
  1568. }
  1569. /**
  1570. * Given the path to a program executable, get the directory part of the path with the
  1571. * file stripped off. If there is no directory part, the empty string is returned.
  1572. */
  1573. std::string cmSystemTools::GetProgramPath(const char* in_name)
  1574. {
  1575. std::string dir, file;
  1576. cmSystemTools::SplitProgramPath(in_name, dir, file);
  1577. return dir;
  1578. }
  1579. /**
  1580. * Given the path to a program executable, get the directory part of the path
  1581. * with the file stripped off. If there is no directory part, the empty
  1582. * string is returned.
  1583. */
  1584. void cmSystemTools::SplitProgramPath(const char* in_name,
  1585. std::string& dir,
  1586. std::string& file)
  1587. {
  1588. dir = in_name;
  1589. file = "";
  1590. cmSystemTools::ConvertToUnixSlashes(dir);
  1591. if(!cmSystemTools::FileIsDirectory(dir.c_str()))
  1592. {
  1593. std::string::size_type slashPos = dir.rfind("/");
  1594. if(slashPos != std::string::npos)
  1595. {
  1596. file = dir.substr(slashPos+1);
  1597. dir = dir.substr(0, slashPos);
  1598. }
  1599. else
  1600. {
  1601. file = dir;
  1602. dir = "";
  1603. }
  1604. }
  1605. if((dir != "") && !cmSystemTools::FileIsDirectory(dir.c_str()))
  1606. {
  1607. std::string oldDir = in_name;
  1608. cmSystemTools::ConvertToUnixSlashes(oldDir);
  1609. cmSystemTools::Error("Error splitting file name off end of path:\n",
  1610. oldDir.c_str(), "\nDirectory not found: ",
  1611. dir.c_str());
  1612. dir = in_name;
  1613. return;
  1614. }
  1615. }
  1616. /**
  1617. * Given a path to a file or directory, convert it to a full path.
  1618. * This collapses away relative paths. The full path is returned.
  1619. */
  1620. std::string cmSystemTools::CollapseFullPath(const char* in_name)
  1621. {
  1622. std::string dir, file;
  1623. cmSystemTools::SplitProgramPath(in_name, dir, file);
  1624. #ifdef _WIN32
  1625. // Ultra-hack warning:
  1626. // This changes to the target directory, saves the working directory,
  1627. // and then changes back to the original working directory.
  1628. std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
  1629. if(dir != "") { Chdir(dir.c_str()); }
  1630. std::string newDir = cmSystemTools::GetCurrentWorkingDirectory();
  1631. Chdir(cwd.c_str());
  1632. cmSystemTools::ConvertToUnixSlashes(newDir);
  1633. std::string newPath = newDir+"/"+file;
  1634. return newPath;
  1635. #else
  1636. # ifdef MAXPATHLEN
  1637. char resolved_name[MAXPATHLEN];
  1638. # else
  1639. # ifdef PATH_MAX
  1640. char resolved_name[PATH_MAX];
  1641. # else
  1642. char resolved_name[5024];
  1643. # endif
  1644. # endif
  1645. if(dir != "")
  1646. {
  1647. realpath(dir.c_str(), resolved_name);
  1648. dir = resolved_name;
  1649. }
  1650. else
  1651. {
  1652. dir = cmSystemTools::GetCurrentWorkingDirectory();
  1653. }
  1654. if(file == "")
  1655. {
  1656. return dir;
  1657. }
  1658. return dir + "/" + file;
  1659. #endif
  1660. }
  1661. bool cmSystemTools::Split(const char* str, std::vector<cmStdString>& lines)
  1662. {
  1663. std::string data(str);
  1664. std::string::size_type lpos = 0;
  1665. while(lpos < data.length())
  1666. {
  1667. std::string::size_type rpos = data.find_first_of("\n", lpos);
  1668. if(rpos == std::string::npos)
  1669. {
  1670. // Line ends at end of string without a newline.
  1671. lines.push_back(data.substr(lpos));
  1672. return false;
  1673. }
  1674. if((rpos > lpos) && (data[rpos-1] == '\r'))
  1675. {
  1676. // Line ends in a "\r\n" pair, remove both characters.
  1677. lines.push_back(data.substr(lpos, (rpos-1)-lpos));
  1678. }
  1679. else
  1680. {
  1681. // Line ends in a "\n", remove the character.
  1682. lines.push_back(data.substr(lpos, rpos-lpos));
  1683. }
  1684. lpos = rpos+1;
  1685. }
  1686. return true;
  1687. }
  1688. /**
  1689. * Return path of a full filename (no trailing slashes).
  1690. * Warning: returned path is converted to Unix slashes format.
  1691. */
  1692. std::string cmSystemTools::GetFilenamePath(const std::string& filename)
  1693. {
  1694. std::string fn = filename;
  1695. cmSystemTools::ConvertToUnixSlashes(fn);
  1696. std::string::size_type slash_pos = fn.rfind("/");
  1697. if(slash_pos != std::string::npos)
  1698. {
  1699. return fn.substr(0, slash_pos);
  1700. }
  1701. else
  1702. {
  1703. return "";
  1704. }
  1705. }
  1706. /**
  1707. * Return file name of a full filename (i.e. file name without path).
  1708. */
  1709. std::string cmSystemTools::GetFilenameName(const std::string& filename)
  1710. {
  1711. std::string fn = filename;
  1712. cmSystemTools::ConvertToUnixSlashes(fn);
  1713. std::string::size_type slash_pos = fn.rfind("/");
  1714. if(slash_pos != std::string::npos)
  1715. {
  1716. return fn.substr(slash_pos + 1);
  1717. }
  1718. else
  1719. {
  1720. return filename;
  1721. }
  1722. }
  1723. /**
  1724. * Return file extension of a full filename (dot included).
  1725. * Warning: this is the longest extension (for example: .tar.gz)
  1726. */
  1727. std::string cmSystemTools::GetFilenameExtension(const std::string& filename)
  1728. {
  1729. std::string name = cmSystemTools::GetFilenameName(filename);
  1730. std::string::size_type dot_pos = name.find(".");
  1731. if(dot_pos != std::string::npos)
  1732. {
  1733. return name.substr(dot_pos);
  1734. }
  1735. else
  1736. {
  1737. return "";
  1738. }
  1739. }
  1740. /**
  1741. * Return file name without extension of a full filename (i.e. without path).
  1742. * Warning: it considers the longest extension (for example: .tar.gz)
  1743. */
  1744. std::string cmSystemTools::GetFilenameWithoutExtension(const std::string& filename)
  1745. {
  1746. std::string name = cmSystemTools::GetFilenameName(filename);
  1747. std::string::size_type dot_pos = name.find(".");
  1748. if(dot_pos != std::string::npos)
  1749. {
  1750. return name.substr(0, dot_pos);
  1751. }
  1752. else
  1753. {
  1754. return name;
  1755. }
  1756. }
  1757. /**
  1758. * Return file name without extension of a full filename (i.e. without path).
  1759. * Warning: it considers the last extension (for example: removes .gz
  1760. * from .tar.gz)
  1761. */
  1762. std::string
  1763. cmSystemTools::GetFilenameWithoutLastExtension(const std::string& filename)
  1764. {
  1765. std::string name = cmSystemTools::GetFilenameName(filename);
  1766. std::string::size_type dot_pos = name.rfind(".");
  1767. if(dot_pos != std::string::npos)
  1768. {
  1769. return name.substr(0, dot_pos);
  1770. }
  1771. else
  1772. {
  1773. return name;
  1774. }
  1775. }
  1776. bool cmSystemTools::FileIsFullPath(const char* in_name)
  1777. {
  1778. std::string name = in_name;
  1779. #if defined(_WIN32)
  1780. // On Windows, the name must be at least two characters long.
  1781. if(name.length() < 2)
  1782. {
  1783. return false;
  1784. }
  1785. if(name[1] == ':')
  1786. {
  1787. return true;
  1788. }
  1789. if(name[0] == '\\')
  1790. {
  1791. return true;
  1792. }
  1793. #else
  1794. // On UNIX, the name must be at least one character long.
  1795. if(name.length() < 1)
  1796. {
  1797. return false;
  1798. }
  1799. #endif
  1800. // On UNIX, the name must begin in a '/'.
  1801. // On Windows, if the name begins in a '/', then it is a full
  1802. // network path.
  1803. if(name[0] == '/')
  1804. {
  1805. return true;
  1806. }
  1807. return false;
  1808. }
  1809. void cmSystemTools::Glob(const char *directory, const char *regexp,
  1810. std::vector<std::string>& files)
  1811. {
  1812. cmDirectory d;
  1813. cmRegularExpression reg(regexp);
  1814. if (d.Load(directory))
  1815. {
  1816. size_t numf;
  1817. unsigned int i;
  1818. numf = d.GetNumberOfFiles();
  1819. for (i = 0; i < numf; i++)
  1820. {
  1821. std::string fname = d.GetFile(i);
  1822. if (reg.find(fname))
  1823. {
  1824. files.push_back(fname);
  1825. }
  1826. }
  1827. }
  1828. }
  1829. void cmSystemTools::GlobDirs(const char *fullPath,
  1830. std::vector<std::string>& files)
  1831. {
  1832. std::string path = fullPath;
  1833. std::string::size_type pos = path.find("/*");
  1834. if(pos == std::string::npos)
  1835. {
  1836. files.push_back(fullPath);
  1837. return;
  1838. }
  1839. std::string startPath = path.substr(0, pos);
  1840. std::string finishPath = path.substr(pos+2);
  1841. cmDirectory d;
  1842. if (d.Load(startPath.c_str()))
  1843. {
  1844. for (unsigned int i = 0; i < d.GetNumberOfFiles(); ++i)
  1845. {
  1846. if((std::string(d.GetFile(i)) != ".")
  1847. && (std::string(d.GetFile(i)) != ".."))
  1848. {
  1849. std::string fname = startPath;
  1850. fname +="/";
  1851. fname += d.GetFile(i);
  1852. if(cmSystemTools::FileIsDirectory(fname.c_str()))
  1853. {
  1854. fname += finishPath;
  1855. cmSystemTools::GlobDirs(fname.c_str(), files);
  1856. }
  1857. }
  1858. }
  1859. }
  1860. }
  1861. void cmSystemTools::ExpandList(std::vector<std::string> const& arguments,
  1862. std::vector<std::string>& newargs)
  1863. {
  1864. std::vector<std::string>::const_iterator i;
  1865. for(i = arguments.begin();i != arguments.end(); ++i)
  1866. {
  1867. cmSystemTools::ExpandListArgument(*i, newargs);
  1868. }
  1869. }
  1870. void cmSystemTools::ExpandListArgument(const std::string& arg,
  1871. std::vector<std::string>& newargs)
  1872. {
  1873. std::string newarg;
  1874. // If argument is empty, it is an empty list.
  1875. if(arg.length() == 0)
  1876. {
  1877. return;
  1878. }
  1879. // if there are no ; in the name then just copy the current string
  1880. if(arg.find(';') == std::string::npos)
  1881. {
  1882. newargs.push_back(arg);
  1883. }
  1884. else
  1885. {
  1886. std::string::size_type start = 0;
  1887. std::string::size_type endpos = 0;
  1888. const std::string::size_type size = arg.size();
  1889. // break up ; separated sections of the string into separate strings
  1890. while(endpos != size)
  1891. {
  1892. endpos = arg.find(';', start);
  1893. if(endpos == std::string::npos)
  1894. {
  1895. endpos = arg.size();
  1896. }
  1897. else
  1898. {
  1899. // skip right over escaped ; ( \; )
  1900. while((endpos != std::string::npos)
  1901. && (endpos > 0)
  1902. && ((arg)[endpos-1] == '\\') )
  1903. {
  1904. endpos = arg.find(';', endpos+1);
  1905. }
  1906. if(endpos == std::string::npos)
  1907. {
  1908. endpos = arg.size();
  1909. }
  1910. }
  1911. std::string::size_type len = endpos - start;
  1912. if (len > 0)
  1913. {
  1914. // check for a closing ] after the start position
  1915. if(arg.find('[', start) == std::string::npos)
  1916. {
  1917. // if there is no [ in the string then keep it
  1918. newarg = arg.substr(start, len);
  1919. }
  1920. else
  1921. {
  1922. int opencount = 0;
  1923. int closecount = 0;
  1924. for(std::string::size_type j = start; j < endpos; ++j)
  1925. {
  1926. if(arg.at(j) == '[')
  1927. {
  1928. ++opencount;
  1929. }
  1930. else if (arg.at(j) == ']')
  1931. {
  1932. ++closecount;
  1933. }
  1934. }
  1935. if(opencount != closecount)
  1936. {
  1937. // skip this one
  1938. endpos = arg.find(';', endpos+1);
  1939. if(endpos == std::string::npos)
  1940. {
  1941. endpos = arg.size();
  1942. }
  1943. len = endpos - start;
  1944. }
  1945. newarg = arg.substr(start, len);
  1946. }
  1947. std::string::size_type pos = newarg.find("\\;");
  1948. if(pos != std::string::npos)
  1949. {
  1950. newarg.erase(pos, 1);
  1951. }
  1952. newargs.push_back(newarg);
  1953. }
  1954. start = endpos+1;
  1955. }
  1956. }
  1957. }
  1958. bool cmSystemTools::GetShortPath(const char* path, std::string& shortPath)
  1959. {
  1960. #if defined(WIN32) && !defined(__CYGWIN__)
  1961. const int size = int(strlen(path)) +1; // size of return
  1962. char *buffer = new char[size]; // create a buffer
  1963. char *tempPath = new char[size]; // create a buffer
  1964. int ret;
  1965. // if the path passed in has quotes around it, first remove the quotes
  1966. if (path[0] == '"' && path[strlen(path)-1] == '"')
  1967. {
  1968. strcpy(tempPath,path+1);
  1969. tempPath[strlen(tempPath)-1] = '\0';
  1970. }
  1971. else
  1972. {
  1973. strcpy(tempPath,path);
  1974. }
  1975. buffer[0] = 0;
  1976. ret = GetShortPathName(tempPath, buffer, size);
  1977. if(buffer[0] == 0 || ret > size)
  1978. {
  1979. if(ret < size)
  1980. {
  1981. LPVOID lpMsgBuf;
  1982. FormatMessage(
  1983. FORMAT_MESSAGE_ALLOCATE_BUFFER |
  1984. FORMAT_MESSAGE_FROM_SYSTEM |
  1985. FORMAT_MESSAGE_IGNORE_INSERTS,
  1986. NULL,
  1987. GetLastError(),
  1988. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  1989. (LPTSTR) &lpMsgBuf,
  1990. 0,
  1991. NULL
  1992. );
  1993. cmSystemTools::Error((LPCTSTR)lpMsgBuf);
  1994. LocalFree( lpMsgBuf );
  1995. }
  1996. cmSystemTools::Error("Unable to get a short path: ", path);
  1997. delete [] tempPath;
  1998. return false;
  1999. }
  2000. else
  2001. {
  2002. shortPath = buffer;
  2003. delete [] buffer;
  2004. delete [] tempPath;
  2005. return true;
  2006. }
  2007. #else
  2008. shortPath = path;
  2009. return true;
  2010. #endif
  2011. }
  2012. bool cmSystemTools::SimpleGlob(const std::string& glob,
  2013. std::vector<std::string>& files,
  2014. int type /* = 0 */)
  2015. {
  2016. files.clear();
  2017. if ( glob[glob.size()-1] != '*' )
  2018. {
  2019. return false;
  2020. }
  2021. std::string path = cmSystemTools::GetFilenamePath(glob);
  2022. std::string ppath = cmSystemTools::GetFilenameName(glob);
  2023. ppath = ppath.substr(0, ppath.size()-1);
  2024. if ( path.size() == 0 )
  2025. {
  2026. path = "/";
  2027. }
  2028. bool res = false;
  2029. cmDirectory d;
  2030. if (d.Load(path.c_str()))
  2031. {
  2032. for (unsigned int i = 0; i < d.GetNumberOfFiles(); ++i)
  2033. {
  2034. if((std::string(d.GetFile(i)) != ".")
  2035. && (std::string(d.GetFile(i)) != ".."))
  2036. {
  2037. std::string fname = path;
  2038. if ( path[path.size()-1] != '/' )
  2039. {
  2040. fname +="/";
  2041. }
  2042. fname += d.GetFile(i);
  2043. std::string sfname = d.GetFile(i);
  2044. if ( type > 0 && cmSystemTools::FileIsDirectory(fname.c_str()) )
  2045. {
  2046. continue;
  2047. }
  2048. if ( type < 0 && !cmSystemTools::FileIsDirectory(fname.c_str()) )
  2049. {
  2050. continue;
  2051. }
  2052. if ( sfname.size() >= ppath.size() &&
  2053. sfname.substr(0, ppath.size()) ==
  2054. ppath )
  2055. {
  2056. files.push_back(fname);
  2057. res = true;
  2058. }
  2059. }
  2060. }
  2061. }
  2062. return res;
  2063. }
  2064. cmSystemTools::FileFormat cmSystemTools::GetFileFormat(const char* cext)
  2065. {
  2066. if ( ! cext || *cext == 0 )
  2067. {
  2068. return cmSystemTools::NO_FILE_FORMAT;
  2069. }
  2070. std::string ext = cmSystemTools::LowerCase(cext);
  2071. if ( ext == "c" || ext == ".c" ) { return cmSystemTools::C_FILE_FORMAT; }
  2072. if ( ext == "cxx" || ext == ".cxx" ||
  2073. ext == "cpp" || ext == ".cpp" ||
  2074. ext == "c++" || ext == ".c++" ||
  2075. ext == "mm" || ext == ".mm" ||
  2076. ext == "cc" || ext == ".cc" ) { return cmSystemTools::CXX_FILE_FORMAT; }
  2077. if ( ext == "java" || ext == ".java" ) { return cmSystemTools::JAVA_FILE_FORMAT; }
  2078. if ( ext == "h" || ext == ".h" ||
  2079. ext == "hpp" || ext == ".hpp" ||
  2080. ext == "h++" || ext == ".h++" ||
  2081. ext == "hxx" || ext == ".hxx" ) { return cmSystemTools::HEADER_FILE_FORMAT; }
  2082. if ( ext == "rc" || ext == ".rc" ) { return cmSystemTools::RESOURCE_FILE_FORMAT; }
  2083. if ( ext == "def" || ext == ".def" ) { return cmSystemTools::DEFINITION_FILE_FORMAT; }
  2084. if ( ext == "lib" || ext == ".lib" ||
  2085. ext == "a" || ext == ".a") { return cmSystemTools::STATIC_LIBRARY_FILE_FORMAT; }
  2086. if ( ext == "o" || ext == ".o" ||
  2087. ext == "obj" || ext == ".obj") { return cmSystemTools::OBJECT_FILE_FORMAT; }
  2088. #ifdef __APPLE__
  2089. if ( ext == "dylib" || ext == ".dylib" )
  2090. { return cmSystemTools::SHARED_LIBRARY_FILE_FORMAT; }
  2091. if ( ext == "so" || ext == ".so" ||
  2092. ext == "bundle" || ext == ".bundle" )
  2093. { return cmSystemTools::MODULE_FILE_FORMAT; }
  2094. #else // __APPLE__
  2095. if ( ext == "so" || ext == ".so" ||
  2096. ext == "sl" || ext == ".sl" ||
  2097. ext == "dll" || ext == ".dll" )
  2098. { return cmSystemTools::SHARED_LIBRARY_FILE_FORMAT; }
  2099. #endif // __APPLE__
  2100. return cmSystemTools::UNKNOWN_FILE_FORMAT;
  2101. }
  2102. void cmSystemTools::SplitProgramFromArgs(const char* path,
  2103. std::string& program, std::string& args)
  2104. {
  2105. if(cmSystemTools::FileExists(path))
  2106. {
  2107. program = path;
  2108. args = "";
  2109. return;
  2110. }
  2111. std::vector<std::string> e;
  2112. std::string findProg = cmSystemTools::FindProgram(path, e);
  2113. if(findProg.size())
  2114. {
  2115. program = findProg;
  2116. args = "";
  2117. return;
  2118. }
  2119. std::string dir = path;
  2120. std::string::size_type spacePos = dir.rfind(' ');
  2121. if(spacePos == std::string::npos)
  2122. {
  2123. program = "";
  2124. args = "";
  2125. return;
  2126. }
  2127. while(spacePos != std::string::npos)
  2128. {
  2129. std::string tryProg = dir.substr(0, spacePos);
  2130. if(cmSystemTools::FileExists(tryProg.c_str()))
  2131. {
  2132. program = tryProg;
  2133. args = dir.substr(spacePos, dir.size()-spacePos);
  2134. return;
  2135. }
  2136. findProg = cmSystemTools::FindProgram(tryProg.c_str(), e);
  2137. if(findProg.size())
  2138. {
  2139. program = findProg;
  2140. args = dir.substr(spacePos, dir.size()-spacePos);
  2141. return;
  2142. }
  2143. spacePos = dir.rfind(' ', spacePos--);
  2144. }
  2145. program = "";
  2146. args = "";
  2147. }
  2148. #if defined(_MSC_VER) && defined(_DEBUG)
  2149. # include <crtdbg.h>
  2150. # include <stdio.h>
  2151. # include <stdlib.h>
  2152. static int cmSystemToolsDebugReport(int, char* message, int*)
  2153. {
  2154. fprintf(stderr, message);
  2155. exit(1);
  2156. return 0;
  2157. }
  2158. void cmSystemTools::EnableMSVCDebugHook()
  2159. {
  2160. if(getenv("DART_TEST_FROM_DART"))
  2161. {
  2162. _CrtSetReportHook(cmSystemToolsDebugReport);
  2163. }
  2164. }
  2165. #else
  2166. void cmSystemTools::EnableMSVCDebugHook()
  2167. {
  2168. }
  2169. #endif