From 31eaad570536ae4f7699228220df27296b4a3453 Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Sun, 20 Jul 2014 22:05:52 -0500 Subject: [PATCH] Replay svn revisions 33204 and 33205. These revisions were apparently lost in the svn-to-git conversion. --- doc/news/changes.h | 9 ++--- source/base/utilities.cc | 39 +++++++++++++-------- tests/base/utilities_07.cc | 64 ++++++++++++++++++++++++++++++++++ tests/base/utilities_07.output | 5 +++ 4 files changed, 99 insertions(+), 18 deletions(-) create mode 100644 tests/base/utilities_07.cc create mode 100644 tests/base/utilities_07.output diff --git a/doc/news/changes.h b/doc/news/changes.h index 4d033f8846..4d4eae2789 100644 --- a/doc/news/changes.h +++ b/doc/news/changes.h @@ -190,11 +190,12 @@ inconvenience this causes.

Specific improvements

    -
  1. Fixed: Utilities::string_to_int() did not catch if the - string given started with an integer but contained additional - text. It now throws an exception if this happens. +
  2. Fixed: Utilities::string_to_int() and + Utilities::string_to_double() did not catch if the + string given started with an integer or double but contained additional + text. They now throw an exception if this happens.
    - (Wolfgang Bangerth, 2014/07/14) + (Wolfgang Bangerth, 2014/07/20)
  3. New: The function GridOut::write, can now be used also in diff --git a/source/base/utilities.cc b/source/base/utilities.cc index a09e9dabf1..e7934eda30 100644 --- a/source/base/utilities.cc +++ b/source/base/utilities.cc @@ -156,6 +156,12 @@ namespace Utilities while ((s.size() > 0) && (s[s.size()-1] == ' ')) s.erase (s.end()-1); + // now convert and see whether we succeed. note that strtol only + // touches errno if an error occurred, so if we want to check + // whether an error happened, we need to make sure that errno==0 + // before calling strtol since otherwise it may be that the + // conversion succeeds and that errno remains at the value it + // was before, whatever that was char *p; errno = 0; const int i = std::strtol(s.c_str(), &p, 10); @@ -179,23 +185,28 @@ namespace Utilities double - string_to_double (const std::string &s) + string_to_double (const std::string &s_) { - std::istringstream ss(s); - - double i = std::numeric_limits::max(); - ss >> i; - - // check for errors - AssertThrow (i != std::numeric_limits::max(), - ExcCantConvertString (s)); + // trim whitespace on either side of the text if necessary + std::string s = s_; + while ((s.size() > 0) && (s[0] == ' ')) + s.erase (s.begin()); + while ((s.size() > 0) && (s[s.size()-1] == ' ')) + s.erase (s.end()-1); -//TODO: The test for errors above doesn't work, as can easily be -//verified. furthermore, it doesn't catch cases like when calling -//string_to_int("1.23.4") since it just reads in however much it can, without -//realizing that there is more + // now convert and see whether we succeed. note that strtol only + // touches errno if an error occurred, so if we want to check + // whether an error happened, we need to make sure that errno==0 + // before calling strtol since otherwise it may be that the + // conversion succeeds and that errno remains at the value it + // was before, whatever that was + char *p; + errno = 0; + const double d = std::strtod(s.c_str(), &p); + AssertThrow ( !((errno != 0) || (s.size() == 0) || ((s.size()>0) && (*p != '\0'))), + ExcMessage ("Can't convert <" + s + "> to an integer.")); - return i; + return d; } diff --git a/tests/base/utilities_07.cc b/tests/base/utilities_07.cc new file mode 100644 index 0000000000..0d4e99616e --- /dev/null +++ b/tests/base/utilities_07.cc @@ -0,0 +1,64 @@ +// --------------------------------------------------------------------- +// $Id$ +// +// Copyright (C) 2005 - 2014 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE at +// the top level of the deal.II distribution. +// +// --------------------------------------------------------------------- + + +// verify that Utilities::string_to_double actually catches errors + +#include "../tests.h" +#include +#include +#include +#include +#include + +#include + +using namespace dealii; + + + + +void verify (const std::string &s) +{ + bool exception_caught = false; + try + { + Utilities::string_to_double(s); + } + catch (...) + { + exception_caught = true; + } + Assert (exception_caught == true, ExcMessage ("Function is broken!")); + + deallog << "Done correctly: " << s << std::endl; +} + + + + +int main() +{ + std::ofstream logfile("output"); + deallog.attach(logfile); + deallog.depth_console(0); + deallog.threshold_double(1.e-10); + + verify ("abc"); + verify ("1.23.4"); + verify ("1 23 4"); + verify ("123abc"); +} diff --git a/tests/base/utilities_07.output b/tests/base/utilities_07.output new file mode 100644 index 0000000000..110cf89fba --- /dev/null +++ b/tests/base/utilities_07.output @@ -0,0 +1,5 @@ + +DEAL::Done correctly: abc +DEAL::Done correctly: 1.23.4 +DEAL::Done correctly: 1 23 4 +DEAL::Done correctly: 123abc -- 2.39.5