diff options
Diffstat (limited to 'src/mmo/human_time_diff.cpp')
-rw-r--r-- | src/mmo/human_time_diff.cpp | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/src/mmo/human_time_diff.cpp b/src/mmo/human_time_diff.cpp index 49a7664..aaa7928 100644 --- a/src/mmo/human_time_diff.cpp +++ b/src/mmo/human_time_diff.cpp @@ -18,9 +18,51 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. +#include "../io/extract.hpp" + #include "../poison.hpp" namespace tmwa { +bool impl_extract(XString str, HumanTimeDiff *iv) +{ + // str is a sequence of [-+]?[0-9]+([ay]|m|[jd]|h|mn|s) + // there are NO spaces here + // parse by counting the number starts + auto is_num = [](char c) + { return c == '-' || c == '+' || ('0' <= c && c <= '9'); }; + if (!str || !is_num(str.front())) + return false; + *iv = HumanTimeDiff{}; + while (str) + { + auto it = std::find_if_not(str.begin(), str.end(), is_num); + auto it2 = std::find_if(it, str.end(), is_num); + XString number = str.xislice_h(it); + XString suffix = str.xislice(it, it2); + str = str.xislice_t(it2); + + short *ptr = nullptr; + if (suffix == "y"_s || suffix == "a"_s) + ptr = &iv->year; + else if (suffix == "m"_s) + ptr = &iv->month; + else if (suffix == "j"_s || suffix == "d"_s) + ptr = &iv->day; + else if (suffix == "h"_s) + ptr = &iv->hour; + else if (suffix == "mn"_s) + ptr = &iv->minute; + else if (suffix == "s"_s) + ptr = &iv->second; + else + return false; + if (number.startswith('+') && !number.startswith("+-"_s)) + number = number.xslice_t(1); + if (*ptr || !extract(number, ptr)) + return false; + } + return true; +} } // namespace tmwa |