1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
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
43 #include <sys/types.h>
51 #if ((defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64) && !defined __CYGWIN__ && !defined __CYGWIN32__)
60 #include "gmx_fatal.h"
65 #include "thread_mpi.h"
68 #include "fflibutil.h"
70 const char *fflib_forcefield_dir_ext()
75 const char *fflib_forcefield_itp()
77 return "forcefield.itp";
80 const char *fflib_forcefield_doc()
82 return "forcefield.doc";
85 void fflib_filename_base(const char *filename
,char *filebase
,int maxlen
)
90 cptr
= strrchr(filename
,DIR_SEPARATOR
);
93 /* Skip the separator */
100 if (strlen(filename
) >= maxlen
)
102 gmx_fatal(FARGS
,"filename is longer (%d) than maxlen (%d)",
103 strlen(filename
),maxlen
);
105 strcpy(filebase
,cptr
);
106 /* Remove the extension */
107 ptr
= strrchr(filebase
,'.');
114 static void sort_filenames(int n
,char **name
,char **name2
)
116 /* Slow sort, but we usually have tens of names */
125 if (strcmp(name
[j
],name
[f
]) < 0)
145 static int low_fflib_search_file_end(const char *ffdir
,
146 const char *file_end
,
149 char ***filenames_short
)
151 #ifndef HAVE_DIRENT_H
152 gmx_fatal(FARGS
,"lib_search_file_end called while the 'dirent' functionality is not available on this system");
161 char **fns
,**fns_short
;
162 char dir_print
[GMX_PATH_MAX
];
164 char *s
,fn_dir
[GMX_PATH_MAX
];
166 struct dirent
*dirent
;
169 len_fe
= strlen(file_end
);
174 /* Search in current dir and ffdir */
175 libpath
= gmxlibfn(ffdir
);
179 /* GMXLIB can be a path now */
180 lib
= getenv("GMXLIB");
181 snew(libpath
,GMX_PATH_MAX
);
185 strncpy(libpath
,lib
,GMX_PATH_MAX
);
187 else if (!get_libdir(libpath
))
189 strncpy(libpath
,GMXLIBDIR
,GMX_PATH_MAX
);
196 /* Start with the current directory, continue with libpath */
200 dirptr
= opendir(dir
);
203 if (strcmp(dir
,".") == 0)
205 /* Print the absolute path to the current working dir. */
206 #if ((defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64) && !defined __CYGWIN__ && !defined __CYGWIN32__)
207 pdum
= _getcwd(dir_print
,sizeof(dir_print
)-1);
209 pdum
= getcwd(dir_print
,sizeof(dir_print
)-1);
214 /* Print the directory dir, can be relative or absolute. */
215 strcpy(dir_print
,dir
);
219 while ((dirent
= readdir(dirptr
)) != NULL
)
223 fprintf(debug
,"dir '%s' file '%s'\n",dir
,dirent
->d_name
);
225 len_name
= strlen(dirent
->d_name
);
226 /* What about case sensitivity? */
227 if (len_name
>= len_fe
&&
228 strcmp(dirent
->d_name
+len_name
-len_fe
,file_end
) == 0)
230 /* We have a match */
232 sprintf(fn_dir
,"%s%c%s",
233 dir_print
,DIR_SEPARATOR
,dirent
->d_name
);
235 /* Copy the file name, possibly including the path. */
236 fns
[n
] = strdup(fn_dir
);
240 /* We are searching in a path.
241 * Use the relative path when we use share/top
242 * from the installation.
243 * Add the full path when we use the current
244 * working directory of GMXLIB.
246 srenew(fns_short
,n
+1);
247 if (strcmp(dir
,".") == 0 || env_is_set
)
249 fns_short
[n
] = strdup(fn_dir
);
253 fns_short
[n
] = strdup(dirent
->d_name
);
261 sort_filenames(n_thisdir
,
263 fns_short
==NULL
? NULL
: fns_short
+n
-n_thisdir
);
266 while((dir
=gmx_strsep(&s
, PATH_SEPARATOR
)) != NULL
);
270 if (n
== 0 && bFatalError
)
274 gmx_fatal(FARGS
,"Could not find any files ending on '%s' in the force field directory '%s'",file_end
,ffdir
);
278 gmx_fatal(FARGS
,"Could not find any files ending on '%s' in the current directory or the GROMACS library search path",file_end
);
285 *filenames_short
= fns_short
;
292 int fflib_search_file_end(const char *ffdir
,const char *file_end
,
296 return low_fflib_search_file_end(ffdir
,file_end
,bFatalError
,filenames
,NULL
);
299 int fflib_search_file_in_dirend(const char *filename
,const char *dirend
,
302 #ifndef HAVE_DIRENT_H
303 gmx_fatal(FARGS
,"lib_search_file_in_dirend called while the 'dirent' functionality is not available on this system");
311 struct dirent
*dirent
;
313 /* Find all files (not only dir's) ending on dirend */
314 nf
= low_fflib_search_file_end(NULL
,dirend
,FALSE
,&f
,&f_short
);
320 dirptr
= opendir(f
[i
]);
323 while ((dirent
= readdir(dirptr
)) != NULL
)
325 if (strcmp(dirent
->d_name
,filename
) == 0)
327 /* We have a match */
329 dns
[n
] = strdup(f_short
[i
]);
346 bool fflib_fexist(const char *file
)
350 file_fullpath
= low_gmxlibfn(file
,FALSE
);
352 if (file_fullpath
== NULL
)
358 sfree(file_fullpath
);
365 FILE *fflib_open(const char *file
)
370 file_fullpath
= gmxlibfn(file
);
371 fprintf(stderr
,"Opening force field file %s\n",file_fullpath
);
372 fp
= ffopen(file_fullpath
,"r");
373 sfree(file_fullpath
);