2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
37 * Implements gmx::CommandLineHelpModule.
39 * \author Teemu Murtola <teemu.murtola@gmail.com>
40 * \ingroup module_commandline
44 #include "cmdlinehelpmodule.h"
49 #include <boost/scoped_ptr.hpp>
51 #include "gromacs/commandline/cmdlinehelpcontext.h"
52 #include "gromacs/commandline/cmdlinehelpwriter.h"
53 #include "gromacs/commandline/cmdlineparser.h"
54 #include "gromacs/onlinehelp/helpformat.h"
55 #include "gromacs/onlinehelp/helpmanager.h"
56 #include "gromacs/onlinehelp/helptopic.h"
57 #include "gromacs/onlinehelp/helpwritercontext.h"
58 #include "gromacs/options/basicoptions.h"
59 #include "gromacs/options/options.h"
60 #include "gromacs/utility/baseversion.h"
61 #include "gromacs/utility/exceptions.h"
62 #include "gromacs/utility/file.h"
63 #include "gromacs/utility/fileredirector.h"
64 #include "gromacs/utility/gmxassert.h"
65 #include "gromacs/utility/programcontext.h"
66 #include "gromacs/utility/stringutil.h"
68 #include "shellcompletions.h"
75 class HelpExportInterface;
79 /********************************************************************
80 * CommandLineHelpModuleImpl declaration
83 class CommandLineHelpModuleImpl
86 CommandLineHelpModuleImpl(const ProgramContextInterface &programContext,
87 const std::string &binaryName,
88 const CommandLineModuleMap &modules,
89 const CommandLineModuleGroupList &groups);
91 void exportHelp(HelpExportInterface *exporter) const;
93 boost::scoped_ptr<RootHelpTopic> rootTopic_;
94 const ProgramContextInterface &programContext_;
95 std::string binaryName_;
96 const CommandLineModuleMap &modules_;
97 const CommandLineModuleGroupList &groups_;
99 CommandLineHelpContext *context_;
100 const CommandLineModuleInterface *moduleOverride_;
103 FileOutputRedirectorInterface *outputRedirector_;
105 GMX_DISALLOW_COPY_AND_ASSIGN(CommandLineHelpModuleImpl);
111 /********************************************************************
112 * HelpExportInterface
116 * Callbacks for exporting help information for command-line modules.
118 * \ingroup module_commandline
120 class HelpExportInterface
123 //! Shorthand for a list of modules contained in a group.
124 typedef CommandLineModuleGroupData::ModuleList ModuleGroupContents;
126 virtual ~HelpExportInterface() {};
129 * Called once before exporting individual modules.
131 * Can, e.g., open shared output files (e.g., if the output is written
132 * into a single file, or if a separate index is required) and write
135 virtual void startModuleExport() = 0;
137 * Called to export the help for each module.
139 * \param[in] module Module for which the help should be exported.
140 * \param[in] tag Unique tag for the module (gmx-something).
141 * \param[in] displayName Display name for the module (gmx something).
143 virtual void exportModuleHelp(
144 const CommandLineModuleInterface &module,
145 const std::string &tag,
146 const std::string &displayName) = 0;
148 * Called after all modules have been exported.
150 * Can close files opened in startModuleExport(), write footers to them
153 virtual void finishModuleExport() = 0;
156 * Called once before exporting module groups.
158 * Can, e.g., open a single output file for listing all the groups.
160 virtual void startModuleGroupExport() = 0;
162 * Called to export the help for each module group.
164 * \param[in] title Title for the group.
165 * \param[in] modules List of modules in the group.
167 virtual void exportModuleGroup(const char *title,
168 const ModuleGroupContents &modules) = 0;
170 * Called after all module groups have been exported.
172 * Can close files opened in startModuleGroupExport(), write footers to them
175 virtual void finishModuleGroupExport() = 0;
178 * Called to export the help for a top-level topic.
180 * \param[in] topic Topic to export.
182 virtual void exportTopic(const HelpTopicInterface &topic) = 0;
185 /********************************************************************
191 static const char name[];
192 static const char title[];
193 static const char *const text[];
196 // The first two are not used.
197 const char RootHelpText::name[] = "";
198 const char RootHelpText::title[] = "";
199 const char *const RootHelpText::text[] = { "" };
202 * Help topic that forms the root of the help tree for the help subcommand.
204 * \ingroup module_commandline
206 class RootHelpTopic : public CompositeHelpTopic<RootHelpText>
210 * Creates a root help topic.
214 explicit RootHelpTopic(const CommandLineHelpModuleImpl &helpModule)
215 : helpModule_(helpModule)
219 //! Adds a top-level topic and optionally marks it as exported.
220 void addTopic(HelpTopicPointer topic, bool bExported)
224 exportedTopics_.push_back(topic->name());
226 addSubTopic(move(topic));
228 //! Exports all the top-level topics with the given exporter.
229 void exportHelp(HelpExportInterface *exporter) const;
231 virtual void writeHelp(const HelpWriterContext &context) const;
234 const CommandLineHelpModuleImpl &helpModule_;
235 std::vector<std::string> exportedTopics_;
237 GMX_DISALLOW_COPY_AND_ASSIGN(RootHelpTopic);
240 void RootHelpTopic::exportHelp(HelpExportInterface *exporter) const
242 std::vector<std::string>::const_iterator topicName;
243 for (topicName = exportedTopics_.begin();
244 topicName != exportedTopics_.end();
247 const HelpTopicInterface *topic = findSubTopic(topicName->c_str());
248 GMX_RELEASE_ASSERT(topic != NULL, "Exported help topic no longer found");
249 exporter->exportTopic(*topic);
253 void RootHelpTopic::writeHelp(const HelpWriterContext &context) const
255 if (context.outputFormat() != eHelpOutputFormat_Console)
257 // TODO: Implement once the situation with Redmine issue #969 is more
259 GMX_THROW(NotImplementedError(
260 "Root help is not implemented for this output format"));
263 CommandLineCommonOptionsHolder optionsHolder;
264 CommandLineHelpContext cmdlineContext(*helpModule_.context_);
265 cmdlineContext.setModuleDisplayName(helpModule_.binaryName_);
266 optionsHolder.initOptions();
267 // TODO: Add <command> [<args>] into the synopsis.
268 CommandLineHelpWriter(*optionsHolder.options())
269 .writeHelp(cmdlineContext);
271 // TODO: Consider printing a list of "core" commands. Would require someone
272 // to determine such a set...
273 writeSubTopicList(context,
274 "Additional help is available on the following topics:");
275 // TODO: Make these respect the binary name passed in, to make tests work better.
276 context.writeTextBlock("To access the help, use '[PROGRAM] help <topic>'.");
277 context.writeTextBlock("For help on a command, use '[PROGRAM] help <command>'.");
280 /********************************************************************
285 * Help topic for listing the commands.
287 * \ingroup module_commandline
289 class CommandsHelpTopic : public HelpTopicInterface
293 * Creates a command list help topic.
295 * \param[in] helpModule Help module to get module information from.
299 explicit CommandsHelpTopic(const CommandLineHelpModuleImpl &helpModule)
300 : helpModule_(helpModule)
304 virtual const char *name() const { return "commands"; }
305 virtual const char *title() const { return "List of available commands"; }
306 virtual bool hasSubTopics() const { return false; }
307 virtual const HelpTopicInterface *findSubTopic(const char * /*name*/) const
312 virtual void writeHelp(const HelpWriterContext &context) const;
315 const CommandLineHelpModuleImpl &helpModule_;
317 GMX_DISALLOW_COPY_AND_ASSIGN(CommandsHelpTopic);
320 void CommandsHelpTopic::writeHelp(const HelpWriterContext &context) const
322 if (context.outputFormat() != eHelpOutputFormat_Console)
324 GMX_THROW(NotImplementedError(
325 "Module list is not implemented for this output format"));
327 int maxNameLength = 0;
328 const CommandLineModuleMap &modules = helpModule_.modules_;
329 CommandLineModuleMap::const_iterator module;
330 for (module = modules.begin(); module != modules.end(); ++module)
332 int nameLength = static_cast<int>(module->first.length());
333 if (module->second->shortDescription() != NULL
334 && nameLength > maxNameLength)
336 maxNameLength = nameLength;
339 context.writeTextBlock(
340 "Usage: [PROGRAM] [<options>] <command> [<args>][PAR]"
341 "Available commands:");
342 File &file = context.outputFile();
343 TextTableFormatter formatter;
344 formatter.addColumn(NULL, maxNameLength + 1, false);
345 formatter.addColumn(NULL, 72 - maxNameLength, true);
346 formatter.setFirstColumnIndent(4);
347 for (module = modules.begin(); module != modules.end(); ++module)
349 const char *name = module->first.c_str();
350 const char *description = module->second->shortDescription();
351 if (description != NULL)
354 formatter.addColumnLine(0, name);
355 formatter.addColumnLine(1, description);
356 file.writeString(formatter.formatRow());
359 context.writeTextBlock(
360 "For help on a command, use '[PROGRAM] help <command>'.");
363 /********************************************************************
368 * Help topic wrapper for a command-line module.
370 * This class implements HelpTopicInterface such that it wraps a
371 * CommandLineModuleInterface, allowing subcommand "help <command>"
372 * to produce the help for "<command>".
374 * \ingroup module_commandline
376 class ModuleHelpTopic : public HelpTopicInterface
379 //! Constructs a help topic for a specific module.
380 ModuleHelpTopic(const CommandLineModuleInterface &module,
381 const CommandLineHelpModuleImpl &helpModule)
382 : module_(module), helpModule_(helpModule)
386 virtual const char *name() const { return module_.name(); }
387 virtual const char *title() const { return NULL; }
388 virtual bool hasSubTopics() const { return false; }
389 virtual const HelpTopicInterface *findSubTopic(const char * /*name*/) const
393 virtual void writeHelp(const HelpWriterContext &context) const;
396 const CommandLineModuleInterface &module_;
397 const CommandLineHelpModuleImpl &helpModule_;
399 GMX_DISALLOW_COPY_AND_ASSIGN(ModuleHelpTopic);
402 void ModuleHelpTopic::writeHelp(const HelpWriterContext & /*context*/) const
404 CommandLineHelpContext context(*helpModule_.context_);
405 const char *const program = helpModule_.binaryName_.c_str();
406 context.setModuleDisplayName(formatString("%s %s", program, module_.name()));
407 module_.writeHelp(context);
410 /********************************************************************
411 * HelpExportReStructuredText
415 * Adds hyperlinks to modules within this binary.
417 * \param[in,out] links Links are added here.
418 * \param[in] helpModule Help module to get module information from.
419 * \throws std::bad_alloc if out of memory.
421 * Initializes a HelpLinks object with links to modules defined in
424 * \ingroup module_commandline
426 void initProgramLinks(HelpLinks *links, const CommandLineHelpModuleImpl &helpModule)
428 const char *const program = helpModule.binaryName_.c_str();
429 CommandLineModuleMap::const_iterator module;
430 for (module = helpModule.modules_.begin();
431 module != helpModule.modules_.end();
434 if (module->second->shortDescription() != NULL)
436 std::string linkName("[gmx-" + module->first + "]");
437 const char *name = module->first.c_str();
438 std::string reference(
439 formatString(":doc:`%s %s <%s-%s>`", program, name, program, name));
440 std::string displayName(
441 formatString("[TT]%s %s[tt]", program, name));
442 links->addLink(linkName, reference, displayName);
448 * Implements export for web pages as reStructuredText.
450 * \ingroup module_commandline
452 class HelpExportReStructuredText : public HelpExportInterface
455 //! Initializes reST exporter.
456 explicit HelpExportReStructuredText(
457 const CommandLineHelpModuleImpl &helpModule);
459 virtual void startModuleExport();
460 virtual void exportModuleHelp(
461 const CommandLineModuleInterface &module,
462 const std::string &tag,
463 const std::string &displayName);
464 virtual void finishModuleExport();
466 virtual void startModuleGroupExport();
467 virtual void exportModuleGroup(const char *title,
468 const ModuleGroupContents &modules);
469 virtual void finishModuleGroupExport();
471 virtual void exportTopic(const HelpTopicInterface &topic);
474 FileOutputRedirectorInterface *outputRedirector_;
476 boost::scoped_ptr<File> indexFile_;
477 boost::scoped_ptr<File> manPagesFile_;
480 HelpExportReStructuredText::HelpExportReStructuredText(
481 const CommandLineHelpModuleImpl &helpModule)
482 : outputRedirector_(helpModule.outputRedirector_),
483 links_(eHelpOutputFormat_Rst)
485 File linksFile("links.dat", "r");
487 while (linksFile.readLine(&line))
489 links_.addLink("[REF]." + line + "[ref]",
490 formatString(":ref:`.%s <%s>`", line.c_str(), line.c_str()),
492 links_.addLink("[REF]" + line + "[ref]", formatString(":ref:`%s`", line.c_str()), line);
495 initProgramLinks(&links_, helpModule);
498 void HelpExportReStructuredText::startModuleExport()
501 new File(outputRedirector_->openFileForWriting("programs/byname.rst")));
502 indexFile_->writeLine("Tools by Name");
503 indexFile_->writeLine("=============");
505 new File(outputRedirector_->openFileForWriting("conf-man.py")));
506 manPagesFile_->writeLine("man_pages = [");
509 void HelpExportReStructuredText::exportModuleHelp(
510 const CommandLineModuleInterface &module,
511 const std::string &tag,
512 const std::string &displayName)
514 // TODO: Ideally, the file would only be touched if it really changes.
515 // This would make Sphinx reruns much faster.
516 File file(outputRedirector_->openFileForWriting("programs/" + tag + ".rst"));
517 file.writeLine(formatString(".. _%s:", displayName.c_str()));
518 if (0 == displayName.compare("gmx mdrun"))
520 // Make an extra link target for the convenience of
521 // MPI-specific documentation
522 file.writeLine(".. _mdrun_mpi:");
526 CommandLineHelpContext context(&file, eHelpOutputFormat_Rst, &links_);
527 context.enterSubSection(displayName);
528 context.setModuleDisplayName(displayName);
529 module.writeHelp(context);
532 file.writeLine(".. only:: man");
534 file.writeLine(" See also");
535 file.writeLine(" --------");
537 file.writeLine(" :manpage:`gromacs(7)`");
539 file.writeLine(" More information about |Gromacs| is available at <http://www.gromacs.org/>.");
542 indexFile_->writeLine(formatString("* :doc:`%s <%s>` - %s",
543 displayName.c_str(), tag.c_str(),
544 module.shortDescription()));
545 manPagesFile_->writeLine(
546 formatString(" ('programs/%s', '%s', \"%s\", '', 1),",
547 tag.c_str(), tag.c_str(), module.shortDescription()));
550 void HelpExportReStructuredText::finishModuleExport()
554 manPagesFile_->writeLine(" ('man/gromacs.7', 'gromacs', 'molecular dynamics simulation suite', '', 7)");
555 manPagesFile_->writeLine("]");
556 manPagesFile_->close();
557 manPagesFile_.reset();
560 void HelpExportReStructuredText::startModuleGroupExport()
563 new File(outputRedirector_->openFileForWriting("programs/bytopic.rst")));
564 indexFile_->writeLine("Tools by Topic");
565 indexFile_->writeLine("==============");
567 new File(outputRedirector_->openFileForWriting("man/bytopic.rst")));
570 void HelpExportReStructuredText::exportModuleGroup(
572 const ModuleGroupContents &modules)
574 indexFile_->writeLine(title);
575 indexFile_->writeLine(std::string(std::strlen(title), '-'));
576 manPagesFile_->writeLine(title);
577 manPagesFile_->writeLine(std::string(std::strlen(title), '+'));
579 ModuleGroupContents::const_iterator module;
580 for (module = modules.begin(); module != modules.end(); ++module)
582 const std::string &tag(module->first);
583 std::string displayName(tag);
584 // TODO: This does not work if the binary name would contain a dash,
585 // but that is not currently the case.
586 const size_t dashPos = displayName.find('-');
587 GMX_RELEASE_ASSERT(dashPos != std::string::npos,
588 "There should always be at least one dash in the tag");
589 displayName[dashPos] = ' ';
590 indexFile_->writeLine(formatString("| :doc:`%s <%s>` - %s",
591 displayName.c_str(), tag.c_str(),
593 manPagesFile_->writeLine(formatString("| ``%s`` - %s",
597 indexFile_->writeLine();
598 manPagesFile_->writeLine();
601 void HelpExportReStructuredText::finishModuleGroupExport()
605 manPagesFile_->close();
606 manPagesFile_.reset();
609 void HelpExportReStructuredText::exportTopic(const HelpTopicInterface &topic)
611 const std::string path("programs/" + std::string(topic.name()) + ".rst");
612 File file(outputRedirector_->openFileForWriting(path));
613 HelpWriterContext context(&file, eHelpOutputFormat_Rst, &links_);
614 HelpManager manager(topic, context);
615 manager.writeCurrentTopic();
618 /********************************************************************
619 * HelpExportCompletion
623 * Implements export for command-line completion.
625 * \ingroup module_commandline
627 class HelpExportCompletion : public HelpExportInterface
630 //! Initializes completion exporter.
631 explicit HelpExportCompletion(const CommandLineHelpModuleImpl &helpModule);
633 virtual void startModuleExport();
634 virtual void exportModuleHelp(
635 const CommandLineModuleInterface &module,
636 const std::string &tag,
637 const std::string &displayName);
638 virtual void finishModuleExport();
640 virtual void startModuleGroupExport() {}
641 virtual void exportModuleGroup(const char * /*title*/,
642 const ModuleGroupContents & /*modules*/) {}
643 virtual void finishModuleGroupExport() {}
645 virtual void exportTopic(const HelpTopicInterface & /*topic*/) {}
648 ShellCompletionWriter bashWriter_;
649 std::vector<std::string> modules_;
652 HelpExportCompletion::HelpExportCompletion(
653 const CommandLineHelpModuleImpl &helpModule)
654 : bashWriter_(helpModule.binaryName_, eShellCompletionFormat_Bash)
658 void HelpExportCompletion::startModuleExport()
660 bashWriter_.startCompletions();
663 void HelpExportCompletion::exportModuleHelp(
664 const CommandLineModuleInterface &module,
665 const std::string & /*tag*/,
666 const std::string & /*displayName*/)
668 modules_.push_back(module.name());
670 CommandLineHelpContext context(&bashWriter_);
671 // We use the display name to pass the name of the module to the
672 // completion writer.
673 context.setModuleDisplayName(module.name());
674 module.writeHelp(context);
678 void HelpExportCompletion::finishModuleExport()
680 CommandLineCommonOptionsHolder optionsHolder;
681 optionsHolder.initOptions();
682 bashWriter_.writeWrapperCompletions(modules_, *optionsHolder.options());
683 bashWriter_.finishCompletions();
688 /********************************************************************
689 * CommandLineHelpModuleImpl implementation
692 CommandLineHelpModuleImpl::CommandLineHelpModuleImpl(
693 const ProgramContextInterface &programContext,
694 const std::string &binaryName,
695 const CommandLineModuleMap &modules,
696 const CommandLineModuleGroupList &groups)
697 : rootTopic_(new RootHelpTopic(*this)), programContext_(programContext),
698 binaryName_(binaryName), modules_(modules), groups_(groups),
699 context_(NULL), moduleOverride_(NULL), bHidden_(false),
700 outputRedirector_(&defaultFileOutputRedirector())
704 void CommandLineHelpModuleImpl::exportHelp(HelpExportInterface *exporter) const
706 // TODO: Would be nicer to have the file names supplied by the build system
707 // and/or export a list of files from here.
708 const char *const program = binaryName_.c_str();
710 exporter->startModuleExport();
711 CommandLineModuleMap::const_iterator module;
712 for (module = modules_.begin(); module != modules_.end(); ++module)
714 if (module->second->shortDescription() != NULL)
716 const char *const moduleName = module->first.c_str();
717 std::string tag(formatString("%s-%s", program, moduleName));
718 std::string displayName(formatString("%s %s", program, moduleName));
719 exporter->exportModuleHelp(*module->second, tag, displayName);
722 exporter->finishModuleExport();
724 exporter->startModuleGroupExport();
725 CommandLineModuleGroupList::const_iterator group;
726 for (group = groups_.begin(); group != groups_.end(); ++group)
728 exporter->exportModuleGroup((*group)->title(), (*group)->modules());
730 exporter->finishModuleGroupExport();
732 rootTopic_->exportHelp(exporter);
735 /********************************************************************
736 * CommandLineHelpModule
739 CommandLineHelpModule::CommandLineHelpModule(
740 const ProgramContextInterface &programContext,
741 const std::string &binaryName,
742 const CommandLineModuleMap &modules,
743 const CommandLineModuleGroupList &groups)
744 : impl_(new Impl(programContext, binaryName, modules, groups))
748 CommandLineHelpModule::~CommandLineHelpModule()
752 HelpTopicPointer CommandLineHelpModule::createModuleHelpTopic(
753 const CommandLineModuleInterface &module) const
755 return HelpTopicPointer(new ModuleHelpTopic(module, *impl_));
758 void CommandLineHelpModule::addTopic(HelpTopicPointer topic, bool bExported)
760 impl_->rootTopic_->addTopic(move(topic), bExported);
763 void CommandLineHelpModule::setShowHidden(bool bHidden)
765 impl_->bHidden_ = bHidden;
768 void CommandLineHelpModule::setModuleOverride(
769 const CommandLineModuleInterface &module)
771 impl_->moduleOverride_ = &module;
774 void CommandLineHelpModule::setOutputRedirector(
775 FileOutputRedirectorInterface *output)
777 impl_->outputRedirector_ = output;
780 int CommandLineHelpModule::run(int argc, char *argv[])
782 // Add internal topics lazily here.
783 addTopic(HelpTopicPointer(new CommandsHelpTopic(*impl_)), false);
785 const char *const exportFormats[] = { "rst", "completion" };
786 std::string exportFormat;
787 Options options(NULL, NULL);
788 options.addOption(StringOption("export").store(&exportFormat)
789 .enumValue(exportFormats));
790 CommandLineParser(&options).parse(&argc, argv);
791 if (!exportFormat.empty())
793 boost::scoped_ptr<HelpExportInterface> exporter;
794 if (exportFormat == "rst")
796 exporter.reset(new HelpExportReStructuredText(*impl_));
798 else if (exportFormat == "completion")
800 exporter.reset(new HelpExportCompletion(*impl_));
804 GMX_THROW(NotImplementedError("This help format is not implemented"));
806 impl_->exportHelp(exporter.get());
810 File &outputFile = impl_->outputRedirector_->standardOutput();
811 HelpLinks links(eHelpOutputFormat_Console);
812 initProgramLinks(&links, *impl_);
813 boost::scoped_ptr<CommandLineHelpContext> context(
814 new CommandLineHelpContext(&outputFile,
815 eHelpOutputFormat_Console, &links));
816 context->setShowHidden(impl_->bHidden_);
817 if (impl_->moduleOverride_ != NULL)
819 context->setModuleDisplayName(impl_->programContext_.displayName());
820 impl_->moduleOverride_->writeHelp(*context);
823 impl_->context_ = context.get();
825 HelpManager helpManager(*impl_->rootTopic_, context->writerContext());
828 for (int i = 1; i < argc; ++i)
830 helpManager.enterTopic(argv[i]);
833 catch (const InvalidInputError &ex)
835 fprintf(stderr, "%s\n", ex.what());
838 helpManager.writeCurrentTopic();
842 void CommandLineHelpModule::writeHelp(const CommandLineHelpContext &context) const
844 const HelpWriterContext &writerContext = context.writerContext();
846 if (writerContext.outputFormat() != eHelpOutputFormat_Console)
850 writerContext.writeTextBlock(
851 "Usage: [PROGRAM] help [<command>|<topic> [<subtopic> [...]]]");
852 // TODO: More information.