cmdargs: use boost::program_options
This commit is contained in:
10
configure.ac
10
configure.ac
@@ -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 ============================
|
||||
|
||||
186
src/cmdargs.cpp
186
src/cmdargs.cpp
@@ -18,115 +18,159 @@
|
||||
* 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 (!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)
|
||||
exit(1);
|
||||
Mpd.SetHostname(argv[i]);
|
||||
continue;
|
||||
cout << "Usage: " << argv[0] << " [options]...\n" << desc << "\n";
|
||||
return false;
|
||||
}
|
||||
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"))
|
||||
if (vm.count("version"))
|
||||
{
|
||||
std::cout << "ncmpcpp " << VERSION << "\n\n"
|
||||
<< "optional screens compiled-in:\n"
|
||||
# ifdef HAVE_TAGLIB_H
|
||||
# ifdef HAVE_TAGLIB_H
|
||||
<< " - tag editor\n"
|
||||
<< " - tiny tag editor\n"
|
||||
# endif
|
||||
# ifdef HAVE_CURL_CURL_H
|
||||
# endif
|
||||
# ifdef HAVE_CURL_CURL_H
|
||||
<< " - artist info\n"
|
||||
# endif
|
||||
# ifdef ENABLE_OUTPUTS
|
||||
# endif
|
||||
# ifdef ENABLE_OUTPUTS
|
||||
<< " - outputs\n"
|
||||
# endif
|
||||
# ifdef ENABLE_VISUALIZER
|
||||
# endif
|
||||
# ifdef ENABLE_VISUALIZER
|
||||
<< " - visualizer\n"
|
||||
# endif
|
||||
# ifdef ENABLE_CLOCK
|
||||
# endif
|
||||
# ifdef ENABLE_CLOCK
|
||||
<< " - clock\n"
|
||||
# endif
|
||||
# endif
|
||||
<< "\nencoding detection: "
|
||||
# ifdef HAVE_LANGINFO_H
|
||||
# ifdef HAVE_LANGINFO_H
|
||||
<< "enabled"
|
||||
# else
|
||||
# else
|
||||
<< "disabled"
|
||||
# endif // HAVE_LANGINFO_H
|
||||
# endif // HAVE_LANGINFO_H
|
||||
<< "\nbuilt with support for:"
|
||||
# ifdef HAVE_CURL_CURL_H
|
||||
# ifdef HAVE_CURL_CURL_H
|
||||
<< " curl"
|
||||
# endif
|
||||
# ifdef HAVE_FFTW3_H
|
||||
# endif
|
||||
# ifdef HAVE_FFTW3_H
|
||||
<< " fftw"
|
||||
# endif
|
||||
# ifdef USE_PDCURSES
|
||||
# endif
|
||||
# ifdef USE_PDCURSES
|
||||
<< " pdcurses"
|
||||
# else
|
||||
# else
|
||||
<< " ncurses"
|
||||
# endif
|
||||
# ifdef HAVE_TAGLIB_H
|
||||
# endif
|
||||
# ifdef HAVE_TAGLIB_H
|
||||
<< " taglib"
|
||||
# endif
|
||||
# ifdef NCMPCPP_UNICODE
|
||||
# endif
|
||||
# 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);
|
||||
# endif
|
||||
<< "\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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user