From 79873de309791d2e3a6fd68bc41320a7f0deefce Mon Sep 17 00:00:00 2001 From: Florian Pose <fp@igh-essen.com> Date: Tue, 14 Dec 2010 21:58:53 +0100 Subject: [PATCH] Implemented ranges for slaves, configs and domains. --- TODO | 1 - tool/Command.cpp | 255 ++++++++++++++++++++++++++------------ tool/Command.h | 43 ++----- tool/NumberListParser.cpp | 30 +++-- tool/NumberListParser.h | 12 +- tool/main.cpp | 46 ++----- 6 files changed, 221 insertions(+), 166 deletions(-) diff --git a/TODO b/TODO index 66341b7a..b0d60341 100644 --- a/TODO +++ b/TODO @@ -15,7 +15,6 @@ Version 1.5.0: - Add native drivers from 2.6.24 up to 2.6.31. * ethercat tool: - Output error after usage. - - Implement ranges for slaves and domains. * Fix casting away constness during expected WC calculation. * Include SoE drive_no in ethercat tool. diff --git a/tool/Command.cpp b/tool/Command.cpp index 12d35c68..d2089454 100644 --- a/tool/Command.cpp +++ b/tool/Command.cpp @@ -29,6 +29,9 @@ * ****************************************************************************/ +#include <map> +using namespace std; + #include "Command.h" #include "MasterDevice.h" #include "NumberListParser.h" @@ -38,13 +41,89 @@ 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(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.config_count; i++) { + ec_ioctl_config_t config; + dev.getConfig(&config, i); + if (config.alias > maxAlias) { + maxAlias = config.alias; + } + } + return maxAlias ? maxAlias : -1; + }; + + private: + ec_ioctl_master_t &master; + MasterDevice &dev; +}; + +/*****************************************************************************/ + +class PositionParser: + public NumberListParser +{ + public: + PositionParser(unsigned int count): + count(count) {} + + protected: + int getMax() { + return count - 1; + }; + + private: + const unsigned int count; }; /*****************************************************************************/ @@ -78,23 +157,23 @@ void Command::setVerbosity(Verbosity v) /*****************************************************************************/ -void Command::setAlias(int a) +void Command::setAliases(const string &a) { - alias = a; + aliases = a; }; /*****************************************************************************/ -void Command::setPosition(int p) +void Command::setPositions(const string &p) { - position = p; + positions = p; }; /*****************************************************************************/ -void Command::setDomain(int d) +void Command::setDomains(const string &d) { - domain = d; + domains = d; }; /*****************************************************************************/ @@ -227,51 +306,59 @@ unsigned int Command::getSingleMasterIndex() const 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); - list.push_back(slave); - } - } else { // no alias, but position given - // one item by position - m.getSlave(&slave, position); + 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++) { + m.getSlave(&slave, *pi); 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<ec_ioctl_slave_t> 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; - } - if (lastAlias && aliasIndex == (unsigned int) position) { - list.push_back(slave); + + 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]); + } else { + stringstream err; + err << "Warning: Slave " << *ai << ":" << *pi + << " does not exist on master " << m.getIndex(); + throwCommandException(err); } - aliasIndex++; } } } @@ -302,37 +389,50 @@ Command::ConfigList Command::selectedConfigs(MasterDevice &m) 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 == "-") { // no alias given + PositionParser pp(master.config_count); + NumberListParser::List posList = pp.parse(positions.c_str()); + NumberListParser::List::const_iterator pi; + for (pi = posList.begin(); pi != posList.end(); pi++) { + m.getConfig(&config, *pi); // FIXME use sorted list + list.push_back(config); } } else { // alias given - if (position == -1) { // alias, but no position given - // take all items with a given alias + ConfigAliasParser 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 configs with that alias + map<uint16_t, ec_ioctl_config_t> aliasConfigs; + + int maxPos = -1; for (i = 0; i < master.config_count; i++) { m.getConfig(&config, i); - if (config.alias == alias) { - list.push_back(config); + if (config.alias == *ai) { + aliasConfigs[config.position] = config; + if (config.position > maxPos) { + maxPos = config.position; + } } } - } 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 + + PositionParser pp(maxPos + 1); + NumberListParser::List posList = pp.parse(positions.c_str()); + NumberListParser::List::const_iterator pi; + + for (pi = posList.begin(); pi != posList.end(); pi++) { + map<uint16_t, ec_ioctl_config_t>::const_iterator ci; + ci = aliasConfigs.find(*pi); + + if (ci != aliasConfigs.end()) { + list.push_back(ci->second); + } else { + stringstream err; + err << "Warning: Config " << *ai << ":" << *pi + << " does not exist on master " << m.getIndex(); + throwCommandException(err); } } } @@ -346,21 +446,18 @@ Command::ConfigList Command::selectedConfigs(MasterDevice &m) 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); - m.getMaster(&master); + PositionParser pp(master.domain_count); + NumberListParser::List domList = pp.parse(domains.c_str()); + NumberListParser::List::const_iterator di; - for (i = 0; i < master.domain_count; i++) { - m.getDomain(&d, i); - list.push_back(d); - } - } else { - m.getDomain(&d, domain); + for (di = domList.begin(); di != domList.end(); di++) { + ec_ioctl_domain_t d; + m.getDomain(&d, *di); list.push_back(d); } diff --git a/tool/Command.h b/tool/Command.h index 14306c53..46d3d579 100644 --- a/tool/Command.h +++ b/tool/Command.h @@ -96,16 +96,20 @@ class Command }; void setVerbosity(Verbosity); Verbosity getVerbosity() const; - void setAlias(int); - int getAlias() const; - void setPosition(int); - int getPosition() const; - void setDomain(int); - int getDomain() const; + + void setAliases(const string &); + void setPositions(const string &); + + void setDomains(const string &); + typedef list<unsigned int> DomainIndexList; + DomainIndexList getDomainIndices() const; + void setDataType(const string &); const string &getDataType() const; + void setForce(bool); bool getForce() const; + void setOutputFile(const string &); const string &getOutputFile() const; @@ -141,9 +145,9 @@ class Command string briefDesc; string masters; Verbosity verbosity; - int alias; - int position; - int domain; + string aliases; + string positions; + string domains; string dataType; bool force; string outputFile; @@ -174,27 +178,6 @@ inline Command::Verbosity Command::getVerbosity() const /****************************************************************************/ -inline int Command::getAlias() const -{ - return alias; -} - -/****************************************************************************/ - -inline int Command::getPosition() const -{ - return position; -} - -/****************************************************************************/ - -inline int Command::getDomain() const -{ - return domain; -} - -/****************************************************************************/ - inline const string &Command::getDataType() const { return dataType; diff --git a/tool/NumberListParser.cpp b/tool/NumberListParser.cpp index bdef69f1..33e46720 100644 --- a/tool/NumberListParser.cpp +++ b/tool/NumberListParser.cpp @@ -50,9 +50,9 @@ NumberListParser::~NumberListParser() /*****************************************************************************/ -NumberListParser::NumberList NumberListParser::parse(const char *data) +NumberListParser::List NumberListParser::parse(const char *data) { - NumberList ret; + List ret; unsigned int i = 0, size = strlen(data), firstNum = 0U, secondNum = 0U; typedef enum { SectionStart, @@ -108,18 +108,22 @@ NumberListParser::NumberList NumberListParser::parse(const char *data) case Range: if (i >= size) { - secondNum = maximum(); - NumberList r = range(firstNum, secondNum); - ret.splice(ret.end(), r); + int max = maximum(); + if (max >= 0) { + List r = range(firstNum, max); + ret.splice(ret.end(), r); + } state = Finished; } else if (isNumeric(data[i])) { secondNum = parseNumber(data, &i, size); state = SecondNumber; } else if (data[i] == ',') { + int max = maximum(); i++; - secondNum = maximum(); - NumberList r = range(firstNum, secondNum); - ret.splice(ret.end(), r); + if (max >= 0) { + List r = range(firstNum, max); + ret.splice(ret.end(), r); + } state = SectionStart; } else { stringstream err; @@ -132,12 +136,12 @@ NumberListParser::NumberList NumberListParser::parse(const char *data) case SecondNumber: if (i >= size) { - NumberList r = range(firstNum, secondNum); + List r = range(firstNum, secondNum); ret.splice(ret.end(), r); state = Finished; } else if (data[i] == ',') { i++; - NumberList r = range(firstNum, secondNum); + List r = range(firstNum, secondNum); ret.splice(ret.end(), r); state = SectionStart; } else { @@ -163,7 +167,7 @@ NumberListParser::NumberList NumberListParser::parse(const char *data) /*****************************************************************************/ -unsigned int NumberListParser::maximum() +int NumberListParser::maximum() { if (!hasMax) { max = getMax(); @@ -207,12 +211,12 @@ unsigned int NumberListParser::parseNumber( /****************************************************************************/ -NumberListParser::NumberList NumberListParser::range( +NumberListParser::List NumberListParser::range( unsigned int i, unsigned int j ) { - NumberList ret; + List ret; if (i <= j) { for (; i <= j; i++) { diff --git a/tool/NumberListParser.h b/tool/NumberListParser.h index 6cf0dd16..ec30aa67 100644 --- a/tool/NumberListParser.h +++ b/tool/NumberListParser.h @@ -38,22 +38,22 @@ class NumberListParser NumberListParser(); virtual ~NumberListParser(); - typedef list<unsigned int> NumberList; + typedef list<unsigned int> List; - NumberList parse(const char *); + List parse(const char *); - virtual unsigned int getMax() = 0; + virtual int getMax() = 0; private: - unsigned int max; + int max; bool hasMax; - unsigned int maximum(); + int maximum(); static bool isNumeric(char); static unsigned int parseNumber(const char *, unsigned int *, unsigned int); - static NumberList range(unsigned int, unsigned int); + static List range(unsigned int, unsigned int); }; /****************************************************************************/ diff --git a/tool/main.cpp b/tool/main.cpp index 0afa35c9..6f6948b0 100644 --- a/tool/main.cpp +++ b/tool/main.cpp @@ -77,9 +77,9 @@ Command::StringVector commandArgs; // option variables string masters = "-"; // all masters -int slavePosition = -1; -int slaveAlias = -1; -int domainIndex = -1; +string positions = "-"; // all positions +string aliases = "-"; // all aliases +string domains = "-"; // all domains string dataTypeStr; Command::Verbosity verbosity = Command::Normal; bool force = false; @@ -163,43 +163,15 @@ void getOptions(int argc, char **argv) break; case 'a': - str.clear(); - str.str(""); - str << optarg; - str >> resetiosflags(ios::basefield) // guess base from prefix - >> slaveAlias; - if (str.fail() || slaveAlias < 0 || slaveAlias > 0xFFFF) { - cerr << "Invalid slave alias " << optarg << "!" << endl - << endl << usage(); - exit(1); - } + aliases = optarg; break; case 'p': - str.clear(); - str.str(""); - str << optarg; - str >> resetiosflags(ios::basefield) // guess base from prefix - >> slavePosition; - if (str.fail() - || slavePosition < 0 || slavePosition > 0xFFFF) { - cerr << "Invalid slave position " << optarg << "!" << endl - << endl << usage(); - exit(1); - } + positions = optarg; break; case 'd': - str.clear(); - str.str(""); - str << optarg; - str >> resetiosflags(ios::basefield) // guess base from prefix - >> domainIndex; - if (str.fail() || domainIndex < 0) { - cerr << "Invalid domain index " << optarg << "!" << endl - << endl << usage(); - exit(1); - } + domains = optarg; break; case 't': @@ -331,9 +303,9 @@ int main(int argc, char **argv) try { cmd->setMasters(masters); cmd->setVerbosity(verbosity); - cmd->setAlias(slaveAlias); - cmd->setPosition(slavePosition); - cmd->setDomain(domainIndex); + cmd->setAliases(aliases); + cmd->setPositions(positions); + cmd->setDomains(domains); cmd->setDataType(dataTypeStr); cmd->setOutputFile(outputFile); cmd->setForce(force); -- GitLab