Code beautification with uncrustify
[alexxy/gromacs.git] / src / gromacs / gmxlib / 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 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #include <time.h>
40
41 #include <string>
42
43 #include "gromacs/utility/exceptions.h"
44 #include "gromacs/utility/stringutil.h"
45
46 #include "gmx_fatal.h"
47 #include "string2.h"
48 #include "smalloc.h"
49 #include "sysstuff.h"
50 #include "filenm.h"
51 #include "macros.h"
52 #include "wman.h"
53 #include "statutil.h"
54 #include "copyrite.h"
55 #include "strdb.h"
56 #include "readinp.h"
57
58 /* The source code in this file should be thread-safe.
59          Please keep it that way. */
60
61
62 typedef struct {
63     const char *search, *replace;
64 } t_sandr_const;
65
66 typedef struct {
67     char *search, *replace;
68 } t_sandr;
69
70 /* The order of these arrays is significant. Text search and replace
71  * for each element occurs in order, so earlier changes can induce
72  * subsequent changes even though the original text might not appear
73  * to invoke the latter changes. */
74
75 const t_sandr_const sandrTeX[] = {
76     { "[TT]", "{\\tt " },
77     { "[tt]", "}"      },
78     { "[BB]", "{\\bf " },
79     { "[bb]", "}"      },
80     { "[IT]", "{\\em " },
81     { "[it]", "}"      },
82     { "[PAR]", "\n\n"   },
83     /* Escaping underscore for LaTeX is no longer necessary, and it breaks
84      * text searching and the index if you do. */
85     /*
86        { "_",    "\\_"    },
87      */
88     { "$",    "\\$"    },
89     { "<=",   "\\ensuremath{\\leq{}}"},
90     { ">=",   "\\ensuremath{\\geq{}}"},
91     { "<",    "\\textless{}" },
92     { ">",    "\\textgreater{}" },
93     { "^",    "\\^{}"    },
94     { "\\^{}t", "\\ensuremath{^t}" },
95     { "\\^{}a", "\\ensuremath{^a}" },
96     { "\\^{}b", "\\ensuremath{^b}" },
97     { "\\^{}2", "\\ensuremath{^2}" },
98     { "\\^{}3", "\\ensuremath{^3}" },
99     { "\\^{}6", "\\ensuremath{^6}" },
100     { "#",    "\\#"    },
101     { "[BR]", "\\\\"   },
102     { "%",    "\\%"    },
103     { "&",    "\\&"    },
104     /* The next couple of lines allow true Greek symbols to be written to the
105        manual, which makes it look pretty */
106     { "[GRK]", "\\ensuremath{\\" },
107     { "[grk]", "}" },
108     { "[MATH]", "\\ensuremath{" },
109     { "[math]", "}" },
110     { "[CHEVRON]", "\\ensuremath{<}" },
111     { "[chevron]", "\\ensuremath{>}" },
112     { "[MAG]", "\\ensuremath{|}" },
113     { "[mag]", "\\ensuremath{|}" },
114     { "[INT]", "\\ensuremath{\\int" },
115     { "[FROM]", "_" },
116     { "[from]", "" },
117     { "[TO]", "^" },
118     { "[to]", "" },
119     { "[int]", "}" },
120     { "[SUM]", "\\ensuremath{\\sum" },
121     { "[sum]", "}" },
122     { "[SUB]", "\\ensuremath{_{" },
123     { "[sub]", "}}" },
124     { "[SQRT]", "\\ensuremath{\\sqrt{" },
125     { "[sqrt]", "}}" },
126     { "[EXP]", "\\ensuremath{\\exp{(" },
127     { "[exp]", ")}}" },
128     { "[LN]", "\\ensuremath{\\ln{(" },
129     { "[ln]", ")}}" },
130     { "[LOG]", "\\ensuremath{\\log{(" },
131     { "[log]", ")}}" },
132     { "[COS]", "\\ensuremath{\\cos{(" },
133     { "[cos]", ")}}" },
134     { "[SIN]", "\\ensuremath{\\sin{(" },
135     { "[sin]", ")}}" },
136     { "[TAN]", "\\ensuremath{\\tan{(" },
137     { "[tan]", ")}}" },
138     { "[COSH]", "\\ensuremath{\\cosh{(" },
139     { "[cosh]", ")}}" },
140     { "[SINH]", "\\ensuremath{\\sinh{(" },
141     { "[sinh]", ")}}" },
142     { "[TANH]", "\\ensuremath{\\tanh{(" },
143     { "[tanh]", ")}}" }
144 };
145 #define NSRTEX asize(sandrTeX)
146
147 const t_sandr_const sandrTty[] = {
148     { "[TT]", "" },
149     { "[tt]", "" },
150     { "[BB]", "" },
151     { "[bb]", "" },
152     { "[IT]", "" },
153     { "[it]", "" },
154     { "[MATH]", "" },
155     { "[math]", "" },
156     { "[CHEVRON]", "<" },
157     { "[chevron]", ">" },
158     { "[MAG]", "|" },
159     { "[mag]", "|" },
160     { "[INT]", "integral" },
161     { "[FROM]", " from " },
162     { "[from]", "" },
163     { "[TO]", " to " },
164     { "[to]", " of" },
165     { "[int]", "" },
166     { "[SUM]", "sum" },
167     { "[sum]", "" },
168     { "[SUB]", "_" },
169     { "[sub]", "" },
170     { "[SQRT]", "sqrt(" },
171     { "[sqrt]", ")" },
172     { "[EXP]", "exp(" },
173     { "[exp]", ")" },
174     { "[LN]", "ln(" },
175     { "[ln]", ")" },
176     { "[LOG]", "log(" },
177     { "[log]", ")" },
178     { "[COS]", "cos(" },
179     { "[cos]", ")" },
180     { "[SIN]", "sin(" },
181     { "[sin]", ")" },
182     { "[TAN]", "tan(" },
183     { "[tan]", ")" },
184     { "[COSH]", "cosh(" },
185     { "[cosh]", ")" },
186     { "[SINH]", "sinh(" },
187     { "[sinh]", ")" },
188     { "[TANH]", "tanh(" },
189     { "[tanh]", ")" },
190     { "[PAR]", "\n\n" },
191     { "[BR]", "\n"},
192     { "[GRK]", "" },
193     { "[grk]", "" }
194 };
195 #define NSRTTY asize(sandrTty)
196
197 const t_sandr_const sandrWiki[] = {
198     { "&",    "&amp;" },
199     { "<",    "&lt;" },
200     { ">",    "&gt;" },
201     { "[TT]", "&lt;code&gt;" },
202     { "[tt]", "&lt;/code&gt;" },
203     { "[BB]", "'''" },
204     { "[bb]", "'''" },
205     { "[IT]", "''" },
206     { "[it]", "''" },
207     { "[MATH]", "" },
208     { "[math]", "" },
209     { "[CHEVRON]", "<" },
210     { "[chevron]", ">" },
211     { "[MAG]", "|" },
212     { "[mag]", "|" },
213     { "[INT]", "integral" },
214     { "[FROM]", " from " },
215     { "[from]", "" },
216     { "[TO]", " to " },
217     { "[to]", " of" },
218     { "[int]", "" },
219     { "[SUM]", "sum" },
220     { "[sum]", "" },
221     { "[SUB]", "_" },
222     { "[sub]", "" },
223     { "[SQRT]", "sqrt(" },
224     { "[sqrt]", ")", },
225     { "[EXP]", "exp(" },
226     { "[exp]", ")" },
227     { "[LN]", "ln(" },
228     { "[ln]", ")" },
229     { "[LOG]", "log(" },
230     { "[log]", ")" },
231     { "[COS]", "cos(" },
232     { "[cos]", ")" },
233     { "[SIN]", "sin(" },
234     { "[sin]", ")" },
235     { "[TAN]", "tan(" },
236     { "[tan]", ")" },
237     { "[COSH]", "cosh(" },
238     { "[cosh]", ")" },
239     { "[SINH]", "sinh(" },
240     { "[sinh]", ")" },
241     { "[TANH]", "tanh(" },
242     { "[tanh]", ")" },
243     { "[PAR]", "\n\n" },
244     { "[BR]", "\n" },
245     { "[GRK]", "&" },
246     { "[grk]", ";" }
247 };
248 #define NSRWIKI asize(sandrWiki)
249
250 const t_sandr_const sandrNROFF[] = {
251     { "[TT]", "\\fB " },
252     { "[tt]", "\\fR" },
253     { "[BB]", "\\fB " },
254     { "[bb]", "\\fR" },
255     { "[IT]", "\\fI " },
256     { "[it]", "\\fR" },
257     { "[MATH]", "" },
258     { "[math]", "" },
259     { "[CHEVRON]", "<" },
260     { "[chevron]", ">" },
261     { "[MAG]", "|" },
262     { "[mag]", "|" },
263     { "[INT]", "integral" },
264     { "[FROM]", " from " },
265     { "[from]", "" },
266     { "[TO]", " to " },
267     { "[to]", " of" },
268     { "[int]", "" },
269     { "[SUM]", "sum" },
270     { "[sum]", "" },
271     { "[SUB]", "_" },
272     { "[sub]", "" },
273     { "[SQRT]", "sqrt(" },
274     { "[sqrt]", ")", },
275     { "[EXP]", "exp(" },
276     { "[exp]", ")" },
277     { "[LN]", "ln(" },
278     { "[ln]", ")" },
279     { "[LOG]", "log(" },
280     { "[log]", ")" },
281     { "[COS]", "cos(" },
282     { "[cos]", ")" },
283     { "[SIN]", "sin(" },
284     { "[sin]", ")" },
285     { "[TAN]", "tan(" },
286     { "[tan]", ")" },
287     { "[COSH]", "cosh(" },
288     { "[cosh]", ")" },
289     { "[SINH]", "sinh(" },
290     { "[sinh]", ")" },
291     { "[TANH]", "tanh(" },
292     { "[tanh]", ")" },
293     { "[PAR]", "\n\n" },
294     { "\n ",    "\n" },
295     { "<",    "" },
296     { ">",    "" },
297     { "^",    "" },
298     { "#",    "" },
299     { "[BR]", "\n"},
300     { "-",    "\\-"},
301     { "[GRK]", "" },
302     { "[grk]", "" }
303 };
304 #define NSRNROFF asize(sandrNROFF)
305
306 const t_sandr_const sandrHTML[] = {
307     { "<",    "&lt;" },
308     { ">",    "&gt;" },
309     { "[TT]", "<tt>" },
310     { "[tt]", "</tt>" },
311     { "[BB]", "<b>" },
312     { "[bb]", "</b>" },
313     { "[IT]", "<it>" },
314     { "[it]", "</it>" },
315     { "[MATH]", "" },
316     { "[math]", "" },
317     { "[CHEVRON]", "<" },
318     { "[chevron]", ">" },
319     { "[MAG]", "|" },
320     { "[mag]", "|" },
321     { "[INT]", "integral" },
322     { "[FROM]", " from " },
323     { "[from]", "" },
324     { "[TO]", " to " },
325     { "[to]", " of" },
326     { "[int]", "" },
327     { "[SUM]", "sum" },
328     { "[sum]", "" },
329     { "[SUB]", "_" },
330     { "[sub]", "" },
331     { "[SQRT]", "sqrt(" },
332     { "[sqrt]", ")", },
333     { "[EXP]", "exp(" },
334     { "[exp]", ")" },
335     { "[LN]", "ln(" },
336     { "[ln]", ")" },
337     { "[LOG]", "log(" },
338     { "[log]", ")" },
339     { "[COS]", "cos(" },
340     { "[cos]", ")" },
341     { "[SIN]", "sin(" },
342     { "[sin]", ")" },
343     { "[TAN]", "tan(" },
344     { "[tan]", ")" },
345     { "[COSH]", "cosh(" },
346     { "[cosh]", ")" },
347     { "[SINH]", "sinh(" },
348     { "[sinh]", ")" },
349     { "[TANH]", "tanh(" },
350     { "[tanh]", ")" },
351     { "[PAR]", "<p>" },
352     { "[BR]", "<br>" },
353     { "[GRK]", "&"  },
354     { "[grk]", ";"  }
355 };
356 #define NSRHTML asize(sandrHTML)
357
358 const t_sandr_const sandrXML[] = {
359     { "<",    "&lt;" },
360     { ">",    "&gt;" },
361     { "[TT]", "<arg>" },
362     { "[tt]", "</arg>" },
363     { "[BB]", "<emp>" },
364     { "[bb]", "</emp>" },
365     { "[IT]", "<it>" },
366     { "[it]", "</it>" },
367     { "[MATH]", "" },
368     { "[math]", "" },
369     { "[CHEVRON]", "<" },
370     { "[chevron]", ">" },
371     { "[MAG]", "|" },
372     { "[mag]", "|" },
373     { "[INT]", "integral" },
374     { "[FROM]", " from " },
375     { "[from]", "" },
376     { "[TO]", " to " },
377     { "[to]", " of" },
378     { "[int]", "" },
379     { "[SUM]", "sum" },
380     { "[sum]", "" },
381     { "[SUB]", "_" },
382     { "[sub]", "" },
383     { "[SQRT]", "sqrt(" },
384     { "[sqrt]", ")", },
385     { "[EXP]", "exp(" },
386     { "[exp]", ")" },
387     { "[LN]", "ln(" },
388     { "[ln]", ")" },
389     { "[LOG]", "log(" },
390     { "[log]", ")" },
391     { "[COS]", "cos(" },
392     { "[cos]", ")" },
393     { "[SIN]", "sin(" },
394     { "[sin]", ")" },
395     { "[TAN]", "tan(" },
396     { "[tan]", ")" },
397     { "[COSH]", "cosh(" },
398     { "[cosh]", ")" },
399     { "[SINH]", "sinh(" },
400     { "[sinh]", ")" },
401     { "[TANH]", "tanh(" },
402     { "[tanh]", ")" },
403     { "[PAR]", "</par>\n<par>" },
404     { "[BR]", "<br />" },
405     { "[GRK]", "" },
406     { "[grk]", "" }
407 };
408 #define NSRXML asize(sandrXML)
409
410 static void mynum(char *buf, int n)
411 {
412     if (n >= 10)
413     {
414         sprintf(buf, "%2d", n);
415     }
416     else
417     {
418         sprintf(buf, "0%1d", n);
419     }
420 }
421
422 static char *mydate(char buf[], int maxsize, gmx_bool bWiki)
423 {
424     const char *mon[] = {
425         "Jan", "Feb", "Mar", "Apr", "May", "Jun",
426         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
427     };
428     const char *day[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
429     time_t      now;
430     struct tm   tm;
431
432     time(&now);
433 #ifdef GMX_NATIVE_WINDOWS
434     /* Native windows */
435     localtime_s(&tm, &now);
436 #else
437     localtime_r(&now, &tm);
438 #endif
439
440     /* subtract one from maxsize, so we have room for \0. */
441     if (bWiki)
442     {
443         char dd[8], mm[8], ss[8], hh[8], mn[8];
444
445         mynum(dd, tm.tm_mday);
446         mynum(mm, tm.tm_mon);
447         mynum(ss, tm.tm_sec);
448         mynum(hh, tm.tm_hour);
449         mynum(mn, tm.tm_min);
450         sprintf(buf, "%4d-%2s-%2sT%2s:%2s:%2sZ",
451                 tm.tm_year+1900, mm, dd, hh, mn, ss);
452     }
453     else
454     {
455         sprintf(buf, "%s %d %s %d", day[tm.tm_wday], tm.tm_mday,
456                 mon[tm.tm_mon], tm.tm_year+1900);
457     }
458
459     return buf;
460 }
461
462 /* Data structure for saved HTML links */
463 typedef struct t_linkdata {
464     int      nsr;
465     t_sandr *sr;
466 } t_linkdata;
467
468 static t_linkdata *init_linkdata()
469 {
470     t_linkdata *p;
471     snew(p, 1);
472     p->sr  = NULL;
473     p->nsr = 0;
474
475     return p;
476 }
477
478 static void finish_linkdata(t_linkdata *p)
479 {
480     int i;
481
482     for (i = 0; i < p->nsr; i++)
483     {
484         sfree(p->sr[i].search);
485         sfree(p->sr[i].replace);
486     }
487     sfree(p->sr);
488     sfree(p);
489 }
490
491 static char *repall(const char *s, int nsr, const t_sandr_const sa[])
492 {
493     try
494     {
495         std::string result(s);
496         for (int i = 0; i < nsr; ++i)
497         {
498             result = gmx::replaceAll(result, sa[i].search, sa[i].replace);
499         }
500         return gmx_strdup(result.c_str());
501     }
502     GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
503 }
504
505 static char *repallww(const char *s, int nsr, const t_sandr sa[])
506 {
507     try
508     {
509         std::string result(s);
510         for (int i = 0; i < nsr; ++i)
511         {
512             result = gmx::replaceAllWords(result, sa[i].search, sa[i].replace);
513         }
514         return gmx_strdup(result.c_str());
515     }
516     GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
517 }
518
519 static char *html_xref(char *s, const char *program, t_linkdata *links, gmx_bool bWiki)
520 {
521     char   buf[256], **filestr;
522     int    i, j, n;
523
524     if (links->sr == NULL)
525     {
526         n          = get_file("links.dat", &(filestr));
527         links->nsr = n;
528         snew(links->sr, n);
529         for (i = 0, j = 0; (i < n); i++)
530         {
531             if (!program || (gmx_strcasecmp(program, filestr[i])  != 0))
532             {
533                 links->sr[j].search = gmx_strdup(filestr[i]);
534                 if (bWiki)
535                 {
536                     sprintf(buf, "[[%s]]", filestr[i]);
537                 }
538                 else
539                 {
540                     sprintf(buf, "<a href=\"%s.html\">%s</a>", filestr[i], filestr[i]);
541                 }
542                 links->sr[j].replace = gmx_strdup(buf);
543                 j++;
544             }
545         }
546         links->nsr = j;
547         for (i = 0; i < n; i++)
548         {
549             sfree(filestr[i]);
550         }
551         sfree(filestr);
552     }
553     return repallww(s, links->nsr, links->sr);
554 }
555
556 char *check_tex(const char *s)
557 {
558     return repall(s, NSRTEX, sandrTeX);
559 }
560
561 static char *check_nroff(const char *s)
562 {
563     return repall(s, NSRNROFF, sandrNROFF);
564 }
565
566 static char *check_wiki(const char *s, const char *program, t_linkdata *links)
567 {
568     char *buf;
569
570     buf = repall(s, NSRWIKI, sandrWiki);
571     buf = html_xref(buf, program, links, TRUE);
572
573     return buf;
574 }
575
576 static char *check_html(const char *s, const char *program, t_linkdata *links)
577 {
578     char *buf;
579
580     buf = repall(s, NSRHTML, sandrHTML);
581     buf = html_xref(buf, program, links, FALSE);
582
583     return buf;
584 }
585
586 #define NWR(s) check_wiki(s, program, links)
587 #define NSR(s) check_html(s, program, links)
588
589 #define FLAG_SET(flag, mask) ((flag &mask) == mask)
590 char *fileopt(unsigned long flag, char buf[], int maxsize)
591 {
592     char tmp[256];
593
594     if (FLAG_SET(flag, ffRW))
595     {
596         sprintf(tmp, "In/Out");
597     }
598     else if (FLAG_SET(flag, ffREAD))
599     {
600         sprintf(tmp, "Input");
601     }
602     else if (FLAG_SET(flag, ffWRITE))
603     {
604         sprintf(tmp, "Output");
605     }
606     else
607     {
608         sprintf(tmp, "Dunno");
609     }
610
611     if (FLAG_SET(flag, ffOPT))
612     {
613         strcat(tmp, ", Opt");
614         if (FLAG_SET(flag, ffSET))
615         {
616             strcat(tmp, "!");
617         }
618         else
619         {
620             strcat(tmp, ".");
621         }
622     }
623     if (FLAG_SET(flag, ffLIB))
624     {
625         strcat(tmp, ", Lib.");
626     }
627     if (FLAG_SET(flag, ffMULT))
628     {
629         strcat(tmp, ", Mult.");
630     }
631
632     sprintf(buf, "%s", tmp);
633
634     return buf;
635 }
636
637 static void write_texman(FILE *out, const char *program,
638                          int nldesc, const char **desc,
639                          int nfile, t_filenm *fnm,
640                          int npargs, t_pargs *pa,
641                          int nbug, const char **bugs,
642                          t_linkdata *links)
643 {
644     int  i;
645     char tmp[256];
646
647     fprintf(out, "\\section{\\normindex{%s}}\\label{%s}\n\n", check_tex(program), check_tex(program));
648
649     if (nldesc > 0)
650     {
651         for (i = 0; (i < nldesc); i++)
652         {
653             fprintf(out, "%s\n", check_tex(desc[i]));
654         }
655     }
656
657     if (nfile > 0)
658     {
659         fprintf(out, "\\vspace{-2ex}\\begin{tabbing}\n");
660         fprintf(out, "\n{\\normalsize \\bf Files}\\nopagebreak\\\\\n");
661         fprintf(out, "{\\tt ~~~~~~~} \\= {\\tt ~~~~~~~~~~~~~~} \\= "
662                 "~~~~~~~~~~~~~~~~~~~~~~ \\= \\nopagebreak\\kill\n");
663         for (i = 0; (i < nfile); i++)
664         {
665             fprintf(out, "\\>{\\tt %s} \\'\\> {\\tt %s} \\' %s \\> "
666                     "\\parbox[t]{0.55\\linewidth}{%s} \\\\\n",
667                     check_tex(fnm[i].opt), check_tex(fnm[i].fns[0]),
668                     check_tex(fileopt(fnm[i].flag, tmp, 255)),
669                     check_tex(ftp2desc(fnm[i].ftp)));
670         }
671         fprintf(out, "\\end{tabbing}\\vspace{-4ex}\n");
672     }
673     if (npargs > 0)
674     {
675         fprintf(out, "\\vspace{-2ex}\\begin{tabbing}\n");
676         fprintf(out, "\n{\\normalsize \\bf Other options}\\nopagebreak\\\\\n");
677         fprintf(out, "{\\tt ~~~~~~~~~~} \\= vector \\= "
678                 "{\\tt ~~~~~~~} \\= \\nopagebreak\\kill\n");
679         for (i = 0; (i < npargs); i++)
680         {
681             if (strlen(check_tex(pa_val(&(pa[i]), tmp, 255))) <= 8)
682             {
683                 fprintf(out, "\\> {\\tt %s} \\'\\> %s \\'\\> {\\tt %s} \\' "
684                         "\\parbox[t]{0.68\\linewidth}{%s}\\\\\n",
685                         check_tex(pa[i].option), get_arg_desc(pa[i].type),
686                         check_tex(pa_val(&(pa[i]), tmp, 255)),
687                         check_tex(pa[i].desc));
688             }
689             else
690             {
691                 fprintf(out, "\\> {\\tt %s} \\'\\> %s \\'\\>\\\\\n"
692                         "\\> \\'\\> \\'\\> {\\tt %s} \\' "
693                         "\\parbox[t]{0.7\\linewidth}{%s}\\\\\n",
694                         check_tex(pa[i].option), get_arg_desc(pa[i].type),
695                         check_tex(pa_val(&(pa[i]), tmp, 255)),
696                         check_tex(pa[i].desc));
697             }
698         }
699         fprintf(out, "\\end{tabbing}\\vspace{-4ex}\n");
700     }
701     if (nbug > 0)
702     {
703         fprintf(out, "\n");
704         fprintf(out, "\\begin{itemize}\n");
705         for (i = 0; (i < nbug); i++)
706         {
707             fprintf(out, "\\item %s\n", check_tex(bugs[i]));
708         }
709         fprintf(out, "\\end{itemize}\n");
710     }
711 /*   fprintf(out,"\n\\newpage\n"); */
712 }
713
714 static void write_nroffman(FILE *out,
715                            const char *program,
716                            int nldesc, const char **desc,
717                            int nfile, t_filenm *fnm,
718                            int npargs, t_pargs *pa,
719                            int nbug, const char **bugs,
720                            t_linkdata *links)
721
722 {
723     int  i;
724     char tmp[256];
725
726
727     fprintf(out, ".TH %s 1 \"%s\" \"\" \"GROMACS suite, %s\"\n", program, mydate(tmp, 255, FALSE), GromacsVersion());
728     fprintf(out, ".SH NAME\n");
729     fprintf(out, "%s@DESC@\n\n", program);
730     fprintf(out, ".B %s\n", GromacsVersion());
731
732     fprintf(out, ".SH SYNOPSIS\n");
733     fprintf(out, "\\f3%s\\fP\n", program);
734
735     /* command line arguments */
736     if (nfile > 0)
737     {
738         for (i = 0; (i < nfile); i++)
739         {
740             fprintf(out, ".BI \"%s\" \" %s \"\n", check_nroff(fnm[i].opt),
741                     check_nroff(fnm[i].fns[0]));
742         }
743     }
744     if (npargs > 0)
745     {
746         for (i = 0; (i < npargs); i++)
747         {
748             if (pa[i].type == etBOOL)
749             {
750                 fprintf(out, ".BI \"\\-[no]%s\" \"\"\n", check_nroff(pa[i].option+1));
751             }
752             else
753             {
754                 fprintf(out, ".BI \"%s\" \" %s \"\n", check_nroff(pa[i].option),
755                         check_nroff(get_arg_desc(pa[i].type)));
756             }
757         }
758     }
759
760     /* description */
761     if (nldesc > 0)
762     {
763         fprintf(out, ".SH DESCRIPTION\n");
764         for (i = 0; (i < nldesc); i++)
765         {
766             fprintf(out, "\\&%s\n", check_nroff(desc[i]));
767         }
768     }
769
770     /* FILES */
771     if (nfile > 0)
772     {
773         fprintf(out, ".SH FILES\n");
774         for (i = 0; (i < nfile); i++)
775         {
776             fprintf(out, ".BI \"%s\" \" %s\" \n.B %s\n %s \n\n",
777                     check_nroff(fnm[i].opt),
778                     check_nroff(fnm[i].fns[0]),
779                     check_nroff(fileopt(fnm[i].flag, tmp, 255)),
780                     check_nroff(ftp2desc(fnm[i].ftp)));
781         }
782     }
783
784     /* other options */
785     fprintf(out, ".SH OTHER OPTIONS\n");
786     if (npargs > 0)
787     {
788         for (i = 0; (i < npargs); i++)
789         {
790             if (pa[i].type == etBOOL)
791             {
792                 fprintf(out, ".BI \"\\-[no]%s\"  \"%s\"\n %s\n\n",
793                         check_nroff(pa[i].option+1),
794                         check_nroff(pa_val(&(pa[i]), tmp, 255)),
795                         check_nroff(pa[i].desc));
796             }
797             else
798             {
799                 fprintf(out, ".BI \"%s\"  \" %s\" \" %s\" \n %s\n\n",
800                         check_nroff(pa[i].option),
801                         check_nroff(get_arg_desc(pa[i].type)),
802                         check_nroff(pa_val(&(pa[i]), tmp, 255)),
803                         check_nroff(pa[i].desc));
804             }
805         }
806     }
807
808     if (nbug > 0)
809     {
810         fprintf(out, ".SH KNOWN PROBLEMS\n");
811         for (i = 0; (i < nbug); i++)
812         {
813             fprintf(out, "\\- %s\n\n", check_nroff(bugs[i]));
814         }
815     }
816
817     fprintf(out, ".SH SEE ALSO\n.BR gromacs(7)\n\n");
818     fprintf(out, "More information about \\fBGROMACS\\fR is available at <\\fIhttp://www.gromacs.org/\\fR>.\n");
819
820 }
821
822 char *check_tty(const char *s)
823 {
824     return repall(s, NSRTTY, sandrTty);
825 }
826
827 void
828 print_tty_formatted(FILE *out, int nldesc, const char **desc, int indent,
829                     t_linkdata *links, const char *program, gmx_bool bWiki)
830 {
831     char *buf;
832     char *temp;
833     int   buflen, i;
834
835     buflen = 80*nldesc;
836     snew(buf, buflen);
837     for (i = 0; (i < nldesc); i++)
838     {
839         if ((strlen(buf) > 0) &&
840             (buf[strlen(buf)-1] != ' ') && (buf[strlen(buf)-1] != '\n'))
841         {
842             strcat(buf, " ");
843         }
844         if (bWiki)
845         {
846             temp = NWR(desc[i]);
847         }
848         else
849         {
850             temp = check_tty(desc[i]);
851         }
852         if (strlen(buf) + strlen(temp) >= (size_t)(buflen-2))
853         {
854             buflen += strlen(temp);
855             srenew(buf, buflen);
856         }
857         strcat(buf, temp);
858         sfree(temp);
859     }
860     /* Make lines of at most 79 characters */
861     temp = wrap_lines(buf, 78, indent, FALSE);
862     fprintf(out, "%s\n", temp);
863     sfree(temp);
864     sfree(buf);
865 }
866
867 static void write_ttyman(FILE *out,
868                          const char *program,
869                          int nldesc, const char **desc,
870                          int nfile, t_filenm *fnm,
871                          int npargs, t_pargs *pa,
872                          int nbug, const char **bugs, gmx_bool bHeader,
873                          t_linkdata *links)
874 {
875     int   i;
876     char  buf[256];
877     char *tmp;
878
879     if (bHeader)
880     {
881         fprintf(out, "%s\n\n", check_tty(program));
882         fprintf(out, "%s\n%s\n", GromacsVersion(), mydate(buf, 255, FALSE));
883     }
884     if (nldesc > 0)
885     {
886         fprintf(out, "DESCRIPTION\n-----------\n");
887         print_tty_formatted(out, nldesc, desc, 0, links, program, FALSE);
888     }
889     if (nbug > 0)
890     {
891         fprintf(out, "\n");
892         fprintf(out, "KNOWN PROBLEMS\n----------\n");
893         for (i = 0; i < nbug; i++)
894         {
895             snew(tmp, strlen(bugs[i])+3);
896             strcpy(tmp, "* ");
897             strcpy(tmp+2, check_tty(bugs[i]));
898             fprintf(out, "%s\n", wrap_lines(tmp, 78, 2, FALSE));
899             sfree(tmp);
900         }
901     }
902     if (nfile > 0)
903     {
904         fprintf(out, "\n");
905         pr_fns(out, nfile, fnm);
906     }
907     if (npargs > 0)
908     {
909         print_pargs(out, npargs, pa, FALSE);
910     }
911 }
912
913 static void pr_html_files(FILE *out, int nfile, t_filenm fnm[],
914                           const char *program, t_linkdata *links, gmx_bool bWiki)
915 {
916     int  i;
917     char link[10], tmp[255];
918
919     if (bWiki)
920     {
921         fprintf(out, " %-10s %-12s %-12s %-s\n"
922                 " -----------------------------------------------------\n",
923                 "Option", "Filename", "Type", "Description");
924     }
925     else
926     {
927         fprintf(out,
928                 "<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=2>\n"
929                 "<TR>"
930                 "<TH>option</TH>"
931                 "<TH>filename</TH>"
932                 "<TH>type</TH>"
933                 "<TH>description</TH>"
934                 "</TR>\n");
935     }
936
937     for (i = 0; (i < nfile); i++)
938     {
939         strcpy(link, ftp2ext(fnm[i].ftp));
940         if (strcmp(link, "???") == 0)
941         {
942             strcpy(link, "files");
943         }
944         if (bWiki)
945         {
946             fprintf(out, " %-10s %-16s %-12s %-s\n",
947                     fnm[i].opt,
948                     NWR(fnm[i].fns[0]),
949                     fileopt(fnm[i].flag, tmp, 255),
950                     NWR(ftp2desc(fnm[i].ftp)));
951         }
952         else
953         {
954             fprintf(out,
955                     "<TR>"
956                     "<TD ALIGN=RIGHT> <b><tt>%s</tt></b> </TD>"
957                     "<TD ALIGN=RIGHT> <tt><a href=\"%s.html\">%12s</a></tt> </TD>"
958                     "<TD> %s </TD>"
959                     "<TD> %s </TD>"
960                     "</TR>\n",
961                     fnm[i].opt, link, fnm[i].fns[0], fileopt(fnm[i].flag, tmp, 255),
962                     NSR(ftp2desc(fnm[i].ftp)));
963         }
964     }
965     if (!bWiki)
966     {
967         fprintf(out, "</TABLE>\n");
968     }
969 }
970
971 static void write_wikiman(FILE *out,
972                           const char *program,
973                           int nldesc, const char **desc,
974                           int nfile, t_filenm *fnm,
975                           int npargs, t_pargs *pa,
976                           int nbug, const char **bugs, gmx_bool bHeader,
977                           t_linkdata *links)
978 {
979     int   i;
980     char  buf[256];
981     char *tmp;
982     fprintf(out, "<page>\n<title>Manual:%s_%s</title>\n", program,
983             VERSION);
984     fprintf(out, "<revision>\n");
985     fprintf(out, "<timestamp>%s</timestamp>\n", mydate(buf, 255, TRUE));
986     fprintf(out, "<text xml:space=\"preserve\">\n");
987     if (nldesc > 0)
988     {
989         fprintf(out, "== Description ==\n");
990         print_tty_formatted(out, nldesc, desc, 0, links, program, TRUE);
991         fprintf(out, "\n");
992     }
993     if (nbug > 0)
994     {
995         fprintf(out, "== Known Problems ==\n");
996         for (i = 0; i < nbug; i++)
997         {
998             snew(tmp, strlen(bugs[i])+3);
999             strcpy(tmp, "* ");
1000             strcpy(tmp+2, bugs[i]);
1001             fprintf(out, "%s\n", NWR(tmp));
1002             sfree(tmp);
1003         }
1004     }
1005     if (nfile > 0)
1006     {
1007         fprintf(out, "\n== Files ==\n");
1008         pr_html_files(out, nfile, fnm, program, links, TRUE);
1009     }
1010     if (npargs > 0)
1011     {
1012         fprintf(out, "\n== Options ==\n");
1013         fprintf(out, " %-12s %-6s %-6s  %-s\n",
1014                 "Option", "Type", "Value", "Description");
1015         fprintf(out, " ------------------------------------------------------\n");
1016         for (i = 0; (i < npargs); i++)
1017         {
1018             tmp = NWR(pargs_print_line(&pa[i], TRUE));
1019             fprintf(out, "%s", tmp);
1020             sfree(tmp);
1021         }
1022     }
1023     fprintf(out, "[[category:Manual_Pages_%s|%s]]\n", VERSION, program);
1024     fprintf(out, "</text>\n");
1025     fprintf(out, "</revision>\n");
1026     fprintf(out, "</page>\n\n");
1027 }
1028
1029 static void write_htmlman(FILE *out,
1030                           const char *program,
1031                           int nldesc, const char **desc,
1032                           int nfile, t_filenm *fnm,
1033                           int npargs, t_pargs *pa,
1034                           int nbug, const char **bugs,
1035                           t_linkdata *links)
1036 {
1037     int  i;
1038     char tmp[255];
1039
1040     fprintf(out, "<HTML>\n<HEAD>\n<TITLE>%s</TITLE>\n", program);
1041     fprintf(out, "<LINK rel=stylesheet href=\"style.css\" type=\"text/css\">\n");
1042     fprintf(out, "<BODY text=\"#000000\" bgcolor=\"#FFFFFF\" link=\"#0000FF\" vlink=\"#990000\" alink=\"#FF0000\">\n");
1043     fprintf(out, "<TABLE WIDTH=\"98%%\" NOBORDER >\n<TR><TD WIDTH=400>\n");
1044     fprintf(out, "<TABLE WIDTH=400 NOBORDER>\n<TD WIDTH=116>\n");
1045     fprintf(out, "<a href=\"http://www.gromacs.org/\">"
1046             "<img SRC=\"../images/gmxlogo_small.png\""
1047             "BORDER=0 </a></td>\n");
1048     fprintf(out, "<td ALIGN=LEFT VALIGN=TOP WIDTH=280>"
1049             "<br><h2>%s</h2>", program);
1050     fprintf(out, "<font size=-1><A HREF=\"../online.html\">Main Table of Contents</A></font><br>");
1051     fprintf(out, "<br></td>\n</TABLE></TD><TD WIDTH=\"*\" ALIGN=RIGHT VALIGN=BOTTOM><p><B>%s<br>\n", GromacsVersion());
1052     fprintf(out, "%s</B></td></tr></TABLE>\n<HR>\n", mydate(tmp, 255, FALSE));
1053
1054     if (nldesc > 0)
1055     {
1056         fprintf(out, "<H3>Description</H3>\n<p>\n");
1057         for (i = 0; (i < nldesc); i++)
1058         {
1059             fprintf(out, "%s\n", NSR(desc[i]));
1060         }
1061     }
1062     if (nfile > 0)
1063     {
1064         fprintf(out, "<P>\n");
1065         fprintf(out, "<H3>Files</H3>\n");
1066         pr_html_files(out, nfile, fnm, program, links, FALSE);
1067     }
1068     if (npargs > 0)
1069     {
1070         fprintf(out, "<P>\n");
1071         fprintf(out, "<H3>Other options</H3>\n");
1072         fprintf(out,
1073                 "<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=2>\n"
1074                 "<TR>"
1075                 "<TH>option</TH>"
1076                 "<TH>type</TH>"
1077                 "<TH>default</TH>"
1078                 "<TH>description</TH>"
1079                 "</TR>\n");
1080         for (i = 0; (i < npargs); i++)
1081         {
1082             fprintf(out,
1083                     "<TR>"
1084                     "<TD ALIGN=RIGHT> <b><tt>%s%s</tt></b> </TD>"
1085                     "<TD ALIGN=RIGHT> %s </TD>"
1086                     "<TD ALIGN=RIGHT> <tt>%s</tt> </TD>"
1087                     "<TD> %s </TD>"
1088                     "</TD>\n",
1089                     (pa[i].type == etBOOL) ? "-[no]" : "-", pa[i].option+1,
1090                     get_arg_desc(pa[i].type), pa_val(&(pa[i]), tmp, 255), NSR(pa[i].desc));
1091         }
1092         fprintf(out, "</TABLE>\n");
1093     }
1094     if (nbug > 0)
1095     {
1096         fprintf(out, "<P>\n");
1097         fprintf(out, "<H3>Known problems</H3>\n");
1098         fprintf(out, "<UL>\n");
1099         for (i = 0; (i < nbug); i++)
1100         {
1101             fprintf(out, "<LI>%s\n", NSR(bugs[i]));
1102         }
1103         fprintf(out, "</UL>\n");
1104     }
1105     fprintf(out, "<P>\n");
1106     fprintf(out, "<hr>\n<div ALIGN=RIGHT>\n");
1107     fprintf(out, "<font size=\"-1\"><a href=\"http://www.gromacs.org\">"
1108             "http://www.gromacs.org</a></font><br>\n");
1109     fprintf(out, "<font size=\"-1\"><a href=\"mailto:gromacs@gromacs.org\">"
1110             "gromacs@gromacs.org</a></font><br>\n");
1111     fprintf(out, "</div>\n");
1112     fprintf(out, "</BODY>\n");
1113 }
1114
1115 char *check_xml(const char *s, const char *program, t_linkdata *links)
1116 {
1117     char *buf;
1118
1119     buf = repall(s, NSRXML, sandrXML);
1120     buf = html_xref(buf, program, links, FALSE); /* the same in html and xml */
1121
1122     return buf;
1123 }
1124
1125 static void write_xmlman(FILE *out,
1126                          const char *program,
1127                          int nldesc, const char **desc,
1128                          int nfile, t_filenm *fnm,
1129                          int npargs, t_pargs *pa,
1130                          int nbug, const char **bugs,
1131                          t_linkdata *links)
1132 {
1133     int  i;
1134     char link[10], buf[256], opt[10];
1135
1136 #define NSR2(s) check_xml(s, program, links)
1137 #define FLAG(w, f) (((w) & (f)) == (f))
1138
1139     fprintf(out, "<gromacs-manual version=\"%s\" date=\"%s\" www=\"http://www.gromacs.org\">\n", GromacsVersion(), mydate(buf, 255, FALSE));
1140     /* fprintf(out,"<LINK rel=stylesheet href=\"style.css\" type=\"text/css\">\n"); */
1141
1142     fprintf(out, "<program name=\"%s\">", program);
1143     if (nldesc > 0)
1144     {
1145         fprintf(out, "\n<description>\n<par>\n");
1146         for (i = 0; (i < nldesc); i++)
1147         {
1148             fprintf(out, "%s\n", NSR2(desc[i]));
1149         }
1150     }
1151     fprintf(out, "</par>\n</description>\n");
1152
1153     if (nfile > 0)
1154     {
1155         fprintf(out, "\n<files>\n");
1156         for (i = 0; (i < nfile); i++)
1157         {
1158             strcpy(link, ftp2ext(fnm[i].ftp));
1159             if (strcmp(link, "???") == 0)
1160             {
1161                 strcpy(link, "files");
1162             }
1163             if (fnm[i].opt[0] == '-')
1164             {
1165                 strcpy(opt, fnm[i].opt+1);
1166             }
1167             else
1168             {
1169                 strcpy(opt, fnm[i].opt);
1170             }
1171             fprintf(out,
1172                     "<file type=\"%s\" typeid=\"%d\">\n"
1173                     "\t<flags read=\"%d\" write=\"%d\" optional=\"%d\"/>\n"
1174                     "\t<option>%s</option>\n"
1175                     "\t<default-name link=\"%s.html\">%s</default-name>\n"
1176                     "\t<description>%s</description>\n"
1177                     "</file>\n",
1178                     ftp2defnm(fnm[i].ftp), /* from gmxlib/filenm.c */
1179                     fnm[i].ftp,
1180                     FLAG(fnm[i].flag, ffREAD), FLAG(fnm[i].flag, ffWRITE), FLAG(fnm[i].flag, ffOPT),
1181                     opt, link, fnm[i].fn, /*fileopt(fnm[i].flag),*/
1182                     NSR(ftp2desc(fnm[i].ftp)));
1183         }
1184         fprintf(out, "</files>\n");
1185     }
1186
1187     if (npargs > 0)
1188     {
1189         fprintf(out, "\n<options>\n");
1190         for (i = 0; (i < npargs); i++)
1191         {
1192             fprintf(out,
1193                     "<option type=\"%s\" hidden=\"%d\">\n"
1194                     "\t<name >%s</name>\n"
1195                     "\t<default-value>%s</default-value>\n"
1196                     "\t<description>%s</description>\n"
1197                     "</option>\n",
1198                     get_arg_desc(pa[i].type), is_hidden(&pa[i]),
1199                     pa[i].option+1,                          /* +1 - with no trailing '-' */
1200                     pa_val(&(pa[i]), buf, 255), pa[i].desc); /*get_argtp()[pa[i].type],*/
1201         }
1202         fprintf(out, "</options>\n");
1203     }
1204
1205     if (nbug > 0)
1206     {
1207         fprintf(out, "\n<bugs>\n");
1208         for (i = 0; (i < nbug); i++)
1209         {
1210             fprintf(out, "\t<bug>%s</bug>\n", NSR(bugs[i]));
1211         }
1212         fprintf(out, "</bugs>\n");
1213     }
1214     fprintf(out, "\n</program>\n</gromacs-manual>\n");
1215 #undef FLAG
1216 }
1217
1218 static void pr_opts(FILE *fp,
1219                     int nfile,  t_filenm *fnm,
1220                     int npargs, t_pargs pa[], int shell)
1221 {
1222     int i;
1223
1224     switch (shell)
1225     {
1226         case eshellCSH:
1227             fprintf(fp, " \"c/-/(");
1228             for (i = 0; i < nfile; i++)
1229             {
1230                 fprintf(fp, " %s", fnm[i].opt+1);
1231             }
1232             for (i = 0; i < npargs; i++)
1233             {
1234                 if ( (pa[i].type == etBOOL) && *(pa[i].u.b) )
1235                 {
1236                     fprintf(fp, " no%s", pa[i].option+1);
1237                 }
1238                 else
1239                 {
1240                     fprintf(fp, " %s", pa[i].option+1);
1241                 }
1242             }
1243             fprintf(fp, ")/\"");
1244             break;
1245         case eshellBASH:
1246             fprintf(fp, "if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W '");
1247             for (i = 0; i < nfile; i++)
1248             {
1249                 fprintf(fp, " -%s", fnm[i].opt+1);
1250             }
1251             for (i = 0; i < npargs; i++)
1252             {
1253                 if ( (pa[i].type == etBOOL) && *(pa[i].u.b) )
1254                 {
1255                     fprintf(fp, " -no%s", pa[i].option+1);
1256                 }
1257                 else
1258                 {
1259                     fprintf(fp, " -%s", pa[i].option+1);
1260                 }
1261             }
1262             fprintf(fp, "' -- $c)); return 0; fi\n");
1263             break;
1264         case eshellZSH:
1265             fprintf(fp, " -x 's[-]' -s \"");
1266             for (i = 0; i < nfile; i++)
1267             {
1268                 fprintf(fp, " %s", fnm[i].opt+1);
1269             }
1270             for (i = 0; i < npargs; i++)
1271             {
1272                 if ( (pa[i].type == etBOOL) && *(pa[i].u.b) )
1273                 {
1274                     fprintf(fp, " no%s", pa[i].option+1);
1275                 }
1276                 else
1277                 {
1278                     fprintf(fp, " %s", pa[i].option+1);
1279                 }
1280             }
1281             fprintf(fp, "\" ");
1282             break;
1283     }
1284 }
1285
1286 static void write_cshcompl(FILE *out,
1287                            int nfile,  t_filenm *fnm,
1288                            int npargs, t_pargs *pa)
1289 {
1290     fprintf(out, "complete %s", ShortProgram());
1291     pr_enums(out, npargs, pa, eshellCSH);
1292     pr_fopts(out, nfile, fnm, eshellCSH);
1293     pr_opts(out, nfile, fnm, npargs, pa, eshellCSH);
1294     fprintf(out, "\n");
1295 }
1296
1297 static void write_zshcompl(FILE *out,
1298                            int nfile,  t_filenm *fnm,
1299                            int npargs, t_pargs *pa)
1300 {
1301     fprintf(out, "compctl ");
1302
1303     /* start with options, since they are always present */
1304     pr_opts(out, nfile, fnm, npargs, pa, eshellZSH);
1305     pr_enums(out, npargs, pa, eshellZSH);
1306     pr_fopts(out, nfile, fnm, eshellZSH);
1307     fprintf(out, "-- %s\n", ShortProgram());
1308 }
1309
1310 static void write_bashcompl(FILE *out,
1311                             int nfile,  t_filenm *fnm,
1312                             int npargs, t_pargs *pa)
1313 {
1314     /* Advanced bash completions are handled by shell functions.
1315      * p and c hold the previous and current word on the command line.
1316      * We need to use extended globbing, so write it in each completion file */
1317     fprintf(out, "shopt -s extglob\n");
1318     fprintf(out, "_%s_compl() {\nlocal p c\n", ShortProgram());
1319     fprintf(out, "COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}\n");
1320     pr_opts(out, nfile, fnm, npargs, pa, eshellBASH);
1321     fprintf(out, "case \"$p\" in\n");
1322
1323     pr_enums(out, npargs, pa, eshellBASH);
1324     pr_fopts(out, nfile, fnm, eshellBASH);
1325     fprintf(out, "esac }\ncomplete -F _%s_compl %s\n", ShortProgram(), ShortProgram());
1326 }
1327
1328 static void write_py(FILE *out, const char *program,
1329                      int nldesc, const char **desc,
1330                      int nfile, t_filenm *fnm,
1331                      int npargs, t_pargs *pa,
1332                      int nbug, const char **bugs,
1333                      t_linkdata *links)
1334 {
1335     const char *cls = program;
1336     char       *tmp;
1337     int         i, j;
1338
1339     /* Header stuff */
1340     fprintf(out, "#!/usr/bin/python\n\nfrom GmxDialog import *\n\n");
1341
1342     /* Class definition */
1343     fprintf(out, "class %s:\n", cls);
1344     fprintf(out, "    def __init__(self,tk):\n");
1345
1346     /* Help text */
1347     fprintf(out, "        %s_help = \"\"\"\n", cls);
1348     fprintf(out, "        DESCRIPTION\n");
1349     print_tty_formatted(out, nldesc, desc, 8, links, program, FALSE);
1350     if (nbug > 0)
1351     {
1352         fprintf(out, "\n        BUGS and PROBLEMS\n");
1353         for (i = 0; i < nbug; i++)
1354         {
1355             snew(tmp, strlen(bugs[i])+3);
1356             strcpy(tmp, "* ");
1357             strcpy(tmp+2, check_tty(bugs[i]));
1358             fprintf(out, "%s\n", wrap_lines(tmp, 78, 10, TRUE));
1359             sfree(tmp);
1360         }
1361     }
1362     fprintf(out, "        \"\"\"\n\n        # Command line options\n");
1363     /* File options */
1364     fprintf(out, "        flags = []\n");
1365     for (i = 0; (i < nfile); i++)
1366     {
1367         fprintf(out, "        flags.append(pca_file('%s',\"%s\",0,%d))\n",
1368                 ftp2ext_generic(fnm[i].ftp), fnm[i].opt ? fnm[i].opt : "k",
1369                 is_optional(&(fnm[i])));
1370     }
1371
1372
1373     /* Other options */
1374     for (i = 0; (i < npargs); i++)
1375     {
1376         switch (pa[i].type)
1377         {
1378             case etINT:
1379                 fprintf(out, "        flags.append(pca_int(\"%s\",\"%s\",%d,%d))\n",
1380                         pa[i].option, pa[i].desc, *pa[i].u.i, is_hidden(&(pa[i])));
1381                 break;
1382             case etREAL:
1383             case etTIME:
1384                 fprintf(out, "        flags.append(pca_float(\"%s\",\"%s\",%f,%d))\n",
1385                         pa[i].option, pa[i].desc, *pa[i].u.r, is_hidden(&(pa[i])));
1386                 break;
1387             case etSTR:
1388             case etBOOL:
1389                 fprintf(out, "        flags.append(pca_gmx_bool(\"%s\",\"%s\",%d,%d))\n",
1390                         pa[i].option, pa[i].desc, *pa[i].u.b, is_hidden(&(pa[i])));
1391                 break;
1392             case etRVEC:
1393                 fprintf(stderr, "Sorry, no rvecs yet...\n");
1394                 break;
1395             case etENUM:
1396                 fprintf(out, "        flags.append(pca_enum(\"%s\",\"%s\",\n",
1397                         pa[i].option, pa[i].desc);
1398                 fprintf(out, "        ['%s'", pa[i].u.c[1]);
1399                 for (j = 2; (pa[i].u.c[j] != NULL); j++)
1400                 {
1401                     fprintf(out, ",'%s'", pa[i].u.c[j]);
1402                 }
1403                 fprintf(out, "],%d))\n", is_hidden(&(pa[i])));
1404                 break;
1405             default:
1406                 break;
1407         }
1408     }
1409
1410     /* Make the dialog box */
1411     fprintf(out, "        gmxd = gmx_dialog(tk,\"%s\",flags,%s_help)\n\n",
1412             cls, cls);
1413
1414     /* Main loop */
1415     fprintf(out, "#####################################################\n");
1416     fprintf(out, "tk     = Tk()\n");
1417     fprintf(out, "my%s = %s(tk)\n", cls, cls);
1418     fprintf(out, "tk.mainloop()\n");
1419 }
1420
1421 void write_man(FILE *out, const char *mantp,
1422                const char *program,
1423                int nldesc, const char **desc,
1424                int nfile, t_filenm *fnm,
1425                int npargs, t_pargs *pa,
1426                int nbug, const char **bugs,
1427                gmx_bool bHidden)
1428 {
1429     const char *pr;
1430     int         i, npar;
1431     t_pargs    *par;
1432
1433     t_linkdata *links;
1434
1435     links = init_linkdata();
1436
1437     /* Don't write hidden options to completions, it just
1438      * makes the options more complicated for normal users
1439      */
1440
1441     if (bHidden)
1442     {
1443         npar = npargs;
1444         par  = pa;
1445     }
1446     else
1447     {
1448         snew(par, npargs);
1449         npar = 0;
1450         for (i = 0; i < npargs; i++)
1451         {
1452             if (!is_hidden(&pa[i]))
1453             {
1454                 par[npar] = pa[i];
1455                 npar++;
1456             }
1457         }
1458     }
1459
1460     if ((pr = strrchr(program, DIR_SEPARATOR)) == NULL)
1461     {
1462         pr = program;
1463     }
1464     else
1465     {
1466         pr += 1;
1467     }
1468     if (strcmp(mantp, "tex") == 0)
1469     {
1470         write_texman(out, pr, nldesc, desc, nfile, fnm, npar, par, nbug, bugs, links);
1471     }
1472     if (strcmp(mantp, "nroff") == 0)
1473     {
1474         write_nroffman(out, pr, nldesc, desc, nfile, fnm, npar, par, nbug, bugs, links);
1475     }
1476     if (strcmp(mantp, "ascii") == 0)
1477     {
1478         write_ttyman(out, pr, nldesc, desc, nfile, fnm, npar, par, nbug, bugs, TRUE, links);
1479     }
1480     if (strcmp(mantp, "wiki") == 0)
1481     {
1482         write_wikiman(out, pr, nldesc, desc, nfile, fnm, npar, par, nbug, bugs, TRUE, links);
1483     }
1484     if (strcmp(mantp, "help") == 0)
1485     {
1486         write_ttyman(out, pr, nldesc, desc, nfile, fnm, npar, par, nbug, bugs, FALSE, links);
1487     }
1488     if (strcmp(mantp, "html") == 0)
1489     {
1490         write_htmlman(out, pr, nldesc, desc, nfile, fnm, npar, par, nbug, bugs, links);
1491     }
1492     if (strcmp(mantp, "py") == 0)
1493     {
1494         write_py(out, pr, nldesc, desc, nfile, fnm, npar, par, nbug, bugs, links);
1495     }
1496     if (strcmp(mantp, "xml") == 0)
1497     {
1498         write_xmlman(out, pr, nldesc, desc, nfile, fnm, npargs, pa, nbug, bugs, links);
1499     }
1500     if (strcmp(mantp, "completion-zsh") == 0)
1501     {
1502         write_zshcompl(out, nfile, fnm, npar, par);
1503     }
1504     if (strcmp(mantp, "completion-bash") == 0)
1505     {
1506         write_bashcompl(out, nfile, fnm, npar, par);
1507     }
1508     if (strcmp(mantp, "completion-csh") == 0)
1509     {
1510         write_cshcompl(out, nfile, fnm, npar, par);
1511     }
1512
1513     if (!bHidden)
1514     {
1515         sfree(par);
1516     }
1517
1518     finish_linkdata(links);
1519 }
1520
1521 const char *get_arg_desc(int type)
1522 {
1523     static const char *argtp[etNR] = {
1524         "int", "step", "real", "time", "string", "bool", "vector", "enum"
1525     };
1526     return argtp[type];
1527 }