Replace Argument class with CLI11
CLI11 is one of the most commonly use argument parser in OpenBMC.
The Argument class will be replaced with CLI11 and the
argument.(h/c)pp file will be removed.
Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: Ibff60a19d3ff9209ca70889acc9e6aec4a8d4fca
diff --git a/argument.cpp b/argument.cpp
deleted file mode 100644
index f8e5aaf..0000000
--- a/argument.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * Copyright © 2016 IBM Corporation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "argument.hpp"
-
-#include <algorithm>
-#include <cassert>
-#include <iostream>
-#include <iterator>
-
-namespace phosphor
-{
-namespace led
-{
-ArgumentParser::ArgumentParser(int argc, char** argv)
-{
- int option = 0;
- while (-1 !=
- (option = getopt_long(argc, argv, optionstr, &options[0], nullptr)))
- {
- switch (option)
- {
- case '?':
- case 'h':
- usage(argv);
- exit(-1);
- break;
- case 'p':
- arguments["path"] = optarg;
- break;
- }
- }
-}
-
-const std::string& ArgumentParser::operator[](const std::string& opt)
-{
- static const std::string emptyString{};
-
- auto i = arguments.find(opt);
- if (i == arguments.end())
- {
- return emptyString;
- }
-
- return i->second;
-}
-
-void ArgumentParser::usage(char** argv)
-{
- // NOLINTNEXTLINE
- std::cerr << "Usage: " << argv[0] << " [options]" << std::endl;
- std::cerr << "Options:" << std::endl;
- std::cerr << " --help Print this menu" << std::endl;
- std::cerr << " --path=<path> absolute path of LED in sysfs; like";
- std::cerr << " /sys/class/leds/<name>" << std::endl;
-}
-} // namespace led
-} // namespace phosphor
diff --git a/argument.hpp b/argument.hpp
deleted file mode 100644
index 6afb762..0000000
--- a/argument.hpp
+++ /dev/null
@@ -1,58 +0,0 @@
-#ifndef ARGUMENT_H
-#define ARGUMENT_H
-#include <getopt.h>
-
-#include <map>
-#include <string>
-
-namespace phosphor
-{
-namespace led
-{
-/** @brief Class - Encapsulates parsing command line options and
- * populating arguments
- */
-class ArgumentParser
-{
- public:
- ArgumentParser() = delete;
- ~ArgumentParser() = default;
- ArgumentParser(const ArgumentParser&) = delete;
- ArgumentParser& operator=(const ArgumentParser&) = delete;
- ArgumentParser(ArgumentParser&&) = default;
- ArgumentParser& operator=(ArgumentParser&&) = default;
-
- /** @brief Constructs Argument object
- *
- * @param argc - the main function's argc passed as is
- * @param argv - the main function's argv passed as is
- * @return Object constructed
- */
- ArgumentParser(int argc, char** argv);
-
- /** @brief Given a option, returns its argument(optarg) */
- const std::string& operator[](const std::string& opt);
-
- /** @brief Displays usage */
- static void usage(char** argv);
-
- private:
- /** @brief Option to argument mapping */
- std::map<const std::string, std::string> arguments;
-
- /** @brief Array of struct options as needed by getopt_long */
- // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays)
- static inline const option options[] = {
- {"path", required_argument, nullptr, 'p'},
- {"help", no_argument, nullptr, 'h'},
- {nullptr, 0, nullptr, 0},
- };
-
- /** @brief optstring as needed by getopt_long */
- static inline const char* const optionstr = "p:?h";
-};
-
-} // namespace led
-} // namespace phosphor
-
-#endif
diff --git a/controller.cpp b/controller.cpp
index afe476e..fd08c74 100644
--- a/controller.cpp
+++ b/controller.cpp
@@ -14,24 +14,16 @@
* limitations under the License.
*/
-#include "argument.hpp"
#include "physical.hpp"
#include "sysfs.hpp"
+#include <CLI/CLI.hpp>
#include <boost/algorithm/string.hpp>
#include <algorithm>
#include <iostream>
#include <string>
-static void exitWithError(const char* err, char** argv)
-{
- phosphor::led::ArgumentParser::usage(argv);
- std::cerr << std::endl;
- std::cerr << "ERROR: " << err << std::endl;
- exit(-1);
-}
-
struct LedDescr
{
std::string devicename;
@@ -50,7 +42,10 @@
void getLedDescr(const std::string& name, LedDescr& ledDescr)
{
std::vector<std::string> words;
+ // FIXME: https://bugs.llvm.org/show_bug.cgi?id=41141
+ // NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks)
boost::split(words, name, boost::is_any_of(":"));
+ // NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
try
{
ledDescr.devicename = words.at(0);
@@ -90,19 +85,23 @@
static constexpr auto objParent = "/xyz/openbmc_project/led/physical";
static constexpr auto devParent = "/sys/class/leds/";
- // Read arguments.
- auto options = phosphor::led::ArgumentParser(argc, argv);
+ CLI::App app{"Control and Drive the physical LEDs"};
- // FIXME: https://bugs.llvm.org/show_bug.cgi?id=41141
- // NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks)
+ // Read arguments.
+ std::string path{};
+ app.add_option("-p,--path", path,
+ "absolute path of LED in sysfs; like /sys/class/leds/<name>")
+ ->required();
// Parse out Path argument.
- if (options["path"].empty())
+ try
{
- exitWithError("Path not specified.", argv);
+ app.parse(argc, argv);
}
-
- auto path = options["path"];
+ catch (const CLI::Error& e)
+ {
+ return app.exit(e);
+ }
// If the LED has a hyphen in the name like: "one-two", then it gets passed
// as /one/two/ as opposed to /one-two to the service file. There is a
@@ -133,7 +132,7 @@
// Convert LED name in sysfs into DBus name
LedDescr ledDescr;
getLedDescr(name, ledDescr);
- // NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
+
name = getDbusName(ledDescr);
// Unique bus name representing a single LED.
diff --git a/meson.build b/meson.build
index 0ae8584..2d4dd91 100644
--- a/meson.build
+++ b/meson.build
@@ -13,7 +13,16 @@
sdbusplus_dep = dependency('sdbusplus')
phosphor_dbus_interfaces_dep = dependency('phosphor-dbus-interfaces')
boost = dependency('boost', include_type: 'system')
+
+cxx = meson.get_compiler('cpp')
+if cxx.has_header('CLI/CLI.hpp')
+ cli11_dep = declare_dependency()
+else
+ cli11_dep = dependency('CLI11')
+endif
+
deps = [
+ cli11_dep,
sdbusplus_dep,
phosphor_dbus_interfaces_dep,
boost,
@@ -28,7 +37,6 @@
)
sources = [
- 'argument.cpp',
'controller.cpp',
'physical.cpp',
'sysfs.cpp',
diff --git a/subprojects/CLI11.wrap b/subprojects/CLI11.wrap
new file mode 100644
index 0000000..2e5a95b
--- /dev/null
+++ b/subprojects/CLI11.wrap
@@ -0,0 +1,6 @@
+[wrap-git]
+url = https://github.com/CLIUtils/CLI11.git
+revision = HEAD
+
+[provide]
+CLI11 = CLI11_dep