resolve cyclic dependency with zstd
[platform/upstream/cmake.git] / Source / cmAddTestCommand.cxx
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 "cmAddTestCommand.h"
4
5 #include <cm/memory>
6
7 #include "cmExecutionStatus.h"
8 #include "cmMakefile.h"
9 #include "cmStringAlgorithms.h"
10 #include "cmTest.h"
11 #include "cmTestGenerator.h"
12
13 static bool cmAddTestCommandHandleNameMode(
14   std::vector<std::string> const& args, cmExecutionStatus& status);
15
16 bool cmAddTestCommand(std::vector<std::string> const& args,
17                       cmExecutionStatus& status)
18 {
19   if (!args.empty() && args[0] == "NAME") {
20     return cmAddTestCommandHandleNameMode(args, status);
21   }
22
23   // First argument is the name of the test Second argument is the name of
24   // the executable to run (a target or external program) Remaining arguments
25   // are the arguments to pass to the executable
26   if (args.size() < 2) {
27     status.SetError("called with incorrect number of arguments");
28     return false;
29   }
30
31   cmMakefile& mf = status.GetMakefile();
32   // Collect the command with arguments.
33   std::vector<std::string> command(args.begin() + 1, args.end());
34
35   // Create the test but add a generator only the first time it is
36   // seen.  This preserves behavior from before test generators.
37   cmTest* test = mf.GetTest(args[0]);
38   if (test) {
39     // If the test was already added by a new-style signature do not
40     // allow it to be duplicated.
41     if (!test->GetOldStyle()) {
42       status.SetError(cmStrCat(" given test name \"", args[0],
43                                "\" which already exists in this directory."));
44       return false;
45     }
46   } else {
47     test = mf.CreateTest(args[0]);
48     test->SetOldStyle(true);
49     mf.AddTestGenerator(cm::make_unique<cmTestGenerator>(test));
50   }
51   test->SetCommand(command);
52
53   return true;
54 }
55
56 bool cmAddTestCommandHandleNameMode(std::vector<std::string> const& args,
57                                     cmExecutionStatus& status)
58 {
59   std::string name;
60   std::vector<std::string> configurations;
61   std::string working_directory;
62   std::vector<std::string> command;
63   bool command_expand_lists = false;
64
65   // Read the arguments.
66   enum Doing
67   {
68     DoingName,
69     DoingCommand,
70     DoingConfigs,
71     DoingWorkingDirectory,
72     DoingNone
73   };
74   Doing doing = DoingName;
75   for (unsigned int i = 1; i < args.size(); ++i) {
76     if (args[i] == "COMMAND") {
77       if (!command.empty()) {
78         status.SetError(" may be given at most one COMMAND.");
79         return false;
80       }
81       doing = DoingCommand;
82     } else if (args[i] == "CONFIGURATIONS") {
83       if (!configurations.empty()) {
84         status.SetError(" may be given at most one set of CONFIGURATIONS.");
85         return false;
86       }
87       doing = DoingConfigs;
88     } else if (args[i] == "WORKING_DIRECTORY") {
89       if (!working_directory.empty()) {
90         status.SetError(" may be given at most one WORKING_DIRECTORY.");
91         return false;
92       }
93       doing = DoingWorkingDirectory;
94     } else if (args[i] == "COMMAND_EXPAND_LISTS") {
95       if (command_expand_lists) {
96         status.SetError(" may be given at most one COMMAND_EXPAND_LISTS.");
97         return false;
98       }
99       command_expand_lists = true;
100       doing = DoingNone;
101     } else if (doing == DoingName) {
102       name = args[i];
103       doing = DoingNone;
104     } else if (doing == DoingCommand) {
105       command.push_back(args[i]);
106     } else if (doing == DoingConfigs) {
107       configurations.push_back(args[i]);
108     } else if (doing == DoingWorkingDirectory) {
109       working_directory = args[i];
110       doing = DoingNone;
111     } else {
112       status.SetError(cmStrCat(" given unknown argument:\n  ", args[i], "\n"));
113       return false;
114     }
115   }
116
117   // Require a test name.
118   if (name.empty()) {
119     status.SetError(" must be given non-empty NAME.");
120     return false;
121   }
122
123   // Require a command.
124   if (command.empty()) {
125     status.SetError(" must be given non-empty COMMAND.");
126     return false;
127   }
128
129   cmMakefile& mf = status.GetMakefile();
130
131   // Require a unique test name within the directory.
132   if (mf.GetTest(name)) {
133     status.SetError(cmStrCat(" given test NAME \"", name,
134                              "\" which already exists in this directory."));
135     return false;
136   }
137
138   // Add the test.
139   cmTest* test = mf.CreateTest(name);
140   test->SetOldStyle(false);
141   test->SetCommand(command);
142   if (!working_directory.empty()) {
143     test->SetProperty("WORKING_DIRECTORY", working_directory);
144   }
145   test->SetCommandExpandLists(command_expand_lists);
146   mf.AddTestGenerator(cm::make_unique<cmTestGenerator>(test, configurations));
147
148   return true;
149 }