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>
48 #include "gromacs/fileio/futil.h"
50 #include "gmx_fatal.h"
58 #include "fflibutil.h"
60 const char *fflib_forcefield_dir_ext()
65 const char *fflib_forcefield_itp()
67 return "forcefield.itp";
70 const char *fflib_forcefield_doc()
72 return "forcefield.doc";
75 void fflib_filename_base(const char *filename, char *filebase, int maxlen)
80 cptr = strrchr(filename, DIR_SEPARATOR);
83 /* Skip the separator */
90 if (strlen(filename) >= (size_t)maxlen)
92 gmx_fatal(FARGS, "filename is longer (%d) than maxlen (%d)",
93 strlen(filename), maxlen);
95 strcpy(filebase, cptr);
96 /* Remove the extension */
97 ptr = strrchr(filebase, '.');
104 static void sort_filenames(int n, char **name, char **name2)
106 /* Slow sort, but we usually have tens of names */
110 for (i = 0; i < n-1; i++)
113 for (j = i+1; j < n; j++)
115 if (strcmp(name[j], name[f]) < 0)
135 static int low_fflib_search_file_end(const char *ffdir,
137 const char *file_end,
138 gmx_bool bFatalError,
140 char ***filenames_short)
145 int len_fe, len_name;
146 char **fns, **fns_short;
147 char dir_print[GMX_PATH_MAX];
148 char *s, fn_dir[GMX_PATH_MAX];
149 gmx_directory_t dirhandle;
150 char nextname[STRLEN];
151 int n, n_thisdir, rc;
153 len_fe = strlen(file_end);
158 /* Search in current dir and ffdir */
159 libpath = gmxlibfn(ffdir);
163 /* GMXLIB can be a path now */
164 lib = getenv("GMXLIB");
165 snew(libpath, GMX_PATH_MAX);
168 sprintf(libpath, "%s%s", ".", PATH_SEPARATOR);
173 strncat(libpath, lib, GMX_PATH_MAX);
177 get_libdir(libpath + strlen(libpath));
184 /* Loop over all the entries in libpath */
185 while ((dir = gmx_strsep(&s, PATH_SEPARATOR)) != NULL)
187 rc = gmx_directory_open(&dirhandle, dir);
190 strcpy(dir_print, dir);
193 while (gmx_directory_nextfile(dirhandle, nextname, STRLEN-1) == 0)
195 nextname[STRLEN-1] = 0;
198 fprintf(debug, "dir '%s' %d file '%s'\n",
199 dir, n_thisdir, nextname);
201 len_name = strlen(nextname);
202 /* What about case sensitivity? */
203 if (len_name >= len_fe &&
204 strcmp(nextname+len_name-len_fe, file_end) == 0)
206 /* We have a match */
208 sprintf(fn_dir, "%s%c%s",
209 dir_print, DIR_SEPARATOR, nextname);
211 /* Copy the file name, possibly including the path. */
212 fns[n] = strdup(fn_dir);
216 /* We are searching in a path.
217 * Use the relative path when we use share/top
218 * from the installation.
219 * Add the full path when we use the current
220 * working directory of GMXLIB.
222 srenew(fns_short, n+1);
223 if (strcmp(dir, ".") == 0 || env_is_set)
225 fns_short[n] = strdup(fn_dir);
229 fns_short[n] = strdup(nextname);
236 gmx_directory_close(dirhandle);
238 sort_filenames(n_thisdir,
240 fns_short == NULL ? NULL : fns_short+n-n_thisdir);
246 if (n == 0 && bFatalError)
250 gmx_fatal(FARGS, "Could not find any files ending on '%s' in the force field directory '%s'", file_end, ffdir);
254 gmx_fatal(FARGS, "Could not find any files ending on '%s' in the current directory or the GROMACS library search path", file_end);
261 *filenames_short = fns_short;
267 int fflib_search_file_end(const char *ffdir,
268 const char *file_end,
269 gmx_bool bFatalError,
272 return low_fflib_search_file_end(ffdir, FALSE, file_end, bFatalError,
276 int fflib_search_file_in_dirend(const char *filename, const char *dirend,
283 gmx_directory_t dirhandle;
284 char nextname[STRLEN];
287 /* Find all files (not only dir's) ending on dirend */
288 nf = low_fflib_search_file_end(NULL, TRUE, dirend, FALSE, &f, &f_short);
292 for (i = 0; i < nf; i++)
294 rc = gmx_directory_open(&dirhandle, f[i]);
298 while (gmx_directory_nextfile(dirhandle, nextname, STRLEN-1) == 0)
300 nextname[STRLEN-1] = 0;
301 if (strcmp(nextname, filename) == 0)
303 /* We have a match */
305 dns[n] = strdup(f_short[i]);
309 gmx_directory_close(dirhandle);
322 gmx_bool fflib_fexist(const char *file)
326 file_fullpath = low_gmxlibfn(file, TRUE, FALSE);
328 if (file_fullpath == NULL)
334 sfree(file_fullpath);
341 FILE *fflib_open(const char *file)
346 file_fullpath = gmxlibfn(file);
347 fprintf(stderr, "Opening force field file %s\n", file_fullpath);
348 fp = ffopen(file_fullpath, "r");
349 sfree(file_fullpath);