Commit 628dc9202b4a0f0d8eb1fae357a452d85278a73b

Authored by Eyal Rozenberg
Committed by GitHub
1 parent 548d6196

Fixes #345, fixes #346: Exception code tweaks (#347)

* Fixes #345, fixes #346, regards #340: Put exceptions in a sub-namespace and renamed them accordingly.

* Also fixed some "loose ends" regarding namespace indentation which were missing in PR #350.

* Dropped `required_option_missing` as it is unused.
README.md
... ... @@ -109,9 +109,9 @@ result.unmatched()
109 109  
110 110 Exceptional situations throw C++ exceptions. There are two types of
111 111 exceptions: errors defining the options, and errors when parsing a list of
112   -arguments. All exceptions derive from `cxxopts::OptionException`. Errors
113   -defining options derive from `cxxopts::OptionSpecException` and errors
114   -parsing arguments derive from `cxxopts::OptionParseException`.
  112 +arguments. All exceptions derive from `cxxopts::exceptions::exception`. Errors
  113 +defining options derive from `cxxopts::exceptions::specification` and errors
  114 +parsing arguments derive from `cxxopts::exceptions::parsing`.
115 115  
116 116 All exceptions define a `what()` function to get a printable string
117 117 explaining the error.
... ...
include/cxxopts.hpp
... ... @@ -227,6 +227,7 @@ empty(const String& s)
227 227 } // namespace cxxopts
228 228  
229 229 namespace std {
  230 +
230 231 inline
231 232 cxxopts::UnicodeStringIterator
232 233 begin(const icu::UnicodeString& s)
... ... @@ -304,6 +305,7 @@ empty(const std::string& s)
304 305 #endif
305 306  
306 307 namespace cxxopts {
  308 +
307 309 namespace {
308 310 #ifdef _WIN32
309 311 const std::string LQUOTE("\'");
... ... @@ -368,164 +370,155 @@ class Value : public std::enable_shared_from_this<Value>
368 370 #if defined(__GNUC__)
369 371 #pragma GCC diagnostic pop
370 372 #endif
371   -class OptionException : public std::exception
372   -{
373   - public:
374   - explicit OptionException(std::string message)
375   - : m_message(std::move(message))
376   - {
377   - }
378   -
379   - CXXOPTS_NODISCARD
380   - const char*
381   - what() const noexcept override
  373 +namespace exceptions {
  374 + class exception : public std::exception
382 375 {
383   - return m_message.c_str();
384   - }
  376 + public:
  377 + explicit exception(std::string message)
  378 + : m_message(std::move(message))
  379 + {
  380 + }
385 381  
386   - private:
387   - std::string m_message;
388   -};
  382 + CXXOPTS_NODISCARD
  383 + const char*
  384 + what() const noexcept override
  385 + {
  386 + return m_message.c_str();
  387 + }
389 388  
390   -class OptionSpecException : public OptionException
391   -{
392   - public:
  389 + private:
  390 + std::string m_message;
  391 + };
393 392  
394   - explicit OptionSpecException(const std::string& message)
395   - : OptionException(message)
  393 + class specification : public exception
396 394 {
397   - }
398   -};
  395 + public:
399 396  
400   -class OptionParseException : public OptionException
401   -{
402   - public:
403   - explicit OptionParseException(const std::string& message)
404   - : OptionException(message)
405   - {
406   - }
407   -};
  397 + explicit specification(const std::string& message)
  398 + : exception(message)
  399 + {
  400 + }
  401 + };
408 402  
409   -class option_exists_error : public OptionSpecException
410   -{
411   - public:
412   - explicit option_exists_error(const std::string& option)
413   - : OptionSpecException("Option " + LQUOTE + option + RQUOTE + " already exists")
  403 + class parsing : public exception
414 404 {
415   - }
416   -};
  405 + public:
  406 + explicit parsing(const std::string& message)
  407 + : exception(message)
  408 + {
  409 + }
  410 + };
417 411  
418   -class invalid_option_format_error : public OptionSpecException
419   -{
420   - public:
421   - explicit invalid_option_format_error(const std::string& format)
422   - : OptionSpecException("Invalid option format " + LQUOTE + format + RQUOTE)
  412 + class option_already_exists : public specification
423 413 {
424   - }
425   -};
  414 + public:
  415 + explicit option_already_exists(const std::string& option)
  416 + : specification("Option " + LQUOTE + option + RQUOTE + " already exists")
  417 + {
  418 + }
  419 + };
426 420  
427   -class option_syntax_exception : public OptionParseException {
428   - public:
429   - explicit option_syntax_exception(const std::string& text)
430   - : OptionParseException("Argument " + LQUOTE + text + RQUOTE +
431   - " starts with a - but has incorrect syntax")
  421 + class invalid_option_format : public specification
432 422 {
433   - }
434   -};
  423 + public:
  424 + explicit invalid_option_format(const std::string& format)
  425 + : specification("Invalid option format " + LQUOTE + format + RQUOTE)
  426 + {
  427 + }
  428 + };
435 429  
436   -class option_not_exists_exception : public OptionParseException
437   -{
438   - public:
439   - explicit option_not_exists_exception(const std::string& option)
440   - : OptionParseException("Option " + LQUOTE + option + RQUOTE + " does not exist")
441   - {
442   - }
443   -};
  430 + class invalid_option_syntax : public parsing {
  431 + public:
  432 + explicit invalid_option_syntax(const std::string& text)
  433 + : parsing("Argument " + LQUOTE + text + RQUOTE +
  434 + " starts with a - but has incorrect syntax")
  435 + {
  436 + }
  437 + };
444 438  
445   -class missing_argument_exception : public OptionParseException
446   -{
447   - public:
448   - explicit missing_argument_exception(const std::string& option)
449   - : OptionParseException(
450   - "Option " + LQUOTE + option + RQUOTE + " is missing an argument"
451   - )
  439 + class no_such_option : public parsing
452 440 {
453   - }
454   -};
  441 + public:
  442 + explicit no_such_option(const std::string& option)
  443 + : parsing("Option " + LQUOTE + option + RQUOTE + " does not exist")
  444 + {
  445 + }
  446 + };
455 447  
456   -class option_requires_argument_exception : public OptionParseException
457   -{
458   - public:
459   - explicit option_requires_argument_exception(const std::string& option)
460   - : OptionParseException(
461   - "Option " + LQUOTE + option + RQUOTE + " requires an argument"
462   - )
  448 + class missing_argument : public parsing
463 449 {
464   - }
465   -};
  450 + public:
  451 + explicit missing_argument(const std::string& option)
  452 + : parsing(
  453 + "Option " + LQUOTE + option + RQUOTE + " is missing an argument"
  454 + )
  455 + {
  456 + }
  457 + };
466 458  
467   -class option_not_has_argument_exception : public OptionParseException
468   -{
469   - public:
470   - option_not_has_argument_exception
471   - (
472   - const std::string& option,
473   - const std::string& arg
474   - )
475   - : OptionParseException(
476   - "Option " + LQUOTE + option + RQUOTE +
477   - " does not take an argument, but argument " +
478   - LQUOTE + arg + RQUOTE + " given"
479   - )
  459 + class option_requires_argument : public parsing
480 460 {
481   - }
482   -};
  461 + public:
  462 + explicit option_requires_argument(const std::string& option)
  463 + : parsing(
  464 + "Option " + LQUOTE + option + RQUOTE + " requires an argument"
  465 + )
  466 + {
  467 + }
  468 + };
483 469  
484   -class option_not_present_exception : public OptionParseException
485   -{
486   - public:
487   - explicit option_not_present_exception(const std::string& option)
488   - : OptionParseException("Option " + LQUOTE + option + RQUOTE + " not present")
  470 + class gratuitous_argument_for_option : public parsing
489 471 {
490   - }
491   -};
  472 + public:
  473 + gratuitous_argument_for_option
  474 + (
  475 + const std::string& option,
  476 + const std::string& arg
  477 + )
  478 + : parsing(
  479 + "Option " + LQUOTE + option + RQUOTE +
  480 + " does not take an argument, but argument " +
  481 + LQUOTE + arg + RQUOTE + " given"
  482 + )
  483 + {
  484 + }
  485 + };
492 486  
493   -class option_has_no_value_exception : public OptionException
494   -{
495   - public:
496   - explicit option_has_no_value_exception(const std::string& option)
497   - : OptionException(
498   - !option.empty() ?
499   - ("Option " + LQUOTE + option + RQUOTE + " has no value") :
500   - "Option has no value")
  487 + class requested_option_not_present : public parsing
501 488 {
502   - }
503   -};
  489 + public:
  490 + explicit requested_option_not_present(const std::string& option)
  491 + : parsing("Option " + LQUOTE + option + RQUOTE + " not present")
  492 + {
  493 + }
  494 + };
504 495  
505   -class argument_incorrect_type : public OptionParseException
506   -{
507   - public:
508   - explicit argument_incorrect_type
509   - (
510   - const std::string& arg
511   - )
512   - : OptionParseException(
513   - "Argument " + LQUOTE + arg + RQUOTE + " failed to parse"
514   - )
  496 + class option_has_no_value : public exception
515 497 {
516   - }
517   -};
  498 + public:
  499 + explicit option_has_no_value(const std::string& option)
  500 + : exception(
  501 + !option.empty() ?
  502 + ("Option " + LQUOTE + option + RQUOTE + " has no value") :
  503 + "Option has no value")
  504 + {
  505 + }
  506 + };
518 507  
519   -class option_required_exception : public OptionParseException
520   -{
521   - public:
522   - explicit option_required_exception(const std::string& option)
523   - : OptionParseException(
524   - "Option " + LQUOTE + option + RQUOTE + " is required but not present"
525   - )
  508 + class incorrect_argument_type : public parsing
526 509 {
527   - }
528   -};
  510 + public:
  511 + explicit incorrect_argument_type
  512 + (
  513 + const std::string& arg
  514 + )
  515 + : parsing(
  516 + "Argument " + LQUOTE + arg + RQUOTE + " failed to parse"
  517 + )
  518 + {
  519 + }
  520 + };
  521 +}
529 522  
530 523 template <typename T>
531 524 void throw_or_mimic(const std::string& text)
... ... @@ -547,7 +540,9 @@ void throw_or_mimic(const std::string&amp; text)
547 540 }
548 541  
549 542 namespace values {
  543 +
550 544 namespace parser_tool {
  545 +
551 546 struct IntegerDesc
552 547 {
553 548 std::string negative = "";
... ... @@ -560,12 +555,13 @@ struct ArguDesc {
560 555 bool set_value = false;
561 556 std::string value = "";
562 557 };
  558 +
563 559 #ifdef CXXOPTS_NO_REGEX
564 560 inline IntegerDesc SplitInteger(const std::string &text)
565 561 {
566 562 if (text.empty())
567 563 {
568   - throw_or_mimic<argument_incorrect_type>(text);
  564 + throw_or_mimic<exceptions::incorrect_argument_type>(text);
569 565 }
570 566 IntegerDesc desc;
571 567 const char *pdata = text.c_str();
... ... @@ -585,7 +581,7 @@ inline IntegerDesc SplitInteger(const std::string &amp;text)
585 581 }
586 582 else
587 583 {
588   - throw_or_mimic<argument_incorrect_type>(text);
  584 + throw_or_mimic<exceptions::incorrect_argument_type>(text);
589 585 }
590 586 return desc;
591 587 }
... ... @@ -644,7 +640,7 @@ inline std::pair&lt;std::string, std::string&gt; SplitSwitchDef(const std::string &amp;tex
644 640 if (*pdata == '\0') {
645 641 long_sw = std::string(store, pdata - store);
646 642 } else {
647   - throw_or_mimic<invalid_option_format_error>(text);
  643 + throw_or_mimic<exceptions::invalid_option_format>(text);
648 644 }
649 645 }
650 646 return std::pair<std::string, std::string>(short_sw, long_sw);
... ... @@ -725,7 +721,7 @@ inline IntegerDesc SplitInteger(const std::string &amp;text)
725 721  
726 722 if (match.length() == 0)
727 723 {
728   - throw_or_mimic<argument_incorrect_type>(text);
  724 + throw_or_mimic<exceptions::incorrect_argument_type>(text);
729 725 }
730 726  
731 727 IntegerDesc desc;
... ... @@ -741,7 +737,6 @@ inline IntegerDesc SplitInteger(const std::string &amp;text)
741 737 }
742 738  
743 739 return desc;
744   -
745 740 }
746 741  
747 742 inline bool IsTrueText(const std::string &text)
... ... @@ -764,7 +759,7 @@ inline std::pair&lt;std::string, std::string&gt; SplitSwitchDef(const std::string &amp;tex
764 759 std::regex_match(text.c_str(), result, option_specifier);
765 760 if (result.empty())
766 761 {
767   - throw_or_mimic<invalid_option_format_error>(text);
  762 + throw_or_mimic<exceptions::invalid_option_format>(text);
768 763 }
769 764  
770 765 const std::string& short_sw = result[2];
... ... @@ -799,6 +794,7 @@ inline ArguDesc ParseArgument(const char *arg, bool &amp;matched)
799 794 } // namespace parser_tool
800 795  
801 796 namespace detail {
  797 +
802 798 template <typename T, bool B>
803 799 struct SignedCheck;
804 800  
... ... @@ -813,14 +809,14 @@ struct SignedCheck&lt;T, true&gt;
813 809 {
814 810 if (u > static_cast<U>((std::numeric_limits<T>::min)()))
815 811 {
816   - throw_or_mimic<argument_incorrect_type>(text);
  812 + throw_or_mimic<exceptions::incorrect_argument_type>(text);
817 813 }
818 814 }
819 815 else
820 816 {
821 817 if (u > static_cast<U>((std::numeric_limits<T>::max)()))
822 818 {
823   - throw_or_mimic<argument_incorrect_type>(text);
  819 + throw_or_mimic<exceptions::incorrect_argument_type>(text);
824 820 }
825 821 }
826 822 }
... ... @@ -857,7 +853,7 @@ template &lt;typename R, typename T&gt;
857 853 void
858 854 checked_negate(R&, T&&, const std::string& text, std::false_type)
859 855 {
860   - throw_or_mimic<argument_incorrect_type>(text);
  856 + throw_or_mimic<exceptions::incorrect_argument_type>(text);
861 857 }
862 858  
863 859 template <typename T>
... ... @@ -893,13 +889,13 @@ integer_parser(const std::string&amp; text, T&amp; value)
893 889 }
894 890 else
895 891 {
896   - throw_or_mimic<argument_incorrect_type>(text);
  892 + throw_or_mimic<exceptions::incorrect_argument_type>(text);
897 893 }
898 894  
899 895 const US next = static_cast<US>(result * base + digit);
900 896 if (result > next)
901 897 {
902   - throw_or_mimic<argument_incorrect_type>(text);
  898 + throw_or_mimic<exceptions::incorrect_argument_type>(text);
903 899 }
904 900  
905 901 result = next;
... ... @@ -923,7 +919,7 @@ void stringstream_parser(const std::string&amp; text, T&amp; value)
923 919 std::stringstream in(text);
924 920 in >> value;
925 921 if (!in) {
926   - throw_or_mimic<argument_incorrect_type>(text);
  922 + throw_or_mimic<exceptions::incorrect_argument_type>(text);
927 923 }
928 924 }
929 925  
... ... @@ -951,7 +947,7 @@ parse_value(const std::string&amp; text, bool&amp; value)
951 947 return;
952 948 }
953 949  
954   - throw_or_mimic<argument_incorrect_type>(text);
  950 + throw_or_mimic<exceptions::incorrect_argument_type>(text);
955 951 }
956 952  
957 953 inline
... ... @@ -1007,7 +1003,7 @@ void parse_value(const std::string&amp; text, char&amp; c)
1007 1003 {
1008 1004 if (text.length() != 1)
1009 1005 {
1010   - throw_or_mimic<argument_incorrect_type>(text);
  1006 + throw_or_mimic<exceptions::incorrect_argument_type>(text);
1011 1007 }
1012 1008  
1013 1009 c = text[0];
... ... @@ -1204,6 +1200,7 @@ class standard_value&lt;bool&gt; : public abstract_value&lt;bool&gt;
1204 1200 m_implicit_value = "true";
1205 1201 }
1206 1202 };
  1203 +
1207 1204 } // namespace values
1208 1205  
1209 1206 template <typename T>
... ... @@ -1388,7 +1385,7 @@ class OptionValue
1388 1385 as() const
1389 1386 {
1390 1387 if (m_value == nullptr) {
1391   - throw_or_mimic<option_has_no_value_exception>(
  1388 + throw_or_mimic<exceptions::option_has_no_value>(
1392 1389 m_long_name == nullptr ? "" : *m_long_name);
1393 1390 }
1394 1391  
... ... @@ -1576,14 +1573,14 @@ class ParseResult
1576 1573  
1577 1574 if (iter == m_keys.end())
1578 1575 {
1579   - throw_or_mimic<option_not_present_exception>(option);
  1576 + throw_or_mimic<exceptions::requested_option_not_present>(option);
1580 1577 }
1581 1578  
1582 1579 auto viter = m_values.find(iter->second);
1583 1580  
1584 1581 if (viter == m_values.end())
1585 1582 {
1586   - throw_or_mimic<option_not_present_exception>(option);
  1583 + throw_or_mimic<exceptions::requested_option_not_present>(option);
1587 1584 }
1588 1585  
1589 1586 return viter->second;
... ... @@ -1898,184 +1895,186 @@ class OptionAdder
1898 1895 };
1899 1896  
1900 1897 namespace {
1901   - constexpr size_t OPTION_LONGEST = 30;
1902   - constexpr size_t OPTION_DESC_GAP = 2;
1903 1898  
1904   - String
1905   - format_option
1906   - (
1907   - const HelpOptionDetails& o
1908   - )
  1899 +constexpr size_t OPTION_LONGEST = 30;
  1900 +constexpr size_t OPTION_DESC_GAP = 2;
  1901 +
  1902 +String
  1903 +format_option
  1904 +(
  1905 + const HelpOptionDetails& o
  1906 +)
  1907 +{
  1908 + const auto& s = o.s;
  1909 + const auto& l = o.l;
  1910 +
  1911 + String result = " ";
  1912 +
  1913 + if (!s.empty())
  1914 + {
  1915 + result += "-" + toLocalString(s);
  1916 + if (!l.empty())
  1917 + {
  1918 + result += ",";
  1919 + }
  1920 + }
  1921 + else
  1922 + {
  1923 + result += " ";
  1924 + }
  1925 +
  1926 + if (!l.empty())
1909 1927 {
1910   - const auto& s = o.s;
1911   - const auto& l = o.l;
  1928 + result += " --" + toLocalString(l);
  1929 + }
1912 1930  
1913   - String result = " ";
  1931 + auto arg = !o.arg_help.empty() ? toLocalString(o.arg_help) : "arg";
1914 1932  
1915   - if (!s.empty())
  1933 + if (!o.is_boolean)
  1934 + {
  1935 + if (o.has_implicit)
1916 1936 {
1917   - result += "-" + toLocalString(s);
1918   - if (!l.empty())
1919   - {
1920   - result += ",";
1921   - }
  1937 + result += " [=" + arg + "(=" + toLocalString(o.implicit_value) + ")]";
1922 1938 }
1923 1939 else
1924 1940 {
1925   - result += " ";
  1941 + result += " " + arg;
1926 1942 }
  1943 + }
1927 1944  
1928   - if (!l.empty())
1929   - {
1930   - result += " --" + toLocalString(l);
1931   - }
  1945 + return result;
  1946 +}
1932 1947  
1933   - auto arg = !o.arg_help.empty() ? toLocalString(o.arg_help) : "arg";
  1948 +String
  1949 +format_description
  1950 +(
  1951 + const HelpOptionDetails& o,
  1952 + size_t start,
  1953 + size_t allowed,
  1954 + bool tab_expansion
  1955 +)
  1956 +{
  1957 + auto desc = o.desc;
1934 1958  
1935   - if (!o.is_boolean)
  1959 + if (o.has_default && (!o.is_boolean || o.default_value != "false"))
  1960 + {
  1961 + if(!o.default_value.empty())
1936 1962 {
1937   - if (o.has_implicit)
1938   - {
1939   - result += " [=" + arg + "(=" + toLocalString(o.implicit_value) + ")]";
1940   - }
1941   - else
1942   - {
1943   - result += " " + arg;
1944   - }
  1963 + desc += toLocalString(" (default: " + o.default_value + ")");
  1964 + }
  1965 + else
  1966 + {
  1967 + desc += toLocalString(" (default: \"\")");
1945 1968 }
1946   -
1947   - return result;
1948 1969 }
1949 1970  
1950   - String
1951   - format_description
1952   - (
1953   - const HelpOptionDetails& o,
1954   - size_t start,
1955   - size_t allowed,
1956   - bool tab_expansion
1957   - )
1958   - {
1959   - auto desc = o.desc;
  1971 + String result;
1960 1972  
1961   - if (o.has_default && (!o.is_boolean || o.default_value != "false"))
  1973 + if (tab_expansion)
  1974 + {
  1975 + String desc2;
  1976 + auto size = size_t{ 0 };
  1977 + for (auto c = std::begin(desc); c != std::end(desc); ++c)
1962 1978 {
1963   - if(!o.default_value.empty())
  1979 + if (*c == '\n')
1964 1980 {
1965   - desc += toLocalString(" (default: " + o.default_value + ")");
  1981 + desc2 += *c;
  1982 + size = 0;
1966 1983 }
1967   - else
  1984 + else if (*c == '\t')
1968 1985 {
1969   - desc += toLocalString(" (default: \"\")");
  1986 + auto skip = 8 - size % 8;
  1987 + stringAppend(desc2, skip, ' ');
  1988 + size += skip;
1970 1989 }
1971   - }
1972   -
1973   - String result;
1974   -
1975   - if (tab_expansion)
1976   - {
1977   - String desc2;
1978   - auto size = size_t{ 0 };
1979   - for (auto c = std::begin(desc); c != std::end(desc); ++c)
  1990 + else
1980 1991 {
1981   - if (*c == '\n')
1982   - {
1983   - desc2 += *c;
1984   - size = 0;
1985   - }
1986   - else if (*c == '\t')
1987   - {
1988   - auto skip = 8 - size % 8;
1989   - stringAppend(desc2, skip, ' ');
1990   - size += skip;
1991   - }
1992   - else
1993   - {
1994   - desc2 += *c;
1995   - ++size;
1996   - }
  1992 + desc2 += *c;
  1993 + ++size;
1997 1994 }
1998   - desc = desc2;
1999 1995 }
  1996 + desc = desc2;
  1997 + }
2000 1998  
2001   - desc += " ";
  1999 + desc += " ";
2002 2000  
2003   - auto current = std::begin(desc);
2004   - auto previous = current;
2005   - auto startLine = current;
2006   - auto lastSpace = current;
  2001 + auto current = std::begin(desc);
  2002 + auto previous = current;
  2003 + auto startLine = current;
  2004 + auto lastSpace = current;
2007 2005  
2008   - auto size = size_t{};
  2006 + auto size = size_t{};
2009 2007  
2010   - bool appendNewLine;
2011   - bool onlyWhiteSpace = true;
  2008 + bool appendNewLine;
  2009 + bool onlyWhiteSpace = true;
2012 2010  
2013   - while (current != std::end(desc))
  2011 + while (current != std::end(desc))
  2012 + {
  2013 + appendNewLine = false;
  2014 +
  2015 + if (std::isblank(*previous))
2014 2016 {
2015   - appendNewLine = false;
  2017 + lastSpace = current;
  2018 + }
2016 2019  
2017   - if (std::isblank(*previous))
2018   - {
2019   - lastSpace = current;
2020   - }
  2020 + if (!std::isblank(*current))
  2021 + {
  2022 + onlyWhiteSpace = false;
  2023 + }
2021 2024  
2022   - if (!std::isblank(*current))
2023   - {
2024   - onlyWhiteSpace = false;
2025   - }
  2025 + while (*current == '\n')
  2026 + {
  2027 + previous = current;
  2028 + ++current;
  2029 + appendNewLine = true;
  2030 + }
2026 2031  
2027   - while (*current == '\n')
  2032 + if (!appendNewLine && size >= allowed)
  2033 + {
  2034 + if (lastSpace != startLine)
2028 2035 {
  2036 + current = lastSpace;
2029 2037 previous = current;
2030   - ++current;
2031   - appendNewLine = true;
2032 2038 }
  2039 + appendNewLine = true;
  2040 + }
2033 2041  
2034   - if (!appendNewLine && size >= allowed)
2035   - {
2036   - if (lastSpace != startLine)
2037   - {
2038   - current = lastSpace;
2039   - previous = current;
2040   - }
2041   - appendNewLine = true;
2042   - }
  2042 + if (appendNewLine)
  2043 + {
  2044 + stringAppend(result, startLine, current);
  2045 + startLine = current;
  2046 + lastSpace = current;
2043 2047  
2044   - if (appendNewLine)
  2048 + if (*previous != '\n')
2045 2049 {
2046   - stringAppend(result, startLine, current);
2047   - startLine = current;
2048   - lastSpace = current;
2049   -
2050   - if (*previous != '\n')
2051   - {
2052   - stringAppend(result, "\n");
2053   - }
2054   -
2055   - stringAppend(result, start, ' ');
  2050 + stringAppend(result, "\n");
  2051 + }
2056 2052  
2057   - if (*previous != '\n')
2058   - {
2059   - stringAppend(result, lastSpace, current);
2060   - }
  2053 + stringAppend(result, start, ' ');
2061 2054  
2062   - onlyWhiteSpace = true;
2063   - size = 0;
  2055 + if (*previous != '\n')
  2056 + {
  2057 + stringAppend(result, lastSpace, current);
2064 2058 }
2065 2059  
2066   - previous = current;
2067   - ++current;
2068   - ++size;
  2060 + onlyWhiteSpace = true;
  2061 + size = 0;
2069 2062 }
2070 2063  
2071   - //append whatever is left but ignore whitespace
2072   - if (!onlyWhiteSpace)
2073   - {
2074   - stringAppend(result, startLine, previous);
2075   - }
  2064 + previous = current;
  2065 + ++current;
  2066 + ++size;
  2067 + }
2076 2068  
2077   - return result;
  2069 + //append whatever is left but ignore whitespace
  2070 + if (!onlyWhiteSpace)
  2071 + {
  2072 + stringAppend(result, startLine, previous);
2078 2073 }
  2074 +
  2075 + return result;
  2076 +}
  2077 +
2079 2078 } // namespace
2080 2079  
2081 2080 inline
... ... @@ -2115,11 +2114,11 @@ OptionAdder::operator()
2115 2114  
2116 2115 if (!short_sw.length() && !long_sw.length())
2117 2116 {
2118   - throw_or_mimic<invalid_option_format_error>(opts);
  2117 + throw_or_mimic<exceptions::invalid_option_format>(opts);
2119 2118 }
2120 2119 else if (long_sw.length() == 1 && short_sw.length())
2121 2120 {
2122   - throw_or_mimic<invalid_option_format_error>(opts);
  2121 + throw_or_mimic<exceptions::invalid_option_format>(opts);
2123 2122 }
2124 2123  
2125 2124 auto option_names = []
... ... @@ -2201,7 +2200,7 @@ OptionParser::checked_parse_arg
2201 2200 }
2202 2201 else
2203 2202 {
2204   - throw_or_mimic<missing_argument_exception>(name);
  2203 + throw_or_mimic<exceptions::missing_argument>(name);
2205 2204 }
2206 2205 }
2207 2206 else
... ... @@ -2249,7 +2248,7 @@ OptionParser::consume_positional(const std::string&amp; a, PositionalListIterator&amp; n
2249 2248 add_to_option(iter, *next, a);
2250 2249 return true;
2251 2250 }
2252   - throw_or_mimic<option_not_exists_exception>(*next);
  2251 + throw_or_mimic<exceptions::no_such_option>(*next);
2253 2252 }
2254 2253  
2255 2254 return false;
... ... @@ -2315,7 +2314,7 @@ OptionParser::parse(int argc, const char* const* argv)
2315 2314 // but if it starts with a `-`, then it's an error
2316 2315 if (argv[current][0] == '-' && argv[current][1] != '\0') {
2317 2316 if (!m_allow_unrecognised) {
2318   - throw_or_mimic<option_syntax_exception>(argv[current]);
  2317 + throw_or_mimic<exceptions::invalid_option_syntax>(argv[current]);
2319 2318 }
2320 2319 }
2321 2320  
... ... @@ -2350,7 +2349,7 @@ OptionParser::parse(int argc, const char* const* argv)
2350 2349 continue;
2351 2350 }
2352 2351 //error
2353   - throw_or_mimic<option_not_exists_exception>(name);
  2352 + throw_or_mimic<exceptions::no_such_option>(name);
2354 2353 }
2355 2354  
2356 2355 auto value = iter->second;
... ... @@ -2373,7 +2372,7 @@ OptionParser::parse(int argc, const char* const* argv)
2373 2372 else
2374 2373 {
2375 2374 //error
2376   - throw_or_mimic<option_requires_argument_exception>(name);
  2375 + throw_or_mimic<exceptions::option_requires_argument>(name);
2377 2376 }
2378 2377 }
2379 2378 }
... ... @@ -2393,7 +2392,7 @@ OptionParser::parse(int argc, const char* const* argv)
2393 2392 continue;
2394 2393 }
2395 2394 //error
2396   - throw_or_mimic<option_not_exists_exception>(name);
  2395 + throw_or_mimic<exceptions::no_such_option>(name);
2397 2396 }
2398 2397  
2399 2398 auto opt = iter->second;
... ... @@ -2531,7 +2530,7 @@ Options::add_one_option
2531 2530  
2532 2531 if (!in.second)
2533 2532 {
2534   - throw_or_mimic<option_exists_error>(option);
  2533 + throw_or_mimic<exceptions::option_already_exists>(option);
2535 2534 }
2536 2535 }
2537 2536  
... ...
src/example.cpp
... ... @@ -182,7 +182,7 @@ parse(int argc, const char* argv[])
182 182 }
183 183 std::cout << std::endl;
184 184 }
185   - catch (const cxxopts::OptionException& e)
  185 + catch (const cxxopts::exceptions::exception& e)
186 186 {
187 187 std::cout << "error parsing options: " << e.what() << std::endl;
188 188 return false;
... ...
test/catch.hpp
... ... @@ -9188,7 +9188,7 @@ namespace Catch {
9188 9188 // And... Print a result applicable to each result type.
9189 9189 switch( assertionResult.getResultType() ) {
9190 9190 case ResultWas::ThrewException:
9191   - m_xml.scopedElement( "Exception" )
  9191 + m_xml.scopedElement( "exception" )
9192 9192 .writeAttribute( "filename", assertionResult.getSourceInfo().file )
9193 9193 .writeAttribute( "line", assertionResult.getSourceInfo().line )
9194 9194 .writeText( assertionResult.getMessage() );
... ...
test/options.cpp
... ... @@ -94,7 +94,7 @@ TEST_CASE(&quot;Basic options&quot;, &quot;[options]&quot;)
94 94 CHECK(arguments[2].key() == "value");
95 95 CHECK(arguments[3].key() == "av");
96 96  
97   - CHECK_THROWS_AS(result["nothing"].as<std::string>(), cxxopts::option_has_no_value_exception&);
  97 + CHECK_THROWS_AS(result["nothing"].as<std::string>(), cxxopts::exceptions::option_has_no_value&);
98 98  
99 99 CHECK(options.program() == "tester");
100 100 }
... ... @@ -122,7 +122,7 @@ TEST_CASE(&quot;Short options&quot;, &quot;[options]&quot;)
122 122 CHECK(arguments[0].value() == "value");
123 123  
124 124 REQUIRE_THROWS_AS(options.add_options()("", "nothing option"),
125   - cxxopts::invalid_option_format_error&);
  125 + cxxopts::exceptions::invalid_option_format&);
126 126 }
127 127  
128 128 TEST_CASE("No positional", "[positional]")
... ... @@ -235,7 +235,7 @@ TEST_CASE(&quot;Positional not valid&quot;, &quot;[positional]&quot;) {
235 235 auto** argv = av.argv();
236 236 auto argc = av.argc();
237 237  
238   - CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::option_not_exists_exception&);
  238 + CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::exceptions::no_such_option&);
239 239 }
240 240  
241 241 TEST_CASE("Positional with empty arguments", "[positional]") {
... ... @@ -294,7 +294,7 @@ TEST_CASE(&quot;Boolean without implicit value&quot;, &quot;[implicit]&quot;)
294 294 auto** argv = av.argv();
295 295 auto argc = av.argc();
296 296  
297   - CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::missing_argument_exception&);
  297 + CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::exceptions::missing_argument&);
298 298 }
299 299  
300 300 SECTION("With equal-separated true") {
... ... @@ -460,7 +460,7 @@ TEST_CASE(&quot;Unsigned integers&quot;, &quot;[options]&quot;)
460 460 auto argc = av.argc();
461 461  
462 462 options.parse_positional("positional");
463   - CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::argument_incorrect_type&);
  463 + CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::exceptions::incorrect_argument_type&);
464 464 }
465 465  
466 466 TEST_CASE("Integer bounds", "[integer]")
... ... @@ -497,12 +497,12 @@ TEST_CASE(&quot;Overflow on boundary&quot;, &quot;[integer]&quot;)
497 497 int8_t si;
498 498 uint8_t ui;
499 499  
500   - CHECK_THROWS_AS((integer_parser("128", si)), cxxopts::argument_incorrect_type&);
501   - CHECK_THROWS_AS((integer_parser("-129", si)), cxxopts::argument_incorrect_type&);
502   - CHECK_THROWS_AS((integer_parser("256", ui)), cxxopts::argument_incorrect_type&);
503   - CHECK_THROWS_AS((integer_parser("-0x81", si)), cxxopts::argument_incorrect_type&);
504   - CHECK_THROWS_AS((integer_parser("0x80", si)), cxxopts::argument_incorrect_type&);
505   - CHECK_THROWS_AS((integer_parser("0x100", ui)), cxxopts::argument_incorrect_type&);
  500 + CHECK_THROWS_AS((integer_parser("128", si)), cxxopts::exceptions::incorrect_argument_type&);
  501 + CHECK_THROWS_AS((integer_parser("-129", si)), cxxopts::exceptions::incorrect_argument_type&);
  502 + CHECK_THROWS_AS((integer_parser("256", ui)), cxxopts::exceptions::incorrect_argument_type&);
  503 + CHECK_THROWS_AS((integer_parser("-0x81", si)), cxxopts::exceptions::incorrect_argument_type&);
  504 + CHECK_THROWS_AS((integer_parser("0x80", si)), cxxopts::exceptions::incorrect_argument_type&);
  505 + CHECK_THROWS_AS((integer_parser("0x100", ui)), cxxopts::exceptions::incorrect_argument_type&);
506 506 }
507 507  
508 508 TEST_CASE("Integer overflow", "[options]")
... ... @@ -519,11 +519,11 @@ TEST_CASE(&quot;Integer overflow&quot;, &quot;[options]&quot;)
519 519 auto argc = av.argc();
520 520  
521 521 options.parse_positional("positional");
522   - CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::argument_incorrect_type&);
  522 + CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::exceptions::incorrect_argument_type&);
523 523  
524 524 int integer = 0;
525   - CHECK_THROWS_AS((integer_parser("23423423423", integer)), cxxopts::argument_incorrect_type&);
526   - CHECK_THROWS_AS((integer_parser("234234234234", integer)), cxxopts::argument_incorrect_type&);
  525 + CHECK_THROWS_AS((integer_parser("23423423423", integer)), cxxopts::exceptions::incorrect_argument_type&);
  526 + CHECK_THROWS_AS((integer_parser("234234234234", integer)), cxxopts::exceptions::incorrect_argument_type&);
527 527 }
528 528  
529 529 TEST_CASE("Floats", "[options]")
... ... @@ -564,7 +564,7 @@ TEST_CASE(&quot;Invalid integers&quot;, &quot;[integer]&quot;) {
564 564 auto argc = av.argc();
565 565  
566 566 options.parse_positional("positional");
567   - CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::argument_incorrect_type&);
  567 + CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::exceptions::incorrect_argument_type&);
568 568 }
569 569  
570 570 TEST_CASE("Booleans", "[boolean]") {
... ... @@ -670,7 +670,7 @@ TEST_CASE(&quot;Unrecognised options&quot;, &quot;[options]&quot;) {
670 670 auto argc = av.argc();
671 671  
672 672 SECTION("Default behaviour") {
673   - CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::option_not_exists_exception&);
  673 + CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::exceptions::no_such_option&);
674 674 }
675 675  
676 676 SECTION("After allowing unrecognised options") {
... ... @@ -697,7 +697,7 @@ TEST_CASE(&quot;Allow bad short syntax&quot;, &quot;[options]&quot;) {
697 697 auto argc = av.argc();
698 698  
699 699 SECTION("Default behaviour") {
700   - CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::option_syntax_exception&);
  700 + CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::exceptions::invalid_option_syntax&);
701 701 }
702 702  
703 703 SECTION("After allowing unrecognised options") {
... ... @@ -720,7 +720,7 @@ TEST_CASE(&quot;Invalid option syntax&quot;, &quot;[options]&quot;) {
720 720 auto argc = av.argc();
721 721  
722 722 SECTION("Default behaviour") {
723   - CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::option_syntax_exception&);
  723 + CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::exceptions::invalid_option_syntax&);
724 724 }
725 725 }
726 726  
... ... @@ -739,7 +739,7 @@ TEST_CASE(&quot;Options empty&quot;, &quot;[options]&quot;) {
739 739 auto** argv = argv_.argv();
740 740  
741 741 CHECK(options.groups().empty());
742   - CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::option_not_exists_exception&);
  742 + CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::exceptions::no_such_option&);
743 743 }
744 744  
745 745 TEST_CASE("Initializer list with group", "[options]") {
... ...