added Verlet scheme and NxN non-bonded functionality
[gromacs.git] / src / gmxlib / filenm.c
blobd42f37e11c273556f1423cdc50b5ec6437208b5d
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.
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
32 * And Hey:
33 * GROningen Mixture of Alchemy and Childrens' Stories
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
39 #include <string.h>
40 #include "sysstuff.h"
41 #include "typedefs.h"
42 #include "smalloc.h"
43 #include "string2.h"
44 #include "gmx_fatal.h"
45 #include "filenm.h"
46 #include "futil.h"
47 #include "wman.h"
48 #include "xdrf.h"
49 #include "macros.h"
51 #ifdef GMX_THREAD_MPI
52 #include "thread_mpi.h"
53 #endif
55 /* NOTE: this was a cesspool of thread-unsafe code, has now been
56 properly proteced by mutexes (hopefully). */
58 /* XDR should be available on all platforms now,
59 * but we keep the possibility of turning it off...
61 #define USE_XDR
63 /* Use bitflag ... */
64 #define IS_SET(fn) ((fn.flag & ffSET) != 0)
65 #define IS_OPT(fn) ((fn.flag & ffOPT) != 0)
66 #define IS_MULT(fn) ((fn.flag & ffMULT) != 0)
67 #define UN_SET(fn) (fn.flag = (fn.flag & ~ffSET))
68 #define DO_SET(fn) (fn.flag = (fn.flag | ffSET))
70 enum
72 eftASC, eftBIN, eftXDR, eftGEN, eftNR
75 /* To support multiple file types with one general (eg TRX) we have
76 * these arrays.
78 static const int trxs[] =
80 #ifdef USE_XDR
81 efXTC, efTRR, efCPT,
82 #endif
83 efTRJ, efGRO, efG96, efPDB, efG87 };
84 #define NTRXS asize(trxs)
86 static const int tros[] =
88 #ifdef USE_XDR
89 efXTC, efTRR,
90 #endif
91 efTRJ, efGRO, efG96, efPDB, efG87 };
92 #define NTROS asize(tros)
94 static const int trns[] =
96 #ifdef USE_XDR
97 efTRR, efCPT,
98 #endif
99 efTRJ };
100 #define NTRNS asize(trns)
102 static const int stos[] =
103 { efGRO, efG96, efPDB, efBRK, efENT, efESP, efXYZ };
104 #define NSTOS asize(stos)
106 static const int stxs[] =
107 { efGRO, efG96, efPDB, efBRK, efENT, efESP, efXYZ,
108 #ifdef USE_XDR
109 efTPR,
110 #endif
111 efTPB, efTPA };
112 #define NSTXS asize(stxs)
114 static const int tpxs[] =
116 #ifdef USE_XDR
117 efTPR,
118 #endif
119 efTPB, efTPA };
120 #define NTPXS asize(tpxs)
122 static const int tpss[] =
124 #ifdef USE_XDR
125 efTPR,
126 #endif
127 efTPB, efTPA, efGRO, efG96, efPDB, efBRK, efENT };
128 #define NTPSS asize(tpss)
130 typedef struct
132 int ftype;
133 const char *ext;
134 const char *defnm;
135 const char *defopt;
136 const char *descr;
137 int ntps;
138 const int *tps;
139 } t_deffile;
141 /* this array should correspond to the enum in include/types/filenm.h */
142 static const t_deffile
143 deffile[efNR] =
145 { eftASC, ".mdp", "grompp", "-f", "grompp input file with MD parameters" },
146 { eftASC, ".gct", "gct", "-f", "General coupling stuff"},
147 { eftGEN, ".???", "traj", "-f",
148 "Trajectory: xtc trr trj gro g96 pdb cpt", NTRXS, trxs },
149 { eftGEN, ".???", "trajout", "-f",
150 "Trajectory: xtc trr trj gro g96 pdb", NTROS, tros },
151 { eftGEN, ".???", "traj", NULL,
152 "Full precision trajectory: trr trj cpt", NTRNS, trns },
153 { eftXDR, ".trr", "traj", NULL, "Trajectory in portable xdr format" },
154 { eftBIN, ".trj", "traj", NULL, "Trajectory file (architecture specific)" },
155 { eftXDR, ".xtc", "traj", NULL,
156 "Compressed trajectory (portable xdr format)" },
157 { eftASC, ".g87", "gtraj", NULL, "Gromos-87 ASCII trajectory format" },
158 { eftXDR, ".edr", "ener", NULL, "Energy file"},
159 { eftGEN, ".???", "conf", "-c", "Structure file: gro g96 pdb tpr etc.",
160 NSTXS, stxs },
161 { eftGEN, ".???", "out", "-o", "Structure file: gro g96 pdb etc.",
162 NSTOS, stos },
163 { eftASC, ".gro", "conf", "-c", "Coordinate file in Gromos-87 format" },
164 { eftASC, ".g96", "conf", "-c", "Coordinate file in Gromos-96 format" },
165 { eftASC, ".pdb", "eiwit", "-f", "Protein data bank file"},
166 { eftASC, ".brk", "eiwit", "-f", "Brookhaven data bank file"},
167 { eftASC, ".ent", "eiwit", "-f", "Entry in the protein date bank" },
168 { eftASC, ".esp", "conf", "-f", "Coordinate file in Espresso format" },
169 { eftASC, ".pqr", "state", "-o", "Coordinate file for MEAD"},
170 { eftASC, ".xyz", "conf", "-o", "Coordinate file for some other programs" },
171 { eftXDR, ".cpt", "state", "-cp","Checkpoint file"},
172 { eftASC, ".log", "run", "-l", "Log file"},
173 { eftASC, ".xvg", "graph", "-o", "xvgr/xmgr file"},
174 { eftASC, ".out", "hello", "-o", "Generic output file"},
175 { eftASC, ".ndx", "index", "-n", "Index file",},
176 { eftASC, ".top", "topol", "-p", "Topology file"},
177 { eftASC, ".itp", "topinc", NULL, "Include file for topology"},
178 { eftGEN, ".???", "topol", "-s", "Run input file: tpr tpb tpa",
179 NTPXS, tpxs },
180 { eftGEN, ".???", "topol", "-s",
181 "Structure+mass(db): tpr tpb tpa gro g96 pdb", NTPSS, tpss },
182 { eftXDR, ".tpr", "topol", "-s", "Portable xdr run input file"},
183 { eftASC, ".tpa", "topol", "-s", "Ascii run input file"},
184 { eftBIN, ".tpb", "topol", "-s", "Binary run input file"},
185 { eftASC, ".tex", "doc", "-o", "LaTeX file"},
186 { eftASC, ".rtp", "residue", NULL, "Residue Type file used by pdb2gmx" },
187 { eftASC, ".atp", "atomtp", NULL, "Atomtype file used by pdb2gmx" },
188 { eftASC, ".hdb", "polar", NULL, "Hydrogen data base"},
189 { eftASC, ".dat", "nnnice", NULL, "Generic data file"},
190 { eftASC, ".dlg", "user", NULL, "Dialog Box data for ngmx"},
191 { eftASC, ".map", "ss", NULL, "File that maps matrix data to colors" },
192 { eftASC, ".eps", "plot", NULL, "Encapsulated PostScript (tm) file" },
193 { eftASC, ".mat", "ss", NULL, "Matrix Data file"},
194 { eftASC, ".m2p", "ps", NULL, "Input file for mat2ps"},
195 { eftXDR, ".mtx", "hessian","-m", "Hessian matrix"},
196 { eftASC, ".edi", "sam", NULL, "ED sampling input"},
197 { eftASC, ".edo", "sam", NULL, "ED sampling output"},
198 { eftASC, ".hat", "gk", NULL, "Fourier transform of spread function" },
199 { eftASC, ".cub", "pot", NULL, "Gaussian cube file" },
200 { eftASC, ".xpm", "root", NULL, "X PixMap compatible matrix file" },
201 { eftASC, "", "rundir", NULL, "Run directory" }
204 static char *default_file_name = NULL;
206 #ifdef GMX_THREAD_MPI
207 static tMPI_Thread_mutex_t filenm_mutex=TMPI_THREAD_MUTEX_INITIALIZER;
208 #endif
210 #define NZEXT 2
211 const char *z_ext[NZEXT] =
212 { ".gz", ".Z" };
214 void set_default_file_name(const char *name)
216 int i;
217 #ifdef GMX_THREAD_MPI
218 tMPI_Thread_mutex_lock(&filenm_mutex);
219 #endif
220 default_file_name = strdup(name);
221 #ifdef GMX_THREAD_MPI
222 tMPI_Thread_mutex_unlock(&filenm_mutex);
223 #endif
225 #if 0
226 for(i=0; i<efNR; i++)
227 deffile[i].defnm = default_file_name;
228 #endif
231 const char *ftp2ext(int ftp)
233 if ((0 <= ftp) && (ftp < efNR))
234 return deffile[ftp].ext + 1;
235 else
236 return "unknown";
239 const char *ftp2ext_generic(int ftp)
241 if ((0 <= ftp) && (ftp < efNR))
243 switch (ftp)
245 case efTRX:
246 return "trx";
247 case efTRN:
248 return "trn";
249 case efSTO:
250 return "sto";
251 case efSTX:
252 return "stx";
253 case efTPX:
254 return "tpx";
255 case efTPS:
256 return "tps";
257 default:
258 return ftp2ext(ftp);
261 else
262 return "unknown";
265 const char *ftp2desc(int ftp)
267 if ((0 <= ftp) && (ftp < efNR))
268 return deffile[ftp].descr;
269 else
270 return "unknown filetype";
273 const char *ftp2ftype(int ftp)
275 if ((ftp >= 0) && (ftp < efNR))
277 switch (deffile[ftp].ftype)
279 case eftASC:
280 return "ASCII";
281 case eftBIN:
282 return "Binary";
283 case eftXDR:
284 return "XDR portable";
285 case eftGEN:
286 return "";
287 default:
288 gmx_fatal(FARGS, "Unknown filetype %d in ftp2ftype",deffile[ftp].ftype);
289 break;
292 return "unknown";
295 const char *ftp2defnm(int ftp)
297 const char *buf = NULL;
299 #ifdef GMX_THREAD_MPI
300 tMPI_Thread_mutex_lock(&filenm_mutex);
301 #endif
303 if (default_file_name)
305 buf = default_file_name;
307 else
309 if ((0 <= ftp) && (ftp < efNR))
311 buf = deffile[ftp].defnm;
314 #ifdef GMX_THREAD_MPI
315 tMPI_Thread_mutex_unlock(&filenm_mutex);
316 #endif
318 return buf;
321 void pr_def(FILE *fp, int ftp)
323 const t_deffile *df;
324 const char *s = NULL;
325 char *flst, *tmp, *desc;
326 const char *ext;
327 const char *defnm;
329 df = &(deffile[ftp]);
330 defnm = ftp2defnm(ftp);
331 /* find default file extension and \tt-ify description */
332 /* FIXME: The constness should not be cast away */
333 flst = (char *) "";
334 desc = strdup(df->descr);
336 if (df->ntps)
338 ext = deffile[df->tps[0]].ext;
339 tmp = strstr(desc, ": ") + 1;
340 if (tmp)
342 tmp[0] = '\0';
343 tmp++;
344 snew(flst,strlen(tmp)+6);
345 strcpy(flst, " \\tt ");
346 strcat(flst, tmp);
349 else
351 ext = df->ext;
353 /* now skip dot */
354 if (ext[0])
355 ext++;
356 else
357 ext = "";
358 /* set file contents type */
359 switch (df->ftype)
361 case eftASC:
362 s = "Asc";
363 break;
364 case eftBIN:
365 s = "Bin";
366 break;
367 case eftXDR:
368 s = "xdr";
369 break;
370 case eftGEN:
371 s = "";
372 break;
373 default:
374 gmx_fatal(FARGS, "Unimplemented filetype %d %d",ftp,
375 df->ftype);
377 fprintf(fp,"\\tt %8s & \\tt %3s & %3s & \\tt %2s & %s%s \\\\[-0.1ex]\n",
378 defnm, ext, s, df->defopt ? df->defopt : "",
379 check_tex(desc),check_tex(flst));
380 free(desc);
383 void pr_fns(FILE *fp, int nf, const t_filenm tfn[])
385 int i, f;
386 size_t j;
387 char buf[256], *wbuf, opt_buf[32];
388 #define OPTLEN 4
389 #define NAMELEN 14
390 fprintf(fp, "%6s %12s %-12s %s\n", "Option", "Filename", "Type",
391 "Description");
392 fprintf(fp,
393 "------------------------------------------------------------\n");
394 for (i = 0; (i < nf); i++)
396 for (f = 0; (f < tfn[i].nfiles); f++)
398 sprintf(buf, "%4s %14s %-12s ", (f == 0) ? tfn[i].opt : "",
399 tfn[i].fns[f], (f == 0) ? fileopt(tfn[i].flag, opt_buf, 32)
400 : "");
401 if (f < tfn[i].nfiles - 1)
402 fprintf(fp, "%s\n", buf);
404 if (tfn[i].nfiles > 0)
406 strcat(buf, deffile[tfn[i].ftp].descr);
407 if ((strlen(tfn[i].opt) > OPTLEN)
408 && (strlen(tfn[i].opt) <= ((OPTLEN + NAMELEN)
409 - strlen(tfn[i].fns[tfn[i].nfiles - 1]))))
411 for (j = strlen(tfn[i].opt); j < strlen(buf)
412 - (strlen(tfn[i].opt) - OPTLEN) + 1; j++)
413 buf[j] = buf[j + strlen(tfn[i].opt) - OPTLEN];
415 wbuf = wrap_lines(buf, 78, 35, FALSE);
416 fprintf(fp, "%s\n", wbuf);
417 sfree(wbuf);
420 fprintf(fp, "\n");
421 fflush(fp);
424 void pr_fopts(FILE *fp, int nf, const t_filenm tfn[], int shell)
426 int i, j;
428 switch (shell)
430 case eshellCSH:
431 for (i = 0; (i < nf); i++)
433 fprintf(fp, " \"n/%s/f:*.", tfn[i].opt);
434 if (deffile[tfn[i].ftp].ntps)
436 fprintf(fp, "{");
437 for (j = 0; j < deffile[tfn[i].ftp].ntps; j++)
439 if (j > 0)
440 fprintf(fp, ",");
441 fprintf(fp, "%s", deffile[deffile[tfn[i].ftp].tps[j]].ext
442 + 1);
444 fprintf(fp, "}");
446 else
447 fprintf(fp, "%s", deffile[tfn[i].ftp].ext + 1);
448 fprintf(fp, "{");
449 for (j = 0; j < NZEXT; j++)
450 fprintf(fp, ",%s", z_ext[j]);
451 fprintf(fp, "}/\"");
453 break;
454 case eshellBASH:
455 for (i = 0; (i < nf); i++)
457 fprintf(fp, "%s) COMPREPLY=( $(compgen -X '!*.", tfn[i].opt);
458 if (deffile[tfn[i].ftp].ntps)
460 fprintf(fp, "+(");
461 for (j = 0; j < deffile[tfn[i].ftp].ntps; j++)
463 if (j > 0)
464 fprintf(fp, "|");
465 fprintf(fp, "%s", deffile[deffile[tfn[i].ftp].tps[j]].ext
466 + 1);
468 fprintf(fp, ")");
470 else
471 fprintf(fp, "%s", deffile[tfn[i].ftp].ext + 1);
472 fprintf(fp, "*(");
473 for (j = 0; j < NZEXT; j++)
475 if (j > 0)
476 fprintf(fp, "|");
477 fprintf(fp, "%s", z_ext[j]);
479 fprintf(fp, ")' -f $c ; compgen -S '/' -X '.*' -d $c ));;\n");
481 break;
482 case eshellZSH:
483 for (i = 0; (i < nf); i++)
485 fprintf(fp, "- 'c[-1,%s]' -g '*.", tfn[i].opt);
486 if (deffile[tfn[i].ftp].ntps)
488 fprintf(fp, "(");
489 for (j = 0; j < deffile[tfn[i].ftp].ntps; j++)
491 if (j > 0)
492 fprintf(fp, "|");
493 fprintf(fp, "%s", deffile[deffile[tfn[i].ftp].tps[j]].ext
494 + 1);
496 fprintf(fp, ")");
498 else
499 fprintf(fp, "%s", deffile[tfn[i].ftp].ext + 1);
500 fprintf(fp, "(");
501 for (j = 0; j < NZEXT; j++)
502 fprintf(fp, "|%s", z_ext[j]);
503 fprintf(fp, ") *(/)' ");
505 break;
509 static void check_opts(int nf, t_filenm fnm[])
511 int i;
512 const t_deffile *df;
514 for (i = 0; (i < nf); i++)
516 df = &(deffile[fnm[i].ftp]);
517 if (fnm[i].opt == NULL)
519 if (df->defopt == NULL)
521 gmx_fatal(FARGS, "No default cmd-line option for %s (type %d)\n",
522 deffile[fnm[i].ftp].ext,fnm[i].ftp);
524 else
526 fnm[i].opt=df->defopt;
532 int fn2ftp(const char *fn)
534 int i, len;
535 const char *feptr;
536 const char *eptr;
538 if (!fn)
539 return efNR;
541 len = strlen(fn);
542 if ((len >= 4) && (fn[len - 4] == '.'))
543 feptr = &(fn[len - 4]);
544 else
545 return efNR;
547 for (i = 0; (i < efNR); i++)
548 if ((eptr = deffile[i].ext) != NULL)
549 if (gmx_strcasecmp(feptr, eptr) == 0)
550 break;
552 return i;
555 static void set_extension(char *buf, int ftp)
557 int len, extlen;
558 const t_deffile *df;
560 /* check if extension is already at end of filename */
561 df = &(deffile[ftp]);
562 len = strlen(buf);
563 extlen = strlen(df->ext);
564 if ((len <= extlen) || (gmx_strcasecmp(&(buf[len - extlen]), df->ext) != 0))
565 strcat(buf, df->ext);
568 static void add_filenm(t_filenm *fnm, const char *filenm)
570 srenew(fnm->fns, fnm->nfiles+1);
571 fnm->fns[fnm->nfiles] = strdup(filenm);
572 fnm->nfiles++;
575 static void set_grpfnm(t_filenm *fnm, const char *name, gmx_bool bCanNotOverride)
577 char buf[256], buf2[256];
578 int i, type;
579 gmx_bool bValidExt;
580 int nopts;
581 const int *ftps;
583 nopts = deffile[fnm->ftp].ntps;
584 ftps = deffile[fnm->ftp].tps;
585 if ((nopts == 0) || (ftps == NULL))
586 gmx_fatal(FARGS, "nopts == 0 || ftps == NULL");
588 bValidExt = FALSE;
589 if (name && (bCanNotOverride || (default_file_name == NULL)))
591 strcpy(buf,name);
592 /* First check whether we have a valid filename already */
593 type = fn2ftp(name);
594 if ((fnm->flag & ffREAD) && (fnm->ftp == efTRX))
596 /*if file exist don't add an extension for trajectory reading*/
597 bValidExt = gmx_fexist(name);
599 for(i=0; (i<nopts) && !bValidExt; i++)
601 if (type == ftps[i])
603 bValidExt = TRUE;
607 else
608 /* No name given, set the default name */
609 strcpy(buf,ftp2defnm(fnm->ftp));
611 if (!bValidExt && (fnm->flag & ffREAD))
613 /* for input-files only: search for filenames in the directory */
614 for(i=0; (i<nopts) && !bValidExt; i++)
616 type = ftps[i];
617 strcpy(buf2,buf);
618 set_extension(buf2,type);
619 if (gmx_fexist(buf2))
621 bValidExt = TRUE;
622 strcpy(buf,buf2);
627 if (!bValidExt)
629 /* Use the first extension type */
630 set_extension(buf,ftps[0]);
633 add_filenm(fnm, buf);
636 static void set_filenm(t_filenm *fnm, const char *name, gmx_bool bCanNotOverride,
637 gmx_bool bReadNode)
639 /* Set the default filename, extension and option for those fields that
640 * are not already set. An extension is added if not present, if fn = NULL
641 * or empty, the default filename is given.
643 char buf[256];
644 int i, len, extlen;
646 if ((fnm->flag & ffREAD) && !bReadNode)
648 return;
651 if ((fnm->ftp < 0) || (fnm->ftp >= efNR))
652 gmx_fatal(FARGS, "file type out of range (%d)",fnm->ftp);
654 if (name)
655 strcpy(buf, name);
656 if ((fnm->flag & ffREAD) && name && gmx_fexist(name))
658 /* check if filename ends in .gz or .Z, if so remove that: */
659 len = strlen(name);
660 for (i=0; i<NZEXT; i++)
662 extlen = strlen(z_ext[i]);
663 if (len > extlen)
665 if (gmx_strcasecmp(name+len-extlen,z_ext[i]) == 0)
667 buf[len-extlen]='\0';
668 break;
674 if (deffile[fnm->ftp].ntps)
676 set_grpfnm(fnm,name ? buf : NULL,bCanNotOverride);
678 else
680 if ((name == NULL) || !(bCanNotOverride || (default_file_name ==NULL)))
682 const char *defnm=ftp2defnm(fnm->ftp);
683 strcpy(buf,defnm);
685 set_extension(buf,fnm->ftp);
687 add_filenm(fnm, buf);
691 static void set_filenms(int nf, t_filenm fnm[], gmx_bool bReadNode)
693 int i;
695 for (i = 0; (i < nf); i++)
696 if (!IS_SET(fnm[i]))
697 set_filenm(&(fnm[i]), fnm[i].fn, FALSE, bReadNode);
700 void parse_file_args(int *argc, char *argv[], int nf, t_filenm fnm[],
701 gmx_bool bKeep, gmx_bool bReadNode)
703 int i, j;
704 gmx_bool *bRemove;
706 check_opts(nf, fnm);
708 for (i = 0; (i < nf); i++)
709 UN_SET(fnm[i]);
711 if (*argc > 1)
713 snew(bRemove,(*argc)+1);
714 i = 1;
717 for (j = 0; (j < nf); j++)
719 if (strcmp(argv[i], fnm[j].opt) == 0)
721 DO_SET(fnm[j]);
722 bRemove[i] = TRUE;
723 i++;
724 /* check if we are out of arguments for this option */
725 if ((i >= *argc) || (argv[i][0] == '-'))
726 set_filenm(&fnm[j], fnm[j].fn, FALSE, bReadNode);
727 /* sweep up all file arguments for this option */
728 while ((i < *argc) && (argv[i][0] != '-'))
730 set_filenm(&fnm[j], argv[i], TRUE, bReadNode);
731 bRemove[i] = TRUE;
732 i++;
733 /* only repeat for 'multiple' file options: */
734 if (!IS_MULT(fnm[j]))
735 break;
738 break; /* jump out of 'j' loop */
741 /* No file found corresponding to option argv[i] */
742 if (j == nf)
743 i++;
744 } while (i < *argc);
746 if (!bKeep)
748 /* Remove used entries */
749 for (i = j = 0; (i <= *argc); i++)
751 if (!bRemove[i])
752 argv[j++] = argv[i];
754 (*argc) = j - 1;
756 sfree(bRemove);
759 set_filenms(nf, fnm, bReadNode);
763 const char *opt2fn(const char *opt, int nfile, const t_filenm fnm[])
765 int i;
767 for (i = 0; (i < nfile); i++)
768 if (strcmp(opt, fnm[i].opt) == 0)
770 return fnm[i].fns[0];
773 fprintf(stderr, "No option %s\n", opt);
775 return NULL;
778 const char *opt2fn_master(const char *opt, int nfile, const t_filenm fnm[],
779 t_commrec *cr)
781 return SIMMASTER(cr) ? opt2fn(opt, nfile, fnm) : NULL;
784 int opt2fns(char **fns[], const char *opt, int nfile, const t_filenm fnm[])
786 int i;
788 for (i = 0; (i < nfile); i++)
789 if (strcmp(opt, fnm[i].opt) == 0)
791 *fns = fnm[i].fns;
792 return fnm[i].nfiles;
795 fprintf(stderr, "No option %s\n", opt);
796 return 0;
799 const char *ftp2fn(int ftp, int nfile, const t_filenm fnm[])
801 int i;
803 for (i = 0; (i < nfile); i++)
804 if (ftp == fnm[i].ftp)
805 return fnm[i].fns[0];
807 fprintf(stderr, "ftp2fn: No filetype %s\n", deffile[ftp].ext);
808 return NULL;
811 int ftp2fns(char **fns[], int ftp, int nfile, const t_filenm fnm[])
813 int i;
815 for (i = 0; (i < nfile); i++)
816 if (ftp == fnm[i].ftp)
818 *fns = fnm[i].fns;
819 return fnm[i].nfiles;
822 fprintf(stderr, "ftp2fn: No filetype %s\n", deffile[ftp].ext);
823 return 0;
826 gmx_bool ftp2bSet(int ftp, int nfile, const t_filenm fnm[])
828 int i;
830 for (i = 0; (i < nfile); i++)
831 if (ftp == fnm[i].ftp)
832 return (gmx_bool) IS_SET(fnm[i]);
834 fprintf(stderr, "ftp2bSet: No filetype %s\n", deffile[ftp].ext);
836 return FALSE;
839 gmx_bool opt2bSet(const char *opt, int nfile, const t_filenm fnm[])
841 int i;
843 for (i = 0; (i < nfile); i++)
844 if (strcmp(opt, fnm[i].opt) == 0)
845 return (gmx_bool) IS_SET(fnm[i]);
847 fprintf(stderr, "No option %s\n", opt);
849 return FALSE;
852 const char *opt2fn_null(const char *opt, int nfile, const t_filenm fnm[])
854 int i;
856 for (i = 0; (i < nfile); i++)
857 if (strcmp(opt, fnm[i].opt) == 0)
859 if (IS_OPT(fnm[i]) && !IS_SET(fnm[i]))
860 return NULL;
861 else
862 return fnm[i].fns[0];
864 fprintf(stderr, "No option %s\n", opt);
865 return NULL;
868 const char *ftp2fn_null(int ftp, int nfile, const t_filenm fnm[])
870 int i;
872 for (i = 0; (i < nfile); i++)
873 if (ftp == fnm[i].ftp)
875 if (IS_OPT(fnm[i]) && !IS_SET(fnm[i]))
876 return NULL;
877 else
878 return fnm[i].fns[0];
880 fprintf(stderr, "ftp2fn: No filetype %s\n", deffile[ftp].ext);
881 return NULL;
884 #if 0
885 static void add_filters(char *filter,int *n,int nf,const int ftp[])
887 char buf[8];
888 int i;
890 sprintf(filter,"*.{");
891 for(i=0; (i<nf); i++)
893 sprintf(buf,"%s",ftp2ext(ftp[i]));
894 if (*n > 0)
895 strcat(filter,",");
896 strcat(filter,buf);
897 (*n) ++;
899 strcat(filter,"}");
902 char *ftp2filter(int ftp)
904 int n;
905 static char filter[128];
907 filter[0] = '\0';
908 n = 0;
909 switch (ftp)
911 case efTRX:
912 add_filters(filter,&n,NTRXS,trxs);
913 break;
914 case efTRN:
915 add_filters(filter,&n,NTRNS,trns);
916 break;
917 case efSTO:
918 add_filters(filter,&n,NSTOS,stos);
919 break;
920 case efSTX:
921 add_filters(filter,&n,NSTXS,stxs);
922 break;
923 case efTPX:
924 add_filters(filter,&n,NTPXS,tpxs);
925 break;
926 default:
927 sprintf(filter,"*%s",ftp2ext(ftp));
928 break;
930 return filter;
932 #endif
934 gmx_bool is_optional(const t_filenm *fnm)
936 return ((fnm->flag & ffOPT) == ffOPT);
939 gmx_bool is_output(const t_filenm *fnm)
941 return ((fnm->flag & ffWRITE) == ffWRITE);
944 gmx_bool is_set(const t_filenm *fnm)
946 return ((fnm->flag & ffSET) == ffSET);
949 int add_suffix_to_output_names(t_filenm *fnm, int nfile, const char *suffix)
951 int i, j, pos;
952 char buf[STRLEN], newname[STRLEN];
953 char *extpos;
955 for (i = 0; i < nfile; i++)
957 if (is_output(&fnm[i]) && fnm[i].ftp != efCPT)
959 /* We never use multiple _outputs_, but we might as well check
960 for it, just in case... */
961 for (j = 0; j < fnm[i].nfiles; j++)
963 strncpy(buf, fnm[i].fns[j], STRLEN - 1);
964 extpos = strrchr(buf, '.');
965 *extpos = '\0';
966 sprintf(newname, "%s%s.%s", buf, suffix, extpos + 1);
967 free(fnm[i].fns[j]);
968 fnm[i].fns[j] = strdup(newname);
972 return 0;
975 t_filenm *dup_tfn(int nf, const t_filenm tfn[])
977 int i, j;
978 t_filenm *ret;
980 snew(ret, nf);
981 for (i = 0; i < nf; i++)
983 ret[i] = tfn[i]; /* just directly copy all non-string fields */
984 if (tfn[i].opt)
985 ret[i].opt = strdup(tfn[i].opt);
986 else
987 ret[i].opt = NULL;
989 if (tfn[i].fn)
990 ret[i].fn = strdup(tfn[i].fn);
991 else
992 ret[i].fn = NULL;
994 if (tfn[i].nfiles > 0)
996 snew(ret[i].fns,tfn[i].nfiles);
997 for (j = 0; j < tfn[i].nfiles; j++)
999 ret[i].fns[j] = strdup(tfn[i].fns[j]);
1003 return ret;
1006 void done_filenms(int nf, t_filenm fnm[])
1008 int i, j;
1010 for (i = 0; i < nf; ++i)
1012 for (j = 0; j < fnm[i].nfiles; ++j)
1014 sfree(fnm[i].fns[j]);
1016 sfree(fnm[i].fns);
1017 fnm[i].fns = NULL;