lmi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi-commits] [lmi] master b9967dd 1/4: Make InputSequence ctor throw on


From: Greg Chicares
Subject: [lmi-commits] [lmi] master b9967dd 1/4: Make InputSequence ctor throw on parser failure
Date: Mon, 6 Feb 2017 19:13:31 +0000 (UTC)

branch: master
commit b9967ddc5c9f07f672b78e7c5b40a64cca5b3751
Author: Gregory W. Chicares <address@hidden>
Commit: Gregory W. Chicares <address@hidden>

    Make InputSequence ctor throw on parser failure
    
    Formerly, the ctor "succeeded", but it was unsafe to use the object it
    created without checking whether it was "valid" (although that check
    was not always performed). Now validity precedes existence, or, if you
    prefer, correctness must be the starting point.
---
 input_seq_test.cpp |   20 +-------------
 input_sequence.cpp |   76 +++++++++++++++++++---------------------------------
 input_sequence.hpp |    8 ++----
 3 files changed, 31 insertions(+), 73 deletions(-)

diff --git a/input_seq_test.cpp b/input_seq_test.cpp
index 26a7ccd..0d89699 100644
--- a/input_seq_test.cpp
+++ b/input_seq_test.cpp
@@ -76,22 +76,7 @@ void check
             std::cout << std::endl;
             }
 
-        std::string const& x(seq.formatted_diagnostics());
-        std::string const y = (nullptr == m) ? std::string() : std::string(m);
-        bool const by = x == y;
-        if(!by)
-            {
-            std::cout
-                <<   "\nObserved diagnostics:"
-                << "\n\n'" << x << "'"
-                << "\n\ndiffer from expected:"
-                << "\n\n'" << y << "'"
-                << std::endl
-                ;
-            }
-
-        bool const b = bv && bs && by;
-        INVOKE_BOOST_TEST(b, file, line);
+        INVOKE_BOOST_TEST(bv && bs, file, line);
         }
     catch(std::exception const& x)
         {
@@ -403,9 +388,6 @@ int test_main(int, char*[])
     }
 
     // Test keywords-only switch with input it forbids.
-    // SOMEDAY !! It is not ideal for construction to succeed and give
-    // a vector of zeros. Instead, the ctor should throw what is now
-    // made available (only on demand) as formatted_diagnostics().
     {
     int const n = 10;
     strvec const c      {"z", "z", "z", "z", "z", "z", "z", "z", "z", "z"};
diff --git a/input_sequence.cpp b/input_sequence.cpp
index fab69eb..da43a71 100644
--- a/input_sequence.cpp
+++ b/input_sequence.cpp
@@ -734,7 +734,12 @@ InputSequence::InputSequence
         ,a_keywords_only
         );
 
-    parser_diagnostics_ = parser.diagnostics();
+    std::string const parser_diagnostics = parser.diagnostics();
+    if(!parser_diagnostics.empty())
+        {
+        throw std::runtime_error(parser_diagnostics);
+        }
+
     intervals_ = parser.intervals();
 
     // Inception and maturity endpoints exist, so the interval they
@@ -919,21 +924,11 @@ InputSequence::~InputSequence() = default;
 
 std::vector<double> const& InputSequence::linear_number_representation() const
 {
-    if(!formatted_diagnostics().empty())
-        {
-        throw std::runtime_error(formatted_diagnostics());
-        }
-
     return number_result_;
 }
 
 std::vector<std::string> const& InputSequence::linear_keyword_representation() 
const
 {
-    if(!formatted_diagnostics().empty())
-        {
-        throw std::runtime_error(formatted_diagnostics());
-        }
-
     return keyword_result_;
 }
 
@@ -956,11 +951,6 @@ std::vector<std::string> const& 
InputSequence::linear_keyword_representation() c
 
 std::string InputSequence::mathematical_representation() const
 {
-    if(!formatted_diagnostics().empty())
-        {
-        throw std::runtime_error(formatted_diagnostics());
-        }
-
     std::ostringstream oss;
     for(auto const& interval_i : intervals_)
         {
@@ -1004,35 +994,9 @@ std::string InputSequence::mathematical_representation() 
const
 
 std::vector<ValueInterval> const& InputSequence::interval_representation() 
const
 {
-    if(!formatted_diagnostics().empty())
-        {
-        throw std::runtime_error(formatted_diagnostics());
-        }
-
     return intervals_;
 }
 
-/// Rationale for option to show only first diagnostic:
-/// downstream errors can confuse users.
-
-std::string InputSequence::formatted_diagnostics
-    (bool show_first_message_only
-    ) const
-{
-    // Data member parser_diagnostics_ exists only so that this function
-    // can return it. Eliminate it when this function is eliminated.
-    std::string s(parser_diagnostics_);
-    if(show_first_message_only)
-        {
-        std::string::size_type z(s.find('\n'));
-        if(std::string::npos != z)
-            {
-            s.erase(z);
-            }
-        }
-    return s;
-}
-
 void InputSequence::realize_vector()
 {
     // Post-construction invariants.
@@ -1050,12 +1014,6 @@ void InputSequence::realize_vector()
     number_result_  = r;
     keyword_result_ = s;
 
-    // Vectors have default values if the input expression could not be parsed.
-    if(!formatted_diagnostics().empty())
-        {
-        return;
-        }
-
     int prior_begin_duration = 0;
     for(auto const& interval_i : intervals_)
         {
@@ -1147,3 +1105,25 @@ void InputSequence::realize_vector()
     keyword_result_ = s;
 }
 
+/// Extract first substring from a '\n'-delimited exception::what().
+///
+/// SequenceParser::diagnostics() returns a '\n'-delimited string
+/// describing all the anomalies diagnosed while parsing an input
+/// sequence. When that string is not empty, it is reasonable to throw
+/// an exception constructed from it--most generally, in its entirety.
+/// In the important special case where diagnostics are to be shown to
+/// end users to whom the full multiline set may be overwhelming, this
+/// function may be used to extract only the first line (without any
+/// terminal '\n'), which is presumably the most helpful element.
+
+std::string abridge_diagnostics(char const* what)
+{
+    std::string s(what);
+    std::string::size_type z(s.find('\n'));
+    if(std::string::npos != z)
+        {
+        s.erase(z);
+        }
+    return s;
+}
+
diff --git a/input_sequence.hpp b/input_sequence.hpp
index 1c43a0b..e6fc244 100644
--- a/input_sequence.hpp
+++ b/input_sequence.hpp
@@ -280,10 +280,6 @@ class LMI_SO InputSequence
 
     std::vector<ValueInterval> const& interval_representation() const;
 
-    std::string formatted_diagnostics
-        (bool show_first_message_only = false
-        ) const;
-
   private:
     void realize_vector();
 
@@ -300,12 +296,12 @@ class LMI_SO InputSequence
     // Copy of a ctor arg that is unique to this class.
     std::string default_keyword_;
 
-    std::string parser_diagnostics_;
-
     std::vector<ValueInterval> intervals_;
     std::vector<double> number_result_;
     std::vector<std::string> keyword_result_;
 };
 
+std::string LMI_SO abridge_diagnostics(char const* what);
+
 #endif // input_sequence_hpp
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]