tool/Command.cpp
changeset 2015 ce2fae4d3c4f
parent 2014 1d2111370ad5
child 2421 bc2d4bf9cbe5
child 2589 2b9c78543663
equal deleted inserted replaced
2011:04fdb4abf120 2015:ce2fae4d3c4f
    33 using namespace std;
    33 using namespace std;
    34 
    34 
    35 #include "Command.h"
    35 #include "Command.h"
    36 #include "MasterDevice.h"
    36 #include "MasterDevice.h"
    37 #include "NumberListParser.h"
    37 #include "NumberListParser.h"
       
    38 
       
    39 /*****************************************************************************/
       
    40 
       
    41 typedef map<uint16_t, ec_ioctl_config_t> AliasMap;
       
    42 typedef map<uint16_t, AliasMap> ConfigMap;
    38 
    43 
    39 /*****************************************************************************/
    44 /*****************************************************************************/
    40 
    45 
    41 class MasterIndexParser:
    46 class MasterIndexParser:
    42     public NumberListParser
    47     public NumberListParser
    83 
    88 
    84 class ConfigAliasParser:
    89 class ConfigAliasParser:
    85     public NumberListParser
    90     public NumberListParser
    86 {
    91 {
    87     public:
    92     public:
    88         ConfigAliasParser(ec_ioctl_master_t &master, MasterDevice &dev):
    93         ConfigAliasParser(unsigned int maxAlias):
    89             master(master), dev(dev) {}
    94             maxAlias(maxAlias) {}
    90 
    95 
    91     protected:
    96     protected:
    92         int getMax() {
    97         int getMax() { return maxAlias; };
    93             unsigned int i;
       
    94 
       
    95             uint16_t maxAlias = 0;
       
    96             for (i = 0; i < master.config_count; i++) {
       
    97                 ec_ioctl_config_t config;
       
    98                 dev.getConfig(&config, i);
       
    99                 if (config.alias > maxAlias) {
       
   100                     maxAlias = config.alias;
       
   101                 }
       
   102             }
       
   103             return maxAlias ? maxAlias : -1;
       
   104         };
       
   105 
    98 
   106     private:
    99     private:
   107         ec_ioctl_master_t &master;
   100         unsigned int maxAlias;
   108         MasterDevice &dev;
       
   109 };
   101 };
   110 
   102 
   111 /*****************************************************************************/
   103 /*****************************************************************************/
   112 
   104 
   113 class PositionParser:
   105 class PositionParser:
   122             return count - 1;
   114             return count - 1;
   123         };
   115         };
   124 
   116 
   125     private:
   117     private:
   126         const unsigned int count;
   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;
   127 };
   146 };
   128 
   147 
   129 /*****************************************************************************/
   148 /*****************************************************************************/
   130 
   149 
   131 Command::Command(const string &name, const string &briefDesc):
   150 Command::Command(const string &name, const string &briefDesc):
   291 /*****************************************************************************/
   310 /*****************************************************************************/
   292 
   311 
   293 unsigned int Command::getSingleMasterIndex() const
   312 unsigned int Command::getSingleMasterIndex() const
   294 {
   313 {
   295     MasterIndexList masterIndices = getMasterIndices();
   314     MasterIndexList masterIndices = getMasterIndices();
       
   315 
   296     if (masterIndices.size() != 1) {
   316     if (masterIndices.size() != 1) {
   297         stringstream err;
   317         stringstream err;
   298         err << getName() << " requires to select a single master!";
   318         err << getName() << " requires to select a single master!";
   299         throwInvalidUsageException(err);
   319         throwInvalidUsageException(err);
   300     }
   320     }
       
   321 
   301     return masterIndices.front();
   322     return masterIndices.front();
   302 }
   323 }
   303 
   324 
   304 /*****************************************************************************/
   325 /*****************************************************************************/
   305 
   326 
   314 
   335 
   315     if (aliases == "-") { // no alias given
   336     if (aliases == "-") { // no alias given
   316         PositionParser pp(master.slave_count);
   337         PositionParser pp(master.slave_count);
   317         NumberListParser::List posList = pp.parse(positions.c_str());
   338         NumberListParser::List posList = pp.parse(positions.c_str());
   318         NumberListParser::List::const_iterator pi;
   339         NumberListParser::List::const_iterator pi;
       
   340 
   319         for (pi = posList.begin(); pi != posList.end(); pi++) {
   341         for (pi = posList.begin(); pi != posList.end(); pi++) {
   320             m.getSlave(&slave, *pi);
   342             if (*pi < master.slave_count) {
   321             list.push_back(slave);
   343                 m.getSlave(&slave, *pi);
       
   344                 list.push_back(slave);
       
   345             }
   322         }
   346         }
   323     } else { // aliases given
   347     } else { // aliases given
   324         SlaveAliasParser ap(master, m);
   348         SlaveAliasParser ap(master, m);
   325         NumberListParser::List aliasList = ap.parse(aliases.c_str());
   349         NumberListParser::List aliasList = ap.parse(aliases.c_str());
   326         NumberListParser::List::const_iterator ai;
   350         NumberListParser::List::const_iterator ai;
   351             NumberListParser::List::const_iterator pi;
   375             NumberListParser::List::const_iterator pi;
   352 
   376 
   353             for (pi = posList.begin(); pi != posList.end(); pi++) {
   377             for (pi = posList.begin(); pi != posList.end(); pi++) {
   354                 if (*pi < aliasSlaves.size()) {
   378                 if (*pi < aliasSlaves.size()) {
   355                     list.push_back(aliasSlaves[*pi]);
   379                     list.push_back(aliasSlaves[*pi]);
   356                 } else {
       
   357                     stringstream err;
       
   358                     err << "Warning: Slave " << *ai << ":" << *pi
       
   359                         << " does not exist on master " << m.getIndex();
       
   360                     throwCommandException(err);
       
   361                 }
   380                 }
   362             }
   381             }
   363         }
   382         }
   364     }
   383     }
   365 
   384 
   387     ConfigList list;
   406     ConfigList list;
   388     stringstream err;
   407     stringstream err;
   389 
   408 
   390     m.getMaster(&master);
   409     m.getMaster(&master);
   391 
   410 
   392     if (aliases == "-") { // no alias given
   411     if (aliases == "-" && positions == "-") { // shortcut
   393         PositionParser pp(master.config_count);
   412         for (i = 0; i < master.config_count; i++) {
   394         NumberListParser::List posList = pp.parse(positions.c_str());
   413             m.getConfig(&config, i);
   395         NumberListParser::List::const_iterator pi;
       
   396         for (pi = posList.begin(); pi != posList.end(); pi++) {
       
   397             m.getConfig(&config, *pi); // FIXME use sorted list
       
   398             list.push_back(config);
   414             list.push_back(config);
   399         }
   415         }
   400     } else { // alias given
   416     } else { // take the long way home...
   401         ConfigAliasParser ap(master, m);
   417         ConfigMap configs;
       
   418         uint16_t maxAlias = 0;
       
   419 
       
   420         // fill cascaded map structure with all configs
       
   421         for (i = 0; i < master.config_count; i++) {
       
   422             m.getConfig(&config, i);
       
   423             AliasMap &aliasMap = configs[config.alias];
       
   424             aliasMap[config.position] = config;
       
   425             if (config.alias > maxAlias) {
       
   426                 maxAlias = config.alias;
       
   427             }
       
   428         }
       
   429 
       
   430         ConfigAliasParser ap(maxAlias);
   402         NumberListParser::List aliasList = ap.parse(aliases.c_str());
   431         NumberListParser::List aliasList = ap.parse(aliases.c_str());
   403         NumberListParser::List::const_iterator ai;
   432         NumberListParser::List::const_iterator ai;
   404 
   433 
   405         for (ai = aliasList.begin(); ai != aliasList.end(); ai++) {
   434         for (ai = aliasList.begin(); ai != aliasList.end(); ai++) {
   406 
   435 
   407             // gather configs with that alias
   436             ConfigMap::iterator ci = configs.find(*ai);
   408             map<uint16_t, ec_ioctl_config_t> aliasConfigs;
   437             if (ci == configs.end()) {
   409 
   438                 continue;
   410             int maxPos = -1;
   439             }
   411             for (i = 0; i < master.config_count; i++) {
   440 
   412                 m.getConfig(&config, i);
   441             AliasMap &aliasMap = configs[*ai];
   413                 if (config.alias == *ai) {
   442             AliasPositionParser pp(aliasMap);
   414                     aliasConfigs[config.position] = config;
       
   415                     if (config.position > maxPos) {
       
   416                         maxPos = config.position;
       
   417                     }
       
   418                 }
       
   419             }
       
   420 
       
   421             PositionParser pp(maxPos + 1);
       
   422             NumberListParser::List posList = pp.parse(positions.c_str());
   443             NumberListParser::List posList = pp.parse(positions.c_str());
   423             NumberListParser::List::const_iterator pi;
   444             NumberListParser::List::const_iterator pi;
   424 
   445 
   425             for (pi = posList.begin(); pi != posList.end(); pi++) {
   446             for (pi = posList.begin(); pi != posList.end(); pi++) {
   426                 map<uint16_t, ec_ioctl_config_t>::const_iterator ci;
   447                 AliasMap::const_iterator ci;
   427                 ci = aliasConfigs.find(*pi);
   448 
   428 
   449                 ci = aliasMap.find(*pi);
   429                 if (ci != aliasConfigs.end()) {
   450                 if (ci != aliasMap.end()) {
   430                     list.push_back(ci->second);
   451                     list.push_back(ci->second);
   431                 } else { 
       
   432                     stringstream err;
       
   433                     err << "Warning: Config " << *ai << ":" << *pi
       
   434                         << " does not exist on master " << m.getIndex();
       
   435                     throwCommandException(err);
       
   436                 }
   452                 }
   437             }
   453             }
   438         }
   454         }
   439     }
   455     }
   440 
   456 
   454     PositionParser pp(master.domain_count);
   470     PositionParser pp(master.domain_count);
   455     NumberListParser::List domList = pp.parse(domains.c_str());
   471     NumberListParser::List domList = pp.parse(domains.c_str());
   456     NumberListParser::List::const_iterator di;
   472     NumberListParser::List::const_iterator di;
   457 
   473 
   458     for (di = domList.begin(); di != domList.end(); di++) {
   474     for (di = domList.begin(); di != domList.end(); di++) {
   459         ec_ioctl_domain_t d;
   475         if (*di < master.domain_count) {
   460         m.getDomain(&d, *di);
   476             ec_ioctl_domain_t d;
   461         list.push_back(d);
   477             m.getDomain(&d, *di);
       
   478             list.push_back(d);
       
   479         }
   462     }
   480     }
   463 
   481 
   464     return list;
   482     return list;
   465 }
   483 }
   466 
   484