27 * |
27 * |
28 * vim: expandtab |
28 * vim: expandtab |
29 * |
29 * |
30 ****************************************************************************/ |
30 ****************************************************************************/ |
31 |
31 |
|
32 #include <map> |
|
33 using namespace std; |
|
34 |
32 #include "Command.h" |
35 #include "Command.h" |
33 #include "MasterDevice.h" |
36 #include "MasterDevice.h" |
34 #include "NumberListParser.h" |
37 #include "NumberListParser.h" |
35 |
38 |
36 /*****************************************************************************/ |
39 /*****************************************************************************/ |
37 |
40 |
|
41 typedef map<uint16_t, ec_ioctl_config_t> AliasMap; |
|
42 typedef map<uint16_t, AliasMap> ConfigMap; |
|
43 |
|
44 /*****************************************************************************/ |
|
45 |
38 class MasterIndexParser: |
46 class MasterIndexParser: |
39 public NumberListParser |
47 public NumberListParser |
40 { |
48 { |
41 unsigned int getMax() |
49 protected: |
42 { |
50 int getMax() { |
43 MasterDevice dev; |
51 MasterDevice dev; |
44 dev.setIndex(0U); |
52 dev.setIndex(0U); |
45 dev.open(MasterDevice::Read); |
53 dev.open(MasterDevice::Read); |
46 return dev.getMasterCount() - 1; |
54 return (int) dev.getMasterCount() - 1; |
47 }; |
55 }; |
|
56 }; |
|
57 |
|
58 /*****************************************************************************/ |
|
59 |
|
60 class SlaveAliasParser: |
|
61 public NumberListParser |
|
62 { |
|
63 public: |
|
64 SlaveAliasParser(ec_ioctl_master_t &master, MasterDevice &dev): |
|
65 master(master), dev(dev) {} |
|
66 |
|
67 protected: |
|
68 int getMax() { |
|
69 unsigned int i; |
|
70 |
|
71 uint16_t maxAlias = 0; |
|
72 for (i = 0; i < master.slave_count; i++) { |
|
73 ec_ioctl_slave_t slave; |
|
74 dev.getSlave(&slave, i); |
|
75 if (slave.alias > maxAlias) { |
|
76 maxAlias = slave.alias; |
|
77 } |
|
78 } |
|
79 return maxAlias ? maxAlias : -1; |
|
80 }; |
|
81 |
|
82 private: |
|
83 ec_ioctl_master_t &master; |
|
84 MasterDevice &dev; |
|
85 }; |
|
86 |
|
87 /*****************************************************************************/ |
|
88 |
|
89 class ConfigAliasParser: |
|
90 public NumberListParser |
|
91 { |
|
92 public: |
|
93 ConfigAliasParser(unsigned int maxAlias): |
|
94 maxAlias(maxAlias) {} |
|
95 |
|
96 protected: |
|
97 int getMax() { return maxAlias; }; |
|
98 |
|
99 private: |
|
100 unsigned int maxAlias; |
|
101 }; |
|
102 |
|
103 /*****************************************************************************/ |
|
104 |
|
105 class PositionParser: |
|
106 public NumberListParser |
|
107 { |
|
108 public: |
|
109 PositionParser(unsigned int count): |
|
110 count(count) {} |
|
111 |
|
112 protected: |
|
113 int getMax() { |
|
114 return count - 1; |
|
115 }; |
|
116 |
|
117 private: |
|
118 const unsigned int count; |
|
119 }; |
|
120 |
|
121 /*****************************************************************************/ |
|
122 |
|
123 class AliasPositionParser: |
|
124 public NumberListParser |
|
125 { |
|
126 public: |
|
127 AliasPositionParser(const AliasMap &aliasMap): |
|
128 aliasMap(aliasMap) {} |
|
129 |
|
130 protected: |
|
131 int getMax() { |
|
132 AliasMap::const_iterator i; |
|
133 int maxPos = -1; |
|
134 |
|
135 for (i = aliasMap.begin(); i != aliasMap.end(); i++) { |
|
136 if (i->first > maxPos) { |
|
137 maxPos = i->first; |
|
138 } |
|
139 } |
|
140 |
|
141 return maxPos; |
|
142 }; |
|
143 |
|
144 private: |
|
145 const AliasMap &aliasMap; |
48 }; |
146 }; |
49 |
147 |
50 /*****************************************************************************/ |
148 /*****************************************************************************/ |
51 |
149 |
52 Command::Command(const string &name, const string &briefDesc): |
150 Command::Command(const string &name, const string &briefDesc): |
76 verbosity = v; |
174 verbosity = v; |
77 }; |
175 }; |
78 |
176 |
79 /*****************************************************************************/ |
177 /*****************************************************************************/ |
80 |
178 |
81 void Command::setAlias(int a) |
179 void Command::setAliases(const string &a) |
82 { |
180 { |
83 alias = a; |
181 aliases = a; |
84 }; |
182 }; |
85 |
183 |
86 /*****************************************************************************/ |
184 /*****************************************************************************/ |
87 |
185 |
88 void Command::setPosition(int p) |
186 void Command::setPositions(const string &p) |
89 { |
187 { |
90 position = p; |
188 positions = p; |
91 }; |
189 }; |
92 |
190 |
93 /*****************************************************************************/ |
191 /*****************************************************************************/ |
94 |
192 |
95 void Command::setDomain(int d) |
193 void Command::setDomains(const string &d) |
96 { |
194 { |
97 domain = d; |
195 domains = d; |
98 }; |
196 }; |
99 |
197 |
100 /*****************************************************************************/ |
198 /*****************************************************************************/ |
101 |
199 |
102 void Command::setDataType(const string &t) |
200 void Command::setDataType(const string &t) |
212 /*****************************************************************************/ |
310 /*****************************************************************************/ |
213 |
311 |
214 unsigned int Command::getSingleMasterIndex() const |
312 unsigned int Command::getSingleMasterIndex() const |
215 { |
313 { |
216 MasterIndexList masterIndices = getMasterIndices(); |
314 MasterIndexList masterIndices = getMasterIndices(); |
|
315 |
217 if (masterIndices.size() != 1) { |
316 if (masterIndices.size() != 1) { |
218 stringstream err; |
317 stringstream err; |
219 err << getName() << " requires to select a single master!"; |
318 err << getName() << " requires to select a single master!"; |
220 throwInvalidUsageException(err); |
319 throwInvalidUsageException(err); |
221 } |
320 } |
|
321 |
222 return masterIndices.front(); |
322 return masterIndices.front(); |
223 } |
323 } |
224 |
324 |
225 /*****************************************************************************/ |
325 /*****************************************************************************/ |
226 |
326 |
227 Command::SlaveList Command::selectedSlaves(MasterDevice &m) |
327 Command::SlaveList Command::selectedSlaves(MasterDevice &m) |
228 { |
328 { |
229 ec_ioctl_master_t master; |
329 ec_ioctl_master_t master; |
230 unsigned int i, aliasIndex; |
330 unsigned int i; |
231 uint16_t lastAlias; |
|
232 ec_ioctl_slave_t slave; |
331 ec_ioctl_slave_t slave; |
233 SlaveList list; |
332 SlaveList list; |
234 |
333 |
235 m.getMaster(&master); |
334 m.getMaster(&master); |
236 |
335 |
237 if (alias == -1) { // no alias given |
336 if (aliases == "-") { // no alias given |
238 if (position == -1) { // no alias and position given |
337 PositionParser pp(master.slave_count); |
239 // all items |
338 NumberListParser::List posList = pp.parse(positions.c_str()); |
240 for (i = 0; i < master.slave_count; i++) { |
339 NumberListParser::List::const_iterator pi; |
241 m.getSlave(&slave, i); |
340 |
|
341 for (pi = posList.begin(); pi != posList.end(); pi++) { |
|
342 if (*pi < master.slave_count) { |
|
343 m.getSlave(&slave, *pi); |
242 list.push_back(slave); |
344 list.push_back(slave); |
243 } |
345 } |
244 } else { // no alias, but position given |
|
245 // one item by position |
|
246 m.getSlave(&slave, position); |
|
247 list.push_back(slave); |
|
248 } |
346 } |
249 } else { // alias given |
347 } else { // aliases given |
250 if (position == -1) { // alias, but no position given |
348 SlaveAliasParser ap(master, m); |
251 // take all items with a given alias |
349 NumberListParser::List aliasList = ap.parse(aliases.c_str()); |
252 lastAlias = 0; |
350 NumberListParser::List::const_iterator ai; |
|
351 |
|
352 for (ai = aliasList.begin(); ai != aliasList.end(); ai++) { |
|
353 |
|
354 // gather slaves with that alias (and following) |
|
355 uint16_t lastAlias = 0; |
|
356 vector<ec_ioctl_slave_t> aliasSlaves; |
|
357 |
253 for (i = 0; i < master.slave_count; i++) { |
358 for (i = 0; i < master.slave_count; i++) { |
254 m.getSlave(&slave, i); |
359 m.getSlave(&slave, i); |
255 if (slave.alias) { |
360 if (slave.alias) { |
|
361 if (lastAlias && lastAlias == *ai && slave.alias != *ai) { |
|
362 // ignore multiple ocurrences of the same alias to |
|
363 // assure consistency for the position argument |
|
364 break; |
|
365 } |
256 lastAlias = slave.alias; |
366 lastAlias = slave.alias; |
257 } |
367 } |
258 if (lastAlias == (uint16_t) alias) { |
368 if (lastAlias == *ai) { |
259 list.push_back(slave); |
369 aliasSlaves.push_back(slave); |
260 } |
370 } |
261 } |
371 } |
262 } else { // alias and position given |
372 |
263 lastAlias = 0; |
373 PositionParser pp(aliasSlaves.size()); |
264 aliasIndex = 0; |
374 NumberListParser::List posList = pp.parse(positions.c_str()); |
265 for (i = 0; i < master.slave_count; i++) { |
375 NumberListParser::List::const_iterator pi; |
266 m.getSlave(&slave, i); |
376 |
267 if (slave.alias && slave.alias == (uint16_t) alias) { |
377 for (pi = posList.begin(); pi != posList.end(); pi++) { |
268 lastAlias = slave.alias; |
378 if (*pi < aliasSlaves.size()) { |
269 aliasIndex = 0; |
379 list.push_back(aliasSlaves[*pi]); |
270 } |
380 } |
271 if (lastAlias && aliasIndex == (unsigned int) position) { |
|
272 list.push_back(slave); |
|
273 } |
|
274 aliasIndex++; |
|
275 } |
381 } |
276 } |
382 } |
277 } |
383 } |
278 |
384 |
279 return list; |
385 return list; |
300 ConfigList list; |
406 ConfigList list; |
301 stringstream err; |
407 stringstream err; |
302 |
408 |
303 m.getMaster(&master); |
409 m.getMaster(&master); |
304 |
410 |
305 if (alias == -1) { // no alias given |
411 if (aliases == "-" && positions == "-") { // shortcut |
306 if (position == -1) { // no alias and position given |
412 for (i = 0; i < master.config_count; i++) { |
307 // all items |
413 m.getConfig(&config, i); |
308 for (i = 0; i < master.config_count; i++) { |
414 list.push_back(config); |
309 m.getConfig(&config, i); |
|
310 list.push_back(config); |
|
311 } |
|
312 } else { // no alias, but position given |
|
313 for (i = 0; i < master.config_count; i++) { |
|
314 m.getConfig(&config, i); |
|
315 if (!config.alias && config.position == position) { |
|
316 list.push_back(config); |
|
317 break; // there can be at most one matching |
|
318 } |
|
319 } |
|
320 } |
415 } |
321 } else { // alias given |
416 } else { // take the long way home... |
322 if (position == -1) { // alias, but no position given |
417 ConfigMap configs; |
323 // take all items with a given alias |
418 uint16_t maxAlias = 0; |
324 for (i = 0; i < master.config_count; i++) { |
419 |
325 m.getConfig(&config, i); |
420 // fill cascaded map structure with all configs |
326 if (config.alias == alias) { |
421 for (i = 0; i < master.config_count; i++) { |
327 list.push_back(config); |
422 m.getConfig(&config, i); |
328 } |
423 AliasMap &aliasMap = configs[config.alias]; |
329 } |
424 aliasMap[config.position] = config; |
330 } else { // alias and position given |
425 if (config.alias > maxAlias) { |
331 for (i = 0; i < master.config_count; i++) { |
426 maxAlias = config.alias; |
332 m.getConfig(&config, i); |
427 } |
333 if (config.alias == alias && config.position == position) { |
428 } |
334 list.push_back(config); |
429 |
335 break; // there can be at most one matching |
430 ConfigAliasParser ap(maxAlias); |
|
431 NumberListParser::List aliasList = ap.parse(aliases.c_str()); |
|
432 NumberListParser::List::const_iterator ai; |
|
433 |
|
434 for (ai = aliasList.begin(); ai != aliasList.end(); ai++) { |
|
435 |
|
436 ConfigMap::iterator ci = configs.find(*ai); |
|
437 if (ci == configs.end()) { |
|
438 continue; |
|
439 } |
|
440 |
|
441 AliasMap &aliasMap = configs[*ai]; |
|
442 AliasPositionParser pp(aliasMap); |
|
443 NumberListParser::List posList = pp.parse(positions.c_str()); |
|
444 NumberListParser::List::const_iterator pi; |
|
445 |
|
446 for (pi = posList.begin(); pi != posList.end(); pi++) { |
|
447 AliasMap::const_iterator ci; |
|
448 |
|
449 ci = aliasMap.find(*pi); |
|
450 if (ci != aliasMap.end()) { |
|
451 list.push_back(ci->second); |
336 } |
452 } |
337 } |
453 } |
338 } |
454 } |
339 } |
455 } |
340 |
456 |