Remove Options::isSet()
[alexxy/gromacs.git] / src / gromacs / commandline / cmdlinemodulemanager.cpp
index 8fee8aa10e28ca0cef593bdd1b1d1a8ffc6410e5..83f35de08bb2b031c9ad2936cc81a686cf635a5d 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
 
 #include "cmdlinemodulemanager.h"
 
-#include "config.h"
-
 #include <cstdio>
 
 #include <string>
 #include <utility>
 
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
 #include "gromacs/commandline/cmdlinehelpcontext.h"
 #include "gromacs/commandline/cmdlineinit.h"
 #include "gromacs/commandline/cmdlinemodule.h"
 #include "gromacs/commandline/cmdlineparser.h"
 #include "gromacs/commandline/cmdlineprogramcontext.h"
 #include "gromacs/legacyheaders/copyrite.h"
+#include "gromacs/math/utilities.h"
 #include "gromacs/options/basicoptions.h"
 #include "gromacs/options/options.h"
 #include "gromacs/utility/basenetwork.h"
 #include "gromacs/utility/exceptions.h"
 #include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/futil.h"
 #include "gromacs/utility/gmxassert.h"
 #include "gromacs/utility/stringutil.h"
+#include "gromacs/utility/sysinfo.h"
 
 #include "cmdlinehelpmodule.h"
 #include "cmdlinemodulemanager-impl.h"
@@ -85,10 +82,10 @@ namespace
  */
 
 /*! \brief
- * Implements a CommandLineModuleInterface, given a function with C/C++ main()
+ * Implements a ICommandLineModule, given a function with C/C++ main()
  * signature.
  */
-class CMainCommandLineModule : public CommandLineModuleInterface
+class CMainCommandLineModule : public ICommandLineModule
 {
     public:
         //! \copydoc gmx::CommandLineModuleManager::CMainFunction
@@ -149,7 +146,8 @@ class CMainCommandLineModule : public CommandLineModuleInterface
 CommandLineCommonOptionsHolder::CommandLineCommonOptionsHolder()
     : options_(NULL, NULL), bHelp_(false), bHidden_(false),
       bQuiet_(false), bVersion_(false), bCopyright_(true),
-      niceLevel_(19), debugLevel_(0)
+      niceLevel_(19), bNiceSet_(false), bBackup_(true), bFpexcept_(false),
+      debugLevel_(0)
 {
     binaryInfoSettings_.copyright(true);
 }
@@ -171,8 +169,12 @@ void CommandLineCommonOptionsHolder::initOptions()
                            .description("Print extended version information and quit"));
     options_.addOption(BooleanOption("copyright").store(&bCopyright_)
                            .description("Print copyright information on startup"));
-    options_.addOption(IntegerOption("nice").store(&niceLevel_)
+    options_.addOption(IntegerOption("nice").store(&niceLevel_).storeIsSet(&bNiceSet_)
                            .description("Set the nicelevel (default depends on command)"));
+    options_.addOption(BooleanOption("backup").store(&bBackup_)
+                           .description("Write backups if output files exist"));
+    options_.addOption(BooleanOption("fpexcept").store(&bFpexcept_)
+                           .hidden().description("Enable floating-point exceptions"));
     options_.addOption(IntegerOption("debug").store(&debugLevel_)
                            .hidden().defaultValueIfSet(1)
                            .description("Write file with debug information, "
@@ -192,7 +194,7 @@ bool CommandLineCommonOptionsHolder::finishOptions()
 void CommandLineCommonOptionsHolder::adjustFromSettings(
         const CommandLineModuleSettings &settings)
 {
-    if (!options_.isSet("nice"))
+    if (!bNiceSet_)
     {
         niceLevel_ = settings.defaultNiceLevel();
     }
@@ -245,24 +247,6 @@ class CommandLineModuleManager::Impl
          */
         CommandLineModuleMap::const_iterator
         findModuleByName(const std::string &name) const;
-        /*! \brief
-         * Finds a module that the name of the binary.
-         *
-         * \param[in] invokedName  Name by which the program was invoked.
-         * \throws    std::bad_alloc if out of memory.
-         * \returns   Iterator to the found module, or
-         *      \c modules_.end() if not found.
-         *
-         * Checks whether the program is invoked through a symlink whose name
-         * is different from \a binaryName_, and if so, checks
-         * if a module name matches the name of the symlink.
-         *
-         * Note that the \p invokedName parameter is currently not necessary
-         * (as the program context object is also available and provides this
-         * value), but it clarifies the control flow.
-         */
-        CommandLineModuleMap::const_iterator
-        findModuleFromBinaryName(const char *invokedName) const;
 
         /*! \brief
          * Processes command-line options for the wrapper binary.
@@ -280,7 +264,7 @@ class CommandLineModuleManager::Impl
          * options).  Also finds the module that should be run and the
          * arguments that should be passed to it.
          */
-        CommandLineModuleInterface *
+        ICommandLineModule *
         processCommonOptions(CommandLineCommonOptionsHolder *optionsHolder,
                              int *argc, char ***argv);
 
@@ -309,7 +293,7 @@ class CommandLineModuleManager::Impl
          */
         CommandLineHelpModule       *helpModule_;
         //! If non-NULL, run this module in single-module mode.
-        CommandLineModuleInterface  *singleModule_;
+        ICommandLineModule          *singleModule_;
         //! Stores the value set with setQuiet().
         bool                         bQuiet_;
 
@@ -336,7 +320,7 @@ void CommandLineModuleManager::Impl::addModule(CommandLineModulePointer module)
     HelpTopicPointer helpTopic(helpModule_->createModuleHelpTopic(*module));
     modules_.insert(std::make_pair(std::string(module->name()),
                                    move(module)));
-    helpModule_->addTopic(move(helpTopic));
+    helpModule_->addTopic(move(helpTopic), false);
 }
 
 void CommandLineModuleManager::Impl::ensureHelpModuleExists()
@@ -356,45 +340,12 @@ CommandLineModuleManager::Impl::findModuleByName(const std::string &name) const
     return modules_.find(name);
 }
 
-CommandLineModuleMap::const_iterator
-CommandLineModuleManager::Impl::findModuleFromBinaryName(
-        const char *invokedName) const
-{
-    std::string moduleName = invokedName;
-#ifdef GMX_BINARY_SUFFIX
-    moduleName = stripSuffixIfPresent(moduleName, GMX_BINARY_SUFFIX);
-#endif
-    if (moduleName == binaryName_)
-    {
-        return modules_.end();
-    }
-    if (startsWith(moduleName, "g_"))
-    {
-        moduleName.erase(0, 2);
-    }
-    if (startsWith(moduleName, "gmx"))
-    {
-        moduleName.erase(0, 3);
-    }
-    return findModuleByName(moduleName);
-}
-
-CommandLineModuleInterface *
+ICommandLineModule *
 CommandLineModuleManager::Impl::processCommonOptions(
         CommandLineCommonOptionsHolder *optionsHolder, int *argc, char ***argv)
 {
     // Check if we are directly invoking a certain module.
-    CommandLineModuleInterface *module = singleModule_;
-    if (module == NULL)
-    {
-        // Also check for invokation through named symlinks.
-        CommandLineModuleMap::const_iterator moduleIter
-            = findModuleFromBinaryName(programContext_.programName());
-        if (moduleIter != modules_.end())
-        {
-            module = moduleIter->second.get();
-        }
-    }
+    ICommandLineModule *module = singleModule_;
 
     // TODO: It would be nice to propagate at least the -quiet option to
     // the modules so that they can also be quiet in response to this.
@@ -486,13 +437,14 @@ void CommandLineModuleManager::setQuiet(bool bQuiet)
     impl_->bQuiet_ = bQuiet;
 }
 
-void CommandLineModuleManager::setOutputRedirect(File *output)
+void CommandLineModuleManager::setOutputRedirector(
+        IFileOutputRedirector *output)
 {
     impl_->ensureHelpModuleExists();
-    impl_->helpModule_->setOutputRedirect(output);
+    impl_->helpModule_->setOutputRedirector(output);
 }
 
-void CommandLineModuleManager::setSingleModule(CommandLineModuleInterface *module)
+void CommandLineModuleManager::setSingleModule(ICommandLineModule *module)
 {
     impl_->singleModule_ = module;
 }
@@ -524,12 +476,12 @@ CommandLineModuleGroup CommandLineModuleManager::addModuleGroup(
 void CommandLineModuleManager::addHelpTopic(HelpTopicPointer topic)
 {
     impl_->ensureHelpModuleExists();
-    impl_->helpModule_->addTopic(move(topic));
+    impl_->helpModule_->addTopic(move(topic), true);
 }
 
 int CommandLineModuleManager::run(int argc, char *argv[])
 {
-    CommandLineModuleInterface    *module;
+    ICommandLineModule            *module;
     const bool                     bMaster = (gmx_node_rank() == 0);
     bool                           bQuiet  = impl_->bQuiet_ || !bMaster;
     CommandLineCommonOptionsHolder optionsHolder;
@@ -565,6 +517,8 @@ int CommandLineModuleManager::run(int argc, char *argv[])
     module->init(&settings);
     optionsHolder.adjustFromSettings(settings);
 
+    gmx_set_max_backup_count(optionsHolder.shouldBackup() ? -1 : 0);
+
     // Open the debug file.
     if (optionsHolder.debugLevel() > 0)
     {
@@ -578,21 +532,22 @@ int CommandLineModuleManager::run(int argc, char *argv[])
         fprintf(stderr, "Will write debug log file: %s\n", filename.c_str());
         gmx_init_debug(optionsHolder.debugLevel(), filename.c_str());
     }
-#if defined(HAVE_UNISTD_H) && !defined(GMX_NO_NICE) && !defined(__MINGW32__)
     // Set the nice level unless disabled in the configuration.
     if (optionsHolder.niceLevel() != 0)
     {
         static bool bNiceSet = false; // Only set it once.
         if (!bNiceSet)
         {
-            if (nice(optionsHolder.niceLevel()) == -1)
-            {
-                // Do nothing, but use the return value to avoid warnings.
-            }
+            // TODO: Diagnostic if this fails and the user explicitly requested it.
+            gmx_set_nice(optionsHolder.niceLevel());
             bNiceSet = true;
         }
     }
-#endif
+    if (optionsHolder.enableFPExceptions())
+    {
+        //TODO: currently it is always enabled for mdrun (verlet) and tests.
+        gmx_feenableexcept();
+    }
 
     int rc = 0;
     if (!(module == impl_->helpModule_ && !bMaster))
@@ -608,7 +563,7 @@ int CommandLineModuleManager::run(int argc, char *argv[])
 
 // static
 int CommandLineModuleManager::runAsMainSingleModule(
-        int argc, char *argv[], CommandLineModuleInterface *module)
+        int argc, char *argv[], ICommandLineModule *module)
 {
     CommandLineProgramContext &programContext = gmx::initForCommandLine(&argc, &argv);
     try
@@ -622,7 +577,7 @@ int CommandLineModuleManager::runAsMainSingleModule(
     catch (const std::exception &ex)
     {
         printFatalErrorMessage(stderr, ex);
-        return processExceptionAtExit(ex);
+        return processExceptionAtExitForCommandLine(ex);
     }
 }