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)
|
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 ============================
|
||||||
|
|||||||
190
src/cmdargs.cpp
190
src/cmdargs.cpp
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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())
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user