tool/Command.cpp
changeset 2042 8b358effa78b
parent 2014 1d2111370ad5
child 2421 bc2d4bf9cbe5
child 2589 2b9c78543663
--- 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 <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;