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"
57 #include "fflibutil.h"
59 const char *fflib_forcefield_dir_ext()
64 const char *fflib_forcefield_itp()
66 return "forcefield.itp";
69 const char *fflib_forcefield_doc()
71 return "forcefield.doc";
74 void fflib_filename_base(const char *filename, char *filebase, int maxlen)
79 cptr = strrchr(filename, DIR_SEPARATOR);
82 /* Skip the separator */
89 if (strlen(filename) >= (size_t)maxlen)
91 gmx_fatal(FARGS, "filename is longer (%d) than maxlen (%d)",
92 strlen(filename), maxlen);
94 strcpy(filebase, cptr);
95 /* Remove the extension */
96 ptr = strrchr(filebase, '.');
103 static void sort_filenames(int n, char **name, char **name2)
105 /* Slow sort, but we usually have tens of names */
109 for (i = 0; i < n-1; i++)
112 for (j = i+1; j < n; j++)
114 if (strcmp(name[j], name[f]) < 0)
134 static int low_fflib_search_file_end(const char *ffdir,
136 const char *file_end,
137 gmx_bool bFatalError,
139 char ***filenames_short)
144 int len_fe, len_name;
145 char **fns, **fns_short;
146 char dir_print[GMX_PATH_MAX];
147 char *s, fn_dir[GMX_PATH_MAX];
148 gmx_directory_t dirhandle;
149 char nextname[STRLEN];
150 int n, n_thisdir, rc;
152 len_fe = strlen(file_end);
157 /* Search in current dir and ffdir */
158 libpath = gmxlibfn(ffdir);
162 /* GMXLIB can be a path now */
163 lib = getenv("GMXLIB");
164 snew(libpath, GMX_PATH_MAX);
167 sprintf(libpath, "%s%s", ".", PATH_SEPARATOR);
172 strncat(libpath, lib, GMX_PATH_MAX);
176 get_libdir(libpath + strlen(libpath));
183 /* Loop over all the entries in libpath */
184 while ((dir = gmx_strsep(&s, PATH_SEPARATOR)) != NULL)
186 rc = gmx_directory_open(&dirhandle, dir);
189 strcpy(dir_print, dir);
192 while (gmx_directory_nextfile(dirhandle, nextname, STRLEN-1) == 0)
194 nextname[STRLEN-1] = 0;
197 fprintf(debug, "dir '%s' %d file '%s'\n",
198 dir, n_thisdir, nextname);
200 len_name = strlen(nextname);
201 /* What about case sensitivity? */
202 if (len_name >= len_fe &&
203 strcmp(nextname+len_name-len_fe, file_end) == 0)
205 /* We have a match */
207 sprintf(fn_dir, "%s%c%s",
208 dir_print, DIR_SEPARATOR, nextname);
210 /* Copy the file name, possibly including the path. */
211 fns[n] = strdup(fn_dir);
215 /* We are searching in a path.
216 * Use the relative path when we use share/top
217 * from the installation.
218 * Add the full path when we use the current
219 * working directory of GMXLIB.
221 srenew(fns_short, n+1);
222 if (strcmp(dir, ".") == 0 || env_is_set)
224 fns_short[n] = strdup(fn_dir);
228 fns_short[n] = strdup(nextname);
235 gmx_directory_close(dirhandle);
237 sort_filenames(n_thisdir,
239 fns_short == NULL ? NULL : fns_short+n-n_thisdir);
245 if (n == 0 && bFatalError)
249 gmx_fatal(FARGS, "Could not find any files ending on '%s' in the force field directory '%s'", file_end, ffdir);
253 gmx_fatal(FARGS, "Could not find any files ending on '%s' in the current directory or the GROMACS library search path", file_end);
260 *filenames_short = fns_short;
266 int fflib_search_file_end(const char *ffdir,
267 const char *file_end,
268 gmx_bool bFatalError,
271 return low_fflib_search_file_end(ffdir, FALSE, file_end, bFatalError,
275 int fflib_search_file_in_dirend(const char *filename, const char *dirend,
282 gmx_directory_t dirhandle;
283 char nextname[STRLEN];
286 /* Find all files (not only dir's) ending on dirend */
287 nf = low_fflib_search_file_end(NULL, TRUE, dirend, FALSE, &f, &f_short);
291 for (i = 0; i < nf; i++)
293 rc = gmx_directory_open(&dirhandle, f[i]);
297 while (gmx_directory_nextfile(dirhandle, nextname, STRLEN-1) == 0)
299 nextname[STRLEN-1] = 0;
300 if (strcmp(nextname, filename) == 0)
302 /* We have a match */
304 dns[n] = strdup(f_short[i]);
308 gmx_directory_close(dirhandle);
321 gmx_bool fflib_fexist(const char *file)
325 file_fullpath = low_gmxlibfn(file, TRUE, FALSE);
327 if (file_fullpath == NULL)
333 sfree(file_fullpath);
340 FILE *fflib_open(const char *file)
345 file_fullpath = gmxlibfn(file);
346 fprintf(stderr, "Opening force field file %s\n", file_fullpath);
347 fp = ffopen(file_fullpath, "r");
348 sfree(file_fullpath);