Mercurial > projects > mde
comparison mde/file/paths.d @ 135:bc697a218716
Somewhat unified path lookup between linux and windows and added font paths.
author | Diggory Hardy <diggory.hardy@gmail.com> |
---|---|
date | Fri, 30 Jan 2009 15:51:42 +0000 |
parents | 7ababdf97748 |
children | 4084f07f2c7a |
comparison
equal
deleted
inserted
replaced
134:7ababdf97748 | 135:bc697a218716 |
---|---|
125 Cout ("Data paths found:"); | 125 Cout ("Data paths found:"); |
126 dataDir.coutPaths; | 126 dataDir.coutPaths; |
127 Cout ("\nConf paths found:"); | 127 Cout ("\nConf paths found:"); |
128 confDir.coutPaths; | 128 confDir.coutPaths; |
129 Cout ("\nLog file directory:\n\t")(logDir); | 129 Cout ("\nLog file directory:\n\t")(logDir); |
130 version (Windows) { | 130 Cout ("\nFont directories:"); |
131 Cout ("\nFont directory:\n\t")(fontDir).newline; | 131 foreach (path; fontPaths) |
132 } else version (linux) { | 132 Cout ("\n\t")(path.toString); |
133 Cout ("\nFont files found:"); | 133 Cout.newline; |
134 foreach (f,p; fontFiles) | |
135 Cout ("\n\t")(f)("\t")(p[0..$-1]); | |
136 Cout.newline; | |
137 } | |
138 } | 134 } |
139 | 135 |
140 private: | 136 private: |
141 FilePath[] getFiles (char[] filename, PRIORITY readOrder) | 137 FilePath[] getFiles (char[] filename, PRIORITY readOrder) |
142 { | 138 { |
200 // Lowest priority paths are first. | 196 // Lowest priority paths are first. |
201 char[][MAX_PATHS] paths; | 197 char[][MAX_PATHS] paths; |
202 ubyte pathsLen = 0; | 198 ubyte pathsLen = 0; |
203 } | 199 } |
204 | 200 |
201 /** Get the actual path of a font file, or throw NoFileException if not found. | |
202 * | |
203 * Returns a C string (null terminated). */ | |
204 char[] getFontPath (char[] file) { | |
205 foreach (path; fontPaths) { | |
206 FilePath font = path.dup.append (file); | |
207 if (font.exists && font.isFile) | |
208 return font.cString; | |
209 } | |
210 throw new NoFileException ("Unable to find font file: "~file); | |
211 } | |
212 | |
205 /** These are the actual instances, one for each of the data and conf "directories". */ | 213 /** These are the actual instances, one for each of the data and conf "directories". */ |
206 mdeDirectory dataDir, confDir; | 214 mdeDirectory dataDir, confDir; |
207 char[] logDir; /// Directory for log files | 215 char[] logDir; /// Directory for log files |
216 FilePath[] fontPaths; /// All directories for fonts | |
208 | 217 |
209 //BEGIN Path resolution | 218 //BEGIN Path resolution |
219 /// For command line args: these paths are added if non-null, with highest priority. | |
220 char[] extraDataPath, extraConfPath; | |
221 | |
222 /** Add an extra font directory. May be called multiple times. */ | |
223 void addFontPath (char[] path) { | |
224 FilePath fp = FilePath (path); | |
225 if (fp.exists && fp.isFolder) | |
226 fontPaths ~= fp; | |
227 } | |
228 | |
210 /** Find at least one path for each required directory. */ | 229 /** Find at least one path for each required directory. */ |
211 debug (mdeUnitTest) { | 230 debug (mdeUnitTest) { |
212 /** In unittest mode, add paths unittest/data and unittest/conf before init runs. */ | 231 /** In unittest mode, add paths unittest/data and unittest/conf before init runs. */ |
213 static this () { | 232 static this () { |
214 dataDir.tryPath ("unittest/data"); | 233 dataDir.tryPath ("unittest/data"); |
216 if (!(dataDir.pathsLen && confDir.pathsLen)) | 235 if (!(dataDir.pathsLen && confDir.pathsLen)) |
217 throw new mdeException ("Fatal: unittest/data and unittest/conf don't both exist"); | 236 throw new mdeException ("Fatal: unittest/data and unittest/conf don't both exist"); |
218 // Don't bother with real paths or logDir or font dir(s) for unittest. | 237 // Don't bother with real paths or logDir or font dir(s) for unittest. |
219 } | 238 } |
220 } | 239 } |
221 version (linux) { | 240 void resolvePaths (char[] base = ".") { |
222 SortedMap!(char[],char[]) fontFiles; // key is file name, value is CString path | 241 size_t iFP = fontPaths.length; |
223 /** Get the actual path of a font file, or throw NoFileException if not found. | 242 fontPaths.length = fontPaths.length + 4; |
224 * | 243 |
225 * Returns a C string (null terminated). */ | 244 version (linux) { |
226 char[] getFontPath (char[] file) { | |
227 char[] ret; | |
228 if (fontFiles.get (file, ret)) | |
229 return ret; | |
230 throw new NoFileException ("Unable to find font file: "~file); | |
231 } | |
232 | |
233 // base-path not used on posix | |
234 void resolvePaths (char[] base = "data") { | |
235 // Home directory: | 245 // Home directory: |
236 char[] HOME = Environment.get("HOME", "."); | 246 char[] HOME = Environment.get("HOME", "."); |
237 | 247 |
238 // Base paths: | 248 // Installation base (should contain "data" and "conf"): |
239 // Static data (must exist): | 249 FilePath staticPath = findPath (false, |
240 FilePath staticPath = | 250 "/usr/share/games/mde", |
241 findPath (false, "/usr/share/games/mde", "/usr/local/share/games/mde", base); | 251 "/usr/local/share/games/mde", |
242 // Config (can just use defaults if necessary, so long as we can save afterwards): | 252 base~"/data"); |
253 // Path for user-adjusted files: | |
243 FilePath userPath = findPath (true, HOME~"/.config/mde", HOME~"/.mde"); | 254 FilePath userPath = findPath (true, HOME~"/.config/mde", HOME~"/.mde"); |
244 | 255 |
245 // Static data paths: | 256 dataDir.addPath (staticPath.toString); |
246 dataDir.addPath (staticPath.toString); // we know this is valid anyway | |
247 dataDir.tryPath (userPath.toString ~ "/data"); | |
248 if (extraDataPath) dataDir.tryPath (extraDataPath); | |
249 if (!dataDir.pathsLen) throw new mdeException ("Fatal: no data path found!"); | |
250 | |
251 // Configuration paths: | |
252 confDir.tryPath (staticPath.toString ~ "/conf"); | 257 confDir.tryPath (staticPath.toString ~ "/conf"); |
253 confDir.tryPath ("/etc/mde"); | 258 confDir.tryPath ("/etc/mde"); |
254 confDir.tryPath (userPath.toString ~ "/conf", true); | 259 |
255 if (extraConfPath) confDir.tryPath (extraConfPath); | |
256 if (!confDir.pathsLen) throw new mdeException ("Fatal: no conf path found!"); | |
257 | |
258 // Logging path: | |
259 logDir = userPath.toString; | |
260 | |
261 // Font paths: | 260 // Font paths: |
262 auto fs = new FileScan; | 261 auto fontP1 = FilePath("/usr/share/fonts").toList; |
263 // Scan for directories containing truetype and type1 fonts: | 262 foreach (fp1; fontP1) |
264 fs.sweep ("/usr/share/fonts", delegate bool(FilePath fp, bool isDir) | 263 if (fp1.isFolder) |
265 { return isDir || fp.suffix == ".ttf" || fp.suffix == ".pfb"; }, | 264 foreach (fp2; fp1.toList) |
266 true); | 265 if (fp2.isFolder) { |
267 fontFiles = new SortedMap!(char[],char[]); | 266 if (iFP >= fontPaths.length) |
268 foreach (fp; fs.files) | 267 fontPaths.length = fontPaths.length * 2; |
269 fontFiles.add (fp.file, fp.cString); // both strings should be slices of same memory | 268 fontPaths[iFP++] = fp2; |
270 } | 269 } |
271 } else version (Windows) { | 270 } else version (Windows) { |
272 char[] fontDir; | |
273 /** Get the actual path of a font file, or throw NoFileException if not found. | |
274 * | |
275 * Returns a C string (null terminated). */ | |
276 char[] getFontPath (char[] file) { | |
277 FilePath path = new FilePath (fontDir~file); | |
278 if (path.exists && !path.isFolder) | |
279 return path.cString; | |
280 throw new NoFileException ("Unable to find font file: "~file); | |
281 } | |
282 | |
283 void resolvePaths (char[] base = "./") { | |
284 //FIXME: Get base path from registry | 271 //FIXME: Get base path from registry |
285 | 272 |
286 // Base paths: | 273 FilePath staticPath = findPath (false, base~"/data"); |
287 FilePath installPath = findPath (false, base); | |
288 FilePath staticPath = findPath (false, installPath.toString); | |
289 FilePath userPath = findPath (true, getSpecialPath(CSIDL_LOCAL_APPDATA) ~ "/mde"); | 274 FilePath userPath = findPath (true, getSpecialPath(CSIDL_LOCAL_APPDATA) ~ "/mde"); |
290 | 275 |
291 // Static data paths: | 276 dataDir.addPath (staticPath.toString); |
292 dataDir.addPath (staticPath.toString); // we know this is valid anyway | |
293 dataDir.tryPath (userPath.toString ~ "/data"); | |
294 if (extraDataPath) dataDir.tryPath (extraDataPath); | |
295 if (!dataDir.pathsLen) throw new mdeException ("Fatal: no data path found!"); | |
296 | |
297 // Configuration paths: | |
298 confDir.tryPath (staticPath.toString ~ "/conf"); | 277 confDir.tryPath (staticPath.toString ~ "/conf"); |
299 confDir.tryPath (installPath.append("user").toString); | |
300 confDir.tryPath (userPath.toString ~ "/conf", true); | |
301 if (extraConfPath) confDir.tryPath (extraConfPath); | |
302 if (!confDir.pathsLen) throw new mdeException ("Fatal: no conf path found!"); | |
303 | |
304 // Logging path: | |
305 logDir = userPath.toString; | |
306 | 278 |
307 // Font path: | 279 // Font path: |
308 fontDir = getSpecialPath (CSIDL_FONTS) ~ "/"; // append separator | 280 fontPaths ~= FilePath(getSpecialPath (CSIDL_FONTS)); |
309 } | 281 } else { |
310 } else { | 282 static assert (false, "Platform is not linux or Windows: no support for paths on this platform yet!"); |
311 static assert (false, "Platform is not linux or Windows: no support for paths on this platform yet!"); | 283 } |
312 } | 284 |
313 | 285 // Static data paths: |
314 /// For command line args: these paths are added if non-null, with highest priority. | 286 dataDir.tryPath (userPath.toString ~ "/data"); |
315 char[] extraDataPath, extraConfPath; | 287 if (extraDataPath) dataDir.tryPath (extraDataPath); |
288 | |
289 // Configuration paths: | |
290 confDir.tryPath (userPath.toString ~ "/conf", true); | |
291 if (extraConfPath) confDir.tryPath (extraConfPath); | |
292 | |
293 if (!dataDir.pathsLen) throw new mdeException ("Fatal: no data path found!"); | |
294 if (!confDir.pathsLen) throw new mdeException ("Fatal: no conf path found!"); | |
295 | |
296 for (int i = dataDir.pathsLen - 1; i >= 0; --i) { | |
297 FilePath font = FilePath (dataDir.paths[i] ~ "fonts"); | |
298 Cout ("considering: ")(font.toString).newline; | |
299 if (font.exists && font.isFolder) | |
300 fontPaths[iFP++] = font; | |
301 } | |
302 fontPaths.length = iFP; | |
303 | |
304 // Logging path: | |
305 logDir = userPath.toString; | |
306 } | |
316 | 307 |
317 private { | 308 private { |
318 class PathException : mdeException { | 309 class PathException : mdeException { |
319 this(char[] msg) { | 310 this(char[] msg) { |
320 super (msg); | 311 super (msg); |