4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
11 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
12 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
13 * Copyright (c) 2001-2004, The GROMACS development team,
14 * check out http://www.gromacs.org for more information.
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * If you want to redistribute modifications, please consider that
22 * scientific software is very special. Version control is crucial -
23 * bugs must be traceable. We will be happy to consider code for
24 * inclusion in the official distribution, but derived work must not
25 * be called official GROMACS. Details are found in the README & COPYING
26 * files - if they are missing, get the official version at www.gromacs.org.
28 * To help us fund GROMACS development, we humbly ask that you cite
29 * the papers on the package - you can find them in the top README file.
31 * For more info, check our website at http://www.gromacs.org
34 * GROningen Mixture of Alchemy and Childrens' Stories
52 /* XDR should be available on all platforms now,
53 * but we keep the possibility of turning it off...
58 #define IS_SET(fn) ((fn.flag & ffSET) != 0)
59 #define IS_OPT(fn) ((fn.flag & ffOPT) != 0)
60 #define IS_MULT(fn) ((fn.flag & ffMULT) != 0)
61 #define UN_SET(fn) (fn.flag = (fn.flag & ~ffSET))
62 #define DO_SET(fn) (fn.flag = (fn.flag | ffSET))
64 enum { eftASC
, eftBIN
, eftXDR
, eftGEN
, eftNR
};
66 /* To support multiple file types with one general (eg TRX) we have
69 static const int trxs
[]={
73 efTRJ
, efGRO
, efG96
, efPDB
, efG87
};
74 #define NTRXS asize(trxs)
76 static const int trns
[]={
81 #define NTRNS asize(trns)
83 static const int stos
[]={ efGRO
, efG96
, efPDB
, efBRK
,
88 #define NSTOS asize(stos)
90 static const int stxs
[]={ efGRO
, efG96
, efPDB
, efBRK
, efENT
,
99 #define NSTXS asize(stxs)
101 static const int enxs
[]={
106 #define NENXS asize(enxs)
108 static const int tpxs
[]={
117 #define NTPXS asize(tpxs)
119 static const int tpss
[]={
127 efGRO
, efG96
, efPDB
, efBRK
, efENT
};
128 #define NTPSS asize(tpss)
141 /* this array should correspond to the enum in include/types/filenm.h */
142 static t_deffile deffile
[efNR
] = {
143 { eftASC
, ".mdp", "grompp", "-f", "grompp input file with MD parameters" },
144 { eftASC
, ".gct", "gct", "-f", "General coupling stuff" },
145 { eftGEN
, ".???", "traj", "-f", "Generic trajectory: xtc trr trj gro g96 pdb", NTRXS
, trxs
},
146 { eftGEN
, ".???", "traj", NULL
, "Full precision trajectory: trr trj", NTRNS
, trns
},
147 { eftXDR
, ".trr", "traj", NULL
, "Trajectory in portable xdr format" },
148 { eftBIN
, ".trj", "traj", NULL
, "Trajectory file (architecture specific)" },
149 { eftXDR
, ".xtc", "traj", NULL
, "Compressed trajectory (portable xdr format)"},
150 { eftASC
, ".g87", "gtraj", NULL
, "Gromos-87 ASCII trajectory format" },
151 { eftGEN
, ".???", "ener", NULL
, "Generic energy: edr ene", NENXS
, enxs
},
152 { eftXDR
, ".edr", "ener", NULL
, "Energy file in portable xdr format" },
153 { eftBIN
, ".ene", "ener", NULL
, "Energy file" },
154 { eftGEN
, ".???", "conf", "-c", "Generic structure: gro g96 pdb tpr tpb tpa xml", NSTXS
, stxs
},
155 { eftGEN
, ".???", "out", "-o", "Generic structure: gro g96 pdb xml", NSTOS
, stos
},
156 { eftASC
, ".gro", "conf", "-c", "Coordinate file in Gromos-87 format" },
157 { eftASC
, ".g96", "conf", "-c", "Coordinate file in Gromos-96 format" },
158 { eftASC
, ".pdb", "eiwit", "-f", "Protein data bank file" },
159 { eftASC
, ".brk", "eiwit", "-f", "Brookhaven data bank file" },
160 { eftASC
, ".ent", "eiwit", "-f", "Entry in the protein date bank" },
161 { eftASC
, ".log", "run", "-l", "Log file" },
162 { eftASC
, ".xvg", "graph", "-o", "xvgr/xmgr file" },
163 { eftASC
, ".out", "hello", "-o", "Generic output file" },
164 { eftASC
, ".ndx", "index", "-n", "Index file", },
165 { eftASC
, ".top", "topol", "-p", "Topology file" },
166 { eftASC
, ".itp", "topinc", NULL
, "Include file for topology" },
167 { eftGEN
, ".???", "topol", "-s", "Generic run input: tpr tpb tpa xml", NTPXS
, tpxs
},
168 { eftGEN
, ".???", "topol", "-s", "Structure+mass(db): tpr tpb tpa gro g96 pdb xml", NTPSS
, tpss
},
169 { eftXDR
, ".tpr", "topol", "-s", "Portable xdr run input file" },
170 { eftASC
, ".tpa", "topol", "-s", "Ascii run input file" },
171 { eftBIN
, ".tpb", "topol", "-s", "Binary run input file" },
173 { eftASC
, ".xml", "gmx", "-x", "Portable status file" },
175 { eftASC
, ".tex", "doc", "-o", "LaTeX file" },
176 { eftASC
, ".rtp", "residue",NULL
, "Residue Type file used by pdb2gmx" },
177 { eftASC
, ".atp", "atomtp", NULL
, "Atomtype file used by pdb2gmx" },
178 { eftASC
, ".hdb", "polar", NULL
, "Hydrogen data base" },
179 { eftASC
, ".dat", "nnnice", NULL
, "Generic data file" },
180 { eftASC
, ".dlg", "user", NULL
, "Dialog Box data for ngmx" },
181 { eftASC
, ".map", "ss", NULL
, "File that maps matrix data to colors" },
182 { eftASC
, ".eps", "plot", NULL
, "Encapsulated PostScript (tm) file" },
183 { eftASC
, ".mat", "ss", NULL
, "Matrix Data file" },
184 { eftASC
, ".m2p", "ps", NULL
, "Input file for mat2ps" },
185 { eftBIN
, ".mtx", "hessian","-m", "Hessian matrix" },
186 { eftASC
, ".edi", "sam", NULL
, "ED sampling input" },
187 { eftASC
, ".edo", "sam", NULL
, "ED sampling output" },
188 { eftASC
, ".ppa", "pull", NULL
, "Pull parameters" },
189 { eftASC
, ".pdo", "pull", NULL
, "Pull data output" },
190 { eftASC
, ".hat", "gk", NULL
, "Fourier transform of spread function" },
191 { eftASC
, ".xpm", "root", NULL
, "X PixMap compatible matrix file" }
194 static char *default_file_name
=NULL
;
197 const char *z_ext
[NZEXT
] = { ".gz", ".Z" };
199 void set_default_file_name(const char *name
)
203 default_file_name
= strdup(name
);
205 for(i
=0; i
<efNR
; i
++)
206 deffile
[i
].defnm
= default_file_name
;
209 const char *ftp2ext(int ftp
)
211 if ((0 <= ftp
) && (ftp
< efNR
))
212 return deffile
[ftp
].ext
+1;
217 const char *ftp2ext_generic(int ftp
)
219 if ((0 <= ftp
) && (ftp
< efNR
)) {
243 const char *ftp2desc(int ftp
)
245 if ((0 <= ftp
) && (ftp
< efNR
))
246 return deffile
[ftp
].descr
;
248 return "unknown filetype";
251 const char *ftp2ftype(int ftp
)
253 if ((ftp
>= 0) && (ftp
< efNR
)) {
254 switch (deffile
[ftp
].ftype
) {
255 case eftASC
: return "ASCII";
256 case eftBIN
: return "Binary";
257 case eftXDR
: return "XDR portable";
258 case eftGEN
: return "";
259 default: fatal_error(0,"DEATH HORROR: Unknown filetype in ftp2ftype (%d)",
267 const char *ftp2defnm(int ftp
)
269 static char buf
[256];
271 if ((0 <= ftp
) && (ftp
< efNR
)) {
272 sprintf(buf
,"%s",deffile
[ftp
].defnm
);
279 void pr_def(FILE *fp
,int ftp
)
283 const char *ext
,*desc
;
286 /* find default file extension and \tt-ify description */
289 ext
= deffile
[df
->tps
[0]].ext
;
290 desc
= strdup(df
->descr
);
291 s
= strstr(desc
,": ")+1;
295 snew(flst
,strlen(s
)+6);
296 strcpy(flst
, " \\tt ");
308 /* set file contents type */
310 case eftASC
: s
="Asc";
312 case eftBIN
: s
="Bin";
314 case eftXDR
: s
="xdr";
319 fatal_error(0,"Unimplemented filetype %d %d",ftp
,df
->ftype
);
321 fprintf(fp
,"\\tt %8s & \\tt %3s & %3s & \\tt %2s & %s%s \\\\[-0.1ex]\n",
322 df
->defnm
, ext
, s
, df
->defopt
? df
->defopt
: "",
323 check_tex(desc
),check_tex(flst
));
326 void pr_fns(FILE *fp
,int nf
,t_filenm tfn
[])
329 char buf
[256],*wbuf
,opt_buf
[32];
332 fprintf(fp
,"%6s %12s %-12s %s\n",
333 "Option","Filename","Type","Description");
334 fprintf(fp
,"------------------------------------------------------------\n");
335 for(i
=0; (i
<nf
); i
++) {
336 for(f
=0; (f
<tfn
[i
].nfiles
); f
++) {
337 sprintf(buf
, "%4s %14s %-12s ",
338 (f
==0) ? tfn
[i
].opt
: "",tfn
[i
].fns
[f
],
339 (f
==0) ? fileopt(tfn
[i
].flag
,opt_buf
,32) : "");
340 if ( f
< tfn
[i
].nfiles
-1 )
341 fprintf(fp
, "%s\n", buf
);
343 if (tfn
[i
].nfiles
> 0) {
344 strcat(buf
, deffile
[tfn
[i
].ftp
].descr
);
345 if ( (strlen(tfn
[i
].opt
)>OPTLEN
) &&
346 (strlen(tfn
[i
].opt
)<=
347 ((OPTLEN
+NAMELEN
)-strlen(tfn
[i
].fns
[tfn
[i
].nfiles
-1]))) ) {
348 for(j
=strlen(tfn
[i
].opt
);
349 j
<strlen(buf
)-(strlen(tfn
[i
].opt
)-OPTLEN
)+1; j
++)
350 buf
[j
]=buf
[j
+strlen(tfn
[i
].opt
)-OPTLEN
];
352 wbuf
=wrap_lines(buf
,78,35,FALSE
);
353 fprintf(fp
,"%s\n",wbuf
);
361 void pr_fopts(FILE *fp
,int nf
,t_filenm tfn
[], int shell
)
367 for(i
=0; (i
<nf
); i
++) {
368 fprintf(fp
," \"n/%s/f:*.",tfn
[i
].opt
);
369 if (deffile
[tfn
[i
].ftp
].ntps
) {
371 for(j
=0; j
<deffile
[tfn
[i
].ftp
].ntps
; j
++) {
374 fprintf(fp
,"%s",deffile
[deffile
[tfn
[i
].ftp
].tps
[j
]].ext
+1);
378 fprintf(fp
,"%s",deffile
[tfn
[i
].ftp
].ext
+1);
380 for(j
=0; j
<NZEXT
; j
++)
381 fprintf(fp
,",%s",z_ext
[j
]);
386 for(i
=0; (i
<nf
); i
++) {
387 fprintf(fp
,"%s) COMPREPLY=( $(compgen -X '!*.",tfn
[i
].opt
);
388 if (deffile
[tfn
[i
].ftp
].ntps
) {
390 for(j
=0; j
<deffile
[tfn
[i
].ftp
].ntps
; j
++) {
393 fprintf(fp
,"%s",deffile
[deffile
[tfn
[i
].ftp
].tps
[j
]].ext
+1);
397 fprintf(fp
,"%s",deffile
[tfn
[i
].ftp
].ext
+1);
399 for(j
=0; j
<NZEXT
; j
++) {
402 fprintf(fp
,"%s",z_ext
[j
]);
404 fprintf(fp
,")' -f $c ; compgen -S '/' -X '.*' -d $c ));;\n");
408 for(i
=0; (i
<nf
); i
++) {
409 fprintf(fp
,"- 'c[-1,%s]' -g '*.",tfn
[i
].opt
);
410 if (deffile
[tfn
[i
].ftp
].ntps
) {
412 for(j
=0; j
<deffile
[tfn
[i
].ftp
].ntps
; j
++) {
415 fprintf(fp
,"%s",deffile
[deffile
[tfn
[i
].ftp
].tps
[j
]].ext
+1);
419 fprintf(fp
,"%s",deffile
[tfn
[i
].ftp
].ext
+1);
421 for(j
=0; j
<NZEXT
; j
++)
422 fprintf(fp
,"|%s",z_ext
[j
]);
423 fprintf(fp
,") *(/)' ");
429 static void check_opts(int nf
,t_filenm fnm
[])
434 for(i
=0; (i
<nf
); i
++) {
435 df
=&(deffile
[fnm
[i
].ftp
]);
436 if (fnm
[i
].opt
== NULL
) {
437 if (df
->defopt
== NULL
)
438 fatal_error(0,"No default cmd-line option for %s (type %d)\n",
439 deffile
[fnm
[i
].ftp
].ext
,fnm
[i
].ftp
);
441 fnm
[i
].opt
=df
->defopt
;
455 if ((len
>= 4) && (fn
[len
-4] == '.'))
460 for(i
=0; (i
<efNR
); i
++)
461 if ((eptr
=deffile
[i
].ext
) != NULL
)
462 if (strcasecmp(feptr
,eptr
)==0)
468 static void set_extension(char *buf
,int ftp
)
473 /* check if extension is already at end of filename */
476 extlen
= strlen(df
->ext
);
477 if ((len
<= extlen
) || (strcasecmp(&(buf
[len
-extlen
]),df
->ext
) != 0))
481 static void add_filenm(t_filenm
*fnm
, char *filenm
)
483 srenew(fnm
->fns
, fnm
->nfiles
+1);
484 fnm
->fns
[fnm
->nfiles
] = strdup(filenm
);
488 static void set_grpfnm(t_filenm
*fnm
,char *name
,bool bCanNotOverride
)
490 char buf
[256],buf2
[256];
496 nopts
= deffile
[fnm
->ftp
].ntps
;
497 ftps
= deffile
[fnm
->ftp
].tps
;
498 if ((nopts
== 0) || (ftps
== NULL
))
499 fatal_error(0,"DEATH HORROR ERROR in %s:%d",__FILE__
,__LINE__
);
502 if (name
&& (bCanNotOverride
|| (default_file_name
== NULL
))) {
504 /* First check whether we have a valid filename already */
506 for(i
=0; (i
<nopts
) && !bValidExt
; i
++)
510 /* No name given, set the default name */
511 strcpy(buf
,ftp2defnm(fnm
->ftp
));
513 if (!bValidExt
&& (fnm
->flag
& ffREAD
)) {
514 /* for input-files only: search for filenames in the directory */
515 for(i
=0; (i
<nopts
) && !bValidExt
; i
++) {
518 set_extension(buf2
,type
);
527 /* Use the first extension type */
528 set_extension(buf
,ftps
[0]);
530 add_filenm(fnm
, buf
);
533 static void set_filenm(t_filenm
*fnm
,char *name
,bool bCanNotOverride
)
535 /* Set the default filename, extension and option for those fields that
536 * are not already set. An extension is added if not present, if fn = NULL
537 * or empty, the default filename is given.
542 if ((fnm
->ftp
< 0) || (fnm
->ftp
>= efNR
))
543 fatal_error(0,"file type out of range (%d)",fnm
->ftp
);
545 if ((fnm
->flag
& ffREAD
) && name
&& fexist(name
)) {
546 /* check if filename ends in .gz or .Z, if so remove that: */
548 for (i
=0; i
<NZEXT
; i
++) {
549 extlen
= strlen(z_ext
[i
]);
551 if (strcasecmp(name
+len
-extlen
,z_ext
[i
]) == 0) {
552 name
[len
-extlen
]='\0';
558 if (deffile
[fnm
->ftp
].ntps
)
559 set_grpfnm(fnm
,name
,bCanNotOverride
);
561 if ((name
!= NULL
) && (bCanNotOverride
|| (default_file_name
== NULL
)))
564 strcpy(buf
,deffile
[fnm
->ftp
].defnm
);
565 set_extension(buf
,fnm
->ftp
);
567 add_filenm(fnm
, buf
);
571 static void set_filenms(int nf
,t_filenm fnm
[])
575 for(i
=0; (i
<nf
); i
++)
577 set_filenm(&(fnm
[i
]),fnm
[i
].fn
,FALSE
);
580 void parse_file_args(int *argc
,char *argv
[],int nf
,t_filenm fnm
[],
588 for(i
=0; (i
<nf
); i
++)
592 snew(bRemove
,(*argc
)+1);
595 for(j
=0; (j
<nf
); j
++) {
596 if (strcmp(argv
[i
],fnm
[j
].opt
) == 0) {
600 /* check if we are out of arguments for this option */
601 if ( (i
>= *argc
) || (argv
[i
][0] == '-') )
602 set_filenm(&fnm
[j
],fnm
[j
].fn
,FALSE
);
603 /* sweep up all file arguments for this option */
604 while ((i
< *argc
) && (argv
[i
][0] != '-')) {
605 set_filenm(&fnm
[j
],argv
[i
],TRUE
);
608 /* only repeat for 'multiple' file options: */
609 if ( ! IS_MULT(fnm
[j
]) )
613 break; /* jump out of 'j' loop */
616 /* No file found corresponding to option argv[i] */
622 /* Remove used entries */
623 for(i
=j
=0; (i
<=*argc
); i
++) {
635 char *opt2fn(char *opt
,int nfile
,t_filenm fnm
[])
639 for(i
=0; (i
<nfile
); i
++)
640 if (strcmp(opt
,fnm
[i
].opt
)==0) {
641 return fnm
[i
].fns
[0];
644 fprintf(stderr
,"No option %s\n",opt
);
649 int opt2fns(char **fns
[], char *opt
,int nfile
,t_filenm fnm
[])
653 for(i
=0; (i
<nfile
); i
++)
654 if (strcmp(opt
,fnm
[i
].opt
)==0) {
656 return fnm
[i
].nfiles
;
659 fprintf(stderr
,"No option %s\n",opt
);
663 char *ftp2fn(int ftp
,int nfile
,t_filenm fnm
[])
667 for(i
=0; (i
<nfile
); i
++)
668 if (ftp
== fnm
[i
].ftp
)
669 return fnm
[i
].fns
[0];
671 fprintf(stderr
,"ftp2fn: No filetype %s\n",deffile
[ftp
].ext
);
675 int ftp2fns(char **fns
[], int ftp
,int nfile
,t_filenm fnm
[])
679 for(i
=0; (i
<nfile
); i
++)
680 if (ftp
== fnm
[i
].ftp
) {
682 return fnm
[i
].nfiles
;
685 fprintf(stderr
,"ftp2fn: No filetype %s\n",deffile
[ftp
].ext
);
689 bool ftp2bSet(int ftp
,int nfile
,t_filenm fnm
[])
693 for(i
=0; (i
<nfile
); i
++)
694 if (ftp
== fnm
[i
].ftp
)
695 return (bool) IS_SET(fnm
[i
]);
697 fprintf(stderr
,"ftp2bSet: No filetype %s\n",deffile
[ftp
].ext
);
702 bool opt2bSet(char *opt
,int nfile
,t_filenm fnm
[])
706 for(i
=0; (i
<nfile
); i
++)
707 if (strcmp(opt
,fnm
[i
].opt
)==0)
708 return (bool) IS_SET(fnm
[i
]);
710 fprintf(stderr
,"No option %s\n",opt
);
715 char *opt2fn_null(char *opt
,int nfile
,t_filenm fnm
[])
719 for(i
=0; (i
<nfile
); i
++)
720 if (strcmp(opt
,fnm
[i
].opt
)==0) {
721 if (IS_OPT(fnm
[i
]) && !IS_SET(fnm
[i
]))
724 return fnm
[i
].fns
[0];
726 fprintf(stderr
,"No option %s\n",opt
);
730 char *ftp2fn_null(int ftp
,int nfile
,t_filenm fnm
[])
734 for(i
=0; (i
<nfile
); i
++)
735 if (ftp
== fnm
[i
].ftp
) {
736 if (IS_OPT(fnm
[i
]) && !IS_SET(fnm
[i
]))
739 return fnm
[i
].fns
[0];
741 fprintf(stderr
,"ftp2fn: No filetype %s\n",deffile
[ftp
].ext
);
745 static void add_filters(char *filter
,int *n
,int nf
,const int ftp
[])
750 sprintf(filter
,"*.{");
751 for(i
=0; (i
<nf
); i
++) {
752 sprintf(buf
,"%s",ftp2ext(ftp
[i
]));
761 char *ftp2filter(int ftp
)
764 static char filter
[128];
770 add_filters(filter
,&n
,NENXS
,enxs
);
773 add_filters(filter
,&n
,NTRXS
,trxs
);
776 add_filters(filter
,&n
,NTRNS
,trns
);
779 add_filters(filter
,&n
,NSTOS
,stos
);
782 add_filters(filter
,&n
,NSTXS
,stxs
);
785 add_filters(filter
,&n
,NTPXS
,tpxs
);
788 sprintf(filter
,"*%s",ftp2ext(ftp
));
794 bool is_optional(t_filenm
*fnm
)
796 return ((fnm
->flag
& ffOPT
) == ffOPT
);
799 bool is_output(t_filenm
*fnm
)
801 return ((fnm
->flag
& ffWRITE
) == ffWRITE
);
804 bool is_set(t_filenm
*fnm
)
806 return ((fnm
->flag
& ffSET
) == ffSET
);