cmdargs: use boost::program_options

This commit is contained in:
Andrzej Rybczak
2014-08-28 05:46:49 +02:00
parent 99937bb468
commit 8a1e4a48dd
6 changed files with 133 additions and 119 deletions

View File

@@ -146,6 +146,16 @@ AC_CHECK_HEADERS([boost/date_time/posix_time/posix_time.hpp], ,
AC_MSG_ERROR(boost/date_time/posix_time/posix_time.hpp is missing) AC_MSG_ERROR(boost/date_time/posix_time/posix_time.hpp is missing)
) )
dnl ======================================
dnl = checking for boost.program_options =
dnl ======================================
AC_CHECK_HEADERS([boost/program_options.hpp], ,
AC_MSG_ERROR(boost/program_options.hpp is missing)
)
AC_CHECK_LIB(boost_program_options$BOOST_LIB_SUFFIX, main, LDFLAGS="$LDFLAGS -lboost_program_options$BOOST_LIB_SUFFIX",
AC_MSG_ERROR([no boost.program_options library found])
)
dnl ============================ dnl ============================
dnl = checking for boost.regex = dnl = checking for boost.regex =
dnl ============================ dnl ============================

View File

@@ -18,115 +18,159 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/ ***************************************************************************/
#include <boost/program_options.hpp>
#include <iostream> #include <iostream>
#include "bindings.h"
#include "cmdargs.h" #include "cmdargs.h"
#include "config.h" #include "config.h"
#include "mpdpp.h" #include "mpdpp.h"
#include "settings.h" #include "settings.h"
void ParseArgv(int argc, char **argv) namespace po = boost::program_options;
using std::cerr;
using std::cout;
namespace {
const char *env_home;
void replace_tilda_with_home(std::string &s)
{ {
for (int i = 1; i < argc; ++i) if (!s.empty() && s[0] == '~')
s.replace(0, 1, env_home);
}
}
bool ParseArguments(int argc, char **argv)
{
std::string bindings_path, config_path;
po::options_description desc("Options");
desc.add_options()
("host,h", po::value<std::string>()->default_value("localhost"), "connect to server at host")
("port,p", po::value<int>()->default_value(6600), "connect to server at port")
("config,c", po::value<std::string>(&config_path)->default_value("~/.ncmpcpp/config"), "specify configuration file")
("bindigs,b", po::value<std::string>(&bindings_path)->default_value("~/.ncmpcpp/bindings"), "specify bindings file")
("screen,s", po::value<std::string>(), "specify the startup screen")
("help,?", "show help message")
("version,v", "display version information")
;
po::variables_map vm;
try
{ {
if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--host")) po::store(po::parse_command_line(argc, argv, desc), vm);
if (vm.count("help"))
{ {
if (++i >= argc) cout << "Usage: " << argv[0] << " [options]...\n" << desc << "\n";
exit(1); return false;
Mpd.SetHostname(argv[i]);
continue;
} }
if (!strcmp(argv[i], "-p") || !strcmp(argv[i], "--port")) if (vm.count("version"))
{
if (++i >= argc)
exit(1);
Mpd.SetPort(atoi(argv[i]));
continue;
}
else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version"))
{ {
std::cout << "ncmpcpp " << VERSION << "\n\n" std::cout << "ncmpcpp " << VERSION << "\n\n"
<< "optional screens compiled-in:\n" << "optional screens compiled-in:\n"
# ifdef HAVE_TAGLIB_H # ifdef HAVE_TAGLIB_H
<< " - tag editor\n" << " - tag editor\n"
<< " - tiny tag editor\n" << " - tiny tag editor\n"
# endif # endif
# ifdef HAVE_CURL_CURL_H # ifdef HAVE_CURL_CURL_H
<< " - artist info\n" << " - artist info\n"
# endif # endif
# ifdef ENABLE_OUTPUTS # ifdef ENABLE_OUTPUTS
<< " - outputs\n" << " - outputs\n"
# endif # endif
# ifdef ENABLE_VISUALIZER # ifdef ENABLE_VISUALIZER
<< " - visualizer\n" << " - visualizer\n"
# endif # endif
# ifdef ENABLE_CLOCK # ifdef ENABLE_CLOCK
<< " - clock\n" << " - clock\n"
# endif # endif
<< "\nencoding detection: " << "\nencoding detection: "
# ifdef HAVE_LANGINFO_H # ifdef HAVE_LANGINFO_H
<< "enabled" << "enabled"
# else # else
<< "disabled" << "disabled"
# endif // HAVE_LANGINFO_H # endif // HAVE_LANGINFO_H
<< "\nbuilt with support for:" << "\nbuilt with support for:"
# ifdef HAVE_CURL_CURL_H # ifdef HAVE_CURL_CURL_H
<< " curl" << " curl"
# endif # endif
# ifdef HAVE_FFTW3_H # ifdef HAVE_FFTW3_H
<< " fftw" << " fftw"
# endif # endif
# ifdef USE_PDCURSES # ifdef USE_PDCURSES
<< " pdcurses" << " pdcurses"
# else # else
<< " ncurses" << " ncurses"
# endif # endif
# ifdef HAVE_TAGLIB_H # ifdef HAVE_TAGLIB_H
<< " taglib" << " taglib"
# endif # endif
# ifdef NCMPCPP_UNICODE # ifdef NCMPCPP_UNICODE
<< " unicode" << " unicode"
# endif # endif
<< std::endl; << "\n";
exit(0); return false;
}
else if (!strcmp(argv[i], "-?") || !strcmp(argv[i], "--help"))
{
std::cout
<< "Usage: ncmpcpp [OPTION]...\n"
<< " -h, --host connect to server at host [localhost]\n"
<< " -p, --port connect to server at port [6600]\n"
<< " -c, --config use alternative configuration file\n"
<< " -s, --screen <name> specify the startup screen\n"
<< " -?, --help show help message\n"
<< " -v, --version display version information\n"
;
exit(0);
} }
if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--screen")) po::notify(vm);
env_home = getenv("HOME");
if (env_home == nullptr)
{ {
if (++i == argc) cerr << "Fatal error: HOME environment variable is not defined\n";
{ return false;
std::cerr << "No screen specified" << std::endl; }
exit(1); replace_tilda_with_home(config_path);
} replace_tilda_with_home(bindings_path);
Config.startup_screen_type = stringtoStartupScreenType(argv[i]);
// read configuration
Config.SetDefaults();
Config.Read(config_path);
Config.GenerateColumns();
// read bindings
if (Bindings.read(bindings_path) == false)
return false;
Bindings.generateDefaults();
// try to get MPD connection details from environment variables
// as they take precedence over these from the configuration.
auto env_host = getenv("MPD_HOST");
auto env_port = getenv("MPD_PORT");
if (env_host != nullptr)
Mpd.SetHostname(env_host);
if (env_port != nullptr)
Mpd.SetPort(boost::lexical_cast<int>(env_port));
// if MPD connection details are provided as command line
// parameters, use them as their priority is the highest.
if (vm.count("host"))
Mpd.SetHostname(vm["host"].as<std::string>());
if (vm.count("port"))
Mpd.SetPort(vm["port"].as<int>());
// custom startup screen
if (vm.count("screen"))
{
auto screen = vm["screen"].as<std::string>();
Config.startup_screen_type = stringtoStartupScreenType(screen);
if (Config.startup_screen_type == ScreenType::Unknown) if (Config.startup_screen_type == ScreenType::Unknown)
{ {
std::cerr << "Invalid screen: " << argv[i] << std::endl; std::cerr << "Invalid screen: " << screen << "\n";
exit(1); return false;
} }
} }
else if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--config"))
{
// this is used in Configuration::CheckForCommandLineConfigFilePath, ignoring here.
++i;
}
else
{
std::cerr << "Invalid option: " << argv[i] << std::endl;
exit(1);
}
} }
catch (std::exception &e)
{
cerr << "Error while parsing command line options: " << e.what() << "\n";
return false;
}
return true;
} }

View File

@@ -21,6 +21,6 @@
#ifndef NCMPCPP_CMDARGS_H #ifndef NCMPCPP_CMDARGS_H
#define NCMPCPP_CMDARGS_H #define NCMPCPP_CMDARGS_H
void ParseArgv(int argc, char **argv); bool ParseArguments(int argc, char **argv);
#endif // NCMPCPP_CMDARGS_H #endif // NCMPCPP_CMDARGS_H

View File

@@ -101,31 +101,10 @@ int main(int argc, char **argv)
std::setlocale(LC_ALL, ""); std::setlocale(LC_ALL, "");
std::locale::global(Charset::internalLocale()); std::locale::global(Charset::internalLocale());
Config.CheckForCommandLineConfigFilePath(argv, argc); if (!ParseArguments(argc, argv))
return 0;
Config.SetDefaults();
Config.Read();
Config.GenerateColumns();
if (!Bindings.read(Config.ncmpcpp_directory + "bindings"))
return 1;
Bindings.generateDefaults();
if (getenv("MPD_HOST"))
Mpd.SetHostname(getenv("MPD_HOST"));
if (getenv("MPD_PORT"))
Mpd.SetPort(atoi(getenv("MPD_PORT")));
if (Config.mpd_host != "localhost")
Mpd.SetHostname(Config.mpd_host);
if (Config.mpd_port != 6600)
Mpd.SetPort(Config.mpd_port);
Mpd.SetTimeout(Config.mpd_connection_timeout); Mpd.SetTimeout(Config.mpd_connection_timeout);
if (argc > 1)
ParseArgv(argc, argv);
CreateDir(Config.ncmpcpp_directory); CreateDir(Config.ncmpcpp_directory);
// always execute these commands, even if ncmpcpp use exit function // always execute these commands, even if ncmpcpp use exit function

View File

@@ -221,7 +221,6 @@ Configuration::Configuration()
ncmpcpp_directory = GetHomeDirectory() + ".ncmpcpp/"; ncmpcpp_directory = GetHomeDirectory() + ".ncmpcpp/";
lyrics_directory = GetHomeDirectory() + ".lyrics/"; lyrics_directory = GetHomeDirectory() + ".lyrics/";
# endif // WIN32 # endif // WIN32
config_file_path = ncmpcpp_directory + "config";
} }
const std::string &Configuration::GetHomeDirectory() const std::string &Configuration::GetHomeDirectory()
@@ -242,24 +241,9 @@ const std::string &Configuration::GetHomeDirectory()
return home_directory; return home_directory;
} }
void Configuration::CheckForCommandLineConfigFilePath(char **argv, int argc) void Configuration::Read(const std::string &config_path)
{ {
if (argc < 3) std::ifstream f(config_path.c_str());
return;
for (int i = 1; i < argc; ++i)
{
if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--config"))
{
if (++i >= argc)
continue;
config_file_path = argv[i];
}
}
}
void Configuration::Read()
{
std::ifstream f(config_file_path.c_str());
std::string cl, v, name; std::string cl, v, name;
if (!f.is_open()) if (!f.is_open())

View File

@@ -30,8 +30,6 @@
#include "screen_type.h" #include "screen_type.h"
#include "strbuffer.h" #include "strbuffer.h"
struct BaseScreen; // forward declaration for screens sequence
enum SortMode { smName, smMTime, smCustomFormat }; enum SortMode { smName, smMTime, smCustomFormat };
struct Column struct Column
@@ -56,7 +54,7 @@ struct Configuration
void CheckForCommandLineConfigFilePath(char **argv, int argc); void CheckForCommandLineConfigFilePath(char **argv, int argc);
void SetDefaults(); void SetDefaults();
void Read(); void Read(const std::string& config_path);
void GenerateColumns(); void GenerateColumns();
std::string ncmpcpp_directory; std::string ncmpcpp_directory;
@@ -199,7 +197,6 @@ private:
void MakeProperPath(std::string &dir); void MakeProperPath(std::string &dir);
std::string home_directory; std::string home_directory;
std::string config_file_path;
}; };
extern Configuration Config; extern Configuration Config;