/src/CMake/Source/cmAddTestCommand.cxx
Line | Count | Source |
1 | | /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
2 | | file LICENSE.rst or https://cmake.org/licensing for details. */ |
3 | | #include "cmAddTestCommand.h" |
4 | | |
5 | | #include <algorithm> |
6 | | |
7 | | #include <cm/memory> |
8 | | |
9 | | #include "cmExecutionStatus.h" |
10 | | #include "cmMakefile.h" |
11 | | #include "cmPolicies.h" |
12 | | #include "cmStringAlgorithms.h" |
13 | | #include "cmTest.h" |
14 | | #include "cmTestGenerator.h" |
15 | | |
16 | | static std::string const keywordCMP0178 = "__CMP0178"; |
17 | | |
18 | | static bool cmAddTestCommandHandleNameMode( |
19 | | std::vector<std::string> const& args, cmExecutionStatus& status); |
20 | | |
21 | | bool cmAddTestCommand(std::vector<std::string> const& args, |
22 | | cmExecutionStatus& status) |
23 | 0 | { |
24 | 0 | if (!args.empty() && args[0] == "NAME") { |
25 | 0 | return cmAddTestCommandHandleNameMode(args, status); |
26 | 0 | } |
27 | | |
28 | | // First argument is the name of the test Second argument is the name of |
29 | | // the executable to run (a target or external program) Remaining arguments |
30 | | // are the arguments to pass to the executable |
31 | 0 | if (args.size() < 2) { |
32 | 0 | status.SetError("called with incorrect number of arguments"); |
33 | 0 | return false; |
34 | 0 | } |
35 | | |
36 | 0 | cmMakefile& mf = status.GetMakefile(); |
37 | 0 | cmPolicies::PolicyStatus cmp0178; |
38 | | |
39 | | // If the __CMP0178 keyword is present, it is always at the end |
40 | 0 | auto endOfCommandIter = |
41 | 0 | std::find(args.begin() + 2, args.end(), keywordCMP0178); |
42 | 0 | if (endOfCommandIter != args.end()) { |
43 | 0 | auto cmp0178Iter = endOfCommandIter + 1; |
44 | 0 | if (cmp0178Iter == args.end()) { |
45 | 0 | status.SetError(cmStrCat(keywordCMP0178, " keyword missing value")); |
46 | 0 | return false; |
47 | 0 | } |
48 | 0 | if (*cmp0178Iter == "NEW") { |
49 | 0 | cmp0178 = cmPolicies::PolicyStatus::NEW; |
50 | 0 | } else if (*cmp0178Iter == "OLD") { |
51 | 0 | cmp0178 = cmPolicies::PolicyStatus::OLD; |
52 | 0 | } else { |
53 | 0 | cmp0178 = cmPolicies::PolicyStatus::WARN; |
54 | 0 | } |
55 | 0 | } else { |
56 | 0 | cmp0178 = mf.GetPolicyStatus(cmPolicies::CMP0178); |
57 | 0 | } |
58 | | |
59 | | // Collect the command with arguments. |
60 | 0 | std::vector<std::string> command(args.begin() + 1, endOfCommandIter); |
61 | | |
62 | | // Create the test but add a generator only the first time it is |
63 | | // seen. This preserves behavior from before test generators. |
64 | 0 | cmTest* test = mf.GetTest(args[0]); |
65 | 0 | if (test) { |
66 | | // If the test was already added by a new-style signature do not |
67 | | // allow it to be duplicated. |
68 | 0 | if (!test->GetOldStyle()) { |
69 | 0 | status.SetError(cmStrCat(" given test name \"", args[0], |
70 | 0 | "\" which already exists in this directory.")); |
71 | 0 | return false; |
72 | 0 | } |
73 | 0 | } else { |
74 | 0 | test = mf.CreateTest(args[0]); |
75 | 0 | test->SetOldStyle(true); |
76 | 0 | test->SetCMP0178(cmp0178); |
77 | 0 | mf.AddTestGenerator(cm::make_unique<cmTestGenerator>(test)); |
78 | 0 | } |
79 | 0 | test->SetCommand(command); |
80 | |
|
81 | 0 | return true; |
82 | 0 | } |
83 | | |
84 | | bool cmAddTestCommandHandleNameMode(std::vector<std::string> const& args, |
85 | | cmExecutionStatus& status) |
86 | 0 | { |
87 | 0 | cmMakefile& mf = status.GetMakefile(); |
88 | |
|
89 | 0 | std::string name; |
90 | 0 | std::vector<std::string> configurations; |
91 | 0 | std::string working_directory; |
92 | 0 | std::vector<std::string> command; |
93 | 0 | bool command_expand_lists = false; |
94 | 0 | cmPolicies::PolicyStatus cmp0178 = mf.GetPolicyStatus(cmPolicies::CMP0178); |
95 | | |
96 | | // Read the arguments. |
97 | 0 | enum Doing |
98 | 0 | { |
99 | 0 | DoingName, |
100 | 0 | DoingCommand, |
101 | 0 | DoingConfigs, |
102 | 0 | DoingWorkingDirectory, |
103 | 0 | DoingCmp0178, |
104 | 0 | DoingNone |
105 | 0 | }; |
106 | 0 | Doing doing = DoingName; |
107 | 0 | for (unsigned int i = 1; i < args.size(); ++i) { |
108 | 0 | if (args[i] == "COMMAND") { |
109 | 0 | if (!command.empty()) { |
110 | 0 | status.SetError(" may be given at most one COMMAND."); |
111 | 0 | return false; |
112 | 0 | } |
113 | 0 | doing = DoingCommand; |
114 | 0 | } else if (args[i] == "CONFIGURATIONS") { |
115 | 0 | if (!configurations.empty()) { |
116 | 0 | status.SetError(" may be given at most one set of CONFIGURATIONS."); |
117 | 0 | return false; |
118 | 0 | } |
119 | 0 | doing = DoingConfigs; |
120 | 0 | } else if (args[i] == "WORKING_DIRECTORY") { |
121 | 0 | if (!working_directory.empty()) { |
122 | 0 | status.SetError(" may be given at most one WORKING_DIRECTORY."); |
123 | 0 | return false; |
124 | 0 | } |
125 | 0 | doing = DoingWorkingDirectory; |
126 | 0 | } else if (args[i] == keywordCMP0178) { |
127 | 0 | doing = DoingCmp0178; |
128 | 0 | } else if (args[i] == "COMMAND_EXPAND_LISTS") { |
129 | 0 | if (command_expand_lists) { |
130 | 0 | status.SetError(" may be given at most one COMMAND_EXPAND_LISTS."); |
131 | 0 | return false; |
132 | 0 | } |
133 | 0 | command_expand_lists = true; |
134 | 0 | doing = DoingNone; |
135 | 0 | } else if (doing == DoingName) { |
136 | 0 | name = args[i]; |
137 | 0 | doing = DoingNone; |
138 | 0 | } else if (doing == DoingCommand) { |
139 | 0 | command.push_back(args[i]); |
140 | 0 | } else if (doing == DoingConfigs) { |
141 | 0 | configurations.push_back(args[i]); |
142 | 0 | } else if (doing == DoingWorkingDirectory) { |
143 | 0 | working_directory = args[i]; |
144 | 0 | doing = DoingNone; |
145 | 0 | } else if (doing == DoingCmp0178) { |
146 | 0 | if (args[i] == "NEW") { |
147 | 0 | cmp0178 = cmPolicies::PolicyStatus::NEW; |
148 | 0 | } else if (args[i] == "OLD") { |
149 | 0 | cmp0178 = cmPolicies::PolicyStatus::OLD; |
150 | 0 | } else { |
151 | 0 | cmp0178 = cmPolicies::PolicyStatus::WARN; |
152 | 0 | } |
153 | 0 | doing = DoingNone; |
154 | 0 | } else { |
155 | 0 | status.SetError(cmStrCat(" given unknown argument:\n ", args[i], '\n')); |
156 | 0 | return false; |
157 | 0 | } |
158 | 0 | } |
159 | | |
160 | | // Require a test name. |
161 | 0 | if (name.empty()) { |
162 | 0 | status.SetError(" must be given non-empty NAME."); |
163 | 0 | return false; |
164 | 0 | } |
165 | | |
166 | | // Require a command. |
167 | 0 | if (command.empty()) { |
168 | 0 | status.SetError(" must be given non-empty COMMAND."); |
169 | 0 | return false; |
170 | 0 | } |
171 | | |
172 | | // Require a unique test name within the directory. |
173 | 0 | if (mf.GetTest(name)) { |
174 | 0 | status.SetError(cmStrCat(" given test NAME \"", name, |
175 | 0 | "\" which already exists in this directory.")); |
176 | 0 | return false; |
177 | 0 | } |
178 | | |
179 | | // Add the test. |
180 | 0 | cmTest* test = mf.CreateTest(name); |
181 | 0 | test->SetOldStyle(false); |
182 | 0 | test->SetCMP0178(cmp0178); |
183 | 0 | test->SetCommand(command); |
184 | 0 | if (!working_directory.empty()) { |
185 | 0 | test->SetProperty("WORKING_DIRECTORY", working_directory); |
186 | 0 | } |
187 | 0 | test->SetCommandExpandLists(command_expand_lists); |
188 | 0 | mf.AddTestGenerator(cm::make_unique<cmTestGenerator>(test, configurations)); |
189 | |
|
190 | 0 | return true; |
191 | 0 | } |