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 |
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; |