diff --git a/src/lib/util.cpp b/src/lib/util.cpp index 7ab8dfe67..93920c1a1 100644 --- a/src/lib/util.cpp +++ b/src/lib/util.cpp @@ -29,7 +29,9 @@ */ +#include "error.hpp" #include "lib/util.hpp" +#include "lib/format-string.hpp" #include #include @@ -40,12 +42,18 @@ using boost::algorithm::is_any_of; using boost::algorithm::is_alnum; using boost::algorithm::is_space; +#include + +using std::regex; +using std::regex_match; + +using std::function; +using util::_Fmt; namespace util { - using std::function; - typedef function ChPredicate; + using ChPredicate = function; ChPredicate operator! (ChPredicate p) { return not bind(p,_1); } // character classes used for sanitising a string @@ -63,12 +71,12 @@ namespace util { while ( i != e ) { while ( i != e && !isValid (*i) ) ++i; - while ( i != e && isValid (*i) ) *(j++) = *(i++); - if ( i != e && isPunct (*i) ) + while ( i != e && isValid (*i) ) *(j++) = *(i++); + if ( i != e && isPunct (*i) ) { *j++ = '_'; do ++i; - while ( i != e && isPunct (*i)); + while ( i != e && isPunct (*i)); } } res.erase(j,res.end()); @@ -79,7 +87,7 @@ namespace util { /** * @remarks this function just forwards to boost::algorithm::trim_copy. * Use this call when boost header inclusion is an issue, otherwise - * a direct invocation is likely to perform better, due to inlining. + * a direct invocation is likely to perform better, due to inlining. */ string trim (string const& org) @@ -87,6 +95,29 @@ namespace util { return boost::algorithm::trim_copy (org); } + + + + namespace { + regex trueTokens{ "\\s*(true|True|TRUE|yes|Yes|YES|1|\\+)\\s*", regex::ECMAScript | regex::optimize}; + regex falseTokens{"\\s*(false|False|FALSE|no|No|NO|0|\\-)\\s*", regex::ECMAScript | regex::optimize}; + } + + bool + boolVal (string const& textForm) + { + if (regex_match (textForm, trueTokens)) return true; + if (regex_match (textForm, falseTokens)) return false; + throw lumiera::error::Invalid(_Fmt{"String '%s' can not be interpreted as bool value"} % textForm); + } + + + bool + isYes (string const& textForm) noexcept + { + return regex_match (textForm, trueTokens); + } + } // namespace util diff --git a/src/lib/util.hpp b/src/lib/util.hpp index 4d35ff019..8e15d0872 100644 --- a/src/lib/util.hpp +++ b/src/lib/util.hpp @@ -359,8 +359,8 @@ namespace util { "mixed Ω garbage" --> 'mixed_garbage' "Bääääh!!" --> 'Bh' \endverbatim - * @see sanitised-identifier-test.cpp - * @see lib::meta::sanitisedSymbol() + * @see \ref UtilSanitizedIdentifier_test + * @see \ref lib::meta::sanitisedSymbol() */ string sanitise (string const& org); @@ -371,6 +371,23 @@ namespace util { string trim (string const& org); + /** interpret text representation of a boolean value. + * @remarks this function detects the relevant token rather strict.... + * - yields `true` for the tokens "true", "True", "TRUE", "yes", "Yes", "YES", "1", "+" + * - yields `false` for the tokens "false", "False", "FALSE", "no", "No, "NO", "0", "-" + * - leading and trailing whitespace is ignored + * @throws lumiera::error::Invalid for any other text content + */ + bool boolVal(string const&); + + + /** check the given text if it can be interpreted as affirmative answer (bool `true`). + * @remarks this function just fishes for the known `true` tokens and interprets + * all other content as `false`, including empty strings. Never throws. + */ + bool isYes(string const&) noexcept; + + /** convenience shortcut: conversion to c-String via string. diff --git a/src/proc/cmd/meta-cmd.cpp b/src/proc/cmd/meta-cmd.cpp index 25754046f..69f78dc93 100644 --- a/src/proc/cmd/meta-cmd.cpp +++ b/src/proc/cmd/meta-cmd.cpp @@ -44,8 +44,8 @@ #include "lib/idi/entry-id.hpp" #include "lib/format-string.hpp" //////////////////////////////////////////////////////////////TICKET #1099 : include needed temporarily //#include "lib/symbol.hpp" +#include "lib/util.hpp" -#include #include using lib::hash::LuidH; @@ -58,8 +58,8 @@ using gui::GuiNotification; using lib::diff::GenNode; //using util::cStr; using util::_Fmt; //////////////////////////////////////////////////////////////TICKET #1099 : include needed temporarily +using util::isYes; using std::string; -using boost::lexical_cast; namespace proc { @@ -214,7 +214,7 @@ COMMAND_DEFINITION (test_meta_markAction) { ID errorLogID = gui::interact::Wizard::getErrorLogID(); GuiNotification::facade().mark (errorLogID - ,actionID=="expand"? GenNode{actionID, lexical_cast (message)} ///////////FIXME : lexical_cast is not suitable. We need a generic bool parse function! + ,actionID=="expand"? GenNode{actionID, isYes(message)} : GenNode{actionID, message}); }) .captureUndo ([](string actionID, string message) -> string diff --git a/tests/15library.tests b/tests/15library.tests index 3aa51767f..a9779dc4c 100644 --- a/tests/15library.tests +++ b/tests/15library.tests @@ -493,22 +493,6 @@ return: 0 END -TEST "create sanitised identifiers" SanitizedIdentifier_test < 'Word' -out-lit: 'a Sentence' --> 'a_Sentence' -out-lit: 'trailing Withespace -out-lit: ' --> 'trailing_Withespace' -out-lit: 'with a lot -out-lit: of Whitespace' --> 'with_a_lot_of_Whitespace' -out-lit: 'with"much (punctuation)[]!' --> 'withmuch_(punctuation)' -out-lit: '§&Ω%€ leading garbage' --> 'leading_garbage' -out-lit: 'mixed Ω garbage' --> 'mixed_garbage' -out-lit: 'Bääääh!!' --> 'Bh' -out-lit: '§&Ω%€' --> '' -return: 0 -END - - TEST "ScopedHolder_test" ScopedHolder_test <... out: checking ScopedPtrHolder... @@ -588,6 +572,11 @@ return: 0 END +TEST "ownership of malloced data" UniqueMallocOwner_test < 'Word' +out-lit: 'a Sentence' --> 'a_Sentence' +out-lit: 'trailing Withespace +out-lit: ' --> 'trailing_Withespace' +out-lit: 'with a lot +out-lit: of Whitespace' --> 'with_a_lot_of_Whitespace' +out-lit: 'with"much (punctuation)[]!' --> 'withmuch_(punctuation)' +out-lit: '§&Ω%€ leading garbage' --> 'leading_garbage' +out-lit: 'mixed Ω garbage' --> 'mixed_garbage' +out-lit: 'Bääääh!!' --> 'Bh' +out-lit: '§&Ω%€' --> '' return: 0 END diff --git a/tests/library/util-parse-bool-test.cpp b/tests/library/util-parse-bool-test.cpp new file mode 100644 index 000000000..10a7d4db6 --- /dev/null +++ b/tests/library/util-parse-bool-test.cpp @@ -0,0 +1,106 @@ +/* + UtilParseBool(Test) - derive bool value from text form + + Copyright (C) Lumiera.org + 2018, Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + +/** @file util-parse-bool-test.cpp + ** unit test \ref UtilParseBool_test + */ + + +#include "lib/test/run.hpp" +#include "lib/test/test-helper.hpp" +#include "lib/util.hpp" + +#include + + +using lumiera::error::LUMIERA_ERROR_INVALID; + + +namespace util { +namespace test { + + + class UtilParseBool_test : public Test + { + virtual void + run (Arg) + { + CHECK (boolVal ("true")); + CHECK (boolVal ("True")); + CHECK (boolVal ("TRUE")); + CHECK (boolVal ("yes")); + CHECK (boolVal ("Yes")); + CHECK (boolVal ("YES")); + CHECK (boolVal ("1")); + CHECK (boolVal ("+")); + + CHECK (not boolVal ("false")); + CHECK (not boolVal ("False")); + CHECK (not boolVal ("FALSE")); + CHECK (not boolVal ("no")); + CHECK (not boolVal ("No")); + CHECK (not boolVal ("NO")); + CHECK (not boolVal ("0")); + CHECK (not boolVal ("-")); + + CHECK (boolVal ("yes ")); + CHECK (boolVal (" Yes")); + CHECK (boolVal (" + ")); + CHECK (not boolVal (" \n0 ")); + + VERIFY_ERROR (INVALID, boolVal("") ); + VERIFY_ERROR (INVALID, boolVal(" ") ); + VERIFY_ERROR (INVALID, boolVal("yEs") ); + VERIFY_ERROR (INVALID, boolVal("tRuE") ); + VERIFY_ERROR (INVALID, boolVal("falsehood")); + VERIFY_ERROR (INVALID, boolVal("11") ); + VERIFY_ERROR (INVALID, boolVal("+1") ); + VERIFY_ERROR (INVALID, boolVal("↯") ); + + + CHECK (isYes ("true")); + CHECK (isYes ("True")); + CHECK (isYes ("TRUE")); + CHECK (isYes ("yes")); + CHECK (isYes ("Yes")); + CHECK (isYes ("1")); + CHECK (isYes ("+")); + + CHECK (isYes (" True ")); + CHECK (isYes (" \n\n 1 \t ")); + + CHECK (not isYes (" True and False")); + CHECK (not isYes ("tRuE")); + CHECK (not isYes ("+2")); + CHECK (not isYes ("no")); + CHECK (not isYes ("1010")); + CHECK (not isYes ("↯")); + CHECK (not isYes (" ")); + CHECK (not isYes ("")); + } + }; + + LAUNCHER (UtilParseBool_test, "unit common"); + + +}} // namespace util::test + diff --git a/tests/library/sanitised-identifier-test.cpp b/tests/library/util-sanitised-identifier-test.cpp similarity index 85% rename from tests/library/sanitised-identifier-test.cpp rename to tests/library/util-sanitised-identifier-test.cpp index 7d7ce6d18..cdfd9f05b 100644 --- a/tests/library/sanitised-identifier-test.cpp +++ b/tests/library/util-sanitised-identifier-test.cpp @@ -1,5 +1,5 @@ /* - SanitizedIdentifier(Test) - remove non-standard-chars and punctuation + UtilSanitizedIdentifier(Test) - remove non-standard-chars and punctuation Copyright (C) Lumiera.org 2008, Hermann Vosseler @@ -20,8 +20,8 @@ * *****************************************************/ -/** @file sanitised-identifier-test.cpp - ** unit test \ref SanitizedIdentifier_test +/** @file util-sanitised-identifier-test.cpp + ** unit test \ref UtilSanitizedIdentifier_test */ @@ -38,7 +38,7 @@ namespace util { namespace test { - class SanitizedIdentifier_test : public Test + class UtilSanitizedIdentifier_test : public Test { virtual void run (Arg) { @@ -60,7 +60,7 @@ namespace test { } }; - LAUNCHER (SanitizedIdentifier_test, "unit common"); + LAUNCHER (UtilSanitizedIdentifier_test, "unit common"); }} // namespace util::test diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 7be1572e7..4f616e56b 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -2962,8 +2962,8 @@ - - + + @@ -2978,7 +2978,7 @@ - + @@ -3419,7 +3419,9 @@ - + + + @@ -3536,12 +3538,21 @@ + + + + + + + + +