1 /* <!-- copyright */
2 /*
3 * aria2 - The high speed download utility
4 *
5 * Copyright (C) 2010 Tatsuhiro Tsujikawa
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 * In addition, as a special exception, the copyright holders give
22 * permission to link the code of portions of this program with the
23 * OpenSSL library under certain conditions as described in each
24 * individual source file, and distribute linked combinations
25 * including the two.
26 * You must obey the GNU General Public License in all respects
27 * for all of the code used other than OpenSSL. If you modify
28 * file(s) with this exception, you may extend this exception to your
29 * version of the file(s), but you are not obligated to do so. If you
30 * do not wish to do so, delete this exception statement from your
31 * version. If you delete this exception statement from all source
32 * files in the program, then also delete it here.
33 */
34 /* copyright --> */
35 #include "OptionHandlerImpl.h"
36
37 #include <cassert>
38 #include <cstdio>
39 #include <cstring>
40 #include <utility>
41 #include <algorithm>
42 #include <numeric>
43 #include <sstream>
44 #include <iterator>
45 #include <vector>
46 #include <stdexcept>
47
48 #include "util.h"
49 #include "DlAbortEx.h"
50 #include "prefs.h"
51 #include "Option.h"
52 #include "fmt.h"
53 #include "A2STR.h"
54 #include "Request.h"
55 #include "a2functional.h"
56 #include "message.h"
57 #include "File.h"
58 #include "FileEntry.h"
59 #include "a2io.h"
60 #include "LogFactory.h"
61 #include "uri.h"
62 #include "SegList.h"
63 #include "array_fun.h"
64 #include "help_tags.h"
65 #include "MessageDigest.h"
66
67 namespace aria2 {
68
BooleanOptionHandler(PrefPtr pref,const char * description,const std::string & defaultValue,OptionHandler::ARG_TYPE argType,char shortName)69 BooleanOptionHandler::BooleanOptionHandler(PrefPtr pref,
70 const char* description,
71 const std::string& defaultValue,
72 OptionHandler::ARG_TYPE argType,
73 char shortName)
74 : AbstractOptionHandler(pref, description, defaultValue, argType, shortName)
75 {
76 }
77
78 BooleanOptionHandler::~BooleanOptionHandler() = default;
79
parseArg(Option & option,const std::string & optarg) const80 void BooleanOptionHandler::parseArg(Option& option,
81 const std::string& optarg) const
82 {
83 if (optarg == "true" || ((argType_ == OptionHandler::OPT_ARG ||
84 argType_ == OptionHandler::NO_ARG) &&
85 optarg.empty())) {
86 option.put(pref_, A2_V_TRUE);
87 }
88 else if (optarg == "false") {
89 option.put(pref_, A2_V_FALSE);
90 }
91 else {
92 std::string msg = pref_->k;
93 msg += " ";
94 msg += _("must be either 'true' or 'false'.");
95 throw DL_ABORT_EX(msg);
96 }
97 }
98
createPossibleValuesString() const99 std::string BooleanOptionHandler::createPossibleValuesString() const
100 {
101 return "true, false";
102 }
103
IntegerRangeOptionHandler(PrefPtr pref,const char * description,const std::string & defaultValue,int32_t min,int32_t max,char shortName)104 IntegerRangeOptionHandler::IntegerRangeOptionHandler(
105 PrefPtr pref, const char* description, const std::string& defaultValue,
106 int32_t min, int32_t max, char shortName)
107 : AbstractOptionHandler(pref, description, defaultValue,
108 OptionHandler::REQ_ARG, shortName),
109 min_(min),
110 max_(max)
111 {
112 }
113
114 IntegerRangeOptionHandler::~IntegerRangeOptionHandler() = default;
115
parseArg(Option & option,const std::string & optarg) const116 void IntegerRangeOptionHandler::parseArg(Option& option,
117 const std::string& optarg) const
118 {
119 auto sgl = util::parseIntSegments(optarg);
120 sgl.normalize();
121 while (sgl.hasNext()) {
122 int v = sgl.next();
123 if (v < min_ || max_ < v) {
124 std::string msg = pref_->k;
125 msg += " ";
126 msg += _("must be between %d and %d.");
127 throw DL_ABORT_EX(fmt(msg.c_str(), min_, max_));
128 }
129 option.put(pref_, optarg);
130 }
131 }
132
createPossibleValuesString() const133 std::string IntegerRangeOptionHandler::createPossibleValuesString() const
134 {
135 return fmt("%d-%d", min_, max_);
136 }
137
NumberOptionHandler(PrefPtr pref,const char * description,const std::string & defaultValue,int64_t min,int64_t max,char shortName)138 NumberOptionHandler::NumberOptionHandler(PrefPtr pref, const char* description,
139 const std::string& defaultValue,
140 int64_t min, int64_t max,
141 char shortName)
142 : AbstractOptionHandler(pref, description, defaultValue,
143 OptionHandler::REQ_ARG, shortName),
144 min_(min),
145 max_(max)
146 {
147 }
148
149 NumberOptionHandler::~NumberOptionHandler() = default;
150
parseArg(Option & option,const std::string & optarg) const151 void NumberOptionHandler::parseArg(Option& option,
152 const std::string& optarg) const
153 {
154 int64_t number;
155 if (util::parseLLIntNoThrow(number, optarg)) {
156 parseArg(option, number);
157 }
158 else {
159 throw DL_ABORT_EX(fmt("Bad number %s", optarg.c_str()));
160 }
161 }
162
parseArg(Option & option,int64_t number) const163 void NumberOptionHandler::parseArg(Option& option, int64_t number) const
164 {
165 if ((min_ == -1 || min_ <= number) && (max_ == -1 || number <= max_)) {
166 option.put(pref_, util::itos(number));
167 return;
168 }
169
170 std::string msg = pref_->k;
171 msg += " ";
172 if (min_ == -1 && max_ != -1) {
173 msg += fmt(_("must be smaller than or equal to %" PRId64 "."), max_);
174 }
175 else if (min_ != -1 && max_ != -1) {
176 msg += fmt(_("must be between %" PRId64 " and %" PRId64 "."), min_, max_);
177 }
178 else if (min_ != -1 && max_ == -1) {
179 msg += fmt(_("must be greater than or equal to %" PRId64 "."), min_);
180 }
181 else {
182 msg += _("must be a number.");
183 }
184 throw DL_ABORT_EX(msg);
185 }
186
createPossibleValuesString() const187 std::string NumberOptionHandler::createPossibleValuesString() const
188 {
189 std::string values;
190 if (min_ == -1) {
191 values += "*";
192 }
193 else {
194 values += util::itos(min_);
195 }
196 values += "-";
197 if (max_ == -1) {
198 values += "*";
199 }
200 else {
201 values += util::itos(max_);
202 }
203 return values;
204 }
205
UnitNumberOptionHandler(PrefPtr pref,const char * description,const std::string & defaultValue,int64_t min,int64_t max,char shortName)206 UnitNumberOptionHandler::UnitNumberOptionHandler(
207 PrefPtr pref, const char* description, const std::string& defaultValue,
208 int64_t min, int64_t max, char shortName)
209 : NumberOptionHandler(pref, description, defaultValue, min, max, shortName)
210 {
211 }
212
213 UnitNumberOptionHandler::~UnitNumberOptionHandler() = default;
214
parseArg(Option & option,const std::string & optarg) const215 void UnitNumberOptionHandler::parseArg(Option& option,
216 const std::string& optarg) const
217 {
218 int64_t num = util::getRealSize(optarg);
219 NumberOptionHandler::parseArg(option, num);
220 }
221
FloatNumberOptionHandler(PrefPtr pref,const char * description,const std::string & defaultValue,double min,double max,char shortName)222 FloatNumberOptionHandler::FloatNumberOptionHandler(
223 PrefPtr pref, const char* description, const std::string& defaultValue,
224 double min, double max, char shortName)
225 : AbstractOptionHandler(pref, description, defaultValue,
226 OptionHandler::REQ_ARG, shortName),
227 min_(min),
228 max_(max)
229 {
230 }
231
232 FloatNumberOptionHandler::~FloatNumberOptionHandler() = default;
233
parseArg(Option & option,const std::string & optarg) const234 void FloatNumberOptionHandler::parseArg(Option& option,
235 const std::string& optarg) const
236 {
237 double number = strtod(optarg.c_str(), nullptr);
238 if ((min_ < 0 || min_ <= number) && (max_ < 0 || number <= max_)) {
239 option.put(pref_, optarg);
240 }
241 else {
242 std::string msg = pref_->k;
243 msg += " ";
244 if (min_ < 0 && max_ >= 0) {
245 msg += fmt(_("must be smaller than or equal to %.1f."), max_);
246 }
247 else if (min_ >= 0 && max_ >= 0) {
248 msg += fmt(_("must be between %.1f and %.1f."), min_, max_);
249 }
250 else if (min_ >= 0 && max_ < 0) {
251 msg += fmt(_("must be greater than or equal to %.1f."), min_);
252 }
253 else {
254 msg += _("must be a number.");
255 }
256 throw DL_ABORT_EX(msg);
257 }
258 }
259
createPossibleValuesString() const260 std::string FloatNumberOptionHandler::createPossibleValuesString() const
261 {
262 std::string valuesString;
263 if (min_ < 0) {
264 valuesString += "*";
265 }
266 else {
267 valuesString += fmt("%.1f", min_);
268 }
269 valuesString += "-";
270 if (max_ < 0) {
271 valuesString += "*";
272 }
273 else {
274 valuesString += fmt("%.1f", max_);
275 }
276 return valuesString;
277 }
278
DefaultOptionHandler(PrefPtr pref,const char * description,const std::string & defaultValue,const std::string & possibleValuesString,OptionHandler::ARG_TYPE argType,char shortName)279 DefaultOptionHandler::DefaultOptionHandler(
280 PrefPtr pref, const char* description, const std::string& defaultValue,
281 const std::string& possibleValuesString, OptionHandler::ARG_TYPE argType,
282 char shortName)
283 : AbstractOptionHandler(pref, description, defaultValue, argType,
284 shortName),
285 possibleValuesString_(possibleValuesString),
286 allowEmpty_(true)
287 {
288 }
289
290 DefaultOptionHandler::~DefaultOptionHandler() = default;
291
parseArg(Option & option,const std::string & optarg) const292 void DefaultOptionHandler::parseArg(Option& option,
293 const std::string& optarg) const
294 {
295 if (!allowEmpty_ && optarg.empty()) {
296 throw DL_ABORT_EX("Empty string is not allowed");
297 }
298 option.put(pref_, optarg);
299 }
300
createPossibleValuesString() const301 std::string DefaultOptionHandler::createPossibleValuesString() const
302 {
303 return possibleValuesString_;
304 }
305
setAllowEmpty(bool allow)306 void DefaultOptionHandler::setAllowEmpty(bool allow) { allowEmpty_ = allow; }
307
CumulativeOptionHandler(PrefPtr pref,const char * description,const std::string & defaultValue,const std::string & delim,const std::string & possibleValuesString,OptionHandler::ARG_TYPE argType,char shortName)308 CumulativeOptionHandler::CumulativeOptionHandler(
309 PrefPtr pref, const char* description, const std::string& defaultValue,
310 const std::string& delim, const std::string& possibleValuesString,
311 OptionHandler::ARG_TYPE argType, char shortName)
312 : AbstractOptionHandler(pref, description, defaultValue, argType,
313 shortName),
314 delim_(delim),
315 possibleValuesString_(possibleValuesString)
316 {
317 }
318
319 CumulativeOptionHandler::~CumulativeOptionHandler() = default;
320
parseArg(Option & option,const std::string & optarg) const321 void CumulativeOptionHandler::parseArg(Option& option,
322 const std::string& optarg) const
323 {
324 std::string value = option.get(pref_);
325 value += optarg;
326 value += delim_;
327 option.put(pref_, value);
328 }
329
createPossibleValuesString() const330 std::string CumulativeOptionHandler::createPossibleValuesString() const
331 {
332 return possibleValuesString_;
333 }
334
IndexOutOptionHandler(PrefPtr pref,const char * description,char shortName)335 IndexOutOptionHandler::IndexOutOptionHandler(PrefPtr pref,
336 const char* description,
337 char shortName)
338 : AbstractOptionHandler(pref, description, NO_DEFAULT_VALUE,
339 OptionHandler::REQ_ARG, shortName)
340 {
341 }
342
343 IndexOutOptionHandler::~IndexOutOptionHandler() = default;
344
parseArg(Option & option,const std::string & optarg) const345 void IndexOutOptionHandler::parseArg(Option& option,
346 const std::string& optarg) const
347 {
348 // See optarg is in the format of "INDEX=PATH"
349 util::parseIndexPath(optarg);
350 std::string value = option.get(pref_);
351 value += optarg;
352 value += "\n";
353 option.put(pref_, value);
354 }
355
createPossibleValuesString() const356 std::string IndexOutOptionHandler::createPossibleValuesString() const
357 {
358 return "INDEX=PATH";
359 }
360
ChecksumOptionHandler(PrefPtr pref,const char * description,char shortName)361 ChecksumOptionHandler::ChecksumOptionHandler(PrefPtr pref,
362 const char* description,
363 char shortName)
364 : AbstractOptionHandler(pref, description, NO_DEFAULT_VALUE,
365 OptionHandler::REQ_ARG, shortName)
366 {
367 }
368
ChecksumOptionHandler(PrefPtr pref,const char * description,std::vector<std::string> acceptableTypes,char shortName)369 ChecksumOptionHandler::ChecksumOptionHandler(
370 PrefPtr pref, const char* description,
371 std::vector<std::string> acceptableTypes, char shortName)
372 : AbstractOptionHandler(pref, description, NO_DEFAULT_VALUE,
373 OptionHandler::REQ_ARG, shortName),
374 acceptableTypes_(std::move(acceptableTypes))
375 {
376 }
377
378 ChecksumOptionHandler::~ChecksumOptionHandler() = default;
379
parseArg(Option & option,const std::string & optarg) const380 void ChecksumOptionHandler::parseArg(Option& option,
381 const std::string& optarg) const
382 {
383 auto p = util::divide(std::begin(optarg), std::end(optarg), '=');
384 std::string hashType(p.first.first, p.first.second);
385 if (!acceptableTypes_.empty() &&
386 std::find(std::begin(acceptableTypes_), std::end(acceptableTypes_),
387 hashType) == std::end(acceptableTypes_)) {
388 throw DL_ABORT_EX(
389 fmt("Checksum type %s is not acceptable", hashType.c_str()));
390 }
391 std::string hexDigest(p.second.first, p.second.second);
392 util::lowercase(hashType);
393 util::lowercase(hexDigest);
394 if (!MessageDigest::isValidHash(hashType, hexDigest)) {
395 throw DL_ABORT_EX(_("Unrecognized checksum"));
396 }
397 option.put(pref_, optarg);
398 }
399
createPossibleValuesString() const400 std::string ChecksumOptionHandler::createPossibleValuesString() const
401 {
402 return "HASH_TYPE=HEX_DIGEST";
403 }
404
ParameterOptionHandler(PrefPtr pref,const char * description,const std::string & defaultValue,std::vector<std::string> validParamValues,char shortName)405 ParameterOptionHandler::ParameterOptionHandler(
406 PrefPtr pref, const char* description, const std::string& defaultValue,
407 std::vector<std::string> validParamValues, char shortName)
408 : AbstractOptionHandler(pref, description, defaultValue,
409 OptionHandler::REQ_ARG, shortName),
410 validParamValues_(std::move(validParamValues))
411 {
412 }
413
414 ParameterOptionHandler::~ParameterOptionHandler() = default;
415
parseArg(Option & option,const std::string & optarg) const416 void ParameterOptionHandler::parseArg(Option& option,
417 const std::string& optarg) const
418 {
419 auto itr =
420 std::find(validParamValues_.begin(), validParamValues_.end(), optarg);
421 if (itr == validParamValues_.end()) {
422 std::string msg = pref_->k;
423 msg += " ";
424 msg += _("must be one of the following:");
425 if (validParamValues_.size() == 0) {
426 msg += "''";
427 }
428 else {
429 for (const auto& p : validParamValues_) {
430 msg += "'";
431 msg += p;
432 msg += "' ";
433 }
434 }
435 throw DL_ABORT_EX(msg);
436 }
437 else {
438 option.put(pref_, optarg);
439 }
440 }
441
createPossibleValuesString() const442 std::string ParameterOptionHandler::createPossibleValuesString() const
443 {
444 std::stringstream s;
445 std::copy(validParamValues_.begin(), validParamValues_.end(),
446 std::ostream_iterator<std::string>(s, ", "));
447 return util::strip(s.str(), ", ");
448 }
449
HostPortOptionHandler(PrefPtr pref,const char * description,const std::string & defaultValue,PrefPtr hostOptionName,PrefPtr portOptionName,char shortName)450 HostPortOptionHandler::HostPortOptionHandler(
451 PrefPtr pref, const char* description, const std::string& defaultValue,
452 PrefPtr hostOptionName, PrefPtr portOptionName, char shortName)
453 : AbstractOptionHandler(pref, description, defaultValue,
454 OptionHandler::REQ_ARG, shortName),
455 hostOptionName_(hostOptionName),
456 portOptionName_(portOptionName)
457 {
458 }
459
460 HostPortOptionHandler::~HostPortOptionHandler() = default;
461
parseArg(Option & option,const std::string & optarg) const462 void HostPortOptionHandler::parseArg(Option& option,
463 const std::string& optarg) const
464 {
465 std::string uri = "http://";
466 uri += optarg;
467 Request req;
468 if (!req.setUri(uri)) {
469 throw DL_ABORT_EX(_("Unrecognized format"));
470 }
471 option.put(pref_, optarg);
472 setHostAndPort(option, req.getHost(), req.getPort());
473 }
474
setHostAndPort(Option & option,const std::string & hostname,uint16_t port) const475 void HostPortOptionHandler::setHostAndPort(Option& option,
476 const std::string& hostname,
477 uint16_t port) const
478 {
479 option.put(hostOptionName_, hostname);
480 option.put(portOptionName_, util::uitos(port));
481 }
482
createPossibleValuesString() const483 std::string HostPortOptionHandler::createPossibleValuesString() const
484 {
485 return "HOST:PORT";
486 }
487
HttpProxyOptionHandler(PrefPtr pref,const char * description,const std::string & defaultValue,char shortName)488 HttpProxyOptionHandler::HttpProxyOptionHandler(PrefPtr pref,
489 const char* description,
490 const std::string& defaultValue,
491 char shortName)
492 : AbstractOptionHandler(pref, description, defaultValue,
493 OptionHandler::REQ_ARG, shortName),
494 proxyUserPref_(option::k2p(std::string(pref->k) + "-user")),
495 proxyPasswdPref_(option::k2p(std::string(pref->k) + "-passwd"))
496 {
497 }
498
499 HttpProxyOptionHandler::~HttpProxyOptionHandler() = default;
500
parseArg(Option & option,const std::string & optarg) const501 void HttpProxyOptionHandler::parseArg(Option& option,
502 const std::string& optarg) const
503 {
504 if (optarg.empty()) {
505 option.put(pref_, optarg);
506 }
507 else {
508 std::string uri;
509 if (util::startsWith(optarg, "http://") ||
510 util::startsWith(optarg, "https://") ||
511 util::startsWith(optarg, "ftp://")) {
512 uri = optarg;
513 }
514 else {
515 uri = "http://";
516 uri += optarg;
517 }
518 uri::UriStruct us;
519 if (!uri::parse(us, uri)) {
520 throw DL_ABORT_EX(_("unrecognized proxy format"));
521 }
522 us.protocol = "http";
523 option.put(pref_, uri::construct(us));
524 }
525 }
526
createPossibleValuesString() const527 std::string HttpProxyOptionHandler::createPossibleValuesString() const
528 {
529 return "[http://][USER:PASSWORD@]HOST[:PORT]";
530 }
531
LocalFilePathOptionHandler(PrefPtr pref,const char * description,const std::string & defaultValue,bool acceptStdin,char shortName,bool mustExist,const std::string & possibleValuesString)532 LocalFilePathOptionHandler::LocalFilePathOptionHandler(
533 PrefPtr pref, const char* description, const std::string& defaultValue,
534 bool acceptStdin, char shortName, bool mustExist,
535 const std::string& possibleValuesString)
536 : AbstractOptionHandler(pref, description, defaultValue,
537 OptionHandler::REQ_ARG, shortName),
538 possibleValuesString_(possibleValuesString),
539 acceptStdin_(acceptStdin),
540 mustExist_(mustExist)
541 {
542 }
543
parseArg(Option & option,const std::string & optarg) const544 void LocalFilePathOptionHandler::parseArg(Option& option,
545 const std::string& optarg) const
546 {
547 if (acceptStdin_ && optarg == "-") {
548 option.put(pref_, DEV_STDIN);
549 }
550 else {
551 auto path = util::replace(optarg, "${HOME}", util::getHomeDir());
552 if (mustExist_) {
553 File f(path);
554 std::string err;
555 if (!f.exists(err)) {
556 throw DL_ABORT_EX(err);
557 }
558 if (f.isDir()) {
559 throw DL_ABORT_EX(fmt(MSG_NOT_FILE, optarg.c_str()));
560 }
561 }
562 option.put(pref_, path);
563 }
564 }
565
createPossibleValuesString() const566 std::string LocalFilePathOptionHandler::createPossibleValuesString() const
567 {
568 if (!possibleValuesString_.empty()) {
569 return possibleValuesString_;
570 }
571 if (acceptStdin_) {
572 return PATH_TO_FILE_STDIN;
573 }
574 else {
575 return PATH_TO_FILE;
576 }
577 }
578
PrioritizePieceOptionHandler(PrefPtr pref,const char * description,const std::string & defaultValue,char shortName)579 PrioritizePieceOptionHandler::PrioritizePieceOptionHandler(
580 PrefPtr pref, const char* description, const std::string& defaultValue,
581 char shortName)
582 : AbstractOptionHandler(pref, description, defaultValue,
583 OptionHandler::REQ_ARG, shortName)
584 {
585 }
586
parseArg(Option & option,const std::string & optarg) const587 void PrioritizePieceOptionHandler::parseArg(Option& option,
588 const std::string& optarg) const
589 {
590 // Parse optarg against empty FileEntry list to detect syntax
591 // error.
592 std::vector<size_t> result;
593 util::parsePrioritizePieceRange(
594 result, optarg, std::vector<std::shared_ptr<FileEntry>>(), 1024);
595 option.put(pref_, optarg);
596 }
597
createPossibleValuesString() const598 std::string PrioritizePieceOptionHandler::createPossibleValuesString() const
599 {
600 return "head[=SIZE], tail[=SIZE]";
601 }
602
603 OptimizeConcurrentDownloadsOptionHandler::
OptimizeConcurrentDownloadsOptionHandler(PrefPtr pref,const char * description,const std::string & defaultValue,char shortName)604 OptimizeConcurrentDownloadsOptionHandler(PrefPtr pref,
605 const char* description,
606 const std::string& defaultValue,
607 char shortName)
608 : AbstractOptionHandler(pref, description, defaultValue,
609 OptionHandler::OPT_ARG, shortName)
610 {
611 }
612
parseArg(Option & option,const std::string & optarg) const613 void OptimizeConcurrentDownloadsOptionHandler::parseArg(
614 Option& option, const std::string& optarg) const
615 {
616 if (optarg == "true" || optarg.empty()) {
617 option.put(pref_, A2_V_TRUE);
618 }
619 else if (optarg == "false") {
620 option.put(pref_, A2_V_FALSE);
621 }
622 else {
623 auto p = util::divide(std::begin(optarg), std::end(optarg), ':');
624
625 std::string coeff_b(p.second.first, p.second.second);
626 if (coeff_b.empty()) {
627 std::string msg = pref_->k;
628 msg += " ";
629 msg += _("must be either 'true', 'false' or a pair numeric coefficients "
630 "A and B under the form 'A:B'.");
631 throw DL_ABORT_EX(msg);
632 }
633
634 std::string coeff_a(p.first.first, p.first.second);
635
636 PrefPtr pref = PREF_OPTIMIZE_CONCURRENT_DOWNLOADS_COEFFA;
637 std::string* sptr = &coeff_a;
638 for (;;) {
639 char* end;
640 errno = 0;
641 strtod(sptr->c_str(), &end);
642 if (errno != 0 || sptr->c_str() + sptr->size() != end) {
643 throw DL_ABORT_EX(fmt("Bad number '%s'", sptr->c_str()));
644 }
645 option.put(pref, *sptr);
646
647 if (pref == PREF_OPTIMIZE_CONCURRENT_DOWNLOADS_COEFFB) {
648 break;
649 }
650 pref = PREF_OPTIMIZE_CONCURRENT_DOWNLOADS_COEFFB;
651 sptr = &coeff_b;
652 }
653 option.put(pref_, A2_V_TRUE);
654 }
655 }
656
657 std::string
createPossibleValuesString() const658 OptimizeConcurrentDownloadsOptionHandler::createPossibleValuesString() const
659 {
660 return "true, false, A:B";
661 }
662
DeprecatedOptionHandler(OptionHandler * depOptHandler,const OptionHandler * repOptHandler,bool stillWork,std::string additionalMessage)663 DeprecatedOptionHandler::DeprecatedOptionHandler(
664 OptionHandler* depOptHandler, const OptionHandler* repOptHandler,
665 bool stillWork, std::string additionalMessage)
666 : depOptHandler_(depOptHandler),
667 repOptHandler_(repOptHandler),
668 stillWork_(stillWork),
669 additionalMessage_(std::move(additionalMessage))
670 {
671 depOptHandler_->addTag(TAG_DEPRECATED);
672 }
673
~DeprecatedOptionHandler()674 DeprecatedOptionHandler::~DeprecatedOptionHandler()
675 {
676 delete depOptHandler_;
677 // We don't delete repOptHandler_.
678 }
679
parse(Option & option,const std::string & arg) const680 void DeprecatedOptionHandler::parse(Option& option,
681 const std::string& arg) const
682 {
683 if (repOptHandler_) {
684 A2_LOG_WARN(fmt(_("--%s option is deprecated. Use --%s option instead. %s"),
685 depOptHandler_->getName(), repOptHandler_->getName(),
686 additionalMessage_.c_str()));
687 repOptHandler_->parse(option, arg);
688 }
689 else if (stillWork_) {
690 A2_LOG_WARN(fmt(_("--%s option will be deprecated in the future release. "
691 "%s"),
692 depOptHandler_->getName(), additionalMessage_.c_str()));
693 depOptHandler_->parse(option, arg);
694 }
695 else {
696 A2_LOG_WARN(fmt(_("--%s option is deprecated. %s"),
697 depOptHandler_->getName(), additionalMessage_.c_str()));
698 }
699 }
700
createPossibleValuesString() const701 std::string DeprecatedOptionHandler::createPossibleValuesString() const
702 {
703 return depOptHandler_->createPossibleValuesString();
704 }
705
hasTag(uint32_t tag) const706 bool DeprecatedOptionHandler::hasTag(uint32_t tag) const
707 {
708 return depOptHandler_->hasTag(tag);
709 }
710
addTag(uint32_t tag)711 void DeprecatedOptionHandler::addTag(uint32_t tag)
712 {
713 depOptHandler_->addTag(tag);
714 }
715
toTagString() const716 std::string DeprecatedOptionHandler::toTagString() const
717 {
718 return depOptHandler_->toTagString();
719 }
720
getName() const721 const char* DeprecatedOptionHandler::getName() const
722 {
723 return depOptHandler_->getName();
724 }
725
getDescription() const726 const char* DeprecatedOptionHandler::getDescription() const
727 {
728 return depOptHandler_->getDescription();
729 }
730
getDefaultValue() const731 const std::string& DeprecatedOptionHandler::getDefaultValue() const
732 {
733 return depOptHandler_->getDefaultValue();
734 }
735
isHidden() const736 bool DeprecatedOptionHandler::isHidden() const
737 {
738 return depOptHandler_->isHidden();
739 }
740
hide()741 void DeprecatedOptionHandler::hide() { depOptHandler_->hide(); }
742
getPref() const743 PrefPtr DeprecatedOptionHandler::getPref() const
744 {
745 return depOptHandler_->getPref();
746 }
747
getArgType() const748 OptionHandler::ARG_TYPE DeprecatedOptionHandler::getArgType() const
749 {
750 return depOptHandler_->getArgType();
751 }
752
getShortName() const753 char DeprecatedOptionHandler::getShortName() const
754 {
755 return depOptHandler_->getShortName();
756 }
757
getEraseAfterParse() const758 bool DeprecatedOptionHandler::getEraseAfterParse() const
759 {
760 return depOptHandler_->getEraseAfterParse();
761 }
762
setEraseAfterParse(bool eraseAfterParse)763 void DeprecatedOptionHandler::setEraseAfterParse(bool eraseAfterParse)
764 {
765 depOptHandler_->setEraseAfterParse(eraseAfterParse);
766 }
767
getInitialOption() const768 bool DeprecatedOptionHandler::getInitialOption() const
769 {
770 return depOptHandler_->getInitialOption();
771 }
772
setInitialOption(bool f)773 void DeprecatedOptionHandler::setInitialOption(bool f)
774 {
775 depOptHandler_->setInitialOption(f);
776 }
777
getChangeOption() const778 bool DeprecatedOptionHandler::getChangeOption() const
779 {
780 return depOptHandler_->getChangeOption();
781 }
782
setChangeOption(bool f)783 void DeprecatedOptionHandler::setChangeOption(bool f)
784 {
785 depOptHandler_->setChangeOption(f);
786 }
787
getChangeOptionForReserved() const788 bool DeprecatedOptionHandler::getChangeOptionForReserved() const
789 {
790 return depOptHandler_->getChangeOptionForReserved();
791 }
792
setChangeOptionForReserved(bool f)793 void DeprecatedOptionHandler::setChangeOptionForReserved(bool f)
794 {
795 depOptHandler_->setChangeOptionForReserved(f);
796 }
797
getChangeGlobalOption() const798 bool DeprecatedOptionHandler::getChangeGlobalOption() const
799 {
800 return depOptHandler_->getChangeGlobalOption();
801 }
802
setChangeGlobalOption(bool f)803 void DeprecatedOptionHandler::setChangeGlobalOption(bool f)
804 {
805 depOptHandler_->setChangeGlobalOption(f);
806 }
807
getCumulative() const808 bool DeprecatedOptionHandler::getCumulative() const
809 {
810 return depOptHandler_->getCumulative();
811 }
812
setCumulative(bool f)813 void DeprecatedOptionHandler::setCumulative(bool f)
814 {
815 depOptHandler_->setCumulative(f);
816 }
817
818 } // namespace aria2
819