3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
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.
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.
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.
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.
30 * For more info, check our website at http://www.gromacs.org
33 * GROningen Mixture of Alchemy and Childrens' Stories
51 #include "gmx_fatal.h"
53 /* find an entry; return index, or -1 if not found */
54 static int search_einp(int ninp
, const t_inpfile
*inp
, const char *name
);
57 t_inpfile
*read_inpfile(const char *fn
,int *ninp
,
62 char buf
[STRLEN
],lbuf
[STRLEN
],rbuf
[STRLEN
],warn_buf
[STRLEN
];
66 /* setting cppopts from command-line options would be cooler */
67 gmx_bool allow_override
=FALSE
;
71 fprintf(debug
,"Reading MDP file %s\n",fn
);
77 ptr
= fgets2(buf
,STRLEN
-1,in
);
79 set_warning_line(wi
,fn
,lc
);
82 if ((cptr
=strchr(buf
,COMMENTSIGN
)) != NULL
)
87 for(j
=0; (buf
[j
] != '=') && (buf
[j
] != '\0'); j
++)
92 fprintf(debug
,"No = on line %d in file %s, ignored\n",lc
,fn
);
100 if (lbuf
[0] == '\0') {
102 fprintf(debug
,"Empty left hand side on line %d in file %s, ignored\n",lc
,fn
);
105 for(i
=j
+1,k
=0; (buf
[i
] != '\0'); i
++,k
++)
109 if (rbuf
[0] == '\0') {
111 fprintf(debug
,"Empty right hand side on line %d in file %s, ignored\n",lc
,fn
);
114 /* Now finally something sensible */
117 /* first check whether we hit the 'multiple_entries' option */
118 if (gmx_strcasecmp_min(eMultentOpt_names
[eMultentOptName
], lbuf
)==0)
120 /* we now check whether to allow overrides from here or not */
121 if (gmx_strcasecmp_min(eMultentOpt_names
[eMultentOptNo
], rbuf
)==0)
123 allow_override
=FALSE
;
125 else if (gmx_strcasecmp_min(eMultentOpt_names
[eMultentOptLast
], rbuf
)==0)
132 "Parameter \"%s\" should either be %s or %s\n",
134 eMultentOpt_names
[eMultentOptNo
],
135 eMultentOpt_names
[eMultentOptLast
]);
136 warning_error(wi
,warn_buf
);
141 /* it is a regular option; check for duplicates */
142 found_index
=search_einp(nin
, inp
, lbuf
);
144 if (found_index
== -1)
148 inp
[nin
-1].inp_count
= 1;
149 inp
[nin
-1].count
= 0;
150 inp
[nin
-1].bObsolete
= FALSE
;
151 inp
[nin
-1].bSet
= FALSE
;
152 inp
[nin
-1].name
= strdup(lbuf
);
153 inp
[nin
-1].value
= strdup(rbuf
);
160 "Parameter \"%s\" doubly defined (and multiple assignments not allowed)\n",
162 warning_error(wi
,warn_buf
);
167 sfree(inp
[found_index
].value
);
168 inp
[found_index
].value
= strdup(rbuf
);
170 "Overriding existing parameter \"%s\" with value \"%s\"\n",
172 warning_note(wi
,warn_buf
);
185 fprintf(debug
,"Done reading MDP file, there were %d entries in there\n",
197 static int inp_comp(const void *a
,const void *b
)
199 return ((t_inpfile
*)a
)->count
- ((t_inpfile
*)b
)->count
;
202 static void sort_inp(int ninp
,t_inpfile inp
[])
207 for(i
=0; (i
<ninp
); i
++)
208 mm
=max(mm
,inp
[i
].count
);
209 for(i
=0; (i
<ninp
); i
++) {
210 if (inp
[i
].count
== 0)
213 qsort(inp
,ninp
,(size_t)sizeof(inp
[0]),inp_comp
);
216 void write_inpfile(const char *fn
,int ninp
,t_inpfile inp
[],gmx_bool bHaltOnUnknown
,
221 char warn_buf
[STRLEN
];
224 out
=gmx_fio_fopen(fn
,"w");
226 for(i
=0; (i
<ninp
); i
++) {
228 if(inp
[i
].name
[0]==';' || (strlen(inp
[i
].name
)>2 && inp
[i
].name
[1]==';'))
229 fprintf(out
,"%-24s\n",inp
[i
].name
);
231 fprintf(out
,"%-24s = %s\n",inp
[i
].name
,inp
[i
].value
? inp
[i
].value
: "");
232 } else if (!inp
[i
].bObsolete
) {
233 sprintf(warn_buf
,"Unknown left-hand '%s' in parameter file\n",
235 if (bHaltOnUnknown
) {
236 warning_error(wi
,warn_buf
);
238 warning(wi
,warn_buf
);
244 check_warning_error(wi
,FARGS
);
247 void replace_inp_entry(int ninp
,t_inpfile
*inp
,const char *old_entry
,const char *new_entry
)
251 for(i
=0; (i
<ninp
); i
++) {
252 if (gmx_strcasecmp_min(old_entry
,inp
[i
].name
) == 0) {
254 fprintf(stderr
,"Replacing old mdp entry '%s' by '%s'\n",
255 inp
[i
].name
,new_entry
);
257 inp
[i
].name
= strdup(new_entry
);
259 fprintf(stderr
,"Ignoring obsolete mdp entry '%s'\n",
261 inp
[i
].bObsolete
= TRUE
;
267 static int search_einp(int ninp
, const t_inpfile
*inp
, const char *name
)
273 for(i
=0; i
<ninp
; i
++)
274 if (gmx_strcasecmp_min(name
,inp
[i
].name
) == 0)
279 static int get_einp(int *ninp
,t_inpfile
**inp
,const char *name
)
283 char warn_buf
[STRLEN
];
287 for(i=0; (i<(*ninp)); i++)
288 if (gmx_strcasecmp_min(name,(*inp)[i].name) == 0)
290 if (i == (*ninp)) {*/
291 i
=search_einp(*ninp
, *inp
, name
);
296 srenew(*inp
,(*ninp
));
297 (*inp
)[i
].name
=strdup(name
);
300 (*inp
)[i
].count
= (*inp
)[0].inp_count
++;
301 (*inp
)[i
].bSet
= TRUE
;
303 fprintf(debug
,"Inp %d = %s\n",(*inp
)[i
].count
,(*inp
)[i
].name
);
305 /*if (i == (*ninp)-1)*/
312 int get_eint(int *ninp
,t_inpfile
**inp
,const char *name
,int def
,
315 char buf
[32],*ptr
,warn_buf
[STRLEN
];
319 ii
=get_einp(ninp
,inp
,name
);
322 sprintf(buf
,"%d",def
);
323 (*inp
)[(*ninp
)-1].value
=strdup(buf
);
328 ret
= strtol((*inp
)[ii
].value
,&ptr
,10);
329 if (ptr
== (*inp
)[ii
].value
) {
330 sprintf(warn_buf
,"Right hand side '%s' for parameter '%s' in parameter file is not an integer value\n",(*inp
)[ii
].value
,(*inp
)[ii
].name
);
331 warning_error(wi
,warn_buf
);
338 gmx_large_int_t
get_egmx_large_int(int *ninp
,t_inpfile
**inp
,
339 const char *name
,gmx_large_int_t def
,
342 char buf
[32],*ptr
,warn_buf
[STRLEN
];
346 ii
=get_einp(ninp
,inp
,name
);
349 sprintf(buf
,gmx_large_int_pfmt
,def
);
350 (*inp
)[(*ninp
)-1].value
=strdup(buf
);
355 ret
= str_to_large_int_t((*inp
)[ii
].value
,&ptr
);
356 if (ptr
== (*inp
)[ii
].value
) {
357 sprintf(warn_buf
,"Right hand side '%s' for parameter '%s' in parameter file is not an integer value\n",(*inp
)[ii
].value
,(*inp
)[ii
].name
);
358 warning_error(wi
,warn_buf
);
365 double get_ereal(int *ninp
,t_inpfile
**inp
,const char *name
,double def
,
368 char buf
[32],*ptr
,warn_buf
[STRLEN
];
372 ii
=get_einp(ninp
,inp
,name
);
375 sprintf(buf
,"%g",def
);
376 (*inp
)[(*ninp
)-1].value
=strdup(buf
);
381 ret
= strtod((*inp
)[ii
].value
,&ptr
);
382 if (ptr
== (*inp
)[ii
].value
) {
383 sprintf(warn_buf
,"Right hand side '%s' for parameter '%s' in parameter file is not a real value\n",(*inp
)[ii
].value
,(*inp
)[ii
].name
);
384 warning_error(wi
,warn_buf
);
391 const char *get_estr(int *ninp
,t_inpfile
**inp
,const char *name
,const char *def
)
396 ii
=get_einp(ninp
,inp
,name
);
400 sprintf(buf
,"%s",def
);
401 (*inp
)[(*ninp
)-1].value
=strdup(buf
);
404 (*inp
)[(*ninp
)-1].value
=NULL
;
409 return (*inp
)[ii
].value
;
412 int get_eeenum(int *ninp
,t_inpfile
**inp
,const char *name
,const char **defs
,
419 ii
=get_einp(ninp
,inp
,name
);
422 (*inp
)[(*ninp
)-1].value
=strdup(defs
[0]);
427 for(i
=0; (defs
[i
] != NULL
); i
++)
428 if (gmx_strcasecmp_min(defs
[i
],(*inp
)[ii
].value
) == 0)
431 if (defs
[i
] == NULL
) {
432 n
+= sprintf(buf
,"Invalid enum '%s' for variable %s, using '%s'\n",
433 (*inp
)[ii
].value
,name
,defs
[0]);
434 n
+= sprintf(buf
+n
,"Next time use one of:");
437 n
+= sprintf(buf
+n
," '%s'",defs
[j
]);
441 warning_error(wi
,buf
);
443 fprintf(stderr
,"%s\n",buf
);
446 (*inp
)[ii
].value
= strdup(defs
[0]);
454 int get_eenum(int *ninp
,t_inpfile
**inp
,const char *name
,const char **defs
)
458 return get_eeenum(ninp
,inp
,name
,defs
,NULL
);