--- /dev/null
+/*
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * GROningen MAchine for Chemical Simulations
+ *
+ * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2009, The GROMACS development team,
+ * check out http://www.gromacs.org for more information.
+
+ * 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.
+ *
+ * If you want to redistribute modifications, please consider that
+ * scientific software is very special. Version control is crucial -
+ * bugs must be traceable. We will be happy to consider code for
+ * inclusion in the official distribution, but derived work must not
+ * be called official GROMACS. Details are found in the README & COPYING
+ * files - if they are missing, get the official version at www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the papers on the package - you can find them in the top README file.
+ *
+ * For more info, check our website at http://www.gromacs.org
+ */
+/*! \file
+ * \brief
+ * Declares gmx::CommandLineModuleInterface.
+ *
+ * \author Teemu Murtola <teemu.murtola@cbr.su.se>
+ * \inpublicapi
+ * \ingroup module_commandline
+ */
+#ifndef GMX_COMMANDLINE_CMDLINEMODULE_H
+#define GMX_COMMANDLINE_CMDLINEMODULE_H
+
+namespace gmx
+{
+
+/*! \brief
+ * Module that can be run from command line using CommandLineModuleManager.
+ *
+ * \see CommandLineModuleManager
+ *
+ * \inpublicapi
+ * \ingroup module_commandline
+ */
+class CommandLineModuleInterface
+{
+ public:
+ virtual ~CommandLineModuleInterface() {}
+
+ //! Returns the name of the module.
+ virtual const char *name() const = 0;
+
+ /*! \brief
+ * Runs the module with the given arguments.
+ *
+ * \param[in] argc Number of elements in \p argv.
+ * \param[in] argv Command-line arguments.
+ * \throws unspecified May throw exceptions to indicate errors.
+ * \returns Exit code for the program.
+ * \retval 0 on successful termination.
+ *
+ * \p argv[0] is the name of the module, i.e., the arguments are as if
+ * the module was run as a standalone executable.
+ */
+ virtual int run(int argc, char *argv[]) = 0;
+};
+
+} // namespace gmx
+
+#endif
--- /dev/null
+/*
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * GROningen MAchine for Chemical Simulations
+ *
+ * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2009, The GROMACS development team,
+ * check out http://www.gromacs.org for more information.
+
+ * 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.
+ *
+ * If you want to redistribute modifications, please consider that
+ * scientific software is very special. Version control is crucial -
+ * bugs must be traceable. We will be happy to consider code for
+ * inclusion in the official distribution, but derived work must not
+ * be called official GROMACS. Details are found in the README & COPYING
+ * files - if they are missing, get the official version at www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the papers on the package - you can find them in the top README file.
+ *
+ * For more info, check our website at http://www.gromacs.org
+ */
+/*! \internal \file
+ * \brief
+ * Implements gmx::CommandLineModuleManager.
+ *
+ * \author Teemu Murtola <teemu.murtola@cbr.su.se>
+ * \ingroup module_commandline
+ */
+#include "cmdlinemodulemanager.h"
+
+#include <cstdio>
+
+#include <map>
+#include <string>
+#include <utility>
+
+#include "gromacs/legacyheaders/statutil.h"
+
+#include "gromacs/commandline/cmdlinemodule.h"
+#include "gromacs/utility/gmxassert.h"
+
+namespace gmx
+{
+
+/********************************************************************
+ * CommandLineModuleManager::Impl
+ */
+
+/*! \internal \brief
+ * Private implementation class for CommandLineModuleManager.
+ *
+ * \ingroup module_commandline
+ */
+class CommandLineModuleManager::Impl
+{
+ public:
+ //! Container for mapping module names to module objects.
+ typedef std::map<std::string, CommandLineModulePointer> ModuleMap;
+
+ //! Prints usage message to stderr.
+ void printUsage() const;
+
+ /*! \brief
+ * Maps module names to module objects.
+ *
+ * Owns the contained modules.
+ */
+ ModuleMap modules_;
+};
+
+void CommandLineModuleManager::Impl::printUsage() const
+{
+ fprintf(stderr, "Usage: %s <command> [<args>]\n",
+ ShortProgram());
+}
+
+/********************************************************************
+ * CommandLineModuleManager
+ */
+
+CommandLineModuleManager::CommandLineModuleManager()
+ : impl_(new Impl)
+{
+}
+
+CommandLineModuleManager::~CommandLineModuleManager()
+{
+}
+
+void CommandLineModuleManager::addModule(CommandLineModulePointer module)
+{
+ GMX_ASSERT(impl_->modules_.find(module->name()) == impl_->modules_.end(),
+ "Attempted to register a duplicate module name");
+ impl_->modules_.insert(std::make_pair(std::string(module->name()),
+ move(module)));
+}
+
+int CommandLineModuleManager::run(int argc, char *argv[])
+{
+ if (argc < 2)
+ {
+ fprintf(stderr, "\n");
+ impl_->printUsage();
+ return 2;
+ }
+ // TODO: Accept unambiguous prefixes?
+ Impl::ModuleMap::const_iterator module = impl_->modules_.find(argv[1]);
+ if (module == impl_->modules_.end())
+ {
+ fprintf(stderr, "\n");
+ fprintf(stderr, "Unknown command: %s\n", argv[1]);
+ impl_->printUsage();
+ return 2;
+ }
+ return module->second->run(argc - 1, argv + 1);
+}
+
+} // namespace gmx
--- /dev/null
+/*
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * GROningen MAchine for Chemical Simulations
+ *
+ * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2009, The GROMACS development team,
+ * check out http://www.gromacs.org for more information.
+
+ * 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.
+ *
+ * If you want to redistribute modifications, please consider that
+ * scientific software is very special. Version control is crucial -
+ * bugs must be traceable. We will be happy to consider code for
+ * inclusion in the official distribution, but derived work must not
+ * be called official GROMACS. Details are found in the README & COPYING
+ * files - if they are missing, get the official version at www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the papers on the package - you can find them in the top README file.
+ *
+ * For more info, check our website at http://www.gromacs.org
+ */
+/*! \file
+ * \brief
+ * Declares gmx::CommandLineModuleManager.
+ *
+ * \author Teemu Murtola <teemu.murtola@cbr.su.se>
+ * \inpublicapi
+ * \ingroup module_commandline
+ */
+#ifndef GMX_COMMANDLINE_CMDLINEMODULEMANAGER_H
+#define GMX_COMMANDLINE_CMDLINEMODULEMANAGER_H
+
+#include "../utility/common.h"
+#include "../utility/uniqueptr.h"
+
+namespace gmx
+{
+
+class CommandLineModuleInterface;
+
+//! Smart pointer type for managing a CommandLineModuleInterface.
+typedef gmx_unique_ptr<CommandLineModuleInterface>::type
+ CommandLineModulePointer;
+
+/*! \brief
+ * Implements a wrapper command-line interface for multiple modules.
+ *
+ * Typical usage:
+ * \code
+int
+main(int argc, char *argv[])
+{
+ CopyRight(stderr, argv[0]);
+ try
+ {
+ gmx::CommandLineModuleManager manager;
+ // <register all necessary modules>
+ return manager.run(argc, argv);
+ }
+ catch (const std::exception &ex)
+ {
+ fprintf(stderr, "%s", gmx::formatErrorMessage(ex).c_str());
+ return 1;
+ }
+}
+ * \endcode
+ *
+ * \inpublicapi
+ * \ingroup module_commandline
+ */
+class CommandLineModuleManager
+{
+ public:
+ CommandLineModuleManager();
+ ~CommandLineModuleManager();
+
+ /*! \brief
+ * Adds a given module to this manager.
+ *
+ * \param module Module to add.
+ * \throws std::bad_alloc if out of memory.
+ *
+ * The manager takes ownership of the object.
+ *
+ * This method is public mostly for testing purposes; for typical uses,
+ * registerModule() is a more convenient way of adding modules.
+ *
+ * \see registerModule()
+ */
+ void addModule(CommandLineModulePointer module);
+ /*! \brief
+ * Registers a module of a certain type to this manager.
+ *
+ * \tparam Module Type of module to register.
+ * \throws std::bad_alloc if out of memory.
+ *
+ * \p Module must be default-constructible and implement
+ * CommandLineModuleInterface.
+ *
+ * This method is provided as a convenient alternative to addModule()
+ * for cases where each module is implemented by a different type
+ * (which should be the case for typical situations outside unit
+ * tests).
+ */
+ template <class Module>
+ void registerModule()
+ {
+ addModule(CommandLineModulePointer(new Module));
+ }
+
+ /*! \brief
+ * Runs a module based on given command line.
+ *
+ * \param[in] argc Number of elements in \p argv.
+ * \param[in] argv Command-line arguments.
+ * \throws unspecified Throws any exception that the selected module
+ * throws.
+ * \returns Exit code for the program.
+ * \retval 0 on successful termination.
+ * \retval 2 if no module is specified, or if the module is not found.
+ *
+ * Runs the module whose name matches \p argv[1].
+ */
+ int run(int argc, char *argv[]);
+
+ private:
+ class Impl;
+
+ PrivateImplPointer<Impl> impl_;
+};
+
+} // namespace gmx
+
+#endif
if (TESTUTILS_HAVE_REFDATA)
- add_gtest_test(CommandLineUnitTests commandline-test
- cmdlinehelpwriter.cpp
- cmdlineparser.cpp
- cmdlinetest.cpp)
+ add_gtest_or_gmock_test(CommandLineUnitTests commandline-test
+ cmdlinehelpwriter.cpp
+ cmdlineparser.cpp
+ cmdlinetest.cpp
+ GMOCK_ONLY
+ cmdlinemodulemanager.cpp)
endif ()
--- /dev/null
+/*
+ *
+ * This source code is part of
+ *
+ * G R O M A C S
+ *
+ * GROningen MAchine for Chemical Simulations
+ *
+ * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2009, The GROMACS development team,
+ * check out http://www.gromacs.org for more information.
+
+ * 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.
+ *
+ * If you want to redistribute modifications, please consider that
+ * scientific software is very special. Version control is crucial -
+ * bugs must be traceable. We will be happy to consider code for
+ * inclusion in the official distribution, but derived work must not
+ * be called official GROMACS. Details are found in the README & COPYING
+ * files - if they are missing, get the official version at www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the papers on the package - you can find them in the top README file.
+ *
+ * For more info, check our website at http://www.gromacs.org
+ */
+/*! \internal \file
+ * \brief
+ * Tests gmx::CommandLineModuleManager.
+ *
+ * \author Teemu Murtola <teemu.murtola@cbr.su.se>
+ * \ingroup module_commandline
+ */
+#include <vector>
+
+#include <gmock/gmock.h>
+
+#include "gromacs/commandline/cmdlinemodule.h"
+#include "gromacs/commandline/cmdlinemodulemanager.h"
+
+#include "cmdlinetest.h"
+
+namespace
+{
+
+/********************************************************************
+ * MockModule
+ */
+
+/*! \internal \brief
+ * Mock implementation of gmx::CommandLineModuleInterface.
+ *
+ * \ingroup module_commandline
+ */
+class MockModule : public gmx::CommandLineModuleInterface
+{
+ public:
+ //! Creates a mock module with the given name.
+ explicit MockModule(const char *name);
+
+ virtual const char *name() const { return name_; }
+
+ MOCK_METHOD2(run, int(int argc, char *argv[]));
+
+ private:
+ const char *name_;
+};
+
+MockModule::MockModule(const char *name)
+ : name_(name)
+{
+}
+
+/********************************************************************
+ * Test fixture for the tests
+ */
+
+class CommandLineModuleManagerTest : public ::testing::Test
+{
+ public:
+ MockModule &addModule(const char *name);
+
+ gmx::CommandLineModuleManager manager_;
+};
+
+MockModule &
+CommandLineModuleManagerTest::addModule(const char *name)
+{
+ MockModule *module = new MockModule(name);
+ manager_.addModule(gmx::CommandLineModulePointer(module));
+ return *module;
+}
+
+/********************************************************************
+ * Actual tests
+ */
+
+TEST_F(CommandLineModuleManagerTest, RunsModule)
+{
+ const char *const cmdline[] = {
+ "test", "module", "-flag", "yes"
+ };
+ gmx::test::CommandLine args(cmdline);
+ MockModule &mod1 = addModule("module");
+ addModule("other");
+ using ::testing::_;
+ using ::testing::Args;
+ using ::testing::ElementsAreArray;
+ EXPECT_CALL(mod1, run(_, _))
+ .With(Args<1, 0>(ElementsAreArray(args.argv() + 1, args.argc() - 1)));
+ int rc = 0;
+ ASSERT_NO_THROW(rc = manager_.run(args.argc(), args.argv()));
+ ASSERT_EQ(0, rc);
+}
+
+} // namespace
TrajectoryAnalysisModule *_module;
int _debugLevel;
+ bool _bPrintCopyright;
};
TrajectoryAnalysisCommandLineRunner::Impl::Impl(
TrajectoryAnalysisModule *module)
- : _module(module), _debugLevel(0)
+ : _module(module), _debugLevel(0), _bPrintCopyright(true)
{
}
}
+void
+TrajectoryAnalysisCommandLineRunner::setPrintCopyright(bool bPrint)
+{
+ _impl->_bPrintCopyright = bPrint;
+}
+
+
void
TrajectoryAnalysisCommandLineRunner::setSelectionDebugLevel(int debuglevel)
{
{
TrajectoryAnalysisModule *module = _impl->_module;
- CopyRight(stderr, argv[0]);
+ if (_impl->_bPrintCopyright)
+ {
+ CopyRight(stderr, argv[0]);
+ }
SelectionCollection selections;
selections.setDebugLevel(_impl->_debugLevel);
TrajectoryAnalysisCommandLineRunner(TrajectoryAnalysisModule *module);
~TrajectoryAnalysisCommandLineRunner();
+ /*! \brief
+ * Sets whether the runner will print the copyright header.
+ *
+ * \param[in] bPrint Whether to print the copyright header.
+ *
+ * By default, the copyright header is printed.
+ * This is used internally when executing the runner in a context where
+ * the copyright has already been printed at a higher level.
+ *
+ * Does not throw.
+ */
+ void setPrintCopyright(bool bPrint);
/*! \brief
* Sets the default debugging level for selections.
*
*/
/*! \internal \file
* \brief
- * Implements createTrajectoryAnalysisModule().
+ * Implements registerTrajectoryAnalysisModules().
*
* \author Teemu Murtola <teemu.murtola@cbr.su.se>
* \ingroup module_trajectoryanalysis
*/
#include "gromacs/trajectoryanalysis/modules.h"
-#include "string2.h"
-
-#include "gromacs/utility/exceptions.h"
-#include "gromacs/utility/format.h"
+#include "gromacs/commandline/cmdlinemodule.h"
+#include "gromacs/commandline/cmdlinemodulemanager.h"
+#include "gromacs/trajectoryanalysis/cmdlinerunner.h"
#include "modules/angle.h"
#include "modules/distance.h"
#include "modules/select.h"
-namespace
+namespace gmx
{
-using namespace gmx::analysismodules;
-
-struct module_map_t
+namespace
{
- const char *name;
- gmx::TrajectoryAnalysisModulePointer (*creator)(void);
-};
-const module_map_t modules[] =
+/*! \internal \brief
+ * Base class for trajectory analysis module command-line wrappers.
+ *
+ * This class exists to avoid multiple identical copies of the \p run() method
+ * to be generated for the TrajAnalysisCmdLineWrapper template classes.
+ *
+ * \ingroup module_trajectoryanalysis
+ */
+class AbstractTrajAnalysisCmdLineWrapper : public CommandLineModuleInterface
{
- {gmx::analysismodules::angle, Angle::create},
- {gmx::analysismodules::distance, Distance::create},
- {gmx::analysismodules::select, Select::create},
- {NULL, NULL},
-};
+ public:
+ virtual const char *name() const = 0;
-} // namespace
+ virtual int run(int argc, char *argv[]);
-namespace gmx
-{
+ protected:
+ //! Creates the analysis module for this wrapper.
+ virtual TrajectoryAnalysisModulePointer createModule() = 0;
+};
-TrajectoryAnalysisModulePointer
-createTrajectoryAnalysisModule(const char *name)
+int AbstractTrajAnalysisCmdLineWrapper::run(int argc, char *argv[])
{
- size_t len = strlen(name);
- int match_i = -1;
+ TrajectoryAnalysisModulePointer module(createModule());
+ TrajectoryAnalysisCommandLineRunner runner(module.get());
+ runner.setPrintCopyright(false);
+ return runner.run(argc, argv);
+}
- for (int i = 0; modules[i].name != NULL; ++i)
- {
- if (gmx_strncasecmp(name, modules[i].name, len) == 0)
+/*! \internal \brief
+ * Template for command-line wrapper of a trajectory analysis module.
+ *
+ * \tparam Module Trajectory analysis module to wrap.
+ *
+ * \p Module should be default-constructible, derive from
+ * TrajectoryAnalysisModule, and have a static public member
+ * \c "const char name[]".
+ *
+ * \ingroup module_trajectoryanalysis
+ */
+template <class Module>
+class TrajAnalysisCmdLineWrapper : public AbstractTrajAnalysisCmdLineWrapper
+{
+ public:
+ virtual const char *name() const
{
- if (strlen(modules[i].name) == len)
- {
- match_i = i;
- break;
- }
- else if (match_i == -1)
- {
- match_i = i;
- }
- else
- {
- GMX_THROW(InvalidInputError(
- gmx::formatString("Requested analysis module '%s' is ambiguous", name)));
- }
+ return Module::name;
}
- }
- if (match_i != -1)
- {
- return modules[match_i].creator();
- }
- GMX_THROW(InvalidInputError(
- gmx::formatString("Unknown analysis module: %s", name)));
+ virtual TrajectoryAnalysisModulePointer createModule()
+ {
+ return TrajectoryAnalysisModulePointer(new Module);
+ }
+};
+
+} // namespace
+
+void registerTrajectoryAnalysisModules(CommandLineModuleManager *manager)
+{
+ using namespace gmx::analysismodules;
+ manager->registerModule<TrajAnalysisCmdLineWrapper<Angle> >();
+ manager->registerModule<TrajAnalysisCmdLineWrapper<Distance> >();
+ manager->registerModule<TrajAnalysisCmdLineWrapper<Select> >();
}
} // namespace gmx
*/
/*! \file
* \brief
- * Generic interface for creation of trajectory analysis modules.
+ * Generic interface for accessing trajectory analysis modules.
*
* \author Teemu Murtola <teemu.murtola@cbr.su.se>
* \inpublicapi
#ifndef GMX_TRAJECTORYANALYSIS_MODULES_H
#define GMX_TRAJECTORYANALYSIS_MODULES_H
-#include "analysismodule.h"
-
namespace gmx
{
+class CommandLineModuleManager;
+
/*! \brief
- * Creates a TrajectoryAnalysisModule object corresponding to a name.
+ * Registers all trajectory analysis command-line modules.
*
- * \param[in] name Name of the module to create (recognized names are
- * defined in modules.h).
- * \returns An allocated TrajectoryAnalysisModule object.
- * \throws InvalidInputError if \p name is not recognized.
+ * \param[in] manager Command-line module manager to receive the modules.
+ * \throws std::bad_alloc if out of memory.
*
- * This function should be used to instantiate analysis methods defined in the
- * library.
- *
- * In addition to recognizing exact matches on \p name, the function also
- * identifies cases where \p name is a prefix of exactly one recognized name
- * (exact matches always take precedence).
+ * Registers all trajectory analysis modules declared in the library such that
+ * they can be run through \p manager.
*
* \inpublicapi
*/
-TrajectoryAnalysisModulePointer
-createTrajectoryAnalysisModule(const char *name);
-
-namespace analysismodules
-{
-
-static const char * const angle = "angle";
-static const char * const distance = "distance";
-static const char * const select = "select";
-
-} // namespace modules
+void registerTrajectoryAnalysisModules(CommandLineModuleManager *manager);
} // namespace gmx
namespace analysismodules
{
+const char Angle::name[] = "angle";
+
Angle::Angle()
- : _options("angle", "Angle calculation"),
+ : _options(name, "Angle calculation"),
_sel1info(NULL), _sel2info(NULL),
_bSplit1(false), _bSplit2(false), _bMulti(false), _bAll(false),
_bDumpDist(false), _natoms1(0), _natoms2(0), _vt0(NULL)
{
}
-
-TrajectoryAnalysisModulePointer
-Angle::create()
-{
- return TrajectoryAnalysisModulePointer(new Angle());
-}
-
} // namespace modules
} // namespace gmxana
class Angle : public TrajectoryAnalysisModule
{
public:
+ static const char name[];
+
Angle();
virtual ~Angle();
- static TrajectoryAnalysisModulePointer create();
-
virtual Options &initOptions(TrajectoryAnalysisSettings *settings);
virtual void initOptionsDone(TrajectoryAnalysisSettings *settings);
virtual void initAnalysis(const TrajectoryAnalysisSettings &settings,
namespace analysismodules
{
+const char Distance::name[] = "distance";
+
Distance::Distance()
- : _options("distance", "Distance calculation"), _avem(new AnalysisDataAverageModule())
+ : _options(name, "Distance calculation"), _avem(new AnalysisDataAverageModule())
{
}
fprintf(stderr, "Std. deviation: %f\n", _avem->stddev(0));
}
-
-TrajectoryAnalysisModulePointer
-Distance::create()
-{
- return TrajectoryAnalysisModulePointer(new Distance());
-}
-
} // namespace analysismodules
} // namespace gmx
class Distance : public TrajectoryAnalysisModule
{
public:
+ static const char name[];
+
Distance();
virtual ~Distance();
- static TrajectoryAnalysisModulePointer create();
-
virtual Options &initOptions(TrajectoryAnalysisSettings *settings);
virtual void initAnalysis(const TrajectoryAnalysisSettings &settings,
const TopologyInformation &top);
* Select
*/
+const char Select::name[] = "select";
+
Select::Select()
- : _options("select", "Selection information"),
+ : _options(name, "Selection information"),
_bDump(false), _bTotNorm(false), _bFracNorm(false), _bResInd(false),
_top(NULL)
{
{
}
-
-TrajectoryAnalysisModulePointer
-Select::create()
-{
- return TrajectoryAnalysisModulePointer(new Select());
-}
-
} // namespace analysismodules
} // namespace gmx
class Select : public TrajectoryAnalysisModule
{
public:
+ static const char name[];
+
Select();
virtual ~Select();
- static TrajectoryAnalysisModulePointer create();
-
virtual Options &initOptions(TrajectoryAnalysisSettings *settings);
virtual void initAnalysis(const TrajectoryAnalysisSettings &settings,
const TopologyInformation &top);
*/
#include "gromacs/legacyheaders/copyrite.h"
-#include "gromacs/trajectoryanalysis/analysismodule.h"
-#include "gromacs/trajectoryanalysis/cmdlinerunner.h"
+#include "gromacs/commandline/cmdlinemodulemanager.h"
#include "gromacs/trajectoryanalysis/modules.h"
#include "gromacs/utility/exceptions.h"
int
main(int argc, char *argv[])
{
- bool bPrintCopyrightOnError = true;
-
+ CopyRight(stderr, argv[0]);
try
{
- if (argc < 2)
- {
- GMX_THROW(gmx::InvalidInputError("Not enough command-line arguments"));
- }
-
- gmx::TrajectoryAnalysisModulePointer
- mod(gmx::createTrajectoryAnalysisModule(argv[1]));
- --argc;
- ++argv;
-
- gmx::TrajectoryAnalysisCommandLineRunner runner(mod.get());
-#ifndef __clang_analyzer__ //Clang BUG: 11722
- bPrintCopyrightOnError = false;
-#endif
- return runner.run(argc, argv);
+ gmx::CommandLineModuleManager manager;
+ registerTrajectoryAnalysisModules(&manager);
+ return manager.run(argc, argv);
}
catch (const std::exception &ex)
{
- if (bPrintCopyrightOnError)
- {
- CopyRight(stderr, argv[0]);
- }
fprintf(stderr, "%s", gmx::formatErrorMessage(ex).c_str());
return 1;
}