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)
155 value = option.formatDefaultValueIfSet();
159 value = option.formatValue(i);
161 formatter_.addColumnLine(1, value);
162 if (value.length() > 12U && i == firstShortValue)
164 firstShortValue = i + 1;
166 if (value.length() > 25U)
168 if (firstLongValue == -1)
176 if (option.isInputOutputFile())
180 else if (option.isInputFile())
184 else if (option.isOutputFile())
188 if (!option.isRequired())
192 if (option.isLibraryFile())
196 bool bLongType = (type.length() > 12U);
197 formatter_.addColumnLine(2, type);
198 formatter_.addColumnLine(3, substituteMarkupForConsole(option.description()));
201 if (name.length() > 6U || firstShortValue > 0)
203 formatter_.setColumnFirstLineOffset(1, 1);
204 // Assume that the name is <20 chars, so that the type fits
205 if (firstLongValue >= 0)
211 int firstDescriptionLine = 0;
214 firstDescriptionLine = 1;
216 formatter_.setColumnFirstLineOffset(3, firstDescriptionLine);
217 if (firstLongValue >= 0 && formatter_.lastColumnLine(3) >= firstLongValue)
219 firstDescriptionLine = lastLongValue + 1;
220 formatter_.setColumnFirstLineOffset(3, firstDescriptionLine);
223 // Do the formatting.
224 file_.writeString(formatter_.formatRow());
228 /********************************************************************
233 * Helper object for writing help for non-file parameters.
235 * \ingroup module_commandline
237 class ParameterWriter : public OptionsVisitor
240 //! Creates a helper object for writing non-file parameters.
241 ParameterWriter(File *file, const char *timeUnit);
243 //! Sets the writer to show hidden options.
244 void setShowHidden(bool bSet) { bShowHidden_ = bSet; }
245 //! Returns true if anything was written out.
246 bool didOutput() const { return formatter_.didOutput(); }
248 virtual void visitSubSection(const Options §ion);
249 virtual void visitOption(const OptionInfo &option);
253 TextTableFormatter formatter_;
254 const char *timeUnit_;
258 ParameterWriter::ParameterWriter(File *file, const char *timeUnit)
259 : file_(*file), timeUnit_(timeUnit), bShowHidden_(false)
261 formatter_.addColumn("Option", 12, false);
262 formatter_.addColumn("Type", 6, false);
263 formatter_.addColumn("Value", 6, false);
264 formatter_.addColumn("Description", 51, true);
267 void ParameterWriter::visitSubSection(const Options §ion)
269 OptionsIterator iterator(section);
270 iterator.acceptSubSections(this);
271 iterator.acceptOptions(this);
274 void ParameterWriter::visitOption(const OptionInfo &option)
276 if (option.isType<FileNameOptionInfo>()
277 || option.isType<SelectionFileOptionInfo>()
278 || option.isType<SelectionOptionInfo>()
279 || (!bShowHidden_ && option.isHidden()))
285 bool bIsBool = option.isType<BooleanOptionInfo>();
286 std::string name(formatString("-%s%s", bIsBool ? "[no]" : "",
287 option.name().c_str()));
288 formatter_.addColumnLine(0, name);
289 formatter_.addColumnLine(1, option.type());
290 if (name.length() > 12U)
292 formatter_.setColumnFirstLineOffset(1, 1);
294 // TODO: Better handling of multiple long values
296 for (int i = 0; i < option.valueCount(); ++i)
302 values.append(option.formatValue(i));
304 formatter_.addColumnLine(2, values);
305 std::string description(substituteMarkupForConsole(option.description()));
306 const DoubleOptionInfo *doubleOption = option.toType<DoubleOptionInfo>();
307 if (doubleOption != NULL && doubleOption->isTime())
309 description = replaceAll(description, "%t", timeUnit_);
311 formatter_.addColumnLine(3, description);
312 if (values.length() > 6U)
314 formatter_.setColumnFirstLineOffset(3, 1);
317 file_.writeString(formatter_.formatRow());
321 /********************************************************************
322 * SelectionParameterWriter
326 * Helper object for writing help for selection parameters.
328 * \ingroup module_commandline
330 class SelectionParameterWriter : public OptionsVisitor
333 //! Creates a helper object for writing selection parameters.
334 explicit SelectionParameterWriter(File *file);
336 //! Returns true if anything was written out.
337 bool didOutput() const { return formatter_.didOutput(); }
339 virtual void visitSubSection(const Options §ion);
340 virtual void visitOption(const OptionInfo &option);
344 TextTableFormatter formatter_;
347 SelectionParameterWriter::SelectionParameterWriter(File *file)
350 formatter_.addColumn("Selection", 10, false);
351 formatter_.addColumn("Description", 67, true);
354 void SelectionParameterWriter::visitSubSection(const Options §ion)
356 OptionsIterator iterator(section);
357 iterator.acceptSubSections(this);
358 iterator.acceptOptions(this);
361 void SelectionParameterWriter::visitOption(const OptionInfo &option)
363 if (!option.isType<SelectionFileOptionInfo>()
364 && !option.isType<SelectionOptionInfo>())
370 std::string name(formatString("-%s", option.name().c_str()));
371 formatter_.addColumnLine(0, name);
372 formatter_.addColumnLine(1, substituteMarkupForConsole(option.description()));
373 file_.writeString(formatter_.formatRow());
375 // TODO: What to do with selection variables?
376 // They are not printed as values for any option.
377 for (int i = 0; i < option.valueCount(); ++i)
379 std::string value(option.formatValue(i));
381 file_.writeLine(formatString(" %s", value.c_str()));
387 /********************************************************************
388 * CommandLineHelpWriter::Impl
392 * Private implementation class for CommandLineHelpWriter.
394 * \ingroup module_commandline
396 class CommandLineHelpWriter::Impl
399 //! Sets the Options object to use for generating help.
400 explicit Impl(const Options &options);
402 //! Options object to use for generating help.
403 const Options &options_;
404 //! Time unit to show in descriptions.
405 std::string timeUnit_;
406 //! Whether to write descriptions to output.
407 bool bShowDescriptions_;
408 //! Whether to write hidden options to output.
412 CommandLineHelpWriter::Impl::Impl(const Options &options)
413 : options_(options), timeUnit_(TimeUnitManager().timeUnitAsString()),
414 bShowDescriptions_(false), bShowHidden_(false)
418 /********************************************************************
419 * CommandLineHelpWriter
422 CommandLineHelpWriter::CommandLineHelpWriter(const Options &options)
423 : impl_(new Impl(options))
427 CommandLineHelpWriter::~CommandLineHelpWriter()
431 CommandLineHelpWriter &CommandLineHelpWriter::setShowHidden(bool bSet)
433 impl_->bShowHidden_ = bSet;
437 CommandLineHelpWriter &CommandLineHelpWriter::setShowDescriptions(bool bSet)
439 impl_->bShowDescriptions_ = bSet;
443 CommandLineHelpWriter &CommandLineHelpWriter::setTimeUnitString(const char *timeUnit)
445 impl_->timeUnit_ = timeUnit;
449 void CommandLineHelpWriter::writeHelp(File *file)
451 if (impl_->bShowDescriptions_)
453 file->writeLine("DESCRIPTION");
454 file->writeLine("-----------");
456 DescriptionWriter(file).visitSubSection(impl_->options_);
459 FileParameterWriter writer(file);
460 writer.visitSubSection(impl_->options_);
461 if (writer.didOutput())
467 ParameterWriter writer(file, impl_->timeUnit_.c_str());
468 writer.setShowHidden(impl_->bShowHidden_);
469 writer.visitSubSection(impl_->options_);
470 if (writer.didOutput())
476 SelectionParameterWriter writer(file);
477 writer.visitSubSection(impl_->options_);
478 if (writer.didOutput())