diff options
Diffstat (limited to 'Build/source/texk/dvisvgm/dvisvgm-src/src/utility.cpp')
-rw-r--r-- | Build/source/texk/dvisvgm/dvisvgm-src/src/utility.cpp | 84 |
1 files changed, 69 insertions, 15 deletions
diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/utility.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/utility.cpp index 947be916342..b4938f70edc 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/utility.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/utility.cpp @@ -2,7 +2,7 @@ ** utility.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2023 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2024 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -58,7 +58,7 @@ vector<double> math::svd (const double (&m)[2][2]) { theta = (a2-a1)/2; } } - return vector<double>{phi, sx, sy, theta}; + return {phi, sx, sy, theta}; } @@ -68,7 +68,7 @@ vector<double> math::svd (const double (&m)[2][2]) { * @param[in] t1 upper interval boundary * @param[in] n number of slices the interval is divided into * @param[in] f function to integrate */ -double math::integral (double t0, double t1, int n, const std::function<double(double)> &f) { +double math::integral (double t0, double t1, int n, const function<double(double)> &f) { double ti = t0, ui=0; double h = (t1-t0)/n; for (int i=0; i < n; i++) { @@ -103,7 +103,7 @@ double math::normalize_0_2pi (double rad) { * @param[in] str the string to process * @param[in] ws characters treated as whitespace * @return the trimmed string */ -string util::trim (const std::string &str, const char *ws) { +string util::trim (const string &str, const char *ws) { auto first = str.find_first_not_of(ws); if (first == string::npos) return ""; @@ -150,12 +150,13 @@ string util::replace (string str, const string &find, const string &repl) { * returns the substrings. * @param[in] str string to split * @param[in] sep separator to look for + * @param[in] allowEmptyResult if true, the result vector is empty if str is empty; otherwise an empty string is inserted * @return the substrings between the separators */ -vector<string> util::split (const string &str, const string &sep) { +vector<string> util::split (const string &str, const string &sep, bool allowEmptyResult) { vector<string> parts; - if (str.empty() || sep.empty()) + if ((str.empty() && !allowEmptyResult) || sep.empty()) parts.push_back(str); - else { + else if (!str.empty()) { string::size_type left=0; while (left <= str.length()) { auto right = str.find(sep, left); @@ -183,13 +184,8 @@ string util::tolower (const string &str) { /** Converts a double to a string and strips redundant trailing digits/dots. */ string util::to_string (double val) { string str = std::to_string(val); - if (str.find('.') != string::npos) { // double value and not an integer? - auto pos = str.find_last_not_of('0'); - if (pos != string::npos) // trailing zeros - str.erase(pos+1, string::npos); - if (str.back() == '.') // trailing dot? - str.pop_back(); - } + str.erase(str.find_last_not_of('0')+1, string::npos); + str.erase(str.find_last_not_of('.')+1, string::npos); return str; } @@ -206,11 +202,69 @@ int util::ilog10 (int n) { } +/** Reads an integer string of the form (+|-)?[0-9]+ from an input stream + * ana appends it to a given one. + * @param[in] is stream to read from + * @param[out] str the read string is appended to this one + * @param[in] allow_leading_sign true if the first character may be '+' or '-' + * @return true if the string coule be read successfully */ +static bool read_int_string (istream &is, string &str, bool allow_leading_sign=true) { + string intstr; + if (is.peek() == '-' || is.peek() == '+') { + if (!allow_leading_sign) + return false; + intstr += char(is.get()); + if (!isdigit(is.peek())) + return false; + } + while (isdigit(is.peek())) + intstr += char(is.get()); + str += intstr; + return !intstr.empty(); +} + + +/** Reads and parses a double from an input stream. + * @param[in] is stream to read from + * @param[out] value the read double value + * @return true if the value was read and parsed successfully */ +bool util::read_double (istream &is, double &value) { + is >> ws; + string numstr; + // read optional leading sign + bool plusminus = (is.peek() == '-' || is.peek() == '+'); + if (plusminus) + numstr += char(is.get()); + // read optional integer part (before decimal dot) + read_int_string(is, numstr, !plusminus); + if (is.peek() == '.') { + numstr += char(is.get()); + // read fractional part (after decimal dot) + if (!read_int_string(is, numstr, false)) + return false; + } + // read optional exponential part + if (std::tolower(is.peek()) == 'e') { + numstr += char(is.get()); + if (!read_int_string(is, numstr)) + return false; + } + try { + size_t count; + value = stod(numstr, &count); + return count == numstr.length(); + } + catch (...) { + return false; + } +} + + /** Returns the contents of a file. * @param[in] fname name/path of the file */ string util::read_file_contents (const string &fname) { ifstream ifs(fname, ios::binary); - return string(istreambuf_iterator<char>(ifs.rdbuf()), istreambuf_iterator<char>()); + return {istreambuf_iterator<char>(ifs.rdbuf()), istreambuf_iterator<char>()}; } |