gromacs cpp: clean up -Wunused-parameter warnings
[alexxy/gromacs.git] / src / gromacs / onlinehelp / wman.cpp
1 /*
2  *
3  *                This source code is part of
4  *
5  *                 G   R   O   M   A   C   S
6  *
7  *          GROningen MAchine for Chemical Simulations
8  *
9  *                        VERSION 3.2.0
10  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12  * Copyright (c) 2001-2004, The GROMACS development team,
13  * check out http://www.gromacs.org for more information.
14
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  *
20  * If you want to redistribute modifications, please consider that
21  * scientific software is very special. Version control is crucial -
22  * bugs must be traceable. We will be happy to consider code for
23  * inclusion in the official distribution, but derived work must not
24  * be called official GROMACS. Details are found in the README & COPYING
25  * files - if they are missing, get the official version at www.gromacs.org.
26  *
27  * To help us fund GROMACS development, we humbly ask that you cite
28  * the papers on the package - you can find them in the top README file.
29  *
30  * For more info, check our website at http://www.gromacs.org
31  *
32  * And Hey:
33  * GROningen Mixture of Alchemy and Childrens' Stories
34  */
35 #include <cstdio>
36 #include <cstring>
37
38 #include <string>
39
40 #include "gromacs/commandline/cmdlinehelpcontext.h"
41 #include "gromacs/fileio/filenm.h"
42 #include "gromacs/fileio/gmxfio.h"
43 #include "gromacs/onlinehelp/wman.h"
44 #include "gromacs/utility/exceptions.h"
45 #include "gromacs/utility/file.h"
46 #include "gromacs/utility/gmxassert.h"
47 #include "gromacs/utility/stringutil.h"
48
49 #include "string2.h"
50 #include "smalloc.h"
51 #include "macros.h"
52 #include "statutil.h"
53 #include "readinp.h"
54
55 /* The source code in this file should be thread-safe.
56          Please keep it that way. */
57
58
59 typedef struct {
60     const char *search, *replace;
61 } t_sandr;
62
63 /* The order of these arrays is significant. Text search and replace
64  * for each element occurs in order, so earlier changes can induce
65  * subsequent changes even though the original text might not appear
66  * to invoke the latter changes. */
67
68 const t_sandr sandrTty[] = {
69     { "[TT]", "" },
70     { "[tt]", "" },
71     { "[BB]", "" },
72     { "[bb]", "" },
73     { "[IT]", "" },
74     { "[it]", "" },
75     { "[MATH]", "" },
76     { "[math]", "" },
77     { "[CHEVRON]", "<" },
78     { "[chevron]", ">" },
79     { "[MAG]", "|" },
80     { "[mag]", "|" },
81     { "[INT]", "integral" },
82     { "[FROM]", " from " },
83     { "[from]", "" },
84     { "[TO]", " to " },
85     { "[to]", " of" },
86     { "[int]", "" },
87     { "[SUM]", "sum" },
88     { "[sum]", "" },
89     { "[SUB]", "_" },
90     { "[sub]", "" },
91     { "[SQRT]", "sqrt(" },
92     { "[sqrt]", ")" },
93     { "[EXP]", "exp(" },
94     { "[exp]", ")" },
95     { "[LN]", "ln(" },
96     { "[ln]", ")" },
97     { "[LOG]", "log(" },
98     { "[log]", ")" },
99     { "[COS]", "cos(" },
100     { "[cos]", ")" },
101     { "[SIN]", "sin(" },
102     { "[sin]", ")" },
103     { "[TAN]", "tan(" },
104     { "[tan]", ")" },
105     { "[COSH]", "cosh(" },
106     { "[cosh]", ")" },
107     { "[SINH]", "sinh(" },
108     { "[sinh]", ")" },
109     { "[TANH]", "tanh(" },
110     { "[tanh]", ")" },
111     { "[PAR]", "\n\n" },
112     { "[BR]", "\n"},
113     { "[GRK]", "" },
114     { "[grk]", "" }
115 };
116 #define NSRTTY asize(sandrTty)
117
118 const t_sandr sandrNROFF[] = {
119     { "[TT]", "\\fB " },
120     { "[tt]", "\\fR" },
121     { "[BB]", "\\fB " },
122     { "[bb]", "\\fR" },
123     { "[IT]", "\\fI " },
124     { "[it]", "\\fR" },
125     { "[MATH]", "" },
126     { "[math]", "" },
127     { "[CHEVRON]", "<" },
128     { "[chevron]", ">" },
129     { "[MAG]", "|" },
130     { "[mag]", "|" },
131     { "[INT]", "integral" },
132     { "[FROM]", " from " },
133     { "[from]", "" },
134     { "[TO]", " to " },
135     { "[to]", " of" },
136     { "[int]", "" },
137     { "[SUM]", "sum" },
138     { "[sum]", "" },
139     { "[SUB]", "_" },
140     { "[sub]", "" },
141     { "[SQRT]", "sqrt(" },
142     { "[sqrt]", ")", },
143     { "[EXP]", "exp(" },
144     { "[exp]", ")" },
145     { "[LN]", "ln(" },
146     { "[ln]", ")" },
147     { "[LOG]", "log(" },
148     { "[log]", ")" },
149     { "[COS]", "cos(" },
150     { "[cos]", ")" },
151     { "[SIN]", "sin(" },
152     { "[sin]", ")" },
153     { "[TAN]", "tan(" },
154     { "[tan]", ")" },
155     { "[COSH]", "cosh(" },
156     { "[cosh]", ")" },
157     { "[SINH]", "sinh(" },
158     { "[sinh]", ")" },
159     { "[TANH]", "tanh(" },
160     { "[tanh]", ")" },
161     { "[PAR]", "\n\n" },
162     { "\n ",    "\n" },
163     { "<",    "" },
164     { ">",    "" },
165     { "^",    "" },
166     { "#",    "" },
167     { "[BR]", "\n"},
168     { "-",    "\\-"},
169     { "[GRK]", "" },
170     { "[grk]", "" }
171 };
172 #define NSRNROFF asize(sandrNROFF)
173
174 const t_sandr sandrHTML[] = {
175     { "<",    "&lt;" },
176     { ">",    "&gt;" },
177     { "[TT]", "<tt>" },
178     { "[tt]", "</tt>" },
179     { "[BB]", "<b>" },
180     { "[bb]", "</b>" },
181     { "[IT]", "<it>" },
182     { "[it]", "</it>" },
183     { "[MATH]", "" },
184     { "[math]", "" },
185     { "[CHEVRON]", "<" },
186     { "[chevron]", ">" },
187     { "[MAG]", "|" },
188     { "[mag]", "|" },
189     { "[INT]", "integral" },
190     { "[FROM]", " from " },
191     { "[from]", "" },
192     { "[TO]", " to " },
193     { "[to]", " of" },
194     { "[int]", "" },
195     { "[SUM]", "sum" },
196     { "[sum]", "" },
197     { "[SUB]", "_" },
198     { "[sub]", "" },
199     { "[SQRT]", "sqrt(" },
200     { "[sqrt]", ")", },
201     { "[EXP]", "exp(" },
202     { "[exp]", ")" },
203     { "[LN]", "ln(" },
204     { "[ln]", ")" },
205     { "[LOG]", "log(" },
206     { "[log]", ")" },
207     { "[COS]", "cos(" },
208     { "[cos]", ")" },
209     { "[SIN]", "sin(" },
210     { "[sin]", ")" },
211     { "[TAN]", "tan(" },
212     { "[tan]", ")" },
213     { "[COSH]", "cosh(" },
214     { "[cosh]", ")" },
215     { "[SINH]", "sinh(" },
216     { "[sinh]", ")" },
217     { "[TANH]", "tanh(" },
218     { "[tanh]", ")" },
219     { "[PAR]", "<p>" },
220     { "[BR]", "<br>" },
221     { "[GRK]", "&"  },
222     { "[grk]", ";"  }
223 };
224 #define NSRHTML asize(sandrHTML)
225
226 static char *repall(const char *s, int nsr, const t_sandr sa[])
227 {
228     try
229     {
230         std::string result(s);
231         for (int i = 0; i < nsr; ++i)
232         {
233             result = gmx::replaceAll(result, sa[i].search, sa[i].replace);
234         }
235         return gmx_strdup(result.c_str());
236     }
237     GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
238 }
239
240 char *check_nroff(const char *s)
241 {
242     return repall(s, NSRNROFF, sandrNROFF);
243 }
244
245 char *check_html(const char *s)
246 {
247     return repall(s, NSRHTML, sandrHTML);
248 }
249
250 std::string check(const char *s, const gmx::HelpWriterContext &context)
251 {
252     return context.substituteMarkupAndWrapToString(gmx::TextLineWrapperSettings(), s);
253 }
254
255 #define FLAG_SET(flag, mask) ((flag &mask) == mask)
256 char *fileopt(unsigned long flag, char buf[])
257 {
258     char tmp[256];
259
260     if (FLAG_SET(flag, ffRW))
261     {
262         sprintf(tmp, "In/Out");
263     }
264     else if (FLAG_SET(flag, ffREAD))
265     {
266         sprintf(tmp, "Input");
267     }
268     else if (FLAG_SET(flag, ffWRITE))
269     {
270         sprintf(tmp, "Output");
271     }
272     else
273     {
274         sprintf(tmp, "Dunno");
275     }
276
277     if (FLAG_SET(flag, ffOPT))
278     {
279         strcat(tmp, ", Opt");
280         if (FLAG_SET(flag, ffSET))
281         {
282             strcat(tmp, "!");
283         }
284         else
285         {
286             strcat(tmp, ".");
287         }
288     }
289     if (FLAG_SET(flag, ffLIB))
290     {
291         strcat(tmp, ", Lib.");
292     }
293     if (FLAG_SET(flag, ffMULT))
294     {
295         strcat(tmp, ", Mult.");
296     }
297
298     sprintf(buf, "%s", tmp);
299
300     return buf;
301 }
302
303 static void write_nroffman(FILE *out,
304                            const char *program,
305                            int nldesc, const char **desc,
306                            int nfile, t_filenm *fnm,
307                            int npargs, t_pargs *pa,
308                            int nbug, const char **bugs,
309                            const gmx::HelpWriterContext &context)
310 {
311     int  i;
312     char tmp[256];
313
314     fprintf(out, ".SH SYNOPSIS\n");
315     fprintf(out, "\\f3%s\\fP\n", program);
316
317     /* command line arguments */
318     if (nfile > 0)
319     {
320         for (i = 0; (i < nfile); i++)
321         {
322             fprintf(out, ".BI \"%s\" \" %s \"\n",
323                     check(fnm[i].opt, context).c_str(),
324                     check(fnm[i].fns[0], context).c_str());
325         }
326     }
327     if (npargs > 0)
328     {
329         for (i = 0; (i < npargs); i++)
330         {
331             if (pa[i].type == etBOOL)
332             {
333                 fprintf(out, ".BI \"\\-[no]%s\" \"\"\n",
334                         check(pa[i].option+1, context).c_str());
335             }
336             else
337             {
338                 fprintf(out, ".BI \"%s\" \" %s \"\n",
339                         check(pa[i].option, context).c_str(),
340                         check(get_arg_desc(pa[i].type), context).c_str());
341             }
342         }
343     }
344
345     /* description */
346     if (nldesc > 0)
347     {
348         fprintf(out, ".SH DESCRIPTION\n");
349         for (i = 0; (i < nldesc); i++)
350         {
351             fprintf(out, "\\&%s\n", check(desc[i], context).c_str());
352         }
353     }
354
355     /* FILES */
356     if (nfile > 0)
357     {
358         fprintf(out, ".SH FILES\n");
359         for (i = 0; (i < nfile); i++)
360         {
361             fprintf(out, ".BI \"%s\" \" %s\" \n.B %s\n %s \n\n",
362                     check(fnm[i].opt, context).c_str(),
363                     check(fnm[i].fns[0], context).c_str(),
364                     check(fileopt(fnm[i].flag, tmp), context).c_str(),
365                     check(ftp2desc(fnm[i].ftp), context).c_str());
366         }
367     }
368
369     /* other options */
370     fprintf(out, ".SH OTHER OPTIONS\n");
371     if (npargs > 0)
372     {
373         for (i = 0; (i < npargs); i++)
374         {
375             if (pa[i].type == etBOOL)
376             {
377                 fprintf(out, ".BI \"\\-[no]%s\"  \"%s\"\n %s\n\n",
378                         check(pa[i].option+1, context).c_str(),
379                         check(pa_val(&(pa[i]), tmp, 255), context).c_str(),
380                         check(pa[i].desc, context).c_str());
381             }
382             else
383             {
384                 fprintf(out, ".BI \"%s\"  \" %s\" \" %s\" \n %s\n\n",
385                         check(pa[i].option, context).c_str(),
386                         check(get_arg_desc(pa[i].type), context).c_str(),
387                         check(pa_val(&(pa[i]), tmp, 255), context).c_str(),
388                         check(pa[i].desc, context).c_str());
389             }
390         }
391     }
392
393     if (nbug > 0)
394     {
395         fprintf(out, ".SH KNOWN PROBLEMS\n");
396         for (i = 0; (i < nbug); i++)
397         {
398             fprintf(out, "\\- %s\n\n", check(bugs[i], context).c_str());
399         }
400     }
401 }
402
403 char *check_tty(const char *s)
404 {
405     return repall(s, NSRTTY, sandrTty);
406 }
407
408 static void
409 print_tty_formatted(FILE *out, int nldesc, const char **desc,
410                     const gmx::HelpWriterContext &context)
411 {
412     char *buf;
413     int   buflen, i;
414
415     buflen = 80*nldesc;
416     snew(buf, buflen);
417     for (i = 0; (i < nldesc); i++)
418     {
419         if ((strlen(buf) > 0) &&
420             (buf[strlen(buf)-1] != ' ') && (buf[strlen(buf)-1] != '\n'))
421         {
422             strcat(buf, " ");
423         }
424         std::string temp = check(desc[i], context);
425         if (strlen(buf) + temp.length() >= (size_t)(buflen-2))
426         {
427             buflen += temp.length();
428             srenew(buf, buflen);
429         }
430         strcat(buf, temp.c_str());
431     }
432     /* Make lines of at most 79 characters */
433     char *temp = wrap_lines(buf, 78, 0, FALSE);
434     fprintf(out, "%s\n", temp);
435     sfree(temp);
436     sfree(buf);
437 }
438
439 static void write_ttyman(FILE *out,
440                          int nldesc, const char **desc,
441                          int nfile, t_filenm *fnm,
442                          int npargs, t_pargs *pa,
443                          int nbug, const char **bugs,
444                          const gmx::HelpWriterContext &context)
445 {
446     int   i;
447     char *tmp;
448
449     if (nldesc > 0)
450     {
451         fprintf(out, "DESCRIPTION\n-----------\n");
452         print_tty_formatted(out, nldesc, desc, context);
453     }
454     if (nbug > 0)
455     {
456         fprintf(out, "\n");
457         fprintf(out, "KNOWN PROBLEMS\n----------\n");
458         for (i = 0; i < nbug; i++)
459         {
460             snew(tmp, strlen(bugs[i])+3);
461             strcpy(tmp, "* ");
462             strcpy(tmp+2, check(bugs[i], context).c_str());
463             fprintf(out, "%s\n", wrap_lines(tmp, 78, 2, FALSE));
464             sfree(tmp);
465         }
466     }
467     if (nfile > 0)
468     {
469         fprintf(out, "\n");
470         pr_fns(out, nfile, fnm);
471     }
472     if (npargs > 0)
473     {
474         print_pargs(out, npargs, pa);
475     }
476 }
477
478 static void pr_html_files(FILE *out, int nfile, t_filenm fnm[],
479                           const gmx::HelpWriterContext &context)
480 {
481     int  i;
482     char link[10], tmp[255];
483
484     fprintf(out,
485             "<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=2>\n"
486             "<TR>"
487             "<TH>option</TH>"
488             "<TH>filename</TH>"
489             "<TH>type</TH>"
490             "<TH>description</TH>"
491             "</TR>\n");
492
493     for (i = 0; (i < nfile); i++)
494     {
495         strcpy(link, ftp2ext(fnm[i].ftp));
496         if (strcmp(link, "???") == 0)
497         {
498             strcpy(link, "files");
499         }
500         fprintf(out,
501                 "<TR>"
502                 "<TD ALIGN=RIGHT> <b><tt>%s</tt></b> </TD>"
503                 "<TD ALIGN=RIGHT> <tt><a href=\"%s.html\">%12s</a></tt> </TD>"
504                 "<TD> %s </TD>"
505                 "<TD> %s </TD>"
506                 "</TR>\n",
507                 fnm[i].opt, link, fnm[i].fns[0], fileopt(fnm[i].flag, tmp),
508                 check(ftp2desc(fnm[i].ftp), context).c_str());
509     }
510     fprintf(out, "</TABLE>\n");
511 }
512
513 static void write_htmlman(FILE *out,
514                           int nldesc, const char **desc,
515                           int nfile, t_filenm *fnm,
516                           int npargs, t_pargs *pa,
517                           int nbug, const char **bugs,
518                           const gmx::HelpWriterContext &context)
519 {
520     int  i;
521     char tmp[255];
522
523     if (nldesc > 0)
524     {
525         fprintf(out, "<H3>Description</H3>\n<p>\n");
526         for (i = 0; (i < nldesc); i++)
527         {
528             fprintf(out, "%s\n", check(desc[i], context).c_str());
529         }
530     }
531     if (nfile > 0)
532     {
533         fprintf(out, "<P>\n");
534         fprintf(out, "<H3>Files</H3>\n");
535         pr_html_files(out, nfile, fnm, context);
536     }
537     if (npargs > 0)
538     {
539         fprintf(out, "<P>\n");
540         fprintf(out, "<H3>Other options</H3>\n");
541         fprintf(out,
542                 "<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=2>\n"
543                 "<TR>"
544                 "<TH>option</TH>"
545                 "<TH>type</TH>"
546                 "<TH>default</TH>"
547                 "<TH>description</TH>"
548                 "</TR>\n");
549         for (i = 0; (i < npargs); i++)
550         {
551             fprintf(out,
552                     "<TR>"
553                     "<TD ALIGN=RIGHT> <b><tt>%s%s</tt></b> </TD>"
554                     "<TD ALIGN=RIGHT> %s </TD>"
555                     "<TD ALIGN=RIGHT> <tt>%s</tt> </TD>"
556                     "<TD> %s </TD>"
557                     "</TD>\n",
558                     (pa[i].type == etBOOL) ? "-[no]" : "-", pa[i].option+1,
559                     get_arg_desc(pa[i].type), pa_val(&(pa[i]), tmp, 255),
560                     check(pa[i].desc, context).c_str());
561         }
562         fprintf(out, "</TABLE>\n");
563     }
564     if (nbug > 0)
565     {
566         fprintf(out, "<P>\n");
567         fprintf(out, "<H3>Known problems</H3>\n");
568         fprintf(out, "<UL>\n");
569         for (i = 0; (i < nbug); i++)
570         {
571             fprintf(out, "<LI>%s\n", check(bugs[i], context).c_str());
572         }
573         fprintf(out, "</UL>\n");
574     }
575 }
576
577 static void pr_opts(FILE *fp,
578                     int nfile,  t_filenm *fnm,
579                     int npargs, t_pargs pa[], int shell)
580 {
581     int i;
582
583     switch (shell)
584     {
585         case eshellCSH:
586             fprintf(fp, " \"c/-/(");
587             for (i = 0; i < nfile; i++)
588             {
589                 fprintf(fp, " %s", fnm[i].opt+1);
590             }
591             for (i = 0; i < npargs; i++)
592             {
593                 if ( (pa[i].type == etBOOL) && *(pa[i].u.b) )
594                 {
595                     fprintf(fp, " no%s", pa[i].option+1);
596                 }
597                 else
598                 {
599                     fprintf(fp, " %s", pa[i].option+1);
600                 }
601             }
602             fprintf(fp, ")/\"");
603             break;
604         case eshellBASH:
605             fprintf(fp, "if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W '");
606             for (i = 0; i < nfile; i++)
607             {
608                 fprintf(fp, " -%s", fnm[i].opt+1);
609             }
610             for (i = 0; i < npargs; i++)
611             {
612                 if ( (pa[i].type == etBOOL) && *(pa[i].u.b) )
613                 {
614                     fprintf(fp, " -no%s", pa[i].option+1);
615                 }
616                 else
617                 {
618                     fprintf(fp, " -%s", pa[i].option+1);
619                 }
620             }
621             fprintf(fp, "' -- $c)); return 0; fi\n");
622             break;
623         case eshellZSH:
624             fprintf(fp, " -x 's[-]' -s \"");
625             for (i = 0; i < nfile; i++)
626             {
627                 fprintf(fp, " %s", fnm[i].opt+1);
628             }
629             for (i = 0; i < npargs; i++)
630             {
631                 if ( (pa[i].type == etBOOL) && *(pa[i].u.b) )
632                 {
633                     fprintf(fp, " no%s", pa[i].option+1);
634                 }
635                 else
636                 {
637                     fprintf(fp, " %s", pa[i].option+1);
638                 }
639             }
640             fprintf(fp, "\" ");
641             break;
642     }
643 }
644
645 static void write_cshcompl(FILE *out,
646                            int nfile,  t_filenm *fnm,
647                            int npargs, t_pargs *pa)
648 {
649     fprintf(out, "complete %s", ShortProgram());
650     pr_enums(out, npargs, pa, eshellCSH);
651     pr_fopts(out, nfile, fnm, eshellCSH);
652     pr_opts(out, nfile, fnm, npargs, pa, eshellCSH);
653     fprintf(out, "\n");
654 }
655
656 static void write_zshcompl(FILE *out,
657                            int nfile,  t_filenm *fnm,
658                            int npargs, t_pargs *pa)
659 {
660     fprintf(out, "compctl ");
661
662     /* start with options, since they are always present */
663     pr_opts(out, nfile, fnm, npargs, pa, eshellZSH);
664     pr_enums(out, npargs, pa, eshellZSH);
665     pr_fopts(out, nfile, fnm, eshellZSH);
666     fprintf(out, "-- %s\n", ShortProgram());
667 }
668
669 static void write_bashcompl(FILE *out,
670                             int nfile,  t_filenm *fnm,
671                             int npargs, t_pargs *pa)
672 {
673     /* Advanced bash completions are handled by shell functions.
674      * p and c hold the previous and current word on the command line.
675      * We need to use extended globbing, so write it in each completion file */
676     fprintf(out, "shopt -s extglob\n");
677     fprintf(out, "_%s_compl() {\nlocal p c\n", ShortProgram());
678     fprintf(out, "COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}\n");
679     pr_opts(out, nfile, fnm, npargs, pa, eshellBASH);
680     fprintf(out, "case \"$p\" in\n");
681
682     pr_enums(out, npargs, pa, eshellBASH);
683     pr_fopts(out, nfile, fnm, eshellBASH);
684     fprintf(out, "esac }\ncomplete -F _%s_compl %s\n", ShortProgram(), ShortProgram());
685 }
686
687 void write_man(const char *mantp,
688                const char *program,
689                int nldesc, const char **desc,
690                int nfile, t_filenm *fnm,
691                int npargs, t_pargs *pa,
692                int nbug, const char **bugs)
693 {
694     bool        bHidden = false;
695     int         npar;
696     t_pargs    *par;
697
698     const gmx::CommandLineHelpContext *context
699         = gmx::GlobalCommandLineHelpContext::get();
700     bool  bFileOpened = false;
701     FILE *out;
702     if (context != NULL)
703     {
704         out     = context->writerContext().outputFile().handle();
705         bHidden = context->showHidden();
706     }
707     else
708     {
709         char buf[256];
710         sprintf(buf, "%s.%s", program, mantp);
711         out         = gmx_fio_fopen(buf, "w");
712         bFileOpened = true;
713     }
714
715     if (bHidden)
716     {
717         npar = npargs;
718         par  = pa;
719     }
720     else
721     {
722         snew(par, npargs);
723         npar = 0;
724         for (int i = 0; i < npargs; i++)
725         {
726             if (!is_hidden(&pa[i]))
727             {
728                 par[npar] = pa[i];
729                 npar++;
730             }
731         }
732     }
733
734     if (strcmp(mantp, "nroff") == 0)
735     {
736         GMX_RELEASE_ASSERT(context != NULL,
737                            "Man page export only implemented with the new context");
738         write_nroffman(out, context->moduleDisplayName(), nldesc, desc,
739                        nfile, fnm, npar, par, nbug, bugs,
740                        context->writerContext());
741     }
742     if (strcmp(mantp, "help") == 0)
743     {
744         GMX_RELEASE_ASSERT(context != NULL,
745                            "Help export only implemented with the new context");
746         write_ttyman(out, nldesc, desc, nfile, fnm, npar, par, nbug, bugs,
747                      context->writerContext());
748     }
749     if (strcmp(mantp, "html") == 0)
750     {
751         GMX_RELEASE_ASSERT(context != NULL,
752                            "HTML export only implemented with the new context");
753         write_htmlman(out, nldesc, desc, nfile, fnm, npar, par, nbug, bugs,
754                       context->writerContext());
755     }
756     if (strcmp(mantp, "completion-zsh") == 0)
757     {
758         write_zshcompl(out, nfile, fnm, npar, par);
759     }
760     if (strcmp(mantp, "completion-bash") == 0)
761     {
762         write_bashcompl(out, nfile, fnm, npar, par);
763     }
764     if (strcmp(mantp, "completion-csh") == 0)
765     {
766         write_cshcompl(out, nfile, fnm, npar, par);
767     }
768
769     if (bFileOpened)
770     {
771         gmx_fio_fclose(out);
772     }
773
774     if (!bHidden)
775     {
776         sfree(par);
777     }
778 }
779
780 const char *get_arg_desc(int type)
781 {
782     static const char *argtp[etNR] = {
783         "int", "step", "real", "time", "string", "bool", "vector", "enum"
784     };
785     return argtp[type];
786 }