2 +--------------------------------------------------------------------+
3 | libmemcached - C/C++ Client Library for memcached |
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted under the terms of the BSD license. |
7 | You should have received a copy of the license in a bundled file |
8 | named LICENSE; in case you did not receive a copy you can review |
9 | the terms online at: https://opensource.org/licenses/BSD-3-Clause |
10 +--------------------------------------------------------------------+
11 | Copyright (c) 2006-2014 Brian Aker https://datadifferential.com/ |
12 | Copyright (c) 2020 Michael Wallner <mike@php.net> |
13 +--------------------------------------------------------------------+
16 #include "options.hpp"
18 void client_options::print_version() const {
19 std::cout
<< prog_name
<< " v" << prog_vers
<< " (libmemcached v" << LIBMEMCACHED_VERSION_STRING
<< ")"
23 void client_options::print_help() const {
25 std::cout
<< "\n\t" << prog_desc
<< "\n\n";
26 std::cout
<< "Usage:\n\t" << prog_name
<< " -[";
27 for (const auto &opt
: options
) {
28 if (!opt
.opt
.has_arg
&& opt
.opt
.val
!= '-') {
29 std::cout
<< (char) opt
.opt
.val
;
33 for (const auto &ext
: options
) {
34 if (ext
.opt
.has_arg
) {
35 std::cout
<< (char) ext
.opt
.val
;
36 if ((&ext
) != &*options
.rbegin())
40 std::cout
<< " <arg>] ";
43 std::cout
<< prog_argp
;
45 std::cout
<< "\n\nOptions:\n";
46 for (const auto &ext
: options
) {
47 if (ext
.opt
.val
== '-' || !(ext
.opt
.val
|| ext
.opt
.name
)) {
52 std::cout
<< "-" << (char) ext
.opt
.val
;
60 std::cout
<< "--" << ext
.opt
.name
<< " ";
64 if (ext
.opt
.has_arg
) {
65 if (ext
.opt
.has_arg
== optional_argument
) {
71 if (ext
.opt
.has_arg
== optional_argument
) {
77 std::cout
<< "\n\t\t" << ext
.help
<< "\n";
81 std::cout
<< "\nEnvironment:\n";
82 std::cout
<< "\tMEMCACHED_SERVERS=\n";
83 std::cout
<< "\t\tList of servers to use if `-s|--servers` was not provided.\n";
85 std::cout
<< std::endl
;
88 bool client_options::parse(int argc
, char **argv
, char ***argp
) {
89 /* extern */ optind
= 1;
90 auto debug
= has("debug") ? &get("debug") : nullptr;
91 std::string short_opts
{};
92 std::vector
<option
> long_opts
{};
94 short_opts
.reserve(options
.size() * 3);
95 long_opts
.reserve(options
.size() + 1);
97 for (const auto &ext
: options
) {
99 short_opts
.push_back(ext
.opt
.val
);
100 for (int i
= 0; i
< ext
.opt
.has_arg
; ++i
) {
101 short_opts
.push_back(':');
105 long_opts
.push_back(ext
.opt
);
108 long_opts
.push_back({});
111 auto opt
= getopt_long(argc
, argv
, short_opts
.c_str(), long_opts
.data(), nullptr);
113 if (debug
->set
&& opt
> 0) {
114 std::cerr
<< "Processing option '" << (char) opt
<< "' (" << opt
<< ")\n";
121 *argp
= &argv
[optind
];
126 auto &ext_opt
= get(opt
);
128 // grab optional argument
129 if (ext_opt
.opt
.has_arg
== optional_argument
&& !optarg
) {
130 auto next_arg
= argv
[optind
];
132 if (next_arg
&& *next_arg
&& *next_arg
!= '-') {
139 ext_opt
.arg
= optarg
;
142 if (!ext_opt
.parse(*this, ext_opt
)) {
149 bool client_options::apply(memcached_st
*memc
) {
152 if (WSAStartup(MAKEWORD(2, 2), &wsaData
)) {
153 std::cerr
<< "Socket Initialization Error.\n";
158 extended_option
*servers
= nullptr;
159 for (auto &opt
: options
) {
161 // servers should be applied last, so they take up any behaviors previously set
162 if (opt
.opt
.val
== 's' && opt
.opt
.name
== std::string("servers")) {
166 if (!opt
.apply(*this, opt
, memc
)) {
172 if (!servers
->apply(*this, *servers
, memc
)) {