Added conditional inclusion of config.h to source files
[gromacs.git] / src / gmxlib / filenm.c
bloba2044ffdfb6e2297707b725fb28e0462693afe57
1 /*
2 * $Id$
3 *
4 * This source code is part of
5 *
6 * G R O M A C S
7 *
8 * GROningen MAchine for Chemical Simulations
9 *
10 * VERSION 3.2.0
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
33 * And Hey:
34 * GROningen Mixture of Alchemy and Childrens' Stories
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
40 #include <string.h>
41 #include "sysstuff.h"
42 #include "typedefs.h"
43 #include "smalloc.h"
44 #include "string2.h"
45 #include "fatal.h"
46 #include "filenm.h"
47 #include "futil.h"
48 #include "wman.h"
49 #include "xdrf.h"
50 #include "macros.h"
52 /* XDR should be available on all platforms now,
53 * but we keep the possibility of turning it off...
55 #define USE_XDR
57 /* Use bitflag ... */
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
67 * these arrays.
69 static const int trxs[]={
70 #ifdef USE_XDR
71 efXTC, efTRR,
72 #endif
73 efTRJ, efGRO, efG96, efPDB, efG87 };
74 #define NTRXS asize(trxs)
76 static const int trns[]={
77 #ifdef USE_XDR
78 efTRR,
79 #endif
80 efTRJ };
81 #define NTRNS asize(trns)
83 static const int stos[]={ efGRO, efG96, efPDB, efBRK,
84 #ifdef HAVE_LIBXML2
85 efXML,
86 #endif
87 efENT};
88 #define NSTOS asize(stos)
90 static const int stxs[]={ efGRO, efG96, efPDB, efBRK, efENT,
91 #ifdef USE_XDR
92 efTPR,
93 #endif
94 efTPB, efTPA
95 #ifdef HAVE_LIBXML2
96 , efXML
97 #endif
99 #define NSTXS asize(stxs)
101 static const int enxs[]={
102 #ifdef USE_XDR
103 efEDR,
104 #endif
105 efENE };
106 #define NENXS asize(enxs)
108 static const int tpxs[]={
109 #ifdef USE_XDR
110 efTPR,
111 #endif
112 efTPB, efTPA
113 #ifdef HAVE_LIBXML2
114 , efXML
115 #endif
117 #define NTPXS asize(tpxs)
119 static const int tpss[]={
120 #ifdef USE_XDR
121 efTPR,
122 #endif
123 efTPB, efTPA,
124 #ifdef HAVE_LIBXML2
125 efXML,
126 #endif
127 efGRO, efG96, efPDB, efBRK, efENT };
128 #define NTPSS asize(tpss)
130 typedef struct {
131 int ftype;
132 char *ext;
133 char *defnm;
134 char *defopt;
135 const char *descr;
136 int ntps;
137 const int *tps;
138 } t_deffile;
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" },
172 #ifdef HAVE_LIBXML2
173 { eftASC, ".xml", "gmx", "-x", "Portable status file" },
174 #endif
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;
196 #define NZEXT 2
197 const char *z_ext[NZEXT] = { ".gz", ".Z" };
199 void set_default_file_name(const char *name)
201 int i;
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;
213 else
214 return "unknown";
217 const char *ftp2ext_generic(int ftp)
219 if ((0 <= ftp) && (ftp < efNR)) {
220 switch (ftp) {
221 case efENX:
222 return "enx";
223 case efTRX:
224 return "trx";
225 case efTRN:
226 return "trn";
227 case efSTO:
228 return "sto";
229 case efSTX:
230 return "stx";
231 case efTPX:
232 return "tpx";
233 case efTPS:
234 return "tps";
235 default:
236 return ftp2ext(ftp);
239 else
240 return "unknown";
243 const char *ftp2desc(int ftp)
245 if ((0 <= ftp) && (ftp < efNR))
246 return deffile[ftp].descr;
247 else
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)",
260 deffile[ftp].ftype);
261 break;
264 return "unknown";
267 const char *ftp2defnm(int ftp)
269 static char buf[256];
271 if ((0 <= ftp) && (ftp < efNR)) {
272 sprintf(buf,"%s",deffile[ftp].defnm);
273 return buf;
275 else
276 return NULL;
279 void pr_def(FILE *fp,int ftp)
281 t_deffile *df;
282 char *s=NULL,*flst;
283 const char *ext,*desc;
285 df=&(deffile[ftp]);
286 /* find default file extension and \tt-ify description */
287 flst="";
288 if (df->ntps) {
289 ext = deffile[df->tps[0]].ext;
290 desc= strdup(df->descr);
291 s = strstr(desc,": ")+1;
292 if (s) {
293 s[0] = '\0';
294 s++;
295 snew(flst,strlen(s)+6);
296 strcpy(flst, " \\tt ");
297 strcat(flst, s);
299 } else {
300 ext = df->ext;
301 desc= df->descr;
303 /* now skip dot */
304 if (ext[0])
305 ext++;
306 else
307 ext="";
308 /* set file contents type */
309 switch (df->ftype) {
310 case eftASC: s="Asc";
311 break;
312 case eftBIN: s="Bin";
313 break;
314 case eftXDR: s="xdr";
315 break;
316 case eftGEN: s="";
317 break;
318 default:
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[])
328 int i,j,f;
329 char buf[256],*wbuf,opt_buf[32];
330 #define OPTLEN 4
331 #define NAMELEN 14
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);
354 sfree(wbuf);
357 fprintf(fp,"\n");
358 fflush(fp);
361 void pr_fopts(FILE *fp,int nf,t_filenm tfn[], int shell)
363 int i,j;
365 switch (shell) {
366 case eshellCSH:
367 for(i=0; (i<nf); i++) {
368 fprintf(fp," \"n/%s/f:*.",tfn[i].opt);
369 if (deffile[tfn[i].ftp].ntps) {
370 fprintf(fp,"{");
371 for(j=0; j<deffile[tfn[i].ftp].ntps; j++) {
372 if (j>0)
373 fprintf(fp,",");
374 fprintf(fp,"%s",deffile[deffile[tfn[i].ftp].tps[j]].ext+1);
376 fprintf(fp,"}");
377 } else
378 fprintf(fp,"%s",deffile[tfn[i].ftp].ext+1);
379 fprintf(fp,"{");
380 for(j=0; j<NZEXT; j++)
381 fprintf(fp,",%s",z_ext[j]);
382 fprintf(fp,"}/\"");
384 break;
385 case eshellBASH:
386 for(i=0; (i<nf); i++) {
387 fprintf(fp,"%s) COMPREPLY=( $(compgen -X '!*.",tfn[i].opt);
388 if (deffile[tfn[i].ftp].ntps) {
389 fprintf(fp,"+(");
390 for(j=0; j<deffile[tfn[i].ftp].ntps; j++) {
391 if (j>0)
392 fprintf(fp,"|");
393 fprintf(fp,"%s",deffile[deffile[tfn[i].ftp].tps[j]].ext+1);
395 fprintf(fp,")");
396 } else
397 fprintf(fp,"%s",deffile[tfn[i].ftp].ext+1);
398 fprintf(fp,"*(");
399 for(j=0; j<NZEXT; j++) {
400 if (j>0)
401 fprintf(fp,"|");
402 fprintf(fp,"%s",z_ext[j]);
404 fprintf(fp,")' -f $c ; compgen -S '/' -X '.*' -d $c ));;\n");
406 break;
407 case eshellZSH:
408 for(i=0; (i<nf); i++) {
409 fprintf(fp,"- 'c[-1,%s]' -g '*.",tfn[i].opt);
410 if (deffile[tfn[i].ftp].ntps) {
411 fprintf(fp,"(");
412 for(j=0; j<deffile[tfn[i].ftp].ntps; j++) {
413 if (j>0)
414 fprintf(fp,"|");
415 fprintf(fp,"%s",deffile[deffile[tfn[i].ftp].tps[j]].ext+1);
417 fprintf(fp,")");
418 } else
419 fprintf(fp,"%s",deffile[tfn[i].ftp].ext+1);
420 fprintf(fp,"(");
421 for(j=0; j<NZEXT; j++)
422 fprintf(fp,"|%s",z_ext[j]);
423 fprintf(fp,") *(/)' ");
425 break;
429 static void check_opts(int nf,t_filenm fnm[])
431 int i;
432 t_deffile *df;
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);
440 else
441 fnm[i].opt=df->defopt;
446 int fn2ftp(char *fn)
448 int i,len;
449 char *feptr,*eptr;
451 if (!fn)
452 return efNR;
454 len=strlen(fn);
455 if ((len >= 4) && (fn[len-4] == '.'))
456 feptr=&(fn[len-4]);
457 else
458 return efNR;
460 for(i=0; (i<efNR); i++)
461 if ((eptr=deffile[i].ext) != NULL)
462 if (strcasecmp(feptr,eptr)==0)
463 break;
465 return i;
468 static void set_extension(char *buf,int ftp)
470 int len,extlen;
471 t_deffile *df;
473 /* check if extension is already at end of filename */
474 df=&(deffile[ftp]);
475 len=strlen(buf);
476 extlen = strlen(df->ext);
477 if ((len <= extlen) || (strcasecmp(&(buf[len-extlen]),df->ext) != 0))
478 strcat(buf,df->ext);
481 static void add_filenm(t_filenm *fnm, char *filenm)
483 srenew(fnm->fns, fnm->nfiles+1);
484 fnm->fns[fnm->nfiles] = strdup(filenm);
485 fnm->nfiles++;
488 static void set_grpfnm(t_filenm *fnm,char *name,bool bCanNotOverride)
490 char buf[256],buf2[256];
491 int i,type;
492 bool bValidExt;
493 int nopts;
494 const int *ftps;
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__);
501 bValidExt = FALSE;
502 if (name && (bCanNotOverride || (default_file_name == NULL))) {
503 strcpy(buf,name);
504 /* First check whether we have a valid filename already */
505 type = fn2ftp(name);
506 for(i=0; (i<nopts) && !bValidExt; i++)
507 if (type == ftps[i])
508 bValidExt = TRUE;
509 } else
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++) {
516 type = ftps[i];
517 strcpy(buf2,buf);
518 set_extension(buf2,type);
519 if (fexist(buf2)) {
520 bValidExt = TRUE;
521 strcpy(buf,buf2);
526 if (!bValidExt)
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.
539 char buf[256];
540 int i,len,extlen;
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: */
547 len = strlen(name);
548 for (i=0; i<NZEXT; i++) {
549 extlen = strlen(z_ext[i]);
550 if (len > extlen)
551 if (strcasecmp(name+len-extlen,z_ext[i]) == 0) {
552 name[len-extlen]='\0';
553 break;
558 if (deffile[fnm->ftp].ntps)
559 set_grpfnm(fnm,name,bCanNotOverride);
560 else {
561 if ((name != NULL) && (bCanNotOverride || (default_file_name == NULL)))
562 strcpy(buf,name);
563 else
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[])
573 int i;
575 for(i=0; (i<nf); i++)
576 if (!IS_SET(fnm[i]))
577 set_filenm(&(fnm[i]),fnm[i].fn,FALSE);
580 void parse_file_args(int *argc,char *argv[],int nf,t_filenm fnm[],
581 bool bKeep)
583 int i,j;
584 bool *bRemove;
586 check_opts(nf,fnm);
588 for(i=0; (i<nf); i++)
589 UN_SET(fnm[i]);
591 if (*argc > 1) {
592 snew(bRemove,(*argc)+1);
593 i=1;
594 do {
595 for(j=0; (j<nf); j++) {
596 if (strcmp(argv[i],fnm[j].opt) == 0) {
597 DO_SET(fnm[j]);
598 bRemove[i]=TRUE;
599 i++;
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);
606 bRemove[i]=TRUE;
607 i++;
608 /* only repeat for 'multiple' file options: */
609 if ( ! IS_MULT(fnm[j]) )
610 break;
613 break; /* jump out of 'j' loop */
616 /* No file found corresponding to option argv[i] */
617 if (j == nf)
618 i++;
619 } while (i < *argc);
621 if (!bKeep) {
622 /* Remove used entries */
623 for(i=j=0; (i<=*argc); i++) {
624 if (!bRemove[i])
625 argv[j++]=argv[i];
627 (*argc)=j-1;
629 sfree(bRemove);
632 set_filenms(nf,fnm);
635 char *opt2fn(char *opt,int nfile,t_filenm fnm[])
637 int i;
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);
646 return NULL;
649 int opt2fns(char **fns[], char *opt,int nfile,t_filenm fnm[])
651 int i;
653 for(i=0; (i<nfile); i++)
654 if (strcmp(opt,fnm[i].opt)==0) {
655 *fns = fnm[i].fns;
656 return fnm[i].nfiles;
659 fprintf(stderr,"No option %s\n",opt);
660 return 0;
663 char *ftp2fn(int ftp,int nfile,t_filenm fnm[])
665 int i;
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);
672 return NULL;
675 int ftp2fns(char **fns[], int ftp,int nfile,t_filenm fnm[])
677 int i;
679 for(i=0; (i<nfile); i++)
680 if (ftp == fnm[i].ftp) {
681 *fns = fnm[i].fns;
682 return fnm[i].nfiles;
685 fprintf(stderr,"ftp2fn: No filetype %s\n",deffile[ftp].ext);
686 return 0;
689 bool ftp2bSet(int ftp,int nfile,t_filenm fnm[])
691 int i;
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);
699 return FALSE;
702 bool opt2bSet(char *opt,int nfile,t_filenm fnm[])
704 int i;
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);
712 return FALSE;
715 char *opt2fn_null(char *opt,int nfile,t_filenm fnm[])
717 int i;
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]))
722 return NULL;
723 else
724 return fnm[i].fns[0];
726 fprintf(stderr,"No option %s\n",opt);
727 return NULL;
730 char *ftp2fn_null(int ftp,int nfile,t_filenm fnm[])
732 int i;
734 for(i=0; (i<nfile); i++)
735 if (ftp == fnm[i].ftp) {
736 if (IS_OPT(fnm[i]) && !IS_SET(fnm[i]))
737 return NULL;
738 else
739 return fnm[i].fns[0];
741 fprintf(stderr,"ftp2fn: No filetype %s\n",deffile[ftp].ext);
742 return NULL;
745 static void add_filters(char *filter,int *n,int nf,const int ftp[])
747 char buf[8];
748 int i;
750 sprintf(filter,"*.{");
751 for(i=0; (i<nf); i++) {
752 sprintf(buf,"%s",ftp2ext(ftp[i]));
753 if (*n > 0)
754 strcat(filter,",");
755 strcat(filter,buf);
756 (*n) ++;
758 strcat(filter,"}");
761 char *ftp2filter(int ftp)
763 int n;
764 static char filter[128];
766 filter[0] = '\0';
767 n = 0;
768 switch (ftp) {
769 case efENX:
770 add_filters(filter,&n,NENXS,enxs);
771 break;
772 case efTRX:
773 add_filters(filter,&n,NTRXS,trxs);
774 break;
775 case efTRN:
776 add_filters(filter,&n,NTRNS,trns);
777 break;
778 case efSTO:
779 add_filters(filter,&n,NSTOS,stos);
780 break;
781 case efSTX:
782 add_filters(filter,&n,NSTXS,stxs);
783 break;
784 case efTPX:
785 add_filters(filter,&n,NTPXS,tpxs);
786 break;
787 default:
788 sprintf(filter,"*%s",ftp2ext(ftp));
789 break;
791 return filter;
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);