tool/main.cpp
changeset 1125 9976f7b9fe66
parent 1122 ee305a780a02
child 1126 b09fd81894cb
equal deleted inserted replaced
1124:5da7c73c4f63 1125:9976f7b9fe66
    18 
    18 
    19 string binaryBaseName;
    19 string binaryBaseName;
    20 unsigned int masterIndex = 0;
    20 unsigned int masterIndex = 0;
    21 int slavePosition = -1;
    21 int slavePosition = -1;
    22 int domainIndex = -1;
    22 int domainIndex = -1;
    23 string command;
    23 string commandName;
    24 vector<string> commandArgs;
    24 vector<string> commandArgs;
    25 Verbosity verbosity = Normal;
    25 Verbosity verbosity = Normal;
    26 string dataTypeStr;
    26 string dataTypeStr;
    27 bool force = false;
    27 bool force = false;
    28 
    28 
    31 MasterDevice masterDev;
    31 MasterDevice masterDev;
    32 
    32 
    33 /*****************************************************************************/
    33 /*****************************************************************************/
    34 
    34 
    35 struct Command {
    35 struct Command {
       
    36     const char *name;
    36     void (*func)(void);
    37     void (*func)(void);
    37     const char *helpString;
    38     const char *helpString;
    38 
    39 
    39     int execute(void) const;
    40     int execute(void) const;
    40     void displayHelp(void) const;
    41     void displayHelp(void) const;
    41 };
    42 };
    42 
    43 
    43 struct CommandAlias {
       
    44     const char *name;
       
    45     const Command *command;
       
    46 };
       
    47 
       
    48 /*****************************************************************************/
    44 /*****************************************************************************/
    49 
    45 
    50 #define COMMAND(name) \
    46 #define COMMAND(name) \
    51     void command_##name(void); \
    47     void command_##name(void); \
    52     extern const char *help_##name; \
    48     extern const char *help_##name
    53     const Command cmd_##name = {command_##name, help_##name};
    49 
       
    50 #define INIT_COMMAND(name) {#name, command_##name, help_##name}
    54 
    51 
    55 COMMAND(alias);
    52 COMMAND(alias);
    56 COMMAND(config);
    53 COMMAND(config);
    57 
    54 
    58 const CommandAlias commandAliases[] = {
    55 static const Command commands[] = {
    59     {"alias",  &cmd_alias},
    56     INIT_COMMAND(alias),
    60 
    57     INIT_COMMAND(config),
    61     {"config", &cmd_config},
       
    62     {"conf",   &cmd_config},
       
    63     {"cf",     &cmd_config},
       
    64 };
    58 };
    65 
    59 
    66 #if 0
    60 #if 0
    67         } else if (command == "data") {
    61         } else if (command == "data") {
    68             master.outputData(domainIndex);
    62             master.outputData(domainIndex);
   113         << "  sii_read      Output a slave's SII contents." << endl
   107         << "  sii_read      Output a slave's SII contents." << endl
   114         << "  sii_write     Write slave's SII contents." << endl
   108         << "  sii_write     Write slave's SII contents." << endl
   115         << "  slaves        Show slaves." << endl
   109         << "  slaves        Show slaves." << endl
   116         << "  state         Request slave states." << endl
   110         << "  state         Request slave states." << endl
   117         << "  xml           Generate slave information xmls." << endl
   111         << "  xml           Generate slave information xmls." << endl
       
   112         << "Commands can be generously abbreviated." << endl
   118 		<< "Global options:" << endl
   113 		<< "Global options:" << endl
   119         << "  --master  -m <master>  Index of the master to use. Default: 0"
   114         << "  --master  -m <master>  Index of the master to use. Default: 0"
   120 		<< endl
   115 		<< endl
   121         << "  --slave   -s <index>   Positive numerical ring position,"
   116         << "  --slave   -s <index>   Positive numerical ring position,"
   122         << endl
   117         << endl
   239         }
   234         }
   240         printUsage();
   235         printUsage();
   241         exit(!helpRequested);
   236         exit(!helpRequested);
   242 	}
   237 	}
   243 
   238 
   244     command = argv[optind];
   239     commandName = argv[optind];
   245     while (++optind < argc)
   240     while (++optind < argc)
   246         commandArgs.push_back(string(argv[optind]));
   241         commandArgs.push_back(string(argv[optind]));
   247 }
   242 }
   248 
   243 
   249 /****************************************************************************/
   244 /****************************************************************************/
   269 
   264 
   270 /****************************************************************************/
   265 /****************************************************************************/
   271 
   266 
   272 void Command::displayHelp() const
   267 void Command::displayHelp() const
   273 {
   268 {
   274     cerr << binaryBaseName << " " << command << " " << helpString;
   269     cerr << binaryBaseName << " " << commandName << " " << helpString;
       
   270 }
       
   271 
       
   272 /****************************************************************************/
       
   273 
       
   274 bool abbrevMatch(const string &abb, const string &full)
       
   275 {
       
   276     unsigned int abbIndex;
       
   277     size_t fullPos = 0;
       
   278 
       
   279     for (abbIndex = 0; abbIndex < abb.length(); abbIndex++) {
       
   280         fullPos = full.find(abb[abbIndex], fullPos);
       
   281         if (fullPos == string::npos)
       
   282             return false;
       
   283     }
       
   284 
       
   285     return true;
       
   286 }
       
   287     
       
   288 /****************************************************************************/
       
   289 
       
   290 list<const Command *> getMatchingCommands(const string &cmdStr)
       
   291 {
       
   292     const Command *cmd, *endCmd =
       
   293         commands + sizeof(commands) / sizeof(Command);
       
   294     list<const Command *> res;
       
   295 
       
   296     // find matching commands
       
   297     for (cmd = commands; cmd < endCmd; cmd++) {
       
   298         if (abbrevMatch(cmdStr, cmd->name)) {
       
   299             res.push_back(cmd);
       
   300         }
       
   301     }
       
   302 
       
   303     return res;
   275 }
   304 }
   276 
   305 
   277 /****************************************************************************/
   306 /****************************************************************************/
   278 
   307 
   279 int main(int argc, char **argv)
   308 int main(int argc, char **argv)
   280 {
   309 {
   281     int retval = 0;
   310     int retval = 0;
   282     const CommandAlias *alias;
   311     list<const Command *> commands;
   283     const CommandAlias *endAlias =
   312     list<const Command *>::const_iterator ci;
   284         commandAliases + sizeof(commandAliases) / sizeof(CommandAlias);
   313     const Command *cmd;
   285 
   314 
   286     binaryBaseName = basename(argv[0]);
   315     binaryBaseName = basename(argv[0]);
   287 	getOptions(argc, argv);
   316 	getOptions(argc, argv);
   288 
   317 
   289     // search command alias in alias map
   318     commands = getMatchingCommands(commandName);
   290     for (alias = commandAliases; alias < endAlias; alias++) {
   319 
   291         if (command == alias->name)
   320     if (commands.size()) {
   292             break;
   321         if (commands.size() == 1) {
   293     }
   322             cmd = commands.front();
   294 
   323             if (!helpRequested) {
   295     if (alias < endAlias) { // command alias found
   324                 masterDev.setIndex(masterIndex);
   296         if (!helpRequested) {
   325                 retval = cmd->execute();
   297             masterDev.setIndex(masterIndex);
   326             } else {
   298             retval = alias->command->execute();
   327                 cmd->displayHelp();
       
   328             }
   299         } else {
   329         } else {
   300             alias->command->displayHelp();
   330             cerr << "Ambigous command abbreviation! Matching:" << endl;
       
   331             for (ci = commands.begin(); ci != commands.end(); ci++) {
       
   332                 cerr << (*ci)->name << endl;
       
   333             }
       
   334             cerr << endl;
       
   335             printUsage();
       
   336             retval = 1;
   301         }
   337         }
   302     } else { // command not found
   338     } else {
   303         cerr << "Unknown command " << command << "!" << endl << endl;
   339         cerr << "Unknown command " << commandName << "!" << endl << endl;
   304         printUsage();
   340         printUsage();
   305         retval = 1;
   341         retval = 1;
   306     }
   342     }
   307 
   343 
   308 	return retval;
   344 	return retval;