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)
)
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 = checking for boost.regex =
dnl ============================

View File

@@ -18,32 +18,58 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include <boost/program_options.hpp>
#include <iostream>
#include "bindings.h"
#include "cmdargs.h"
#include "config.h"
#include "mpdpp.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 (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--host"))
{
if (++i >= argc)
exit(1);
Mpd.SetHostname(argv[i]);
continue;
if (!s.empty() && s[0] == '~')
s.replace(0, 1, env_home);
}
if (!strcmp(argv[i], "-p") || !strcmp(argv[i], "--port"))
{
if (++i >= argc)
exit(1);
Mpd.SetPort(atoi(argv[i]));
continue;
}
else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version"))
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
{
po::store(po::parse_command_line(argc, argv, desc), vm);
if (vm.count("help"))
{
cout << "Usage: " << argv[0] << " [options]...\n" << desc << "\n";
return false;
}
if (vm.count("version"))
{
std::cout << "ncmpcpp " << VERSION << "\n\n"
<< "optional screens compiled-in:\n"
@@ -87,46 +113,64 @@ void ParseArgv(int argc, char **argv)
# ifdef NCMPCPP_UNICODE
<< " unicode"
# endif
<< std::endl;
exit(0);
}
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);
<< "\n";
return false;
}
if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--screen"))
po::notify(vm);
env_home = getenv("HOME");
if (env_home == nullptr)
{
if (++i == argc)
{
std::cerr << "No screen specified" << std::endl;
exit(1);
cerr << "Fatal error: HOME environment variable is not defined\n";
return false;
}
Config.startup_screen_type = stringtoStartupScreenType(argv[i]);
replace_tilda_with_home(config_path);
replace_tilda_with_home(bindings_path);
// 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)
{
std::cerr << "Invalid screen: " << argv[i] << std::endl;
exit(1);
std::cerr << "Invalid screen: " << screen << "\n";
return false;
}
}
else if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--config"))
}
catch (std::exception &e)
{
// this is used in Configuration::CheckForCommandLineConfigFilePath, ignoring here.
++i;
}
else
{
std::cerr << "Invalid option: " << argv[i] << std::endl;
exit(1);
}
cerr << "Error while parsing command line options: " << e.what() << "\n";
return false;
}
return true;
}

View File

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

View File

@@ -101,31 +101,10 @@ int main(int argc, char **argv)
std::setlocale(LC_ALL, "");
std::locale::global(Charset::internalLocale());
Config.CheckForCommandLineConfigFilePath(argv, argc);
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);
if (!ParseArguments(argc, argv))
return 0;
Mpd.SetTimeout(Config.mpd_connection_timeout);
if (argc > 1)
ParseArgv(argc, argv);
CreateDir(Config.ncmpcpp_directory);
// always execute these commands, even if ncmpcpp use exit function

View File

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

View File

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