1 /** 2 * This file is part of DCD, a development tool for the D programming language. 3 * Copyright (C) 2014 Brian Schott 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 module dcd.server.server; 20 21 import std.algorithm; 22 import std.array; 23 import std.experimental.logger; 24 import std.file; 25 import std.path; 26 import std.process: environment; 27 import std.stdio: File; 28 import std.stdio: KeepTerminator; 29 30 import dsymbol.modulecache; 31 32 /// Name of the server configuration file 33 enum CONFIG_FILE_NAME = "dcd.conf"; 34 35 version(linux) version = useXDG; 36 version(BSD) version = useXDG; 37 version(FreeBSD) version = useXDG; 38 version(OSX) version = useXDG; 39 40 /** 41 * Locates the configuration file 42 */ 43 string getConfigurationLocation() 44 { 45 version (useXDG) 46 { 47 string configDir = environment.get("XDG_CONFIG_HOME", null); 48 if (configDir is null) 49 { 50 configDir = environment.get("HOME", null); 51 if (configDir !is null) 52 configDir = buildPath(configDir, ".config", "dcd", CONFIG_FILE_NAME); 53 if (!exists(configDir)) 54 configDir = buildPath("/etc/", CONFIG_FILE_NAME); 55 } 56 else 57 { 58 configDir = buildPath(configDir, "dcd", CONFIG_FILE_NAME); 59 } 60 return configDir; 61 } 62 else version(Windows) 63 { 64 return CONFIG_FILE_NAME; 65 } 66 } 67 68 import std.regex : ctRegex; 69 alias envVarRegex = ctRegex!(`\$\{([_a-zA-Z][_a-zA-Z 0-9]*)\}`); 70 71 private unittest 72 { 73 import std.regex : replaceAll; 74 75 enum input = `${HOME}/aaa/${_bb_b}/ccc`; 76 77 assert(replaceAll!(m => m[1])(input, envVarRegex) == `HOME/aaa/_bb_b/ccc`); 78 } 79 80 /** 81 * Loads import directories from the configuration file 82 */ 83 string[] loadConfiguredImportDirs() 84 { 85 string expandEnvVars(string l) 86 { 87 import std.regex : replaceAll; 88 return replaceAll!(m => environment.get(m[1], ""))(l, envVarRegex); 89 } 90 91 immutable string configLocation = getConfigurationLocation(); 92 if (!configLocation.exists()) 93 return []; 94 info("Loading configuration from ", configLocation); 95 File f = File(configLocation, "rt"); 96 return f.byLine(KeepTerminator.no) 97 .filter!(a => a.length > 0 && a[0] != '#') 98 .map!(a => a.idup) 99 .map!(expandEnvVars) 100 .filter!(a => existanceCheck(a)) 101 .array(); 102 }