From 6cd5ac2d0dc89c13fda7ff2046f41d64e2cf3420 Mon Sep 17 00:00:00 2001 From: James Turner Date: Wed, 27 Sep 2017 15:06:37 +0100 Subject: [PATCH] Move readTime (parse_time) from options.cxx --- simgear/misc/strutils.cxx | 27 +++++++++++++++++++++++++++ simgear/misc/strutils.hxx | 10 ++++++++++ simgear/misc/strutils_test.cxx | 27 ++++++++++++++++++++++++++- 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/simgear/misc/strutils.cxx b/simgear/misc/strutils.cxx index 1f854ef6..f45e0ac8 100644 --- a/simgear/misc/strutils.cxx +++ b/simgear/misc/strutils.cxx @@ -538,6 +538,33 @@ namespace simgear { unsigned long long readNonNegativeInt( const std::string& s); #endif + + // parse a time string ([+/-]%f[:%f[:%f]]) into hours + double readTime(const string& time_in) + { + if (time_in.empty()) { + return 0.0; + } + + const bool negativeSign = time_in.front() == '-'; + const string_list pieces = split(time_in, ":"); + if (pieces.size() > 3) { + throw sg_format_exception("Unable to parse time string, too many pieces", time_in); + } + + const int hours = std::abs(to_int(pieces.front())); + int minutes = 0, seconds = 0; + if (pieces.size() > 1) { + minutes = to_int(pieces.at(1)); + if (pieces.size() > 2) { + seconds = to_int(pieces.at(2)); + } + } + + double result = hours + (minutes / 60.0) + (seconds / 3600.0); + return negativeSign ? -result : result; + } + int compare_versions(const string& v1, const string& v2, int maxComponents) { diff --git a/simgear/misc/strutils.hxx b/simgear/misc/strutils.hxx index ed0ff014..b6126cd5 100644 --- a/simgear/misc/strutils.hxx +++ b/simgear/misc/strutils.hxx @@ -209,6 +209,16 @@ namespace simgear { typename = typename std::enable_if::value, T>::type > T readNonNegativeInt(const std::string& s); + + /** + * Read a time value, seperated by colons, as a value in hours. + * Allowable input is ([+/-]%f[:%f[:%f]]) + * i.e 15:04:35 is parsed as 15 + (04 / 60) + (35 / 2600) + * This code is moved from flightgear's options.cxx where it was called + * parse_time(), + */ + double readTime(const std::string& s); + /** * Convert a string representing a boolean, to a bool. * Accepted values include YES, true, 0, 1, false, no, True, diff --git a/simgear/misc/strutils_test.cxx b/simgear/misc/strutils_test.cxx index dd686fa2..84978da5 100644 --- a/simgear/misc/strutils_test.cxx +++ b/simgear/misc/strutils_test.cxx @@ -19,6 +19,7 @@ #include #include #include +#include using std::string; using std::vector; @@ -581,6 +582,29 @@ void test_error_string() SG_CHECK_GT(strutils::error_string(saved_errno).size(), 0); } +void test_readTime() +{ + SG_CHECK_EQUAL_EP(strutils::readTime(""), 0.0); + + SG_CHECK_EQUAL_EP(strutils::readTime("11"), 11.0); + SG_CHECK_EQUAL_EP(strutils::readTime("+11"), 11.0); + SG_CHECK_EQUAL_EP(strutils::readTime("-11"), -11.0); + + SG_CHECK_EQUAL_EP(strutils::readTime("11:30"), 11.5); + SG_CHECK_EQUAL_EP(strutils::readTime("+11:15"), 11.25); + SG_CHECK_EQUAL_EP(strutils::readTime("-11:45"), -11.75); + + const double seconds = 1 / 3600.0; + SG_CHECK_EQUAL_EP(strutils::readTime("11:30:00"), 11.5); + SG_CHECK_EQUAL_EP(strutils::readTime("+11:15:05"), 11.25 + 5 * seconds); + SG_CHECK_EQUAL_EP(strutils::readTime("-11:45:15"), -(11.75 + 15 * seconds)); + + SG_CHECK_EQUAL_EP(strutils::readTime("0:0:0"), 0); + + SG_CHECK_EQUAL_EP(strutils::readTime("0:0:28"), 28 * seconds); + SG_CHECK_EQUAL_EP(strutils::readTime("-0:0:28"), -28 * seconds); +} + int main(int argc, char* argv[]) { test_strip(); @@ -599,6 +623,7 @@ int main(int argc, char* argv[]) test_md5_hex(); test_error_string(); test_propPathMatch(); - + test_readTime(); + return EXIT_SUCCESS; }