2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2004, The GROMACS development team,
6 * check out http://www.gromacs.org for more information.
7 * Copyright (c) 2012, by the GROMACS development team, led by
8 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
9 * others, as listed in the AUTHORS file in the top-level source
10 * directory and at http://www.gromacs.org.
12 * GROMACS is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
17 * GROMACS is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with GROMACS; if not, see
24 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 * If you want to redistribute modifications to GROMACS, please
28 * consider that scientific software is very special. Version
29 * control is crucial - bugs must be traceable. We will be happy to
30 * consider code for inclusion in the official distribution, but
31 * derived work must not be called official GROMACS. Details are found
32 * in the README & COPYING files - if they are missing, get the
33 * official version at http://www.gromacs.org.
35 * To help us fund GROMACS development, we humbly ask that you cite
36 * the research papers on the package. Check out http://www.gromacs.org.
38 /* This file is completely threadsafe - keep it that way! */
47 #include "gmx_fatal.h"
55 /* The source code in this file should be thread-safe.
56 Please keep it that way. */
58 gmx_bool is_hidden(t_pargs *pa)
60 return ((strstr(pa->desc,"HIDDEN") != NULL) ||
61 (strstr(pa->desc,"[hidden]") != NULL));
64 void get_pargs(int *argc,char *argv[],int nparg,t_pargs pa[],gmx_bool bKeepArgs)
75 for(i=1; (i<*argc); i++) {
77 for(j=0; (j<nparg); j++) {
78 if (pa[j].type == etBOOL) {
79 sprintf(buf,"-no%s",pa[j].option+1);
80 if (strcmp(pa[j].option,argv[i])== 0) {
85 else if (strcmp(buf,argv[i])== 0) {
91 else if (strcmp(pa[j].option,argv[i])== 0) {
93 fprintf(stderr,"Setting option %s more than once!\n",
99 *pa[j].u.i = iscan(*argc,argv,&i);
101 case etGMX_LARGE_INT:
102 *pa[j].u.is = istepscan(*argc,argv,&i);
106 *pa[j].u.r = dscan(*argc,argv,&i);
109 *(pa[j].u.c) = sscan(*argc,argv,&i);
113 ptr = sscan(*argc,argv,&i);
114 for(k=1; (pa[j].u.c[k] != NULL); k++)
115 /* only check ptr against beginning of
117 if (gmx_strncasecmp(ptr,pa[j].u.c[k],strlen(ptr)) == 0)
118 if ( ( match == NOTSET ) ||
119 ( strlen(pa[j].u.c[k]) <
120 strlen(pa[j].u.c[match]) ) )
123 pa[j].u.c[0] = pa[j].u.c[match];
125 gmx_fatal(FARGS,"Invalid argument %s for option %s",
129 (*pa[j].u.rv)[0] = dscan(*argc,argv,&i);
130 if ( (i+1 == *argc) ||
131 ( (argv[i+1][0]=='-') &&
132 !isdigit(argv[i+1][1]) ) )
138 (*pa[j].u.rv)[1] = dscan(*argc,argv,&i);
139 if ( (i+1 == *argc) ||
140 ( (argv[i+1][0]=='-') &&
141 !isdigit(argv[i+1][1]) ) )
143 "%s: vector must have 1 or 3 real parameters",
146 (*pa[j].u.rv)[2] = dscan(*argc,argv,&i);
150 gmx_fatal(FARGS,"Invalid type %d in pargs",pa[j].type);
152 /* i may be incremented, so set it to not keep */
158 /* Remove used entries */
159 for(i=j=0; (i<=*argc); i++) {
168 int opt2parg_int(const char *option,int nparg,t_pargs pa[])
172 for(i=0; (i<nparg); i++)
173 if (strcmp(pa[i].option,option) == 0)
176 gmx_fatal(FARGS,"No integer option %s in pargs",option);
181 gmx_bool opt2parg_gmx_bool(const char *option,int nparg,t_pargs pa[])
185 for(i=0; (i<nparg); i++)
186 if (strcmp(pa[i].option,option) == 0)
189 gmx_fatal(FARGS,"No gmx_boolean option %s in pargs",option);
194 real opt2parg_real(const char *option,int nparg,t_pargs pa[])
198 for(i=0; (i<nparg); i++)
199 if (strcmp(pa[i].option,option) == 0)
202 gmx_fatal(FARGS,"No real option %s in pargs",option);
207 const char *opt2parg_str(const char *option,int nparg,t_pargs pa[])
211 for(i=0; (i<nparg); i++)
212 if (strcmp(pa[i].option,option) == 0)
215 gmx_fatal(FARGS,"No string option %s in pargs",option);
220 gmx_bool opt2parg_bSet(const char *option,int nparg,t_pargs pa[])
224 for(i=0; (i<nparg); i++)
225 if (strcmp(pa[i].option,option) == 0)
228 gmx_fatal(FARGS,"No such option %s in pargs",option);
230 return FALSE; /* Too make some compilers happy */
233 const char *opt2parg_enum(const char *option,int nparg,t_pargs pa[])
237 for(i=0; (i<nparg); i++)
238 if (strcmp(pa[i].option,option) == 0)
241 gmx_fatal(FARGS,"No such option %s in pargs",option);
246 char *pa_val(t_pargs *pa, char buf[], int sz)
249 char buf_str[1256]; buf_str[0]='\0';
254 gmx_fatal(FARGS,"Buffer must be at least 255 chars\n");
258 sprintf(buf,"%-d",*(pa->u.i));
260 case etGMX_LARGE_INT:
261 sprintf(buf,gmx_large_int_pfmt,*(pa->u.is));
266 sprintf(buf_str,"%-6g",r);
267 strcpy(buf, buf_str);
270 sprintf(buf,"%-6s",*(pa->u.b) ? "yes" : "no");
274 if (strlen(*(pa->u.c)) >= (size_t)sz)
275 gmx_fatal(FARGS,"Argument too long: \"%d\"\n",*(pa->u.c));
277 strcpy(buf,*(pa->u.c));
281 strcpy(buf,*(pa->u.c));
284 sprintf(buf,"%g %g %g",(*pa->u.rv)[0],
295 char *pargs_print_line(t_pargs *pa,gmx_bool bLeadingSpace)
297 char buf[LONGSTR],*buf2,*tmp,*desc;
299 snew(buf2,LONGSTR+strlen(pa->desc));
300 snew(tmp,LONGSTR+strlen(pa->desc));
302 if (pa->type == etBOOL)
303 sprintf(buf,"-[no]%s",pa->option+1);
305 strcpy(buf,pa->option);
306 desc = check_tty(pa->desc);
307 if (strlen(buf)>((OPTLEN+TYPELEN)-max(strlen(argtp[pa->type]),4))) {
308 sprintf(buf2,"%s%s %-6s %-6s %-s\n",
309 bLeadingSpace ? " " : "",buf,
310 argtp[pa->type],pa_val(pa,tmp,LONGSTR-1),desc);
311 } else if (strlen(buf)>OPTLEN) {
312 /* so type can be 3 or 4 char's, this fits in the %4s */
313 sprintf(buf2,"%s%-14s %-4s %-6s %-s\n",
314 bLeadingSpace ? " " : "",buf,argtp[pa->type],
315 pa_val(pa,tmp,LONGSTR-1),desc);
317 sprintf(buf2,"%s%-12s %-6s %-6s %-s\n",
318 bLeadingSpace ? " " : "",buf,argtp[pa->type],
319 pa_val(pa,tmp,LONGSTR-1),desc);
323 tmp = wrap_lines(buf2,78,28,FALSE);
330 void print_pargs(FILE *fp, int npargs,t_pargs pa[],gmx_bool bLeadingSpace)
332 gmx_bool bShowHidden;
333 char buf[32],buf2[256],tmp[256];
337 /* Cannot call opt2parg_bSet here, because it crashes when the option
338 * is not in the list (mdrun)
341 for(i=0; (i<npargs); i++)
342 if ((strcmp(pa[i].option,"-hidden")==0) && (pa[i].bSet))
346 fprintf(fp,"%s%-12s %-6s %-6s %-s\n",
347 bLeadingSpace ? " " : "","Option","Type","Value","Description");
348 fprintf(fp,"%s------------------------------------------------------\n",
349 bLeadingSpace ? " " : "");
350 for(i=0; (i<npargs); i++) {
351 if (bShowHidden || !is_hidden(&pa[i])) {
352 wdesc = pargs_print_line(&pa[i],bLeadingSpace);
353 fprintf(fp,"%s",wdesc);
361 void pr_enums(FILE *fp, int npargs,t_pargs pa[], int shell)
367 for (i=0; i<npargs; i++)
368 if (pa[i].type==etENUM) {
369 fprintf(fp," \"n/%s/(",pa[i].option);
370 for(j=1; pa[i].u.c[j]; j++)
371 fprintf(fp," %s",pa[i].u.c[j]);
376 for (i=0; i<npargs; i++)
377 if (pa[i].type==etENUM) {
378 fprintf(fp,"%s) COMPREPLY=( $(compgen -W '",pa[i].option);
379 for(j=1; pa[i].u.c[j]; j++)
380 fprintf(fp," %s",pa[i].u.c[j]);
381 fprintf(fp," ' -- $c ));;\n");
385 for (i=0; i<npargs; i++)
386 if (pa[i].type==etENUM) {
387 fprintf(fp,"- 'c[-1,%s]' -s \"", pa[i].option);
388 for(j=1; pa[i].u.c[j]; j++)
389 fprintf(fp," %s",pa[i].u.c[j]);