lmi-commits
[Top][All Lists]
Advanced

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

[lmi-commits] [lmi] master 416ab02 030/156: Add support for vector varia


From: Greg Chicares
Subject: [lmi-commits] [lmi] master 416ab02 030/156: Add support for vector variables to PDF generating code
Date: Tue, 30 Jan 2018 17:22:01 -0500 (EST)

branch: master
commit 416ab02fb8b8ea4da036fa86d27fdf19772f6a69
Author: Vadim Zeitlin <address@hidden>
Commit: Vadim Zeitlin <address@hidden>

    Add support for vector variables to PDF generating code
    
    Recognize anything of the form "name[index]" as a vector.
---
 ledger_pdf_generator_wx.cpp | 42 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 41 insertions(+), 1 deletion(-)

diff --git a/ledger_pdf_generator_wx.cpp b/ledger_pdf_generator_wx.cpp
index ca68fa7..c7bf5f3 100644
--- a/ledger_pdf_generator_wx.cpp
+++ b/ledger_pdf_generator_wx.cpp
@@ -39,6 +39,7 @@
 
 #include <wx/pdfdc.h>
 
+#include <cstdint>                      // SIZE_MAX
 #include <map>
 #include <memory>
 #include <sstream>
@@ -140,6 +141,11 @@ class html_interpolator
         return evaluator_(name);
     }
 
+    std::string evaluate(std::string const& name, std::size_t index) const
+    {
+        return evaluator_(name, index);
+    }
+
   private:
     // The expansion function used with interpolate_string().
     text expand_html(std::string const& s) const
@@ -151,7 +157,41 @@ class html_interpolator
             return it->second;
             }
 
-        // Then look in the ledger.
+        // Then look in the ledger, either as a scalar or a vector depending on
+        // whether it has "[index]" part or not.
+        if(!s.empty() && *s.rbegin() == ']')
+            {
+            auto const open_pos = s.find('[');
+            if(open_pos == std::string::npos)
+                {
+                throw std::runtime_error
+                    ("Variable '" + s + "' doesn't have the expected '['"
+                    );
+                }
+
+            char* stop = nullptr;
+            auto const index = std::strtoul(s.c_str() + open_pos + 1, &stop, 
10);
+
+            // Conversion must have stopped at the closing bracket character
+            // and also check for overflow (notice that index == SIZE_MAX
+            // doesn't, in theory, need to indicate overflow, but in practice
+            // we're never going to have valid indices close to this number).
+            if(stop != s.c_str() + s.length() - 1 || index >= SIZE_MAX)
+                {
+                throw std::runtime_error
+                    ("Index of vector variable '" + s + "' is not a valid 
number"
+                    );
+                }
+
+            // Cast below is valid because of the check for overflow above.
+            return text::from
+                (evaluator_
+                    (s.substr(0, open_pos)
+                    ,static_cast<std::size_t>(index)
+                    )
+                );
+            }
+
         return text::from(evaluator_(s));
     }
 



reply via email to

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