FIX: Remove undistributable CHEMKIN files
[freefoam.git] / data / python / FreeFOAM / path.py
blobda0a1d216145c395b62709fbc69065d4bf4bfa62
1 #-------------------------------------------------------------------------------
2 # ______ _ ____ __ __
3 # | ____| _| |_ / __ \ /\ | \/ |
4 # | |__ _ __ ___ ___ / \| | | | / \ | \ / |
5 # | __| '__/ _ \/ _ ( (| |) ) | | |/ /\ \ | |\/| |
6 # | | | | | __/ __/\_ _/| |__| / ____ \| | | |
7 # |_| |_| \___|\___| |_| \____/_/ \_\_| |_|
9 # FreeFOAM: The Cross-Platform CFD Toolkit
11 # Copyright (C) 2008-2012 Michael Wild <themiwi@users.sf.net>
12 # Gerber van der Graaf <gerber_graaf@users.sf.net>
13 #-------------------------------------------------------------------------------
14 # License
15 # This file is part of FreeFOAM.
17 # FreeFOAM is free software: you can redistribute it and/or modify it
18 # under the terms of the GNU General Public License as published by the
19 # Free Software Foundation, either version 3 of the License, or (at your
20 # option) any later version.
22 # FreeFOAM is distributed in the hope that it will be useful, but WITHOUT
23 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
24 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 # for more details.
27 # You should have received a copy of the GNU General Public License
28 # along with FreeFOAM. If not, see <http://www.gnu.org/licenses/>.
30 # Description
31 # Path searching functions.
33 #-------------------------------------------------------------------------------
35 """Path manipulation and search functions."""
37 # want to be future proof
38 from FreeFOAM.compat import *
40 import FreeFOAM as _f
42 # local helper
43 def _isreadable(fname):
44 """Determine whether a file is readable by the user.
46 Parameters
47 ----------
48 fname : Path to the file to test.
50 Returns
51 -------
52 True if the file is readable by the user, False otherwise.
54 """
55 import os
56 return os.access(fname, os.R_OK)
58 # local helper
59 def _isexecutable(fname):
60 """Determine whether a file is executable by the user.
62 Parameters
63 ----------
64 fname : Path to the file to test.
66 Returns
67 -------
68 True if the file is executable by the user, False otherwise.
70 """
71 import os
72 import os.path
73 return os.path.isfile(fname) and os.access(fname, os.X_OK)
76 def split_search_path(path_str, normpath=True):
77 """Splits a search path string into a list of directories.
79 Parameters
80 ----------
81 path_str : The search path to split.
82 normpath : If True, os.path.normpath is applied to each element in the
83 returned list.
85 Returns
86 -------
87 path : A list of directories created by splitting 'path_str'.
89 """
90 import os
91 import os.path
92 # replace all os.pathsep by :
93 if os.pathsep != ':':
94 path_str = path_str.replace(os.pathsep,':')
95 # split at ':' and remove empty elements (e.g. from double :)
96 path = list(filter(len, path_str.split(':')))
97 # normalize paths if requested
98 if normpath and len(path):
99 path = list(map(os.path.normpath, path))
100 return path
102 def find_on_search_path(fname, path, predicate=_isreadable):
103 """Find a file on a search path subject to a predicate.
105 The first match for which 'predicate' returns true, will be selected.
106 It is completely up to 'predicate' to determine what a valid match is (e.g.
107 it is allowed to return True for a non-existing file).
109 Parameters
110 ----------
111 fname : Name of the file to find.
112 path : Either a sequence of directories or a ':' (on Windows also ';')
113 delimited string of directories to search.
114 predicate : A function which returns True if the file meets the requirements.
116 Returns
117 -------
118 path : The first path for which 'predicate' returned true.
121 import os.path
122 if isinstance(path, str):
123 path = split_search_path(path, True)
124 # loop over all directories in path
125 for dir in path:
126 # construct full candidate path
127 f = os.path.join(dir, fname)
128 # test whether it meets the predicate
129 if predicate(f):
130 return os.path.normpath(f)
131 # failed to find the file
132 return None
134 def create_app_search_path(basedir=_f.LIBEXEC_DIR, syspath=False):
135 """Create a search path for FreeFOAM applications.
137 First directories in the list given by the environment variable
138 'FREEFOAM_PATH' (if it is defined) are used. The elements of 'FREEFOAM_PATH'
139 must be separated by ':' (or optionally by ';' on Windows). Next the
140 directory '<basedir>' is appended, where '<basedir>' defaults to
141 'LIBEXEC_DIR'. This can be overriden using the 'basedir' argument. If the
142 argument 'syspath' is set to True, the directories in the system 'PATH'
143 variable will appended to the list.
145 Parameters
146 ----------
147 basedir : Directory in which the FreeFOAM applications are located.
148 syspath : If True, the system 'PATH' environment variable will also be
149 searched.
151 Returns
152 -------
153 path : A list of directories comprising the search path.
156 import os
157 import os.path
158 # set up the search path
159 path = []
160 # start with FREEFOAM_PATH elements if present
161 if 'FREEFOAM_PATH' in os.environ:
162 path.extend(split_search_path(os.environ['FREEFOAM_PATH']))
163 # append with basedir
164 path.append(os.path.abspath(basedir))
165 # append system PATH elements if present and desired by the user
166 if syspath and 'PATH' in os.environ:
167 path.extend(split_search_path(os.environ['PATH']))
168 # done
169 return path
171 def locate_app(fname, spath=None):
172 """Searches the search-path 'path' for an application named 'fname'.
174 The name of the file searched will be constructed as
175 'FreeFOAM.EXE_PREFIX+fname'. The elements of 'spath' will be searched for a
176 file with that name which is executable by the current user.
178 Parameters
179 ----------
180 fname : Name of the application to find.
181 spath : Sequence of directories to be used as the search path.
182 If set to None, the default search path will be constructed
183 by calling create_app_search_path with no arguments.
185 Returns
186 -------
187 path : The full path to the file if it was found, None otherwise.
190 import os.path
191 fname = os.path.normpath(fname)
192 # first check whether this is a relative/absolute path
193 if _isexecutable(fname):
194 if not os.path.isabs(fname) and fname[0] != '.':
195 fname = os.path.join('.',fname)
196 return fname
197 # construct default search path if none specified
198 if not spath:
199 spath = create_app_search_path()
200 # construct correct file name
201 fname = _f.EXE_PREFIX + fname + _f.EXE_SUFFIX
202 # find the thing
203 return find_on_search_path(fname, spath, _isexecutable)
205 def locate_config(fname):
206 """Searches the filesystem for a configuration file named 'fname'.
208 By default the 'CONFIG_DIR' directory is search, which can be overriden by
209 the 'FREEFOAM_CONFIG_DIR' environment variable.
211 Parameters
212 ----------
213 fname : Name of the configuration file to find.
215 Returns
216 -------
217 path : The full path to the file if it was found, None otherwise.
220 import os
221 import os.path
222 if 'FREEFOAM_CONFIG_DIR' in os.environ:
223 dir = os.environ['FREEFOAM_CONFIG_DIR']
224 else:
225 dir = _f.CONFIG_DIR
226 return find_on_search_path(fname, [dir])
228 def locate_tmpl(fname):
229 """Searches the filesystem for the template file 'fname'.
231 These text templates are searched for in 'DATA_DIR+"/templates"'.
233 Parameters
234 ----------
235 fname : Name of the template file to locate.
237 Returns
238 -------
239 path : The full path to the template file if it was found, None otherwise.
242 import os.path
243 dir = os.path.join(_f.DATA_DIR,'templates')
244 return find_on_search_path(fname, [dir])
246 # ------------------------- vim: set sw=3 sts=3 et: --------------- end-of-file