tool/main.cpp
changeset 1122 ee305a780a02
parent 1121 52a005ffd011
child 1125 9976f7b9fe66
equal deleted inserted replaced
1121:52a005ffd011 1122:ee305a780a02
    10 #include <iostream>
    10 #include <iostream>
    11 #include <string>
    11 #include <string>
    12 #include <vector>
    12 #include <vector>
    13 using namespace std;
    13 using namespace std;
    14 
    14 
    15 #include "Master.h"
    15 #include "globals.h"
    16 
    16 
    17 /*****************************************************************************/
    17 /*****************************************************************************/
    18 
    18 
    19 #define DEFAULT_MASTER 0
    19 string binaryBaseName;
    20 
    20 unsigned int masterIndex = 0;
    21 static string cmdName;
    21 int slavePosition = -1;
    22 static unsigned int masterIndex = DEFAULT_MASTER;
    22 int domainIndex = -1;
    23 static int slavePosition = -1;
    23 string command;
    24 static int domainIndex = -1;
       
    25 static string command;
       
    26 vector<string> commandArgs;
    24 vector<string> commandArgs;
    27 static Master::Verbosity verbosity = Master::Normal;
    25 Verbosity verbosity = Normal;
    28 string dataTypeStr;
    26 string dataTypeStr;
    29 bool force = false;
    27 bool force = false;
       
    28 
    30 bool helpRequested = false;
    29 bool helpRequested = false;
    31 
    30 
    32 /*****************************************************************************/
    31 MasterDevice masterDev;
    33 
    32 
    34 void printUsage()
    33 /*****************************************************************************/
    35 {
    34 
    36     cerr
    35 struct Command {
    37         << "Usage: " << cmdName << " <COMMAND> [OPTIONS]" << endl
    36     void (*func)(void);
    38 		<< "Commands:" << endl
    37     const char *helpString;
    39         << "  alias         Write alias addresses." << endl
    38 
    40         << "  config        Show bus configuration." << endl
    39     int execute(void) const;
    41         << "  data          Output binary domain process data." << endl
    40     void displayHelp(void) const;
    42         << "  debug         Set the master's debug level." << endl
    41 };
    43         << "  domain        Show domain information." << endl
    42 
    44         << "  master        Show master information." << endl
    43 struct CommandAlias {
    45         << "  pdos          List Pdo assignment/mapping." << endl
    44     const char *name;
    46         << "  sdo_download  Write an Sdo entry." << endl
    45     const Command *command;
    47         << "  sdos          List Sdo dictionaries." << endl
    46 };
    48         << "  sdo_upload    Read an Sdo entry." << endl
    47 
    49         << "  sii_read      Output a slave's SII contents." << endl
    48 /*****************************************************************************/
    50         << "  sii_write     Write slave's SII contents." << endl
    49 
    51         << "  slaves        Show slaves." << endl
    50 #define COMMAND(name) \
    52         << "  state         Request slave states." << endl
    51     void command_##name(void); \
    53         << "  xml           Generate slave information xmls." << endl
    52     extern const char *help_##name; \
    54 		<< "Global options:" << endl
    53     const Command cmd_##name = {command_##name, help_##name};
    55         << "  --master  -m <master>  Index of the master to use. Default: "
    54 
    56 		<< DEFAULT_MASTER << endl
    55 COMMAND(alias);
    57         << "  --slave   -s <index>   Positive numerical ring position,"
    56 COMMAND(config);
    58         << endl
    57 
    59         << "                         or 'all' for all slaves (default)."
    58 const CommandAlias commandAliases[] = {
    60         << endl
    59     {"alias",  &cmd_alias},
    61         << "  --domain  -d <index>   Positive numerical index,"
    60 
    62         << endl
    61     {"config", &cmd_config},
    63         << "                         or 'all' for all domains (default)."
    62     {"conf",   &cmd_config},
    64         << endl
    63     {"cf",     &cmd_config},
    65         << "  --type    -t <type>    Forced Sdo data type." << endl
    64 };
    66         << "  --force   -f           Force action." << endl
    65 
    67         << "  --quiet   -q           Output less information." << endl
    66 #if 0
    68         << "  --verbose -v           Output more information." << endl
       
    69         << "  --help    -h           Show this help." << endl
       
    70         << "Call '" << cmdName << " <COMMAND> --help' for command-specific "
       
    71         << "help." << endl
       
    72         << "Send bug reports to " << PACKAGE_BUGREPORT << "." << endl;
       
    73 }
       
    74 
       
    75 /*****************************************************************************/
       
    76 
       
    77 void getOptions(int argc, char **argv)
       
    78 {
       
    79     int c, argCount, optionIndex, number;
       
    80 	char *remainder;
       
    81 
       
    82     static struct option longOptions[] = {
       
    83         //name,     has_arg,           flag, val
       
    84         {"master",  required_argument, NULL, 'm'},
       
    85         {"slave",   required_argument, NULL, 's'},
       
    86         {"domain",  required_argument, NULL, 'd'},
       
    87         {"type",    required_argument, NULL, 't'},
       
    88         {"force",   no_argument,       NULL, 'f'},
       
    89         {"quiet",   no_argument,       NULL, 'q'},
       
    90         {"verbose", no_argument,       NULL, 'v'},
       
    91         {"help",    no_argument,       NULL, 'h'},
       
    92         {}
       
    93     };
       
    94 
       
    95     do {
       
    96         c = getopt_long(argc, argv, "m:s:d:t:fqvh", longOptions, &optionIndex);
       
    97 
       
    98         switch (c) {
       
    99             case 'm':
       
   100                 number = strtoul(optarg, &remainder, 0);
       
   101                 if (remainder == optarg || *remainder || number < 0) {
       
   102                     cerr << "Invalid master number " << optarg << "!" << endl;
       
   103                     printUsage();
       
   104                     exit(1);
       
   105                 }
       
   106 				masterIndex = number;
       
   107                 break;
       
   108 
       
   109             case 's':
       
   110                 if (!strcmp(optarg, "all")) {
       
   111                     slavePosition = -1;
       
   112                 } else {
       
   113                     number = strtoul(optarg, &remainder, 0);
       
   114                     if (remainder == optarg || *remainder
       
   115                             || number < 0 || number > 0xFFFF) {
       
   116                         cerr << "Invalid slave position "
       
   117                             << optarg << "!" << endl;
       
   118                         printUsage();
       
   119                         exit(1);
       
   120                     }
       
   121                     slavePosition = number;
       
   122                 }
       
   123                 break;
       
   124 
       
   125             case 'd':
       
   126                 if (!strcmp(optarg, "all")) {
       
   127                     domainIndex = -1;
       
   128                 } else {
       
   129                     number = strtoul(optarg, &remainder, 0);
       
   130                     if (remainder == optarg || *remainder || number < 0) {
       
   131                         cerr << "Invalid domain index "
       
   132 							<< optarg << "!" << endl;
       
   133                         printUsage();
       
   134                         exit(1);
       
   135                     }
       
   136                     domainIndex = number;
       
   137                 }
       
   138                 break;
       
   139 
       
   140             case 't':
       
   141                 dataTypeStr = optarg;
       
   142                 break;
       
   143 
       
   144             case 'f':
       
   145                 force = true;
       
   146                 break;
       
   147 
       
   148             case 'q':
       
   149                 verbosity = Master::Quiet;
       
   150                 break;
       
   151 
       
   152             case 'v':
       
   153                 verbosity = Master::Verbose;
       
   154                 break;
       
   155 
       
   156             case 'h':
       
   157                 helpRequested = true;
       
   158                 break;
       
   159 
       
   160             case '?':
       
   161                 printUsage();
       
   162                 exit(1);
       
   163 
       
   164             default:
       
   165                 break;
       
   166         }
       
   167     }
       
   168     while (c != -1);
       
   169 
       
   170 	argCount = argc - optind;
       
   171 
       
   172     if (!argCount) {
       
   173         if (!helpRequested) {
       
   174             cerr << "Please specify a command!" << endl;
       
   175         }
       
   176         printUsage();
       
   177         exit(!helpRequested);
       
   178 	}
       
   179 
       
   180     command = argv[optind];
       
   181     while (++optind < argc)
       
   182         commandArgs.push_back(string(argv[optind]));
       
   183 }
       
   184 
       
   185 /****************************************************************************/
       
   186 
       
   187 int main(int argc, char **argv)
       
   188 {
       
   189     Master master;
       
   190 
       
   191     cmdName = basename(argv[0]);
       
   192     
       
   193 	getOptions(argc, argv);
       
   194 
       
   195     master.setIndex(masterIndex);
       
   196     master.setVerbosity(verbosity);
       
   197 
       
   198     try {
       
   199         if (command == "alias") {
       
   200             master.writeAlias(slavePosition, force, commandArgs);
       
   201         } else if (command == "config") {
       
   202             master.showConfigs();
       
   203         } else if (command == "data") {
    67         } else if (command == "data") {
   204             master.outputData(domainIndex);
    68             master.outputData(domainIndex);
   205         } else if (command == "debug") {
    69         } else if (command == "debug") {
   206             master.setDebug(commandArgs);
    70             master.setDebug(commandArgs);
   207         } else if (command == "domain") {
    71         } else if (command == "domain") {
   225             master.siiWrite(slavePosition, force, commandArgs);
    89             master.siiWrite(slavePosition, force, commandArgs);
   226         } else if (command == "state") {
    90         } else if (command == "state") {
   227             master.requestStates(slavePosition, commandArgs);
    91             master.requestStates(slavePosition, commandArgs);
   228         } else if (command == "xml") {
    92         } else if (command == "xml") {
   229             master.generateXml(slavePosition);
    93             master.generateXml(slavePosition);
       
    94 #endif
       
    95 
       
    96 /*****************************************************************************/
       
    97 
       
    98 void printUsage()
       
    99 {
       
   100     cerr
       
   101         << "Usage: " << binaryBaseName << " <COMMAND> [OPTIONS]" << endl
       
   102 		<< "Commands:" << endl
       
   103         << "  alias         Write alias addresses." << endl
       
   104         << "  config        Show bus configuration." << endl
       
   105         << "  data          Output binary domain process data." << endl
       
   106         << "  debug         Set the master's debug level." << endl
       
   107         << "  domain        Show domain information." << endl
       
   108         << "  master        Show master information." << endl
       
   109         << "  pdos          List Pdo assignment/mapping." << endl
       
   110         << "  sdo_download  Write an Sdo entry." << endl
       
   111         << "  sdos          List Sdo dictionaries." << endl
       
   112         << "  sdo_upload    Read an Sdo entry." << endl
       
   113         << "  sii_read      Output a slave's SII contents." << endl
       
   114         << "  sii_write     Write slave's SII contents." << endl
       
   115         << "  slaves        Show slaves." << endl
       
   116         << "  state         Request slave states." << endl
       
   117         << "  xml           Generate slave information xmls." << endl
       
   118 		<< "Global options:" << endl
       
   119         << "  --master  -m <master>  Index of the master to use. Default: 0"
       
   120 		<< endl
       
   121         << "  --slave   -s <index>   Positive numerical ring position,"
       
   122         << endl
       
   123         << "                         or 'all' for all slaves (default)."
       
   124         << endl
       
   125         << "  --domain  -d <index>   Positive numerical index,"
       
   126         << endl
       
   127         << "                         or 'all' for all domains (default)."
       
   128         << endl
       
   129         << "  --type    -t <type>    Forced Sdo data type." << endl
       
   130         << "  --force   -f           Force action." << endl
       
   131         << "  --quiet   -q           Output less information." << endl
       
   132         << "  --verbose -v           Output more information." << endl
       
   133         << "  --help    -h           Show this help." << endl
       
   134         << "Call '" << binaryBaseName
       
   135         << " <COMMAND> --help' for command-specific help." << endl
       
   136         << "Send bug reports to " << PACKAGE_BUGREPORT << "." << endl;
       
   137 }
       
   138 
       
   139 /*****************************************************************************/
       
   140 
       
   141 void getOptions(int argc, char **argv)
       
   142 {
       
   143     int c, argCount, optionIndex, number;
       
   144 	char *remainder;
       
   145 
       
   146     static struct option longOptions[] = {
       
   147         //name,     has_arg,           flag, val
       
   148         {"master",  required_argument, NULL, 'm'},
       
   149         {"slave",   required_argument, NULL, 's'},
       
   150         {"domain",  required_argument, NULL, 'd'},
       
   151         {"type",    required_argument, NULL, 't'},
       
   152         {"force",   no_argument,       NULL, 'f'},
       
   153         {"quiet",   no_argument,       NULL, 'q'},
       
   154         {"verbose", no_argument,       NULL, 'v'},
       
   155         {"help",    no_argument,       NULL, 'h'},
       
   156         {}
       
   157     };
       
   158 
       
   159     do {
       
   160         c = getopt_long(argc, argv, "m:s:d:t:fqvh", longOptions, &optionIndex);
       
   161 
       
   162         switch (c) {
       
   163             case 'm':
       
   164                 number = strtoul(optarg, &remainder, 0);
       
   165                 if (remainder == optarg || *remainder || number < 0) {
       
   166                     cerr << "Invalid master number " << optarg << "!" << endl;
       
   167                     printUsage();
       
   168                     exit(1);
       
   169                 }
       
   170 				masterIndex = number;
       
   171                 break;
       
   172 
       
   173             case 's':
       
   174                 if (!strcmp(optarg, "all")) {
       
   175                     slavePosition = -1;
       
   176                 } else {
       
   177                     number = strtoul(optarg, &remainder, 0);
       
   178                     if (remainder == optarg || *remainder
       
   179                             || number < 0 || number > 0xFFFF) {
       
   180                         cerr << "Invalid slave position "
       
   181                             << optarg << "!" << endl;
       
   182                         printUsage();
       
   183                         exit(1);
       
   184                     }
       
   185                     slavePosition = number;
       
   186                 }
       
   187                 break;
       
   188 
       
   189             case 'd':
       
   190                 if (!strcmp(optarg, "all")) {
       
   191                     domainIndex = -1;
       
   192                 } else {
       
   193                     number = strtoul(optarg, &remainder, 0);
       
   194                     if (remainder == optarg || *remainder || number < 0) {
       
   195                         cerr << "Invalid domain index "
       
   196 							<< optarg << "!" << endl;
       
   197                         printUsage();
       
   198                         exit(1);
       
   199                     }
       
   200                     domainIndex = number;
       
   201                 }
       
   202                 break;
       
   203 
       
   204             case 't':
       
   205                 dataTypeStr = optarg;
       
   206                 break;
       
   207 
       
   208             case 'f':
       
   209                 force = true;
       
   210                 break;
       
   211 
       
   212             case 'q':
       
   213                 verbosity = Quiet;
       
   214                 break;
       
   215 
       
   216             case 'v':
       
   217                 verbosity = Verbose;
       
   218                 break;
       
   219 
       
   220             case 'h':
       
   221                 helpRequested = true;
       
   222                 break;
       
   223 
       
   224             case '?':
       
   225                 printUsage();
       
   226                 exit(1);
       
   227 
       
   228             default:
       
   229                 break;
       
   230         }
       
   231     }
       
   232     while (c != -1);
       
   233 
       
   234 	argCount = argc - optind;
       
   235 
       
   236     if (!argCount) {
       
   237         if (!helpRequested) {
       
   238             cerr << "Please specify a command!" << endl;
       
   239         }
       
   240         printUsage();
       
   241         exit(!helpRequested);
       
   242 	}
       
   243 
       
   244     command = argv[optind];
       
   245     while (++optind < argc)
       
   246         commandArgs.push_back(string(argv[optind]));
       
   247 }
       
   248 
       
   249 /****************************************************************************/
       
   250 
       
   251 int Command::execute() const
       
   252 {
       
   253     try {
       
   254         func();
       
   255     } catch (InvalidUsageException &e) {
       
   256         cerr << e.what() << endl << endl;
       
   257         displayHelp();
       
   258         return 1;
       
   259     } catch (ExecutionFailureException &e) {
       
   260         cerr << e.what() << endl;
       
   261         return 1;
       
   262     } catch (MasterDeviceException &e) {
       
   263         cerr << e.what() << endl;
       
   264         return 1;
       
   265     }
       
   266 
       
   267     return 0;
       
   268 }
       
   269 
       
   270 /****************************************************************************/
       
   271 
       
   272 void Command::displayHelp() const
       
   273 {
       
   274     cerr << binaryBaseName << " " << command << " " << helpString;
       
   275 }
       
   276 
       
   277 /****************************************************************************/
       
   278 
       
   279 int main(int argc, char **argv)
       
   280 {
       
   281     int retval = 0;
       
   282     const CommandAlias *alias;
       
   283     const CommandAlias *endAlias =
       
   284         commandAliases + sizeof(commandAliases) / sizeof(CommandAlias);
       
   285 
       
   286     binaryBaseName = basename(argv[0]);
       
   287 	getOptions(argc, argv);
       
   288 
       
   289     // search command alias in alias map
       
   290     for (alias = commandAliases; alias < endAlias; alias++) {
       
   291         if (command == alias->name)
       
   292             break;
       
   293     }
       
   294 
       
   295     if (alias < endAlias) { // command alias found
       
   296         if (!helpRequested) {
       
   297             masterDev.setIndex(masterIndex);
       
   298             retval = alias->command->execute();
   230         } else {
   299         } else {
   231             cerr << "Unknown command " << command << "!" << endl;
   300             alias->command->displayHelp();
   232             printUsage();
       
   233             exit(1);
       
   234         }
   301         }
   235     } catch (MasterException &e) {
   302     } else { // command not found
   236         cerr << e.what() << endl;
   303         cerr << "Unknown command " << command << "!" << endl << endl;
   237         exit(1);
   304         printUsage();
       
   305         retval = 1;
   238     }
   306     }
   239 
   307 
   240 	return 0;
   308 	return retval;
   241 }
   309 }
   242 
   310 
   243 /****************************************************************************/
   311 /****************************************************************************/