Reorganize help writing code.
authorTeemu Murtola <teemu.murtola@gmail.com>
Wed, 18 Sep 2013 18:37:51 +0000 (21:37 +0300)
committerGerrit Code Review <gerrit@gerrit.gromacs.org>
Sat, 16 Nov 2013 22:06:25 +0000 (23:06 +0100)
Move all code related to printing the help (console or other formats)
into wman.cpp from pargs.c and filenm.c.  This allows making a lot of
functions internal to this file.

Move code related to markup substitution from wman.cpp into
helpwritercontext.cpp, making it a bit more C++-like in the process.

This commit is mostly cut&pasting code, but some small changes here and
there were required to make it compile (mostly, replacing direct access
to deffile[] with ftp2*() function calls).

Change-Id: I233be210f98c65ffc6308bc91021100bacf7c831

src/gromacs/fileio/filenm.c
src/gromacs/fileio/filenm.h
src/gromacs/gmxlib/pargs.c
src/gromacs/legacyheaders/readinp.h
src/gromacs/legacyheaders/types/enums.h
src/gromacs/onlinehelp/helpwritercontext.cpp
src/gromacs/onlinehelp/wman.cpp
src/gromacs/onlinehelp/wman.h

index 7cb81ca54e6424e875409fa174c83742dcba7c14..97b941d248c4361d8d0ea95079ec05dd2c39ad68 100644 (file)
@@ -50,8 +50,6 @@
 #include "xdrf.h"
 #include "macros.h"
 
-#include "gromacs/onlinehelp/wman.h"
-
 #ifdef GMX_THREAD_MPI
 #include "thread_mpi.h"
 #endif
@@ -216,7 +214,7 @@ static tMPI_Thread_mutex_t filenm_mutex = TMPI_THREAD_MUTEX_INITIALIZER;
 #endif
 
 #define NZEXT 2
-const char *z_ext[NZEXT] =
+static const char *z_ext[NZEXT] =
 { ".gz", ".Z" };
 
 void set_default_file_name(const char *name)
@@ -368,154 +366,6 @@ const char *ftp2defnm(int ftp)
     return buf;
 }
 
-void pr_fns(FILE *fp, int nf, const t_filenm tfn[])
-{
-    int    i, f;
-    size_t j;
-    char   buf[256], *wbuf, opt_buf[32];
-#define OPTLEN 4
-#define NAMELEN 14
-    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, deffile[tfn[i].ftp].descr);
-            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);
-}
-
-void pr_fopts(FILE *fp, int nf, const t_filenm tfn[], int shell)
-{
-    int i, j;
-
-    switch (shell)
-    {
-        case eshellCSH:
-            for (i = 0; (i < nf); i++)
-            {
-                fprintf(fp, " \"n/%s/f:*.", tfn[i].opt);
-                if (deffile[tfn[i].ftp].ntps)
-                {
-                    fprintf(fp, "{");
-                    for (j = 0; j < deffile[tfn[i].ftp].ntps; j++)
-                    {
-                        if (j > 0)
-                        {
-                            fprintf(fp, ",");
-                        }
-                        fprintf(fp, "%s", deffile[deffile[tfn[i].ftp].tps[j]].ext
-                                + 1);
-                    }
-                    fprintf(fp, "}");
-                }
-                else
-                {
-                    fprintf(fp, "%s", deffile[tfn[i].ftp].ext + 1);
-                }
-                fprintf(fp, "{");
-                for (j = 0; j < NZEXT; j++)
-                {
-                    fprintf(fp, ",%s", z_ext[j]);
-                }
-                fprintf(fp, "}/\"");
-            }
-            break;
-        case eshellBASH:
-            for (i = 0; (i < nf); i++)
-            {
-                fprintf(fp, "%s) COMPREPLY=( $(compgen -X '!*.", tfn[i].opt);
-                if (deffile[tfn[i].ftp].ntps)
-                {
-                    fprintf(fp, "+(");
-                    for (j = 0; j < deffile[tfn[i].ftp].ntps; j++)
-                    {
-                        if (j > 0)
-                        {
-                            fprintf(fp, "|");
-                        }
-                        fprintf(fp, "%s", deffile[deffile[tfn[i].ftp].tps[j]].ext
-                                + 1);
-                    }
-                    fprintf(fp, ")");
-                }
-                else
-                {
-                    fprintf(fp, "%s", deffile[tfn[i].ftp].ext + 1);
-                }
-                fprintf(fp, "*(");
-                for (j = 0; j < NZEXT; j++)
-                {
-                    if (j > 0)
-                    {
-                        fprintf(fp, "|");
-                    }
-                    fprintf(fp, "%s", z_ext[j]);
-                }
-                fprintf(fp, ")' -f $c ; compgen -S '/' -X '.*' -d $c ));;\n");
-            }
-            break;
-        case eshellZSH:
-            for (i = 0; (i < nf); i++)
-            {
-                fprintf(fp, "- 'c[-1,%s]' -g '*.", tfn[i].opt);
-                if (deffile[tfn[i].ftp].ntps)
-                {
-                    fprintf(fp, "(");
-                    for (j = 0; j < deffile[tfn[i].ftp].ntps; j++)
-                    {
-                        if (j > 0)
-                        {
-                            fprintf(fp, "|");
-                        }
-                        fprintf(fp, "%s", deffile[deffile[tfn[i].ftp].tps[j]].ext
-                                + 1);
-                    }
-                    fprintf(fp, ")");
-                }
-                else
-                {
-                    fprintf(fp, "%s", deffile[tfn[i].ftp].ext + 1);
-                }
-                fprintf(fp, "(");
-                for (j = 0; j < NZEXT; j++)
-                {
-                    fprintf(fp, "|%s", z_ext[j]);
-                }
-                fprintf(fp, ") *(/)' ");
-            }
-            break;
-    }
-}
-
 static void check_opts(int nf, t_filenm fnm[])
 {
     int              i;
index 49725e7e32e0a2694df54f79ceb5f2ce79bc21d2..e2af5fce3fe71b1bcdcec01d41c2258fc5afe9ca 100644 (file)
@@ -120,12 +120,6 @@ const char *ftp2defnm(int ftp);
 const char *ftp2ftype(int ftp);
 /* Return Binary or ASCII depending on file type */
 
-void pr_fns(FILE *fp, int nf, const t_filenm tfn[]);
-/* Print nf file names and types */
-
-void pr_fopts(FILE *fp, int nf, const t_filenm tfn[], int shell);
-/* prints file options in tcsh 'complete' format */
-
 void parse_file_args(int *argc, char *argv[], int nf, t_filenm fnm[],
                      gmx_bool bKeep, gmx_bool bReadNode);
 /* Parse command line for file names. When bKeep is set args are
index 6206985ea51d06f62af0dc4effdc96050765f1c7..08066b9489a466a6ec1d8c956a1917fd8c321105 100644 (file)
@@ -50,8 +50,6 @@
 #include "vec.h"
 #include "macros.h"
 
-#include "gromacs/onlinehelp/wman.h"
-
 /* The source code in this file should be thread-safe.
       Please keep it that way. */
 
@@ -294,175 +292,3 @@ const char *opt2parg_enum(const char *option, int nparg, t_pargs pa[])
 
     return NULL;
 }
-
-char *pa_val(t_pargs *pa, char buf[], int sz)
-{
-    real r;
-    char buf_str[1256]; buf_str[0] = '\0';
-
-    buf[0] = '\0';
-
-    if (sz < 255)
-    {
-        gmx_fatal(FARGS, "Buffer must be at least 255 chars\n");
-    }
-
-    switch (pa->type)
-    {
-        case etINT:
-            sprintf(buf, "%-d", *(pa->u.i));
-            break;
-        case etGMX_LARGE_INT:
-            sprintf(buf, gmx_large_int_pfmt, *(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)
-{
-    char buf[LONGSTR], *buf2, *tmp, *desc;
-
-    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);
-    }
-    desc = check_tty(pa->desc);
-    if (strlen(buf) > ((OPTLEN+TYPELEN)-max(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);
-    }
-    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);
-    }
-    else
-    {
-        sprintf(buf2, "%-12s %-6s %-6s  %-s\n",
-                buf, get_arg_desc(pa->type), pa_val(pa, tmp, LONGSTR-1), desc);
-    }
-    sfree(desc);
-    sfree(tmp);
-
-    tmp = wrap_lines(buf2, 78, 28, FALSE);
-
-    sfree(buf2);
-
-    return tmp;
-}
-
-void print_pargs(FILE *fp, int npargs, t_pargs pa[])
-{
-    char     buf[32], buf2[256], tmp[256];
-    char    *wdesc;
-    int      i;
-
-
-    if (npargs > 0)
-    {
-        fprintf(fp, "%-12s %-6s %-6s  %-s\n",
-                "Option", "Type", "Value", "Description");
-        fprintf(fp, "------------------------------------------------------\n");
-        for (i = 0; (i < npargs); i++)
-        {
-            wdesc = pargs_print_line(&pa[i]);
-            fprintf(fp, "%s", wdesc);
-            sfree(wdesc);
-        }
-        fprintf(fp, "\n");
-    }
-}
-
-void pr_enums(FILE *fp, int npargs, t_pargs pa[], int shell)
-{
-    int i, j;
-
-    switch (shell)
-    {
-        case eshellCSH:
-            for (i = 0; i < npargs; i++)
-            {
-                if (pa[i].type == etENUM)
-                {
-                    fprintf(fp, " \"n/%s/(", pa[i].option);
-                    for (j = 1; pa[i].u.c[j]; j++)
-                    {
-                        fprintf(fp, " %s", pa[i].u.c[j]);
-                    }
-                    fprintf(fp, ")/\"");
-                }
-            }
-            break;
-        case eshellBASH:
-            for (i = 0; i < npargs; i++)
-            {
-                if (pa[i].type == etENUM)
-                {
-                    fprintf(fp, "%s) COMPREPLY=( $(compgen -W '", pa[i].option);
-                    for (j = 1; pa[i].u.c[j]; j++)
-                    {
-                        fprintf(fp, " %s", pa[i].u.c[j]);
-                    }
-                    fprintf(fp, " ' -- $c ));;\n");
-                }
-            }
-            break;
-        case eshellZSH:
-            for (i = 0; i < npargs; i++)
-            {
-                if (pa[i].type == etENUM)
-                {
-                    fprintf(fp, "- 'c[-1,%s]' -s \"", pa[i].option);
-                    for (j = 1; pa[i].u.c[j]; j++)
-                    {
-                        fprintf(fp, " %s", pa[i].u.c[j]);
-                    }
-                    fprintf(fp, "\" ");
-                }
-            }
-            break;
-    }
-}
index 1bd859ecb09be77fa3fa7bdbc92a1342c3038317..c25e78e4e27551f38ee126fd5e2b3bec7c3b8652 100644 (file)
@@ -114,9 +114,6 @@ enum {
     etINT, etGMX_LARGE_INT, etREAL, etTIME, etSTR,    etBOOL, etRVEC,   etENUM, etNR
 };
 
-/* name to print in help info for command line arguments (defined in enum above) */
-const char *get_arg_desc(int type);
-
 typedef struct {
     const char *option;
     gmx_bool    bSet;
@@ -145,11 +142,6 @@ void get_pargs(int *argc, char *argv[], int nparg, t_pargs pa[],
 gmx_bool is_hidden(t_pargs *pa);
 /* Return TRUE when the option is a secret one */
 
-char *pa_val(t_pargs *pa, char *buf, int sz);
-/* Return the value of pa in the provided buffer buf, of size sz.
- * The return value is also a pointer to buf.
- */
-
 int opt2parg_int(const char *option, int nparg, t_pargs pa[]);
 
 gmx_bool opt2parg_gmx_bool(const char *option, int nparg, t_pargs pa[]);
@@ -162,10 +154,6 @@ const char *opt2parg_enum(const char *option, int nparg, t_pargs pa[]);
 
 gmx_bool opt2parg_bSet(const char *option, int nparg, t_pargs pa[]);
 
-void print_pargs(FILE *fp, int npargs, t_pargs pa[]);
-
-void pr_enums(FILE *fp, int npargs, t_pargs pa[], int shell);
-
 #ifdef __cplusplus
 }
 #endif
index 6187c927f480b56446b7dcea3c141781c78ae1d2..31863448a370382b450c9b51fb5e3b4adc702e0e 100644 (file)
@@ -255,11 +255,6 @@ enum {
     edispcNO, edispcEnerPres, edispcEner, edispcAllEnerPres, edispcAllEner, edispcNR
 };
 
-/* Shell types, for completion stuff */
-enum {
-    eshellCSH, eshellBASH, eshellZSH, eshellNR
-};
-
 /* Center of mass motion selection */
 enum {
     ecmLINEAR, ecmANGULAR, ecmNO, ecmNR
index 08239d30db423d3d710621fa2b577c7780349b12..609013bb3d26a572e704e73c8ce11534bf81a157 100644 (file)
@@ -47,8 +47,6 @@
 #include <string>
 #include <vector>
 
-#include "gromacs/legacyheaders/smalloc.h"
-
 #include "gromacs/onlinehelp/helpformat.h"
 #include "gromacs/onlinehelp/wman.h"
 #include "gromacs/utility/exceptions.h"
@@ -63,13 +61,205 @@ namespace gmx
 namespace
 {
 
+//! \addtogroup module_onlinehelp
+//! \{
+
+struct t_sandr
+{
+    const char *search;
+    const char *replace;
+};
+
+/* The order of these arrays is significant. Text search and replace
+ * for each element occurs in order, so earlier changes can induce
+ * subsequent changes even though the original text might not appear
+ * to invoke the latter changes. */
+
+//! List of replacements for console output.
+const t_sandr sandrTty[] = {
+    { "[TT]", "" },
+    { "[tt]", "" },
+    { "[BB]", "" },
+    { "[bb]", "" },
+    { "[IT]", "" },
+    { "[it]", "" },
+    { "[MATH]", "" },
+    { "[math]", "" },
+    { "[CHEVRON]", "<" },
+    { "[chevron]", ">" },
+    { "[MAG]", "|" },
+    { "[mag]", "|" },
+    { "[INT]", "integral" },
+    { "[FROM]", " from " },
+    { "[from]", "" },
+    { "[TO]", " to " },
+    { "[to]", " of" },
+    { "[int]", "" },
+    { "[SUM]", "sum" },
+    { "[sum]", "" },
+    { "[SUB]", "_" },
+    { "[sub]", "" },
+    { "[SQRT]", "sqrt(" },
+    { "[sqrt]", ")" },
+    { "[EXP]", "exp(" },
+    { "[exp]", ")" },
+    { "[LN]", "ln(" },
+    { "[ln]", ")" },
+    { "[LOG]", "log(" },
+    { "[log]", ")" },
+    { "[COS]", "cos(" },
+    { "[cos]", ")" },
+    { "[SIN]", "sin(" },
+    { "[sin]", ")" },
+    { "[TAN]", "tan(" },
+    { "[tan]", ")" },
+    { "[COSH]", "cosh(" },
+    { "[cosh]", ")" },
+    { "[SINH]", "sinh(" },
+    { "[sinh]", ")" },
+    { "[TANH]", "tanh(" },
+    { "[tanh]", ")" },
+    { "[PAR]", "\n\n" },
+    { "[BR]", "\n"},
+    { "[GRK]", "" },
+    { "[grk]", "" }
+};
+
+//! List of replacements for man page output.
+const t_sandr sandrMan[] = {
+    { "[TT]", "\\fB " },
+    { "[tt]", "\\fR" },
+    { "[BB]", "\\fB " },
+    { "[bb]", "\\fR" },
+    { "[IT]", "\\fI " },
+    { "[it]", "\\fR" },
+    { "[MATH]", "" },
+    { "[math]", "" },
+    { "[CHEVRON]", "<" },
+    { "[chevron]", ">" },
+    { "[MAG]", "|" },
+    { "[mag]", "|" },
+    { "[INT]", "integral" },
+    { "[FROM]", " from " },
+    { "[from]", "" },
+    { "[TO]", " to " },
+    { "[to]", " of" },
+    { "[int]", "" },
+    { "[SUM]", "sum" },
+    { "[sum]", "" },
+    { "[SUB]", "_" },
+    { "[sub]", "" },
+    { "[SQRT]", "sqrt(" },
+    { "[sqrt]", ")", },
+    { "[EXP]", "exp(" },
+    { "[exp]", ")" },
+    { "[LN]", "ln(" },
+    { "[ln]", ")" },
+    { "[LOG]", "log(" },
+    { "[log]", ")" },
+    { "[COS]", "cos(" },
+    { "[cos]", ")" },
+    { "[SIN]", "sin(" },
+    { "[sin]", ")" },
+    { "[TAN]", "tan(" },
+    { "[tan]", ")" },
+    { "[COSH]", "cosh(" },
+    { "[cosh]", ")" },
+    { "[SINH]", "sinh(" },
+    { "[sinh]", ")" },
+    { "[TANH]", "tanh(" },
+    { "[tanh]", ")" },
+    { "[PAR]", "\n\n" },
+    { "\n ",    "\n" },
+    { "<",    "" },
+    { ">",    "" },
+    { "^",    "" },
+    { "#",    "" },
+    { "[BR]", "\n"},
+    { "-",    "\\-"},
+    { "[GRK]", "" },
+    { "[grk]", "" }
+};
+
+//! List of replacements for HTML output.
+const t_sandr sandrHtml[] = {
+    { "<",    "&lt;" },
+    { ">",    "&gt;" },
+    { "[TT]", "<tt>" },
+    { "[tt]", "</tt>" },
+    { "[BB]", "<b>" },
+    { "[bb]", "</b>" },
+    { "[IT]", "<it>" },
+    { "[it]", "</it>" },
+    { "[MATH]", "" },
+    { "[math]", "" },
+    { "[CHEVRON]", "<" },
+    { "[chevron]", ">" },
+    { "[MAG]", "|" },
+    { "[mag]", "|" },
+    { "[INT]", "integral" },
+    { "[FROM]", " from " },
+    { "[from]", "" },
+    { "[TO]", " to " },
+    { "[to]", " of" },
+    { "[int]", "" },
+    { "[SUM]", "sum" },
+    { "[sum]", "" },
+    { "[SUB]", "_" },
+    { "[sub]", "" },
+    { "[SQRT]", "sqrt(" },
+    { "[sqrt]", ")", },
+    { "[EXP]", "exp(" },
+    { "[exp]", ")" },
+    { "[LN]", "ln(" },
+    { "[ln]", ")" },
+    { "[LOG]", "log(" },
+    { "[log]", ")" },
+    { "[COS]", "cos(" },
+    { "[cos]", ")" },
+    { "[SIN]", "sin(" },
+    { "[sin]", ")" },
+    { "[TAN]", "tan(" },
+    { "[tan]", ")" },
+    { "[COSH]", "cosh(" },
+    { "[cosh]", ")" },
+    { "[SINH]", "sinh(" },
+    { "[sinh]", ")" },
+    { "[TANH]", "tanh(" },
+    { "[tanh]", ")" },
+    { "[PAR]", "<p>" },
+    { "[BR]", "<br>" },
+    { "[GRK]", "&"  },
+    { "[grk]", ";"  }
+};
+
+/*! \brief
+ * Replaces all entries from a list of replacements.
+ */
+std::string repall(const std::string &s, int nsr, const t_sandr sa[])
+{
+    std::string result(s);
+    for (int i = 0; i < nsr; ++i)
+    {
+        result = replaceAll(result, sa[i].search, sa[i].replace);
+    }
+    return result;
+}
+
+/*! \brief
+ * Replaces all entries from a list of replacements.
+ */
+template <size_t nsr>
+std::string repall(const std::string &s, const t_sandr (&sa)[nsr])
+{
+    return repall(s, nsr, sa);
+}
+
 /*! \brief
  * Custom output interface for HelpWriterContext::Impl::processMarkup().
  *
  * Provides an interface that is used to implement different types of output
  * from HelpWriterContext::Impl::processMarkup().
- *
- * \ingroup module_onlinehelp
  */
 class WrapperInterface
 {
@@ -90,8 +280,6 @@ class WrapperInterface
 
 /*! \brief
  * Wraps markup output into a single string.
- *
- * \ingroup module_onlinehelp
  */
 class WrapperToString : public WrapperInterface
 {
@@ -120,8 +308,6 @@ class WrapperToString : public WrapperInterface
 
 /*! \brief
  * Wraps markup output into a vector of string (one line per element).
- *
- * \ingroup module_onlinehelp
  */
 class WrapperToVector : public WrapperInterface
 {
@@ -155,8 +341,6 @@ class WrapperToVector : public WrapperInterface
  * \param[in] text  Input text.
  * \returns   \p text with all characters transformed to uppercase.
  * \throws    std::bad_alloc if out of memory.
- *
- * \ingroup module_onlinehelp
  */
 std::string toUpperCase(const std::string &text)
 {
@@ -165,6 +349,8 @@ std::string toUpperCase(const std::string &text)
     return result;
 }
 
+//! \}
+
 }   // namespace
 
 /********************************************************************
@@ -263,11 +449,7 @@ void HelpWriterContext::Impl::processMarkup(const std::string &text,
     {
         case eHelpOutputFormat_Console:
         {
-            {
-                char            *resultStr = check_tty(result.c_str());
-                scoped_ptr_sfree resultGuard(resultStr);
-                result = resultStr;
-            }
+            result = repall(result, sandrTty);
             if (wrapper->settings().lineLength() == 0)
             {
                 wrapper->settings().setLineLength(78);
@@ -276,20 +458,12 @@ void HelpWriterContext::Impl::processMarkup(const std::string &text,
         }
         case eHelpOutputFormat_Man:
         {
-            {
-                char            *resultStr = check_nroff(result.c_str());
-                scoped_ptr_sfree resultGuard(resultStr);
-                result = resultStr;
-            }
+            result = repall(result, sandrMan);
             return wrapper->wrap(result);
         }
         case eHelpOutputFormat_Html:
         {
-            {
-                char            *resultStr = check_html(result.c_str());
-                scoped_ptr_sfree resultGuard(resultStr);
-                result = resultStr;
-            }
+            result = repall(result, sandrHtml);
             if (links_ != NULL)
             {
                 HelpLinks::Impl::LinkList::const_iterator link;
index 63057b1af577916d5a4362346fbfff8adb158720..e9632d9ecb80ac1c0e681ceaab08c37309246b07 100644 (file)
 #include "gromacs/fileio/filenm.h"
 #include "gromacs/fileio/gmxfio.h"
 #include "gromacs/onlinehelp/wman.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"
-#include "macros.h"
 #include "statutil.h"
-#include "readinp.h"
 
-/* The source code in this file should be thread-safe.
-         Please keep it that way. */
-
-
-typedef struct {
-    const char *search, *replace;
-} t_sandr;
-
-/* The order of these arrays is significant. Text search and replace
- * for each element occurs in order, so earlier changes can induce
- * subsequent changes even though the original text might not appear
- * to invoke the latter changes. */
-
-const t_sandr sandrTty[] = {
-    { "[TT]", "" },
-    { "[tt]", "" },
-    { "[BB]", "" },
-    { "[bb]", "" },
-    { "[IT]", "" },
-    { "[it]", "" },
-    { "[MATH]", "" },
-    { "[math]", "" },
-    { "[CHEVRON]", "<" },
-    { "[chevron]", ">" },
-    { "[MAG]", "|" },
-    { "[mag]", "|" },
-    { "[INT]", "integral" },
-    { "[FROM]", " from " },
-    { "[from]", "" },
-    { "[TO]", " to " },
-    { "[to]", " of" },
-    { "[int]", "" },
-    { "[SUM]", "sum" },
-    { "[sum]", "" },
-    { "[SUB]", "_" },
-    { "[sub]", "" },
-    { "[SQRT]", "sqrt(" },
-    { "[sqrt]", ")" },
-    { "[EXP]", "exp(" },
-    { "[exp]", ")" },
-    { "[LN]", "ln(" },
-    { "[ln]", ")" },
-    { "[LOG]", "log(" },
-    { "[log]", ")" },
-    { "[COS]", "cos(" },
-    { "[cos]", ")" },
-    { "[SIN]", "sin(" },
-    { "[sin]", ")" },
-    { "[TAN]", "tan(" },
-    { "[tan]", ")" },
-    { "[COSH]", "cosh(" },
-    { "[cosh]", ")" },
-    { "[SINH]", "sinh(" },
-    { "[sinh]", ")" },
-    { "[TANH]", "tanh(" },
-    { "[tanh]", ")" },
-    { "[PAR]", "\n\n" },
-    { "[BR]", "\n"},
-    { "[GRK]", "" },
-    { "[grk]", "" }
-};
-#define NSRTTY asize(sandrTty)
-
-const t_sandr sandrNROFF[] = {
-    { "[TT]", "\\fB " },
-    { "[tt]", "\\fR" },
-    { "[BB]", "\\fB " },
-    { "[bb]", "\\fR" },
-    { "[IT]", "\\fI " },
-    { "[it]", "\\fR" },
-    { "[MATH]", "" },
-    { "[math]", "" },
-    { "[CHEVRON]", "<" },
-    { "[chevron]", ">" },
-    { "[MAG]", "|" },
-    { "[mag]", "|" },
-    { "[INT]", "integral" },
-    { "[FROM]", " from " },
-    { "[from]", "" },
-    { "[TO]", " to " },
-    { "[to]", " of" },
-    { "[int]", "" },
-    { "[SUM]", "sum" },
-    { "[sum]", "" },
-    { "[SUB]", "_" },
-    { "[sub]", "" },
-    { "[SQRT]", "sqrt(" },
-    { "[sqrt]", ")", },
-    { "[EXP]", "exp(" },
-    { "[exp]", ")" },
-    { "[LN]", "ln(" },
-    { "[ln]", ")" },
-    { "[LOG]", "log(" },
-    { "[log]", ")" },
-    { "[COS]", "cos(" },
-    { "[cos]", ")" },
-    { "[SIN]", "sin(" },
-    { "[sin]", ")" },
-    { "[TAN]", "tan(" },
-    { "[tan]", ")" },
-    { "[COSH]", "cosh(" },
-    { "[cosh]", ")" },
-    { "[SINH]", "sinh(" },
-    { "[sinh]", ")" },
-    { "[TANH]", "tanh(" },
-    { "[tanh]", ")" },
-    { "[PAR]", "\n\n" },
-    { "\n ",    "\n" },
-    { "<",    "" },
-    { ">",    "" },
-    { "^",    "" },
-    { "#",    "" },
-    { "[BR]", "\n"},
-    { "-",    "\\-"},
-    { "[GRK]", "" },
-    { "[grk]", "" }
-};
-#define NSRNROFF asize(sandrNROFF)
-
-const t_sandr sandrHTML[] = {
-    { "<",    "&lt;" },
-    { ">",    "&gt;" },
-    { "[TT]", "<tt>" },
-    { "[tt]", "</tt>" },
-    { "[BB]", "<b>" },
-    { "[bb]", "</b>" },
-    { "[IT]", "<it>" },
-    { "[it]", "</it>" },
-    { "[MATH]", "" },
-    { "[math]", "" },
-    { "[CHEVRON]", "<" },
-    { "[chevron]", ">" },
-    { "[MAG]", "|" },
-    { "[mag]", "|" },
-    { "[INT]", "integral" },
-    { "[FROM]", " from " },
-    { "[from]", "" },
-    { "[TO]", " to " },
-    { "[to]", " of" },
-    { "[int]", "" },
-    { "[SUM]", "sum" },
-    { "[sum]", "" },
-    { "[SUB]", "_" },
-    { "[sub]", "" },
-    { "[SQRT]", "sqrt(" },
-    { "[sqrt]", ")", },
-    { "[EXP]", "exp(" },
-    { "[exp]", ")" },
-    { "[LN]", "ln(" },
-    { "[ln]", ")" },
-    { "[LOG]", "log(" },
-    { "[log]", ")" },
-    { "[COS]", "cos(" },
-    { "[cos]", ")" },
-    { "[SIN]", "sin(" },
-    { "[sin]", ")" },
-    { "[TAN]", "tan(" },
-    { "[tan]", ")" },
-    { "[COSH]", "cosh(" },
-    { "[cosh]", ")" },
-    { "[SINH]", "sinh(" },
-    { "[sinh]", ")" },
-    { "[TANH]", "tanh(" },
-    { "[tanh]", ")" },
-    { "[PAR]", "<p>" },
-    { "[BR]", "<br>" },
-    { "[GRK]", "&"  },
-    { "[grk]", ";"  }
+// Shell types, for completion stuff
+enum {
+    eshellCSH, eshellBASH, eshellZSH
 };
-#define NSRHTML asize(sandrHTML)
 
-static char *repall(const char *s, int nsr, const t_sandr sa[])
-{
-    try
-    {
-        std::string result(s);
-        for (int i = 0; i < nsr; ++i)
-        {
-            result = gmx::replaceAll(result, sa[i].search, sa[i].replace);
-        }
-        return gmx_strdup(result.c_str());
-    }
-    GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
-}
+// TODO: Don't duplicate this from filenm.c/futil.c.
+#define NZEXT 2
+static const char *z_ext[NZEXT] = { ".gz", ".Z" };
 
-char *check_nroff(const char *s)
-{
-    return repall(s, NSRNROFF, sandrNROFF);
-}
-
-char *check_html(const char *s)
-{
-    return repall(s, NSRHTML, sandrHTML);
-}
+/* The source code in this file should be thread-safe.
+ * Please keep it that way. */
 
-std::string check(const char *s, const gmx::HelpWriterContext &context)
+static std::string check(const char *s, const gmx::HelpWriterContext &context)
 {
     return context.substituteMarkupAndWrapToString(gmx::TextLineWrapperSettings(), s);
 }
 
 #define FLAG_SET(flag, mask) ((flag &mask) == mask)
-char *fileopt(unsigned long flag, char buf[])
+/* 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];
 
@@ -300,6 +121,186 @@ char *fileopt(unsigned long flag, char buf[])
     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 etGMX_LARGE_INT:
+            sprintf(buf, gmx_large_int_pfmt, *(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,
                            const char *program,
                            int nldesc, const char **desc,
@@ -400,11 +401,6 @@ static void write_nroffman(FILE *out,
     }
 }
 
-char *check_tty(const char *s)
-{
-    return repall(s, NSRTTY, sandrTty);
-}
-
 static void
 print_tty_formatted(FILE *out, int nldesc, const char **desc,
                     const gmx::HelpWriterContext &context)
@@ -471,7 +467,7 @@ static void write_ttyman(FILE *out,
     }
     if (npargs > 0)
     {
-        print_pargs(out, npargs, pa);
+        print_pargs(out, npargs, pa, context);
     }
 }
 
@@ -574,6 +570,113 @@ static void write_htmlman(FILE *out,
     }
 }
 
+static void pr_fopts(FILE *fp, int nf, const t_filenm tfn[], int shell)
+{
+    switch (shell)
+    {
+        case eshellCSH:
+            for (int i = 0; i < nf; i++)
+            {
+                fprintf(fp, " \"n/%s/f:*.", tfn[i].opt);
+                const int ftp          = tfn[i].ftp;
+                const int genericCount = ftp2generic_count(ftp);
+                if (genericCount > 0)
+                {
+                    fprintf(fp, "{");
+                    const int *const genericTypes = ftp2generic_list(ftp);
+                    for (int j = 0; j < genericCount; j++)
+                    {
+                        if (j > 0)
+                        {
+                            fprintf(fp, ",");
+                        }
+                        fprintf(fp, "%s", ftp2ext(genericTypes[j]));
+                    }
+                    fprintf(fp, "}");
+                }
+                else
+                {
+                    fprintf(fp, "%s", ftp2ext(ftp));
+                }
+                fprintf(fp, "{");
+                for (int j = 0; j < NZEXT; j++)
+                {
+                    fprintf(fp, ",%s", z_ext[j]);
+                }
+                fprintf(fp, "}/\"");
+            }
+            break;
+        case eshellBASH:
+            for (int i = 0; i < nf; i++)
+            {
+                fprintf(fp, "%s) COMPREPLY=( $(compgen -X '!*.", tfn[i].opt);
+                const int ftp          = tfn[i].ftp;
+                const int genericCount = ftp2generic_count(ftp);
+                if (genericCount > 0)
+                {
+                    fprintf(fp, "+(");
+                    const int *const genericTypes = ftp2generic_list(ftp);
+                    for (int j = 0; j < genericCount; j++)
+                    {
+                        if (j > 0)
+                        {
+                            fprintf(fp, "|");
+                        }
+                        fprintf(fp, "%s", ftp2ext(genericTypes[j]));
+                    }
+                    fprintf(fp, ")");
+                }
+                else
+                {
+                    fprintf(fp, "%s", ftp2ext(ftp));
+                }
+                fprintf(fp, "*(");
+                for (int j = 0; j < NZEXT; j++)
+                {
+                    if (j > 0)
+                    {
+                        fprintf(fp, "|");
+                    }
+                    fprintf(fp, "%s", z_ext[j]);
+                }
+                fprintf(fp, ")' -f $c ; compgen -S '/' -X '.*' -d $c ));;\n");
+            }
+            break;
+        case eshellZSH:
+            for (int i = 0; i < nf; i++)
+            {
+                fprintf(fp, "- 'c[-1,%s]' -g '*.", tfn[i].opt);
+                const int ftp          = tfn[i].ftp;
+                const int genericCount = ftp2generic_count(ftp);
+                if (genericCount > 0)
+                {
+                    fprintf(fp, "(");
+                    const int *const genericTypes = ftp2generic_list(ftp);
+                    for (int j = 0; j < genericCount; j++)
+                    {
+                        if (j > 0)
+                        {
+                            fprintf(fp, "|");
+                        }
+                        fprintf(fp, "%s", ftp2ext(genericTypes[j]));
+                    }
+                    fprintf(fp, ")");
+                }
+                else
+                {
+                    fprintf(fp, "%s", ftp2ext(ftp));
+                }
+                fprintf(fp, "(");
+                for (int j = 0; j < NZEXT; j++)
+                {
+                    fprintf(fp, "|%s", z_ext[j]);
+                }
+                fprintf(fp, ") *(/)' ");
+            }
+            break;
+    }
+}
+
 static void pr_opts(FILE *fp,
                     int nfile,  t_filenm *fnm,
                     int npargs, t_pargs pa[], int shell)
@@ -642,6 +745,57 @@ static void pr_opts(FILE *fp,
     }
 }
 
+static void pr_enums(FILE *fp, int npargs, t_pargs pa[], int shell)
+{
+    int i, j;
+
+    switch (shell)
+    {
+        case eshellCSH:
+            for (i = 0; i < npargs; i++)
+            {
+                if (pa[i].type == etENUM)
+                {
+                    fprintf(fp, " \"n/%s/(", pa[i].option);
+                    for (j = 1; pa[i].u.c[j]; j++)
+                    {
+                        fprintf(fp, " %s", pa[i].u.c[j]);
+                    }
+                    fprintf(fp, ")/\"");
+                }
+            }
+            break;
+        case eshellBASH:
+            for (i = 0; i < npargs; i++)
+            {
+                if (pa[i].type == etENUM)
+                {
+                    fprintf(fp, "%s) COMPREPLY=( $(compgen -W '", pa[i].option);
+                    for (j = 1; pa[i].u.c[j]; j++)
+                    {
+                        fprintf(fp, " %s", pa[i].u.c[j]);
+                    }
+                    fprintf(fp, " ' -- $c ));;\n");
+                }
+            }
+            break;
+        case eshellZSH:
+            for (i = 0; i < npargs; i++)
+            {
+                if (pa[i].type == etENUM)
+                {
+                    fprintf(fp, "- 'c[-1,%s]' -s \"", pa[i].option);
+                    for (j = 1; pa[i].u.c[j]; j++)
+                    {
+                        fprintf(fp, " %s", pa[i].u.c[j]);
+                    }
+                    fprintf(fp, "\" ");
+                }
+            }
+            break;
+    }
+}
+
 static void write_cshcompl(FILE *out,
                            int nfile,  t_filenm *fnm,
                            int npargs, t_pargs *pa)
@@ -776,11 +930,3 @@ void write_man(const char *mantp,
         sfree(par);
     }
 }
-
-const char *get_arg_desc(int type)
-{
-    static const char *argtp[etNR] = {
-        "int", "step", "real", "time", "string", "bool", "vector", "enum"
-    };
-    return argtp[type];
-}
index 607837421ad58630e5564cbef98752c0246435d9..06e9f7fc31427eed0f4f8b1ef8245265cc46d804 100644 (file)
 #include "readinp.h"
 #include "gromacs/fileio/filenm.h"
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 void write_man(const char *mantp, const char *program,
                int nldesc, const char **desc,
                int nfile, t_filenm *fnm,
                int npargs, t_pargs *pa,
                int nbug, const char **bugs);
 
-char *fileopt(unsigned long flag, char buf[]);
-/* 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.
- */
-
-char *check_nroff(const char *s);
-char *check_html(const char *s);
-char *check_tty(const char *s);
-
-#ifdef __cplusplus
-}
-#endif
-
 #endif