3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
9 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
10 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
11 * Copyright (c) 2001-2009, The GROMACS development team,
12 * check out http://www.gromacs.org for more information.
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * If you want to redistribute modifications, please consider that
20 * scientific software is very special. Version control is crucial -
21 * bugs must be traceable. We will be happy to consider code for
22 * inclusion in the official distribution, but derived work must not
23 * be called official GROMACS. Details are found in the README & COPYING
24 * files - if they are missing, get the official version at www.gromacs.org.
26 * To help us fund GROMACS development, we humbly ask that you cite
27 * the papers on the package - you can find them in the top README file.
29 * For more info, check our website at http://www.gromacs.org
33 * Implements gmx::CommandLineHelpWriter.
35 * \author Teemu Murtola <teemu.murtola@cbr.su.se>
36 * \ingroup module_commandline
38 #include "cmdlinehelpwriter.h"
42 #include "gromacs/onlinehelp/helpformat.h"
43 #include "gromacs/options/basicoptioninfo.h"
44 #include "gromacs/options/filenameoptioninfo.h"
45 #include "gromacs/options/options.h"
46 #include "gromacs/options/optionsvisitor.h"
47 #include "gromacs/options/timeunitmanager.h"
48 #include "gromacs/selection/selectionfileoptioninfo.h"
49 #include "gromacs/selection/selectionoptioninfo.h"
50 #include "gromacs/utility/file.h"
51 #include "gromacs/utility/stringutil.h"
59 /********************************************************************
64 * Helper object for writing section descriptions to help.
66 * \ingroup module_commandline
68 class DescriptionWriter : public OptionsVisitor
71 //! Creates a helper object for writing section descriptions.
72 explicit DescriptionWriter(File *file) : file_(*file) {}
74 virtual void visitSubSection(const Options §ion);
75 virtual void visitOption(const OptionInfo & /*option*/) { }
81 void DescriptionWriter::visitSubSection(const Options §ion)
83 if (!section.description().empty())
85 const std::string &title = section.title();
88 file_.writeLine(title);
91 writeHelpTextForConsole(&file_, section.description());
94 OptionsIterator(section).acceptSubSections(this);
98 /********************************************************************
103 * Helper object for writing help for file parameters.
105 * \ingroup module_commandline
107 class FileParameterWriter : public OptionsTypeVisitor<FileNameOptionInfo>
110 //! Creates a helper object for writing file parameters.
111 explicit FileParameterWriter(File *file);
113 //! Returns true if anything was written out.
114 bool didOutput() const { return formatter_.didOutput(); }
116 virtual void visitSubSection(const Options §ion);
117 virtual void visitOptionType(const FileNameOptionInfo &option);
121 TextTableFormatter formatter_;
124 FileParameterWriter::FileParameterWriter(File *file)
127 formatter_.addColumn("Option", 6, false);
128 formatter_.addColumn("Filename", 12, false);
129 formatter_.addColumn("Type", 12, false);
130 formatter_.addColumn("Description", 45, true);
133 void FileParameterWriter::visitSubSection(const Options §ion)
135 OptionsIterator iterator(section);
136 iterator.acceptSubSections(this);
137 iterator.acceptOptions(this);
140 void FileParameterWriter::visitOptionType(const FileNameOptionInfo &option)
142 int firstShortValue = 0; // The first value after which the type fits.
143 int firstLongValue = -1; // First value that overlaps description column.
144 int lastLongValue = -1; // Last value like the above.
146 // Get the values to write and check where text overflows the columns.
148 std::string name(formatString("-%s", option.name().c_str()));
149 formatter_.addColumnLine(0, name);
150 for (int i = 0; i < option.valueCount() || i == 0; ++i)
153 if (option.valueCount() == 0
154 || (option.valueCount() == 1 && option.formatValue(0).empty()))
156 value = option.formatDefaultValueIfSet();
160 value = option.formatValue(i);
162 formatter_.addColumnLine(1, value);
163 if (value.length() > 12U && i == firstShortValue)
165 firstShortValue = i + 1;
167 if (value.length() > 25U)
169 if (firstLongValue == -1)
177 if (option.isInputOutputFile())
181 else if (option.isInputFile())
185 else if (option.isOutputFile())
189 if (!option.isRequired())
193 if (option.isLibraryFile())
197 bool bLongType = (type.length() > 12U);
198 formatter_.addColumnLine(2, type);
199 formatter_.addColumnLine(3, substituteMarkupForConsole(option.description()));
202 if (name.length() > 6U || firstShortValue > 0)
204 formatter_.setColumnFirstLineOffset(1, 1);
205 // Assume that the name is <20 chars, so that the type fits
206 if (firstLongValue >= 0)
212 int firstDescriptionLine = 0;
215 firstDescriptionLine = 1;
217 formatter_.setColumnFirstLineOffset(3, firstDescriptionLine);
218 if (firstLongValue >= 0 && formatter_.lastColumnLine(3) >= firstLongValue)
220 firstDescriptionLine = lastLongValue + 1;
221 formatter_.setColumnFirstLineOffset(3, firstDescriptionLine);
224 // Do the formatting.
225 file_.writeString(formatter_.formatRow());
229 /********************************************************************
234 * Helper object for writing help for non-file parameters.
236 * \ingroup module_commandline
238 class ParameterWriter : public OptionsVisitor
241 //! Creates a helper object for writing non-file parameters.
242 ParameterWriter(File *file, const char *timeUnit);
244 //! Sets the writer to show hidden options.
245 void setShowHidden(bool bSet) { bShowHidden_ = bSet; }
246 //! Returns true if anything was written out.
247 bool didOutput() const { return formatter_.didOutput(); }
249 virtual void visitSubSection(const Options §ion);
250 virtual void visitOption(const OptionInfo &option);
254 TextTableFormatter formatter_;
255 const char *timeUnit_;
259 ParameterWriter::ParameterWriter(File *file, const char *timeUnit)
260 : file_(*file), timeUnit_(timeUnit), bShowHidden_(false)
262 formatter_.addColumn("Option", 12, false);
263 formatter_.addColumn("Type", 6, false);
264 formatter_.addColumn("Value", 6, false);
265 formatter_.addColumn("Description", 51, true);
268 void ParameterWriter::visitSubSection(const Options §ion)
270 OptionsIterator iterator(section);
271 iterator.acceptSubSections(this);
272 iterator.acceptOptions(this);
275 void ParameterWriter::visitOption(const OptionInfo &option)
277 if (option.isType<FileNameOptionInfo>()
278 || option.isType<SelectionFileOptionInfo>()
279 || option.isType<SelectionOptionInfo>()
280 || (!bShowHidden_ && option.isHidden()))
286 bool bIsBool = option.isType<BooleanOptionInfo>();
287 std::string name(formatString("-%s%s", bIsBool ? "[no]" : "",
288 option.name().c_str()));
289 formatter_.addColumnLine(0, name);
290 formatter_.addColumnLine(1, option.type());
291 if (name.length() > 12U)
293 formatter_.setColumnFirstLineOffset(1, 1);
295 // TODO: Better handling of multiple long values
297 for (int i = 0; i < option.valueCount(); ++i)
303 values.append(option.formatValue(i));
305 formatter_.addColumnLine(2, values);
306 std::string description(substituteMarkupForConsole(option.description()));
307 const DoubleOptionInfo *doubleOption = option.toType<DoubleOptionInfo>();
308 if (doubleOption != NULL && doubleOption->isTime())
310 description = replaceAll(description, "%t", timeUnit_);
312 formatter_.addColumnLine(3, description);
313 if (values.length() > 6U)
315 formatter_.setColumnFirstLineOffset(3, 1);
318 file_.writeString(formatter_.formatRow());
322 /********************************************************************
323 * SelectionParameterWriter
327 * Helper object for writing help for selection parameters.
329 * \ingroup module_commandline
331 class SelectionParameterWriter : public OptionsVisitor
334 //! Creates a helper object for writing selection parameters.
335 explicit SelectionParameterWriter(File *file);
337 //! Returns true if anything was written out.
338 bool didOutput() const { return formatter_.didOutput(); }
340 virtual void visitSubSection(const Options §ion);
341 virtual void visitOption(const OptionInfo &option);
345 TextTableFormatter formatter_;
348 SelectionParameterWriter::SelectionParameterWriter(File *file)
351 formatter_.addColumn("Selection", 10, false);
352 formatter_.addColumn("Description", 67, true);
355 void SelectionParameterWriter::visitSubSection(const Options §ion)
357 OptionsIterator iterator(section);
358 iterator.acceptSubSections(this);
359 iterator.acceptOptions(this);
362 void SelectionParameterWriter::visitOption(const OptionInfo &option)
364 if (!option.isType<SelectionFileOptionInfo>()
365 && !option.isType<SelectionOptionInfo>())
371 std::string name(formatString("-%s", option.name().c_str()));
372 formatter_.addColumnLine(0, name);
373 formatter_.addColumnLine(1, substituteMarkupForConsole(option.description()));
374 file_.writeString(formatter_.formatRow());
376 // TODO: What to do with selection variables?
377 // They are not printed as values for any option.
378 for (int i = 0; i < option.valueCount(); ++i)
380 std::string value(option.formatValue(i));
382 file_.writeLine(formatString(" %s", value.c_str()));
388 /********************************************************************
389 * CommandLineHelpWriter::Impl
393 * Private implementation class for CommandLineHelpWriter.
395 * \ingroup module_commandline
397 class CommandLineHelpWriter::Impl
400 //! Sets the Options object to use for generating help.
401 explicit Impl(const Options &options);
403 //! Options object to use for generating help.
404 const Options &options_;
405 //! Time unit to show in descriptions.
406 std::string timeUnit_;
407 //! Whether to write descriptions to output.
408 bool bShowDescriptions_;
409 //! Whether to write hidden options to output.
413 CommandLineHelpWriter::Impl::Impl(const Options &options)
414 : options_(options), timeUnit_(TimeUnitManager().timeUnitAsString()),
415 bShowDescriptions_(false), bShowHidden_(false)
419 /********************************************************************
420 * CommandLineHelpWriter
423 CommandLineHelpWriter::CommandLineHelpWriter(const Options &options)
424 : impl_(new Impl(options))
428 CommandLineHelpWriter::~CommandLineHelpWriter()
432 CommandLineHelpWriter &CommandLineHelpWriter::setShowHidden(bool bSet)
434 impl_->bShowHidden_ = bSet;
438 CommandLineHelpWriter &CommandLineHelpWriter::setShowDescriptions(bool bSet)
440 impl_->bShowDescriptions_ = bSet;
444 CommandLineHelpWriter &CommandLineHelpWriter::setTimeUnitString(const char *timeUnit)
446 impl_->timeUnit_ = timeUnit;
450 void CommandLineHelpWriter::writeHelp(File *file)
452 if (impl_->bShowDescriptions_)
454 file->writeLine("DESCRIPTION");
455 file->writeLine("-----------");
457 DescriptionWriter(file).visitSubSection(impl_->options_);
460 FileParameterWriter writer(file);
461 writer.visitSubSection(impl_->options_);
462 if (writer.didOutput())
468 ParameterWriter writer(file, impl_->timeUnit_.c_str());
469 writer.setShowHidden(impl_->bShowHidden_);
470 writer.visitSubSection(impl_->options_);
471 if (writer.didOutput())
477 SelectionParameterWriter writer(file);
478 writer.visitSubSection(impl_->options_);
479 if (writer.didOutput())