tool/Command.cpp
changeset 2042 8b358effa78b
parent 2014 1d2111370ad5
child 2421 bc2d4bf9cbe5
child 2589 2b9c78543663
equal deleted inserted replaced
2041:f5b31f46c38f 2042:8b358effa78b
    27  *
    27  *
    28  *  vim: expandtab
    28  *  vim: expandtab
    29  *
    29  *
    30  ****************************************************************************/
    30  ****************************************************************************/
    31 
    31 
       
    32 #include <map>
       
    33 using namespace std;
       
    34 
    32 #include "Command.h"
    35 #include "Command.h"
    33 #include "MasterDevice.h"
    36 #include "MasterDevice.h"
    34 #include "NumberListParser.h"
    37 #include "NumberListParser.h"
    35 
    38 
    36 /*****************************************************************************/
    39 /*****************************************************************************/
    37 
    40 
       
    41 typedef map<uint16_t, ec_ioctl_config_t> AliasMap;
       
    42 typedef map<uint16_t, AliasMap> ConfigMap;
       
    43 
       
    44 /*****************************************************************************/
       
    45 
    38 class MasterIndexParser:
    46 class MasterIndexParser:
    39     public NumberListParser
    47     public NumberListParser
    40 {
    48 {
    41     unsigned int getMax()
    49     protected:
    42     {
    50         int getMax() {
    43         MasterDevice dev;
    51             MasterDevice dev;
    44         dev.setIndex(0U);
    52             dev.setIndex(0U);
    45         dev.open(MasterDevice::Read);
    53             dev.open(MasterDevice::Read);
    46         return dev.getMasterCount() - 1;
    54             return (int) dev.getMasterCount() - 1;
    47     };
    55         };
       
    56 };
       
    57 
       
    58 /*****************************************************************************/
       
    59 
       
    60 class SlaveAliasParser:
       
    61     public NumberListParser
       
    62 {
       
    63     public:
       
    64         SlaveAliasParser(ec_ioctl_master_t &master, MasterDevice &dev):
       
    65             master(master), dev(dev) {}
       
    66 
       
    67     protected:
       
    68         int getMax() {
       
    69             unsigned int i;
       
    70 
       
    71             uint16_t maxAlias = 0;
       
    72             for (i = 0; i < master.slave_count; i++) {
       
    73                 ec_ioctl_slave_t slave;
       
    74                 dev.getSlave(&slave, i);
       
    75                 if (slave.alias > maxAlias) {
       
    76                     maxAlias = slave.alias;
       
    77                 }
       
    78             }
       
    79             return maxAlias ? maxAlias : -1;
       
    80         };
       
    81 
       
    82     private:
       
    83         ec_ioctl_master_t &master;
       
    84         MasterDevice &dev;
       
    85 };
       
    86 
       
    87 /*****************************************************************************/
       
    88 
       
    89 class ConfigAliasParser:
       
    90     public NumberListParser
       
    91 {
       
    92     public:
       
    93         ConfigAliasParser(unsigned int maxAlias):
       
    94             maxAlias(maxAlias) {}
       
    95 
       
    96     protected:
       
    97         int getMax() { return maxAlias; };
       
    98 
       
    99     private:
       
   100         unsigned int maxAlias;
       
   101 };
       
   102 
       
   103 /*****************************************************************************/
       
   104 
       
   105 class PositionParser:
       
   106     public NumberListParser
       
   107 {
       
   108     public:
       
   109         PositionParser(unsigned int count):
       
   110             count(count) {}
       
   111 
       
   112     protected:
       
   113         int getMax() {
       
   114             return count - 1;
       
   115         };
       
   116 
       
   117     private:
       
   118         const unsigned int count;
       
   119 };
       
   120 
       
   121 /*****************************************************************************/
       
   122 
       
   123 class AliasPositionParser:
       
   124     public NumberListParser
       
   125 {
       
   126     public:
       
   127         AliasPositionParser(const AliasMap &aliasMap):
       
   128             aliasMap(aliasMap) {}
       
   129 
       
   130     protected:
       
   131         int getMax() {
       
   132             AliasMap::const_iterator i;
       
   133             int maxPos = -1;
       
   134 
       
   135             for (i = aliasMap.begin(); i != aliasMap.end(); i++) {
       
   136                 if (i->first > maxPos) {
       
   137                     maxPos = i->first;
       
   138                 }
       
   139             }
       
   140 
       
   141             return maxPos;
       
   142         };
       
   143 
       
   144     private:
       
   145         const AliasMap &aliasMap;
    48 };
   146 };
    49 
   147 
    50 /*****************************************************************************/
   148 /*****************************************************************************/
    51 
   149 
    52 Command::Command(const string &name, const string &briefDesc):
   150 Command::Command(const string &name, const string &briefDesc):
    76     verbosity = v;
   174     verbosity = v;
    77 };
   175 };
    78 
   176 
    79 /*****************************************************************************/
   177 /*****************************************************************************/
    80 
   178 
    81 void Command::setAlias(int a)
   179 void Command::setAliases(const string &a)
    82 {
   180 {
    83     alias = a;
   181     aliases = a;
    84 };
   182 };
    85 
   183 
    86 /*****************************************************************************/
   184 /*****************************************************************************/
    87 
   185 
    88 void Command::setPosition(int p)
   186 void Command::setPositions(const string &p)
    89 {
   187 {
    90     position = p;
   188     positions = p;
    91 };
   189 };
    92 
   190 
    93 /*****************************************************************************/
   191 /*****************************************************************************/
    94 
   192 
    95 void Command::setDomain(int d)
   193 void Command::setDomains(const string &d)
    96 {
   194 {
    97     domain = d;
   195     domains = d;
    98 };
   196 };
    99 
   197 
   100 /*****************************************************************************/
   198 /*****************************************************************************/
   101 
   199 
   102 void Command::setDataType(const string &t)
   200 void Command::setDataType(const string &t)
   212 /*****************************************************************************/
   310 /*****************************************************************************/
   213 
   311 
   214 unsigned int Command::getSingleMasterIndex() const
   312 unsigned int Command::getSingleMasterIndex() const
   215 {
   313 {
   216     MasterIndexList masterIndices = getMasterIndices();
   314     MasterIndexList masterIndices = getMasterIndices();
       
   315 
   217     if (masterIndices.size() != 1) {
   316     if (masterIndices.size() != 1) {
   218         stringstream err;
   317         stringstream err;
   219         err << getName() << " requires to select a single master!";
   318         err << getName() << " requires to select a single master!";
   220         throwInvalidUsageException(err);
   319         throwInvalidUsageException(err);
   221     }
   320     }
       
   321 
   222     return masterIndices.front();
   322     return masterIndices.front();
   223 }
   323 }
   224 
   324 
   225 /*****************************************************************************/
   325 /*****************************************************************************/
   226 
   326 
   227 Command::SlaveList Command::selectedSlaves(MasterDevice &m)
   327 Command::SlaveList Command::selectedSlaves(MasterDevice &m)
   228 {
   328 {
   229     ec_ioctl_master_t master;
   329     ec_ioctl_master_t master;
   230     unsigned int i, aliasIndex;
   330     unsigned int i;
   231     uint16_t lastAlias;
       
   232     ec_ioctl_slave_t slave;
   331     ec_ioctl_slave_t slave;
   233     SlaveList list;
   332     SlaveList list;
   234 
   333 
   235     m.getMaster(&master);
   334     m.getMaster(&master);
   236 
   335 
   237     if (alias == -1) { // no alias given
   336     if (aliases == "-") { // no alias given
   238         if (position == -1) { // no alias and position given
   337         PositionParser pp(master.slave_count);
   239             // all items
   338         NumberListParser::List posList = pp.parse(positions.c_str());
   240             for (i = 0; i < master.slave_count; i++) {
   339         NumberListParser::List::const_iterator pi;
   241                 m.getSlave(&slave, i);
   340 
       
   341         for (pi = posList.begin(); pi != posList.end(); pi++) {
       
   342             if (*pi < master.slave_count) {
       
   343                 m.getSlave(&slave, *pi);
   242                 list.push_back(slave);
   344                 list.push_back(slave);
   243             }
   345             }
   244         } else { // no alias, but position given
       
   245             // one item by position
       
   246             m.getSlave(&slave, position);
       
   247             list.push_back(slave);
       
   248         }
   346         }
   249     } else { // alias given
   347     } else { // aliases given
   250         if (position == -1) { // alias, but no position given
   348         SlaveAliasParser ap(master, m);
   251             // take all items with a given alias
   349         NumberListParser::List aliasList = ap.parse(aliases.c_str());
   252             lastAlias = 0;
   350         NumberListParser::List::const_iterator ai;
       
   351 
       
   352         for (ai = aliasList.begin(); ai != aliasList.end(); ai++) {
       
   353 
       
   354             // gather slaves with that alias (and following)
       
   355             uint16_t lastAlias = 0;
       
   356             vector<ec_ioctl_slave_t> aliasSlaves;
       
   357 
   253             for (i = 0; i < master.slave_count; i++) {
   358             for (i = 0; i < master.slave_count; i++) {
   254                 m.getSlave(&slave, i);
   359                 m.getSlave(&slave, i);
   255                 if (slave.alias) {
   360                 if (slave.alias) {
       
   361                     if (lastAlias && lastAlias == *ai && slave.alias != *ai) {
       
   362                         // ignore multiple ocurrences of the same alias to
       
   363                         // assure consistency for the position argument
       
   364                         break;
       
   365                     }
   256                     lastAlias = slave.alias;
   366                     lastAlias = slave.alias;
   257                 }
   367                 }
   258                 if (lastAlias == (uint16_t) alias) {
   368                 if (lastAlias == *ai) {
   259                     list.push_back(slave);
   369                     aliasSlaves.push_back(slave);
   260                 }
   370                 }
   261             }
   371             }
   262         } else { // alias and position given
   372 
   263             lastAlias = 0;
   373             PositionParser pp(aliasSlaves.size());
   264             aliasIndex = 0;
   374             NumberListParser::List posList = pp.parse(positions.c_str());
   265             for (i = 0; i < master.slave_count; i++) {
   375             NumberListParser::List::const_iterator pi;
   266                 m.getSlave(&slave, i);
   376 
   267                 if (slave.alias && slave.alias == (uint16_t) alias) {
   377             for (pi = posList.begin(); pi != posList.end(); pi++) {
   268                     lastAlias = slave.alias;
   378                 if (*pi < aliasSlaves.size()) {
   269                     aliasIndex = 0;
   379                     list.push_back(aliasSlaves[*pi]);
   270                 }
   380                 }
   271                 if (lastAlias && aliasIndex == (unsigned int) position) {
       
   272                     list.push_back(slave);
       
   273                 }
       
   274                 aliasIndex++;
       
   275             }
   381             }
   276         }
   382         }
   277     }
   383     }
   278 
   384 
   279     return list;
   385     return list;
   300     ConfigList list;
   406     ConfigList list;
   301     stringstream err;
   407     stringstream err;
   302 
   408 
   303     m.getMaster(&master);
   409     m.getMaster(&master);
   304 
   410 
   305     if (alias == -1) { // no alias given
   411     if (aliases == "-" && positions == "-") { // shortcut
   306         if (position == -1) { // no alias and position given
   412         for (i = 0; i < master.config_count; i++) {
   307             // all items
   413             m.getConfig(&config, i);
   308             for (i = 0; i < master.config_count; i++) {
   414             list.push_back(config);
   309                 m.getConfig(&config, i);
       
   310                 list.push_back(config);
       
   311             }
       
   312         } else { // no alias, but position given
       
   313             for (i = 0; i < master.config_count; i++) {
       
   314                 m.getConfig(&config, i);
       
   315                 if (!config.alias && config.position == position) {
       
   316                     list.push_back(config);
       
   317                     break; // there can be at most one matching
       
   318                 }
       
   319             }
       
   320         }
   415         }
   321     } else { // alias given
   416     } else { // take the long way home...
   322         if (position == -1) { // alias, but no position given
   417         ConfigMap configs;
   323             // take all items with a given alias
   418         uint16_t maxAlias = 0;
   324             for (i = 0; i < master.config_count; i++) {
   419 
   325                 m.getConfig(&config, i);
   420         // fill cascaded map structure with all configs
   326                 if (config.alias == alias) {
   421         for (i = 0; i < master.config_count; i++) {
   327                     list.push_back(config);
   422             m.getConfig(&config, i);
   328                 }
   423             AliasMap &aliasMap = configs[config.alias];
   329             }
   424             aliasMap[config.position] = config;
   330         } else { // alias and position given
   425             if (config.alias > maxAlias) {
   331             for (i = 0; i < master.config_count; i++) {
   426                 maxAlias = config.alias;
   332                 m.getConfig(&config, i);
   427             }
   333                 if (config.alias == alias && config.position == position) {
   428         }
   334                     list.push_back(config);
   429 
   335                     break; // there can be at most one matching
   430         ConfigAliasParser ap(maxAlias);
       
   431         NumberListParser::List aliasList = ap.parse(aliases.c_str());
       
   432         NumberListParser::List::const_iterator ai;
       
   433 
       
   434         for (ai = aliasList.begin(); ai != aliasList.end(); ai++) {
       
   435 
       
   436             ConfigMap::iterator ci = configs.find(*ai);
       
   437             if (ci == configs.end()) {
       
   438                 continue;
       
   439             }
       
   440 
       
   441             AliasMap &aliasMap = configs[*ai];
       
   442             AliasPositionParser pp(aliasMap);
       
   443             NumberListParser::List posList = pp.parse(positions.c_str());
       
   444             NumberListParser::List::const_iterator pi;
       
   445 
       
   446             for (pi = posList.begin(); pi != posList.end(); pi++) {
       
   447                 AliasMap::const_iterator ci;
       
   448 
       
   449                 ci = aliasMap.find(*pi);
       
   450                 if (ci != aliasMap.end()) {
       
   451                     list.push_back(ci->second);
   336                 }
   452                 }
   337             }
   453             }
   338         }
   454         }
   339     }
   455     }
   340 
   456 
   344 
   460 
   345 /****************************************************************************/
   461 /****************************************************************************/
   346 
   462 
   347 Command::DomainList Command::selectedDomains(MasterDevice &m)
   463 Command::DomainList Command::selectedDomains(MasterDevice &m)
   348 {
   464 {
   349     ec_ioctl_domain_t d;
   465     ec_ioctl_master_t master;
   350     DomainList list;
   466     DomainList list;
   351 
   467 
   352     if (domain == -1) {
   468     m.getMaster(&master);
   353         ec_ioctl_master_t master;
   469 
   354         unsigned int i;
   470     PositionParser pp(master.domain_count);
   355 
   471     NumberListParser::List domList = pp.parse(domains.c_str());
   356         m.getMaster(&master);
   472     NumberListParser::List::const_iterator di;
   357 
   473 
   358         for (i = 0; i < master.domain_count; i++) {
   474     for (di = domList.begin(); di != domList.end(); di++) {
   359             m.getDomain(&d, i);
   475         if (*di < master.domain_count) {
       
   476             ec_ioctl_domain_t d;
       
   477             m.getDomain(&d, *di);
   360             list.push_back(d);
   478             list.push_back(d);
   361         }
   479         }
   362     } else {
       
   363         m.getDomain(&d, domain);
       
   364         list.push_back(d);
       
   365     }
   480     }
   366 
   481 
   367     return list;
   482     return list;
   368 }
   483 }
   369 
   484