summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Benjamin Barenblat <bbaren@mit.edu>2015-07-28 10:38:10 -0400
committerGravatar Benjamin Barenblat <bbaren@mit.edu>2015-07-28 10:38:10 -0400
commit2f6799a42360a995b665244b922ebd3b2275c839 (patch)
tree23102228a85e96561f1ce20c5321d31b573b94d7 /src
parenta8b108619083c2088269ea8071c7958f277ed41f (diff)
Replace my bounds-checked numeric conversion with Boost’s
Boost provides numeric_cast, which is much better than what I was using for safe numeric type conversion. This does introduce a Boost dependency, but that tends to be true of most nontrivial C++ programs, so it’s pretty reasonable.
Diffstat (limited to 'src')
-rw-r--r--src/regex__FFI.cc32
1 files changed, 11 insertions, 21 deletions
diff --git a/src/regex__FFI.cc b/src/regex__FFI.cc
index 0ea3455..c2f8a4b 100644
--- a/src/regex__FFI.cc
+++ b/src/regex__FFI.cc
@@ -14,12 +14,10 @@
#include "regex__FFI.h"
-#include <regex.h>
-
#include <cstring>
-#include <limits>
#include <regex>
+#include <boost/numeric/conversion/cast.hpp>
extern "C" {
#include <urweb/urweb_cpp.h>
}
@@ -54,18 +52,13 @@ void DeleteMatchResults(void* match_result,
}
// Bounds-checked numeric type conversion
-template<typename T, typename U>
-U Number(uw_context* const context, const T input) {
- Assert(context, input <= std::numeric_limits<U>::max(),
- "regex: detected overflow during numeric conversion");
- if (std::numeric_limits<T>::is_signed == std::numeric_limits<U>::is_signed) {
- Assert(context, std::numeric_limits<U>::lowest() <= input,
- "regex: detected underflow during numeric conversion");
- } else if (std::numeric_limits<T>::is_signed) {
- Assert(context, 0 <= input,
- "regex: detected underflow during numeric conversion");
+template<typename Target, typename Source>
+Target Number(uw_context* const context, Source arg) {
+ try {
+ return boost::numeric_cast<Target>(arg);
+ } catch (const boost::numeric::bad_numeric_cast& e) {
+ uw_error(context, FATAL, "regex: %s", e.what());
}
- return static_cast<U>(input);
}
} // namespace
@@ -90,7 +83,7 @@ uw_Basis_int uw_Regex__FFI_n_subexpression_matches(
} else {
// At least one match occurred. Compute the number of parenthesized
// subexpressions that got matched, and return it.
- return Number<std::cmatch::size_type, uw_Basis_int>(context, n_matches) - 1;
+ return Number<uw_Basis_int>(context, n_matches) - 1;
}
}
@@ -101,18 +94,15 @@ uw_Basis_string uw_Regex__FFI_subexpression_match(
const std::cmatch* const match_result =
reinterpret_cast<std::cmatch*>(match.result);
const std::size_t match_index =
- Number<uw_Basis_int, std::size_t>(context, match_index_signed);
+ Number<std::size_t>(context, match_index_signed);
Assert(context, match_index < match_result->size(),
"regex: match does not exist");
const auto matched_substring = (*match_result)[match_index + 1];
// Save the matched substring.
const std::size_t result_length =
- Number<std::csub_match::difference_type, std::size_t>(
- context,
- matched_substring.length());
+ Number<std::size_t>(context,matched_substring.length());
uw_Basis_string result =
- reinterpret_cast<uw_Basis_string>(
- uw_malloc(context, result_length + 1));
+ reinterpret_cast<uw_Basis_string>(uw_malloc(context, result_length + 1));
std::strcpy(result, matched_substring.str().c_str());
return result;
}