cmSeparateArgumentsCommand.cxx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
  4. Distributed under the OSI-approved BSD License (the "License");
  5. see accompanying file Copyright.txt for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even the
  7. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the License for more information.
  9. ============================================================================*/
  10. #include "cmSeparateArgumentsCommand.h"
  11. // cmSeparateArgumentsCommand
  12. bool cmSeparateArgumentsCommand::InitialPass(
  13. std::vector<std::string> const& args, cmExecutionStatus&)
  14. {
  15. if (args.empty()) {
  16. this->SetError("must be given at least one argument.");
  17. return false;
  18. }
  19. std::string var;
  20. std::string command;
  21. enum Mode
  22. {
  23. ModeOld,
  24. ModeUnix,
  25. ModeWindows
  26. };
  27. Mode mode = ModeOld;
  28. enum Doing
  29. {
  30. DoingNone,
  31. DoingVariable,
  32. DoingMode,
  33. DoingCommand
  34. };
  35. Doing doing = DoingVariable;
  36. for (unsigned int i = 0; i < args.size(); ++i) {
  37. if (doing == DoingVariable) {
  38. var = args[i];
  39. doing = DoingMode;
  40. } else if (doing == DoingMode && args[i] == "UNIX_COMMAND") {
  41. mode = ModeUnix;
  42. doing = DoingCommand;
  43. } else if (doing == DoingMode && args[i] == "WINDOWS_COMMAND") {
  44. mode = ModeWindows;
  45. doing = DoingCommand;
  46. } else if (doing == DoingCommand) {
  47. command = args[i];
  48. doing = DoingNone;
  49. } else {
  50. std::ostringstream e;
  51. e << "given unknown argument " << args[i];
  52. this->SetError(e.str());
  53. return false;
  54. }
  55. }
  56. if (mode == ModeOld) {
  57. // Original space-replacement version of command.
  58. if (const char* def = this->Makefile->GetDefinition(var)) {
  59. std::string value = def;
  60. std::replace(value.begin(), value.end(), ' ', ';');
  61. this->Makefile->AddDefinition(var, value.c_str());
  62. }
  63. } else {
  64. // Parse the command line.
  65. std::vector<std::string> vec;
  66. if (mode == ModeUnix) {
  67. cmSystemTools::ParseUnixCommandLine(command.c_str(), vec);
  68. } else // if(mode == ModeWindows)
  69. {
  70. cmSystemTools::ParseWindowsCommandLine(command.c_str(), vec);
  71. }
  72. // Construct the result list value.
  73. std::string value;
  74. const char* sep = "";
  75. for (std::vector<std::string>::const_iterator vi = vec.begin();
  76. vi != vec.end(); ++vi) {
  77. // Separate from the previous argument.
  78. value += sep;
  79. sep = ";";
  80. // Preserve semicolons.
  81. for (std::string::const_iterator si = vi->begin(); si != vi->end();
  82. ++si) {
  83. if (*si == ';') {
  84. value += '\\';
  85. }
  86. value += *si;
  87. }
  88. }
  89. this->Makefile->AddDefinition(var, value.c_str());
  90. }
  91. return true;
  92. }