Sort all includes in src/gromacs
[alexxy/gromacs.git] / src / gromacs / commandline / cmdlinemodulemanager.h
index c6dcbdcfe9f8b777097ffec6e224aeb7d54fc132..62b39488ca28461e37673d088c16cbd36b9bc236 100644 (file)
@@ -1,10 +1,10 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2012,2013, by the GROMACS development team, led by
- * David van der Spoel, Berk Hess, Erik Lindahl, and including many
- * others, as listed in the AUTHORS file in the top-level source
- * directory and at http://www.gromacs.org.
+ * Copyright (c) 2012,2013,2014, 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.
  *
  * GROMACS is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
  * To help us fund GROMACS development, we humbly ask that you cite
  * the research papers on the package. Check out http://www.gromacs.org.
  */
-/*! \file
+/*! \libinternal \file
  * \brief
  * Declares gmx::CommandLineModuleManager.
  *
  * \author Teemu Murtola <teemu.murtola@gmail.com>
- * \inpublicapi
+ * \inlibraryapi
  * \ingroup module_commandline
  */
 #ifndef GMX_COMMANDLINE_CMDLINEMODULEMANAGER_H
 #define GMX_COMMANDLINE_CMDLINEMODULEMANAGER_H
 
-#include "../onlinehelp/helptopicinterface.h"
-#include "../utility/common.h"
-#include "../utility/uniqueptr.h"
+#include "gromacs/onlinehelp/helptopicinterface.h"
+#include "gromacs/utility/common.h"
+#include "gromacs/utility/uniqueptr.h"
 
 namespace gmx
 {
 
+class CommandLineModuleGroup;
+class CommandLineModuleGroupData;
 class CommandLineModuleInterface;
-class ProgramInfo;
+class CommandLineProgramContext;
+class File;
+
+//! \addtogroup module_commandline
+//! \{
 
 //! Smart pointer type for managing a CommandLineModuleInterface.
 typedef gmx_unique_ptr<CommandLineModuleInterface>::type
     CommandLineModulePointer;
 
-/*! \brief
+/*! \libinternal \brief
  * Implements a wrapper command-line interface for multiple modules.
  *
  * Typical usage:
  * \code
    int main(int argc, char *argv[])
    {
-       gmx::ProgramInfo &programInfo = gmx::init("gmx", &argc, &argv);
+       gmx::CommandLineProgramContext &programContext = gmx::initForCommandLine(&argc, &argv);
        try
        {
-           gmx::CommandLineModuleManager manager(&programInfo);
+           gmx::CommandLineModuleManager manager("gmx", &programContext);
            // <register all necessary modules>
            int rc = manager.run(argc, argv);
-           gmx::finalize();
+           gmx::finalizeForCommandLine();
            return rc;
        }
        catch (const std::exception &ex)
@@ -81,8 +87,8 @@ typedef gmx_unique_ptr<CommandLineModuleInterface>::type
    }
  * \endcode
  *
- * \inpublicapi
- * \ingroup module_commandline
+ * \see page_wrapperbinary
+ * \inlibraryapi
  */
 class CommandLineModuleManager
 {
@@ -157,16 +163,19 @@ class CommandLineModuleManager
         /*! \brief
          * Initializes a command-line module manager.
          *
-         * \param     programInfo  Program information for the running binary.
+         * \param[in] binaryName     Name of the running binary
+         *     (without Gromacs binary suffix or .exe on Windows).
+         * \param     programContext Program information for the running binary.
          * \throws    std::bad_alloc if out of memory.
          *
-         * The binary name is used to detect when the binary is run through a
+         * \p binaryName is used to detect when the binary is run through a
          * symlink, and automatically invoke a matching module in such a case.
          *
          * \p programInfo is non-const to allow the manager to amend it based
          * on the actual module that is getting executed.
          */
-        explicit CommandLineModuleManager(ProgramInfo *programInfo);
+        CommandLineModuleManager(const char                *binaryName,
+                                 CommandLineProgramContext *programContext);
         ~CommandLineModuleManager();
 
         /*! \brief
@@ -174,13 +183,45 @@ class CommandLineModuleManager
          *
          * \param[in] bQuiet  Whether the module manager should remain silent.
          *
-         * Normally, the module manager prints out some information to stderr
+         * Normally, the module manager prints out some information to `stderr`
          * before it starts the module and after it finishes.  This removes
          * that output, which is useful in particular for unit tests so that
-         * they don't spam stderr.
+         * they don't spam `stderr`.
          */
         void setQuiet(bool bQuiet);
+        /*! \brief
+         * Redirects the output of the module manager to a file.
+         *
+         * \param[in] output  File to write the output to.
+         *
+         * Normally, the module manager prints explicitly requested text such
+         * as help output to `stdout`, but this method can be used to redirect
+         * that output to a file.  This is used for unit tests, either to keep
+         * them quiet or to verify that output.  To keep implementation options
+         * open, behavior with `output == NULL` is undefined and should not be
+         * relied on.  For tests, there should only be need to call this a
+         * single time, right after creating the manager.
+         */
+        void setOutputRedirect(File *output);
 
+        /*! \brief
+         * Makes the manager always run a single module.
+         *
+         * \param     module  Module to run.
+         *
+         * This method disables all mechanisms for selecting a module, and
+         * directly passes all command-line arguments to \p module.
+         * Help arguments are an exception: these are still recognized by the
+         * manager and translated into a call to
+         * CommandLineModuleInterface::writeHelp().
+         *
+         * This is public mainly for unit testing purposes; for other code,
+         * runAsMainSingleModule() typically provides the desired
+         * functionality.
+         *
+         * Does not throw.
+         */
+        void setSingleModule(CommandLineModuleInterface *module);
         /*! \brief
          * Adds a given module to this manager.
          *
@@ -235,7 +276,20 @@ class CommandLineModuleManager
         }
 
         /*! \brief
-         * Make given help topic available through the manager's help module.
+         * Adds a group for modules to use in help output.
+         *
+         * \param[in] title  Short title for the group.
+         * \returns   Handle that can be used to add modules to the group.
+         * \throws    std::bad_alloc if out of memory.
+         *
+         * Creates a group that is used to structure the list of all modules in
+         * help output.  Modules are added to the group using the returned
+         * object.
+         */
+        CommandLineModuleGroup addModuleGroup(const char *title);
+
+        /*! \brief
+         * Makes given help topic available through the manager's help module.
          *
          * \param[in]  topic  Help topic to add.
          * \throws     std::bad_alloc if out of memory.
@@ -265,6 +319,59 @@ class CommandLineModuleManager
         PrivateImplPointer<Impl> impl_;
 };
 
+/*! \libinternal \brief
+ * Handle to add content to a group added with
+ * CommandLineModuleManager::addModuleGroup().
+ *
+ * This class only provides a public interface to construct a module group for
+ * CommandLineModuleManager, and has semantics similar to a pointer: copies all
+ * point to the same group.  The actual state of the group is maintained in an
+ * internal implementation class.
+ *
+ * \inlibraryapi
+ */
+class CommandLineModuleGroup
+{
+    public:
+        /*! \cond internal */
+        //! Shorthand for the implementation type that holds all the data.
+        typedef CommandLineModuleGroupData Impl;
+
+        //! Creates a new group (only called by CommandLineModuleManager).
+        explicit CommandLineModuleGroup(Impl *impl) : impl_(impl) {}
+        //! \endcond
+
+        /*! \brief
+         * Adds a module to this group.
+         *
+         * \param[in] name  Name of the module.
+         * \throws    std::bad_alloc if out of memory.
+         *
+         * This works as addModuleWithDescription(), but uses the short
+         * description of the module itself as the description.
+         *
+         * \see addModuleWithDescription()
+         */
+        void addModule(const char *name);
+        /*! \brief
+         * Adds a module to this group with a custom description.
+         *
+         * \param[in] name        Name of the module.
+         * \param[in] description Description of the module in this group.
+         * \throws    std::bad_alloc if out of memory.
+         *
+         * \p name must name a module added into the CommandLineModuleManager.
+         * It is possible to add the same module into multiple groups.
+         */
+        void addModuleWithDescription(const char *name, const char *description);
+
+    private:
+        //! Pointer to the data owned by CommandLineModuleManager.
+        Impl                     *impl_;
+};
+
+//! \}
+
 } // namespace gmx
 
 #endif