cmCMakeLanguageCommand.cxx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #include "cmCMakeLanguageCommand.h"
  4. #include <algorithm>
  5. #include <cstddef>
  6. #include <memory>
  7. #include <string>
  8. #include "cmExecutionStatus.h"
  9. #include "cmListFileCache.h"
  10. #include "cmMakefile.h"
  11. #include "cmRange.h"
  12. #include "cmStringAlgorithms.h"
  13. bool cmCMakeLanguageCommand(std::vector<cmListFileArgument> const& args,
  14. cmExecutionStatus& status)
  15. {
  16. if (args.empty()) {
  17. status.SetError("called with incorrect number of arguments");
  18. return false;
  19. }
  20. cmMakefile& makefile = status.GetMakefile();
  21. cmListFileContext context = makefile.GetExecutionContext();
  22. bool result = false;
  23. std::vector<std::string> dispatchExpandedArgs;
  24. std::vector<cmListFileArgument> dispatchArgs;
  25. dispatchArgs.emplace_back(args[0]);
  26. makefile.ExpandArguments(dispatchArgs, dispatchExpandedArgs);
  27. if (dispatchExpandedArgs.empty()) {
  28. status.SetError("called with incorrect number of arguments");
  29. return false;
  30. }
  31. if (dispatchExpandedArgs[0] == "CALL") {
  32. if ((args.size() == 1 && dispatchExpandedArgs.size() != 2) ||
  33. dispatchExpandedArgs.size() > 2) {
  34. status.SetError("called with incorrect number of arguments");
  35. return false;
  36. }
  37. // First argument is the name of the function to call
  38. std::string callCommand;
  39. size_t startArg;
  40. if (dispatchExpandedArgs.size() == 1) {
  41. std::vector<std::string> functionExpandedArg;
  42. std::vector<cmListFileArgument> functionArg;
  43. functionArg.emplace_back(args[1]);
  44. makefile.ExpandArguments(functionArg, functionExpandedArg);
  45. if (functionExpandedArg.size() != 1) {
  46. status.SetError("called with incorrect number of arguments");
  47. return false;
  48. }
  49. callCommand = functionExpandedArg[0];
  50. startArg = 2;
  51. } else {
  52. callCommand = dispatchExpandedArgs[1];
  53. startArg = 1;
  54. }
  55. cmListFileFunction func;
  56. func.Name = callCommand;
  57. func.Line = context.Line;
  58. // The rest of the arguments are passed to the function call above
  59. for (size_t i = startArg; i < args.size(); ++i) {
  60. cmListFileArgument lfarg;
  61. lfarg.Delim = args[i].Delim;
  62. lfarg.Line = context.Line;
  63. lfarg.Value = args[i].Value;
  64. func.Arguments.emplace_back(lfarg);
  65. }
  66. result = makefile.ExecuteCommand(func, status);
  67. } else if (dispatchExpandedArgs[0] == "EVAL") {
  68. std::vector<std::string> expandedArgs;
  69. makefile.ExpandArguments(args, expandedArgs);
  70. if (expandedArgs.size() < 2) {
  71. status.SetError("called with incorrect number of arguments");
  72. return false;
  73. }
  74. if (expandedArgs[1] != "CODE") {
  75. auto code_iter =
  76. std::find(expandedArgs.begin() + 2, expandedArgs.end(), "CODE");
  77. if (code_iter == expandedArgs.end()) {
  78. status.SetError("called without CODE argument");
  79. } else {
  80. status.SetError(
  81. "called with unsupported arguments between EVAL and CODE arguments");
  82. }
  83. return false;
  84. }
  85. const std::string code =
  86. cmJoin(cmMakeRange(expandedArgs.begin() + 2, expandedArgs.end()), " ");
  87. result = makefile.ReadListFileAsString(
  88. code, cmStrCat(context.FilePath, ":", context.Line, ":EVAL"));
  89. } else {
  90. status.SetError("called with unknown meta-operation");
  91. }
  92. return result;
  93. }