Implemented ranges for slaves, configs and domains.

This commit is contained in:
Florian Pose 2010-12-14 21:58:53 +01:00
parent d3a9a36d63
commit bf144c593c
6 changed files with 221 additions and 166 deletions

1
TODO
View File

@ -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.

View File

@ -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;
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);
}
if (lastAlias && aliasIndex == (unsigned int) position) {
list.push_back(slave);
}
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);
}

View File

@ -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;

View File

@ -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++) {

View File

@ -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);
};
/****************************************************************************/

View File

@ -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);