cmSystemTools.cxx 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. /*=========================================================================
  2. Program: Insight Segmentation & Registration Toolkit
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2000 National Library of Medicine
  8. All rights reserved.
  9. See COPYRIGHT.txt for copyright details.
  10. =========================================================================*/
  11. #include "cmSystemTools.h"
  12. #include "errno.h"
  13. #include <sys/stat.h>
  14. #include "cmRegularExpression.h"
  15. #if defined(_MSC_VER) || defined(__BORLANDC__)
  16. #include <windows.h>
  17. #include <direct.h>
  18. inline int Mkdir(const char* dir)
  19. {
  20. return _mkdir(dir);
  21. }
  22. #else
  23. #include <sys/types.h>
  24. #include <fcntl.h>
  25. #include <unistd.h>
  26. inline int Mkdir(const char* dir)
  27. {
  28. return mkdir(dir, 00700);
  29. }
  30. #endif
  31. // adds the elements of the env variable path to the arg passed in
  32. void cmSystemTools::GetPath(std::vector<std::string>& path)
  33. {
  34. #if defined(_WIN32) && !defined(__CYGWIN__)
  35. char* pathSep = ";";
  36. #else
  37. char* pathSep = ":";
  38. #endif
  39. std::string pathEnv = getenv("PATH");
  40. std::string::size_type start =0;
  41. bool done = false;
  42. while(!done)
  43. {
  44. std::string::size_type endpos = pathEnv.find(pathSep, start);
  45. if(endpos != std::string::npos)
  46. {
  47. path.push_back(pathEnv.substr(start, endpos-start));
  48. start = endpos+1;
  49. }
  50. else
  51. {
  52. done = true;
  53. }
  54. }
  55. }
  56. bool cmSystemTools::MakeDirectory(const char* path)
  57. {
  58. std::string dir = path;
  59. // replace all of the \ with /
  60. size_t pos = 0;
  61. while((pos = dir.find('\\', pos)) != std::string::npos)
  62. {
  63. dir[pos] = '/';
  64. pos++;
  65. }
  66. pos = dir.find(':');
  67. if(pos == std::string::npos)
  68. {
  69. pos = 0;
  70. }
  71. while((pos = dir.find('/', pos)) != std::string::npos)
  72. {
  73. std::string topdir = dir.substr(0, pos);
  74. Mkdir(topdir.c_str());
  75. pos++;
  76. }
  77. if(Mkdir(path) != 0)
  78. {
  79. // if it is some other error besides directory exists
  80. // then return false
  81. if(errno != EEXIST)
  82. {
  83. return false;
  84. }
  85. }
  86. return true;
  87. }
  88. // replace replace with with as many times as it shows up in source.
  89. // write the result into source.
  90. void cmSystemTools::ReplaceString(std::string& source,
  91. const char* replace,
  92. const char* with)
  93. {
  94. int lengthReplace = strlen(replace);
  95. std::string rest;
  96. size_t start = source.find(replace);
  97. while(start != std::string::npos)
  98. {
  99. rest = source.substr(start+lengthReplace);
  100. source = source.substr(0, start);
  101. source += with;
  102. source += rest;
  103. start = source.find(replace, start + lengthReplace );
  104. }
  105. }
  106. // return true if the file exists
  107. bool cmSystemTools::FileExists(const char* filename)
  108. {
  109. struct stat fs;
  110. if (stat(filename, &fs) != 0)
  111. {
  112. return false;
  113. }
  114. else
  115. {
  116. return true;
  117. }
  118. }
  119. // convert windows slashes to unix slashes \ with /
  120. void cmSystemTools::ConvertToUnixSlashes(std::string& path)
  121. {
  122. std::string::size_type pos = path.find('\\');
  123. while(pos != std::string::npos)
  124. {
  125. path[pos] = '/';
  126. pos = path.find('\\');
  127. }
  128. // remove any trailing slash
  129. if(path[path.size()-1] == '/')
  130. {
  131. path = path.substr(0, path.size()-1);
  132. }
  133. }
  134. int cmSystemTools::Grep(const char* dir, const char* file, const char* expression)
  135. {
  136. std::string path = dir;
  137. path += "/";
  138. path += file;
  139. std::ifstream fin(path.c_str());
  140. char buffer[2056];
  141. int count = 0;
  142. cmRegularExpression reg(expression);
  143. while(fin)
  144. {
  145. fin.getline(buffer, sizeof(buffer));
  146. count += reg.find(buffer);
  147. }
  148. return count;
  149. }
  150. void cmSystemTools::ConvertCygwinPath(std::string& pathname)
  151. {
  152. if(pathname.find("/cygdrive/") != std::string::npos)
  153. {
  154. std::string cygStuff = pathname.substr(0, 11);
  155. std::string replace;
  156. replace += cygStuff.at(10);
  157. replace += ":";
  158. cmSystemTools::ReplaceString(pathname, cygStuff.c_str(), replace.c_str());
  159. }
  160. }
  161. bool cmSystemTools::ParseFunction(std::ifstream& fin,
  162. std::string& name,
  163. std::vector<std::string>& arguments)
  164. {
  165. name = "";
  166. arguments = std::vector<std::string>();
  167. const int BUFFER_SIZE = 4096;
  168. char inbuffer[BUFFER_SIZE];
  169. if(!fin)
  170. {
  171. return false;
  172. }
  173. if(fin.getline(inbuffer, BUFFER_SIZE ) )
  174. {
  175. cmRegularExpression blankLine("^$");
  176. cmRegularExpression comment("^#.*");
  177. cmRegularExpression oneLiner("[ \t]*([A-Za-z_0-9]*).*\\((.*)\\)");
  178. cmRegularExpression multiLine("[ \t]*([A-Za-z_0-9]*).*\\((.*)");
  179. cmRegularExpression lastLine("(.*)\\)");
  180. // BEGIN VERBATIM JUNK SHOULD BE REMOVED
  181. cmRegularExpression verbatim("BEGIN MAKE VERBATIM");
  182. if(verbatim.find(inbuffer))
  183. {
  184. cmRegularExpression endVerbatim("END MAKE VERBATIM");
  185. name = "VERBATIM";
  186. bool done = false;
  187. while(!done)
  188. {
  189. if(fin.getline(inbuffer, BUFFER_SIZE))
  190. {
  191. if(endVerbatim.find(inbuffer))
  192. {
  193. done = true;
  194. }
  195. else
  196. {
  197. arguments.push_back(inbuffer);
  198. }
  199. }
  200. else
  201. {
  202. done = true;
  203. }
  204. }
  205. return true;
  206. }
  207. // END VERBATIM JUNK SHOULD BE REMOVED
  208. // check for black line or comment
  209. if(blankLine.find(inbuffer) || comment.find(inbuffer))
  210. {
  211. return false;
  212. }
  213. // look for a oneline fun(arg arg2)
  214. else if(oneLiner.find(inbuffer))
  215. {
  216. // the arguments are the second match
  217. std::string args = oneLiner.match(2);
  218. name = oneLiner.match(1);
  219. // break up the arguments
  220. cmSystemTools::GetArguments(args, arguments);
  221. return true;
  222. }
  223. // look for a start of a multiline with no trailing ")" fun(arg arg2
  224. else if(multiLine.find(inbuffer))
  225. {
  226. name = multiLine.match(1);
  227. std::string args = multiLine.match(2);
  228. cmSystemTools::GetArguments(args, arguments);
  229. // Read lines until the closing paren is hit
  230. bool done = false;
  231. while(!done)
  232. {
  233. // read lines until the end paren is found
  234. if(fin.getline(inbuffer, BUFFER_SIZE ) )
  235. {
  236. if(lastLine.find(inbuffer))
  237. {
  238. done = true;
  239. std::string args = lastLine.match(1);
  240. cmSystemTools::GetArguments(args, arguments);
  241. }
  242. else
  243. {
  244. std::string line = inbuffer;
  245. cmSystemTools::GetArguments(line, arguments);
  246. }
  247. }
  248. else
  249. {
  250. cmSystemTools::Error("Parse error in read function missing end )",
  251. inbuffer);
  252. return false;
  253. }
  254. }
  255. return true;
  256. }
  257. else
  258. {
  259. cmSystemTools::Error("Parse error in read function ", inbuffer);
  260. return false;
  261. }
  262. }
  263. return false;
  264. }
  265. void cmSystemTools::GetArguments(std::string& line,
  266. std::vector<std::string>& arguments)
  267. {
  268. cmRegularExpression argument("[\t ]*([-/\\.\\\\{}\\$A-Za-z_0-9]+)[\t ]*");
  269. cmRegularExpression argumentWithSpaces("[\t ]*\"([-\\. /\\\\{}\\$A-Za-z_0-9]+)\"[\t ]*");
  270. std::string arg(" ");
  271. while(arg.length() )
  272. {
  273. arg = "";
  274. long endpos;
  275. if (argumentWithSpaces.find(line.c_str()))
  276. {
  277. arg = argumentWithSpaces.match(1);
  278. endpos = argumentWithSpaces.end(1);
  279. }
  280. else if(argument.find(line.c_str()))
  281. {
  282. arg = argument.match(1);
  283. endpos = argument.end(1);
  284. }
  285. if(arg.length())
  286. {
  287. arguments.push_back(arg);
  288. line = line.substr(endpos, line.length() - endpos);
  289. }
  290. }
  291. }
  292. void cmSystemTools::Error(const char* m1, const char* m2)
  293. {
  294. std::string message = "CMake Error: ";
  295. if(m1)
  296. {
  297. message += m1;
  298. }
  299. if(m2)
  300. {
  301. message += m2;
  302. }
  303. #ifdef _WIN32
  304. // MessageBox(0, message.c_str(), 0, MB_OK);
  305. std::cerr << message.c_str() << std::endl;
  306. #else
  307. std::cerr << message.c_str() << std::endl;
  308. #endif
  309. }