#include "gromacs/options/options.h"
#include "gromacs/options/optionsvisitor.h"
#include "gromacs/options/timeunitmanager.h"
+#include "gromacs/utility/arrayref.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/file.h"
#include "gromacs/utility/stringutil.h"
//! Sets the Options object to use for generating help.
explicit Impl(const Options &options);
+ //! Format the list of known issues.
+ void formatBugs(const HelpWriterContext &context);
+
//! Options object to use for generating help.
- const Options &options_;
+ const Options &options_;
+ //! List of bugs/knows issues.
+ ConstArrayRef<const char *> bugs_;
//! Time unit to show in descriptions.
- std::string timeUnit_;
+ std::string timeUnit_;
//! Whether to write descriptions to output.
- bool bShowDescriptions_;
+ bool bShowDescriptions_;
};
CommandLineHelpWriter::Impl::Impl(const Options &options)
{
}
+void CommandLineHelpWriter::Impl::formatBugs(const HelpWriterContext &context)
+{
+ if (bugs_.empty())
+ {
+ return;
+ }
+ context.writeTitle("Known Issues");
+ if (context.outputFormat() != eHelpOutputFormat_Console)
+ {
+ context.writeTextBlock("[UL]");
+ }
+ ConstArrayRef<const char *>::const_iterator i;
+ for (i = bugs_.begin(); i != bugs_.end(); ++i)
+ {
+ const char *const bug = *i;
+ // TODO: The context should be able to do this also for console output, but
+ // that requires a lot more elaborate parser for the markup.
+ if (context.outputFormat() == eHelpOutputFormat_Console)
+ {
+ TextLineWrapperSettings settings;
+ settings.setIndent(2);
+ settings.setFirstLineIndent(0);
+ settings.setLineLength(78);
+ context.outputFile().writeLine(
+ context.substituteMarkupAndWrapToString(
+ settings, formatString("* %s", bug)));
+ }
+ else
+ {
+ context.writeTextBlock(formatString("[LI]%s", bug));
+ }
+ }
+ if (context.outputFormat() != eHelpOutputFormat_Console)
+ {
+ context.writeTextBlock("[ul]");
+ }
+}
+
+
/********************************************************************
* CommandLineHelpWriter
*/
{
}
-CommandLineHelpWriter &CommandLineHelpWriter::setShowDescriptions(bool bSet)
+CommandLineHelpWriter &
+CommandLineHelpWriter::setShowDescriptions(bool bSet)
{
impl_->bShowDescriptions_ = bSet;
return *this;
}
-CommandLineHelpWriter &CommandLineHelpWriter::setTimeUnitString(const char *timeUnit)
+CommandLineHelpWriter &
+CommandLineHelpWriter::setTimeUnitString(const char *timeUnit)
{
impl_->timeUnit_ = timeUnit;
return *this;
}
+CommandLineHelpWriter &
+CommandLineHelpWriter::setKnownIssues(const ConstArrayRef<const char *> &bugs)
+{
+ impl_->bugs_ = bugs;
+ return *this;
+}
+
void CommandLineHelpWriter::writeHelp(const CommandLineHelpContext &context)
{
if (context.isCompletionExport())
filter.formatSelected(OptionsFilter::eSelectOtherOptions,
&formatter, impl_->options_);
formatter.finishSection();
+
+ impl_->formatBugs(writerContext);
}
} // namespace gmx
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,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.
class CommandLineHelpContext;
class Options;
+template <typename T> class ConstArrayRef;
+
/*! \brief
* Writes help information for Options in ascii format.
*
*/
CommandLineHelpWriter &setTimeUnitString(const char *timeUnit);
+ /*! \brief
+ * Sets the list of known bugs/limitations.
+ *
+ * \param[in] bugs Array of bugs/limitations.
+ *
+ * Each entry in the input array identifies a separate issue.
+ * The array passed should remain valid for the lifetime of the writer
+ * object.
+ */
+ CommandLineHelpWriter &
+ setKnownIssues(const ConstArrayRef<const char *> &bugs);
+
/*! \brief
* Writes the help.
*
#include "gromacs/legacyheaders/thread_mpi/threads.h"
#include "gromacs/commandline/cmdlinehelpcontext.h"
+#include "gromacs/commandline/cmdlinehelpwriter.h"
#include "gromacs/commandline/shellcompletions.h"
-#include "gromacs/commandline/wman.h"
#include "gromacs/fileio/timecontrol.h"
+#include "gromacs/options/basicoptions.h"
+#include "gromacs/options/filenameoption.h"
+#include "gromacs/options/options.h"
+#include "gromacs/utility/arrayref.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/gmxassert.h"
-
+#include "gromacs/utility/stringutil.h"
/* The source code in this file should be thread-safe.
Please keep it that way. */
gmx_bool is_hidden(t_pargs *pa)
{
- return ((strstr(pa->desc, "HIDDEN") != NULL) ||
- (strstr(pa->desc, "[hidden]") != NULL));
+ return (strstr(pa->desc, "HIDDEN") != NULL);
}
int nenum(const char *const enumc[])
return npargs+1;
}
-static char *mk_desc(t_pargs *pa, const char *time_unit_str)
+namespace gmx
{
- char *newdesc = NULL, *ndesc = NULL, *nptr = NULL;
- const char*ptr = NULL;
- int len, k;
-
- /* First compute length for description */
- len = strlen(pa->desc)+1;
- if ((ptr = strstr(pa->desc, "HIDDEN")) != NULL)
- {
- len += 4;
- }
- if (pa->type == etENUM)
- {
- len += 10;
- for (k = 1; (pa->u.c[k] != NULL); k++)
- {
- len += strlen(pa->u.c[k])+12;
- }
- }
- snew(newdesc, len);
- /* add label for hidden options */
- if (is_hidden(pa))
- {
- sprintf(newdesc, "[hidden] %s", ptr+6);
- }
- else
- {
- strcpy(newdesc, pa->desc);
- }
+namespace
+{
- /* change '%t' into time_unit */
-#define TUNITLABEL "%t"
-#define NTUNIT strlen(TUNITLABEL)
- if (pa->type == etTIME)
- {
- while ( (nptr = strstr(newdesc, TUNITLABEL)) != NULL)
- {
- nptr[0] = '\0';
- nptr += NTUNIT;
- len += strlen(time_unit_str)-NTUNIT;
- snew(ndesc, len);
- strcpy(ndesc, newdesc);
- strcat(ndesc, time_unit_str);
- strcat(ndesc, nptr);
- sfree(newdesc);
- newdesc = ndesc;
- ndesc = NULL;
- }
- }
-#undef TUNITLABEL
-#undef NTUNIT
+/*! \brief
+ * Converts a t_filenm option into an Options option.
+ *
+ * \param options Options object to add the new option to.
+ * \param[in] fnm t_filenm option to convert.
+ *
+ * \ingroup module_commandline
+ */
+void filenmToOptions(Options *options, const t_filenm *fnm)
+{
+ const bool bRead = ((fnm->flag & ffREAD) != 0);
+ const bool bWrite = ((fnm->flag & ffWRITE) != 0);
+ const bool bOptional = ((fnm->flag & ffOPT) != 0);
+ const bool bLibrary = ((fnm->flag & ffLIB) != 0);
+ const bool bMultiple = ((fnm->flag & ffMULT) != 0);
+ const char *const name = &fnm->opt[1];
+ const char * defName = fnm->fn;
+ if (defName == NULL)
+ {
+ defName = ftp2defnm(fnm->ftp);
+ }
+ // Since we are not (yet) using this for actual parsing, we don't need to
+ // set any storage.
+ options->addOption(
+ FileNameOption(name).defaultBasename(defName).legacyType(fnm->ftp)
+ .readWriteFlags(bRead, bWrite).required(!bOptional)
+ .libraryFile(bLibrary).multiValue(bMultiple)
+ .description(ftp2desc(fnm->ftp)));
+}
- /* Add extra comment for enumerateds */
- if (pa->type == etENUM)
- {
- strcat(newdesc, ": ");
- for (k = 1; (pa->u.c[k] != NULL); k++)
+/*! \brief
+ * Converts a t_pargs option into an Options option.
+ *
+ * \param options Options object to add the new option to.
+ * \param[in] pa t_pargs option to convert.
+ *
+ * \ingroup module_commandline
+ */
+void pargsToOptions(Options *options, t_pargs *pa)
+{
+ const bool bHidden = is_hidden(pa);
+ const char *const name = &pa->option[1];
+ const char *const desc = (bHidden ? &pa->desc[6] : pa->desc);
+ // Since we are not (yet) using this for actual parsing, we can take some
+ // shortcuts and not set any storage where there is no direct
+ // correspondence in the types.
+ switch (pa->type)
+ {
+ case etINT:
+ options->addOption(
+ IntegerOption(name).store(pa->u.i)
+ .description(desc).hidden(bHidden));
+ return;
+ case etINT64:
+ options->addOption(
+ Int64Option(name).store(pa->u.is)
+ .description(desc).hidden(bHidden));
+ return;
+ case etREAL:
+ options->addOption(
+ RealOption(name).store(pa->u.r)
+ .description(desc).hidden(bHidden));
+ return;
+ case etTIME:
+ options->addOption(
+ RealOption(name).store(pa->u.r).timeValue()
+ .description(desc).hidden(bHidden));
+ return;
+ case etSTR:
{
- strcat(newdesc, "[TT]");
- strcat(newdesc, pa->u.c[k]);
- strcat(newdesc, "[tt]");
- /* Print a comma everywhere but at the last one */
- if (pa->u.c[k+1] != NULL)
- {
- if (pa->u.c[k+2] == NULL)
- {
- strcat(newdesc, " or ");
- }
- else
- {
- strcat(newdesc, ", ");
- }
- }
+ const char *const defValue = (*pa->u.c != NULL ? *pa->u.c : "");
+ options->addOption(
+ StringOption(name).defaultValue(defValue)
+ .description(desc).hidden(bHidden));
+ return;
}
- }
- return newdesc;
+ case etBOOL:
+ options->addOption(
+ BooleanOption(name).defaultValue(*pa->u.b)
+ .description(desc).hidden(bHidden));
+ return;
+ case etRVEC:
+ options->addOption(
+ RealOption(name).store(*pa->u.rv).vector()
+ .description(desc).hidden(bHidden));
+ return;
+ case etENUM:
+ options->addOption(
+ StringOption(name).defaultEnumIndex(nenum(pa->u.c))
+ .enumValueFromNullTerminatedArray(pa->u.c + 1)
+ .description(desc).hidden(bHidden));
+ return;
+ }
+ GMX_THROW(NotImplementedError("Argument type not implemented"));
}
+} // namespace
+
+} // namespace gmx
gmx_bool parse_common_args(int *argc, char *argv[], unsigned long Flags,
int nfile, t_filenm fnm[], int npargs, t_pargs *pa,
memcpy(&(pa[i]), &(all_pa[k]), (size_t)sizeof(pa[i]));
}
-
- for (i = 0; (i < npall); i++)
- {
- all_pa[i].desc = mk_desc(&(all_pa[i]), output_env_get_time_unit(*oenv));
- }
-
#if (defined __sgi && USE_SGI_FPE)
doexceptions();
#endif
}
else
{
- write_man(*context, ndesc, desc, nfile, fnm, npall, all_pa, nbugs, bugs);
+ gmx::Options options(NULL, NULL);
+ options.setDescription(gmx::ConstArrayRef<const char *>(desc, ndesc));
+ for (i = 0; i < nfile; i++)
+ {
+ gmx::filenmToOptions(&options, &fnm[i]);
+ }
+ for (i = 0; i < npall; i++)
+ {
+ gmx::pargsToOptions(&options, &all_pa[i]);
+ }
+ gmx::CommandLineHelpWriter(options)
+ .setShowDescriptions(true)
+ .setTimeUnitString(output_env_get_time_unit(*oenv))
+ .setKnownIssues(gmx::ConstArrayRef<const char *>(bugs, nbugs))
+ .writeHelp(*context);
}
}
}
}
/* clear memory */
- for (i = 0; i < npall; ++i)
- {
- sfree((void *)all_pa[i].desc);
- }
sfree(all_pa);
if (!FF(PCA_NOEXIT_ON_ARGS))
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2012,2013, 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
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, 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 http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-#include "gromacs/commandline/wman.h"
-
-#include <cstdio>
-#include <cstring>
-
-#include <string>
-
-#include "gromacs/commandline/cmdlinehelpcontext.h"
-#include "gromacs/fileio/filenm.h"
-#include "gromacs/utility/exceptions.h"
-#include "gromacs/utility/file.h"
-#include "gromacs/utility/gmxassert.h"
-#include "gromacs/utility/stringutil.h"
-
-#include "gmx_fatal.h"
-#include "string2.h"
-#include "smalloc.h"
-
-/* The source code in this file should be thread-safe.
- * Please keep it that way. */
-
-static std::string check(const char *s, const gmx::HelpWriterContext &context)
-{
- return context.substituteMarkupAndWrapToString(gmx::TextLineWrapperSettings(), s);
-}
-
-static std::string check(const char *s, const gmx::CommandLineHelpContext &context)
-{
- return check(s, context.writerContext());
-}
-
-#define FLAG_SET(flag, mask) ((flag &mask) == mask)
-/* Return a string describing the file type in flag.
- * flag should the flag field of a filenm struct.
- * You have to provide a buffer and buffer length in which
- * the result will be written. The returned pointer is just
- * a pointer to this buffer.
- */
-static char *fileopt(unsigned long flag, char buf[])
-{
- char tmp[256];
-
- if (FLAG_SET(flag, ffRW))
- {
- sprintf(tmp, "In/Out");
- }
- else if (FLAG_SET(flag, ffREAD))
- {
- sprintf(tmp, "Input");
- }
- else if (FLAG_SET(flag, ffWRITE))
- {
- sprintf(tmp, "Output");
- }
- else
- {
- sprintf(tmp, "Dunno");
- }
-
- if (FLAG_SET(flag, ffOPT))
- {
- strcat(tmp, ", Opt");
- if (FLAG_SET(flag, ffSET))
- {
- strcat(tmp, "!");
- }
- else
- {
- strcat(tmp, ".");
- }
- }
- if (FLAG_SET(flag, ffLIB))
- {
- strcat(tmp, ", Lib.");
- }
- if (FLAG_SET(flag, ffMULT))
- {
- strcat(tmp, ", Mult.");
- }
-
- sprintf(buf, "%s", tmp);
-
- return buf;
-}
-
-#define OPTLEN 4
-#define NAMELEN 14
-static void pr_fns(FILE *fp, int nf, const t_filenm tfn[])
-{
- int i, f;
- size_t j;
- char buf[256], *wbuf, opt_buf[32];
-
- fprintf(fp, "%6s %12s %-12s %s\n", "Option", "Filename", "Type",
- "Description");
- fprintf(fp,
- "------------------------------------------------------------\n");
- for (i = 0; (i < nf); i++)
- {
- for (f = 0; (f < tfn[i].nfiles); f++)
- {
- sprintf(buf, "%4s %14s %-12s ", (f == 0) ? tfn[i].opt : "",
- tfn[i].fns[f], (f == 0) ? fileopt(tfn[i].flag, opt_buf)
- : "");
- if (f < tfn[i].nfiles - 1)
- {
- fprintf(fp, "%s\n", buf);
- }
- }
- if (tfn[i].nfiles > 0)
- {
- strcat(buf, ftp2desc(tfn[i].ftp));
- if ((strlen(tfn[i].opt) > OPTLEN)
- && (strlen(tfn[i].opt) <= ((OPTLEN + NAMELEN)
- - strlen(tfn[i].fns[tfn[i].nfiles - 1]))))
- {
- for (j = strlen(tfn[i].opt); j < strlen(buf)
- - (strlen(tfn[i].opt) - OPTLEN) + 1; j++)
- {
- buf[j] = buf[j + strlen(tfn[i].opt) - OPTLEN];
- }
- }
- wbuf = wrap_lines(buf, 78, 35, FALSE);
- fprintf(fp, "%s\n", wbuf);
- sfree(wbuf);
- }
- }
- fprintf(fp, "\n");
- fflush(fp);
-}
-#undef OPTLEN
-#undef NAMELEN
-
-/* name to print in help info for command line arguments
- * (defined in enum in readinp.h) */
-static const char *get_arg_desc(int type)
-{
- const char *const argtp[etNR] = {
- "int", "step", "real", "time", "string", "bool", "vector", "enum"
- };
- return argtp[type];
-}
-
-/* Return the value of pa in the provided buffer buf, of size sz.
- * The return value is also a pointer to buf.
- */
-static char *pa_val(t_pargs *pa, char buf[], int sz)
-{
- real r;
- char buf_str[1256]; buf_str[0] = '\0';
-
- buf[0] = '\0';
-
- GMX_RELEASE_ASSERT(sz >= 255, "Buffer must be at least 255 chars");
-
- switch (pa->type)
- {
- case etINT:
- sprintf(buf, "%-d", *(pa->u.i));
- break;
- case etINT64:
- sprintf(buf, "%" GMX_PRId64, *(pa->u.is));
- break;
- case etTIME:
- case etREAL:
- r = *(pa->u.r);
- sprintf(buf_str, "%-6g", r);
- strcpy(buf, buf_str);
- break;
- case etBOOL:
- sprintf(buf, "%-6s", *(pa->u.b) ? "yes" : "no");
- break;
- case etSTR:
- if (*(pa->u.c))
- {
- if (strlen(*(pa->u.c)) >= (size_t)sz)
- {
- gmx_fatal(FARGS, "Argument too long: \"%d\"\n", *(pa->u.c));
- }
- else
- {
- strcpy(buf, *(pa->u.c));
- }
- }
- break;
- case etENUM:
- strcpy(buf, *(pa->u.c));
- break;
- case etRVEC:
- sprintf(buf, "%g %g %g", (*pa->u.rv)[0],
- (*pa->u.rv)[1],
- (*pa->u.rv)[2]);
- break;
- }
- return buf;
-}
-
-#define OPTLEN 12
-#define TYPELEN 6
-#define LONGSTR 1024
-static char *pargs_print_line(t_pargs *pa, const gmx::HelpWriterContext &context)
-{
- char buf[LONGSTR], *buf2, *tmp;
-
- snew(buf2, LONGSTR+strlen(pa->desc));
- snew(tmp, LONGSTR+strlen(pa->desc));
-
- if (pa->type == etBOOL)
- {
- sprintf(buf, "-[no]%s", pa->option+1);
- }
- else
- {
- strcpy(buf, pa->option);
- }
- std::string desc = check(pa->desc, context);
- if ((int)strlen(buf) > ((OPTLEN+TYPELEN)-std::max((int)strlen(get_arg_desc(pa->type)), 4)))
- {
- sprintf(buf2, "%s %-6s %-6s %-s\n",
- buf, get_arg_desc(pa->type), pa_val(pa, tmp, LONGSTR-1),
- desc.c_str());
- }
- else if (strlen(buf) > OPTLEN)
- {
- /* so type can be 3 or 4 char's, this fits in the %4s */
- sprintf(buf2, "%-14s %-4s %-6s %-s\n",
- buf, get_arg_desc(pa->type), pa_val(pa, tmp, LONGSTR-1),
- desc.c_str());
- }
- else
- {
- sprintf(buf2, "%-12s %-6s %-6s %-s\n",
- buf, get_arg_desc(pa->type), pa_val(pa, tmp, LONGSTR-1),
- desc.c_str());
- }
- sfree(tmp);
-
- tmp = wrap_lines(buf2, 78, 28, FALSE);
-
- sfree(buf2);
-
- return tmp;
-}
-#undef OPTLEN
-#undef TYPELEN
-#undef LONGSTR
-
-static void print_pargs(FILE *fp, int npargs, t_pargs pa[],
- const gmx::HelpWriterContext &context)
-{
- if (npargs > 0)
- {
- fprintf(fp, "%-12s %-6s %-6s %-s\n",
- "Option", "Type", "Value", "Description");
- fprintf(fp, "------------------------------------------------------\n");
- for (int i = 0; i < npargs; i++)
- {
- char *wdesc = pargs_print_line(&pa[i], context);
- fprintf(fp, "%s", wdesc);
- sfree(wdesc);
- }
- fprintf(fp, "\n");
- }
-}
-
-static void write_nroffman(FILE *out,
- int nldesc, const char **desc,
- int nfile, t_filenm *fnm,
- int npargs, t_pargs *pa,
- int nbug, const char **bugs,
- const gmx::CommandLineHelpContext &context)
-{
- int i;
- char tmp[256];
-
- fprintf(out, ".SH SYNOPSIS\n");
- fprintf(out, "\\f3%s\\fP\n", context.moduleDisplayName());
-
- /* command line arguments */
- if (nfile > 0)
- {
- for (i = 0; (i < nfile); i++)
- {
- fprintf(out, ".BI \"%s\" \" %s \"\n",
- check(fnm[i].opt, context).c_str(),
- check(fnm[i].fns[0], context).c_str());
- }
- }
- if (npargs > 0)
- {
- for (i = 0; (i < npargs); i++)
- {
- if (pa[i].type == etBOOL)
- {
- fprintf(out, ".BI \"\\-[no]%s\" \"\"\n",
- check(pa[i].option+1, context).c_str());
- }
- else
- {
- fprintf(out, ".BI \"%s\" \" %s \"\n",
- check(pa[i].option, context).c_str(),
- check(get_arg_desc(pa[i].type), context).c_str());
- }
- }
- }
-
- /* description */
- if (nldesc > 0)
- {
- fprintf(out, ".SH DESCRIPTION\n");
- for (i = 0; (i < nldesc); i++)
- {
- fprintf(out, "\\&%s\n", check(desc[i], context).c_str());
- }
- }
-
- /* FILES */
- if (nfile > 0)
- {
- fprintf(out, ".SH FILES\n");
- for (i = 0; (i < nfile); i++)
- {
- fprintf(out, ".BI \"%s\" \" %s\" \n.B %s\n %s \n\n",
- check(fnm[i].opt, context).c_str(),
- check(fnm[i].fns[0], context).c_str(),
- check(fileopt(fnm[i].flag, tmp), context).c_str(),
- check(ftp2desc(fnm[i].ftp), context).c_str());
- }
- }
-
- /* other options */
- fprintf(out, ".SH OTHER OPTIONS\n");
- if (npargs > 0)
- {
- for (i = 0; (i < npargs); i++)
- {
- if (pa[i].type == etBOOL)
- {
- fprintf(out, ".BI \"\\-[no]%s\" \"%s\"\n %s\n\n",
- check(pa[i].option+1, context).c_str(),
- check(pa_val(&(pa[i]), tmp, 255), context).c_str(),
- check(pa[i].desc, context).c_str());
- }
- else
- {
- fprintf(out, ".BI \"%s\" \" %s\" \" %s\" \n %s\n\n",
- check(pa[i].option, context).c_str(),
- check(get_arg_desc(pa[i].type), context).c_str(),
- check(pa_val(&(pa[i]), tmp, 255), context).c_str(),
- check(pa[i].desc, context).c_str());
- }
- }
- }
-
- if (nbug > 0)
- {
- fprintf(out, ".SH KNOWN PROBLEMS\n");
- for (i = 0; (i < nbug); i++)
- {
- fprintf(out, "\\- %s\n\n", check(bugs[i], context).c_str());
- }
- }
-}
-
-static void
-print_tty_formatted(FILE *out, int nldesc, const char **desc,
- const gmx::HelpWriterContext &context)
-{
- char *buf;
- int buflen, i;
-
- buflen = 80*nldesc;
- snew(buf, buflen);
- for (i = 0; (i < nldesc); i++)
- {
- if ((strlen(buf) > 0) &&
- (buf[strlen(buf)-1] != ' ') && (buf[strlen(buf)-1] != '\n'))
- {
- strcat(buf, " ");
- }
- std::string temp = check(desc[i], context);
- if (strlen(buf) + temp.length() >= (size_t)(buflen-2))
- {
- buflen += temp.length();
- srenew(buf, buflen);
- }
- strcat(buf, temp.c_str());
- }
- /* Make lines of at most 79 characters */
- char *temp = wrap_lines(buf, 78, 0, FALSE);
- fprintf(out, "%s\n", temp);
- sfree(temp);
- sfree(buf);
-}
-
-static void write_ttyman(FILE *out,
- int nldesc, const char **desc,
- int nfile, t_filenm *fnm,
- int npargs, t_pargs *pa,
- int nbug, const char **bugs,
- const gmx::HelpWriterContext &context)
-{
- int i;
- char *tmp;
-
- if (nldesc > 0)
- {
- fprintf(out, "DESCRIPTION\n-----------\n");
- print_tty_formatted(out, nldesc, desc, context);
- }
- if (nbug > 0)
- {
- fprintf(out, "\n");
- fprintf(out, "KNOWN PROBLEMS\n----------\n");
- for (i = 0; i < nbug; i++)
- {
- snew(tmp, strlen(bugs[i])+3);
- strcpy(tmp, "* ");
- strcpy(tmp+2, check(bugs[i], context).c_str());
- fprintf(out, "%s\n", wrap_lines(tmp, 78, 2, FALSE));
- sfree(tmp);
- }
- }
- if (nfile > 0)
- {
- fprintf(out, "\n");
- pr_fns(out, nfile, fnm);
- }
- if (npargs > 0)
- {
- print_pargs(out, npargs, pa, context);
- }
-}
-
-static void pr_html_files(FILE *out, int nfile, t_filenm fnm[],
- const gmx::HelpWriterContext &context)
-{
- int i;
- char link[10], tmp[255];
-
- fprintf(out,
- "<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=2>\n"
- "<TR>"
- "<TH>option</TH>"
- "<TH>filename</TH>"
- "<TH>type</TH>"
- "<TH>description</TH>"
- "</TR>\n");
-
- for (i = 0; (i < nfile); i++)
- {
- strcpy(link, ftp2ext(fnm[i].ftp));
- if (strcmp(link, "???") == 0)
- {
- strcpy(link, "files");
- }
- fprintf(out,
- "<TR>"
- "<TD ALIGN=RIGHT> <b><tt>%s</tt></b> </TD>"
- "<TD ALIGN=RIGHT> <tt><a href=\"%s.html\">%12s</a></tt> </TD>"
- "<TD> %s </TD>"
- "<TD> %s </TD>"
- "</TR>\n",
- fnm[i].opt, link, fnm[i].fns[0], fileopt(fnm[i].flag, tmp),
- check(ftp2desc(fnm[i].ftp), context).c_str());
- }
- fprintf(out, "</TABLE>\n");
-}
-
-static void write_htmlman(FILE *out,
- int nldesc, const char **desc,
- int nfile, t_filenm *fnm,
- int npargs, t_pargs *pa,
- int nbug, const char **bugs,
- const gmx::HelpWriterContext &context)
-{
- int i;
- char tmp[255];
-
- if (nldesc > 0)
- {
- fprintf(out, "<H3>Description</H3>\n<p>\n");
- for (i = 0; (i < nldesc); i++)
- {
- fprintf(out, "%s\n", check(desc[i], context).c_str());
- }
- }
- if (nfile > 0)
- {
- fprintf(out, "<P>\n");
- fprintf(out, "<H3>Files</H3>\n");
- pr_html_files(out, nfile, fnm, context);
- }
- if (npargs > 0)
- {
- fprintf(out, "<P>\n");
- fprintf(out, "<H3>Other options</H3>\n");
- fprintf(out,
- "<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=2>\n"
- "<TR>"
- "<TH>option</TH>"
- "<TH>type</TH>"
- "<TH>default</TH>"
- "<TH>description</TH>"
- "</TR>\n");
- for (i = 0; (i < npargs); i++)
- {
- fprintf(out,
- "<TR>"
- "<TD ALIGN=RIGHT> <b><tt>%s%s</tt></b> </TD>"
- "<TD ALIGN=RIGHT> %s </TD>"
- "<TD ALIGN=RIGHT> <tt>%s</tt> </TD>"
- "<TD> %s </TD>"
- "</TD>\n",
- (pa[i].type == etBOOL) ? "-[no]" : "-", pa[i].option+1,
- get_arg_desc(pa[i].type), pa_val(&(pa[i]), tmp, 255),
- check(pa[i].desc, context).c_str());
- }
- fprintf(out, "</TABLE>\n");
- }
- if (nbug > 0)
- {
- fprintf(out, "<P>\n");
- fprintf(out, "<H3>Known problems</H3>\n");
- fprintf(out, "<UL>\n");
- for (i = 0; (i < nbug); i++)
- {
- fprintf(out, "<LI>%s\n", check(bugs[i], context).c_str());
- }
- fprintf(out, "</UL>\n");
- }
-}
-
-void write_man(const gmx::CommandLineHelpContext &context,
- int nldesc, const char **desc,
- int nfile, t_filenm *fnm,
- int npargs, t_pargs *pa,
- int nbug, const char **bugs)
-{
- FILE *out = context.writerContext().outputFile().handle();
- const bool bHidden = context.showHidden();
-
- int npar;
- t_pargs *par;
-
- if (bHidden)
- {
- npar = npargs;
- par = pa;
- }
- else
- {
- snew(par, npargs);
- npar = 0;
- for (int i = 0; i < npargs; i++)
- {
- if (!is_hidden(&pa[i]))
- {
- par[npar] = pa[i];
- npar++;
- }
- }
- }
-
- switch (context.writerContext().outputFormat())
- {
- case gmx::eHelpOutputFormat_Man:
- write_nroffman(out, nldesc, desc, nfile, fnm, npar, par, nbug, bugs,
- context);
- break;
- case gmx::eHelpOutputFormat_Console:
- write_ttyman(out, nldesc, desc, nfile, fnm, npar, par, nbug, bugs,
- context.writerContext());
- break;
- case gmx::eHelpOutputFormat_Html:
- write_htmlman(out, nldesc, desc, nfile, fnm, npar, par, nbug, bugs,
- context.writerContext());
- break;
- default:
- GMX_THROW(gmx::NotImplementedError("Help format not implemented"));
- }
-
- if (!bHidden)
- {
- sfree(par);
- }
-}
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013, 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
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, 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 http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-#ifndef GMX_COMMANDLINE_WMAN_H
-#define GMX_COMMANDLINE_WMAN_H
-
-#include "gromacs/commandline/pargs.h"
-#include "gromacs/fileio/filenm.h"
-
-namespace gmx
-{
-class CommandLineHelpContext;
-} // namespace gmx
-
-void write_man(const gmx::CommandLineHelpContext &context,
- int nldesc, const char **desc,
- int nfile, t_filenm *fnm,
- int npargs, t_pargs *pa,
- int nbug, const char **bugs);
-
-#endif
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2004, The GROMACS development team,
- * Copyright (c) 2013, by the GROMACS development team, led by
+ * Copyright (c) 2001-2004, The GROMACS development team.
+ * Copyright (c) 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.
deffile[efNR] =
{
{ eftASC, ".mdp", "grompp", "-f", "grompp input file with MD parameters" },
- { eftGEN, ".???", "traj", "-f",
- "Trajectory: tng xtc trr trj gro g96 pdb cpt", NTRXS, trxs },
- { eftGEN, ".???", "trajout", "-f",
- "Trajectory: tng xtc trr trj gro g96 pdb", NTROS, tros },
+ { eftGEN, ".???", "traj", "-f", "Trajectory", NTRXS, trxs },
+ { eftGEN, ".???", "trajout", "-f", "Trajectory", NTROS, tros },
{ eftGEN, ".???", "traj", NULL,
- "Full precision trajectory: tng trr trj cpt", NTRNS, trns },
+ "Full precision trajectory", NTRNS, trns },
{ eftXDR, ".trr", "traj", NULL, "Trajectory in portable xdr format" },
{ eftBIN, ".trj", "traj", NULL, "Trajectory file (architecture specific)" },
{ eftGEN, ".???", "traj_comp", NULL,
- "Compressed trajectory (tng format or portable xdr format): tng xtc", NTRCOMPRESSED, trcompressed},
+ "Compressed trajectory (tng format or portable xdr format)", NTRCOMPRESSED, trcompressed},
{ eftXDR, ".xtc", "traj", NULL,
"Compressed trajectory (portable xdr format): xtc" },
{ eftTNG, ".tng", "traj", NULL,
"Trajectory file (tng format)" },
{ eftASC, ".g87", "gtraj", NULL, "Gromos-87 ASCII trajectory format" },
{ eftXDR, ".edr", "ener", NULL, "Energy file"},
- { eftGEN, ".???", "conf", "-c", "Structure file: gro g96 pdb tpr etc.",
- NSTXS, stxs },
- { eftGEN, ".???", "out", "-o", "Structure file: gro g96 pdb etc.",
- NSTOS, stos },
+ { eftGEN, ".???", "conf", "-c", "Structure file", NSTXS, stxs },
+ { eftGEN, ".???", "out", "-o", "Structure file", NSTOS, stos },
{ eftASC, ".gro", "conf", "-c", "Coordinate file in Gromos-87 format" },
{ eftASC, ".g96", "conf", "-c", "Coordinate file in Gromos-96 format" },
{ eftASC, ".pdb", "eiwit", "-f", "Protein data bank file"},
{ eftASC, ".ndx", "index", "-n", "Index file", },
{ eftASC, ".top", "topol", "-p", "Topology file"},
{ eftASC, ".itp", "topinc", NULL, "Include file for topology"},
- { eftGEN, ".???", "topol", "-s", "Run input file: tpr tpb tpa",
- NTPXS, tpxs },
- { eftGEN, ".???", "topol", "-s",
- "Structure+mass(db): tpr tpb tpa gro g96 pdb", NTPSS, tpss },
+ { eftGEN, ".???", "topol", "-s", "Run input file", NTPXS, tpxs },
+ { eftGEN, ".???", "topol", "-s", "Structure+mass(db)", NTPSS, tpss },
{ eftXDR, ".tpr", "topol", "-s", "Portable xdr run input file"},
{ eftASC, ".tpa", "topol", "-s", "Ascii run input file"},
{ eftBIN, ".tpb", "topol", "-s", "Binary run input file"},
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2008, The GROMACS development team.
- * Copyright (c) 2013, by the GROMACS development team, led by
+ * Copyright (c) 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.
"one particle" },
{ "-fitstart", FALSE, etREAL, {&fit_start},
"Time (ps) from which to start fitting the correlation functions in order to obtain the forward and backward rate constants for HB breaking and formation. With [TT]-gemfit[tt] we suggest [TT]-fitstart 0[tt]" },
- { "-fitstart", FALSE, etREAL, {&fit_start},
+ { "-fitend", FALSE, etREAL, {&fit_end},
"Time (ps) to which to stop fitting the correlation functions in order to obtain the forward and backward rate constants for HB breaking and formation (only with [TT]-gemfit[tt])" },
{ "-temp", FALSE, etREAL, {&temp},
"Temperature (K) for computing the Gibbs energy corresponding to HB breaking and reforming" },
{ "[tanh]", ")" },
{ "[PAR]", "\n\n" },
{ "[BR]", "\n"},
+ /* [UL], [LI], [ul] cannot be implemented properly with the current
+ * approach. */
{ "[GRK]", "" },
{ "[grk]", "" }
};
{ "[tanh]", ")" },
{ "[PAR]", "\n\n" },
{ "\n ", "\n" },
+ // The following three work only in the specific context in which they are
+ // currently used.
+ { "[UL]", "" },
+ { "[LI]", "\n- " },
+ { "[ul]", "" },
{ "<", "" },
{ ">", "" },
{ "^", "" },
{ "[tanh]", ")" },
{ "[PAR]", "<p>" },
{ "[BR]", "<br>" },
+ { "[UL]", "<ul>" },
+ { "[LI]", "<li>" },
+ { "[ul]", "</ul>" },
{ "[GRK]", "&" },
{ "[grk]", ";" }
};
//! Requires exactly \p count values for the option.
MyClass &valueCount(int count) { setValueCount(count); return me(); }
//! Allows any number of values for the option.
- MyClass &multiValue() { maxValueCount_ = -1; return me(); }
+ MyClass &multiValue(bool bMulti = true)
+ { if (bMulti) { maxValueCount_ = -1; } return me(); }
/*! \brief
* Sets a default value for the option.
//! Returns a singleton instance of this class.
static const FileTypeRegistry &instance();
//! Returns a handler for a single file type.
- const FileTypeHandler &handlerForType(OptionFileType type) const;
+ const FileTypeHandler &
+ handlerForType(OptionFileType type, int legacyType) const;
private:
//! Initializes the file type registry.
FileTypeRegistry();
//! Registers a file type that corresponds to a ftp in filenm.h.
- void registerType(OptionFileType type, int ftp);
+ void registerType(int type, int ftp);
//! Registers a file type with a single extension.
- void registerType(OptionFileType type, const char *extension);
+ void registerType(int type, const char *extension);
std::vector<FileTypeHandler> filetypes_;
};
}
const FileTypeHandler &
-FileTypeRegistry::handlerForType(OptionFileType type) const
+FileTypeRegistry::handlerForType(OptionFileType type, int legacyType) const
{
- GMX_RELEASE_ASSERT(type >= 0 && static_cast<size_t>(type) < filetypes_.size(),
+ int index = type;
+ if (type == eftUnknown && legacyType >= 0)
+ {
+ index = eftOptionFileType_NR + legacyType;
+ }
+ GMX_RELEASE_ASSERT(index >= 0 && static_cast<size_t>(index) < filetypes_.size(),
"Invalid file type");
- return filetypes_[type];
+ return filetypes_[index];
}
FileTypeRegistry::FileTypeRegistry()
{
- filetypes_.resize(eftOptionFileType_NR);
+ filetypes_.resize(eftOptionFileType_NR + efNR);
registerType(eftTopology, efTPS);
registerType(eftTrajectory, efTRX);
registerType(eftPDB, efPDB);
registerType(eftIndex, efNDX);
registerType(eftPlot, efXVG);
registerType(eftGenericData, efDAT);
+ for (int i = 0; i < efNR; ++i)
+ {
+ registerType(eftOptionFileType_NR + i, i);
+ }
}
-void FileTypeRegistry::registerType(OptionFileType type, int ftp)
+void FileTypeRegistry::registerType(int type, int ftp)
{
GMX_RELEASE_ASSERT(type >= 0 && static_cast<size_t>(type) < filetypes_.size(),
"Invalid file type");
}
}
-void FileTypeRegistry::registerType(OptionFileType type,
- const char *extension)
+void FileTypeRegistry::registerType(int type, const char *extension)
{
GMX_RELEASE_ASSERT(type >= 0 && static_cast<size_t>(type) < filetypes_.size(),
"Invalid file type");
/*! \brief
* Helper method to complete a file name provided to a file name option.
*
- * \param[in] value Value provided to the file name option.
- * \param[in] filetype File type for the option.
+ * \param[in] value Value provided to the file name option.
+ * \param[in] filetype File type for the option.
+ * \param[in] legacyType If \p filetype is eftUnknown, this gives the type as
+ * an enum value from filenm.h.
* \param[in] bCompleteToExisting
- * Whether to check existing files when completing the extension.
+ * Whether to check existing files when completing the extension.
* \returns \p value with possible extension added.
*/
std::string completeFileName(const std::string &value, OptionFileType filetype,
- bool bCompleteToExisting)
+ int legacyType, bool bCompleteToExisting)
{
if (bCompleteToExisting && File::exists(value))
{
return value;
}
const FileTypeRegistry ®istry = FileTypeRegistry::instance();
- const FileTypeHandler &typeHandler = registry.handlerForType(filetype);
+ const FileTypeHandler &typeHandler = registry.handlerForType(filetype, legacyType);
if (typeHandler.hasKnownExtension(value))
{
return value;
FileNameOptionStorage::FileNameOptionStorage(const FileNameOption &settings)
: MyBase(settings), info_(this), filetype_(settings.filetype_),
+ legacyType_(settings.legacyType_),
bRead_(settings.bRead_), bWrite_(settings.bWrite_),
bLibrary_(settings.bLibrary_)
{
if (settings.defaultBasename_ != NULL)
{
std::string defaultValue =
- completeFileName(settings.defaultBasename_, filetype_, false);
+ completeFileName(settings.defaultBasename_, filetype_,
+ legacyType_, false);
setDefaultValueIfSet(defaultValue);
if (isRequired())
{
std::string FileNameOptionStorage::typeString() const
{
const FileTypeRegistry ®istry = FileTypeRegistry::instance();
- const FileTypeHandler &typeHandler = registry.handlerForType(filetype_);
+ const FileTypeHandler &typeHandler = registry.handlerForType(filetype_, legacyType_);
const ExtensionList &extensions = typeHandler.extensions();
std::string result;
ExtensionList::const_iterator i;
}
if (result.empty())
{
- result = "file";
+ if (legacyType_ == efRND)
+ {
+ result = "dir";
+ }
+ else
+ {
+ result = "file";
+ }
}
return result;
}
std::string FileNameOptionStorage::formatExtraDescription() const
{
const FileTypeRegistry ®istry = FileTypeRegistry::instance();
- const FileTypeHandler &typeHandler = registry.handlerForType(filetype_);
+ const FileTypeHandler &typeHandler = registry.handlerForType(filetype_, legacyType_);
const ExtensionList &extensions = typeHandler.extensions();
std::string result;
if (extensions.size() > 2)
void FileNameOptionStorage::convertValue(const std::string &value)
{
bool bInput = isInputFile() || isInputOutputFile();
- addValue(completeFileName(value, filetype_, bInput));
+ addValue(completeFileName(value, filetype_, legacyType_, bInput));
}
/********************************************************************
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2014, by the GROMACS development team, led by
+ * 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.
//! Initializes an option with the given name.
explicit FileNameOption(const char *name)
- : MyBase(name), filetype_(eftUnknown), defaultBasename_(NULL),
+ : MyBase(name), filetype_(eftUnknown), legacyType_(-1),
+ defaultBasename_(NULL),
bRead_(false), bWrite_(false), bLibrary_(false)
{
}
/*! \brief
* Sets the type of the file this option accepts.
*
- * This attribute must be provided.
+ * Either this attribute or legacyType() must be provided.
*/
MyClass &filetype(OptionFileType type)
{ filetype_ = type; return me(); }
+ /*! \brief
+ * Sets the type of the file from an enum in filenm.h.
+ *
+ * New code should prefer filetype(), extending the enumeration if
+ * necessary.
+ */
+ MyClass &legacyType(int type)
+ { legacyType_ = type; return me(); }
//! Tells that the file provided by this option is used for input only.
MyClass &inputFile()
{ bRead_ = true; bWrite_ = false; return me(); }
*/
MyClass &inputOutputFile()
{ bRead_ = bWrite_ = true; return me(); }
+ /*! \brief
+ * Sets the read/write usage for this file from boolean flags.
+ */
+ MyClass &readWriteFlags(bool bRead, bool bWrite)
+ { bRead_ = bRead; bWrite_ = bWrite; return me(); }
/*! \brief
* Tells that the file will be looked up in library directories in
* addition to working directory.
* directories. It would be nicer to do this searching within the
* file name option implementation.
*/
- MyClass &libraryFile() { bLibrary_ = true; return me(); }
+ MyClass &libraryFile(bool bLibrary = true)
+ { bLibrary_ = bLibrary; return me(); }
/*! \brief
* Sets a default basename for the file option.
*
virtual AbstractOptionStoragePointer createStorage() const;
OptionFileType filetype_;
+ int legacyType_;
const char *defaultBasename_;
bool bRead_;
bool bWrite_;
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2014, by the GROMACS development team, led by
+ * 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.
FileNameOptionInfo info_;
OptionFileType filetype_;
+ int legacyType_;
bool bRead_;
bool bWrite_;
bool bLibrary_;