diff -r f5b31f46c38f -r 8b358effa78b tool/Command.cpp --- a/tool/Command.cpp Thu Feb 24 10:04:42 2011 +0100 +++ b/tool/Command.cpp Mon Mar 14 11:20:05 2011 +0100 @@ -29,22 +29,120 @@ * ****************************************************************************/ +#include +using namespace std; + #include "Command.h" #include "MasterDevice.h" #include "NumberListParser.h" /*****************************************************************************/ +typedef map AliasMap; +typedef map ConfigMap; + +/*****************************************************************************/ + class MasterIndexParser: public NumberListParser { - unsigned int getMax() - { - MasterDevice dev; - dev.setIndex(0U); - dev.open(MasterDevice::Read); - return dev.getMasterCount() - 1; - }; + protected: + int getMax() { + MasterDevice dev; + dev.setIndex(0U); + dev.open(MasterDevice::Read); + return (int) dev.getMasterCount() - 1; + }; +}; + +/*****************************************************************************/ + +class SlaveAliasParser: + public NumberListParser +{ + public: + SlaveAliasParser(ec_ioctl_master_t &master, MasterDevice &dev): + master(master), dev(dev) {} + + protected: + int getMax() { + unsigned int i; + + uint16_t maxAlias = 0; + for (i = 0; i < master.slave_count; i++) { + ec_ioctl_slave_t slave; + dev.getSlave(&slave, i); + if (slave.alias > maxAlias) { + maxAlias = slave.alias; + } + } + return maxAlias ? maxAlias : -1; + }; + + private: + ec_ioctl_master_t &master; + MasterDevice &dev; +}; + +/*****************************************************************************/ + +class ConfigAliasParser: + public NumberListParser +{ + public: + ConfigAliasParser(unsigned int maxAlias): + maxAlias(maxAlias) {} + + protected: + int getMax() { return maxAlias; }; + + private: + unsigned int maxAlias; +}; + +/*****************************************************************************/ + +class PositionParser: + public NumberListParser +{ + public: + PositionParser(unsigned int count): + count(count) {} + + protected: + int getMax() { + return count - 1; + }; + + private: + const unsigned int count; +}; + +/*****************************************************************************/ + +class AliasPositionParser: + public NumberListParser +{ + public: + AliasPositionParser(const AliasMap &aliasMap): + aliasMap(aliasMap) {} + + protected: + int getMax() { + AliasMap::const_iterator i; + int maxPos = -1; + + for (i = aliasMap.begin(); i != aliasMap.end(); i++) { + if (i->first > maxPos) { + maxPos = i->first; + } + } + + return maxPos; + }; + + private: + const AliasMap &aliasMap; }; /*****************************************************************************/ @@ -78,23 +176,23 @@ /*****************************************************************************/ -void Command::setAlias(int a) -{ - alias = a; -}; - -/*****************************************************************************/ - -void Command::setPosition(int p) -{ - position = p; -}; - -/*****************************************************************************/ - -void Command::setDomain(int d) -{ - domain = d; +void Command::setAliases(const string &a) +{ + aliases = a; +}; + +/*****************************************************************************/ + +void Command::setPositions(const string &p) +{ + positions = p; +}; + +/*****************************************************************************/ + +void Command::setDomains(const string &d) +{ + domains = d; }; /*****************************************************************************/ @@ -214,11 +312,13 @@ unsigned int Command::getSingleMasterIndex() const { MasterIndexList masterIndices = getMasterIndices(); + if (masterIndices.size() != 1) { stringstream err; err << getName() << " requires to select a single master!"; throwInvalidUsageException(err); } + return masterIndices.front(); } @@ -227,51 +327,57 @@ Command::SlaveList Command::selectedSlaves(MasterDevice &m) { ec_ioctl_master_t master; - unsigned int i, aliasIndex; - uint16_t lastAlias; + unsigned int i; ec_ioctl_slave_t slave; SlaveList list; m.getMaster(&master); - if (alias == -1) { // no alias given - if (position == -1) { // no alias and position given - // all items - for (i = 0; i < master.slave_count; i++) { - m.getSlave(&slave, i); + if (aliases == "-") { // no alias given + PositionParser pp(master.slave_count); + NumberListParser::List posList = pp.parse(positions.c_str()); + NumberListParser::List::const_iterator pi; + + for (pi = posList.begin(); pi != posList.end(); pi++) { + if (*pi < master.slave_count) { + m.getSlave(&slave, *pi); list.push_back(slave); } - } else { // no alias, but position given - // one item by position - m.getSlave(&slave, position); - list.push_back(slave); } - } else { // alias given - if (position == -1) { // alias, but no position given - // take all items with a given alias - lastAlias = 0; + } else { // aliases given + SlaveAliasParser ap(master, m); + NumberListParser::List aliasList = ap.parse(aliases.c_str()); + NumberListParser::List::const_iterator ai; + + for (ai = aliasList.begin(); ai != aliasList.end(); ai++) { + + // gather slaves with that alias (and following) + uint16_t lastAlias = 0; + vector aliasSlaves; + for (i = 0; i < master.slave_count; i++) { m.getSlave(&slave, i); if (slave.alias) { + if (lastAlias && lastAlias == *ai && slave.alias != *ai) { + // ignore multiple ocurrences of the same alias to + // assure consistency for the position argument + break; + } lastAlias = slave.alias; } - if (lastAlias == (uint16_t) alias) { - list.push_back(slave); + if (lastAlias == *ai) { + aliasSlaves.push_back(slave); } } - } else { // alias and position given - lastAlias = 0; - aliasIndex = 0; - for (i = 0; i < master.slave_count; i++) { - m.getSlave(&slave, i); - if (slave.alias && slave.alias == (uint16_t) alias) { - lastAlias = slave.alias; - aliasIndex = 0; + + PositionParser pp(aliasSlaves.size()); + NumberListParser::List posList = pp.parse(positions.c_str()); + NumberListParser::List::const_iterator pi; + + for (pi = posList.begin(); pi != posList.end(); pi++) { + if (*pi < aliasSlaves.size()) { + list.push_back(aliasSlaves[*pi]); } - if (lastAlias && aliasIndex == (unsigned int) position) { - list.push_back(slave); - } - aliasIndex++; } } } @@ -302,37 +408,47 @@ m.getMaster(&master); - if (alias == -1) { // no alias given - if (position == -1) { // no alias and position given - // all items - for (i = 0; i < master.config_count; i++) { - m.getConfig(&config, i); - list.push_back(config); - } - } else { // no alias, but position given - for (i = 0; i < master.config_count; i++) { - m.getConfig(&config, i); - if (!config.alias && config.position == position) { - list.push_back(config); - break; // there can be at most one matching - } - } + if (aliases == "-" && positions == "-") { // shortcut + for (i = 0; i < master.config_count; i++) { + m.getConfig(&config, i); + list.push_back(config); } - } else { // alias given - if (position == -1) { // alias, but no position given - // take all items with a given alias - for (i = 0; i < master.config_count; i++) { - m.getConfig(&config, i); - if (config.alias == alias) { - list.push_back(config); - } - } - } else { // alias and position given - for (i = 0; i < master.config_count; i++) { - m.getConfig(&config, i); - if (config.alias == alias && config.position == position) { - list.push_back(config); - break; // there can be at most one matching + } else { // take the long way home... + ConfigMap configs; + uint16_t maxAlias = 0; + + // fill cascaded map structure with all configs + for (i = 0; i < master.config_count; i++) { + m.getConfig(&config, i); + AliasMap &aliasMap = configs[config.alias]; + aliasMap[config.position] = config; + if (config.alias > maxAlias) { + maxAlias = config.alias; + } + } + + ConfigAliasParser ap(maxAlias); + NumberListParser::List aliasList = ap.parse(aliases.c_str()); + NumberListParser::List::const_iterator ai; + + for (ai = aliasList.begin(); ai != aliasList.end(); ai++) { + + ConfigMap::iterator ci = configs.find(*ai); + if (ci == configs.end()) { + continue; + } + + AliasMap &aliasMap = configs[*ai]; + AliasPositionParser pp(aliasMap); + NumberListParser::List posList = pp.parse(positions.c_str()); + NumberListParser::List::const_iterator pi; + + for (pi = posList.begin(); pi != posList.end(); pi++) { + AliasMap::const_iterator ci; + + ci = aliasMap.find(*pi); + if (ci != aliasMap.end()) { + list.push_back(ci->second); } } } @@ -346,22 +462,21 @@ Command::DomainList Command::selectedDomains(MasterDevice &m) { - ec_ioctl_domain_t d; + ec_ioctl_master_t master; DomainList list; - if (domain == -1) { - ec_ioctl_master_t master; - unsigned int i; - - m.getMaster(&master); - - for (i = 0; i < master.domain_count; i++) { - m.getDomain(&d, i); + m.getMaster(&master); + + PositionParser pp(master.domain_count); + NumberListParser::List domList = pp.parse(domains.c_str()); + NumberListParser::List::const_iterator di; + + for (di = domList.begin(); di != domList.end(); di++) { + if (*di < master.domain_count) { + ec_ioctl_domain_t d; + m.getDomain(&d, *di); list.push_back(d); } - } else { - m.getDomain(&d, domain); - list.push_back(d); } return list;