From 13f04876894ac8a2132c5661c59de09bbc4e4e4c Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Thu, 21 Sep 2017 16:53:46 +0200
Subject: [PATCH] ENH: improve input stringency for argList options

Previously:

  - bad command-line input such as -label 1234xyz would parse as a
    label (with value 1234) and the trailing junk would be silently
    ignored. This may or may not be appropriate. If the trailing junk
    looked like this '100E' or '1000E-' (ie, forgot to type the
    exponent), the incorrectly parsed values can be quite bad:

        label  = 32684
        scalar = 6.93556e-310

Now:

  - use the updated readLabel/readScalar routines that trigger a
    FatalIOError on bad input:

        --> FOAM FATAL IO ERROR:
        Trailing content found parsing '1234xyz'

        --> FOAM FATAL IO ERROR:
        Trailing content found parsing '100E'

   This traps erroneous command-line input immediately.
---
 applications/test/argList/Make/files          |  3 +
 applications/test/argList/Make/options        |  2 +
 applications/test/argList/Test-argList.C      | 80 +++++++++++++++++++
 .../conversion/plot3dToFoam/plot3dToFoam.C    |  4 +-
 src/OpenFOAM/global/argList/argList.H         | 12 +--
 src/OpenFOAM/global/argList/argListI.H        | 55 ++++++++++---
 6 files changed, 136 insertions(+), 20 deletions(-)
 create mode 100644 applications/test/argList/Make/files
 create mode 100644 applications/test/argList/Make/options
 create mode 100644 applications/test/argList/Test-argList.C

diff --git a/applications/test/argList/Make/files b/applications/test/argList/Make/files
new file mode 100644
index 0000000000..f1d558cc1c
--- /dev/null
+++ b/applications/test/argList/Make/files
@@ -0,0 +1,3 @@
+Test-argList.C
+
+EXE = $(FOAM_USER_APPBIN)/Test-argList
diff --git a/applications/test/argList/Make/options b/applications/test/argList/Make/options
new file mode 100644
index 0000000000..6a9e9810b3
--- /dev/null
+++ b/applications/test/argList/Make/options
@@ -0,0 +1,2 @@
+/* EXE_INC = -I$(LIB_SRC)/cfdTools/include */
+/* EXE_LIBS = -lfiniteVolume */
diff --git a/applications/test/argList/Test-argList.C b/applications/test/argList/Test-argList.C
new file mode 100644
index 0000000000..50763f15af
--- /dev/null
+++ b/applications/test/argList/Test-argList.C
@@ -0,0 +1,80 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2017 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+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/>.
+
+Description
+
+\*---------------------------------------------------------------------------*/
+
+#include "argList.H"
+#include "IOstreams.H"
+#include "StringStream.H"
+
+using namespace Foam;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// Main program:
+
+int main(int argc, char *argv[])
+{
+    argList::noBanner();
+    argList::noParallel();
+    argList::noFunctionObjects();
+    argList::removeOption("case");
+
+    argList::addOption("label", "value", "Test parsing of label");
+    argList::addOption("scalar", "value", "Test parsing of scalar");
+
+    argList args(argc, argv);
+
+    label ival;
+    scalar sval;
+
+    Info<< nl;
+
+    Info<< "-label = " << flush;
+    if (args.optionReadIfPresent("label", ival))
+    {
+        Info<< ival << endl;
+    }
+    else
+    {
+        Info<< "not specified" << endl;
+    }
+
+    Info<< "-scalar = " << flush;
+    if (args.optionReadIfPresent("scalar", sval))
+    {
+        Info<< sval << endl;
+    }
+    else
+    {
+        Info<< "not specified" << endl;
+    }
+
+    Info<< "\nEnd\n" << endl;
+
+    return 0;
+}
+
+
+// ************************************************************************* //
diff --git a/applications/utilities/mesh/conversion/plot3dToFoam/plot3dToFoam.C b/applications/utilities/mesh/conversion/plot3dToFoam/plot3dToFoam.C
index e4b5e8b4e8..cc24941602 100644
--- a/applications/utilities/mesh/conversion/plot3dToFoam/plot3dToFoam.C
+++ b/applications/utilities/mesh/conversion/plot3dToFoam/plot3dToFoam.C
@@ -93,8 +93,8 @@ int main(int argc, char *argv[])
 
     const scalar scaleFactor = args.optionLookupOrDefault("scale", 1.0);
 
-    bool readBlank = !args.optionFound("noBlank");
-    bool singleBlock = args.optionFound("singleBlock");
+    const bool readBlank = !args.optionFound("noBlank");
+    const bool singleBlock = args.optionFound("singleBlock");
     scalar twoDThickness = -1;
     if (args.optionReadIfPresent("2D", twoDThickness))
     {
diff --git a/src/OpenFOAM/global/argList/argList.H b/src/OpenFOAM/global/argList/argList.H
index b60cd9fa13..cba9bb009f 100644
--- a/src/OpenFOAM/global/argList/argList.H
+++ b/src/OpenFOAM/global/argList/argList.H
@@ -281,10 +281,10 @@ public:
             inline T argRead(const label index) const;
 
             //- Return options
-            inline const Foam::HashTable<string>& options() const;
+            inline const HashTable<string>& options() const;
 
             //- Return non-const access to options
-            inline Foam::HashTable<string>& options();
+            inline HashTable<string>& options();
 
             //- Return the argument string associated with the named option
             inline const string& option(const word& opt) const;
@@ -302,7 +302,7 @@ public:
             //- Read a value from the named option if present.
             //  Return true if the named option was found.
             template<class T>
-            inline bool optionReadIfPresent(const word& opt, T&) const;
+            inline bool optionReadIfPresent(const word& opt, T& val) const;
 
             //- Read a value from the named option if present.
             //  Return true if the named option was found, otherwise
@@ -311,7 +311,7 @@ public:
             inline bool optionReadIfPresent
             (
                 const word& opt,
-                T&,
+                T& val,
                 const T& deflt
             ) const;
 
@@ -328,7 +328,7 @@ public:
             template<class T>
             List<T> optionReadList(const word& opt) const
             {
-                return readList<T>(optionLookup(opt)());
+                return Foam::readList<T>(optionLookup(opt)());
             }
 
 
@@ -369,7 +369,7 @@ public:
 
             //- Add extra notes for the usage information
             //  This string is used "as-is" without additional formatting
-            static void addNote(const string&);
+            static void addNote(const string& note);
 
             //- Remove option from validOptions and from optionUsage
             static void removeOption(const word& opt);
diff --git a/src/OpenFOAM/global/argList/argListI.H b/src/OpenFOAM/global/argList/argListI.H
index 28caff6acb..4f1b5fdf8d 100644
--- a/src/OpenFOAM/global/argList/argListI.H
+++ b/src/OpenFOAM/global/argList/argListI.H
@@ -127,53 +127,84 @@ inline Foam::IStringStream Foam::argList::optionLookup(const word& opt) const
 
 namespace Foam
 {
-    // Template specialization for string
+    //
+    // Specializations for argRead
+    //
+
     template<>
     inline Foam::string
-    Foam::argList::argRead<Foam::string>(const label index) const
+    argList::argRead<Foam::string>(const label index) const
     {
         return args_[index];
     }
 
-    // Template specialization for word
     template<>
     inline Foam::word
-    Foam::argList::argRead<Foam::word>(const label index) const
+    argList::argRead<Foam::word>(const label index) const
     {
         return args_[index];
     }
 
-    // Template specialization for fileName
     template<>
     inline Foam::fileName
-    Foam::argList::argRead<Foam::fileName>(const label index) const
+    argList::argRead<Foam::fileName>(const label index) const
     {
         return args_[index];
     }
 
-    // Template specialization for string
+    template<>
+    inline Foam::label
+    argList::argRead<Foam::label>(const label index) const
+    {
+        return Foam::readLabel(args_[index]);
+    }
+
+    template<>
+    inline Foam::scalar
+    argList::argRead<Foam::scalar>(const label index) const
+    {
+        return Foam::readScalar(args_[index]);
+    }
+
+    //
+    // Specializations for optionRead
+    //
+
     template<>
     inline Foam::string
-    Foam::argList::optionRead<Foam::string>(const word& opt) const
+    argList::optionRead<Foam::string>(const word& opt) const
     {
         return options_[opt];
     }
 
-    // Template specialization for word
     template<>
     inline Foam::word
-    Foam::argList::optionRead<Foam::word>(const word& opt) const
+    argList::optionRead<Foam::word>(const word& opt) const
     {
         return options_[opt];
     }
 
-    // Template specialization for fileName
     template<>
     inline Foam::fileName
-    Foam::argList::optionRead<Foam::fileName>(const word& opt) const
+    argList::optionRead<Foam::fileName>(const word& opt) const
     {
         return options_[opt];
     }
+
+    template<>
+    inline Foam::label
+    argList::optionRead<Foam::label>(const word& opt) const
+    {
+        return Foam::readLabel(options_[opt]);
+    }
+
+    template<>
+    inline Foam::scalar
+    argList::optionRead<Foam::scalar>(const word& opt) const
+    {
+        return Foam::readScalar(options_[opt]);
+    }
+
 }
 
 
-- 
GitLab