forked from Slicer/SlicerExecutionModel
-
Notifications
You must be signed in to change notification settings - Fork 0
/
BatchMakeUtilities.cxx
315 lines (272 loc) · 10.2 KB
/
BatchMakeUtilities.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
#include "BatchMakeUtilities.h"
#include "ModuleParameterGroup.h"
#include "ModuleParameter.h"
#include <cstdlib>
#include <sstream>
#include <map>
#include <vector>
#include <stdlib.h>
std::string GenerateBatchMakeWrapper(const ModuleDescription& module)
{
std::ostringstream wrapper;
std::string indent1(" ");
std::string indent2 = indent1 + indent1;
std::string indent3 = indent2 + indent1;
std::string indent4 = indent3 + indent1;
// Can only generate BatchMakeWrappers for executables.
if (module.GetType() != "CommandLineModule")
{
return "";
}
// BatchMake only understands parameter types:
// file=0, bool=1, int=2, float=3, string=4, enum=5
//
// Map what we can into these.
//
typedef std::map<std::string, std::string> ModuleParameterToBatchMakeTypeMap;
ModuleParameterToBatchMakeTypeMap mp2bm;
mp2bm["integer"] = "2"; // int
mp2bm["float"] = "3"; // float
mp2bm["double"] = "3"; // float
mp2bm["boolean"] = "1"; // bool
mp2bm["string"] = "4"; // string
mp2bm["integer-vector"] = "4"; // string
mp2bm["float-vector"] = "4"; // string
mp2bm["double-vector"] = "4"; // string
mp2bm["string-vector"] = "4"; // string
mp2bm["integer-enumeration"] = "5"; // enum
mp2bm["float-enumeration"] = "3"; // float ???
mp2bm["double-enumeration"] = "3"; // float ???
mp2bm["string-enumeration"] = "4"; // string ???
mp2bm["file"] = "0"; // file
mp2bm["directory"] = "0"; // file ???
mp2bm["image"] = "0"; // file
mp2bm["geometry"] = "0"; // file
mp2bm["point"] = "4"; // string ???
// BatchMake format preamble
wrapper << "<?xml version=\"1.0\" encoding=\"utf-8\"?>" << std::endl;
wrapper << "<BatchMakeApplicationWrapper>" << std::endl;
wrapper << indent1 << "<BatchMakeApplicationWrapperVersion>1.0</BatchMakeApplicationWrapper>" << std::endl;
wrapper << indent1 << "<Module>" << std::endl;
wrapper << indent2 << "<Name>" << module.GetTitle() << "</Name>"
<< std::endl;
wrapper << indent2 << "<Version>" << module.GetVersion()
<< "</Version>" << std::endl;
wrapper << indent2 << "<Path>" << module.GetLocation() << "</Path>"
<< std::endl;
wrapper << indent2 << "<Parameters>" << std::endl;
std::vector<ModuleParameterGroup>::const_iterator pgbeginit
= module.GetParameterGroups().begin();
std::vector<ModuleParameterGroup>::const_iterator pgendit
= module.GetParameterGroups().end();
std::vector<ModuleParameterGroup>::const_iterator pgit;
ModuleParameterToBatchMakeTypeMap::iterator mp2bmIt;
// Loop over all parameters that have a flag then loop over the
// parameters that are index parameters
//
// Loop over executables with flags
int pcount = 0;
for (pgit = pgbeginit; pgit != pgendit; ++pgit)
{
// iterate over each parameter in this group
std::vector<ModuleParameter>::const_iterator pbeginit
= (*pgit).GetParameters().begin();
std::vector<ModuleParameter>::const_iterator pendit
= (*pgit).GetParameters().end();
std::vector<ModuleParameter>::const_iterator pit;
for (pit = pbeginit; pit != pendit; ++pit)
{
std::string prefix;
std::string flag;
bool hasFlag = false;
if ((*pit).GetLongFlag() != "")
{
prefix = "--";
flag = (*pit).GetLongFlag();
hasFlag = true;
}
else if ((*pit).GetFlag() != "")
{
prefix = "-";
flag = (*pit).GetFlag();
hasFlag = true;
}
if (hasFlag)
{
pcount++;
// Batchmake uses two parameters to represent non-boolean
// options. THe first of the parameters is the "flag", the
// second is the value. THe Parent tag is used to ling flags
// to values.
wrapper << indent3 << "<Param>" << std::endl;
// first parameter in the pair is ALWAYS a bool. If there is
// not a pair, then the parameter is bool anyway.
wrapper << indent4 << "<Type>1</Type>" << std::endl;
// if we are going to be creating a paired set of parameters,
// then name the first one the <parameter name>.flag and the
// second one just <parameter name> for the value.
if ((*pit).GetTag() != "boolean")
{
wrapper << indent4 << "<Name>";
wrapper << (*pit).GetName() + ".flag";
wrapper << "</Name>" << std::endl;
}
else
{
// just use the name
wrapper << indent4 << "<Name>";
wrapper << (*pit).GetName();
wrapper << "</Name>" << std::endl;
}
// Value is the flag
wrapper << indent4 << "<Value>";
wrapper << prefix + flag;
wrapper << "</Value>" << std::endl;
// The flag itself never has a parent
wrapper << indent4 << "<Parent>0</Parent>" << std::endl;
// BatchMake external flag is:
// 0=nothing, 1=input, 2=output
//
// THe flag itself is always external = 0
wrapper << indent4 << "<External>0</External>" << std::endl;
// Any module parameter that has a flag is optional.
wrapper << indent4 << "<Optional>1</Optional>" << std::endl;
wrapper << indent3 << "</Param>" << std::endl;
// Is a child BatchMake parameter needed for the parameter?
if ((*pit).GetTag() != "boolean")
{
pcount++;
wrapper << indent3 << "<Param>" << std::endl;
// find the module parameter type in the map to BatchMake types
mp2bmIt = mp2bm.find((*pit).GetTag());
if (mp2bmIt != mp2bm.end())
{
wrapper << indent4 << "<Type>";
wrapper << (*mp2bmIt).second;
wrapper << "</Type>" << std::endl;
}
else
{
// unsupported type. map to string
wrapper << indent4 << "<Type>4</Type>" << std::endl;
}
// THe name of the BatchMake paired parameter is just the
// original parameter name
wrapper << indent4 << "<Name>";
wrapper << (*pit).GetName();
wrapper << "</Name>" << std::endl;
wrapper << indent4 << "<Value>";
wrapper << (*pit).GetDefault();
wrapper << "</Value>" << std::endl;
// The parent is the previous parameter (the parameter for
// the flag)
wrapper << indent4 << "<Parent>" << pcount - 1
<< "</Parent>" << std::endl;
// BatchMake external flag is:
// 0=nothing, 1=input, 2=output
if ((*pit).GetTag() == "image" || (*pit).GetTag() == "geometry"
|| (*pit).GetTag() == "file")
{
if ((*pit).GetChannel() == "input")
{
wrapper << indent4 << "<External>1</External>" << std::endl;
}
else if ((*pit).GetChannel() == "output")
{
wrapper << indent4 << "<External>2</External>" << std::endl;
}
else
{
wrapper << indent4 << "<External>0</External>" << std::endl;
}
}
else
{
wrapper << indent4 << "<External>0</External>" << std::endl;
}
// If the flag was specified, then the parameter for the
// value cannot be option
wrapper << indent4 << "<Optional>0</Optional>" << std::endl;
wrapper << indent3 << "</Param>" << std::endl;
}
}
}
}
// now tack on any parameters that are based on indices
//
// build a list of indices to traverse in order
std::map<int, ModuleParameter> indexmap;
for (pgit = pgbeginit; pgit != pgendit; ++pgit)
{
// iterate over each parameter in this group
std::vector<ModuleParameter>::const_iterator pbeginit
= (*pgit).GetParameters().begin();
std::vector<ModuleParameter>::const_iterator pendit
= (*pgit).GetParameters().end();
std::vector<ModuleParameter>::const_iterator pit;
for (pit = pbeginit; pit != pendit; ++pit)
{
if ((*pit).GetIndex() != "")
{
indexmap[atoi((*pit).GetIndex().c_str())] = (*pit);
}
}
}
// walk the index parameters in order
std::map<int, ModuleParameter>::const_iterator iit;
for (iit = indexmap.begin(); iit != indexmap.end(); ++iit)
{
wrapper << indent3 << "<Param>" << std::endl;
// find the module parameter type in the map to BatchMake types
mp2bmIt = mp2bm.find((*iit).second.GetTag());
if (mp2bmIt != mp2bm.end())
{
wrapper << indent4 << "<Type>";
wrapper << (*mp2bmIt).second;
wrapper << "</Type>" << std::endl;
}
else
{
// unsupported type. map to string
wrapper << indent4 << "<Type>4</Type>" << std::endl;;
}
wrapper << indent4 << "<Name>";
wrapper << (*iit).second.GetName();
wrapper << "</Name>" << std::endl;
wrapper << indent4 << "<Value>";
wrapper << (*iit).second.GetDefault();
wrapper << "</Value>" << std::endl;
// index parameters have no parents
wrapper << indent4 << "<Parent>0</Parent>" << std::endl;
// BatchMake external flag is:
// 0=nothing, 1=input, 2=output
if ((*iit).second.GetTag() == "image"
|| (*iit).second.GetTag() == "geometry"
|| (*iit).second.GetTag() == "file")
{
if ((*iit).second.GetChannel() == "input")
{
wrapper << indent4 << "<External>1</External>" << std::endl;
}
else if ((*iit).second.GetChannel() == "output")
{
wrapper << indent4 << "<External>2</External>" << std::endl;
}
else
{
wrapper << indent4 << "<External>0</External>" << std::endl;
}
}
else
{
wrapper << indent4 << "<External>0</External>" << std::endl;
}
// Any index parameter is not optional
wrapper << indent4 << "<Optional>0</Optional>" << std::endl;
wrapper << indent3 << "</Param>" << std::endl;
}
wrapper << indent2 << "</Parameters>" << std::endl;
wrapper << indent1 << "</Module>" << std::endl;
wrapper << "</BatchMakeApplicationWrapper>" << std::endl;
return wrapper.str();
}