Switch.C 6.22 KB
Newer Older
Henry's avatar
Henry committed
1 2 3 4
/*---------------------------------------------------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     |
5
    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
6
     \\/     M anipulation  | Copyright (C) 2017-2019 OpenCFD Ltd.
Henry's avatar
Henry committed
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
-------------------------------------------------------------------------------
License
    This file is part of OpenFOAM.

    OpenFOAM 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 3 of the License, or
    (at your option) any later version.

    OpenFOAM 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 OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.

\*---------------------------------------------------------------------------*/

#include "Switch.H"
#include "error.H"
#include "dictionary.H"
29
#include "IOstreams.H"
Henry's avatar
Henry committed
30 31 32

// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //

33 34 35 36 37 38 39 40 41 42 43
namespace
{
static_assert
(
    Foam::Switch::INVALID+1 == 9,
    "Switch::switchType does not have 9 entries"
);

//- The names corresponding to the Switch::switchType enumeration.
//  Includes extra entries for "invalid".
static const char* names[9] =
Henry's avatar
Henry committed
44 45 46
{
    "false", "true",
    "no",    "yes",
47
    "off",   "on",
48
    "none",  "(unused)",
Henry's avatar
Henry committed
49 50 51
    "invalid"
};

52
} // End anonymous namespace
Henry's avatar
Henry committed
53 54 55

// * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //

56
Foam::Switch::switchType Foam::Switch::parse
Henry's avatar
Henry committed
57 58
(
    const std::string& str,
59
    bool allowBad
Henry's avatar
Henry committed
60 61
)
{
62
    switch (str.size())
Henry's avatar
Henry committed
63
    {
64
        case 1: // (f|n|t|y) - single-character forms
Henry's avatar
Henry committed
65
        {
66
            switch (str[0])
Henry's avatar
Henry committed
67
            {
68 69 70 71
                case 'f': return switchType::FALSE;
                case 'n': return switchType::NO;
                case 't': return switchType::TRUE;
                case 'y': return switchType::YES;
Henry's avatar
Henry committed
72
            }
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
            break;
        }
        case 2: // (no|on)
        {
            if (str == names[switchType::NO]) return switchType::NO;
            if (str == names[switchType::ON]) return switchType::ON;
            break;
        }
        case 3: // (off|yes)
        {
            if (str == names[switchType::OFF]) return switchType::OFF;
            if (str == names[switchType::YES]) return switchType::YES;
            break;
        }
        case 4: // (none|true)
        {
            if (str == names[switchType::NONE]) return switchType::NONE;
            if (str == names[switchType::TRUE]) return switchType::TRUE;
            break;
        }
        case 5: // (false)
        {
            if (str == names[switchType::FALSE]) return switchType::FALSE;
            break;
Henry's avatar
Henry committed
97 98 99
        }
    }

100
    if (!allowBad)
Henry's avatar
Henry committed
101
    {
102
        FatalErrorInFunction
103
            << "Unknown switch word " << str << nl
Henry's avatar
Henry committed
104 105 106
            << abort(FatalError);
    }

107
    return switchType::INVALID;
Henry's avatar
Henry committed
108 109 110 111 112 113 114
}


Foam::Switch Foam::Switch::lookupOrAddToDict
(
    const word& name,
    dictionary& dict,
Mark Olesen's avatar
Mark Olesen committed
115
    const Switch defaultValue
Henry's avatar
Henry committed
116 117 118 119 120 121
)
{
    return dict.lookupOrAddDefault<Switch>(name, defaultValue);
}


122 123
// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //

124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
Foam::Switch::Switch
(
    const word& key,
    const dictionary& dict
)
{
    const word str(dict.get<word>(key, keyType::LITERAL));

    (*this) = parse(str, true);

    if (!valid())
    {
        FatalIOErrorInFunction(dict)
            << "Expected 'true/false', 'on/off' ... found " << str << nl
            << exit(FatalIOError);
    }
}


Foam::Switch::Switch
(
    const word& key,
    const dictionary& dict,
    const Switch defaultValue
)
:
    Switch(defaultValue)
{
    const entry* eptr = dict.findEntry(key, keyType::LITERAL);

    if (eptr)
    {
        const word str(eptr->get<word>());

        (*this) = parse(str, true);

        if (!valid())
        {
            // Found entry, but was bad input

            FatalIOErrorInFunction(dict)
                << "Expected 'true/false', 'on/off' ... found " << str << nl
                << exit(FatalIOError);
        }
    }
}


172 173 174 175 176 177
Foam::Switch::Switch(Istream& is)
{
    is >> *this;
}


Henry's avatar
Henry committed
178 179
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //

180
bool Foam::Switch::valid() const noexcept
Henry's avatar
Henry committed
181
{
182 183 184 185 186 187 188 189 190 191
    return switch_ != switchType::INVALID;
}


Foam::Switch::switchType Foam::Switch::type() const noexcept
{
    return switchType(switch_);
}


192 193
const char* Foam::Switch::c_str() const noexcept
{
194
    return names[(switch_ & 0x0F)];
195 196 197 198
}


std::string Foam::Switch::str() const
Henry's avatar
Henry committed
199
{
200
    return names[(switch_ & 0x0F)];
Henry's avatar
Henry committed
201 202 203 204 205 206 207 208 209
}


bool Foam::Switch::readIfPresent(const word& name, const dictionary& dict)
{
    return dict.readIfPresent<Switch>(name, *this);
}


210 211 212 213 214 215 216 217
// * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //

Foam::Istream& Foam::operator>>(Istream& is, Switch& sw)
{
    token t(is);

    if (!t.good())
    {
218 219 220
        FatalIOErrorInFunction(is)
            << "Bad token - could not get bool"
            << exit(FatalIOError);
221 222 223 224 225 226 227 228 229 230
        is.setBad();
        return is;
    }

    if (t.isLabel())
    {
        sw = bool(t.labelToken());
    }
    else if (t.isWord())
    {
231
        // Permit invalid value, but catch immediately for better messages
232 233 234 235 236
        sw = Switch(t.wordToken(), true);

        if (!sw.valid())
        {
            FatalIOErrorInFunction(is)
237 238
                << "Expected 'true/false', 'on/off' ... found "
                << t.wordToken()
239
                << exit(FatalIOError);
240
            is.setBad();
241 242 243 244 245 246
            return is;
        }
    }
    else
    {
        FatalIOErrorInFunction(is)
247 248
            << "Wrong token type - expected bool, found "
            << t.info()
249
            << exit(FatalIOError);
250
        is.setBad();
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
        return is;
    }

    is.check(FUNCTION_NAME);
    return is;
}


Foam::Ostream& Foam::operator<<(Ostream& os, const Switch& sw)
{
    os << sw.c_str();
    return os;
}


Henry's avatar
Henry committed
266
// ************************************************************************* //