OpenMM: added combination rule check, disabled restraint check for now as it's buggy
[gromacs/qmmm-gamess-us.git] / src / kernel / fflibutil.c
blob3e9761866694f391e4ce8e3fbdc0f7604d5da6ae
1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
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 <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <sys/types.h>
44 #include <sys/stat.h>
45 #include <fcntl.h>
47 #ifdef HAVE_DIRENT_H
48 #include <dirent.h>
49 #endif
51 #if ((defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64) && !defined __CYGWIN__ && !defined __CYGWIN32__)
52 #include <direct.h>
53 #include <io.h>
54 #endif
56 #include "sysstuff.h"
57 #include "string2.h"
58 #include "futil.h"
59 #include "network.h"
60 #include "gmx_fatal.h"
61 #include "smalloc.h"
62 #include "statutil.h"
64 #ifdef GMX_THREADS
65 #include "thread_mpi.h"
66 #endif
68 #include "fflibutil.h"
70 const char *fflib_forcefield_dir_ext()
72 return ".ff";
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)
87 const char *cptr;
88 char *ptr;
90 cptr = strrchr(filename,DIR_SEPARATOR);
91 if (cptr != NULL)
93 /* Skip the separator */
94 cptr += 1;
96 else
98 cptr = filename;
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,'.');
108 if (ptr != NULL)
110 ptr[0] = '\0';
114 static void sort_filenames(int n,char **name,char **name2)
116 /* Slow sort, but we usually have tens of names */
117 int i,j,f;
118 char *tmp;
120 for(i=0; i<n-1; i++)
122 f = i;
123 for(j=i+1; j<n; j++)
125 if (strcmp(name[j],name[f]) < 0)
127 f = j;
130 if (f > i)
132 tmp = name[i];
133 name[i] = name[f];
134 name[f] = tmp;
135 if (name2 != NULL)
137 tmp = name2[i];
138 name2[i] = name2[f];
139 name2[f] = tmp;
145 static int low_fflib_search_file_end(const char *ffdir,
146 const char *file_end,
147 bool bFatalError,
148 char ***filenames,
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");
153 return 0;
154 #else
155 char *ret=NULL;
156 char *lib,*dir;
157 char buf[1024];
158 char *libpath;
159 bool env_is_set;
160 int len_fe,len_name;
161 char **fns,**fns_short;
162 char dir_print[GMX_PATH_MAX];
163 char *pdum;
164 char *s,fn_dir[GMX_PATH_MAX];
165 DIR *dirptr;
166 struct dirent *dirent;
167 int n,n_thisdir;
169 len_fe = strlen(file_end);
171 env_is_set = FALSE;
172 if (ffdir != NULL)
174 /* Search in current dir and ffdir */
175 libpath = gmxlibfn(ffdir);
177 else
179 /* GMXLIB can be a path now */
180 lib = getenv("GMXLIB");
181 snew(libpath,GMX_PATH_MAX);
182 if (lib != NULL)
184 env_is_set = TRUE;
185 strncpy(libpath,lib,GMX_PATH_MAX);
187 else if (!get_libdir(libpath))
189 strncpy(libpath,GMXLIBDIR,GMX_PATH_MAX);
192 s = libpath;
193 n = 0;
194 fns = NULL;
195 fns_short = NULL;
196 /* Start with the current directory, continue with libpath */
197 dir = ".";
200 dirptr = opendir(dir);
201 if (dirptr != NULL)
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);
208 #else
209 pdum = getcwd(dir_print,sizeof(dir_print)-1);
210 #endif
212 else
214 /* Print the directory dir, can be relative or absolute. */
215 strcpy(dir_print,dir);
218 n_thisdir = 0;
219 while ((dirent = readdir(dirptr)) != NULL)
221 if (debug)
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 */
231 srenew(fns,n+1);
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);
238 if (ffdir == NULL)
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);
251 else
253 fns_short[n] = strdup(dirent->d_name);
256 n++;
257 n_thisdir++;
261 sort_filenames(n_thisdir,
262 fns+n-n_thisdir,
263 fns_short==NULL ? NULL : fns_short+n-n_thisdir);
266 while((dir=gmx_strsep(&s, PATH_SEPARATOR)) != NULL);
268 sfree(libpath);
270 if (n == 0 && bFatalError)
272 if (ffdir != NULL)
274 gmx_fatal(FARGS,"Could not find any files ending on '%s' in the force field directory '%s'",file_end,ffdir);
276 else
278 gmx_fatal(FARGS,"Could not find any files ending on '%s' in the current directory or the GROMACS library search path",file_end);
282 *filenames = fns;
283 if (ffdir == NULL)
285 *filenames_short = fns_short;
288 return n;
289 #endif
292 int fflib_search_file_end(const char *ffdir,const char *file_end,
293 bool bFatalError,
294 char ***filenames)
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,
300 char ***dirnames)
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");
304 return 0;
305 #else
306 int nf,i;
307 char **f,**f_short;
308 int n;
309 char **dns;
310 DIR *dirptr;
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);
316 n = 0;
317 dns = NULL;
318 for(i=0; i<nf; i++)
320 dirptr = opendir(f[i]);
321 if (dirptr != NULL)
323 while ((dirent = readdir(dirptr)) != NULL)
325 if (strcmp(dirent->d_name,filename) == 0)
327 /* We have a match */
328 srenew(dns,n+1);
329 dns[n] = strdup(f_short[i]);
330 n++;
334 sfree(f[i]);
335 sfree(f_short[i]);
337 sfree(f);
338 sfree(f_short);
340 *dirnames = dns;
342 return n;
343 #endif
346 bool fflib_fexist(const char *file)
348 char *file_fullpath;
350 file_fullpath = low_gmxlibfn(file,FALSE);
352 if (file_fullpath == NULL)
354 return FALSE;
356 else
358 sfree(file_fullpath);
360 return TRUE;
365 FILE *fflib_open(const char *file)
367 char *file_fullpath;
368 FILE *fp;
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);
375 return fp;