]> sigrok.org Git - pulseview.git/blobdiff - pv/util.cpp
Fix #1035 by checking for exceptions when accessing config
[pulseview.git] / pv / util.cpp
index 4a32147d80d1501a5401ee52744ad2911ae661ff..49b9467c1642737a1a995df5adcb622e2bbddfa1 100644 (file)
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include "util.hpp"
 
 #include <extdef.h>
 
-#include <assert.h>
-
 #include <algorithm>
+#include <cassert>
 #include <sstream>
 
-#include <QTextStream>
 #include <QDebug>
+#include <QTextStream>
+
+using std::fixed;
+using std::max;
+using std::ostringstream;
+using std::setfill;
+using std::setprecision;
+using std::showpos;
+using std::string;
 
 using namespace Qt;
 
@@ -84,24 +90,18 @@ static QTextStream& operator<<(QTextStream& stream, const Timestamp& t)
 
        int precision = stream.realNumberPrecision();
 
-       std::ostringstream ss;
-       ss << std::fixed;
+       ostringstream ss;
+       ss << fixed;
 
-       if (stream.numberFlags() & QTextStream::ForceSign) {
-               ss << std::showpos;
-       }
+       if (stream.numberFlags() & QTextStream::ForceSign)
+               ss << showpos;
 
-       if (0 == precision) {
-               ss
-                       << std::setprecision(1)
-                       << round(t);
-       } else {
-               ss
-                       << std::setprecision(precision)
-                       << t;
-       }
+       if (0 == precision)
+               ss << setprecision(1) << round(t);
+       else
+               ss << setprecision(precision) << t;
 
-       std::string str(ss.str());
+       string str(ss.str());
        if (0 == precision) {
                // remove the separator and the unwanted decimal place
                str.resize(str.size() - 2);
@@ -110,12 +110,8 @@ static QTextStream& operator<<(QTextStream& stream, const Timestamp& t)
        return stream << QString::fromStdString(str);
 }
 
-QString format_time_si(
-       const Timestamp& v,
-       SIPrefix prefix,
-       unsigned int precision,
-       QString unit,
-       bool sign)
+QString format_time_si(const Timestamp& v, SIPrefix prefix,
+       unsigned int precision, QString unit, bool sign)
 {
        if (prefix == SIPrefix::unspecified) {
                // No prefix given, calculate it
@@ -142,22 +138,49 @@ QString format_time_si(
        QTextStream ts(&s);
        if (sign && !v.is_zero())
                ts << forcesign;
-       ts
-               << qSetRealNumberPrecision(precision)
-               << (v * multiplier)
-               << ' '
-               << prefix
-               << unit;
+       ts << qSetRealNumberPrecision(precision) << (v * multiplier) << ' '
+               << prefix << unit;
+
+       return s;
+}
+
+QString format_value_si(double v, SIPrefix prefix, unsigned precision,
+       QString unit, bool sign)
+{
+       if (prefix == SIPrefix::unspecified) {
+               // No prefix given, calculate it
+
+               if (v == 0) {
+                       prefix = SIPrefix::none;
+               } else {
+                       int exp = exponent(SIPrefix::yotta);
+                       prefix = SIPrefix::yocto;
+                       while ((fabs(v) * pow(Timestamp(10), exp)) > 999 &&
+                                       prefix < SIPrefix::yotta) {
+                               prefix = successor(prefix);
+                               exp -= 3;
+                       }
+               }
+       }
+
+       assert(prefix >= SIPrefix::yocto);
+       assert(prefix <= SIPrefix::yotta);
+
+       const double multiplier = pow(10.0, -exponent(prefix));
+
+       QString s;
+       QTextStream ts(&s);
+       if (sign && (v != 0))
+               ts << forcesign;
+       ts.setRealNumberNotation(QTextStream::FixedNotation);
+       ts.setRealNumberPrecision(precision);
+       ts << (v * multiplier) << ' ' << prefix << unit;
 
        return s;
 }
 
-QString format_time_si_adjusted(
-       const Timestamp& t,
-       SIPrefix prefix,
-       unsigned precision,
-       QString unit,
-       bool sign)
+QString format_time_si_adjusted(const Timestamp& t, SIPrefix prefix,
+       unsigned precision, QString unit, bool sign)
 {
        // The precision is always given without taking the prefix into account
        // so we need to deduct the number of decimals the prefix might imply
@@ -165,12 +188,11 @@ QString format_time_si_adjusted(
 
        const unsigned int relative_prec =
                (prefix >= SIPrefix::none) ? precision :
-               std::max((int)(precision - prefix_order), 0);
+               max((int)(precision - prefix_order), 0);
 
        return format_time_si(t, prefix, relative_prec, unit, sign);
 }
 
-
 // Helper for 'format_time_minutes()'.
 static QString pad_number(unsigned int number, int length)
 {
@@ -220,13 +242,9 @@ QString format_time_minutes(const Timestamp& t, signed precision, bool sign)
 
                const Timestamp fraction = fabs(t) - whole_seconds;
 
-               std::ostringstream ss;
-               ss
-                       << std::fixed
-                       << std::setprecision(precision)
-                       << std::setfill('0')
-                       << fraction;
-               std::string fs = ss.str();
+               ostringstream ss;
+               ss << fixed << setprecision(precision) << setfill('0') << fraction;
+               string fs = ss.str();
 
                // Copy all digits, inserting spaces as unit separators
                for (int i = 1; i <= precision; i++) {
@@ -241,5 +259,27 @@ QString format_time_minutes(const Timestamp& t, signed precision, bool sign)
        return s;
 }
 
+/**
+ * Split a string into tokens at occurences of the separator.
+ *
+ * @param[in] text The input string to split.
+ * @param[in] separator The delimiter between tokens.
+ *
+ * @return A vector of broken down tokens.
+ */
+vector<string> split_string(string text, string separator)
+{
+       vector<string> result;
+       size_t pos;
+
+       while ((pos = text.find(separator)) != std::string::npos) {
+               result.push_back(text.substr(0, pos));
+               text = text.substr(pos + separator.length());
+       }
+       result.push_back(text);
+
+       return result;
+}
+
 } // namespace util
 } // namespace pv