lshal: add HelpCommand
Add *Command::usage() function for each Command and let
Lshal class to call them.
Suppress output from getopt_long and write our own
error message to customized error stream (for testing).
Test: lshal_test
Test: lshal --help
Change-Id: I8f5847c84a3e01af29fa85871479cab3baeb5312
diff --git a/cmds/lshal/ListCommand.cpp b/cmds/lshal/ListCommand.cpp
index ffb4424..71ac25b 100644
--- a/cmds/lshal/ListCommand.cpp
+++ b/cmds/lshal/ListCommand.cpp
@@ -604,7 +604,7 @@
return status;
}
-Status ListCommand::parseArgs(const std::string &command, const Arg &arg) {
+Status ListCommand::parseArgs(const Arg &arg) {
static struct option longOptions[] = {
// long options with short alternatives
{"help", no_argument, 0, 'h' },
@@ -628,6 +628,9 @@
std::vector<TableColumnType> selectedColumns;
bool enableCmdlines = false;
+ // suppress output to std::err for unknown options
+ opterr = 0;
+
int optionIndex;
int c;
// Lshal::parseArgs has set optind to the next option to parse
@@ -646,7 +649,6 @@
mSortColumn = TableEntry::sortByServerPid;
} else {
err() << "Unrecognized sorting column: " << optarg << std::endl;
- mLshal.usage(command);
return USAGE;
}
break;
@@ -697,22 +699,22 @@
mNeat = true;
break;
}
- case 'h': // falls through
+ case 'h': {
+ return USAGE;
+ }
default: // see unrecognized options
- mLshal.usage(command);
+ err() << "unrecognized option `" << arg.argv[optind - 1] << "'" << std::endl;
return USAGE;
}
}
if (optind < arg.argc) {
// see non option
- err() << "Unrecognized option `" << arg.argv[optind] << "`" << std::endl;
- mLshal.usage(command);
+ err() << "unrecognized option `" << arg.argv[optind] << "'" << std::endl;
return USAGE;
}
if (mNeat && mEmitDebugInfo) {
err() << "Error: --neat should not be used with --debug." << std::endl;
- mLshal.usage(command);
return USAGE;
}
@@ -739,8 +741,8 @@
return OK;
}
-Status ListCommand::main(const std::string &command, const Arg &arg) {
- Status status = parseArgs(command, arg);
+Status ListCommand::main(const Arg &arg) {
+ Status status = parseArgs(arg);
if (status != OK) {
return status;
}
@@ -750,6 +752,41 @@
return status;
}
+void ListCommand::usage() const {
+
+ static const std::string list =
+ "list:\n"
+ " lshal\n"
+ " lshal list\n"
+ " List all hals with default ordering and columns (`lshal list -iepc`)\n"
+ " lshal list [-h|--help]\n"
+ " -h, --help: Print help message for list (`lshal help list`)\n"
+ " lshal [list] [--interface|-i] [--transport|-t] [-r|--arch] [-e|--threads]\n"
+ " [--pid|-p] [--address|-a] [--clients|-c] [--cmdline|-m]\n"
+ " [--sort={interface|i|pid|p}] [--init-vintf[=<output file>]]\n"
+ " [--debug|-d[=<output file>]] [--neat]\n"
+ " -i, --interface: print the interface name column\n"
+ " -n, --instance: print the instance name column\n"
+ " -t, --transport: print the transport mode column\n"
+ " -r, --arch: print if the HAL is in 64-bit or 32-bit\n"
+ " -e, --threads: print currently used/available threads\n"
+ " (note, available threads created lazily)\n"
+ " -p, --pid: print the server PID, or server cmdline if -m is set\n"
+ " -a, --address: print the server object address column\n"
+ " -c, --clients: print the client PIDs, or client cmdlines if -m is set\n"
+ " -m, --cmdline: print cmdline instead of PIDs\n"
+ " -d[=<output file>], --debug[=<output file>]: emit debug info from \n"
+ " IBase::debug with empty options. Cannot be used with --neat.\n"
+ " --sort=i, --sort=interface: sort by interface name\n"
+ " --sort=p, --sort=pid: sort by server pid\n"
+ " --neat: output is machine parsable (no explanatory text)\n"
+ " Cannot be used with --debug.\n"
+ " --init-vintf[=<output file>]: form a skeleton HAL manifest to specified\n"
+ " file, or stdout if no file specified.\n";
+
+ err() << list;
+}
+
} // namespace lshal
} // namespace android