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>
50 #include "gmx_fatal.h"
59 #include "thread_mpi.h"
62 #include "fflibutil.h"
64 const char *fflib_forcefield_dir_ext()
69 const char *fflib_forcefield_itp()
71 return "forcefield.itp";
74 const char *fflib_forcefield_doc()
76 return "forcefield.doc";
79 void fflib_filename_base(const char *filename, char *filebase, int maxlen)
84 cptr = strrchr(filename, DIR_SEPARATOR);
87 /* Skip the separator */
94 if (strlen(filename) >= (size_t)maxlen)
96 gmx_fatal(FARGS, "filename is longer (%d) than maxlen (%d)",
97 strlen(filename), maxlen);
99 strcpy(filebase, cptr);
100 /* Remove the extension */
101 ptr = strrchr(filebase, '.');
108 static void sort_filenames(int n, char **name, char **name2)
110 /* Slow sort, but we usually have tens of names */
114 for (i = 0; i < n-1; i++)
117 for (j = i+1; j < n; j++)
119 if (strcmp(name[j], name[f]) < 0)
139 static int low_fflib_search_file_end(const char *ffdir,
141 const char *file_end,
142 gmx_bool bFatalError,
144 char ***filenames_short)
149 int len_fe, len_name;
150 char **fns, **fns_short;
151 char dir_print[GMX_PATH_MAX];
152 char *s, fn_dir[GMX_PATH_MAX];
153 gmx_directory_t dirhandle;
154 char nextname[STRLEN];
155 int n, n_thisdir, rc;
157 len_fe = strlen(file_end);
162 /* Search in current dir and ffdir */
163 libpath = gmxlibfn(ffdir);
167 /* GMXLIB can be a path now */
168 lib = getenv("GMXLIB");
169 snew(libpath, GMX_PATH_MAX);
172 sprintf(libpath, "%s%s", ".", PATH_SEPARATOR);
177 strncat(libpath, lib, GMX_PATH_MAX);
181 get_libdir(libpath + strlen(libpath));
188 /* Loop over all the entries in libpath */
189 while ((dir = gmx_strsep(&s, PATH_SEPARATOR)) != NULL)
191 rc = gmx_directory_open(&dirhandle, dir);
194 strcpy(dir_print, dir);
197 while (gmx_directory_nextfile(dirhandle, nextname, STRLEN-1) == 0)
199 nextname[STRLEN-1] = 0;
202 fprintf(debug, "dir '%s' %d file '%s'\n",
203 dir, n_thisdir, nextname);
205 len_name = strlen(nextname);
206 /* What about case sensitivity? */
207 if (len_name >= len_fe &&
208 strcmp(nextname+len_name-len_fe, file_end) == 0)
210 /* We have a match */
212 sprintf(fn_dir, "%s%c%s",
213 dir_print, DIR_SEPARATOR, nextname);
215 /* Copy the file name, possibly including the path. */
216 fns[n] = strdup(fn_dir);
220 /* We are searching in a path.
221 * Use the relative path when we use share/top
222 * from the installation.
223 * Add the full path when we use the current
224 * working directory of GMXLIB.
226 srenew(fns_short, n+1);
227 if (strcmp(dir, ".") == 0 || env_is_set)
229 fns_short[n] = strdup(fn_dir);
233 fns_short[n] = strdup(nextname);
240 gmx_directory_close(dirhandle);
242 sort_filenames(n_thisdir,
244 fns_short == NULL ? NULL : fns_short+n-n_thisdir);
250 if (n == 0 && bFatalError)
254 gmx_fatal(FARGS, "Could not find any files ending on '%s' in the force field directory '%s'", file_end, ffdir);
258 gmx_fatal(FARGS, "Could not find any files ending on '%s' in the current directory or the GROMACS library search path", file_end);
265 *filenames_short = fns_short;
271 int fflib_search_file_end(const char *ffdir,
272 const char *file_end,
273 gmx_bool bFatalError,
276 return low_fflib_search_file_end(ffdir, FALSE, file_end, bFatalError,
280 int fflib_search_file_in_dirend(const char *filename, const char *dirend,
287 gmx_directory_t dirhandle;
288 char nextname[STRLEN];
291 /* Find all files (not only dir's) ending on dirend */
292 nf = low_fflib_search_file_end(NULL, TRUE, dirend, FALSE, &f, &f_short);
296 for (i = 0; i < nf; i++)
298 rc = gmx_directory_open(&dirhandle, f[i]);
302 while (gmx_directory_nextfile(dirhandle, nextname, STRLEN-1) == 0)
304 nextname[STRLEN-1] = 0;
305 if (strcmp(nextname, filename) == 0)
307 /* We have a match */
309 dns[n] = strdup(f_short[i]);
313 gmx_directory_close(dirhandle);
326 gmx_bool fflib_fexist(const char *file)
330 file_fullpath = low_gmxlibfn(file, TRUE, FALSE);
332 if (file_fullpath == NULL)
338 sfree(file_fullpath);
345 FILE *fflib_open(const char *file)
350 file_fullpath = gmxlibfn(file);
351 fprintf(stderr, "Opening force field file %s\n", file_fullpath);
352 fp = ffopen(file_fullpath, "r");
353 sfree(file_fullpath);