cmSystemTools.cxx 7.2 KB

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