--- a/TODO Mon Mar 14 16:55:09 2011 +0100
+++ b/TODO Mon Mar 14 16:57:47 2011 +0100
@@ -13,17 +13,12 @@
* Ethernet drivers:
- Fix link detection in generic driver.
- Add native drivers from 2.6.24 up to 2.6.31.
-* ethercat tool:
- - Implement ranges for slaves and domains.
Future issues:
* Remove allow_scanning flag.
-* Output skipped datagrams again.
* Check for Enable SDO Complete Access flag.
* Do not output 'SDO does not exist' when querying data type.
-* Always write down PDO assignment/mapping in doubt? If not, add an interface
- for enforcing this.
* Read AL status code on spontaneous state change.
* recompile tool/CommandVersion.cpp if revision changes.
* Log SoE IDNs with real name ([SP]-x-yyyy).
--- a/include/ecrt.h Mon Mar 14 16:55:09 2011 +0100
+++ b/include/ecrt.h Mon Mar 14 16:57:47 2011 +0100
@@ -76,6 +76,7 @@
* - Added ecrt_slave_config_idn() method for storing SoE IDN configurations,
* and ecrt_master_read_idn() and ecrt_master_write_idn() to read/write IDNs
* ad-hoc via the user-space library.
+ * - Added ecrt_master_reset() to initiate retrying to configure slaves.
* - Added support for overlapping PDOs which allows inputs to use the same
* space as outputs on the frame. This reduces the frame length.
*
@@ -885,6 +886,17 @@
ec_master_t *master /**< EtherCAT master. */
);
+/** Retry configuring slaves.
+ *
+ * Via this method, the application can tell the master to bring all slaves to
+ * OP state. In general, this is not necessary, because it is automatically
+ * done by the master. But with special slaves, that can be reconfigured by
+ * the vendor during runtime, it can be useful.
+ */
+void ecrt_master_reset(
+ ec_master_t *master /**< EtherCAT master. */
+ );
+
/******************************************************************************
* Slave configuration methods
*****************************************************************************/
--- a/lib/master.c Mon Mar 14 16:55:09 2011 +0100
+++ b/lib/master.c Mon Mar 14 16:57:47 2011 +0100
@@ -591,3 +591,12 @@
}
/*****************************************************************************/
+
+void ecrt_master_reset(ec_master_t *master)
+{
+ if (ioctl(master->fd, EC_IOCTL_RESET, NULL) == -1) {
+ fprintf(stderr, "Failed to reset master: %s\n", strerror(errno));
+ }
+}
+
+/*****************************************************************************/
--- a/master/cdev.c Mon Mar 14 16:55:09 2011 +0100
+++ b/master/cdev.c Mon Mar 14 16:57:47 2011 +0100
@@ -2009,6 +2009,25 @@
/*****************************************************************************/
+/** Reset configuration.
+ */
+int ec_cdev_ioctl_reset(
+ ec_master_t *master, /**< EtherCAT master. */
+ unsigned long arg, /**< ioctl() argument. */
+ ec_cdev_priv_t *priv /**< Private data structure of file handle. */
+ )
+{
+ if (unlikely(!priv->requested))
+ return -EPERM;
+
+ ec_mutex_lock(&master->master_mutex);
+ ecrt_master_reset(master);
+ ec_mutex_unlock(&master->master_mutex);
+ return 0;
+}
+
+/*****************************************************************************/
+
/** Configure a sync manager.
*/
int ec_cdev_ioctl_sc_sync(
@@ -3723,6 +3742,10 @@
if (!(filp->f_mode & FMODE_WRITE))
return -EPERM;
return ec_cdev_ioctl_sync_mon_process(master, arg, priv);
+ case EC_IOCTL_RESET:
+ if (!(filp->f_mode & FMODE_WRITE))
+ return -EPERM;
+ return ec_cdev_ioctl_reset(master, arg, priv);
case EC_IOCTL_SC_SYNC:
if (!(filp->f_mode & FMODE_WRITE))
return -EPERM;
--- a/master/ioctl.h Mon Mar 14 16:55:09 2011 +0100
+++ b/master/ioctl.h Mon Mar 14 16:57:47 2011 +0100
@@ -56,7 +56,7 @@
*
* Increment this when changing the ioctl interface!
*/
-#define EC_IOCTL_VERSION_MAGIC 11
+#define EC_IOCTL_VERSION_MAGIC 12
// Command-line tool
#define EC_IOCTL_MODULE EC_IOR(0x00, ec_ioctl_module_t)
@@ -95,7 +95,7 @@
// Application interface
#define EC_IOCTL_REQUEST EC_IO(0x1e)
#define EC_IOCTL_CREATE_DOMAIN EC_IO(0x1f)
-#define EC_IOCTL_CREATE_SLAVE_CONFIG EC_IOWR(0x10, ec_ioctl_config_t)
+#define EC_IOCTL_CREATE_SLAVE_CONFIG EC_IOWR(0x20, ec_ioctl_config_t)
#define EC_IOCTL_ACTIVATE EC_IOR(0x21, size_t)
#define EC_IOCTL_DEACTIVATE EC_IO(0x22)
#define EC_IOCTL_SEND EC_IO(0x23)
@@ -106,38 +106,39 @@
#define EC_IOCTL_SYNC_SLAVES EC_IO(0x28)
#define EC_IOCTL_SYNC_MON_QUEUE EC_IO(0x29)
#define EC_IOCTL_SYNC_MON_PROCESS EC_IOR(0x2a, uint32_t)
-#define EC_IOCTL_SC_SYNC EC_IOW(0x2b, ec_ioctl_config_t)
-#define EC_IOCTL_SC_WATCHDOG EC_IOW(0x2c, ec_ioctl_config_t)
-#define EC_IOCTL_SC_ADD_PDO EC_IOW(0x2d, ec_ioctl_config_pdo_t)
-#define EC_IOCTL_SC_CLEAR_PDOS EC_IOW(0x2e, ec_ioctl_config_pdo_t)
-#define EC_IOCTL_SC_ADD_ENTRY EC_IOW(0x2f, ec_ioctl_add_pdo_entry_t)
-#define EC_IOCTL_SC_CLEAR_ENTRIES EC_IOW(0x20, ec_ioctl_config_pdo_t)
-#define EC_IOCTL_SC_REG_PDO_ENTRY EC_IOWR(0x21, ec_ioctl_reg_pdo_entry_t)
-#define EC_IOCTL_SC_DC EC_IOW(0x32, ec_ioctl_config_t)
-#define EC_IOCTL_SC_SDO EC_IOW(0x33, ec_ioctl_sc_sdo_t)
-#define EC_IOCTL_SC_SDO_REQUEST EC_IOWR(0x34, ec_ioctl_sdo_request_t)
-#define EC_IOCTL_SC_VOE EC_IOWR(0x35, ec_ioctl_voe_t)
-#define EC_IOCTL_SC_STATE EC_IOWR(0x36, ec_ioctl_sc_state_t)
-#define EC_IOCTL_SC_IDN EC_IOW(0x37, ec_ioctl_sc_idn_t)
-#define EC_IOCTL_DOMAIN_OFFSET EC_IO(0x38)
-#define EC_IOCTL_DOMAIN_PROCESS EC_IO(0x39)
-#define EC_IOCTL_DOMAIN_QUEUE EC_IO(0x3a)
-#define EC_IOCTL_DOMAIN_STATE EC_IOWR(0x3b, ec_ioctl_domain_state_t)
-#define EC_IOCTL_SDO_REQUEST_TIMEOUT EC_IOWR(0x3c, ec_ioctl_sdo_request_t)
-#define EC_IOCTL_SDO_REQUEST_STATE EC_IOWR(0x3d, ec_ioctl_sdo_request_t)
-#define EC_IOCTL_SDO_REQUEST_READ EC_IOWR(0x3e, ec_ioctl_sdo_request_t)
-#define EC_IOCTL_SDO_REQUEST_WRITE EC_IOWR(0x3f, ec_ioctl_sdo_request_t)
-#define EC_IOCTL_SDO_REQUEST_DATA EC_IOWR(0x30, ec_ioctl_sdo_request_t)
-#define EC_IOCTL_VOE_SEND_HEADER EC_IOW(0x41, ec_ioctl_voe_t)
-#define EC_IOCTL_VOE_REC_HEADER EC_IOWR(0x42, ec_ioctl_voe_t)
-#define EC_IOCTL_VOE_READ EC_IOW(0x43, ec_ioctl_voe_t)
-#define EC_IOCTL_VOE_READ_NOSYNC EC_IOW(0x44, ec_ioctl_voe_t)
-#define EC_IOCTL_VOE_WRITE EC_IOWR(0x45, ec_ioctl_voe_t)
-#define EC_IOCTL_VOE_EXEC EC_IOWR(0x46, ec_ioctl_voe_t)
-#define EC_IOCTL_VOE_DATA EC_IOWR(0x47, ec_ioctl_voe_t)
-#define EC_IOCTL_SET_SEND_INTERVAL EC_IOW(0x48, size_t)
-#define EC_IOCTL_MASTER_SC_STATE EC_IOR(0x49, ec_master_state_t)
-#define EC_IOCTL_SC_OVERLAPPING_IO EC_IOW(0x50, ec_ioctl_config_t)
+#define EC_IOCTL_RESET EC_IO(0x2b)
+#define EC_IOCTL_SC_SYNC EC_IOW(0x2c, ec_ioctl_config_t)
+#define EC_IOCTL_SC_WATCHDOG EC_IOW(0x2d, ec_ioctl_config_t)
+#define EC_IOCTL_SC_ADD_PDO EC_IOW(0x2e, ec_ioctl_config_pdo_t)
+#define EC_IOCTL_SC_CLEAR_PDOS EC_IOW(0x2f, ec_ioctl_config_pdo_t)
+#define EC_IOCTL_SC_ADD_ENTRY EC_IOW(0x30, ec_ioctl_add_pdo_entry_t)
+#define EC_IOCTL_SC_CLEAR_ENTRIES EC_IOW(0x31, ec_ioctl_config_pdo_t)
+#define EC_IOCTL_SC_REG_PDO_ENTRY EC_IOWR(0x32, ec_ioctl_reg_pdo_entry_t)
+#define EC_IOCTL_SC_DC EC_IOW(0x33, ec_ioctl_config_t)
+#define EC_IOCTL_SC_SDO EC_IOW(0x34, ec_ioctl_sc_sdo_t)
+#define EC_IOCTL_SC_SDO_REQUEST EC_IOWR(0x35, ec_ioctl_sdo_request_t)
+#define EC_IOCTL_SC_VOE EC_IOWR(0x36, ec_ioctl_voe_t)
+#define EC_IOCTL_SC_STATE EC_IOWR(0x37, ec_ioctl_sc_state_t)
+#define EC_IOCTL_SC_IDN EC_IOW(0x38, ec_ioctl_sc_idn_t)
+#define EC_IOCTL_DOMAIN_OFFSET EC_IO(0x39)
+#define EC_IOCTL_DOMAIN_PROCESS EC_IO(0x3a)
+#define EC_IOCTL_DOMAIN_QUEUE EC_IO(0x3b)
+#define EC_IOCTL_DOMAIN_STATE EC_IOWR(0x3c, ec_ioctl_domain_state_t)
+#define EC_IOCTL_SDO_REQUEST_TIMEOUT EC_IOWR(0x3d, ec_ioctl_sdo_request_t)
+#define EC_IOCTL_SDO_REQUEST_STATE EC_IOWR(0x3e, ec_ioctl_sdo_request_t)
+#define EC_IOCTL_SDO_REQUEST_READ EC_IOWR(0x3f, ec_ioctl_sdo_request_t)
+#define EC_IOCTL_SDO_REQUEST_WRITE EC_IOWR(0x40, ec_ioctl_sdo_request_t)
+#define EC_IOCTL_SDO_REQUEST_DATA EC_IOWR(0x41, ec_ioctl_sdo_request_t)
+#define EC_IOCTL_VOE_SEND_HEADER EC_IOW(0x42, ec_ioctl_voe_t)
+#define EC_IOCTL_VOE_REC_HEADER EC_IOWR(0x43, ec_ioctl_voe_t)
+#define EC_IOCTL_VOE_READ EC_IOW(0x44, ec_ioctl_voe_t)
+#define EC_IOCTL_VOE_READ_NOSYNC EC_IOW(0x45, ec_ioctl_voe_t)
+#define EC_IOCTL_VOE_WRITE EC_IOWR(0x46, ec_ioctl_voe_t)
+#define EC_IOCTL_VOE_EXEC EC_IOWR(0x47, ec_ioctl_voe_t)
+#define EC_IOCTL_VOE_DATA EC_IOWR(0x48, ec_ioctl_voe_t)
+#define EC_IOCTL_SET_SEND_INTERVAL EC_IOW(0x49, size_t)
+#define EC_IOCTL_MASTER_SC_STATE EC_IOR(0x50, ec_master_state_t)
+#define EC_IOCTL_SC_OVERLAPPING_IO EC_IOW(0x51, ec_ioctl_config_t)
/*****************************************************************************/
--- a/master/master.c Mon Mar 14 16:55:09 2011 +0100
+++ b/master/master.c Mon Mar 14 16:57:47 2011 +0100
@@ -2477,6 +2477,19 @@
/*****************************************************************************/
+void ecrt_master_reset(ec_master_t *master)
+{
+ ec_slave_config_t *sc;
+
+ list_for_each_entry(sc, &master->configs, list) {
+ if (sc->slave) {
+ ec_slave_request_state(sc->slave, EC_SLAVE_STATE_OP);
+ }
+ }
+}
+
+/*****************************************************************************/
+
/** \cond */
EXPORT_SYMBOL(ecrt_master_create_domain);
@@ -2496,6 +2509,7 @@
EXPORT_SYMBOL(ecrt_master_sync_monitor_process);
EXPORT_SYMBOL(ecrt_master_write_idn);
EXPORT_SYMBOL(ecrt_master_read_idn);
+EXPORT_SYMBOL(ecrt_master_reset);
/** \endcond */
--- a/tool/Command.cpp Mon Mar 14 16:55:09 2011 +0100
+++ b/tool/Command.cpp Mon Mar 14 16:57:47 2011 +0100
@@ -29,22 +29,120 @@
*
****************************************************************************/
+#include <map>
+using namespace std;
+
#include "Command.h"
#include "MasterDevice.h"
#include "NumberListParser.h"
/*****************************************************************************/
+typedef map<uint16_t, ec_ioctl_config_t> AliasMap;
+typedef map<uint16_t, AliasMap> 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<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]);
}
- 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;
--- a/tool/Command.h Mon Mar 14 16:55:09 2011 +0100
+++ b/tool/Command.h Mon Mar 14 16:57:47 2011 +0100
@@ -96,16 +96,20 @@
};
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 @@
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 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;
--- a/tool/NumberListParser.cpp Mon Mar 14 16:55:09 2011 +0100
+++ b/tool/NumberListParser.cpp Mon Mar 14 16:57:47 2011 +0100
@@ -50,9 +50,9 @@
/*****************************************************************************/
-NumberListParser::NumberList NumberListParser::parse(const char *data)
-{
- NumberList ret;
+NumberListParser::List NumberListParser::parse(const char *data)
+{
+ List ret;
unsigned int i = 0, size = strlen(data), firstNum = 0U, secondNum = 0U;
typedef enum {
SectionStart,
@@ -108,17 +108,41 @@
case Range:
if (i >= size) {
- secondNum = maximum();
- NumberList r = range(firstNum, secondNum);
- ret.splice(ret.end(), r);
+ int max = maximum();
+ // only increasing ranges if second number omitted
+ if (max >= 0 && firstNum <= (unsigned int) max) {
+ 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] == ',') {
- i++;
- secondNum = maximum();
- NumberList r = range(firstNum, secondNum);
+ int max = maximum();
+ i++;
+ if (max >= 0) {
+ List r = range(firstNum, max);
+ ret.splice(ret.end(), r);
+ }
+ state = SectionStart;
+ } else {
+ stringstream err;
+ err << "Invalid character " << data[i]
+ << " at position " << i << "in state "
+ << state << "." << endl;
+ throw runtime_error(err.str());
+ }
+ break;
+
+ case SecondNumber:
+ if (i >= size) {
+ List r = range(firstNum, secondNum);
+ ret.splice(ret.end(), r);
+ state = Finished;
+ } else if (data[i] == ',') {
+ i++;
+ List r = range(firstNum, secondNum);
ret.splice(ret.end(), r);
state = SectionStart;
} else {
@@ -130,25 +154,6 @@
}
break;
- case SecondNumber:
- if (i >= size) {
- NumberList r = range(firstNum, secondNum);
- ret.splice(ret.end(), r);
- state = Finished;
- } else if (data[i] == ',') {
- i++;
- NumberList r = range(firstNum, secondNum);
- ret.splice(ret.end(), r);
- state = SectionStart;
- } else {
- stringstream err;
- err << "Invalid character " << data[i]
- << " at position " << i << "in state "
- << state << "." << endl;
- throw runtime_error(err.str());
- }
- break;
-
default:
{
stringstream err;
@@ -163,7 +168,7 @@
/*****************************************************************************/
-unsigned int NumberListParser::maximum()
+int NumberListParser::maximum()
{
if (!hasMax) {
max = getMax();
@@ -207,12 +212,12 @@
/****************************************************************************/
-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++) {
--- a/tool/NumberListParser.h Mon Mar 14 16:55:09 2011 +0100
+++ b/tool/NumberListParser.h Mon Mar 14 16:57:47 2011 +0100
@@ -38,22 +38,22 @@
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);
};
/****************************************************************************/
--- a/tool/main.cpp Mon Mar 14 16:55:09 2011 +0100
+++ b/tool/main.cpp Mon Mar 14 16:57:47 2011 +0100
@@ -77,9 +77,9 @@
// 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 @@
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 @@
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);